source: CIVL/text/include/mpi.cvl@ 05ab4e3

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

get rid of mpi.h and mpi-common.h

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

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