source: CIVL/text/include/mpi.cvl@ ef9edbd

1.23 2.0 main test-branch
Last change on this file since ef9edbd was d8d938c, checked in by Ziqing Luo <ziqing@…>, 12 years ago

change for new assertion

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

  • Property mode set to 100644
File size: 4.8 KB
Line 
1#ifdef __CIVL_MPI__
2#else
3#define __CIVL_MPI__
4
5#include <concurrency.cvh>
6#include <bundle.cvh>
7#include <mpi.h>
8#include <civlmpi.cvh>
9#include <string.h>
10
11/* Completed definition for mpi-common.h */
12struct MPI_Status{
13 int MPI_SOURCE;
14 int MPI_TAG;
15 int MPI_ERROR;
16 int size;
17};
18
19struct MPI_Request{
20 int id;
21};
22
23struct MPI_Comm {
24 $comm p2p; // point-to-point communication
25 $comm col; // collective communication
26 $barrier barrier;
27 __MPI_Sys_status__ status;
28};
29
30/********************************** State *****************************************/
31/* The number of times the MPI_Wtime function has been called */
32int CMPI_time_count = 0;
33
34/************************** MPI LIB Implementations *******************************/
35double MPI_Wtime() {
36 double result = CMPI_time(CMPI_time_count);
37
38 CMPI_time_count++;
39 return result;
40}
41
42int MPI_Comm_size(MPI_Comm comm, int *size) {
43 $assert comm.status == __INIT :
44 "MPI_Comm_size() cannot be invoked without MPI_Init() being called before.\n";
45 *size = $comm_size(comm.p2p);
46 return 0;
47}
48
49int MPI_Comm_rank(MPI_Comm comm, int *rank) {
50 $assert comm.status == __INIT :
51 "MPI_Comm_rank() cannot be invoked without MPI_Init() being called before.\n";
52 *rank = $comm_place(comm.p2p);
53 return 0;
54}
55
56int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest,
57 int tag, MPI_Comm comm) {
58 $assert comm.status == __INIT :
59 "MPI_Send() cannot be invoked without MPI_Init() being called before.\n";
60 return CMPI_Send(buf, count, datatype, dest, tag, comm.p2p);
61}
62
63int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source,
64 int tag, MPI_Comm comm, MPI_Status *status) {
65 $assert comm.status == __INIT :
66 "MPI_Recv() cannot be invoked without "
67 "MPI_Init() being called before.\n";
68 return CMPI_Recv(buf, count, datatype, source, tag, comm.p2p, status);
69}
70
71int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count) {
72 *count = status->size/sizeofDatatype(datatype);
73 return 0;
74}
75
76int MPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
77 int dest, int sendtag,
78 void *recvbuf, int recvcount, MPI_Datatype recvtype,
79 int source, int recvtag,
80 MPI_Comm comm, MPI_Status *status) {
81 $assert comm.status == __INIT :
82 "MPI_Sendrecv() cannot be invoked "
83 "without MPI_Init() being called before.\n";
84 // not correct for checking potential deadlock...rewrite:
85 MPI_Send(sendbuf, sendcount, sendtype, dest, sendtag, comm);
86 MPI_Recv(recvbuf, recvcount, recvtype, source, recvtag, comm, status);
87 return 0;
88}
89
90/* Broadcasts a message from root to everyone else.
91 * Need to use a differnt comm.
92 */
93int MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root,
94 MPI_Comm comm) {
95 $assert comm.status == __INIT :
96 "MPI_Bcast() cannot be invoked without MPI_Init() "
97 "being called before.\n";
98 if ($comm_place(comm.col) == root) {
99 int nprocs = $comm_size(comm.col);
100
101 for (int i=0; i<nprocs; i++)
102 if (i != root)
103 CMPI_Send(buf, count, datatype, i, BCAST_TAG, comm.col);
104 } else {
105 CMPI_Recv(buf, count, datatype, root, BCAST_TAG, comm.col,
106 MPI_STATUS_IGNORE);
107 }
108 return 0;
109}
110
111/* Reduces values on all processes to a single value */
112int MPI_Reduce(void* sendbuf, void* recvbuf, int count,
113 MPI_Datatype datatype, MPI_Op op, int root,
114 MPI_Comm comm) {
115 int rank;
116
117 $assert comm.status == __INIT :
118 "MPI_Reduce() cannot be invoked without "
119 "MPI_Init() being called before.\n";
120 rank = $comm_place(comm.col);
121 if (rank != root)
122 CMPI_Send(sendbuf, count, datatype, root, REDUCE_TAG, comm.col);
123 else {
124 int nprocs = $comm_size(comm.col);
125 int size;
126
127 for (int i = 0; i<nprocs; i++) {
128 if(i == root) continue;
129 else{
130 $message in = $comm_dequeue(comm.col, i, REDUCE_TAG);
131 size = count * sizeofDatatype(datatype);
132
133 /* the third argument "count" indicates the number of cells needs doing the
134 operation. */
135 $bundle_unpack_apply(in.data, sendbuf, count, op);
136 $assert in.size <= size :
137 "Message of size %d exceeds the specified size %d.", in.size, size;
138 }
139 }
140 size = count * sizeofDatatype(datatype);
141 memcpy(recvbuf, sendbuf, size);
142 }
143 return 0;
144}
145
146/* Combines values from all processes and distributes the result back to all processes */
147/* default root is 0 */
148int MPI_Allreduce(void* sendbuf, void* recvbuf, int count,
149 MPI_Datatype datatype,
150 MPI_Op op, MPI_Comm comm) {
151 int root = 0;
152 MPI_Status status;
153
154 $assert comm.status == __INIT :
155 "MPI_Allreduce() cannot be invoked without "
156 "MPI_Init() being called before.\n";
157 MPI_Reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
158 MPI_Bcast(recvbuf, count, datatype, root, comm);
159 return 0;
160}
161
162int MPI_Barrier(MPI_Comm comm){
163 $assert comm.status == __INIT : "MPI_Allreduce() cannot be invoked without MPI_Init() being called before.\n";
164 $barrier_call(comm.barrier);
165}
166#endif
Note: See TracBrowser for help on using the repository browser.