Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with long double on Windows? #37

Open
1 task done
bluescarni opened this issue Nov 28, 2024 · 12 comments
Open
1 task done

Issues with long double on Windows? #37

bluescarni opened this issue Nov 28, 2024 · 12 comments
Labels

Comments

@bluescarni
Copy link

Solution to issue cannot be found in the documentation.

  • I checked the documentation.

Issue

Hello!

I have a conda-forge package that used to depend (on Windows) on MPIR. As suggested by the conda bot, I tried today to switch to GMP instead. Unfortunately, when building against GMP on Windows, my test suite reports a few segfaults and test failures:

https://github.com/bluescarni/mppp/actions/runs/12064541923/job/33641559234?pr=319#step:5:1884

I am currently investigating, but the preliminary result is that the segfaults/errors happen in tests where long double values are being passed into the GMP API. This make sense to me, since, AFAIR, mingw provides by default 80-bit long double, while MSVC (which I am using to compile my library) provides 64-bit long double.

Is this diagnosis correct? If so, what is the correct way of dealing with this?

Installed packages

# packages in environment at C:\Users\User\miniforge3\envs\mppp:
#
# Name                    Version                   Build  Channel
_openmp_mutex             4.5                       2_gnu    conda-forge
bzip2                     1.0.8                h2466b09_7    conda-forge
ca-certificates           2024.8.30            h56e8100_0    conda-forge
cmake                     3.31.1               h400e5d1_0    conda-forge
fmt                       11.0.2               h7f575de_0    conda-forge
git                       2.47.1               h57928b3_0    conda-forge
gmp                       6.3.0                hfeafd45_2    conda-forge
krb5                      1.21.3               hdf4eb48_0    conda-forge
libboost                  1.86.0               h444863b_2    conda-forge
libboost-devel            1.86.0               h91493d7_2    conda-forge
libboost-headers          1.86.0               h57928b3_2    conda-forge
libcurl                   8.10.1               h1ee3ff0_0    conda-forge
libexpat                  2.6.4                he0c23c2_0    conda-forge
libflint                  3.1.2              h0491284_101    conda-forge
libgcc                    14.2.0               h1383e82_1    conda-forge
libgomp                   14.2.0               h1383e82_1    conda-forge
libiconv                  1.17                 hcfcfb64_2    conda-forge
libssh2                   1.11.1               he619c9f_0    conda-forge
libuv                     1.49.2               h2466b09_0    conda-forge
libwinpthread             12.0.0.r4.gg4f2fc60ca      h57928b3_8    conda-forge
libzlib                   1.3.1                h2466b09_2    conda-forge
mpc                       1.3.1                h72bc38f_1    conda-forge
mpfr                      4.2.1                hbc20e70_3    conda-forge
openssl                   3.4.0                h2466b09_0    conda-forge
ucrt                      10.0.22621.0         h57928b3_1    conda-forge
vc                        14.3                ha32ba9b_23    conda-forge
vc14_runtime              14.42.34433         he29a5d6_23    conda-forge
vs2015_runtime            14.42.34433         hdffcdeb_23    conda-forge
xz                        5.2.6                h8d14728_0    conda-forge
zstd                      1.5.6                h0ea2cb4_0    conda-forge

Environment info

active environment : mppp
    active env location : C:\Users\User\miniforge3\envs\mppp
            shell level : 2
       user config file : C:\Users\User\.condarc
 populated config files : C:\Users\User\miniforge3\.condarc
          conda version : 24.11.0
    conda-build version : not installed
         python version : 3.12.6.final.0
                 solver : libmamba (default)
       virtual packages : __archspec=1=x86_64_v3
                          __conda=24.11.0=0
                          __win=0=0
       base environment : C:\Users\User\miniforge3  (writable)
      conda av data dir : C:\Users\User\miniforge3\etc\conda
  conda av metadata url : None
           channel URLs : https://conda.anaconda.org/conda-forge/win-64
                          https://conda.anaconda.org/conda-forge/noarch
          package cache : C:\Users\User\miniforge3\pkgs
                          C:\Users\User\.conda\pkgs
                          C:\Users\User\AppData\Local\conda\conda\pkgs
       envs directories : C:\Users\User\miniforge3\envs
                          C:\Users\User\.conda\envs
                          C:\Users\User\AppData\Local\conda\conda\envs
               platform : win-64
             user-agent : conda/24.11.0 requests/2.32.3 CPython/3.12.6 Windows/11 Windows/10.0.22621 solver/libmamba conda-libmamba-solver/24.9.0 libmambapy/1.5.11
          administrator : False
             netrc file : None
           offline mode : False
