0

CURAND Library - Compiling Error - Undefined reference to functions

I suppose my understanding of linker flags is less than substantial as I don't understand how to use them. Do I need to put the code in my makefile for the program I am running it with? Can someone please explain by writing out the syntax and where I would need to put it? Also, can I simply put the curand.lib file from the CUDA library in the program folder I want to use it with and reference it from there?

Here is the code I am attempting to use to generate a random number for a raytracer program. Any help is greatly appreciated.

float drandGPU()
{

  std::size_t n = 1;
  std::size_t i;
  curandGenerator_t gen;
  float *devData, *hostData;

  hostData = (float*) calloc(n, sizeof(float));
  cudaMalloc((void**) &devData, n*sizeof(float));
  curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_MTGP32);
  curandSetPseudoRandomGeneratorSeed(gen, 1234ULL);
  curandGenerateUniform(gen,devData,n);
  cudaMemcpy(hostData, devData, n*sizeof(float), cudaMemcpyDeviceToHost);

  float f = hostData[0];
  return f;
}

EDIT: I am adding the makefile here:

all: exe

exe: pipe
    g++ -o rayTracer -D__PIKOC_HOST__ -I/usr/local/cuda/include -I../../api/include -I../.. -I. main.cpp -L/usr/local/cuda/lib -lcuda -lGL -lglut

pipe:
    ../../bin/pikoc --numRuns=10 --timer main.cpp

clean:
    rm -f rayTracer __pikoDefines.h __pikoCompiledPipe.h __pikoCompiledPipe.ptx
Community
  • 1
  • 1
Alex Elkman
  • 89
  • 1
  • 2
  • 12
  • What is your build environment? Is it Linux/OSX or Windows? – mty Jan 06 '15 at 05:51
  • Windows running on Linux through SSH ... so Linux (had to be more characters than simply "Linux", haha) – Alex Elkman Jan 06 '15 at 05:52
  • The [CUDA sample codes](http://docs.nvidia.com/cuda/cuda-samples/index.html#monte-carlo-estimation-of-pi--inline-prng-) include various CURAND codes and their associated makefiles. The only thing that should be necessary if compiling with `nvcc` is to add `-lcurand` at appropriate recipes in your makefile. – Robert Crovella Jan 06 '15 at 07:43

1 Answers1

0

On the Linux command line, you can use a Makefile to easily build your code. Assuming that your file is named main.cpp, here is a Makefile that should compile your code:

CUDA_ROOT=/usr/local/cuda
NVCC=$(CUDA_ROOT)/bin/nvcc
NVCC_FLAGS=-ccbin g++ -m64
NVCC_ARCH_FLAGS=-gencode arch=compute_20,code=sm_20 -gencode arch=compute_30,code=sm_30
NVCC_IFLAGS=-I$(CUDA_ROOT)/include -I$(CUDA_ROOT)/samples/common/inc
LFLAGS=-lcurand

all: main.exe

main.o: main.cpp
    $(NVCC) $(NVCC_FLAGS) $(NVCC_IFLAGS) $(NVCC_ARCH_FLAGS) -c $< -o $@

main.exe: main.o
    $(NVCC) $(NVCC_FLAGS) $(NVCC_ARCH_FLAGS) $< -o $@ $(LFLAGS)

clean:
    rm -f *.o

clobber: clean
    rm -f main.exe

All you need to do is to put the snippet above in a file named Makefile in the same directory with your code and type make.

A brief summary of what is going on here is:

The top part of the Makefile that has all-uppercase variables like CUDA_ROOT and NVCC are variable definitions. These variables are used below in compilation and linking using the dollar sign such as $(NVCC).

Here, the variable CUDA_ROOT is especially critical and it may be different depending on the Linux/CUDA installation you have. Mine is actually /usr/local/cuda-6.5 but it is also symlinked to /usr/local/cuda which I am using in the Makefile. You may need to change this variable. If you have the nvcc command available, typing which nvcc should give you this path with /bin/nvcc directory added to it.

Typing make calls the first target rule, which is all: main.exe, and main.exe's rule needs main.o, so it goes to main.o's rule. Thus compiling of the object file, main.o is the first step. There is no linking there, just compiling the .cpp file into .o object file. Then, once the main.o is compiled, main.exe is linked with it and the cuRAND library (hence the LFLAGS variable is included in the main.exe recipe).

I also changed the code you pasted to get some output as:

#include <curand_kernel.h>
#include <helper_cuda.h>
#include <iostream>

float drandGPU()
{
  std::size_t n = 1;
  std::size_t i;
  curandGenerator_t gen;
  float *devData, *hostData;

  hostData = (float*) calloc(n, sizeof(float));
  cudaMalloc((void**) &devData, n*sizeof(float));
  curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_MTGP32);
  curandSetPseudoRandomGeneratorSeed(gen, 1234ULL);
  curandGenerateUniform(gen,devData,n);
  cudaMemcpy(hostData, devData, n*sizeof(float), cudaMemcpyDeviceToHost);

  float f = hostData[0];
  return f;
}


int main()
{
  std::cout << drandGPU() << std::endl;
}

and named it main.cpp.

mty
  • 780
  • 6
  • 15
  • I will try and use this code to aid.. however there is already a Makefile I am working with and it is a bit different. I was wondering, will just having the curand.lib file be enough or does it need to access the entire library? If so, this is slightly problematic as I am running on an SSH from a remote computer... – Alex Elkman Jan 06 '15 at 07:39
  • Yes, Makefile may look totally different and it will still do the same job. The one I wrote above is a relatively simple one for the sake of understandability. The ones in Nvidia samples are quite sophisticated. Good luck! – mty Jan 06 '15 at 07:50
  • Where are you running the code and where are you compiling it? You need to have CUDA toolkit installed on both but you have to have a CUDA card only on the one that you are running. – mty Jan 06 '15 at 07:52
  • I'm really not running anything on my computer, I kind of doubt I even need the toolkit installed on my computer at all (even though I do anyway). It's a remote setup and I do believe the computers have the CUDA toolkit installed. Assuming all of this is correct, then fixing the makefile *should* fix the problem. – Alex Elkman Jan 06 '15 at 07:56
  • Exactly, if the remote computer has a CUDA-compatible card and has CUDA toolkit installed, you don't have to worry about anything on your computer. You can run it remotely through your SSH connection. You can paste the error you encounter when you use the Makefile above together with the source code in the same directory named as main.cpp, and I'll try to help. – mty Jan 06 '15 at 07:59
  • Okay thanks a lot. I need to talk to my professor about the toolkit tomorrow because I am not seeing the files there, and I'm starting to think I may have been incorrect about it's presence. So don't expect another post from me until tomorrow afternoon at the earliest. I appreciate your help! – Alex Elkman Jan 06 '15 at 08:16
  • Ok sorry for such a late reply. I found out the computer does have the libary... I edited my original post and added the makefile into it. – Alex Elkman Jan 13 '15 at 02:19
  • I am encountering some other problems. I don't think it is using the nvcc commands properly. I am geting errors and statments that it doesn't know the cuda commands. – Alex Elkman Jan 13 '15 at 03:09
  • @AlexElkman it will perhaps be best if you can ask a new question, with all the edits and comments, this one got quite complicated! – mty Jan 13 '15 at 03:42