1 /**
2 * @file gpcapi.c
3 *
4 * Implements the C interface.
5 * These calls forward to the (possibly) weak symbols of the internal
6 * implementations.
7 */
8 #if HAVE_CONFIG_H
9 # include "config.h"
10 #endif
11
12 #include <stdio.h>
13 #include <stdlib.h>
14
15 #include "gp.h"
16 #include "gpbase.h"
17 #include "gp-papi.h"
18
19 #if ENABLE_PROFILING
20 # include "gp-wapi.h"
21 #else
22 # include "gp-wapidefs.h"
23 #endif
24
25 #ifdef USE_FAPI
26 # define COPYC2F(carr, farr, n){\
27 int i; for(i=0; i< (n); i++)(farr)[i]=(Integer)(carr)[i];}
28 # define COPYF2C(farr, carr, n){\
29 int i; for(i=0; i< (n); i++)(carr)[i]=(int)(farr)[i];}
30 # define COPYINDEX_F2C COPYF2C
31 #else
32 # define COPYC2F(carr, farr, n){\
33 int i; for(i=0; i< (n); i++)(farr)[n-i-1]=(Integer)(carr)[i];}
34 # define COPYINDEX_C2F(carr, farr, n){\
35 int i; for(i=0; i< (n); i++)(farr)[n-i-1]=(Integer)(carr)[i]+1;}
36 # define COPYINDEX_F2C(farr, carr, n){\
37 int i; for(i=0; i< (n); i++)(carr)[n-i-1]=(int)(farr)[i] -1;}
38 #endif
39
40 static Integer* gp_copy_map(int block[], int block_ndim, int map[]);
41
GP_Access_element(int g_p,int * subscript,void * ptr,int * size)42 void GP_Access_element(int g_p, int *subscript, void *ptr, int *size)
43 {
44 Integer ag_p = (Integer)g_p;
45 Integer _gp_idx[GP_MAX_DIM];
46 Integer asize;
47 int ndim = wgp_get_dimension(ag_p);
48 COPYINDEX_C2F(subscript,_gp_idx,ndim);
49 wgp_access_element(ag_p, _gp_idx, ptr, &asize);
50 *size = (int)asize;
51 }
52
GP_Allocate(int g_p)53 int GP_Allocate(int g_p)
54 {
55 Integer ag_p;
56 ag_p = (Integer)g_p;
57 return (int)wgp_allocate(ag_p);
58 }
59
GP_Assign_local_element(int g_p,int * subscript,void * ptr,int size)60 void GP_Assign_local_element(int g_p, int *subscript, void *ptr, int size)
61 {
62 Integer ag_p = (Integer)g_p;
63 Integer _gp_idx[GP_MAX_DIM];
64 Integer asize = (Integer)size;
65 int ndim = wgp_get_dimension(ag_p);
66 COPYINDEX_C2F(subscript,_gp_idx,ndim);
67 wgp_assign_local_element(ag_p, _gp_idx, ptr, asize, 4);
68 }
69
GP_Create_handle()70 int GP_Create_handle()
71 {
72 return (int)wgp_create_handle();
73 }
74
GP_Debug(int g_p)75 void GP_Debug(int g_p)
76 {
77 Integer ag_p;
78 ag_p = (Integer)g_p;
79 wgp_debug(ag_p, 4);
80 }
81
GP_Destroy(int g_p)82 int GP_Destroy(int g_p)
83 {
84 Integer ag_p;
85 ag_p = (Integer)g_p;
86 return (int)wgp_destroy(ag_p);
87 }
88
GP_Distribution(int g_p,int proc,int * lo,int * hi)89 void GP_Distribution(int g_p, int proc, int *lo, int *hi)
90 {
91 Integer ag_p = (Integer)g_p;
92 Integer p = (Integer)proc;
93 int ndim = (int)wgp_get_dimension(ag_p);
94 Integer _gp_lo[GP_MAX_DIM], _gp_hi[GP_MAX_DIM];
95 wgp_distribution(ag_p, p, _gp_lo, _gp_hi);
96 COPYINDEX_F2C(_gp_lo, lo, ndim);
97 COPYINDEX_F2C(_gp_hi, hi, ndim);
98 }
99
GP_Free(void * ptr)100 void GP_Free(void* ptr)
101 {
102 wgp_free(ptr);
103 }
104
GP_Free_local_element(int g_p,int * subscript)105 void* GP_Free_local_element(int g_p, int *subscript)
106 {
107 Integer ag_p = (Integer)g_p;
108 int ndim = wgp_get_dimension(ag_p);
109 Integer _gp_idx[GP_MAX_DIM];
110 COPYINDEX_C2F(subscript, _gp_idx, ndim);
111 return wgp_free_local_element(ag_p, _gp_idx);
112 }
113
GP_Get_dimension(int g_p)114 int GP_Get_dimension(int g_p)
115 {
116 return wgp_get_dimension(g_p);
117 }
118
GP_Gather_size(int g_p,int nv,int * subscript,int * size)119 void GP_Gather_size(int g_p, int nv, int *subscript, int *size)
120 {
121 int idx, i;
122 Integer ag_p = (Integer)g_p;
123 Integer anv = (Integer)nv;
124 Integer asize;
125 Integer *asubscript;
126 int ndim = wgp_get_dimension(ag_p);
127 asubscript = (Integer*)malloc((int)ndim*nv*sizeof(Integer));
128 if (asubscript == NULL)
129 GA_Error("Memory allocation in GP_Gather_size failed",0);
130
131 /* adjust the indices for fortran interface */
132 for (idx=0; idx<nv; idx++) {
133 for (i=0; i<ndim; i++) {
134 asubscript[idx*ndim +(ndim-i-1)] = subscript[idx*ndim+i] + 1;
135 }
136 }
137
138 wgp_gather_size(ag_p, anv, asubscript, &asize, 4);
139
140 *size = (int)asize;
141
142 free(asubscript);
143 }
144
GP_Gather(int g_p,int nv,int * subscript,void * buf,void ** buf_ptr,int * buf_size,int * size,int setbuf)145 void GP_Gather(int g_p, int nv, int *subscript, void *buf, void **buf_ptr,
146 int *buf_size, int *size, int setbuf)
147 {
148 int idx, i;
149 Integer ag_p = (Integer)g_p;
150 Integer anv = (Integer)nv;
151 Integer aset = (Integer)setbuf;
152 Integer asize;
153 Integer *asubscript;
154 int ndim = wgp_get_dimension(ag_p);
155 asubscript = (Integer*)malloc((int)ndim*nv*sizeof(Integer));
156 if (asubscript == NULL)
157 GA_Error("Memory allocation in GP_Gather failed",0);
158
159 /* adjust the indices for fortran interface */
160 for (idx=0; idx<nv; idx++)
161 for (i=0; i<ndim; i++)
162 asubscript[idx*ndim +(ndim-i-1)] = subscript[idx*ndim+i] + 1;
163
164 wgp_gather(ag_p, anv, asubscript, buf, buf_ptr, buf_size, &asize, 4, aset);
165
166 *size = (int)asize;
167
168 free(asubscript);
169 }
170
GP_Get_size(int g_p,int * lo,int * hi,int * size)171 void GP_Get_size(int g_p, int *lo, int *hi, int *size)
172 {
173 Integer ag_p = (Integer)g_p;
174 int ndim = wgp_get_dimension(ag_p);
175 Integer asize;
176 Integer _gp_lo[GP_MAX_DIM], _gp_hi[GP_MAX_DIM];
177 COPYINDEX_C2F(lo, _gp_lo, ndim);
178 COPYINDEX_C2F(hi, _gp_hi, ndim);
179 wgp_get_size(ag_p, _gp_lo, _gp_hi, &asize, 4);
180 *size = (int)asize;
181 }
182
GP_Get(int g_p,int * lo,int * hi,void * buf,void ** buf_ptr,int * ld,void * buf_size,int * ld_sz,int * size,int setbuf)183 void GP_Get(int g_p, int *lo, int *hi, void *buf, void **buf_ptr, int *ld,
184 void *buf_size, int *ld_sz, int *size, int setbuf)
185 {
186 Integer ag_p = (Integer)g_p;
187 int ndim = wgp_get_dimension(ag_p);
188 Integer asize;
189 Integer asetbuf = (Integer)setbuf;
190 Integer _gp_lo[GP_MAX_DIM], _gp_hi[GP_MAX_DIM];
191 Integer _gp_ld[GP_MAX_DIM], _gp_ld_sz[GP_MAX_DIM];
192 COPYINDEX_C2F(lo, _gp_lo, ndim);
193 COPYINDEX_C2F(hi, _gp_hi, ndim);
194 COPYC2F(ld, _gp_ld, ndim-1);
195 COPYC2F(ld_sz, _gp_ld_sz, ndim-1);
196 wgp_get(ag_p, _gp_lo, _gp_hi, buf, buf_ptr, _gp_ld,
197 buf_size, _gp_ld_sz, &asize, 4, asetbuf);
198 *size = (int)asize;
199 }
200
GP_Initialize()201 void GP_Initialize()
202 {
203 wgp_initialize();
204 }
205
GP_Malloc(size_t size)206 void* GP_Malloc(size_t size)
207 {
208 return wgp_malloc(size);
209 }
210
GP_Memzero(int g_p)211 void GP_Memzero(int g_p)
212 {
213 Integer ag_p;
214 ag_p = (Integer)g_p;
215 wgp_memzero(ag_p, 4);
216 }
217
GP_Put(int g_p,int * lo,int * hi,void ** buf_ptr,int * ld,void * buf_size,int * ld_sz,int * size,int checksize)218 void GP_Put(int g_p, int *lo, int *hi, void **buf_ptr, int *ld,
219 void *buf_size, int *ld_sz, int *size, int checksize)
220 {
221 Integer ag_p = (Integer)g_p;
222 int ndim = wgp_get_dimension(ag_p);
223 Integer achecksize = (Integer)checksize;
224 Integer asize;
225 Integer _gp_lo[GP_MAX_DIM], _gp_hi[GP_MAX_DIM];
226 Integer _gp_ld[GP_MAX_DIM], _gp_ld_sz[GP_MAX_DIM];
227 COPYINDEX_C2F(lo, _gp_lo, ndim);
228 COPYINDEX_C2F(hi, _gp_hi, ndim);
229 COPYC2F(ld, _gp_ld, ndim-1);
230 COPYC2F(ld_sz, _gp_ld_sz, ndim-1);
231 wgp_put(ag_p, _gp_lo, _gp_hi, buf_ptr, _gp_ld,
232 buf_size, _gp_ld_sz, &asize, achecksize, 4);
233 *size = (int)asize;
234 }
235
GP_Release_element(int g_p,int * subscript)236 void GP_Release_element(int g_p, int *subscript)
237 {
238 Integer ag_p = (Integer)g_p;
239 Integer _gp_idx[GP_MAX_DIM];
240 int ndim = wgp_get_dimension(ag_p);
241 COPYINDEX_C2F(subscript,_gp_idx,ndim);
242 wgp_release_element(ag_p, _gp_idx);
243 }
244
GP_Release_update_element(int g_p,int * subscript)245 void GP_Release_update_element(int g_p, int *subscript)
246 {
247 Integer ag_p = (Integer)g_p;
248 Integer _gp_idx[GP_MAX_DIM];
249 int ndim = wgp_get_dimension(ag_p);
250 COPYINDEX_C2F(subscript,_gp_idx,ndim);
251 wgp_release_update_element(ag_p, _gp_idx);
252 }
253
GP_Scatter(int g_p,int nv,int * subscript,void ** buf_ptr,int * buf_size,int * size,int checksize)254 void GP_Scatter(int g_p, int nv, int *subscript, void **buf_ptr,
255 int *buf_size, int *size, int checksize)
256 {
257 int idx, i;
258 Integer ag_p = (Integer)g_p;
259 Integer anv = (Integer)nv;
260 Integer asize;
261 Integer acheck = (Integer)checksize;
262 Integer *asubscript;
263 int ndim = wgp_get_dimension(ag_p);
264 asubscript = (Integer*)malloc((int)ndim*nv*sizeof(Integer));
265 if (asubscript == NULL)
266 GA_Error("Memory allocation in GP_Scatter failed",0);
267
268 /* adjust the indices for fortran interface */
269 for (idx=0; idx<nv; idx++)
270 for (i=0; i<ndim; i++)
271 asubscript[idx*ndim +(ndim-i-1)] = subscript[idx*ndim+i] + 1;
272
273 wgp_scatter(ag_p, anv, asubscript, buf_ptr, buf_size, &asize, acheck, 4);
274
275 *size = (int)asize;
276
277 free(asubscript);
278 }
279
GP_Set_chunk(int g_p,int * chunk)280 void GP_Set_chunk(int g_p, int *chunk)
281 {
282 Integer ag_p;
283 Integer _gp_chunk[GP_MAX_DIM];
284 int ndim;
285 ag_p = (Integer)g_p;
286 ndim = (int)wgp_get_dimension(ag_p);
287 COPYC2F(chunk,_gp_chunk,ndim);
288 wgp_set_chunk(ag_p, _gp_chunk);
289 }
290
GP_Set_dimensions(int g_p,int ndim,int * dims)291 void GP_Set_dimensions(int g_p, int ndim, int *dims)
292 {
293 Integer ag_p, andim;
294 Integer _gp_dims[GP_MAX_DIM];
295 COPYC2F(dims,_gp_dims,ndim);
296 ag_p = (Integer)g_p;
297 andim = (Integer)ndim;
298 wgp_set_dimensions(ag_p, andim, _gp_dims, 4);
299 }
300
GP_Set_irreg_distr(int g_p,int * mapc,int * nblock)301 void GP_Set_irreg_distr(int g_p, int *mapc, int *nblock)
302 {
303 Integer ag_p, andim;
304 Integer ablock[GP_MAX_DIM];
305 Integer *amapc;
306 ag_p = (Integer)g_p;
307 andim = (int)wgp_get_dimension(ag_p);
308 COPYC2F(nblock,ablock,andim);
309 amapc = gp_copy_map(nblock, (int)andim, mapc);
310 wgp_set_irreg_distr(ag_p, amapc, ablock);
311 free(amapc);
312 }
313
GP_Sync()314 void GP_Sync()
315 {
316 wgp_sync();
317 }
318
GP_Terminate()319 void GP_Terminate()
320 {
321 wgp_terminate();
322 }
323
324 /* Internal utility functions */
325
gp_copy_map(int block[],int block_ndim,int map[])326 static Integer* gp_copy_map(int block[], int block_ndim, int map[])
327 {
328 int d;
329 int i,sum=0,capi_offset=0,map_offset=0;
330 Integer *_ga_map_capi;
331
332 for (d=0; d<block_ndim; d++) {
333 sum += block[d];
334 }
335
336 _ga_map_capi = (Integer*)malloc(sum * sizeof(Integer));
337
338 capi_offset = sum;
339 for (d=0; d<block_ndim; d++) {
340 capi_offset -= block[d];
341 for (i=0; i<block[d]; i++) {
342 _ga_map_capi[capi_offset+i] = map[map_offset+i] + 1;
343 }
344 map_offset += block[d];
345 }
346
347 return _ga_map_capi;
348 }
349