source: CIVL/examples/cuda/dotProduct.cvl@ 13ac9574

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

commented out printf() calls.

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

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