Re: [eigen] Re: How to use Eigen in CUDA kernels for eigendecomposition? |
[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]
Dear list,
I am very sorry. I didn't compile the example with the latest development version but some outdated
version from a GitHub mirror. With the latest version from BitBucket it compiles without these
loads of __host__ __device__ warnings. A few warnings are left however, namely
eigen/Eigen/src/Core/MathFunctions.h(1265): warning: calling a constexpr __host__ function("real")
from a __host__ __device__ function("abs") is not allowed. The experimental flag '--expt-relaxed-
constexpr' can be used to allow this.
eigen/Eigen/src/Core/MathFunctions.h(1265): warning: calling a constexpr __host__ function("imag")
from a __host__ __device__ function("abs") is not allowed. The experimental flag '--expt-relaxed-
constexpr' can be used to allow this.
eigen/Eigen/src/Core/MathFunctions.h(1265): warning: calling a constexpr __host__ function from a
__host__ __device__ function is not allowed. The experimental flag '--expt-relaxed-constexpr' can be
used to allow this.
eigen/Eigen/src/Core/MathFunctions.h(1265): warning: calling a constexpr __host__ function from a
__host__ __device__ function is not allowed. The experimental flag '--expt-relaxed-constexpr' can be
used to allow this.
eigen/Eigen/src/Core/MathFunctions.h(1270): warning: calling a constexpr __host__ function("real")
from a __host__ __device__ function("abs") is not allowed. The experimental flag '--expt-relaxed-
constexpr' can be used to allow this.
eigen/Eigen/src/Core/MathFunctions.h(1270): warning: calling a constexpr __host__ function("imag")
from a __host__ __device__ function("abs") is not allowed. The experimental flag '--expt-relaxed-
constexpr' can be used to allow this.
eigen/Eigen/src/Core/MathFunctions.h(1270): warning: calling a constexpr __host__ function from a
__host__ __device__ function is not allowed. The experimental flag '--expt-relaxed-constexpr' can be
used to allow this.
eigen/Eigen/src/Core/MathFunctions.h(1270): warning: calling a constexpr __host__ function from a
__host__ __device__ function is not allowed. The experimental flag '--expt-relaxed-constexpr' can be
used to allow this.
This is slightly concerning. Did I forget to define a function? Because
thrust::abs(thrust::complex<T> const&) already exists.
Cheers, Henri
On Sun, 2017-07-02 at 13:01 +1200, Henri Menke wrote:
> Dear list,
>
> This is my first post to the list and I would like to use it to thank all the developers for their
> astonishing work. Keep it up guys!
>
> Now to my problem: I am using the latest development version of Eigen and I want to calculate the
> eigendecomposition of a matrix in a CUDA kernel.
>
> I followed »Using custom scalar types« (http://eigen.tuxfamily.org/dox-3.2/TopicCustomizingEigen. h
> tm
> l#CustomScalarType) to implement support for thrust::complex.
>
> The example below compiles but is unusable. The approximately 800 lines of nvcc V8.0.61 output
> can
> be view at https://gist.github.com/anonymous/ . There, I see a lot757218ae4daec63ed021b143a38e76 b0
> of warnings which involve calling a __host__ function from a __host__ __device__ function. It
> appears to me that some functions are not correctly decorated (yet). I am very interested in
> helping to fix this but have so far not worked with the internals of Eigen's _expression_ template
> code. Could you please provide some help?
>
> Best regards,
> Henri
>
> ---
>
> The compile command line is simply
> $ nvcc -std=c++11 -I/path/to/eigen/ test.cu
>
>
> #include <iostream>
> #include <thrust/complex.h>
> #include <Eigen/Eigenvalues>
>
> static void HandleError(cudaError_t err, const char *file, int line)
> {
> if (err != cudaSuccess)
> {
> std::cerr << cudaGetErrorString(err) << " in " << file << ' ' << line << '\n';
> exit(EXIT_FAILURE);
> }
> }
> #define HANDLE_ERROR(err) (HandleError(err, __FILE__, __LINE__))
>
>
> namespace Eigen {
> template<typename _Real> struct NumTraits<thrust::complex<_Real> >
> : NumTraits<std::complex<_Real> >
> {
> typedef _Real Real;
> typedef typename NumTraits<_Real>::Literal Literal;
> enum {
> IsComplex = 1,
> RequireInitialization = NumTraits<_Real>::RequireInitialization,
> ReadCost = 2 * NumTraits<_Real>::ReadCost,
> AddCost = 2 * NumTraits<Real>::AddCost,
> MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
> };
> };
> }
>
>
> namespace thrust {
> template < typename T >
> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
> T real(complex<T> const& x) { return x.real(); }
>
> template < typename T >
> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
> T imag(complex<T> const& x) { return x.imag(); }
> }
>
>
> __global__ void test_kernel(int n, float * r) {
> typedef Eigen::Matrix<thrust::complex<float>,2,2> cuMatrixXcf;
>
> cuMatrixXcf m;
> m << 1,0, 0,1;
> m *= threadIdx.x;
>
> Eigen::SelfAdjointEigenSolver< cuMatrixXcf > solver;
> solver.compute(m, Eigen::EigenvaluesOnly);
>
> auto const& D = solver.eigenvalues();
>
> for (int i = 0; i < n; ++i)
> r[n*threadIdx.x + i] = D(i);
> }
>
>
> int main()
> {
> float * r;
> HANDLE_ERROR( cudaMalloc(&r, 4*10*sizeof(float)) );
>
> test_kernel<<<10,1>>>(4,r);
>
> std::vector<float> ev(4*10);
> HANDLE_ERROR( cudaMemcpy(ev.data(), r, 4*10*sizeof(float), cudaMemcpyDeviceToHost) );
>
> for (auto const& p : ev)
> std::cout << p << ' ';
> std::cout << '\n';
> }
Mail converted by MHonArc 2.6.19+ | http://listengine.tuxfamily.org/ |