Nek5000
SEM for Incompressible NS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
gs_local.c
Go to the documentation of this file.
1 #include <string.h>
2 #include <limits.h>
3 #include <float.h>
4 #include "c99.h"
5 #include "name.h"
6 #include "types.h"
7 
8 #define gs_gather_array PREFIXED_NAME(gs_gather_array )
9 #define gs_init_array PREFIXED_NAME(gs_init_array )
10 #define gs_gather PREFIXED_NAME(gs_gather )
11 #define gs_scatter PREFIXED_NAME(gs_scatter )
12 #define gs_init PREFIXED_NAME(gs_init )
13 #define gs_gather_vec PREFIXED_NAME(gs_gather_vec )
14 #define gs_scatter_vec PREFIXED_NAME(gs_scatter_vec )
15 #define gs_init_vec PREFIXED_NAME(gs_init_vec )
16 #define gs_gather_many PREFIXED_NAME(gs_gather_many )
17 #define gs_scatter_many PREFIXED_NAME(gs_scatter_many )
18 #define gs_init_many PREFIXED_NAME(gs_init_many )
19 #define gs_gather_vec_to_many PREFIXED_NAME(gs_gather_vec_to_many )
20 #define gs_scatter_many_to_vec PREFIXED_NAME(gs_scatter_many_to_vec)
21 #define gs_scatter_vec_to_many PREFIXED_NAME(gs_scatter_vec_to_many)
22 
23 #include "gs_defs.h"
26 
27 /*------------------------------------------------------------------------------
28  The array gather kernel
29 ------------------------------------------------------------------------------*/
30 #define DEFINE_GATHER(T,OP) \
31 static void gather_array_##T##_##OP( \
32  T *restrict out, const T *restrict in, uint n) \
33 { \
34  for(;n;--n) { T q = *in++, *p = out++; GS_DO_##OP(*p,q); } \
35 }
36 
37 /*------------------------------------------------------------------------------
38  The array initialization kernel
39 ------------------------------------------------------------------------------*/
40 #define DEFINE_INIT(T) \
41 static void init_array_##T(T *restrict out, uint n, gs_op op) \
42 { \
43  const T e = gs_identity_##T[op]; \
44  for(;n;--n) *out++=e; \
45 }
46 
47 #define DEFINE_PROCS(T) \
48  GS_FOR_EACH_OP(T,DEFINE_GATHER) \
49  DEFINE_INIT(T)
50 
52 
53 #undef DEFINE_PROCS
54 #undef DEFINE_INIT
55 #undef DEFINE_GATHER
56 
57 /*------------------------------------------------------------------------------
58  The basic gather kernel
59 ------------------------------------------------------------------------------*/
60 #define DEFINE_GATHER(T,OP) \
61 static void gather_##T##_##OP( \
62  T *restrict out, const T *restrict in, const unsigned in_stride, \
63  const uint *restrict map) \
64 { \
65  uint i,j; \
66  while((i=*map++)!=-(uint)1) { \
67  T t=out[i]; \
68  j=*map++; do GS_DO_##OP(t,in[j*in_stride]); while((j=*map++)!=-(uint)1); \
69  out[i]=t; \
70  } \
71 }
72 
73 /*------------------------------------------------------------------------------
74  The basic scatter kernel
75 ------------------------------------------------------------------------------*/
76 #define DEFINE_SCATTER(T) \
77 static void scatter_##T( \
78  T *restrict out, const unsigned out_stride, \
79  const T *restrict in, const unsigned in_stride, \
80  const uint *restrict map) \
81 { \
82  uint i,j; \
83  while((i=*map++)!=-(uint)1) { \
84  T t=in[i*in_stride]; \
85  j=*map++; do out[j*out_stride]=t; while((j=*map++)!=-(uint)1); \
86  } \
87 }
88 
89 /*------------------------------------------------------------------------------
90  The basic initialization kernel
91 ------------------------------------------------------------------------------*/
92 #define DEFINE_INIT(T) \
93 static void init_##T(T *restrict out, const uint *restrict map, gs_op op) \
94 { \
95  uint i; const T e = gs_identity_##T[op]; \
96  while((i=*map++)!=-(uint)1) out[i]=e; \
97 }
98 
99 #define DEFINE_PROCS(T) \
100  GS_FOR_EACH_OP(T,DEFINE_GATHER) \
101  DEFINE_SCATTER(T) \
102  DEFINE_INIT(T)
103 
105 
106 #undef DEFINE_PROCS
107 #undef DEFINE_INIT
108 #undef DEFINE_SCATTER
109 #undef DEFINE_GATHER
110 
111 /*------------------------------------------------------------------------------
112  The vector gather kernel
113 ------------------------------------------------------------------------------*/
114 #define DEFINE_GATHER(T,OP) \
115 static void gather_vec_##T##_##OP( \
116  T *restrict out, const T *restrict in, const unsigned vn, \
117  const uint *restrict map) \
118 { \
119  uint i,j; \
120  while((i=*map++)!=-(uint)1) { \
121  T *restrict p = &out[i*vn], *pe = p+vn; \
122  j=*map++; do { \
123  const T *restrict q = &in[j*vn]; \
124  T *restrict pk=p; do { GS_DO_##OP(*pk,*q); ++pk, ++q; } while(pk!=pe); \
125  } while((j=*map++)!=-(uint)1); \
126  } \
127 }
128 
129 /*------------------------------------------------------------------------------
130  The vector scatter kernel
131 ------------------------------------------------------------------------------*/
133  void *restrict out, const void *restrict in, const unsigned vn,
134  const uint *restrict map, gs_dom dom)
135 {
136  unsigned unit_size = vn*gs_dom_size[dom];
137  uint i,j;
138  while((i=*map++)!=-(uint)1) {
139  const char *t = (const char *)in + i*unit_size;
140  j=*map++; do
141  memcpy((char *)out+j*unit_size,t,unit_size);
142  while((j=*map++)!=-(uint)1);
143  }
144 }
145 
146 /*------------------------------------------------------------------------------
147  The vector initialization kernel
148 ------------------------------------------------------------------------------*/
149 #define DEFINE_INIT(T) \
150 static void init_vec_##T(T *restrict out, const unsigned vn, \
151  const uint *restrict map, gs_op op) \
152 { \
153  uint i; const T e = gs_identity_##T[op]; \
154  while((i=*map++)!=-(uint)1) { \
155  T *restrict u = (T*)out + vn*i, *ue = u+vn; \
156  do *u++ = e; while(u!=ue); \
157  } \
158 }
159 
160 #define DEFINE_PROCS(T) \
161  GS_FOR_EACH_OP(T,DEFINE_GATHER) \
162  DEFINE_INIT(T)
163 
165 
166 #undef DEFINE_PROCS
167 #undef DEFINE_INIT
168 #undef DEFINE_GATHER
169 
170 #undef DO_bpr
171 #undef DO_max
172 #undef DO_min
173 #undef DO_mul
174 #undef DO_add
175 
176 #define SWITCH_DOMAIN_CASE(T) case gs_##T: WITH_DOMAIN(T); break;
177 #define SWITCH_DOMAIN(dom) do switch(dom) { \
178  GS_FOR_EACH_DOMAIN(SWITCH_DOMAIN_CASE) case gs_dom_n: break; } while(0)
179 
180 #define SWITCH_OP_CASE(T,OP) case gs_##OP: WITH_OP(T,OP); break;
181 #define SWITCH_OP(T,op) do switch(op) { \
182  GS_FOR_EACH_OP(T,SWITCH_OP_CASE) case gs_op_n: break; } while(0)
183 
184 /*------------------------------------------------------------------------------
185  Array kernels
186 ------------------------------------------------------------------------------*/
187 void gs_gather_array(void *out, const void *in, uint n, gs_dom dom, gs_op op)
188 {
189 #define WITH_OP(T,OP) gather_array_##T##_##OP(out,in,n)
190 #define WITH_DOMAIN(T) SWITCH_OP(T,op)
191  SWITCH_DOMAIN(dom);
192 #undef WITH_DOMAIN
193 #undef WITH_OP
194 }
195 
196 void gs_init_array(void *out, uint n, gs_dom dom, gs_op op)
197 {
198 #define WITH_DOMAIN(T) init_array_##T(out,n,op)
199  SWITCH_DOMAIN(dom);
200 #undef WITH_DOMAIN
201 }
202 
203 /*------------------------------------------------------------------------------
204  Plain kernels; vn parameter ignored but present for consistent signatures
205 ------------------------------------------------------------------------------*/
206 void gs_gather(void *out, const void *in, const unsigned vn,
207  const uint *map, gs_dom dom, gs_op op)
208 {
209 #define WITH_OP(T,OP) gather_##T##_##OP(out,in,1,map)
210 #define WITH_DOMAIN(T) SWITCH_OP(T,op)
211  SWITCH_DOMAIN(dom);
212 #undef WITH_DOMAIN
213 #undef WITH_OP
214 }
215 
216 void gs_scatter(void *out, const void *in, const unsigned vn,
217  const uint *map, gs_dom dom)
218 {
219 #define WITH_DOMAIN(T) scatter_##T(out,1,in,1,map)
220  SWITCH_DOMAIN(dom);
221 #undef WITH_DOMAIN
222 }
223 
224 void gs_init(void *out, const unsigned vn, const uint *map,
225  gs_dom dom, gs_op op)
226 {
227 #define WITH_DOMAIN(T) init_##T(out,map,op)
228  SWITCH_DOMAIN(dom);
229 #undef WITH_DOMAIN
230 }
231 
232 /*------------------------------------------------------------------------------
233  Vector kernels
234 ------------------------------------------------------------------------------*/
235 void gs_gather_vec(void *out, const void *in, const unsigned vn,
236  const uint *map, gs_dom dom, gs_op op)
237 {
238 #define WITH_OP(T,OP) gather_vec_##T##_##OP(out,in,vn,map)
239 #define WITH_DOMAIN(T) SWITCH_OP(T,op)
240  SWITCH_DOMAIN(dom);
241 #undef WITH_DOMAIN
242 #undef WITH_OP
243 }
244 
245 void gs_init_vec(void *out, const unsigned vn, const uint *map,
246  gs_dom dom, gs_op op)
247 {
248 #define WITH_DOMAIN(T) init_vec_##T(out,vn,map,op)
249  SWITCH_DOMAIN(dom);
250 #undef WITH_DOMAIN
251 }
252 
253 /*------------------------------------------------------------------------------
254  Multiple array kernels
255 ------------------------------------------------------------------------------*/
256 void gs_gather_many(void *out, const void *in, const unsigned vn,
257  const uint *map, gs_dom dom, gs_op op)
258 {
259  uint k;
260  typedef void *ptr_to_void; typedef const void *ptr_to_const_void;
261  const ptr_to_void *p = out; const ptr_to_const_void *q = in;
262 #define WITH_OP(T,OP) for(k=0;k<vn;++k) gather_##T##_##OP(p[k],q[k],1,map)
263 #define WITH_DOMAIN(T) SWITCH_OP(T,op)
264  SWITCH_DOMAIN(dom);
265 #undef WITH_DOMAIN
266 #undef WITH_OP
267 }
268 
269 void gs_scatter_many(void *out, const void *in, const unsigned vn,
270  const uint *map, gs_dom dom)
271 {
272  uint k;
273  typedef void *ptr_to_void; typedef const void *ptr_to_const_void;
274  const ptr_to_void *p = out; const ptr_to_const_void *q = in;
275 #define WITH_DOMAIN(T) for(k=0;k<vn;++k) scatter_##T(p[k],1,q[k],1,map)
276  SWITCH_DOMAIN(dom);
277 #undef WITH_DOMAIN
278 }
279 
280 void gs_init_many(void *out, const unsigned vn, const uint *map,
281  gs_dom dom, gs_op op)
282 {
283  uint k;
284  typedef void *ptr_to_void; const ptr_to_void *p = out;
285 #define WITH_DOMAIN(T) for(k=0;k<vn;++k) init_##T(p[k],map,op)
286  SWITCH_DOMAIN(dom);
287 #undef WITH_DOMAIN
288 }
289 
290 /*------------------------------------------------------------------------------
291  Gather from strided array -> multiple arrays
292  Scatter from multiple arrays -> strided array,
293  Scatter from strided array -> multiple arrays,
294 ------------------------------------------------------------------------------*/
295 void gs_gather_vec_to_many(void *out, const void *in, const unsigned vn,
296  const uint *map, gs_dom dom, gs_op op)
297 {
298  unsigned i; const unsigned unit_size = gs_dom_size[dom];
299  typedef void *ptr_to_void;
300  const ptr_to_void *p = out; const char *q = in;
301 #define WITH_OP(T,OP) \
302  for(i=vn;i;--i) gather_##T##_##OP(*p++,(const T*)q,vn,map), q+=unit_size
303 #define WITH_DOMAIN(T) SWITCH_OP(T,op)
304  SWITCH_DOMAIN(dom);
305 #undef WITH_DOMAIN
306 #undef WITH_OP
307 }
308 
309 void gs_scatter_many_to_vec(void *out, const void *in, const unsigned vn,
310  const uint *map, gs_dom dom)
311 {
312  unsigned i; const unsigned unit_size = gs_dom_size[dom];
313  typedef const void *ptr_to_const_void;
314  char *p = out; const ptr_to_const_void *q = in;
315 #define WITH_DOMAIN(T) \
316  for(i=vn;i;--i) scatter_##T((T*)p,vn,*q++,1,map), p+=unit_size
317  SWITCH_DOMAIN(dom);
318 #undef WITH_DOMAIN
319 }
320 
321 void gs_scatter_vec_to_many(void *out, const void *in, const unsigned vn,
322  const uint *map, gs_dom dom)
323 {
324  unsigned i; const unsigned unit_size = gs_dom_size[dom];
325  typedef void *ptr_to_void;
326  const ptr_to_void *p = out; const char *q = in;
327 #define WITH_DOMAIN(T) \
328  for(i=vn;i;--i) scatter_##T(*p++,1,(const T*)q,vn,map), q+=unit_size
329  SWITCH_DOMAIN(dom);
330 #undef WITH_DOMAIN
331 }
332 
333 #undef SWITCH_OP
334 #undef SWITCH_OP_CASE
335 #undef SWITCH_DOMAIN
336 #undef SWITCH_DOMAIN_CASE
#define uint
Definition: types.h:70
#define DEFINE_PROCS(T)
Definition: gs_local.c:160
#define gs_init_many
Definition: gs_local.c:18
#define SWITCH_DOMAIN(dom)
Definition: gs_local.c:177
n
Definition: xxt_test.m:73
#define gs_gather_vec
Definition: gs_local.c:13
#define gs_gather_array
Definition: gs_local.c:8
#define gs_scatter
Definition: gs_local.c:11
#define gs_gather_many
Definition: gs_local.c:16
gs_op
Definition: gs_defs.h:77
#define gs_init
Definition: gs_local.c:12
gs_dom
Definition: gs_defs.h:61
#define GS_DEFINE_IDENTITIES()
Definition: gs_defs.h:47
#define gs_scatter_many
Definition: gs_local.c:17
#define gs_scatter_vec
Definition: gs_local.c:14
p
Definition: xxt_test2.m:1
const gs_dom dom
Definition: gs_test.c:15
#define gs_gather
Definition: gs_local.c:10
#define restrict
Definition: c99.h:11
for i
Definition: xxt_test.m:74
#define gs_scatter_vec_to_many
Definition: gs_local.c:21
#define GS_FOR_EACH_DOMAIN(macro)
Definition: gs_defs.h:18
ulong out[N]
Definition: sort_test2.c:20
#define GS_DEFINE_DOM_SIZES()
Definition: gs_defs.h:70
establishes some macros to establish naming conventions
#define gs_init_vec
Definition: gs_local.c:15
#define gs_gather_vec_to_many
Definition: gs_local.c:19
#define gs_init_array
Definition: gs_local.c:9
#define gs_scatter_many_to_vec
Definition: gs_local.c:20