OSDN Git Service

new file: Integration/Tomography/Makefile.recent
[eos/hostdependX86LINUX64.git] / hostdepend / X86MAC64 / util / X86MAC64 / cuda / samples / 7_CUDALibraries / MersenneTwisterGP11213 / MersenneTwister.cpp
1 /*
2  * Copyright 1993-2013 NVIDIA Corporation.  All rights reserved.
3  *
4  * Please refer to the NVIDIA end user license agreement (EULA) associated
5  * with this source code for terms and conditions that govern your use of
6  * this software. Any use, reproduction, disclosure, or distribution of
7  * this software and related documentation outside the terms of the EULA
8  * is strictly prohibited.
9  *
10  */
11
12 /*
13  * This sample demonstrates the use of CURAND to generate
14  * random numbers on GPU and CPU.
15  */
16
17 // Utilities and system includes
18 // includes, system
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22
23 #include <curand.h>
24
25 // Utilities and system includes
26 #include <helper_functions.h>  // helper for shared functions common to CUDA SDK samples
27 #include <helper_cuda.h>       // helper for CUDA Error handling
28
29 /* Using updated (v2) interfaces to cublas and cusparse */
30 #include <cuda_runtime.h>
31 #include <curand.h>
32
33 float compareResults(int rand_n, float *h_RandGPU, float *h_RandCPU);
34
35 const int    DEFAULT_RAND_N = 2400000;
36 const unsigned int DEFAULT_SEED = 777;
37
38 ///////////////////////////////////////////////////////////////////////////////
39 // Main program
40 ///////////////////////////////////////////////////////////////////////////////
41 int main(int argc, char **argv)
42 {
43     // Start logs
44     printf("%s Starting...\n\n", argv[0]);
45
46     // initialize the GPU, either identified by --device
47     // or by picking the device with highest flop rate.
48     int devID = findCudaDevice(argc, (const char **)argv);
49
50     // parsing the number of random numbers to generate
51     int rand_n = DEFAULT_RAND_N;
52
53     if (checkCmdLineFlag(argc, (const char **) argv, "count"))
54     {
55         rand_n = getCmdLineArgumentInt(argc, (const char **) argv, "count");
56     }
57
58     printf("Allocating data for %i samples...\n", rand_n);
59
60     // parsing the seed
61     int seed = DEFAULT_SEED;
62
63     if (checkCmdLineFlag(argc, (const char **) argv, "seed"))
64     {
65         seed = getCmdLineArgumentInt(argc, (const char **) argv, "seed");
66     }
67
68     printf("Seeding with %i ...\n", seed);
69
70
71     float *d_Rand;
72     checkCudaErrors(cudaMalloc((void **)&d_Rand, rand_n * sizeof(float)));
73
74     curandGenerator_t prngGPU;
75     checkCudaErrors(curandCreateGenerator(&prngGPU, CURAND_RNG_PSEUDO_MTGP32));
76     checkCudaErrors(curandSetPseudoRandomGeneratorSeed(prngGPU, seed));
77
78     curandGenerator_t prngCPU;
79     checkCudaErrors(curandCreateGeneratorHost(&prngCPU, CURAND_RNG_PSEUDO_MTGP32));
80     checkCudaErrors(curandSetPseudoRandomGeneratorSeed(prngCPU, seed));
81
82     //
83     // Example 1: Compare random numbers generated on GPU and CPU
84     float *h_RandGPU  = (float *)malloc(rand_n * sizeof(float));
85
86     printf("Generating random numbers on GPU...\n\n");
87     checkCudaErrors(curandGenerateUniform(prngGPU, (float *) d_Rand, rand_n));
88
89     printf("\nReading back the results...\n");
90     checkCudaErrors(cudaMemcpy(h_RandGPU, d_Rand, rand_n * sizeof(float), cudaMemcpyDeviceToHost));
91
92
93     float *h_RandCPU  = (float *)malloc(rand_n * sizeof(float));
94
95     printf("Generating random numbers on CPU...\n\n");
96     checkCudaErrors(curandGenerateUniform(prngCPU, (float *) h_RandCPU, rand_n));
97
98     printf("Comparing CPU/GPU random numbers...\n\n");
99     float L1norm = compareResults(rand_n, h_RandGPU, h_RandCPU);
100
101     //
102     // Example 2: Timing of random number generation on GPU
103     const int numIterations = 10;
104     int i;
105     StopWatchInterface *hTimer;
106
107     checkCudaErrors(cudaDeviceSynchronize());
108     sdkCreateTimer(&hTimer);
109     sdkResetTimer(&hTimer);
110     sdkStartTimer(&hTimer);
111
112     for (i = 0; i < numIterations; i++)
113     {
114         checkCudaErrors(curandGenerateUniform(prngGPU, (float *) d_Rand, rand_n));
115     }
116
117     checkCudaErrors(cudaDeviceSynchronize());
118     sdkStopTimer(&hTimer);
119
120     double gpuTime = 1.0e-3 * sdkGetTimerValue(&hTimer)/(double)numIterations;
121
122     printf("MersenneTwister, Throughput = %.4f GNumbers/s, Time = %.5f s, Size = %u Numbers\n",
123            1.0e-9 * rand_n / gpuTime, gpuTime, rand_n);
124
125     printf("Shutting down...\n");
126
127     checkCudaErrors(curandDestroyGenerator(prngGPU));
128     checkCudaErrors(curandDestroyGenerator(prngCPU));
129     checkCudaErrors(cudaFree(d_Rand));
130     sdkDeleteTimer(&hTimer);
131     free(h_RandGPU);
132     free(h_RandCPU);
133
134     cudaDeviceReset();
135     exit(L1norm < 1e-6 ? EXIT_SUCCESS : EXIT_FAILURE);
136 }
137
138
139 float compareResults(int rand_n, float *h_RandGPU, float *h_RandCPU)
140 {
141     int i;
142     float rCPU, rGPU, delta;
143     float max_delta = 0.;
144     float sum_delta = 0.;
145     float sum_ref   = 0.;
146
147     for (i = 0; i < rand_n; i++)
148     {
149         rCPU = h_RandCPU[i];
150         rGPU = h_RandGPU[i];
151         delta = fabs(rCPU - rGPU);
152         sum_delta += delta;
153         sum_ref   += fabs(rCPU);
154
155         if (delta >= max_delta)
156         {
157             max_delta = delta;
158         }
159     }
160
161     float L1norm = (float)(sum_delta / sum_ref);
162     printf("Max absolute error: %E\n", max_delta);
163     printf("L1 norm: %E\n\n", L1norm);
164
165     return L1norm;
166 }