source: CIVL/examples/backend/mpiSumarray.cvl@ 635d292

1.23 2.0 main test-branch
Last change on this file since 635d292 was c3bddc1, checked in by Manchun Zheng <zmanchun@…>, 10 years ago

fixed a bug in the enabler for handling atomic blocks.

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

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