Link error with R.dll
I’ve taken a crack at compiling the R package gputools on Windows, but I hit a bit of a roadblock. I’ll describe the steps I’ve taken below, hopefully someone will be able to suggest a way forward.
Some background: gputools provides an interface between R and CUDA, the nVidia API for executing code on a graphics card (GPU). On Linux or Mac OS, installation is fairly straightforward because the CUDA compiler nvcc depends on gcc or clang, respectively. However, interfacing between R and CUDA on Windows is an unsolved problem, since the respective toolchains are fundamentally incompatible. The only supported toolchain for compiling R on Windows is MinGW with gcc and gfortran. On the other hand, the nVidia CUDA Toolkit requires certain specific versions of Microsoft Visual Studio.
I installed Visual Studio Community 2013 and nVidia Toolkit 7.5.18 for Windows 10. You can fool the gputools configure script by running it inside a Cygwin64 terminal. This enables you to generate a Makefile for gcc + nvcc, but of course this won’t actually work as I’ve explained above. There are some Makefile entries that you will need to edit manually, as follows:
NVCC = nvcc CUDA_LIB = $(CUDA_HOME)/lib/x64 R_LIB = -L"$(R_HOME)/bin/x64" -lR CFLAGS = -O2 -Wall TARGETS = gputools.dll
Before you run make, add cl.exe to your PATH so that nvcc can find it:
set PATH=%PATH%;C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin
You will also need to create a file vcvars64.bat in the directory VC\bin\amd64, containing only a single line:
CALL setenv /x64
Unfortunately, there is some unportable code in qrdecomp.cu and cuseful.cu that won’t compile in cl:
qrdecomp.cu(802): error: expression must have a constant value qrdecomp.cu(803): error: expression must have a constant value 2 errors detected in the compilation of "qrdecomp.cpp1.ii". make: *** [qrdecomp.o] Error 2 ../VC/INCLUDE\xlocale(1610): error: identifier "_First1" is undefined ../VC/INCLUDE\xlocale(1610): error: identifier "_Last1" is undefined ../VC/INCLUDE\xlocale(1610): error: identifier "_Count" is undefined ../VC/INCLUDE\xlocale(1845): error: identifier "_First1" is undefined ../VC/INCLUDE\xlocale(1845): error: identifier "_Last1" is undefined ../VC/INCLUDE\xlocale(1845): error: identifier "_Count" is undefined 6 errors detected in the compilation of "cuseful.cpp1.ii". make: *** [cuseful.o] Error 2
For qrdecomp.cu, you need to allocate the arrays using Calloc (and deallocate using Free). For cuseful.cu, the problem is with STL std::string. I chose to work around this problem using good old char* instead. Most of the calls to that private method use .c_str() anyway. If cl had an equivalent compile flag to -std=gnu99 then these changes wouldn’t be necessary.
This is where I hit the final problem, which currently has me stumped:
cuseful.o : error LNK2019: unresolved external symbol Rprintf referenced in function "void __cdecl printMat(int,int,float const *,char const *)" (?printMat@@YAXHHPEBMPEBD@Z) gputools.dll : fatal error LNK1120: 15 unresolved externals make: *** [gputools.dll] Error 2
The version of R that I have installed provides R.dll, but not R.lib. I tried using pexports to create a .def file, but I still end up with unresolved externals as above. It is possible that the only way around this is to compile my own copy of R.dll from source.