forked from ammarhakim/gkyl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathZeroArray.lua
535 lines (488 loc) · 15.7 KB
/
ZeroArray.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
-- Gkyl ------------------------------------------------------------------------
--
-- Lua interface to gkylzero's gkyl_array structure
---
-- _______ ___
-- + 6 @ |||| # P ||| +
--------------------------------------------------------------------------------
-- system libraries
local ffi = require "ffi"
local ffiC = ffi.C
local xsys = require "xsys"
local new, sizeof, typeof, metatype = xsys.from(ffi,
"new, sizeof, typeof, metatype")
local Alloc = require "Lib.Alloc"
local cuda
require "Lib.ZeroUtil"
_M = {}
ffi.cdef [[
/**
* Array object. This is an untype, undimensioned, reference counted
* array object. All additional structure is provided else where,
* mainly by the range object.
*/
struct gkyl_array {
enum gkyl_elem_type type; // type of data stored in array
size_t elemsz, ncomp; // size of elements, number of 'components'
size_t size; // number of indices
size_t esznc; // elemsz*ncomp
void *_data; // pointer to data
uint32_t flags;
struct gkyl_ref_count ref_count;
int nthreads, nblocks; // threads per block, number of blocks
struct gkyl_array *on_dev; // pointer to itself or device data
};
/**
* Create new array. Delete using gkyl_array_release method.
*
* @param type Type of data in array
* @param ncomp Number of components at each index
* @param size Number of indices
* @return Pointer to newly allocated array.
*/
struct gkyl_array* gkyl_array_new(enum gkyl_elem_type type, size_t ncomp, size_t size);
/**
* Create new array with data on NV-GPU. Delete using
* gkyl_array_release method.
*
* NOTE: the data member lives on GPU, but the struct lives on the
* host. However, the on_dev member for this cal is set to a device
* clone of the host struct, and is what should be used to pass to
* CUDA kernels which require the entire array struct on device.
*
* @param type Type of data in array
* @param ncomp Number of components at each index
* @param size Number of indices
* @return Pointer to newly allocated array.
*/
struct gkyl_array* gkyl_array_cu_dev_new(enum gkyl_elem_type type, size_t ncomp, size_t size);
/**
* Create new array with host-pinned data for use with NV-GPU. Delete using
* gkyl_array_release method.
*
* @param type Type of data in array
* @param ncomp Number of components at each index
* @param size Number of indices
* @return Pointer to newly allocated array.
*/
struct gkyl_array* gkyl_array_cu_host_new(enum gkyl_elem_type type, size_t ncomp, size_t size);
/**
* Returns true if array lives on NV-GPU.
*
* @param arr Array to check
* @return true of array lives on NV-GPU, false otherwise
*/
bool gkyl_array_is_cu_dev(const struct gkyl_array *arr);
enum gkyl_array_op { GKYL_MIN, GKYL_MAX, GKYL_SUM };
/**
* Copy into array: pointer to dest array is returned. 'dest' and
* 'src' must not point to same data.
*
* @param dest Destination for copy.
* @param src Srouce to copy from.
* @return dest is returned
*/
struct gkyl_array* gkyl_array_copy(struct gkyl_array* dest,
const struct gkyl_array* src);
/**
* Copy into array using async methods for cuda arrays: pointer to dest array is returned. 'dest' and
* 'src' must not point to same data.
*
* @param dest Destination for copy.
* @param src Srouce to copy from.
* @return dest is returned
*/
struct gkyl_array* gkyl_array_copy_async(struct gkyl_array* dest,
const struct gkyl_array* src);
/**
* Clone array: pointer to newly created array is returned.
*
* @param arr Array to clone
* @return Pointer to clone
*/
struct gkyl_array* gkyl_array_clone(const struct gkyl_array* arr);
/**
* Clear out = val. Returns out.
*
* @param out Output array
* @param val Factor to set
* @return out array
*/
struct gkyl_array* gkyl_array_clear(struct gkyl_array *out, double val);
/**
* Compute out = out + a*inp. Returns out.
*
* @param out Output array
* @param a Factor to multiply input array
* @param inp Input array
* @return out array
*/
struct gkyl_array* gkyl_array_accumulate(struct gkyl_array *out,
double a, const struct gkyl_array *inp);
/**
* Compute out = out + a*inp[coff] where coff is a component-offset if
* out->ncomp < inp->ncomp, or out[coff] = out[coff]+ a*inp if
* out->ncomp > inp->ncomp. Returns out.
*
* @param out Output array
* @param a Factor to multiply input array
* @param inp Input array
* @param coff Component offset
* @return out array
*/
struct gkyl_array* gkyl_array_accumulate_offset(struct gkyl_array *out,
double a, const struct gkyl_array *inp, int coff);
/**
* Set out = a*inp. Returns out.
*
* @param out Output array
* @param a Factor to multiply input array
* @param inp Input array
* @return out array
*/
struct gkyl_array* gkyl_array_set(struct gkyl_array *out,
double a, const struct gkyl_array *inp);
/**
* Set out = a*inp[coff] where coff is a component-offset if
* out->ncomp < inp->ncomp, or out[coff] = a*inp if
* out->ncomp > inp->ncomp. Returns out.
*
* @param out Output array
* @param a Factor to multiply input array
* @param inp Input array
* @param coff Component offset
* @return out array
*/
struct gkyl_array* gkyl_array_set_offset(struct gkyl_array *out,
double a, const struct gkyl_array *inp, int coff);
/**
* Scale out = a*out. Returns out.
*
* @param out Output array
* @param a Factor to scale
* @return out array
*/
struct gkyl_array* gkyl_array_scale(struct gkyl_array *out, double a);
struct gkyl_array* gkyl_array_scale_by_cell(struct gkyl_array *out, const struct gkyl_array *a);
/**
* Shift the k-th coefficient in every cell, out_k = a+out_k. Returns out.
*
* @param out Output array.
* @param a Factor to shift k-th coefficient by.
* @param k Coefficient to be shifted.
* @return out array.
*/
struct gkyl_array* gkyl_array_shiftc(struct gkyl_array *out, double a, unsigned k);
/**
* Clear out = val. Returns out.
*
* @param out Output array
* @param val Factor to set
* @return out array
*/
struct gkyl_array* gkyl_array_clear_range(struct gkyl_array *out, double val,
const struct gkyl_range *range);
/**
* Compute out = out + a*inp over a range of indices.
*
* @param out Output array
* @param a Factor to multiply input array
* @param inp Input array
* @param range Range specifying region to accumulate
* @return out array
*/
struct gkyl_array* gkyl_array_accumulate_range(struct gkyl_array *out,
double a, const struct gkyl_array *inp, const struct gkyl_range *range);
/**
* Compute out = out + a*inp[coff] where coff is a component-offset if
* out->ncomp < inp->ncomp, or out[coff] = out[coff]+ a*inp if
* out->ncomp > inp->ncomp, over a range of indices. Returns out.
*
* @param out Output array
* @param a Factor to multiply input array
* @param inp Input array
* @param coff Component offset
* @return out array
*/
struct gkyl_array* gkyl_array_accumulate_offset_range(struct gkyl_array *out,
double a, const struct gkyl_array *inp, int coff, const struct gkyl_range *range);
/**
* Set out = a*inp. Returns out.
*
* @param out Output array
* @param a Factor to multiply input array
* @param inp Input array
* @return out array
* @param range Range specifying region to set
*/
struct gkyl_array* gkyl_array_set_range(struct gkyl_array *out,
double a, const struct gkyl_array *inp, const struct gkyl_range *range);
/**
* Set out = a*inp[coff] where coff is a component-offset if
* out->ncomp < inp->ncomp, or out[coff] = a*inp if
* out->ncomp > inp->ncomp, over a range of indices. Returns out.
*
* @param out Output array
* @param a Factor to multiply input array
* @param inp Input array
* @return out array
* @param range Range specifying region to set
*/
struct gkyl_array* gkyl_array_set_offset_range(struct gkyl_array *out,
double a, const struct gkyl_array *inp, int coff, const struct gkyl_range *range);
/**
* Scale out = a*ut. Returns out.
*
* @param out Output array
* @param a Factor to scale by
* @return out array
* @param range Range specifying region to scale
*/
struct gkyl_array* gkyl_array_scale_range(struct gkyl_array *out,
double a, const struct gkyl_range *range);
/**
* Shift the k-th coefficient in every cell, out_k = a+out_k within
* a given range. Returns out.
*
* @param out Output array.
* @param a Factor to shift k-th coefficient by.
* @param k Coefficient to be shifted.
* @param range Range to shift coefficient k in.
* @return out array.
*/
struct gkyl_array* gkyl_array_shiftc_range(struct gkyl_array *out, double a,
unsigned k, const struct gkyl_range *range);
/**
* Shift the k-th coefficient in every cell, out_k = a+out_k within
* a given range. Returns out.
*
* @param out Output array.
* @param a Factor to shift k-th coefficient by.
* @param k Coefficient to be shifted.
* @param range Range to shift coefficient k in.
* @return out array.
*/
struct gkyl_array* gkyl_array_shiftc_range(struct gkyl_array *out, double a,
unsigned k, struct gkyl_range range);
/**
* Copy out inp. Returns out.
*
* @param out Output array
* @param inp Input array
* @param range Range specifying region to copy
* @return out array
*/
struct gkyl_array* gkyl_array_copy_range(struct gkyl_array *out,
const struct gkyl_array *inp, const struct gkyl_range *range);
/**
* Copy out inp over specified ranges. Returns out.
* input and output ranges must have the same volume.
*
* @param out Output array
* @param inp Input array
* @param out_range Range specifying region to copy to in out array
* @param inp_range Range specifying region to copy to from in inp array
* @return out array
*/
struct gkyl_array* gkyl_array_copy_range_to_range(struct gkyl_array *out,
const struct gkyl_array *inp, struct gkyl_range *out_range, struct gkyl_range *inp_range);
/**
* Perform an "reduce" operation of data in the array.
*
* @param res On output, reduces values (ncomp size)
* @param arr Array to perform reduction on.
* @param op Reduction operators
*/
void gkyl_array_reduce(double *res, const struct gkyl_array *arr, enum gkyl_array_op op);
/**
* Perform an "reduce" operation of data in the array. Data is reduced
* component-wise.
*
* @param res On output, reduced values (ncomp size)
* @param arr Array to perform reduction on.
* @param op Reduction operators
* @param range Range specifying region
*/
void gkyl_array_reduce_range(double *res,
const struct gkyl_array *arr, enum gkyl_array_op op, const struct gkyl_range *range);
/**
* Copy region of array into a buffer. The buffer must be preallocated
* and at least of size arr->size*arr->elemSz bytes.
*
* @param arr Array to copy from
* @param data Output data buffer.
* @param range Range specifying region to copy from
*/
void gkyl_array_copy_to_buffer(void *data, const struct gkyl_array *arr,
struct gkyl_range *range);
/**
* Copy buffer into region of array. The array must be preallocated.
*
* @param arr Array to copy into
* @param data Input data buffer.
* @param range Range specifying region to copy into
*/
void gkyl_array_copy_from_buffer(struct gkyl_array *arr,
const void *data, struct gkyl_range *range);
/**
* Release pointer to array
*
* @param arr Array to release.
*/
void gkyl_array_release(const struct gkyl_array* arr);
]]
local longSz = sizeof("long")
-- Various types for arrays of basic C-types
_M.int = 'GKYL_INT'
_M.int64 = 'GKYL_INT64'
_M.float = 'GKYL_FLOAT'
_M.double = 'GKYL_DOUBLE'
_M.long = typeof('long')
_M.char = typeof('char')
local function getArrayTypeCode(atype)
if atype == typeof("int") then
return 1
elseif atype == typeof("int64") then
return 2
elseif atype == typeof("float") then
return 3
elseif atype == typeof("double") then
return 4
end
return 42 -- user-defined type
end
local function getType(enum)
if enum == 0 then
return "int"
elseif enum == 1 then
return "int64"
elseif enum == 2 then
return "float"
elseif enum == 3 then
return "double"
end
end
-- Array ctype
local ArrayCt = typeof("struct gkyl_array")
local array_fn = {
copy = function (self, src)
return ffiC.gkyl_array_copy(self, src)
end,
copyAsync = function (self, src)
return ffiC.gkyl_array_copy_async(self, src)
end,
clone = function (self)
return ffiC.gkyl_array_clone(self)
end,
aquire = function (self)
return ffiC.gkyl_array_acquire(self)
end,
data = function (self)
return self:fetch(0)
end,
fetch = function (self, loc)
if loc == nil then loc = 0 end
return ffi.cast(getType(self.type).."*", self._data) + loc*self.ncomp
end,
cfetch = function (self, loc)
if loc == nil then loc = 0 end
return ffi.cast("const "..getType(self.type).."*", self._data) + loc*self.ncomp
end,
get_size = function (self)
return tonumber(self.size)
end,
get_ncomp = function (self)
return tonumber(self.ncomp)
end,
get_elemsz = function (self)
return tonumber(self.elemsz)
end,
clear = function (self, val)
ffiC.gkyl_array_clear(self, val)
end,
clearRange = function (self, val, rng)
ffiC.gkyl_array_clear_range(self, val, rng)
end,
set = function (self, val, fld)
ffiC.gkyl_array_set(self, val, fld)
end,
setOffset = function (self, val, fld, off)
ffiC.gkyl_array_set_offset(self, val, fld, off)
end,
accumulate = function (self, val, fld)
ffiC.gkyl_array_accumulate(self, val, fld)
end,
accumulateOffset = function (self, val, fld, off)
ffiC.gkyl_array_accumulate_offset(self, val, fld, off)
end,
setRange = function (self, val, fld, rng)
ffiC.gkyl_array_set_range(self, val, fld, rng)
end,
setOffsetRange = function (self, val, fld, off, rng)
ffiC.gkyl_array_set_offset_range(self, val, fld, off, rng)
end,
copyRangeToRange = function (self, infld, outrng, inrng)
ffiC.gkyl_array_copy_range_to_range(self, infld, outrng, inrng)
end,
copyRange = function (self, infld, inrng)
ffiC.gkyl_array_copy_range(self, infld, inrng)
end,
accumulateRange = function (self, val, fld, rng)
ffiC.gkyl_array_accumulate_range(self, val, fld, rng)
end,
accumulateOffsetRange = function (self, val, fld, off, rng)
ffiC.gkyl_array_accumulate_offset_range(self, val, fld, off, rng)
end,
scale = function (self, val)
ffiC.gkyl_array_scale(self, val)
end,
scale_by_cell = function (self, val)
ffiC.gkyl_array_scale_by_cell(self, val)
end,
shiftc = function (self, val, comp)
ffiC.gkyl_array_shiftc(self, val, comp)
end,
shiftcRange = function (self, val, comp, rng)
ffiC.gkyl_array_shiftc_range(self, val, comp, rng)
end,
reduceRange = function (self, out, op, rng)
if op == "min" then
enum = 0
elseif op == "max" then
enum = 1
elseif op == "sum" then
enum = 2
end
ffiC.gkyl_array_reduce_range(out, self, enum, rng)
end,
copy_to_buffer = function (self, data, rng)
ffiC.gkyl_array_copy_to_buffer(data, self, rng)
end,
copy_from_buffer = function (self, data, rng)
ffiC.gkyl_array_copy_from_buffer(self, data, rng)
end,
is_cu_dev = function (self)
return ffiC.gkyl_array_is_cu_dev(self)
end,
}
local array_mt = {
__new = function (self, atype, ncomp, size, on_gpu)
if on_gpu==1 then
return ffi.gc(ffiC.gkyl_array_cu_dev_new(atype, ncomp, size),
ffiC.gkyl_array_release)
elseif on_gpu==2 then
return ffi.gc(ffiC.gkyl_array_cu_host_new(atype, ncomp, size),
ffiC.gkyl_array_release)
else
return ffi.gc(ffiC.gkyl_array_new(atype, ncomp, size),
ffiC.gkyl_array_release)
end
end,
__index = array_fn,
}
local ArrayCtor = metatype(ArrayCt, array_mt)
-- Construct array of given shape and type
_M.Array = function (atype, ncomp, size, on_gpu)
return ArrayCtor(atype, ncomp, size, on_gpu)
end
return _M