Runtime #include files also needlessly define device types?

I’m trying to call cudaGetDeviceCount and cudaDeviceProperties from my main.c code, compiled with GCC. I don’t use any other functions, this is just to see if there’s a supported CUDA device. All my runtime kernel launch and kernel itself are in a kernel.cu file which is compiled with nvcc and linked.

The problem is that I can’t use cudaGetDeviceCount() without including its header file, cuda_runtime_api.h .
But including that causes a chain of subincludes, which define many unneeded device specific types like float3… which has typename collisions with types in my main code.

Is it proper to be calling cudaGetDeviceCount() from a .c file that’s not compiled with NVCC?
Or is it fine but CUDA’s header files are not organized well and are bringing in lots of unneeded type definitions?

A workaround would for me to make my own function wrappers in my .cu files and call those wrappers from my .c code but that seems so ugly and arbitrary. And it gets worse since I want to examine the elements of the deviceProperties structure… it gets crazy to make a wrapper call for a getter for each structure element just to see what it’s set to!

I hope i’m missing something stupid… any ideas?

Why not just use the driver API, then?

Good idea but nope.

To get the definitions for cudaGetDeviceCount(), you must include “cuda_runtime_api.h”.

It’s not defined in any other header file.

But cuda_runtime_api.h includes other files, like “cuda_builtin_types.h” which then loads all kinds of new things like

“device_types.h” and “vector_types.h”. Now you have all these typedefs and class definitions in global namespace like float3 which are not used or needed by the simple host function cudaGetDeviceCount() you’re interested in.

So it starts to look like a bad header layouts.

I like the snappier, pithier reply you had earlier better…

There is a pair of equivalent driver API functions cuDeviceGetCount and cuDeviceGetAttribute that return the same information as the two runtime API functions you are using now. Use those and you can bypass the whole runtime API header import and eliminate the type conflicts from stuff you don’t need.