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