6
* MPI_SPAWN: ARMCI on top of MPI Multithreaded
32
#define ARMCI_ROOT 0 /* root process */
34
/* Inter-communicators for communicating between clients and data servers */
35
MPI_Comm MPI_COMM_CLIENT2SERVER=MPI_COMM_NULL;
37
static int armci_nserver=-1;
38
static int *_armci_mpi_tag=NULL;
40
extern char ***_armci_argv;
41
extern int armci_get_shmem_info(char *addrp, int* shmid, long *shmoffset,
45
void armci_mpi2_debug(int rank, const char *format, ...)
50
va_start(arg, format);
58
#define armci_mpi2_debug(x, ...)
62
static inline int MPI_Check (int status)
64
if(status != MPI_SUCCESS)
66
armci_mpi2_debug(armci_me, "MPI Check failed.\n");
67
armci_die("MPI_Check failed.", 0);
71
# define MPI_Check(x) x
75
/**************************************************************************
76
* Platform specific server code as required by the ARMCI s/w layer. (BEGIN)
79
/* Create connections between clients and servers */
80
void armci_init_connections()
82
armci_mpi2_debug(0, "armci_init_connections\n");
83
_armci_buf_init(); /* CHECK: Is this correct ? */
84
MPI_Check(MPI_Barrier(ARMCI_COMM_WORLD));
86
armci_create_server_MPIprocess();
88
armci_mpi2_debug(0, "armci_init_connections completed\n");
91
void armci_wait_for_server()
93
armci_mpi2_debug(0, "armci_wait_for_server: wait for server to quit\n");
94
if (armci_me == armci_master)
100
void armci_client_connect_to_servers()
106
/* NOTE: armci_mpi_strided and armci_mpi_strided2 are the only 2 functions
107
* that are common to client and server part */
108
void armci_mpi_strided_c2s(int op, void *ptr, int stride_levels, int stride_arr[],
109
int count[], int proc, MPI_Comm comm)
112
long idx; /* index offset of current block position to ptr */
113
int n1dim; /* number of 1 dim block */
114
int bvalue[MAX_STRIDE_LEVEL], bunit[MAX_STRIDE_LEVEL];
117
/* number of n-element of the first dimension */
119
for(i=1; i<=stride_levels; i++)
122
/* calculate the destination indices */
123
bvalue[0] = 0; bvalue[1] = 0; bunit[0] = 1; bunit[1] = 1;
124
for(i=2; i<=stride_levels; i++)
127
bunit[i] = bunit[i-1] * count[i-1];
130
for(i=0; i<n1dim; i++)
133
for(j=1; j<=stride_levels; j++)
135
idx += bvalue[j] * stride_arr[j-1];
136
if((i+1) % bunit[j] == 0) bvalue[j]++;
137
if(bvalue[j] > (count[j]-1)) bvalue[j] = 0;
143
MPI_Send(((char*)ptr)+idx, count[0], MPI_BYTE, proc,
144
ARMCI_MPI_CLIENT2SERVER_TAG, comm)
147
else /* ( op == RECV) */
150
MPI_Recv(((char*)ptr)+idx, count[0], MPI_BYTE, proc,
151
ARMCI_MPI_SERVER2CLIENT_TAG, comm, &status)
157
/* This is the only function that is common to client and server part */
158
void armci_mpi_strided2(int op, void *ptr, int stride_levels, int stride_arr[],
159
int count[], int proc, MPI_Comm comm)
165
/*\ client sends request message to server
167
int armci_send_req_msg (int proc, void *buf, int bytes)
169
int clus_id = armci_clus_id(proc);
173
server = armci_clus_info[clus_id].master;
175
armci_mpi2_debug(armci_me, "armci_send_req_msg(): proc=%d, server=%d, "
176
"buf=%p, bytes=%d\n", proc, server, buf, bytes);
179
MPI_Send(buf, bytes, MPI_BYTE, server, ARMCI_MPI_CLIENT2SERVER_TAG,
182
armci_mpi2_debug(armci_me, "armci_send_req_msg(): send msg to server(%d), to"
183
"fwd to client %d\n", server, proc);
188
/*\ client sends strided data + request to server
190
int armci_send_req_msg_strided(int proc, request_header_t *msginfo,char *ptr,
191
int strides, int stride_arr[], int count[])
194
int clus_id = armci_clus_id(proc);
198
server = armci_clus_info[clus_id].master;
200
armci_mpi2_debug(armci_me, "armci_send_req_msg_strided: proc=%d server=%d "
201
"bytes=%d (op=%d)\n", proc, server, msginfo->datalen,
205
/* we write header + descriptor of strided data */
206
bytes = sizeof(request_header_t) + msginfo->dscrlen;
207
armci_send_req_msg(proc, msginfo, bytes);
210
/* for larger blocks write directly thus avoiding memcopy */
211
armci_mpi_strided_c2s(SEND, ptr, strides, stride_arr, count, server,
216
armci_mpi2_debug(armci_me, "armci_send_req_msg_strided(): send msg to "
217
"server(%d), to fwd to client %d\n", server, proc);
222
/*\ client receives data from server
224
char *armci_ReadFromDirect (int proc, request_header_t *msginfo, int len)
228
int clus_id = armci_clus_id(proc);
231
server = armci_clus_info[clus_id].master;
233
armci_mpi2_debug(armci_me, "armci_ReadFromDirect: proc=%d, server=%d, "
234
"msginfo=%p, bytes=%d (op=%d)\n", proc, server, msginfo,
235
len, msginfo->operation);
237
MPI_Recv(msginfo + 1, len, MPI_BYTE, server, ARMCI_MPI_SERVER2CLIENT_TAG,
238
ARMCI_COMM_WORLD, &status)
242
armci_mpi2_debug(armci_me, "recv msg from server(%d), fwd by client %d\n",
247
MPI_Get_count(&status, MPI_BYTE, &count);
250
armci_mpi2_debug(armci_me, "armci_ReadFromDirect: got %d bytes, "
251
"expected %d bytes\n", count, len);
252
armci_die("armci_ReadFromDirect: MPI_Recv failed.", count);
256
return (char *) (msginfo+1);
259
/*\ client receives strided data from server
261
void armci_ReadStridedFromDirect(int proc, request_header_t* msginfo,
262
void *ptr, int strides, int stride_arr[],
267
int clus_id = armci_clus_id(proc);
270
server = armci_clus_info[clus_id].master;
272
armci_mpi2_debug(armci_me, "armci_ReadStridedFromDirect: proc=%d "
273
"stride_levels=%d, server=%d bytes=%d (op=%d)\n",
274
proc, strides, server, msginfo->datalen,
278
armci_mpi_strided_c2s(RECV, ptr, strides, stride_arr, count, server,
286
* Platform specific server code ENDs here. (END)
287
**************************************************************************/
289
static void armci_gather_hostnames(char **hostname_arr)
291
/* Code must not flow through here */
298
* Create server processes. This is called in armci_start_server.
299
* Must be called after armci_init_clusinfo().
301
void armci_create_server_MPIprocess ()
303
int rank, size, flag, i;
305
MPI_Check(MPI_Initialized(&flag));
307
armci_die("ARMCI error: MPI_Init must be called before PARMCI_Init()",0);
309
MPI_Check(MPI_Comm_rank(ARMCI_COMM_WORLD, &rank));
310
MPI_Check(MPI_Comm_size(ARMCI_COMM_WORLD, &size));
312
armci_nserver = armci_nclus;
314
/* makesure all processes sync here. CHECK: does it ensure global sync ? */
315
MPI_Check(MPI_Barrier(ARMCI_COMM_WORLD));
317
armci_mpi2_debug(0, "armci_create_server_MPIprocess: Servers spawned!\n");