Last active
November 23, 2015 11:49
-
-
Save vincevargadev/0235a170fdf159ad1e2b to your computer and use it in GitHub Desktop.
The curand random generator works well, even if we don't copy data back and forth between the host and the device.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <cuda.h> | |
#include <curand.h> | |
#include <sys/time.h> | |
/** | |
* This gist tests if the random number generator works as I expect it to, | |
* even if I don't have an array on host and don't copy random numbers back and forth.. | |
* PROBLEM: In one of my codes I have to use a large (but known) number of | |
* random numbers on the device in my threads. From the results of my program I suspect | |
* that my generator doesn't generate random numbers and the random numbers in the | |
* array are accessed before the numbers have been generated, and I might use zeros | |
* instead of random number in my calculation. | |
* */ | |
/** sh | |
* nvcc -o randomGeneratorOnDevice.out randomGeneratorOnDevice.cu -lcuda -lcurand && \ | |
* randomGeneratorOnDevice.out > \ | |
* randomGeneratorOnDevice.log | |
*/ | |
__global__ void saveRandomNumbers( | |
float *randomNumbers, | |
int I, | |
int LENGTH, | |
float *results | |
) { | |
int i = threadIdx.x; | |
results[I*LENGTH+i] = randomNumbers[i]; | |
} | |
int main (void) { | |
const int LENGTH = 5; | |
int RESULTS_LENGTH = LENGTH * LENGTH; | |
int i; | |
// Get seed for random number generator | |
struct timeval timeValueStructure; | |
gettimeofday(&timeValueStructure, NULL); | |
int seed = (int) timeValueStructure.tv_usec; | |
printf("seed: %d\n", seed); | |
printf("\n\n"); | |
// Create random generator (boilerplate-ish) | |
curandGenerator_t gen; | |
curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_MRG32K3A); | |
curandSetPseudoRandomGeneratorSeed(gen, seed); | |
// array to generate random numbers to (only on device) | |
float *deviceRandomNumbers; | |
cudaMalloc((void **)&deviceRandomNumbers, LENGTH * sizeof(float)); | |
// result array on device | |
float *deviceResults; | |
cudaMalloc((void **)&deviceResults, RESULTS_LENGTH * sizeof(float)); | |
// result array on host | |
float *hostResults; | |
hostResults = (float *) malloc(RESULTS_LENGTH * sizeof(float)); | |
// fill the results array with random numbers | |
// generate LENGTH long random number arrays LENGTH times | |
// and save random numbers on device | |
for (i = 0; i < LENGTH; i++){ | |
curandGenerateUniform(gen, deviceRandomNumbers, LENGTH); | |
saveRandomNumbers<<<1, LENGTH>>>(deviceRandomNumbers, i, LENGTH, deviceResults); | |
} | |
// copy results back and display it | |
cudaMemcpy(hostResults, deviceResults, RESULTS_LENGTH * sizeof(float), cudaMemcpyDeviceToHost); | |
for (i = 0; i < RESULTS_LENGTH; i++) { | |
printf("%f\t", hostResults[i]); | |
if (i%LENGTH == (LENGTH-1)){printf("\n");} | |
} | |
printf("\n\n"); | |
/** | |
* RESULT: The random generator works well, even if we don't copy data back and forth | |
* between the host and the device. | |
* */ | |
// free memory | |
cudaFree(deviceRandomNumbers); | |
cudaFree(deviceResults); | |
free(hostResults); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment