source: CIVL/examples/backend/mpiSumarray.cvl@ 01e53c03

1.23 2.0 main test-branch
Last change on this file since 01e53c03 was cb6e7fe, checked in by Ziqing Luo <ziqing@…>, 10 years ago

rename $mpi_assert_consistent_type to $mpi_assert_consistent_basetype

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

  • Property mode set to 100644
File size: 28.5 KB
RevLine 
[7d856cc]1//======================= int_div.cvl ======================
[39c2026]2$system[civlc] void $assert(_Bool expr, ...);
[7d856cc]3int $int_div(int numerator, int denominator)
4{
5 $assert(denominator != 0, "Possible division by zero");
6 if (numerator == 0)
7 return 0;
8 if (numerator >= 0)
9 {
10 if (denominator >= 0)
11 return numerator / denominator;
12 else
13 return -(numerator / (-denominator));
14 }
15 else
16 {
17 if (denominator >= 0)
18 return -((-numerator) / denominator);
19 else
20 return (-numerator) / (-denominator);
21 }
22}
23//======================== civlc.cvh =======================
24typedef struct $proc $proc;
25typedef struct $scope $scope;
26/*@ depends_on \nothing;
27 @*/
[39c2026]28$system[civlc] void $assert(_Bool expr, ...);
[7d856cc]29/*@ depends_on \nothing;
30 @*/
[39c2026]31$system[civlc] void $assume(_Bool expr);
[dba07d0]32/*@ pure;
33 @ depends_on \nothing;
34 @*/
35$system[civlc] void $elaborate(int x);
[7d856cc]36/*@ depends_on \nothing;
37 @*/
[39c2026]38$system[civlc] void $assert(_Bool expr, ...);
[7d856cc]39/*@ depends_on \nothing;
40 @*/
[39c2026]41$system[civlc] void $assume(_Bool expr);
[dba07d0]42/*@ pure;
43 @ depends_on \nothing;
44 @*/
45$system[civlc] void $elaborate(int x);
[7d856cc]46//========================= stdio.h ========================
[39c2026]47$system[stdio] int printf(char* restrict format, ...);
[7d856cc]48//======================== civlc.cvh =======================
49/*@ depends_on \nothing;
50 @*/
[39c2026]51$system[civlc] void $assert(_Bool expr, ...);
[7d856cc]52/*@ depends_on \nothing;
53 @*/
[39c2026]54$system[civlc] void $assume(_Bool expr);
[dba07d0]55/*@ pure;
56 @ depends_on \nothing;
57 @*/
58$system[civlc] void $elaborate(int x);
[7d856cc]59//======================= bundle.cvh =======================
60typedef struct $bundle $bundle;
61/*@ pure;
62 @*/
[39c2026]63$system[bundle] $bundle $bundle_pack(void* ptr, int size);
64$system[bundle] void $bundle_unpack($bundle bundle, void* ptr);
[7d856cc]65//===================== concurrency.cvh ====================
66typedef struct $gbarrier* $gbarrier;
67typedef struct $barrier* $barrier;
[dba07d0]68/*@ requires size >= 0;
69 @ depends_on \nothing;
[7d856cc]70 @ executes_when $true;
[dba07d0]71 @ assigns \nothing;
[7d856cc]72 @*/
[39c2026]73$system[concurrency] $gbarrier $gbarrier_create($scope scope, int size);
[7d856cc]74/*@ depends_on \nothing;
75 @ executes_when $true;
76 @*/
[39c2026]77$system[concurrency] void $gbarrier_destroy($gbarrier barrier);
[7d856cc]78/*@ depends_on \nothing;
[dba07d0]79 @ assigns \nothing;
[7d856cc]80 @ executes_when $true;
81 @*/
[39c2026]82$system[concurrency] $barrier $barrier_create($scope scope, $gbarrier gbarrier, int place);
[7d856cc]83/*@ depends_on \nothing;
84 @ executes_when $true;
85 @*/
[39c2026]86$system[concurrency] void $barrier_destroy($barrier barrier);
[7d856cc]87typedef struct $collect_record $collect_record;
88typedef struct $gcollect_checker* $gcollect_checker;
89typedef struct $collect_checker* $collect_checker;
90/*@ depends_on \nothing;
91 @ executes_when $true;
92 @*/
[39c2026]93$system[concurrency] $gcollect_checker $gcollect_checker_create($scope scope);
[7d856cc]94/*@ depends_on \nothing;
95 @ executes_when $true;
96 @*/
[39c2026]97$system[concurrency] int $gcollect_checker_destroy($gcollect_checker checker);
[7d856cc]98/*@ depends_on \nothing;
99 @ executes_when $true;
100 @*/
[39c2026]101$system[concurrency] $collect_checker $collect_checker_create($scope scope, $gcollect_checker gchecker);
[7d856cc]102/*@ depends_on \nothing;
103 @ executes_when $true;
104 @*/
[39c2026]105$system[concurrency] void $collect_checker_destroy($collect_checker checker);
[7d856cc]106//========================== mpi.h =========================
107typedef enum $anon_enum_0{
108 MPI_CHAR,
109 MPI_CHARACTER,
110 MPI_SIGNED_CHAR,
111 MPI_UNSIGNED_CHAR,
112 MPI_BYTE,
113 MPI_WCHAR,
114 MPI_SHORT,
115 MPI_UNSIGNED_SHORT,
116 MPI_INT,
117 MPI_INT16_T,
118 MPI_INT32_T,
119 MPI_INT64_T,
120 MPI_INT8_T,
121 MPI_INTEGER,
122 MPI_INTEGER1,
123 MPI_INTEGER16,
124 MPI_INTEGER2,
125 MPI_INTEGER4,
126 MPI_INTEGER8,
127 MPI_UNSIGNED,
128 MPI_LONG,
129 MPI_UNSIGNED_LONG,
130 MPI_FLOAT,
131 MPI_DOUBLE,
132 MPI_LONG_DOUBLE,
133 MPI_LONG_LONG_INT,
134 MPI_UNSIGNED_LONG_LONG,
135 MPI_LONG_LONG,
136 MPI_PACKED,
137 MPI_LB,
138 MPI_UB,
139 MPI_UINT16_T,
140 MPI_UINT32_T,
141 MPI_UINT64_T,
142 MPI_UINT8_T,
143 MPI_FLOAT_INT,
144 MPI_DOUBLE_INT,
145 MPI_LONG_INT,
146 MPI_SHORT_INT,
147 MPI_2INT,
148 MPI_LONG_DOUBLE_INT,
149 MPI_AINT,
150 MPI_OFFSET,
151 MPI_2DOUBLE_PRECISION,
152 MPI_2INTEGER,
153 MPI_2REAL,
154 MPI_C_BOOL,
155 MPI_C_COMPLEX,
156 MPI_C_DOUBLE_COMPLEX,
157 MPI_C_FLOAT_COMPLEX,
158 MPI_C_LONG_DOUBLE_COMPLEX,
159 MPI_COMPLEX,
160 MPI_COMPLEX16,
161 MPI_COMPLEX32,
162 MPI_COMPLEX4,
163 MPI_COMPLEX8,
164 MPI_REAL,
165 MPI_REAL16,
166 MPI_REAL2,
167 MPI_REAL4,
168 MPI_REAL8
169} MPI_Datatype;
170typedef struct MPI_Comm MPI_Comm;
171typedef struct MPI_Status{
172 int MPI_SOURCE;
173 int MPI_TAG;
174 int MPI_ERROR;
175 int size;
176} MPI_Status;
177int MPI_Send(void*, int, MPI_Datatype, int, int, MPI_Comm);
178int MPI_Recv(void*, int, MPI_Datatype, int, int, MPI_Comm, MPI_Status*);
179int MPI_Get_count(MPI_Status*, MPI_Datatype, int*);
180int MPI_Comm_size(MPI_Comm, int*);
181int MPI_Comm_rank(MPI_Comm, int*);
182//======================== comm.cvh ========================
183typedef struct $message{
184 int source;
185 int dest;
186 int tag;
187 $bundle data;
188 int size;
189} $message;
190typedef struct $queue $queue;
191typedef struct $gcomm* $gcomm;
192typedef struct $comm* $comm;
193/*@ pure;
194 @ depends_on \nothing;
195 @ executes_when $true;
196 @*/
197$atomic_f $message $message_pack(int source, int dest, int tag, void* data, int size);
198/*@ pure;
199 @ depends_on \nothing;
200 @ executes_when $true;
201 @*/
202$atomic_f int $message_source($message message);
203/*@ pure;
204 @ depends_on \nothing;
205 @ executes_when $true;
206 @*/
207$atomic_f int $message_tag($message message);
208/*@ pure;
209 @ depends_on \nothing;
210 @ executes_when $true;
211 @*/
212$atomic_f int $message_dest($message message);
213/*@ pure;
214 @ depends_on \nothing;
215 @ executes_when $true;
216 @*/
217$atomic_f int $message_size($message message);
218/*@ depends_on \write(buf);
219 @ executes_when $true;
220 @*/
221$atomic_f void $message_unpack($message message, void* buf, int size);
222/*@ depends_on \nothing;
223 @ executes_when $true;
224 @*/
[39c2026]225$system[comm] $gcomm $gcomm_create($scope scope, int size);
[7d856cc]226/*@ depends_on \nothing;
227 @ executes_when $true;
228 @*/
[39c2026]229$system[comm] int $gcomm_destroy($gcomm gcomm, void* junkMsgs);
[7d856cc]230/*@ depends_on \nothing;
231 @ executes_when $true;
232 @*/
[39c2026]233$system[comm] $comm $comm_create($scope scope, $gcomm gcomm, int place);
[7d856cc]234/*@ depends_on \nothing;
235 @ executes_when $true;
236 @*/
[39c2026]237$system[comm] void $comm_destroy($comm comm);
[7d856cc]238/*@ pure;
239 @ depends_on \nothing;
240 @ executes_when $true;
241 @*/
[39c2026]242$system[comm] int $comm_size($comm comm);
[7d856cc]243/*@ pure;
244 @ depends_on \nothing;
245 @ executes_when $true;
246 @*/
247$atomic_f int $comm_place($comm comm);
248/*@ depends_on \write(comm);
249 @ executes_when $true;
250 @*/
[39c2026]251$system[comm] void $comm_enqueue($comm comm, $message message);
[7d856cc]252/*@ depends_on \write(comm);
253 @*/
[39c2026]254$system[comm] $message $comm_dequeue($comm comm, int source, int tag);
[7d856cc]255//====================== civl-mpi.cvh ======================
256typedef enum _mpi_sys_status_{
257 __UNINIT,
258 __INIT,
259 __FINALIZED
260} $mpi_sys_status;
261typedef struct MPI_Comm MPI_Comm;
262typedef struct MPI_Status MPI_Status;
263typedef struct $mpi_gcomm $mpi_gcomm;
[dba07d0]264int sizeofDatatype(MPI_Datatype);
265$system[mpi] void $mpi_set_status($mpi_sys_status newStatus);
266$system[mpi] $mpi_sys_status $mpi_get_status(void);
267$mpi_gcomm $mpi_gcomm_create($scope, int);
268void $mpi_gcomm_destroy($mpi_gcomm);
[7d856cc]269MPI_Comm $mpi_comm_create($scope, $mpi_gcomm, int);
270void $mpi_comm_destroy(MPI_Comm);
271int $mpi_init(void);
272int $mpi_finalize(void);
273int $mpi_send(void*, int, MPI_Datatype, int, int, MPI_Comm);
274int $mpi_recv(void*, int, MPI_Datatype, int, int, MPI_Comm, MPI_Status*);
[cb6e7fe]275$system[mpi] void $mpi_assert_consistent_basetype(void* buf, MPI_Datatype datatype);
[7d856cc]276//========================= mpi.cvl ========================
277struct MPI_Comm{
278 $comm p2p;
279 $comm col;
280 $collect_checker collect_checker;
281 $barrier barrier;
282 int gcommIndex;
283};
284int MPI_Comm_size(MPI_Comm comm, int* size)
285{
286 $mpi_sys_status curr_status;
287 curr_status = $mpi_get_status();
288 $assert(curr_status == __INIT, "MPI_Comm_size() cannot be invoked without MPI_Init() being called before.\n");
289 *size = $comm_size(comm.p2p);
290 return 0;
291}
292int MPI_Comm_rank(MPI_Comm comm, int* rank)
293{
294 $mpi_sys_status curr_status;
295 curr_status = $mpi_get_status();
296 $assert(curr_status == __INIT, "MPI_Comm_rank() cannot be invoked without MPI_Init() being called before.\n");
297 *rank = $comm_place(comm.p2p);
298 return 0;
299}
300int MPI_Send(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
301{
302 $mpi_sys_status curr_status;
303 curr_status = $mpi_get_status();
304 $assert(curr_status == __INIT, "MPI_Send() cannot be invoked without MPI_Init() being called before.\n");
[cb6e7fe]305 $mpi_assert_consistent_basetype(buf, datatype);
[7d856cc]306 int $sef$0 = $mpi_send(buf, count, datatype, dest, tag, comm);
307 return $sef$0;
308}
309int MPI_Recv(void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status* status)
310{
311 $mpi_sys_status curr_status;
312 curr_status = $mpi_get_status();
313 $assert(curr_status == __INIT, "MPI_Recv() cannot be invoked without MPI_Init() being called before.\n");
[cb6e7fe]314 $mpi_assert_consistent_basetype(buf, datatype);
[7d856cc]315 int $sef$1 = $mpi_recv(buf, count, datatype, source, tag, comm, status);
316 return $sef$1;
317}
318int MPI_Get_count(MPI_Status* status, MPI_Datatype datatype, int* count)
319{
320 $mpi_sys_status curr_status;
321 curr_status = $mpi_get_status();
322 $assert(curr_status == __INIT, "MPI_Get_count() cannot be invoked without MPI_Init() being called before.\n");
323 int $sef$2 = sizeofDatatype(datatype);
324 *count = $int_div((status)->size, $sef$2);
325 return 0;
326}
327//======================== civlc.cvh =======================
328/*@ depends_on \nothing;
329 @*/
[39c2026]330$system[civlc] void $assert(_Bool expr, ...);
[7d856cc]331/*@ depends_on \nothing;
332 @*/
[39c2026]333$system[civlc] void $assume(_Bool expr);
[7d856cc]334/*@ pure;
[39c2026]335 @ depends_on \nothing;
[7d856cc]336 @*/
[dba07d0]337$system[civlc] void $elaborate(int x);
338//======================= bundle.cvh =======================
339/*@ pure;
[39c2026]340 @*/
[dba07d0]341$system[bundle] $bundle $bundle_pack(void* ptr, int size);
[39c2026]342$system[bundle] void $bundle_unpack($bundle bundle, void* ptr);
[7d856cc]343//===================== concurrency.cvh ====================
[dba07d0]344/*@ requires size >= 0;
345 @ depends_on \nothing;
[7d856cc]346 @ executes_when $true;
[dba07d0]347 @ assigns \nothing;
[7d856cc]348 @*/
[39c2026]349$system[concurrency] $gbarrier $gbarrier_create($scope scope, int size);
[7d856cc]350/*@ depends_on \nothing;
351 @ executes_when $true;
352 @*/
[39c2026]353$system[concurrency] void $gbarrier_destroy($gbarrier barrier);
[7d856cc]354/*@ depends_on \nothing;
[dba07d0]355 @ assigns \nothing;
[7d856cc]356 @ executes_when $true;
357 @*/
[39c2026]358$system[concurrency] $barrier $barrier_create($scope scope, $gbarrier gbarrier, int place);
[7d856cc]359/*@ depends_on \nothing;
360 @ executes_when $true;
361 @*/
[39c2026]362$system[concurrency] void $barrier_destroy($barrier barrier);
[7d856cc]363/*@ depends_on \nothing;
364 @ executes_when $true;
365 @*/
[39c2026]366$system[concurrency] $gcollect_checker $gcollect_checker_create($scope scope);
[7d856cc]367/*@ depends_on \nothing;
368 @ executes_when $true;
369 @*/
[39c2026]370$system[concurrency] int $gcollect_checker_destroy($gcollect_checker checker);
[7d856cc]371/*@ depends_on \nothing;
372 @ executes_when $true;
373 @*/
[39c2026]374$system[concurrency] $collect_checker $collect_checker_create($scope scope, $gcollect_checker gchecker);
[7d856cc]375/*@ depends_on \nothing;
376 @ executes_when $true;
377 @*/
[39c2026]378$system[concurrency] void $collect_checker_destroy($collect_checker checker);
[7d856cc]379//========================= seq.cvh ========================
[39c2026]380$system[seq] void $seq_init(void* array, int count, void* value);
[7d856cc]381//===================== concurrency.cvl ====================
382struct $gbarrier{
383 int nprocs;
384 $proc proc_map[];
385 _Bool in_barrier[];
386 int num_in_barrier;
387};
388struct $barrier{
389 int place;
390 $gbarrier gbarrier;
391};
392struct $collect_record{
393 $bundle entries;
394 _Bool marks[];
395 int numMarked;
396};
397struct $gcollect_checker{
398 int length;
399 $collect_record records[];
400};
401struct $collect_checker{
402 $gcollect_checker checker;
403};
404//======================== civlc.cvh =======================
405/*@ depends_on \nothing;
406 @*/
[39c2026]407$system[civlc] void $assert(_Bool expr, ...);
[7d856cc]408/*@ depends_on \nothing;
409 @*/
[39c2026]410$system[civlc] void $assume(_Bool expr);
[7d856cc]411/*@ pure;
[39c2026]412 @ depends_on \nothing;
[7d856cc]413 @*/
[dba07d0]414$system[civlc] void $elaborate(int x);
415//======================= bundle.cvh =======================
416/*@ pure;
[39c2026]417 @*/
[dba07d0]418$system[bundle] $bundle $bundle_pack(void* ptr, int size);
[39c2026]419$system[bundle] void $bundle_unpack($bundle bundle, void* ptr);
[7d856cc]420//===================== concurrency.cvh ====================
[dba07d0]421/*@ requires size >= 0;
422 @ depends_on \nothing;
[7d856cc]423 @ executes_when $true;
[dba07d0]424 @ assigns \nothing;
[7d856cc]425 @*/
[39c2026]426$system[concurrency] $gbarrier $gbarrier_create($scope scope, int size);
[7d856cc]427/*@ depends_on \nothing;
428 @ executes_when $true;
429 @*/
[39c2026]430$system[concurrency] void $gbarrier_destroy($gbarrier barrier);
[7d856cc]431/*@ depends_on \nothing;
[dba07d0]432 @ assigns \nothing;
[7d856cc]433 @ executes_when $true;
434 @*/
[39c2026]435$system[concurrency] $barrier $barrier_create($scope scope, $gbarrier gbarrier, int place);
[7d856cc]436/*@ depends_on \nothing;
437 @ executes_when $true;
438 @*/
[39c2026]439$system[concurrency] void $barrier_destroy($barrier barrier);
[7d856cc]440/*@ depends_on \nothing;
441 @ executes_when $true;
442 @*/
[39c2026]443$system[concurrency] $gcollect_checker $gcollect_checker_create($scope scope);
[7d856cc]444/*@ depends_on \nothing;
445 @ executes_when $true;
446 @*/
[39c2026]447$system[concurrency] int $gcollect_checker_destroy($gcollect_checker checker);
[7d856cc]448/*@ depends_on \nothing;
449 @ executes_when $true;
450 @*/
[39c2026]451$system[concurrency] $collect_checker $collect_checker_create($scope scope, $gcollect_checker gchecker);
[7d856cc]452/*@ depends_on \nothing;
453 @ executes_when $true;
454 @*/
[39c2026]455$system[concurrency] void $collect_checker_destroy($collect_checker checker);
[7d856cc]456//======================== comm.cvh ========================
457/*@ pure;
458 @ depends_on \nothing;
459 @ executes_when $true;
460 @*/
461$atomic_f $message $message_pack(int source, int dest, int tag, void* data, int size);
462/*@ pure;
463 @ depends_on \nothing;
464 @ executes_when $true;
465 @*/
466$atomic_f int $message_source($message message);
467/*@ pure;
468 @ depends_on \nothing;
469 @ executes_when $true;
470 @*/
471$atomic_f int $message_tag($message message);
472/*@ pure;
473 @ depends_on \nothing;
474 @ executes_when $true;
475 @*/
476$atomic_f int $message_dest($message message);
477/*@ pure;
478 @ depends_on \nothing;
479 @ executes_when $true;
480 @*/
481$atomic_f int $message_size($message message);
482/*@ depends_on \write(buf);
483 @ executes_when $true;
484 @*/
485$atomic_f void $message_unpack($message message, void* buf, int size);
486/*@ depends_on \nothing;
487 @ executes_when $true;
488 @*/
[39c2026]489$system[comm] $gcomm $gcomm_create($scope scope, int size);
[7d856cc]490/*@ depends_on \nothing;
491 @ executes_when $true;
492 @*/
[39c2026]493$system[comm] int $gcomm_destroy($gcomm gcomm, void* junkMsgs);
[7d856cc]494/*@ depends_on \nothing;
495 @ executes_when $true;
496 @*/
[39c2026]497$system[comm] $comm $comm_create($scope scope, $gcomm gcomm, int place);
[7d856cc]498/*@ depends_on \nothing;
499 @ executes_when $true;
500 @*/
[39c2026]501$system[comm] void $comm_destroy($comm comm);
[7d856cc]502/*@ pure;
503 @ depends_on \nothing;
504 @ executes_when $true;
505 @*/
[39c2026]506$system[comm] int $comm_size($comm comm);
[7d856cc]507/*@ pure;
508 @ depends_on \nothing;
509 @ executes_when $true;
510 @*/
511$atomic_f int $comm_place($comm comm);
512/*@ depends_on \write(comm);
513 @ executes_when $true;
514 @*/
[39c2026]515$system[comm] void $comm_enqueue($comm comm, $message message);
[7d856cc]516/*@ depends_on \write(comm);
517 @*/
[39c2026]518$system[comm] $message $comm_dequeue($comm comm, int source, int tag);
[7d856cc]519//========================== mpi.h =========================
520int MPI_Send(void*, int, MPI_Datatype, int, int, MPI_Comm);
521int MPI_Recv(void*, int, MPI_Datatype, int, int, MPI_Comm, MPI_Status*);
522int MPI_Get_count(MPI_Status*, MPI_Datatype, int*);
523int MPI_Comm_size(MPI_Comm, int*);
524int MPI_Comm_rank(MPI_Comm, int*);
525//====================== civl-mpi.cvh ======================
[dba07d0]526int sizeofDatatype(MPI_Datatype);
527$system[mpi] void $mpi_set_status($mpi_sys_status newStatus);
528$system[mpi] $mpi_sys_status $mpi_get_status(void);
529$mpi_gcomm $mpi_gcomm_create($scope, int);
530void $mpi_gcomm_destroy($mpi_gcomm);
[7d856cc]531MPI_Comm $mpi_comm_create($scope, $mpi_gcomm, int);
532void $mpi_comm_destroy(MPI_Comm);
533int $mpi_init(void);
534int $mpi_finalize(void);
535int $mpi_send(void*, int, MPI_Datatype, int, int, MPI_Comm);
536int $mpi_recv(void*, int, MPI_Datatype, int, int, MPI_Comm, MPI_Status*);
[cb6e7fe]537$system[mpi] void $mpi_assert_consistent_basetype(void* buf, MPI_Datatype datatype);
[7d856cc]538//========================= seq.cvh ========================
[39c2026]539$system[seq] void $seq_init(void* array, int count, void* value);
[7d856cc]540//====================== civl-mpi.cvl ======================
541char* getCoroutineName(int tag);
542struct $mpi_gcomm{
543 $gcomm p2p;
544 $gcomm col;
545 $gcollect_checker collect_checker;
546 $gbarrier gbarrier;
547};
548int sizeofDatatype(MPI_Datatype datatype)
549{
550 switch (datatype)
551 {
552 case MPI_INT:
553 return sizeof(int);
554 case MPI_2INT:
555 return sizeof(int) * 2;
556 case MPI_FLOAT:
557 return sizeof(float);
558 case MPI_DOUBLE:
559 return sizeof(double);
560 case MPI_CHAR:
561 return sizeof(char);
562 case MPI_BYTE:
563 return sizeof(char);
564 case MPI_SHORT:
565 return sizeof(short);
566 case MPI_LONG:
567 return sizeof(long);
568 case MPI_LONG_DOUBLE:
569 return sizeof(long double);
570 case MPI_LONG_LONG_INT:
571 return sizeof(long long);
572 case MPI_LONG_LONG:
573 return sizeof(long long);
574 case MPI_UNSIGNED_LONG_LONG:
575 return sizeof(unsigned long long);
576 default:
577 $assert(0, "Unreachable");
578 }
579}
580$mpi_gcomm $mpi_gcomm_create($scope scope, int size)
581{
582 $mpi_gcomm result;
583 result.p2p = $gcomm_create(scope, size);
584 result.col = $gcomm_create(scope, size);
585 result.collect_checker = $gcollect_checker_create(scope);
586 result.gbarrier = $gbarrier_create(scope, size);
587 return result;
588}
589void $mpi_gcomm_destroy($mpi_gcomm gc)
590{
591 int numJunkRecord;
592 int numJunkMsg;
593 $message junkMsgs[];
594 $seq_init(&(junkMsgs), 0, (void*)0);
595 numJunkMsg = $gcomm_destroy(gc.p2p, &(junkMsgs));
596 {
597 int i = 0;
598 for (; i < numJunkMsg; i = i + 1)
599 {
600 int src;
601 int dest;
602 int tag;
603 src = $message_source(junkMsgs[i]);
604 dest = $message_dest(junkMsgs[i]);
605 tag = $message_tag(junkMsgs[i]);
606 $assert($false, "MPI message leak: There is a message from rank %d to rank %d with tag %d has been sent but is never received in point-to-point communication.", src, dest, tag);
607 }
608 }
609 numJunkMsg = $gcomm_destroy(gc.col, &(junkMsgs));
610 {
611 int i = 0;
612 for (; i < numJunkMsg; i = i + 1)
613 {
614 int src;
615 int tag;
616 char* routine;
617 src = $message_source(junkMsgs[i]);
618 tag = $message_tag(junkMsgs[i]);
619 routine = getCoroutineName(tag);
620 $assert($false, "MPI message leak: There is a message sent by rank %d for collective routine %s that is never received.", src, routine);
621 }
622 }
623 numJunkRecord = $gcollect_checker_destroy(gc.collect_checker);
624 $gbarrier_destroy(gc.gbarrier);
625 $assert(numJunkRecord == 0, "MPI collective routines are called inappropriately because there are %d collective records still remaining the collective routine checker.", numJunkRecord);
626}
627MPI_Comm $mpi_comm_create($scope scope, $mpi_gcomm gc, int rank)
628{
629 MPI_Comm result;
630 result.p2p = $comm_create(scope, gc.p2p, rank);
631 result.col = $comm_create(scope, gc.col, rank);
632 result.collect_checker = $collect_checker_create(scope, gc.collect_checker);
633 result.barrier = $barrier_create(scope, gc.gbarrier, rank);
634 result.gcommIndex = 0;
635 return result;
636}
637void $mpi_comm_destroy(MPI_Comm comm)
638{
639 $mpi_sys_status curr_status;
640 curr_status = $mpi_get_status();
641 if (comm.gcommIndex == 0)
642 $assert(curr_status == __FINALIZED, "Process terminates without calling MPI_Finalize() first.");
643 $comm_destroy(comm.p2p);
644 $comm_destroy(comm.col);
645 $collect_checker_destroy(comm.collect_checker);
646 $barrier_destroy(comm.barrier);
647}
648int $mpi_init(void)
649{
650 $mpi_set_status(__INIT);
651 return 0;
652}
653int $mpi_finalize(void)
654{
655 $mpi_set_status(__FINALIZED);
656 return 0;
657}
658int $mpi_send(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
659{
660 if (dest >= 0)
661 {
662 int $sef$3 = sizeofDatatype(datatype);
663 int size = count * $sef$3;
664 int place = $comm_place(comm.p2p);
665 $message out = $message_pack(place, dest, tag, buf, size);
666 $comm_enqueue(comm.p2p, out);
667 }
668 return 0;
669}
670int $mpi_recv(void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status* status)
671{
672 if ((source >= 0) || (source == (-1)))
673 {
674 $message in;
675 int place = $comm_place(comm.p2p);
[dba07d0]676 $elaborate(source);
[7d856cc]677 in = $comm_dequeue(comm.p2p, source, tag);
678 int $sef$4 = sizeofDatatype(datatype);
679 int size = count * $sef$4;
680 $message_unpack(in, buf, size);
681 if (status != (void*)0)
682 {
683 (status)->size = $message_size(in);
684 (status)->MPI_SOURCE = $message_source(in);
685 (status)->MPI_TAG = $message_tag(in);
686 (status)->MPI_ERROR = 0;
687 }
688 }
689 return 0;
690}
691char* getCoroutineName(int tag)
692{
693 switch (tag)
694 {
695 case 9999:
696 return "MPI_Bcast";
697 case 9998:
698 return "MPI_Reduce";
699 case 9997:
700 return "MPI_Allreduce";
701 case 9996:
702 return "MPI_Gather";
703 case 9995:
704 return "MPI_Scatter";
705 case 9994:
706 return "MPI_Gatherv";
707 case 9993:
708 return "MPI_Scatterv";
709 case 9992:
710 return "MPI_Allgather";
711 case 9991:
712 return "MPI_Reduce_scatter";
713 case 9990:
714 return "MPI_Alltoall";
715 case 9989:
716 return "MPI_Alltoallv";
717 case 9988:
718 return "MPI_Alltoallw";
719 case 9987:
720 return "MPI_Barrier";
721 case 9986:
722 return "MPI_Commdup";
723 case 9985:
724 return "MPI_Commfree";
725 default:
726 $assert($false, "Internal Error: Unexpected MPI routine tag:%d.\n", tag);
727 }
728}
729//======================== civlc.cvh =======================
730/*@ depends_on \nothing;
731 @*/
[39c2026]732$system[civlc] void $assert(_Bool expr, ...);
[7d856cc]733/*@ depends_on \nothing;
734 @*/
[39c2026]735$system[civlc] void $assume(_Bool expr);
[7d856cc]736/*@ pure;
[39c2026]737 @ depends_on \nothing;
738 @*/
[dba07d0]739$system[civlc] void $elaborate(int x);
740//======================= bundle.cvh =======================
741/*@ pure;
[7d856cc]742 @*/
[dba07d0]743$system[bundle] $bundle $bundle_pack(void* ptr, int size);
[39c2026]744$system[bundle] void $bundle_unpack($bundle bundle, void* ptr);
[7d856cc]745//======================== comm.cvh ========================
746/*@ pure;
747 @ depends_on \nothing;
748 @ executes_when $true;
749 @*/
750$atomic_f $message $message_pack(int source, int dest, int tag, void* data, int size);
751/*@ pure;
752 @ depends_on \nothing;
753 @ executes_when $true;
754 @*/
755$atomic_f int $message_source($message message);
756/*@ pure;
757 @ depends_on \nothing;
758 @ executes_when $true;
759 @*/
760$atomic_f int $message_tag($message message);
761/*@ pure;
762 @ depends_on \nothing;
763 @ executes_when $true;
764 @*/
765$atomic_f int $message_dest($message message);
766/*@ pure;
767 @ depends_on \nothing;
768 @ executes_when $true;
769 @*/
770$atomic_f int $message_size($message message);
771/*@ depends_on \write(buf);
772 @ executes_when $true;
773 @*/
774$atomic_f void $message_unpack($message message, void* buf, int size);
775/*@ depends_on \nothing;
776 @ executes_when $true;
777 @*/
[39c2026]778$system[comm] $gcomm $gcomm_create($scope scope, int size);
[7d856cc]779/*@ depends_on \nothing;
780 @ executes_when $true;
781 @*/
[39c2026]782$system[comm] int $gcomm_destroy($gcomm gcomm, void* junkMsgs);
[7d856cc]783/*@ depends_on \nothing;
784 @ executes_when $true;
785 @*/
[39c2026]786$system[comm] $comm $comm_create($scope scope, $gcomm gcomm, int place);
[7d856cc]787/*@ depends_on \nothing;
788 @ executes_when $true;
789 @*/
[39c2026]790$system[comm] void $comm_destroy($comm comm);
[7d856cc]791/*@ pure;
792 @ depends_on \nothing;
793 @ executes_when $true;
794 @*/
[39c2026]795$system[comm] int $comm_size($comm comm);
[7d856cc]796/*@ pure;
797 @ depends_on \nothing;
798 @ executes_when $true;
799 @*/
800$atomic_f int $comm_place($comm comm);
801/*@ depends_on \write(comm);
802 @ executes_when $true;
803 @*/
[39c2026]804$system[comm] void $comm_enqueue($comm comm, $message message);
[7d856cc]805/*@ depends_on \write(comm);
806 @*/
[39c2026]807$system[comm] $message $comm_dequeue($comm comm, int source, int tag);
[7d856cc]808//======================== comm.cvl ========================
809struct $queue{
810 int length;
811 $message messages[];
812};
813struct $gcomm{
814 int nprocs;
815 $proc procs[];
816 _Bool isInit[];
817 $queue buf[][];
818};
819struct $comm{
820 int place;
821 $gcomm gcomm;
822};
823$message $message_pack(int source, int dest, int tag, void* data, int size)
824{
825 $message result;
826 result.source = source;
827 result.dest = dest;
828 result.tag = tag;
829 result.data = $bundle_pack(data, size);
830 result.size = size;
831 return result;
832}
833int $message_source($message message)
834{
835 return message.source;
836}
837int $message_tag($message message)
838{
839 return message.tag;
840}
841int $message_dest($message message)
842{
843 return message.dest;
844}
845int $message_size($message message)
846{
847 return message.size;
848}
849void $message_unpack($message message, void* buf, int size)
850{
851 $bundle_unpack(message.data, buf);
852 $assert(message.size <= size, "Message of size %d exceeds the specified size %d.", message.size, size);
853}
[dba07d0]854int $comm_place($comm comm)
[7d856cc]855{
856 return (comm)->place;
857}
858//======================== civlc.cvh =======================
859/*@ depends_on \nothing;
860 @*/
[39c2026]861$system[civlc] void $assert(_Bool expr, ...);
[7d856cc]862/*@ depends_on \nothing;
863 @*/
[39c2026]864$system[civlc] void $assume(_Bool expr);
[dba07d0]865/*@ pure;
866 @ depends_on \nothing;
867 @*/
868$system[civlc] void $elaborate(int x);
[7d856cc]869/*@ depends_on \nothing;
870 @*/
[39c2026]871$system[civlc] void $assert(_Bool expr, ...);
[7d856cc]872/*@ depends_on \nothing;
873 @*/
[39c2026]874$system[civlc] void $assume(_Bool expr);
[7d856cc]875/*@ pure;
[39c2026]876 @ depends_on \nothing;
877 @*/
[dba07d0]878$system[civlc] void $elaborate(int x);
879//======================= bundle.cvh =======================
880/*@ pure;
[7d856cc]881 @*/
[dba07d0]882$system[bundle] $bundle $bundle_pack(void* ptr, int size);
[39c2026]883$system[bundle] void $bundle_unpack($bundle bundle, void* ptr);
[7d856cc]884//========================= seq.cvh ========================
[39c2026]885$system[seq] void $seq_init(void* array, int count, void* value);
[7d856cc]886//======================== civlc.cvh =======================
887/*@ depends_on \nothing;
888 @*/
[39c2026]889$system[civlc] void $assert(_Bool expr, ...);
[7d856cc]890/*@ depends_on \nothing;
891 @*/
[39c2026]892$system[civlc] void $assume(_Bool expr);
[dba07d0]893/*@ pure;
894 @ depends_on \nothing;
895 @*/
896$system[civlc] void $elaborate(int x);
[7d856cc]897//========================= stdio.h ========================
[39c2026]898$system[stdio] int printf(char* restrict format, ...);
[7d856cc]899//========================== mpi.h =========================
900int MPI_Send(void*, int, MPI_Datatype, int, int, MPI_Comm);
901int MPI_Recv(void*, int, MPI_Datatype, int, int, MPI_Comm, MPI_Status*);
902int MPI_Get_count(MPI_Status*, MPI_Datatype, int*);
903int MPI_Comm_size(MPI_Comm, int*);
904int MPI_Comm_rank(MPI_Comm, int*);
905//======================= sum_array.c ======================
906$input int _gen_argc;
907$input char _gen_argv[10][];
908$input long NB = 20;
909$input long N;
910//===================== MPITransformer =====================
911$input int _mpi_nprocs;
912$input int _mpi_nprocs_lo = 1;
913//======================= sum_array.c ======================
914$input int _mpi_nprocs_hi = 8;
915//===================== MPITransformer =====================
916$assume((_mpi_nprocs_lo <= _mpi_nprocs) && (_mpi_nprocs <= _mpi_nprocs_hi));
917$mpi_gcomm _mpi_gcomm = $mpi_gcomm_create($here, _mpi_nprocs);
918$mpi_gcomm _mpi_gcomms[];
919$seq_init(&(_mpi_gcomms), 1, &(_mpi_gcomm));
920void _mpi_process(int _mpi_rank)
921{
922 $mpi_sys_status _mpi_status = __UNINIT;
923 $assert(_mpi_status == __UNINIT);
924 MPI_Comm MPI_COMM_WORLD = $mpi_comm_create($here, _mpi_gcomm, _mpi_rank);
[39c2026]925 $system[sum_array] void $assume(_Bool expression);
[7d856cc]926 $assume((0 < _gen_argc) && (_gen_argc < 10));
927 $assume((0 < N) && (N <= NB));
928 double oracle;
929 void master(void);
930 void slave(void);
931 int _gen_main(int argc, char** argv)
932 {
933 int myrank;
934 $mpi_init();
935 MPI_Comm_rank(MPI_COMM_WORLD, &(myrank));
936 if (!myrank)
937 master();
938 else
939 slave();
940 $mpi_finalize();
941 return 0;
942 }
943 void master(void)
944 {
945 float array[N];
946 double mysum;
947 double tmpsum;
948 unsigned long long step;
949 unsigned long long i;
950 int size;
951 MPI_Status status;
952 for (i = 0; i < N; i = i + 1)
953 array[i] = i + 1;
954 oracle = 0.0;
955 for (i = 0; i < N; i = i + 1)
956 oracle = oracle + (array[i]);
957 MPI_Comm_size(MPI_COMM_WORLD, &(size));
958 if (size != 1)
[39c2026]959 step = $int_div(N, size - 1);
[7d856cc]960 else
961 step = N;
962 for (i = 0; i < (size - 1); i = i + 1)
963 MPI_Send(array + (i * step), step, MPI_FLOAT, i + 1, 100, MPI_COMM_WORLD);
964 {
965 i = (size - 1) * step;
966 mysum = 0;
967 for (; i < N; i = i + 1)
968 mysum = mysum + (array[i]);
969 }
970 for (i = 1; i < size; )
971 {
972 MPI_Recv(&(tmpsum), 1, MPI_DOUBLE, -1, 101, MPI_COMM_WORLD, &(status));
973 mysum = mysum + tmpsum;
974 i = i + 1;
975 }
976 $assert(oracle == mysum, "The sum of %d array elements is %f but the expected one is %f.\n", N, mysum, oracle);
977 printf("%lf\n", mysum);
978 }
979 void slave(void)
980 {
981 float array[N];
982 double sum;
983 unsigned long long i;
984 int count;
985 MPI_Status status;
986 MPI_Recv(array, N, MPI_FLOAT, 0, 100, MPI_COMM_WORLD, &(status));
987 MPI_Get_count(&(status), MPI_FLOAT, &(count));
988 {
989 i = 0;
990 sum = 0;
991 for (; i < count; i = i + 1)
992 sum = sum + (array[i]);
993 }
994 MPI_Send(&(sum), 1, MPI_DOUBLE, 0, 101, MPI_COMM_WORLD);
995 }
996 {
997 char* _gen_argv_tmp[10];
998 {
999 int i = 0;
1000 for (; i < 10; i = i + 1)
1001 _gen_argv_tmp[i] = &(_gen_argv[i][0]);
1002 }
1003 _gen_main(_gen_argc, &(_gen_argv_tmp[0]));
1004 }
1005 $mpi_comm_destroy(MPI_COMM_WORLD);
1006}
1007int main()
1008{
1009 $parfor (int i: 0 .. _mpi_nprocs - 1)
1010 _mpi_process(i);
1011 $mpi_gcomm_destroy(_mpi_gcomm);
1012}
Note: See TracBrowser for help on using the repository browser.