【问题标题】:Generating single random number in pyCuda kernel在 pyCuda 内核中生成单个随机数
【发布时间】:2021-09-11 12:00:46
【问题描述】:

我见过很多生成随机数数组的方法。但我想生成一个随机数。 c++ 中有没有像 rand() 这样的函数。我不想要一系列随机数。我只需要在内核中生成一个随机数。有没有生成随机数的内置函数?我已经尝试了下面给定的代码,但它不起作用。

import numpy as np
import pycuda.autoinit
from pycuda.compiler import SourceModule
from pycuda import gpuarray

code = """
    #include <curand_kernel.h>
       __device__ float getRand()
       {
          curandState_t s;
          curand_init(clock64(), 123456, 0, &s);
          return curand_uniform(&s);
       }

        __global__ void myRand(float *values)
        {
          values[0] = getRand();
        }
"""


mod = SourceModule(code)
myRand = mod.get_function("myRand")
gdata = gpuarray.zeros(2, dtype=np.float32)
myRand(gdata, block=(1,1,1), grid=(1,1,1))
print(gdata)

错误是这样的:

/usr/local/cuda/bin/../targets/x86_64-linux/include/curand_poisson.h(548): error: this declaration may not have extern "C" linkage

/usr/local/cuda/bin/../targets/x86_64-linux/include/curand_discrete2.h(69): error: this declaration may not have extern "C" linkage

/usr/local/cuda/bin/../targets/x86_64-linux/include/curand_discrete2.h(78): error: this declaration may not have extern "C" linkage

/usr/local/cuda/bin/../targets/x86_64-linux/include/curand_discrete2.h(86): error: this declaration may not have extern "C" linkage

30 errors detected in the compilation of "kernel.cu".

【问题讨论】:

    标签: python cuda random-seed pycuda


    【解决方案1】:

    基本问题是,默认情况下,PyCUDA silently applies C linkage 将所有代码编译到 SourceModule 中。如错误所示,cuRand 需要 C++ 链接,所以 getRand 不能有 C 链接。

    您可以通过更改以下两行来解决此问题:

    mod = SourceModule(code)
    myRand = mod.get_function("myRand")
    

    mod = SourceModule(code, no_extern_c=True)
    myRand = mod.get_function("_Z6myRandPf")
    

    这会禁用 C 链接,但确实意味着您需要向 get_function 调用提供 C++ 错位名称。您将需要查看详细的编译器输出或在 PyCUDA 之外编译代码以获得该名称(例如 Godbolt)。

    您也可以像这样修改代码:

    import numpy as np
    import pycuda.autoinit
    from pycuda.compiler import SourceModule
    from pycuda import gpuarray
    
    code = """
           #include <curand_kernel.h>
    
           __device__ float getRand()
           {
              curandState_t s;
              curand_init(clock64(), 123456, 0, &s);
              return curand_uniform(&s);
           }
            
            extern "C" {
            __global__ void myRand(float *values)
            {
              values[0] = getRand();
            }
            }
    """
    
    
    mod = SourceModule(code, no_extern_c=True)
    myRand = mod.get_function("myRand")
    gdata = gpuarray.zeros(2, dtype=np.float32)
    myRand(gdata, block=(1,1,1), grid=(1,1,1))
    print(gdata)
    

    这使内核具有 C 链接,但不涉及使用 cuRand 的设备函数。

    【讨论】:

      【解决方案2】:

      你可以在 python 中import random 。并使用random.randint()。通过在函数中定义范围来生成指定范围内的随机数。前random.randint(0,50)

      【讨论】:

      • 我想在内核中生成随机数,而不是在 python 中。实际上,我已经用 C++/C 编写了很多代码,我需要在内核中生成一个随机数来完成我的任务。
      猜你喜欢
      • 2021-09-08
      • 2019-08-11
      • 1970-01-01
      • 2013-09-01
      • 2019-08-12
      • 2019-07-27
      • 2019-06-27
      • 1970-01-01
      相关资源
      最近更新 更多