-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththrust.cu
183 lines (159 loc) · 5.29 KB
/
thrust.cu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include<iostream>
#include<sstream>
#include<thrust/sort.h>
// function to print arrays (with an optional success/error log-message)
void printFunc(int *array, int arr_size, const char *log_message=""){
std::cout<< log_message <<"\n[";
for(int i=0; i<arr_size-1; i++){
std::cout<< array[i] <<", ";
}
std::cout<< array[arr_size-1] << "], size=" << arr_size <<std::endl;
}
/**********************************************************
***********************************************************
error checking stufff
***********************************************************
**********************************************************/
// Enable this for error checking
// #define CUDA_CHECK_ERROR
#define CudaSafeCall( err ) __cudaSafeCall( err, __FILE__, __LINE__ )
#define CudaCheckError() __cudaCheckError( __FILE__, __LINE__ )
inline void __cudaSafeCall(cudaError err,const char *file, const int line)
{
#ifdef CUDA_CHECK_ERROR
#pragma warning( push )
#pragma warning( disable: 4127 ) // Prevent warning on do-while(0)
do
{
if (cudaSuccess != err)
{
fprintf(stderr,"cudaSafeCall() failed at %s:%i : %s\n",file, line, cudaGetErrorString(err));
exit(-1);
}
} while (0);
#pragma warning( pop )
#endif // CUDA_CHECK_ERROR
return;
}
inline void __cudaCheckError(const char *file, const int line)
{
#ifdef CUDA_CHECK_ERROR
#pragma warning( push )
#pragma warning( disable: 4127 ) // Prevent warning on do-while(0);
do
{
cudaError_t err = cudaGetLastError();
if (cudaSuccess != err)
{
fprintf(stderr,"cudaCheckError() failed at %s:%i : %s.\n", file, line, cudaGetErrorString(err));
exit(-1);
}
// More careful checking. However, this will affect performance.
// Comment if not needed.
err = cudaThreadSynchronize();
if (cudaSuccess != err)
{
fprintf(stderr,"cudaCheckError() with sync failed at %s:%i : %s.\n", file, line, cudaGetErrorString(err));
exit(-1);
}
} while (0);
#pragma warning( pop )
#endif // CUDA_CHECK_ERROR
return;
}
/***************************************************************
****************************************************************
end of error checking stuff
****************************************************************
***************************************************************/
// function takes an array pointer and the size of the array, and
// allocates and intializes the array to a bunch of random numbers
int *makeRandArray(const int size, const int seed){
srand(seed);
int *array;
array = (int *)malloc(size*sizeof(int));
for (int i = 0; i < size; i++){
array[i] = rand() % size;
}
return array;
}
int main(int argc, char* argv[]){
int *array;
int size, seed; // values for the size of the array
bool printSorted = false;
// and the seed for generating
// random numbers
// check the command line args
if (argc < 4){
std::cerr << "usage: "
<< argv[0]
<< " [amount of random nums to generate] [seed value for rand]"
<< " [1 to print sorted array, 0 otherwise]"
<< std::endl;
exit(-1);
}
{
std::stringstream ss1(argv[1]);
ss1 >> size;
}
{
std::stringstream ss1(argv[2]);
ss1 >> seed;
}
int sortPrint;
std::stringstream ss1(argv[3]);
ss1 >> sortPrint;
if (sortPrint == 1){
printSorted = true;
}
// creating an array of random elements
array = makeRandArray(size, seed);
/***********************************
create a cuda timer to time execution
***********************************/
cudaEvent_t startTotal, stopTotal;
float timeTotal;
cudaEventCreate(&startTotal);
cudaEventCreate(&stopTotal);
cudaEventRecord(startTotal, 0);
/***********************************
end of cuda timer creation
***********************************/
/////////////////////////////////////////////////////////////////////
// sorting the array using Thrust STL
thrust::sort(array, array + size);
/////////////////////////////////////////////////////////////////////
/* You need to implement your kernel as a function at the top of this file.
* Here you must
*
* 1) allocate device memory
* 2) set up the grid and block sizes
* 3) call your kenrnel
* 4) get the result back from the GPU
*
* to use the error checking code, wrap any cudamalloc functions as follows:
* CudaSafeCall( cudaMalloc( &pointer_to_a_device_pointer,
* length_of_array * sizeof( int ) ) );
* Also, place the following function call immediately after you call your kernel
* ( or after any other cuda call that you think might be causing an error )
* CudaCheckError();
*/
/***********************************
stop and destroy the cuda timer
***********************************/
cudaEventRecord(stopTotal, 0);
cudaEventSynchronize(stopTotal);
cudaEventElapsedTime(&timeTotal, startTotal, stopTotal);
cudaEventDestroy(startTotal);
cudaEventDestroy(stopTotal);
/***********************************
end of cuda timer destruction
***********************************/
std::cerr << "Total time in seconds: "
<< timeTotal / 1000.0 << std::endl;
if (printSorted){
printFunc(array, size, "\nThe sorted array is:");
}
free(array);
return 0;
}