source: CIVL/examples/contracts/contractsMPI/allgather.c@ 02876df

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

fix the transformation of waitsfor clauses

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

  • Property mode set to 100644
File size: 4.2 KB
Line 
1// How to get rid of BOUNDS ?
2/************************** source code **************************/
3#include<mpi.h>
4#include<civl-mpi.cvh>
5#include<civlc.cvh>
6#include<string.h>
7
8#define BUFFER_BOUND 3
9
10/*@
11 @ \mpi_collective(comm, P2P):
12 @ requires 0 <= root && root < \mpi_comm_size;
13 @ requires \mpi_agree(root) && \mpi_agree(count * \mpi_extent(datatype));
14 @ requires 0 <= count && count * \mpi_extent(datatype) < 5;
15 @ requires \mpi_valid(buf, count, datatype);
16 @ behavior root:
17 @ assumes \mpi_comm_rank == root;
18 @ behavior others:
19 @ assumes \mpi_comm_rank != root;
20 @ assigns \mpi_region(buf, count, datatype);
21 @ ensures \mpi_equals(buf, count, datatype, \on(root, buf));
22 @ waitsfor root;
23 @*/
24int broadcast(void * buf, int count,
25 MPI_Datatype datatype, int root, MPI_Comm comm) {
26 int nprocs, rank;
27 int tag = 999;
28
29 MPI_Comm_size(comm, &nprocs);
30 MPI_Comm_rank(comm, &rank);
31 if (rank == root) {
32 for (int i = 0; i < nprocs; i++)
33 if (i != root)
34 MPI_Send(buf, count, datatype, i, tag, comm);
35 } else
36 MPI_Recv(buf, count, datatype, root, tag, comm,
37 MPI_STATUS_IGNORE);
38 return 0;
39}
40
41/*@
42 @ \mpi_collective(comm, P2P) :
43 @ requires \mpi_agree(root) && \mpi_agree(sendcount * \mpi_extent(sendtype));
44 @ requires sendcount * \mpi_extent(sendtype) >= 0 && sendcount * \mpi_extent(sendtype) < 5;
45 @ requires recvcount * \mpi_extent(recvtype) >= 0 && recvcount * \mpi_extent(recvtype) < 5;
46 @ requires 0 <= root && root < \mpi_comm_size;
47 @ requires \mpi_valid(sendbuf, sendcount, sendtype);
48 @ behavior imroot:
49 @ assumes \mpi_comm_rank == root;
50 @ assigns \mpi_region(recvbuf, recvcount * \mpi_comm_size, recvtype);
51 @ requires \mpi_valid(recvbuf, recvcount * \mpi_comm_size, recvtype);
52 @ requires recvcount * \mpi_extent(recvtype) ==
53 @ sendcount * \mpi_extent(sendtype);
54 @ ensures \mpi_equals(\mpi_offset(recvbuf, root * sendcount, sendtype), sendcount, sendtype, sendbuf);
55 @ waitsfor (0 .. \mpi_comm_size-1);
56 @ behavior imnroot:
57 @ assumes \mpi_comm_rank != root;
58 @ ensures \mpi_equals(sendbuf, sendcount, sendtype,
59 @ \mpi_offset(\on(root, recvbuf), \mpi_comm_rank * sendcount, sendtype));
60 @*/
61int gather(void* sendbuf, int sendcount, MPI_Datatype sendtype,
62 void* recvbuf, int recvcount, MPI_Datatype recvtype,
63 int root, MPI_Comm comm){
64 int rank, nprocs;
65 MPI_Status status;
66 int tag = 998;
67
68 MPI_Comm_rank(comm, &rank);
69 MPI_Comm_size(comm, &nprocs);
70 if(root == rank) {
71 void *ptr;
72
73 ptr = $mpi_pointer_add(recvbuf, root * recvcount, recvtype);
74 memcpy(ptr, sendbuf, recvcount * sizeofDatatype(recvtype));
75 }else
76 MPI_Send(sendbuf, sendcount, sendtype, root, tag, comm);
77 if(rank == root) {
78 int real_recvcount;
79 int offset;
80
81 for(int i=0; i<nprocs; i++) {
82 if(i != root) {
83 void * ptr;
84
85 offset = i * recvcount;
86 ptr = $mpi_pointer_add(recvbuf, offset, recvtype);
87 MPI_Recv(ptr, recvcount, recvtype, i, tag, comm,
88 &status);
89 }
90 }
91 }
92 return 0;
93}
94
95/*@ \mpi_collective(comm, P2P):
96 @ requires \mpi_agree(sendcount * \mpi_extent(sendtype));
97 @ requires sendcount >= 0 && sendcount * \mpi_extent(sendtype) * \mpi_comm_size < 5;
98 @ requires recvcount >= 0 && recvcount * \mpi_extent(recvtype) * \mpi_comm_size < 5;
99 @ requires \mpi_valid(sendbuf, sendcount, sendtype);
100 @ requires \mpi_valid(recvbuf, recvcount * \mpi_comm_size, recvtype);
101 @ requires \mpi_extent(recvtype) * recvcount == \mpi_extent(sendtype) * sendcount;
102 @ //assigns \mpi_region(recvbuf, recvcount * \mpi_comm_size, recvtype);
103 @ ensures \mpi_agree(\mpi_region(recvbuf, recvcount * \mpi_comm_size, recvtype));
104 @ ensures \mpi_equals(sendbuf, sendcount, sendtype,
105 @ \mpi_offset(recvbuf, \mpi_comm_rank * recvcount, recvtype));
106 @
107 */
108int allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
109 void *recvbuf, int recvcount, MPI_Datatype recvtype,
110 MPI_Comm comm){
111 int place;
112 int nprocs;
113
114 MPI_Comm_rank(comm, &place);
115 MPI_Comm_size(comm, &nprocs);
116 gather(sendbuf, sendcount, sendtype,
117 recvbuf, recvcount, recvtype,
118 0, comm);
119 broadcast(recvbuf, recvcount*nprocs, recvtype, 0, comm);
120 return 0;
121}
Note: See TracBrowser for help on using the repository browser.