mirror of
https://gitlab.com/libeigen/eigen.git
synced 2024-12-21 07:19:46 +08:00
Disable testing of complex compound assignment operators for MSVC.
MSVC does not support specializing compound assignments for `std::complex`, since it already specializes them (contrary to the standard). Trying to use one of these on device will currently lead to a duplicate definition error. This is still probably preferable to no error though. If we remove the definitions for MSVC, then it will compile, but the kernel will fail silently. The only proper solution would be to define our own custom `Complex` type.
This commit is contained in:
parent
51a0b4e2d2
commit
f0f1d7938b
@ -11,13 +11,24 @@
|
||||
#ifndef EIGEN_COMPLEX_CUDA_H
|
||||
#define EIGEN_COMPLEX_CUDA_H
|
||||
|
||||
// clang-format off
|
||||
// Many std::complex methods such as operator+, operator-, operator* and
|
||||
// operator/ are not constexpr. Due to this, GCC and older versions of clang do
|
||||
// not treat them as device functions and thus Eigen functors making use of
|
||||
// these operators fail to compile. Here, we manually specialize these
|
||||
// operators and functors for complex types when building for CUDA to enable
|
||||
// their use on-device.
|
||||
//
|
||||
// NOTES:
|
||||
// - Compound assignment operators +=,-=,*=,/=(Scalar) will not work on device,
|
||||
// since they are already specialized in the standard. Using them will result
|
||||
// in silent kernel failures.
|
||||
// - Compiling with MSVC and using +=,-=,*=,/=(std::complex<Scalar>) will lead
|
||||
// to duplicate definition errors, since these are already specialized in
|
||||
// Visual Studio's <complex> header (contrary to the standard). This is
|
||||
// preferable to removing such definitions, which will lead to silent kernel
|
||||
// failures.
|
||||
// - Compiling with ICC requires defining _USE_COMPLEX_SPECIALIZATION_ prior
|
||||
// to the first inclusion of <complex>.
|
||||
|
||||
#if defined(EIGEN_CUDACC) && defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
|
||||
|
@ -138,10 +138,12 @@ struct complex_operators {
|
||||
out[out_idx++] = a / numext::real(b);
|
||||
out[out_idx++] = numext::real(a) / b;
|
||||
|
||||
#if !defined(EIGEN_COMP_MSVC)
|
||||
out[out_idx] = a; out[out_idx++] += b;
|
||||
out[out_idx] = a; out[out_idx++] -= b;
|
||||
out[out_idx] = a; out[out_idx++] *= b;
|
||||
out[out_idx] = a; out[out_idx++] /= b;
|
||||
#endif
|
||||
|
||||
const ComplexType true_value = ComplexType(ValueType(1), ValueType(0));
|
||||
const ComplexType false_value = ComplexType(ValueType(0), ValueType(0));
|
||||
@ -188,6 +190,7 @@ struct complex_operators {
|
||||
res.segment(block_idx, size) = x1.real().array() / x2.array();
|
||||
block_idx += size;
|
||||
|
||||
#if !defined(EIGEN_COMP_MSVC)
|
||||
res.segment(block_idx, size) = x1; res.segment(block_idx, size) += x2;
|
||||
block_idx += size;
|
||||
res.segment(block_idx, size) = x1; res.segment(block_idx, size) -= x2;
|
||||
@ -196,6 +199,7 @@ struct complex_operators {
|
||||
block_idx += size;
|
||||
res.segment(block_idx, size) = x1; res.segment(block_idx, size).array() /= x2.array();
|
||||
block_idx += size;
|
||||
#endif
|
||||
|
||||
const T true_vector = T::Constant(true_value);
|
||||
const T false_vector = T::Constant(false_value);
|
||||
|
Loading…
Reference in New Issue
Block a user