5
/* $Id: gpc.c,v 1.7.4.4 2007-06-13 00:44:01 vinod Exp $ *****************************************************
6
Prototype of Global Procedure Calls.
7
July/03 JN - shared memory version
9
*************************************************************/
17
#define GPC_OFFSET -100
18
static void *_table[GPC_SLOTS]={
19
(void*)0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0,
20
(void*)0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0,
21
(void*)0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0,
22
(void*)0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0};
24
#if (defined(LAPI) || defined(GM) || defined(VAPI) || defined(QUADRICS)) && ARMCI_ENABLE_GPC_CALLS
26
/*\ callback functions must be registered -- user gets int handle back
28
int ARMCI_Gpc_register( int (*func) ())
30
int handle =-1, candidate = 0;
34
if(!_table[candidate]){
36
_table[candidate]=func;
39
}while(candidate < GPC_SLOTS && handle == -1);
40
return(GPC_OFFSET-handle);
43
/*\ release/deassociate handle with previously registered callback function
45
void ARMCI_Gpc_release(int handle)
47
int h = -handle + GPC_OFFSET;
50
if(h<0 || h >= GPC_SLOTS) armci_die("ARMCI_Gpc_release: bad handle",h);
56
/*\ Send Request to Execute callback function in a global address space
58
* f - handle to the callback function
59
* p - remote processor
60
* hdr - header data - used to pack extra args for callback (local buffer)
61
* hlen - size of header data < ARMCI_GPC_HLEN
62
* data - bulk data passed to callback (local buffer)
63
* dlen - length of bulk data
64
* rhdr - ptr to reply header (return args from callback)
65
* rhlen - length of buffer to store reply header < ARMCI_GPC_HLEN
66
* rdata - ptr to where reply data from callback should be stored (local buf)
67
* rdlen - size of the buffer to store reply data
68
* nbh - nonblocking handle
71
int ARMCI_Gpc_exec(int h, int p, void *hdr, int hlen, void *data, int dlen,
72
void *rhdr, int rhlen, void *rdata, int rdlen, gpc_hdl_t* nbh)
74
int hnd = -h + GPC_OFFSET;
76
armci_hdl_t *ahdl = (nbh ? &(nbh->ahdl): NULL);
78
if(hnd <0 || hnd>= GPC_SLOTS)
79
err += fprintf(stderr, "ARMCI_Gpc_exec: bad callback handle %d: %d\n",hnd,GPC_SLOTS);
81
err += fprintf(stderr, "ARMCI_Gpc_exec: NULL function %d",hnd);
83
if(hlen<0 || hlen>=ARMCI_Gpc_get_hlen())
84
err += fprintf(stderr, "ARMCI_Gpc_exec: Invalid send header size %d %d\n", hlen, ARMCI_Gpc_get_hlen());
85
if(rhlen<0 || rhlen>=ARMCI_Gpc_get_hlen())
86
err += fprintf(stderr, "ARMCI_Gpc_exec: Invalid recv header size %d %d\n", rhlen, ARMCI_Gpc_get_hlen());
87
if(dlen<0 || dlen>=ARMCI_Gpc_get_dlen())
88
err += fprintf(stderr, "ARMCI_Gpc_exec: Invalid send data size %d %d\n", dlen, ARMCI_Gpc_get_dlen());
89
if(rdlen<0 || rdlen>=ARMCI_Gpc_get_dlen())
90
err += fprintf(stderr, "ARMCI_Gpc_exec: Invalid recv data size %d %d\n", rdlen, ARMCI_Gpc_get_dlen());
92
if(hlen>0 && hdr==NULL)
93
err += fprintf(stderr, "ARMCI_Gpc_exec: Null send header for non-zero header size %d\n", hlen);
94
if(rhlen>0 && rhdr==NULL)
95
err += fprintf(stderr, "ARMCI_Gpc_exec: Null recv header for non-zero header size %d\n", rhlen);
96
if(dlen>0 && data==NULL)
97
err += fprintf(stderr, "ARMCI_Gpc_exec: Null send data for non-zero data size %d\n", dlen);
98
if(rdlen>0 && rdata==NULL)
99
err += fprintf(stderr, "ARMCI_Gpc_exec: Null recv data for non-zero header size %d\n", rdlen);
101
if(p<0 || p >= armci_nproc)
102
err += fprintf(stderr, "ARMCI_Gpc_exec: Invalid target processor id %d\n", p, armci_nproc);
107
if(rhlen + rdlen == 0)
108
armci_die("Zero reply header + data length not yet supported", 0);
113
if(SAMECLUSNODE(p) && armci_nproc==1) {
117
/* fprintf(stderr, "%d:: armci gpc exec. SAMECLUSNODE\n", armci_me); */
120
if(func(p, armci_me, hdr, hlen, data, dlen, rhdr, rhlen, &rhsize,
121
rdata, rdlen, &rdsize, GPC_INIT) != GPC_DONE) {
122
func(p, armci_me, hdr, hlen, data, dlen, rhdr, rhlen, &rhsize,
123
rdata, rdlen, &rdsize, GPC_WAIT);
132
/* fprintf(stderr, "%d:: armci gpc exec. invoking armci gpc\n", armci_me); */
133
return armci_gpc(h, p, hdr, hlen, data, dlen,
134
rhdr, rhlen, rdata, rdlen, ahdl);
138
func - handle to the function executed at each process in the chain
139
callba- handle to the callback to be executed when
140
hdr - header data used to pack extra args for callback (local buffer)
141
hlen - size of header data < ARMCI_GPC_HLEN
142
data - bulk data passed to callback (local buffer)
143
dlen - length of bulk data
144
rhdr - ptr to reply header (return args from callback)
145
rhlen - length of buffer to store reply header < ARMCI_GPC_HLEN
146
rdata - ptr to where reply data from callback should be stored (local buf)
147
rdlen - size of the buffer to store reply data
148
idlen - number of ID's
149
idslst- list of id's in the chained GPC
150
nbh - nonblocking handle which also acts as a context for each individual
152
Tree - the id of tree function used (default is 0=>binary, 1=>binomial,
155
int ARMCI_Gpc_chained_exec(int func, int callback, void *hdr, int hlen,
156
void *data, int dlen, void *rhdr, int rhlen, void *rdata,
157
int rdlen, int idlen, int *idlst, gpc_hdl_t* nbh, int TREE)
160
int hnd = -func + GPC_OFFSET;
162
armci_hdl_t *ahdl = (nbh ? &(nbh->ahdl): NULL);
164
if(hnd <0 || hnd>= GPC_SLOTS)
165
err += fprintf(stderr, "ARMCI_Gpc_exec: bad callback handle %d: %d\n",hnd,GPC_SLOTS);
167
err += fprintf(stderr, "ARMCI_Gpc_exec: NULL function %d",hnd);
169
if(hlen<0 || hlen>=ARMCI_Gpc_get_hlen())
170
err += fprintf(stderr, "ARMCI_Gpc_exec: Invalid send header size %d %d\n", hlen, ARMCI_Gpc_get_hlen());
171
if(rhlen<0 || rhlen>=ARMCI_Gpc_get_hlen())
172
err += fprintf(stderr, "ARMCI_Gpc_exec: Invalid recv header size %d %d\n", rhlen, ARMCI_Gpc_get_hlen());
173
if(dlen<0 || dlen>=ARMCI_Gpc_get_dlen())
174
err += fprintf(stderr, "ARMCI_Gpc_exec: Invalid send data size %d %d\n", dlen, ARMCI_Gpc_get_dlen());
175
if(rdlen<0 || rdlen>=ARMCI_Gpc_get_dlen())
176
err += fprintf(stderr, "ARMCI_Gpc_exec: Invalid recv data size %d %d\n", rdlen, ARMCI_Gpc_get_dlen());
178
if(hlen>0 && hdr==NULL)
179
err += fprintf(stderr, "ARMCI_Gpc_exec: Null send header for non-zero header size %d\n", hlen);
180
if(rhlen>0 && rhdr==NULL)
181
err += fprintf(stderr, "ARMCI_Gpc_exec: Null recv header for non-zero header size %d\n", rhlen);
182
if(dlen>0 && data==NULL)
183
err += fprintf(stderr, "ARMCI_Gpc_exec: Null send data for non-zero data size %d\n", dlen);
184
if(rdlen>0 && rdata==NULL)
185
err += fprintf(stderr, "ARMCI_Gpc_exec: Null recv data for non-zero header size %d\n", rdlen);
187
if(p<0 || p >= armci_nproc)
188
err += fprintf(stderr, "ARMCI_Gpc_exec: Invalid target processor id %d\n", p, armci_nproc);
193
if(rhlen + rdlen == 0)
194
armci_die("Zero reply header + data length not yet supported", 0);
196
tree_id = armci_msg_generate_tree(idlst,idlen,id_tree,TREE);
201
if(SAMECLUSNODE(p) && armci_nproc==1) {
205
/* fprintf(stderr, "%d:: armci gpc exec. SAMECLUSNODE\n", armci_me); */
208
if(func(p, armci_me, hdr, hlen, data, dlen, rhdr, rhlen, &rhsize,
209
rdata, rdlen, &rdsize, GPC_INIT) != GPC_DONE) {
210
func(p, armci_me, hdr, hlen, data, dlen, rhdr, rhlen, &rhsize,
211
rdata, rdlen, &rdsize, GPC_WAIT);
219
/* fprintf(stderr, "%d:: armci gpc exec. invoking armci gpc\n", armci_me); */
220
return armci_gpc(h, p, hdr, hlen, data, dlen,
221
rhdr, rhlen, rdata, rdlen, ahdl);
227
int armci_gpc_local_exec(int h, int to, int from, void *hdr, int hlen,
228
void *data, int dlen,
229
void *rhdr, int rhlen,
230
void *rdata, int rdlen, int rtype) {
233
int hnd = -h + GPC_OFFSET;
235
if(hnd <0 || hnd>= GPC_SLOTS)
236
armci_die2("armci_gpc_local_exec: bad callback handle",hnd,GPC_SLOTS);
237
if(!_table[hnd]) armci_die("armci_gpc_local_exec: NULL function",hnd);
241
if(!SAMECLUSNODE(to))
242
armci_die("armci_gpc_local_exec: GPC call to a different node received!",
245
/* func(to, from, hdr, hlen, data, dlen, rhdr, rhlen, &rhsize, */
246
/* rdata, rdlen, &rdsize); */
248
return func(to, from, hdr, hlen, data, dlen, rhdr, rhlen, &rhsize,
249
rdata, rdlen, &rdsize, rtype);
253
* This is a template for the callback function
254
* The arguments are passed as specified in ARMCI_Gpc_exec
256
* rhsize specifies the actual size of reply header data returned
257
* rdsize specifies the actual size of reply data returned
259
int example_func(int to, int from, void *hdr, int hlen,
260
void *data, int dlen,
261
void *rhdr, int rhlen, int *rhsize,
262
void *rdata, int rdlen, int *rdsize,
267
void armci_gpc_set_serverpid(){
273
* Translate pointer to memory on processor "proc"
274
* to be used in a callback function send by processor "from"
276
void * ARMCI_Gpc_translate(void *ptr, int proc, int from)
282
/*\ acquire lock in a callback function executed in context of processor "proc"
284
void ARMCI_Gpc_lock(int proc)
286
#if defined(CLUSTER) && !defined(SGIALTIX)
287
int lock = (proc-armci_clus_info[armci_clus_id(proc)].master)%NUM_LOCKS;
291
NATIVE_LOCK(lock,proc);
294
/*\ try acquire lock in a callback function to be executed in context of
296
* return value: 1 - success
297
* 0 - failure (already locked by another thread)
299
int ARMCI_Gpc_trylock(int proc)
301
armci_die("ARMCI_Gpc_trylock: not yet implemented",0);
305
/*\ release lock in a callback function executed in context of processor "proc"
307
void ARMCI_Gpc_unlock(int proc)
309
#if defined(CLUSTER) && !defined(SGIALTIX)
310
int lock = (proc-armci_clus_info[armci_clus_id(proc)].master)%NUM_LOCKS;
314
NATIVE_UNLOCK(lock,proc);
317
void ARMCI_Gpc_init_handle(gpc_hdl_t *nbh) {
318
nbh->proc = armci_me;
319
ARMCI_INIT_HANDLE(&nbh->ahdl);
322
void ARMCI_Gpc_wait(gpc_hdl_t *nbh) {
323
if(SAMECLUSNODE(nbh->proc))
325
PARMCI_Wait(&nbh->ahdl);
328
void ARMCI_Gpc_test(gpc_hdl_t *nbh) {
329
if(SAMECLUSNODE(nbh->proc))
331
PARMCI_Test(&nbh->ahdl);
334
#define ARMCI_GPC_HLEN 65536
335
#define ARMCI_GPC_DLEN 65536
336
int ARMCI_Gpc_get_hlen() {
337
return ARMCI_GPC_HLEN;
340
int ARMCI_Gpc_get_dlen() {
341
return ARMCI_GPC_DLEN;