cudaMemset fails on __device__ variable

后端 未结 2 535
北荒
北荒 2021-01-25 04:51

I am having trouble using cudaMemset on a device variable. Is it possible to use the reference to the device variable for cudaMemset, or is it just a m

相关标签:
2条回答
  • 2021-01-25 05:12

    I believe you can also use cudaMemcpyFromSymbol: A function, such as the following kernel, can change the value of the variable declared in global memory (outside of the main function)

    __global__ void kernel1() { d_test = 1.0; }
    

    Inside your main, you can obtain the value using cudaMemcpyFromSymbol

    cudaMemcpyFromSymbol(&h_test,"d_test",sizeof(float),0,cudaMemcpyDeviceToHost);
    

    Of course, there is also cudaMemcpyToSymbol to change the value of the global variable.

    The idea came from here: Having problem assigning a device variable in CUDA

    0 讨论(0)
  • 2021-01-25 05:22

    Your problem is that d_test (as it appears in the host symbol table) isn't a valid device address and the runtime cannot access it directly. The solution is to use the cudaGetSymbolAddress API function to read the address of the device symbol from the context at runtime. Here is a slightly expanded version of your demonstration case which should work correctly:

    #include <stdio.h>
    #include <stdlib.h>
    #include <cuda_runtime.h>
    
    // device variable and kernel
    __device__ float d_test;
    
    inline void gpuAssert(cudaError_t code, char * file, int line, bool Abort=true)
    {
        if (code != cudaSuccess) {
            fprintf(stderr, "GPUassert: %s %s %d\n", cudaGetErrorString(code),file,line);
            if (Abort) exit(code);
        }       
    }
    
    #define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
    
    int main()
    {
    
        float * _d_test;
    
        gpuErrchk( cudaFree(0) );
        gpuErrchk( cudaGetSymbolAddress((void **)&_d_test, "d_test") );
        gpuErrchk( cudaMemset(_d_test,0,sizeof(float)) );
    
        gpuErrchk( cudaThreadExit() );
    
        return 0;
    }
    

    Here, we read the address of the device symbol d_test from the context into a host pointer _d_test. This can then be passed to host side API functions like cudaMemset, cudaMemcpy, etc.


    Edit to note that the form of cudaGetSymbolAddress shown in this answer has been deprecated and removed from the CUDA runtime API. For modern CUDA, the call would be:

    gpuErrchk( cudaGetSymbolAddress((void **)&_d_test, d_test) );
    
    0 讨论(0)
提交回复
热议问题