Curand генератор не на нечетное количество элементов
Я попробовал следующую программу, которая использует curand для генерации случайных чисел. Когда количество элементов для генерации (переменная n
) нечетное число, как 9849 ниже, я получил ошибку в строке с curandGenerateNormal
, Даже количество элементов не имеет этой проблемы. В чем причина этого?
#include <curand.h>
#include <iostream>
#include <cstdlib>
using namespace std;
#define CHKcuda(x) do { \
cudaError_t y = (x); \
if (y != cudaSuccess) { \
cout << __LINE__ << ": " << y << endl; exit(1); \
} \
} while(0)
#define CHKcurand(x) do { \
curandStatus_t y = (x); \
if (y != CURAND_STATUS_SUCCESS) { \
cout << __LINE__ << ": " << y << endl; exit(1); \
} \
} while(0)
int main(int argc, char** argv) {
curandGenerator_t g_randgen;
float *ptr, *h_ptr;
int n;
if (argc > 1) {
n = atoi(argv[1]);
}
CHKcurand(curandCreateGenerator(&g_randgen, CURAND_RNG_PSEUDO_DEFAULT));
CHKcuda(cudaMalloc((void**)&ptr, n * sizeof(float)));
CHKcurand(curandGenerateNormal(g_randgen, ptr, n, 0, 0.1));
h_ptr = static_cast<float*>(malloc(sizeof(float) * n));
CHKcuda(cudaMemcpy(h_ptr, ptr, sizeof(float) * n, cudaMemcpyDeviceToHost));
CHKcuda(cudaDeviceSynchronize());
for (int i = 0; i < 5; i++) {
cout << h_ptr[i] << ", ";
}
cout << endl;
return 0;
}
РЕДАКТИРОВАТЬ:
Я проверил возвращаемое значение производящей функции. Определение кода ошибки говорит следующее:
CURAND_STATUS_LENGTH_NOT_MULTIPLE = 105, ///< Length requested is not a multple of dimension
Однако в документации говорится, что при генерации квазислучайных чисел количество элементов должно быть кратным измерению. Так почему же это влияет на генерацию псевдослучайных чисел здесь? Или это параметр, который я использую для создания генератора (CURAND_RNG_PSEUDO_DEFAULT
) на самом деле создал генератор квазислучайных чисел? И более того, каково точное значение измерения и где я могу его найти?
1 ответ
В общем, нормальные производящие функции (например, curandGenerateNormal
, curandGenerateLogNormal
и т. д.) требуют, чтобы количество запрошенных точек было кратным 2, для псевдослучайного RNG.
Это задокументировано:
curandStatus_t CURANDAPI curandGenerateNormal ( curandGenerator_t generator, float* outputPtr, size_t n, float mean, float stddev )
Generate normally distributed doubles.
Parameters
generator- Generator to use outputPtr- Pointer to device memory to store CUDA-generated results, or Pointer to host memory to store CPU-generated results n- Number of floats to generate mean- Mean of normal distribution stddev- Standard deviation of normal distribution
Returns
•CURAND_STATUS_NOT_INITIALIZED if the generator was never created
•CURAND_STATUS_PREEXISTING_FAILURE if there was an existing error from a previous kernel launch
•CURAND_STATUS_LAUNCH_FAILURE if the kernel launch failed for any reason
•CURAND_STATUS_LENGTH_NOT_MULTIPLE if the number of output samples is not a multiple of the quasirandom dimension, or is not a multiple of two for pseudorandom generators
•CURAND_STATUS_SUCCESS if the results were generated successfully
curandGenerateUniform
Например, не имеет этого ограничения.