Compiling Eigen library with nvcc (CUDA)
Asked Answered
D

3

5

I tried to compile following program (main.cu) with the nvcc (CUDA 5.0 RC):

#include <Eigen/Core>
#include <iostream>

int main( int argc, char** argv )
{
    std::cout << "Pure CUDA" << std::endl;
}

Unfortunately, I get a bunch of warnings and errors I can only explain using nvcc instead of the Microsoft compile.

Is this assumption right? Is there any way to compile Eigen with nvcc? (I actually don´t want to transfer Eigen matrices to the GPU, just access their members)?

If it should not work to compile Eigen with nvcc, is there a nice guide/tutorial about clever ways to seperate host and device code?

I am using CUDA 5.0 RC, Visual Studio 2008, Eigen 3.0.5. To compile the .cu file I used both, the rules file included in CUDA, aswell as the custom build step produced by CMake. Using the CUDA rule file, I targeted the build at compute capability 3.0.

Thanks for your advice.

PS: If I compile the same code with the host compiler it works perfectly.

Dawndawna answered 9/10, 2012 at 14:42 Comment(7)
nvcc isn't really meant to be a fully-fledged C++ compiler, so I wouldn't be surprised if it can't compile Eigen. If you only use the Eigen data types in the normal way on the CPU, you can just compile everything that uses CUDA seperately with nvcc and then link this to your actual program, which is otherwise compiled with your C++ compiler of choice. Works at least with GCC, I don't know about Visual Studio but don't know why it shouldn't work (except that it's Microsoft...).Greige
The part of the code I want to port to CUDA uses Eigen. It´s not that much, but I want a nice solution ... Especially I want to hide the copying of float pointers and that stuff ..Dawndawna
If you want to hide that kind of stuff you'll have to wrap your own handles anyway. I really can't see what parts of Eigen you would need in that part of your code; I would make this very simple and only deal with providing an interface between CUDA and proper CPU C++, and then program all the interesting stuff in safe high-level C++. (That worked quite nicely in this project of mine, which is rather a small-scale thing but might be quite similar to what you want.)Greige
ArrayFire is a fairly close Eigen implementation. See benchmarks of ArrayFire vs Eigen, here: accelereyes.com/products/benchmarks_arrayfire (I know this because I've worked on both Eigen and ArrayFire)Proboscidean
Can you provide some of the errors that you are seeing? If Eigen uses C++11, then that is not likely supported by nvcc. However for any less cutting-edge C++, nvcc should handle it fine -- it will pass the C++ host code to the host compiler.Crossbred
First error is: c:\program files\pcl 1.5.1\3rdparty\eigen\include\eigen\src/Core/VectorBlock.h(137) : error C2373: 'Eigen::DenseBase<Derived>::segment': New definition; different modifiers 1> c:\program files\pcl 1.5.1\3rdparty\eigen\include\eigen\src/Core/DenseBase.h(304): See declaration of 'Eigen::DenseBase<Derived>::segment' (someone installed a german VS2008 on my machine, so I translated the error messages ... )Dawndawna
Thanks for your hints up to now. I think I will just copy the data pointers, which I consider not the most beautiful solution ;)Dawndawna
S
3

NVCC invokes the normal host compiler but not before it has done some preprocessing, so it's likely that NVCC is struggling to parse the Eigen code correctly (especially if it uses C++11 features, but that's unlikely since you say VS2008 works).

I usually advise separating the device code and wrappers into the .cu files and leaving the rest of your application in normal .c/.cpp files to be handled by the host compiler directly. See this answer for some tips on getting this set up with VS2008.

Spelter answered 12/10, 2012 at 16:34 Comment(0)
D
2

It looks like one of the core contributors to Eigen is porting it to be compatible with CUDA. The idea would be to call it from kernel code.

Deedee answered 9/2, 2013 at 0:26 Comment(0)
V
2

Starting with Eigen 3.3, nvcc (7.5) succeeds in passing Eigen code to cl (MSVC 2013) (almost?) correctly. For example, the following code produces only 11 warnings:

#include <Eigen/Core>
#include <iostream>

int main()
{
    std::cout << "Hello Eigen\t";
    std::cout << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION << "\n";
    std::cout << "Hello nvcc\t";
    std::cout << __CUDACC_VER_MAJOR__ << "." << __CUDACC_VER_MINOR__ << "." << __CUDACC_VER_BUILD__ << "\n";
    return 0;
}

Output as expected (Eigen 3.3rc1):

Hello Eigen 3.2.94
Hello nvcc 7.5.17

But a long list of warnings (see post history if you actually want to see them).

Update:

Unfortunately, using CUDA 8.0 & VS2015 (with both Eigen 3.2.9 & Eigen 3.3rc1) results in compilation errors again:

"operator=" has already been declared in the current scope eigen\src\Core\Block.h 111
"operator=" has already been declared in the current scope eigen\src\Core\Ref.h 89

So close...

Update 2:

This has been fixed in commit 59db051 and is available by either using the development branch or waiting for v3.3 (or 3.3rc2) to actually come out.

Verlie answered 28/9, 2016 at 10:55 Comment(2)
Have you managed to get a Kernel, which actually uses e.g. Eigen::Vector3d, to run? I was not able to find this anywhere yet or implement a working MWE myself.Gatian
@GMueller I personally have not, but I haven't needed to. My issues were more like those of OP. Post what you've tried and I'm sure someone will be able to help you out.Verlie

© 2022 - 2024 — McMap. All rights reserved.