cudaMemcpyToSymbol in pycuda

I am using pycuda and i would like to know if there is an equivalent to the function cudaMemcpyToSymbol

I would like to copy a constant from the host to the device like below

import pycuda.driver as cuda
import pycuda.autoinit
from pycuda.compiler import SourceModule
import numpy 
from sys import path
from struct import *
from gpustruct import GPUStruct


if __name__ == '__main__':

    # list devices
    ndevices = cuda.Device.count()
    print '{} devices found'.format(ndevices)
    for i in xrange(ndevices):
        print '  ', cuda.Device(i).name()





    # compile device.cu
    mod = SourceModule('''
    __device__ __constant__ int CONSTd;
    struct Results
        {
         float *A; 
     float *B;
     float *C;
        };

    struct fin
        {
         float *N;
        };

__global__ void  test(Results *src,fin *dest){
    int i=blockIdx.x *blockDim.x + threadIdx.x;
    src->C[i]=src->A[i]+src->B[i]+dest->N[i]+CONSTd;

    }''',
            nvcc='/opt/cuda65/bin/nvcc',
           )

kern = mod.get_function("test")




CONSTANTE=5
src_gpu = GPUStruct([(numpy.int32,'*A', numpy.ones(10,dtype=numpy.int32)),(numpy.int32,'*B', numpy.ones(10,dtype=numpy.int32)),(numpy.int32,'*C', numpy.zeros(10,dtype=numpy.int32))])
test_gpu = GPUStruct([(numpy.int32,'*N', numpy.array(10*[5],dtype=numpy.int32))])

#something like this:
**cudaMemcpyToSymbol(CONSTd, &CONSTANTE, sizeof(int));**

src_gpu.copy_to_gpu() 
test_gpu.copy_to_gpu() 
kern(src_gpu.get_ptr(),test_gpu.get_ptr(),block=(10,1,1),grid=(1,1))
src_gpu.copy_from_gpu()

print(src_gpu)

Answer

The PyCUDA implementation directly follows the CUDA driver API, so you can use any driver API code you can find as a model, but there are two things required to make this work:

  1. Use the module function module.get_global() to retrieve the device pointer to the symbol within the compiled source module
  2. Use driver.memcpy_htod to copy values to that pointer. Note that the PyCUDA APIs require that objects support the Python buffer protocol. In practice this means you should be using numpy.ndarray or similar on the Python side.

This is effectively what cudaMemcpyToSymbol does under the hood.

Leave a Reply

Your email address will not be published. Required fields are marked *