CUdeviceptr should be typdedef'd as void *, instead of unsigned int

I have a question. Isn’t it appropriate to have CUdeviceptr typedef’ed as “void *” instead of “unsigned int”, so that it works on both 32 and 64 bit systems transparently?

This is the use case.

On both 32 and 64 bit systems -

unsigned int is 4 bytes on both the cpu and gpu

void * is 8 bytes on both the cpu and gpu.

Now let us assume you want to pass a CUdeviceptr to the gpu as member of a buffer(which is a structure). Something like this -

typdef struct buffer {

	int a;

	CUdeviceptr p;

	int c;

} buffer;

We create an instance of this above buffer, then assign the buffer->p with a CUdeviceptr value and send this buffer to the gpu. Inside the gpu, we de-reference this buffer using this structure -

typedef struct buffer {

	int a;

	int *p;

	int c;

} buffer;

Now on 32 bit systems this won’t be an issue, since a “pointer” and “unsigned int”(which is the typedef of CUdeviceptr) are both 4 bytes and hence we don’t see any alignment issues, since on both the cpu and the gpu the structure members are aligned on 4 bytes.

But on 64 bit systems, CUdeviceptr is typedef’ed to “unsigned int” in cuda.h just like how it is in 32 bit systems and unsgined int is 4 bytes on 64 bit systems.

So for 64 bit systems, on the cpu, the alignment of buffer->p ; buffer->c is on 4 byte boundaries.

But on the gpu, buffer->p is aligned on a 8 byte boundary and so is buffer->c, since buffer->p is a pointer, and the gpu treats a pointer as 8 bytes. Because of this we end up referencing junk values on the gpu for buffer->p and buffer->c. This can be solved, if both the cpu and the gpu recognize the member as of the same type, i.e. a pointer and this can be done if we set CUdeviceptr as void *, instead of unsigned int.

There is an alternate solution to the above issue, but I feel it is not the right solution and just a means to get things working.

The way to solve this is, to redefine the structure on the gpu to this -

typedef struct buffer {

	int a;

	unsigned int p;

	int c;

} buffer;

and cast buffer->p to a int * pointer. But defining the structure this way on the gpu, removes the transparency in the typedef of CUdeviceptr and forces us to get into the inner details of the CUdeviceptr definition. If any changes are made to this typdef in a newer release, it will involve us changing this definition in all our kernel versions.

I have code that explains this issue further. Any insight on this would be really appreciated.

Do not do this ever. It is a recipe for badness, especially with future versions of CUDA.

I’m sorry. I didn’t get you there. Do not do what?

My question was whether the right typedef for CUdeviceptr is void * instead of unsigned int, and should nvidia change it to void * in future releases of cuda? I have code that explains this issue as well, in case someone wants it.

Found an old post which deals with the same question -

http://forums.nvidia.com/index.php?showtopic=88456

Thanks

It is specifically unsigned int and not void*. Typedefing it to void* may cause very horrible things to occur because the driver treats CUdeviceptr as an unsigned int at all times.