Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you include standard CUDA libraries to link with NVRTC code?

Tags:

c

cuda

gpu

nvrtc

Specifically, my issue is that I have CUDA code that needs <curand_kernel.h> to run. This isn't included by default in NVRTC. Presumably then when creating the program context (i.e. the call to nvrtcCreateProgram), I have to send in the name of the file (curand_kernel.h) and also the source code of curand_kernel.h? I feel like I shouldn't have to do that.

It's hard to tell; I haven't managed to find an example from NVIDIA of someone needing standard CUDA files like this as a source, so I really don't understand what the syntax is. Some issues: curand_kernel.h also has includes... Do I have to do the same for each of these? I am not even sure the NVRTC compiler will even run correctly on curand_kernel.h, because there are some language features it doesn't support, aren't there?

Next: if you've sent in the source code of a header file to nvrtcCreateProgram, do I still have to #include it in the code to be executed / will it cause an error if I do so?

A link to example code that does this or something like it would be appreciated much more than a straightforward answer; I really haven't managed to find any.

like image 588
Billy Smith Avatar asked Oct 17 '16 13:10

Billy Smith


People also ask

Where is cuda Toolkit installed?

By default, the CUDA SDK Toolkit is installed under /usr/local/cuda/. The nvcc compiler driver is installed in /usr/local/cuda/bin, and the CUDA 64-bit runtime libraries are installed in /usr/local/cuda/lib64.

What is Nvrtc?

Introduction. NVRTC is a runtime compilation library for CUDA C++. It accepts CUDA C++ source code in character string form and creates handles that can be used to obtain the PTX.


1 Answers

You have to send the "filename" and the source of each header separately.

When the preprocessor does its thing, it'll use any #include filenames as a key to find the source for the header, based on the collection that you provide.

I suspect that, in this case, the compiler (driver) doesn't have file system access, so you have to give it the source in much the same way that you would for shader includes in OpenGL.

So:

  • Include your header's name when calling nvrtcCreateProgram. The compiler will, internally, generate the equivalent of a std::map<string,string> containing the source of each header indexed by the given name.

  • In your kernel source, use #include "foo.cuh" as usual.

  • The compiler will use foo.cuh as an index or key into its internal map (created when you called nvrtcCreateProgram), and will retrieve the header source from that collection

  • Compilation proceeds as normal.

One of the reasons that nvrtc provides only a "subset" of features is that the compiler plays in a somewhat sandboxed environment, without necessarily having all of the supporting tools and utilities lying around that you have with offline compilation. So, you have to manually handle a lot of the stuff that the normal nvcc + (gcc | MSVC| clang) combination provides.

A possible, but non-ideal, solution would be to preprocess the file that you need in your IDE, save the result and then #include that. However, I bet there is a better way to do that. if you just want curand, consider diving into the library and extracting the part you need (blech) or using another GPU-friendly rand implementation. On older CUDA versions, I just generated a big array of random floats on the host, uploaded it to the GPU, and sampled it in the kernels.

This related link may be helpful.

like image 91
3Dave Avatar answered Sep 17 '22 14:09

3Dave