Using the dynlink API

Hi, I’m having some problems using the cuda_drvapi_dynlink files from C\common\inc in the 4.0 SDK. I ran into a number of problems with this:

  • I need the D3D9 integration, but only three functions (cuD3D9GetDevice, cuD3D9CtxCreate and cuGraphicsD3D9RegisterResource) are loaded in the source file.
  • Moreover, none of the D3D functions are declared as externals in the header file (cuda_drvapi_dynlink_d3d.h)
  • Finally, after fixing these issues, it turns out that a few functions have v2 variants (including cuD3D9CtxCreate) in the 4.0 driver. (This is especially nasty since it seems to work OK but gives invalid context errors on certain function calls.)

What I’m wondering now is if there are better versions of these files available somewhere? Or is this API just a novelty feature not used by anyone?
Another question is what the second argument to cuInit should be? Ideally I want my application (that is dynamically loading nvcuda.dll) to work with both version 3.2 and 4.0 (and as many more as possible) API versions, so how do I do that? If I just hardcode the second argument to 4000 it will break on v3.2 because it tries to load v2 versions of cuCtxDestroy among others. Is it even possible to make my code work with different versions without externally specifying which cuda version is installed on the system?

Sorry for the barrage of questions, I just fail to find any documentation of this, and googling turns up nothing. Any help is appreciated!

Thanks,
/Emil

As a disclaimer, I’ve never used the cuda_drvapi_dynlink files, but cuInit only takes 1 argument (for flags), and according to cuda.h, only takes an argument of 0 at the moment.

/**

 * \brief Initialize the CUDA driver API

 *

 * Initializes the driver API and must be called before any other function from

 * the driver API. Currently, the \p Flags parameter must be 0. If ::cuInit()

 * has not been called, any function from the driver API will return

 * ::CUDA_ERROR_NOT_INITIALIZED.

 *

 * \param Flags - Initialization flag for CUDA.

 *

 * \return

 * ::CUDA_SUCCESS,

 * ::CUDA_ERROR_INVALID_VALUE,

 * ::CUDA_ERROR_INVALID_DEVICE

 * \notefnerr

 */

CUresult CUDAAPI cuInit(unsigned int Flags);

if you want to check what version of cuda is current on the system, check the __CUDA_API_VERSION (or use cuDriverGetVersion), so if it comes to it you can always conditionally load the appropriate file(s) based on that. Also, I don’t see why the v2 variants would be giving context errors. What function calls generate context errors?

Actually, the dynlink variety takes a second version argument:

extern CUresult CUDAAPI cuInit(unsigned int, int cudaVersion);

This version is used together with the version obtained from calling cuDriverGetVersion() and __CUDA_API_VERSION to determine which function pointers to load from the DLL (and in some cases whether to load the v1 or v2 variety).

My calling sequence is this (simplified):

  1. cuInit

  2. cuD3D9CtxCreate

  3. cuCtxPopCurrent

  4. cuCtxPushCurrent

  5. cuMemGetInfo <-- Here I get a CUDA_ERROR_INVALID_CONTEXT

Calling cuCtxGetApiVersion on the context created in step 2 returns 3010, while it returns 3020 for “pure” cuda contexts. This is solved by loading cuD3D9CtxCreate_v2 instead (the stock version of cuda_drvapi_dynlink loads v1). My problem is that I don’t know for which driver versions to load v2, and when to load v1. I am also unsure whether there could be more traps like these hidden in the dynlink files that I haven’t discovered yet.

To elaborate a bit on my environment, we’re producing a library using CUDA through the dynlink API (this is to be able to run on systems without CUDA drivers installed). The user of the library might link to CUDA statically, and I want this to work regardless of what CUDA version they have linked against. Our library can reuse existing cuda context created by the calling application, so the API versions must match for this to work. I’m guessing that I should let the calling application pass the cuda version it uses to my library for use in the cuInit call, can anyone confirm or deny this?