source: CIVL/examples/backend/mpiSumarray.cvl@ 682e8bb

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

change mpi_assert_consistent_basetype to mpi_check_buffer

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

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