@bluescarni bluescarni added the bug label Nov 28, 2024
@isuruf
Copy link
Member

isuruf commented Nov 28, 2024

Thanks for investigating. I've seen segfaults on symengine too, but those tests seem related to long double.

@isuruf
Copy link
Member

isuruf commented Dec 3, 2024

The symengine failures were due to the usage of mpz_set_si taking a long instead of a long long.

@bluescarni
Copy link
Author

bluescarni commented Dec 4, 2024

The symengine failures were due to the usage of mpz_set_si taking a long instead of a long long.

Hi @isuruf !

I have done a bit more investigating, and can confirm that the segfaults in my test suite all happen when passing long double into the GMP/MPFR API. If I remove any trace of long double from the test code, I do not get segfaults any more.

Do you think it would be possible to add the -mlong-double-64 flag to the flags used when building conda-forge packages with MinGW? That should ensure that code compiled with MSVC works correctly when passing long double values into functions compiled with MinGW. See also:

https://sourceforge.net/p/mingw-w64/bugs/675/

@isuruf
Copy link
Member

isuruf commented Dec 4, 2024

Which API are we talking about? GMP doesn't have one AFAIK.

@bluescarni
Copy link
Author

Which API are we talking about? GMP doesn't have one AFAIK.

You are right, I was misremembering. It is actually MPFR which does have support for long double in the API, e.g.:

https://www.mpfr.org/mpfr-current/mpfr.html#index-mpfr_005fset_005fld
https://www.mpfr.org/mpfr-current/mpfr.html#index-mpfr_005finit_005fset_005fld
https://www.mpfr.org/mpfr-current/mpfr.html#index-mpfr_005fget_005fld
https://www.mpfr.org/mpfr-current/mpfr.html#index-mpfr_005fcmp_005fld

And so on...

@isuruf
Copy link
Member

isuruf commented Dec 4, 2024

Would you be able to use mpfr_set_d with a _MSC_VER check on windows?

@bluescarni
Copy link
Author

Would you be able to use mpfr_set_d with a _MSC_VER check on windows?

Let me try...

@isuruf
Copy link
Member

isuruf commented Dec 4, 2024

Maybe something like conda-forge/mpfr-feedstock#50 would be good

@bluescarni
Copy link
Author

Would you be able to use mpfr_set_d with a _MSC_VER check on windows?

Yep that worked, thanks a lot!

Maybe something like conda-forge/mpfr-feedstock#50 would be good

I think this is a good idea in principle, however functions being turned into macros would break code that invokes them prepending :: and maybe would break function pointers too?

BTW, there are also functions from the MPC API taking long double in input, such as mpc_pow_ld().

@isuruf
Copy link
Member

isuruf commented Dec 4, 2024

however functions being turned into macros would break code that invokes them prepending ::

I'm not sure what this means? Something like below works for me

void foo() {

};

#define asd foo

int main() {
  ::asd();
};

@bluescarni
Copy link
Author

however functions being turned into macros would break code that invokes them prepending ::

I'm not sure what this means? Something like below works for me

void foo() {

};

#define asd foo

int main() {
::asd();
};

I remember this not working at one point at least on some compilers, but either I am misremembering or it got fixed.

@bluescarni
Copy link
Author

@isuruf For the function pointers, this is what I mean:

https://godbolt.org/z/decEdWoEc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants