source: CIVL/examples/cuda/dotProduct.cvl@ a465feb

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since a465feb was 296b660, checked in by Manchun Zheng <zmanchun@…>, 12 years ago

add new result to comment.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@590 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 3.5 KB
Line 
1/* dot product of two arrays.
2 *
3maurice:CIVL zmanchun$ civl verify -por=new examples/cuda/dotProduct.cvl -inputBNPG=4 -inputK=8 -inputTNPB=4
4CIVL v0.6 of 2014-02-01 -- http://vsl.cis.udel.edu/civl
5gpu done.
6
7=================== Stats ===================
8 validCalls : 140788
9 proverCalls : 1
10 memory (bytes) : 332398592
11 time (s) : 11.79
12 maxProcs : 21
13 statesInstantiated : 98602
14 statesSaved : 6466
15 statesSeen : 6463
16 statesMatched : 3889
17 steps : 27627
18 transitions : 10351
19
20 */
21
22//#include "../common/book.h"
23
24#include <civlc.h>
25#include <stdio.h>
26
27#define imin(a,b) (a<b?a:b)
28
29$input int BNPG;
30$input int K;//power of 2
31$input int TNPB; // thread number per block: for reductions, threadsPerBlock must be a power of 2
32 // because of the following code
33int N = (BNPG + 1) * K;
34int threadsPerBlock = TNPB;
35int blocksPerGrid =
36 imin(BNPG, (N+threadsPerBlock-1) / threadsPerBlock );
37double *a, *b, c, *partial_c;
38
39void gpu(){
40 void gpuBlock(int blockID){
41 #include "barrier.cvh"
42
43 double cache[threadsPerBlock];
44 int in_barrier[threadsPerBlock];
45
46 void gpuThread(int threadID){
47 int tid = threadID + blockID * threadsPerBlock;
48 int cacheIndex = threadID;
49 double temp = 0;
50
51 $atomic {
52 while (tid < N) {
53 temp += a[tid] * b[tid];
54 tid += threadsPerBlock * blocksPerGrid;
55 }
56 // set cache values
57 cache[cacheIndex] = temp;
58 //printf("cache %d of block %d done.\n", cacheIndex, blockID);
59 }
60 //printf("thread %d of block %d enter first barrier.\n", threadID, blockID);
61 // TODO synchronize
62 barrier(in_barrier, threadID);
63 int i = threadsPerBlock/2;
64 while (i != 0) {
65 if (cacheIndex < i)
66 cache[cacheIndex] += cache[cacheIndex + i];
67 //printf("thread %d of block %d enter second barrier.\n", threadID, blockID);
68 // TODO syncthreads
69 barrier(in_barrier, threadID);
70 i /= 2;
71 }
72 if (cacheIndex == 0)
73 partial_c[blockID] = cache[0];
74 }
75
76 $proc threads[threadsPerBlock];
77
78 //$atomic {
79 barrier_init(in_barrier, threadsPerBlock);
80 //printf("initialized barriers for block %d.\n", blockID);
81 for(int i = 0; i < threadsPerBlock; i++) {
82 threads[i] = $spawn gpuThread(i);
83 }
84 //}
85 $atomic {
86 for(int i = 0; i < threadsPerBlock; i++) {
87 $wait threads[i];
88 }
89 //printf("block %d done.\n", blockID);
90 }
91 }
92 $proc blocks[blocksPerGrid];
93
94 //$atomic {
95 for(int i = 0; i < blocksPerGrid; i++) {
96 blocks[i] = $spawn gpuBlock(i);
97 }
98 //}
99 //$atomic {
100 for(int i = 0; i < blocksPerGrid; i++) {
101 $wait blocks[i];
102 }
103 printf("gpu done.\n");
104 //}
105}
106
107int main( void ) {
108 $heap host;
109 // float *dev_a, *dev_b, *dev_partial_c;
110
111 // allocate memory on the cpu side
112 a = (double *) $malloc(&host, N*sizeof(double));
113 b = (double *) $malloc(&host, N*sizeof(double));
114 partial_c = (double *) $malloc(&host, blocksPerGrid*sizeof(double));
115
116 // fill in the host memory with data
117 for (int i=0; i<N; i++) {
118 a[i] = i;
119 b[i] = i*2;
120 }
121
122 gpu();
123
124 // finish up on the CPU side
125 c = 0;
126 for (int i=0; i<blocksPerGrid; i++) {
127 c += partial_c[i];
128 }
129
130 #define sum_squares(x) (x*(x+1)*(2*x+1)/6)
131 //printf( "Does GPU value %f = %f?\n", c, 2 * sum_squares( (double)(N - 1) ) );
132 // check result
133 $assert(c == 2 * sum_squares( (double)(N - 1) ));
134}
Note: See TracBrowser for help on using the repository browser.