Как генерировать гауссовский шум в исходном модуле pycuda?

#python #gaussian #pycuda

Вопрос:

Я пытаюсь сгенерировать случайное число в соответствии с законом Гаусса со средним значением и стандартным отклонением. На данный момент я пишу этот код.

 import pycuda.driver as cuda
import pycuda.autoinit
from pycuda.compiler import SourceModule
import numpy as np
import matplotlib.pyplot as plt
import time


class GN:
    def __init__(self, ):
        self.NbCells = int(1024 * 100)
        self.init_vectors()
        self.Create_GPU_SourceModule()
        BLOCK_SIZE = 1024
        self.grid = (int(self.NbCells / BLOCK_SIZE), 1, 1)
        self.block = (BLOCK_SIZE, 1, 1)

    def put_vect_on_GPU(self, Variable):
        Variable_gpu = cuda.mem_alloc(Variable.nbytes)
        cuda.memcpy_htod(Variable_gpu, Variable)
        return Variable_gpu

    def init_vectors(self):
        self.V = self.put_vect_on_GPU(np.zeros((self.NbCells), dtype=np.float32))
        self.m = self.put_vect_on_GPU(np.ones((self.NbCells), dtype=np.float32) * 120)
        self.s = self.put_vect_on_GPU(np.ones((self.NbCells), dtype=np.float32) * 60)

    def Create_GPU_SourceModule(self):  #
        self.mod = SourceModule("""
        #include <math.h> 
        #include <curand.h>
        #include <cuda.h>
        
      __global__ void randgauss( float *m, float *s, float *res)
      {
        int idx = threadIdx.x   blockDim.x * blockIdx.x; 
        int n=1;
        curandGenerator_t gen ;
        float d_normals;
        curandCreateGenerator(amp;gen, CURAND_RNG_PSEUDO_MTGP32) ; 
        curandGenerateNormal(gen, amp;d_normals, n, m[idx], s[idx]);   
        res[idx] = d_normals; 
      }
 
      """)

    def updateParameters(self):
        func = self.mod.get_function("sinus")
        func(self.m, self.s, self.V, block=self.block, grid=self.grid)


    def gen(self, N):
        V = np.zeros((N, self.NbCells), dtype=np.float32)
        for k in range(N):
            self.updateParameters()
            cuda.memcpy_dtoh(V[k, :], self.V)

        return V


GN = GN()
t0 = time.time()
Vm = GN.gen(10000)
print('GPU', time.time() - t0)
plt.figure()
plt.subplot(111)
plt.plot(Vm[:, 0] )  # plt.plot(t,Vm[:,0::1000])
#
plt.show()
 

Когда я запускаю его, у меня появляется это сообщение:

 kernel.cu(13): error: calling a __host__ function("curandCreateGenerator") from a __global__ function("randgauss") is not allowed

kernel.cu(13): error: identifier "curandCreateGenerator" is undefined in device code
 

Я не понимаю, как я должен правильно использовать эту curandGenerateNormal функцию.

Комментарии:

1. Вы не можете использовать curandCreateGenerator в ядре. Это часть API хоста

2. Что я могу использовать вместо этого?

3. Очевидно, используйте API устройства. . Обратите внимание, что вам также нужна связь C с API устройства