Describe the issue:
Since gh-31389 (fix for gh-31337), npy_common.h excludes __INTEL_LLVM_COMPILER from
the _MSC_VER branch, so for icx on Windows npy_cdouble is double _Complex rather
than _Dcomplex:
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER)
typedef _Dcomplex npy_cdouble;
#else
typedef double _Complex npy_cdouble;
But npy_math.h's accessors still call the UCRT functions in the C path:
static inline double npy_creal(const npy_cdouble z)
{
#if defined(__cplusplus)
return z._Val[0];
#else
return creal(z);
#endif
}
Windows UCRT declares creal(_Dcomplex), crealf(_Fcomplex), creall(_Lcomplex)
regardless of which frontend compiles it, since it is the same CRT. So the two
headers disagree and including <numpy/npy_math.h> alone fails to compile.
Note the __cplusplus path already avoids the UCRT call by using z._Val[0]; only the
C path is affected.
Suggested fix: use real/imag (or z._Val[0]) instead of UCRT creal/cimag when
_MSC_VER is defined, or do not switch the typedefs based on the CRT at all.
Compiling with -U__INTEL_LLVM_COMPILER makes it build again, which confirms the
typedef selection is the trigger.
This is a different failure location than gh-31337 - that one was numpy's own
meson.build _Fcomplex type check; this one is npy_math.h and affects downstream
projects using the installed headers.
Affects numpy >= 2.4.5 and all 2.5.x.
Reproduce the code example:
// repro.c
#include <Python.h>
#include <numpy/npy_math.h>
icx /c repro.c -I"%PREFIX%\Lib\site-packages\numpy\_core\include" -I"%PREFIX%\Include"
Error message:
npy_math.h(368,18): error: passing 'const npy_cdouble' (aka 'const _Complex double') to parameter of incompatible type '_Dcomplex' (aka 'struct _C_double_complex')
368 | return creal(z);
| ^
ucrt\complex.h(89,49): note: passing argument to parameter '_Z' here
89 | _ACRTIMP double __cdecl creal(_In_ _Dcomplex _Z);
| ^
6 errors generated.
Python and NumPy Versions:
numpy 2.5.2
Python 3.13.15
Runtime Environment:
Windows x86_64
Intel oneAPI DPC++/C++ Compiler (icx) 2026.2.0
Windows SDK / UCRT 10.0.26100.0
How does this issue affect you or how did you find it:
It breaks Windows builds of mkl_umath (https://github.com/IntelPython/mkl_umath),
which compiles with icx against the installed numpy headers. Bisected by compiling
the reproducer against each release: 2.4.4 builds, 2.4.5 fails. The 2.4.4 headers
have no __INTEL_LLVM_COMPILER reference at all; 2.4.5 introduces it.
Describe the issue:
Since gh-31389 (fix for gh-31337), npy_common.h excludes __INTEL_LLVM_COMPILER from
the _MSC_VER branch, so for icx on Windows npy_cdouble is
double _Complexratherthan
_Dcomplex:But npy_math.h's accessors still call the UCRT functions in the C path:
Windows UCRT declares
creal(_Dcomplex),crealf(_Fcomplex),creall(_Lcomplex)regardless of which frontend compiles it, since it is the same CRT. So the two
headers disagree and including <numpy/npy_math.h> alone fails to compile.
Note the __cplusplus path already avoids the UCRT call by using z._Val[0]; only the
C path is affected.
Suggested fix: use real/imag (or z._Val[0]) instead of UCRT creal/cimag when
_MSC_VER is defined, or do not switch the typedefs based on the CRT at all.
Compiling with -U__INTEL_LLVM_COMPILER makes it build again, which confirms the
typedef selection is the trigger.
This is a different failure location than gh-31337 - that one was numpy's own
meson.build _Fcomplex type check; this one is npy_math.h and affects downstream
projects using the installed headers.
Affects numpy >= 2.4.5 and all 2.5.x.
Reproduce the code example:
Error message:
Python and NumPy Versions:
numpy 2.5.2
Python 3.13.15
Runtime Environment:
Windows x86_64
Intel oneAPI DPC++/C++ Compiler (icx) 2026.2.0
Windows SDK / UCRT 10.0.26100.0
How does this issue affect you or how did you find it:
It breaks Windows builds of mkl_umath (https://github.com/IntelPython/mkl_umath),
which compiles with icx against the installed numpy headers. Bisected by compiling
the reproducer against each release: 2.4.4 builds, 2.4.5 fails. The 2.4.4 headers
have no __INTEL_LLVM_COMPILER reference at all; 2.4.5 introduces it.