Reputation: 127
I'm trying to compile a CUDA example which has;
cuda.cu:
__constant__ unsigned VERTICES;
__constant__ unsigned TRIANGLES;
and the corresponding code in main.cpp;
cudaMemcpyToSymbol(VERTICES, &verticesNo, sizeof(int));
cudaMemcpyToSymbol(TRIANGLES, &trianglesNo, sizeof(int));
How to avoid "VERTICES not declared in this scope" error when compiling the main.cpp?
TIA.
cheers,
Upvotes: 1
Views: 1319
Reputation: 346
CUDA is defined by the nvcc compiler which itself is an extension of C99. It sounds like what you really want to do is separate out CUDA so you have a generic header file. You could then use it from C or C++. I prefer to work with data in C++ personally, and as such I have found best way to do this is the following files and include paths:
WRAPPER_HEADER.h CUDA_HEADER.cuh
/ \ / \
/ \ / \
#include #include #include #include
/ \ / \
/ \ / \
/ \ / \
CALL.cpp/CALL.c CUDA_WRAPPER.cu CUDA_KERNEL.cu
CALL.c/CALL.cpp is C/C++ containing whatever you want that will call the wrapper function
CUDA_WRAPPER.cu is the wrapper function which:
WRAPPER_HEADER.h contains a C version of:
CUDA_HEADER.cuh contains:
__constant__
memory that the wrapper can write to via cudaMemcpyToSymbol(...)__global__
specifierCUDA_KERNEL.cu contains:
__global__
void kernel(...) function__device__
specifier__shared__
memory (it only has lifetime of a block so cannot be called from a wrapper based on what I can tell... feel free to correct this anyone)There is some of this demonstrated in the CUDA literature and I like it because it really separates out CUDA C as the specialized language it is. It is only necessary when you are dealing with setting up and running the kernels.
Upvotes: -1
Reputation: 1809
CUDA __constant__
variables have a file scope linkage. That means that the cudaMemcpyToSymbol
have to be in the same .cu file where the __constant__
variable is defined.
You can add a wrapper function to the .cu file and call this one from your .cpp file.
sample for cuda.cu:
__constant__ unsigned VERTICES;
__constant__ unsigned TRIANGLES;
void wrapper_fn(unsigned *verticesNo, unsigned *trianglesNo)
{
cudaMemcpyToSymbol(VERTICES, verticesNo, sizeof(unsigned));
cudaMemcpyToSymbol(TRIANGLES, trianglesNo, sizeof(unsigned));
}
Then only call wrapper_fn
in your main.cpp.
Upvotes: 4