Undefine references of functions from CUDA

Viewed 194

I am looking for a way to use cufft.h a CUDA toolkit which perform GPU parallelization of fast fourier transform.

First of all, I downloaded cuda library and cufft through synaptic. Then I used the sample program from the cufft documentation from NVidia.
my cuda library is located at /usr/local/cuda-9.0 on my laptop.

I added those include :

1 #include <iostream>
2 #include <cstdio>
3 #include "/usr/local/cuda-9.0/include/cuda.h"
4 #include "/usr/local/cuda-9.0/include/cuda_runtime_api.h"
5 #include "/usr/local/cuda-9.0/include/cufft.h"

I compile like this :

g++ -Wall main.cpp -o main

and get undefine references error for each cuda-like functions (cudaMalloc,cudaGetLastError, etc...)

I am pretty young about library implementation and I don't understand what should I do to include properly this cuda-cufft library...

The nvidia documentation talk about filename.cu but I don't know what this is about...

Thank you for your time :)

n.b : I added cuda.h and cuda_runtime_api.h after reading a forum (I forgot which it was). Apparently, only cuda_runtime_api.h is necessary (I tried without cuda.h and get the same errors).

1 Answers

Here is a complete sample code (that doesn't do anything useful) and a sample g++ compile command that will properly compile and link the code:

$ cat t1338.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cuda_runtime.h>
#include <cufft.h>

int main() {
    size_t work_size;

    int fft_sz = 32;            // Size of each FFT
    int num_ffts = 1;         // How many FFTs to do

    cufftComplex *in_buf_h, *in_buf_d, *out_buf_d;

    // Allocate buffers on host and device
    in_buf_h = new cufftComplex[fft_sz*num_ffts];
    cudaMalloc(&in_buf_d, fft_sz*num_ffts*sizeof(cufftComplex));
    cudaMalloc(&out_buf_d, fft_sz*num_ffts*sizeof(cufftComplex));
    cudaMemset(out_buf_d, 0, fft_sz*num_ffts*sizeof(cufftComplex));
    // Fill input buffer with zeros and copy to device
    memset(in_buf_h, 0, fft_sz*num_ffts*sizeof(cufftComplex));
    cudaMemcpy(in_buf_d, in_buf_h, fft_sz*num_ffts*sizeof(cufftComplex), cudaMemcpyHostToDevice);

    // Plan num_ffts of size fft_sz
    cufftHandle plan;
    cufftCreate(&plan);
    cufftMakePlan1d(plan, fft_sz, CUFFT_C2C, num_ffts, &work_size);

    // Execute the plan. We don't actually care about values.
    cufftExecC2C(plan, in_buf_d, out_buf_d, CUFFT_FORWARD);

    // Sync the device to flush the output
    cudaDeviceSynchronize();

    return 0;
}
$ g++ t1338.cpp -I/usr/local/cuda/include -L/usr/local/cuda/lib64 -lcudart -lcufft
$

Your include statements are probably OK as-is, but I have used a format that says "search on the standard path for this file" and then I identify an addition to the standard path with

-I/usr/local/cuda/include

However your compile command is definitely missing the necessary link apparatus. You need to specify where to find the libraries (the path) with -L and then indicate the specific libraries to include, which are both the CUDA runtime library (-lcudart) and also the CUFFT library (-lcufft):

-L/usr/local/cuda/lib64 -lcudart -lcufft

The CUDA toolkit normally gets installed with sample codes which will have sample Makefiles you can inspect, or just compile those projects to see typical compilation command usage.

As I mentioned, this source code is incomplete. It doesn't do anything useful. It is just to demonstrate proper compilation behavior. In particular, I've omitted proper error checking, which I recommend you include in your actual codes.

Depending on whether your install created a symbolic link or not, you may need to change the above paths to:

-I/usr/local/cuda-9.0/include

and

-L/usr/local/cuda-9.0/lib64 -lcudart -lcufft
Related