gumath 0.2.0dev5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +61 -0
- data/Gemfile +5 -0
- data/History.md +0 -0
- data/README.md +5 -0
- data/Rakefile +105 -0
- data/ext/ruby_gumath/examples.c +126 -0
- data/ext/ruby_gumath/extconf.rb +97 -0
- data/ext/ruby_gumath/functions.c +106 -0
- data/ext/ruby_gumath/gufunc_object.c +79 -0
- data/ext/ruby_gumath/gufunc_object.h +55 -0
- data/ext/ruby_gumath/gumath/AUTHORS.txt +5 -0
- data/ext/ruby_gumath/gumath/INSTALL.txt +42 -0
- data/ext/ruby_gumath/gumath/LICENSE.txt +29 -0
- data/ext/ruby_gumath/gumath/MANIFEST.in +3 -0
- data/ext/ruby_gumath/gumath/Makefile.in +62 -0
- data/ext/ruby_gumath/gumath/README.rst +20 -0
- data/ext/ruby_gumath/gumath/config.guess +1530 -0
- data/ext/ruby_gumath/gumath/config.h.in +52 -0
- data/ext/ruby_gumath/gumath/config.sub +1782 -0
- data/ext/ruby_gumath/gumath/configure +5049 -0
- data/ext/ruby_gumath/gumath/configure.ac +167 -0
- data/ext/ruby_gumath/gumath/doc/_static/copybutton.js +66 -0
- data/ext/ruby_gumath/gumath/doc/conf.py +26 -0
- data/ext/ruby_gumath/gumath/doc/gumath/functions.rst +62 -0
- data/ext/ruby_gumath/gumath/doc/gumath/index.rst +26 -0
- data/ext/ruby_gumath/gumath/doc/index.rst +45 -0
- data/ext/ruby_gumath/gumath/doc/libgumath/data-structures.rst +130 -0
- data/ext/ruby_gumath/gumath/doc/libgumath/functions.rst +78 -0
- data/ext/ruby_gumath/gumath/doc/libgumath/index.rst +25 -0
- data/ext/ruby_gumath/gumath/doc/libgumath/kernels.rst +41 -0
- data/ext/ruby_gumath/gumath/doc/releases/index.rst +11 -0
- data/ext/ruby_gumath/gumath/install-sh +527 -0
- data/ext/ruby_gumath/gumath/libgumath/Makefile.in +170 -0
- data/ext/ruby_gumath/gumath/libgumath/Makefile.vc +160 -0
- data/ext/ruby_gumath/gumath/libgumath/apply.c +201 -0
- data/ext/ruby_gumath/gumath/libgumath/extending/bfloat16.c +130 -0
- data/ext/ruby_gumath/gumath/libgumath/extending/examples.c +176 -0
- data/ext/ruby_gumath/gumath/libgumath/extending/graph.c +393 -0
- data/ext/ruby_gumath/gumath/libgumath/extending/pdist.c +140 -0
- data/ext/ruby_gumath/gumath/libgumath/extending/quaternion.c +156 -0
- data/ext/ruby_gumath/gumath/libgumath/func.c +177 -0
- data/ext/ruby_gumath/gumath/libgumath/gumath.h +205 -0
- data/ext/ruby_gumath/gumath/libgumath/kernels/binary.c +547 -0
- data/ext/ruby_gumath/gumath/libgumath/kernels/unary.c +449 -0
- data/ext/ruby_gumath/gumath/libgumath/nploops.c +219 -0
- data/ext/ruby_gumath/gumath/libgumath/tbl.c +223 -0
- data/ext/ruby_gumath/gumath/libgumath/thread.c +175 -0
- data/ext/ruby_gumath/gumath/libgumath/xndloops.c +130 -0
- data/ext/ruby_gumath/gumath/python/extending.py +24 -0
- data/ext/ruby_gumath/gumath/python/gumath/__init__.py +74 -0
- data/ext/ruby_gumath/gumath/python/gumath/_gumath.c +577 -0
- data/ext/ruby_gumath/gumath/python/gumath/examples.c +93 -0
- data/ext/ruby_gumath/gumath/python/gumath/functions.c +77 -0
- data/ext/ruby_gumath/gumath/python/gumath/pygumath.h +95 -0
- data/ext/ruby_gumath/gumath/python/test_gumath.py +405 -0
- data/ext/ruby_gumath/gumath/setup.py +298 -0
- data/ext/ruby_gumath/gumath/vcbuild/INSTALL.txt +36 -0
- data/ext/ruby_gumath/gumath/vcbuild/vcbuild32.bat +21 -0
- data/ext/ruby_gumath/gumath/vcbuild/vcbuild64.bat +21 -0
- data/ext/ruby_gumath/gumath/vcbuild/vcclean.bat +10 -0
- data/ext/ruby_gumath/gumath/vcbuild/vcdistclean.bat +11 -0
- data/ext/ruby_gumath/include/gumath.h +205 -0
- data/ext/ruby_gumath/include/ruby_gumath.h +41 -0
- data/ext/ruby_gumath/lib/libgumath.a +0 -0
- data/ext/ruby_gumath/lib/libgumath.so +1 -0
- data/ext/ruby_gumath/lib/libgumath.so.0 +1 -0
- data/ext/ruby_gumath/lib/libgumath.so.0.2.0dev3 +0 -0
- data/ext/ruby_gumath/ruby_gumath.c +295 -0
- data/ext/ruby_gumath/ruby_gumath.h +41 -0
- data/ext/ruby_gumath/ruby_gumath_internal.h +45 -0
- data/ext/ruby_gumath/util.c +68 -0
- data/ext/ruby_gumath/util.h +48 -0
- data/gumath.gemspec +47 -0
- data/lib/gumath.rb +7 -0
- data/lib/gumath/version.rb +5 -0
- data/lib/ruby_gumath.so +0 -0
- metadata +206 -0
@@ -0,0 +1,223 @@
|
|
1
|
+
/*
|
2
|
+
* BSD 3-Clause License
|
3
|
+
*
|
4
|
+
* Copyright (c) 2017-2018, plures
|
5
|
+
* All rights reserved.
|
6
|
+
*
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
8
|
+
* modification, are permitted provided that the following conditions are met:
|
9
|
+
*
|
10
|
+
* 1. Redistributions of source code must retain the above copyright notice,
|
11
|
+
* this list of conditions and the following disclaimer.
|
12
|
+
*
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
14
|
+
* this list of conditions and the following disclaimer in the documentation
|
15
|
+
* and/or other materials provided with the distribution.
|
16
|
+
*
|
17
|
+
* 3. Neither the name of the copyright holder nor the names of its
|
18
|
+
* contributors may be used to endorse or promote products derived from
|
19
|
+
* this software without specific prior written permission.
|
20
|
+
*
|
21
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
22
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
23
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
24
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
25
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
26
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
27
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
28
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
29
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
*/
|
32
|
+
|
33
|
+
|
34
|
+
#include <stdio.h>
|
35
|
+
#include <limits.h>
|
36
|
+
#include <stddef.h>
|
37
|
+
#include "gumath.h"
|
38
|
+
|
39
|
+
|
40
|
+
/*****************************************************************************/
|
41
|
+
/* Charmap */
|
42
|
+
/*****************************************************************************/
|
43
|
+
|
44
|
+
#define ALPHABET_LEN 64
|
45
|
+
|
46
|
+
static int code[UCHAR_MAX+1];
|
47
|
+
static unsigned char alpha[ALPHABET_LEN+1] =
|
48
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.";
|
49
|
+
|
50
|
+
static void
|
51
|
+
init_charmap(void)
|
52
|
+
{
|
53
|
+
int i;
|
54
|
+
|
55
|
+
for (i = 0; i < UCHAR_MAX+1; i++) {
|
56
|
+
code[i] = UCHAR_MAX;
|
57
|
+
}
|
58
|
+
|
59
|
+
for (i = 0; i < ALPHABET_LEN; i++) {
|
60
|
+
code[alpha[i]] = i;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
|
65
|
+
/*****************************************************************************/
|
66
|
+
/* Function tables */
|
67
|
+
/*****************************************************************************/
|
68
|
+
|
69
|
+
/* Function table */
|
70
|
+
struct _gm_tbl {
|
71
|
+
gm_func_t *value;
|
72
|
+
gm_tbl_t *next[];
|
73
|
+
};
|
74
|
+
|
75
|
+
gm_tbl_t *
|
76
|
+
gm_tbl_new(ndt_context_t *ctx)
|
77
|
+
{
|
78
|
+
gm_tbl_t *t;
|
79
|
+
int i;
|
80
|
+
|
81
|
+
t = ndt_alloc_size(offsetof(gm_tbl_t, next) + ALPHABET_LEN * (sizeof t));
|
82
|
+
if (t == NULL) {
|
83
|
+
return ndt_memory_error(ctx);
|
84
|
+
}
|
85
|
+
|
86
|
+
t->value = NULL;
|
87
|
+
|
88
|
+
for (i = 0; i < ALPHABET_LEN; i++) {
|
89
|
+
t->next[i] = NULL;
|
90
|
+
}
|
91
|
+
|
92
|
+
return t;
|
93
|
+
}
|
94
|
+
|
95
|
+
void
|
96
|
+
gm_tbl_del(gm_tbl_t *t)
|
97
|
+
{
|
98
|
+
int i;
|
99
|
+
|
100
|
+
if (t == NULL) {
|
101
|
+
return;
|
102
|
+
}
|
103
|
+
|
104
|
+
gm_func_del(t->value);
|
105
|
+
|
106
|
+
for (i = 0; i < ALPHABET_LEN; i++) {
|
107
|
+
gm_tbl_del(t->next[i]);
|
108
|
+
}
|
109
|
+
|
110
|
+
ndt_free(t);
|
111
|
+
}
|
112
|
+
|
113
|
+
int
|
114
|
+
gm_tbl_add(gm_tbl_t *tbl, const char *key, gm_func_t *value, ndt_context_t *ctx)
|
115
|
+
{
|
116
|
+
gm_tbl_t *t = tbl;
|
117
|
+
const unsigned char *cp;
|
118
|
+
int i;
|
119
|
+
|
120
|
+
for (cp = (const unsigned char *)key; *cp != '\0'; cp++) {
|
121
|
+
i = code[*cp];
|
122
|
+
if (i == UCHAR_MAX) {
|
123
|
+
ndt_err_format(ctx, NDT_ValueError,
|
124
|
+
"invalid character in function name: '%c'", *cp);
|
125
|
+
gm_func_del(value);
|
126
|
+
return -1;
|
127
|
+
}
|
128
|
+
|
129
|
+
if (t->next[i] == NULL) {
|
130
|
+
gm_tbl_t *u = gm_tbl_new(ctx);
|
131
|
+
if (u == NULL) {
|
132
|
+
gm_func_del(value);
|
133
|
+
return -1;
|
134
|
+
}
|
135
|
+
t->next[i] = u;
|
136
|
+
t = u;
|
137
|
+
}
|
138
|
+
else {
|
139
|
+
t = t->next[i];
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
if (t->value) {
|
144
|
+
ndt_err_format(ctx, NDT_ValueError, "duplicate function name '%s'", key);
|
145
|
+
gm_func_del(value);
|
146
|
+
return -1;
|
147
|
+
}
|
148
|
+
|
149
|
+
t->value = value;
|
150
|
+
return 0;
|
151
|
+
}
|
152
|
+
|
153
|
+
gm_func_t *
|
154
|
+
gm_tbl_find(const gm_tbl_t *tbl, const char *key, ndt_context_t *ctx)
|
155
|
+
{
|
156
|
+
const gm_tbl_t *t = tbl;
|
157
|
+
const unsigned char *cp;
|
158
|
+
int i;
|
159
|
+
|
160
|
+
for (cp = (const unsigned char *)key; *cp != '\0'; cp++) {
|
161
|
+
i = code[*cp];
|
162
|
+
if (i == UCHAR_MAX) {
|
163
|
+
ndt_err_format(ctx, NDT_ValueError,
|
164
|
+
"invalid character in function name: '%c'", *cp);
|
165
|
+
return NULL;
|
166
|
+
}
|
167
|
+
|
168
|
+
if (t->next[i] == NULL) {
|
169
|
+
ndt_err_format(ctx, NDT_ValueError,
|
170
|
+
"cannot find function '%s'", key);
|
171
|
+
return NULL;
|
172
|
+
}
|
173
|
+
t = t->next[i];
|
174
|
+
}
|
175
|
+
|
176
|
+
if (t->value == NULL) {
|
177
|
+
ndt_err_format(ctx, NDT_RuntimeError,
|
178
|
+
"cannot find function '%s'", key);
|
179
|
+
return NULL;
|
180
|
+
}
|
181
|
+
|
182
|
+
return t->value;
|
183
|
+
}
|
184
|
+
|
185
|
+
int
|
186
|
+
gm_tbl_map(const gm_tbl_t *tbl, int (*f)(const gm_func_t *, void *), void *state)
|
187
|
+
{
|
188
|
+
const gm_tbl_t *t = tbl;
|
189
|
+
int i;
|
190
|
+
|
191
|
+
if (t->value) {
|
192
|
+
if (f(t->value, state) < 0) {
|
193
|
+
return -1;
|
194
|
+
}
|
195
|
+
}
|
196
|
+
|
197
|
+
for (i = 0; i < ALPHABET_LEN; i++) {
|
198
|
+
if (t->next[i] && gm_tbl_map(t->next[i], f, state) < 0) {
|
199
|
+
return -1;
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
return 0;
|
204
|
+
}
|
205
|
+
|
206
|
+
|
207
|
+
/*****************************************************************************/
|
208
|
+
/* Initialize global values */
|
209
|
+
/*****************************************************************************/
|
210
|
+
|
211
|
+
void
|
212
|
+
gm_init(void)
|
213
|
+
{
|
214
|
+
static bool initialized = false;
|
215
|
+
|
216
|
+
if (!initialized) {
|
217
|
+
init_charmap();
|
218
|
+
}
|
219
|
+
else {
|
220
|
+
fprintf(stderr, "gm_init: warning: ignoring attempt to initialize "
|
221
|
+
"libgumath a second time\n");
|
222
|
+
}
|
223
|
+
}
|
@@ -0,0 +1,175 @@
|
|
1
|
+
/*
|
2
|
+
* BSD 3-Clause License
|
3
|
+
*
|
4
|
+
* Copyright (c) 2017-2018, plures
|
5
|
+
* All rights reserved.
|
6
|
+
*
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
8
|
+
* modification, are permitted provided that the following conditions are met:
|
9
|
+
*
|
10
|
+
* 1. Redistributions of source code must retain the above copyright notice,
|
11
|
+
* this list of conditions and the following disclaimer.
|
12
|
+
*
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
14
|
+
* this list of conditions and the following disclaimer in the documentation
|
15
|
+
* and/or other materials provided with the distribution.
|
16
|
+
*
|
17
|
+
* 3. Neither the name of the copyright holder nor the names of its
|
18
|
+
* contributors may be used to endorse or promote products derived from
|
19
|
+
* this software without specific prior written permission.
|
20
|
+
*
|
21
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
22
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
23
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
24
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
25
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
26
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
27
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
28
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
29
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
*/
|
32
|
+
|
33
|
+
|
34
|
+
#include <stdlib.h>
|
35
|
+
#include <stdint.h>
|
36
|
+
#include <string.h>
|
37
|
+
#include <inttypes.h>
|
38
|
+
#include "ndtypes.h"
|
39
|
+
#include "xnd.h"
|
40
|
+
#include "gumath.h"
|
41
|
+
#include "config.h"
|
42
|
+
|
43
|
+
|
44
|
+
#ifdef HAVE_PTHREAD_H
|
45
|
+
#include <pthread.h>
|
46
|
+
|
47
|
+
struct thread_info {
|
48
|
+
pthread_t tid;
|
49
|
+
int tnum;
|
50
|
+
int nrows;
|
51
|
+
int ncols;
|
52
|
+
const gm_kernel_t *kernel;
|
53
|
+
xnd_t **slices;
|
54
|
+
int outer_dims;
|
55
|
+
ndt_context_t ctx;
|
56
|
+
};
|
57
|
+
|
58
|
+
static void
|
59
|
+
init_static_context(ndt_context_t *ctx)
|
60
|
+
{
|
61
|
+
static const ndt_context_t c = {
|
62
|
+
.flags=0,
|
63
|
+
.err=NDT_Success,
|
64
|
+
.msg=ConstMsg,
|
65
|
+
.ConstMsg="Success" };
|
66
|
+
|
67
|
+
*ctx = c;
|
68
|
+
}
|
69
|
+
|
70
|
+
static void
|
71
|
+
clear_all_slices(xnd_t *slices[], int *nslices, int stop)
|
72
|
+
{
|
73
|
+
for (int i = 0; i < stop; i++) {
|
74
|
+
for (int k = 0; k < nslices[i]; k++) {
|
75
|
+
ndt_del((ndt_t *)slices[i][k].type);
|
76
|
+
}
|
77
|
+
ndt_free(slices[i]);
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
static void *
|
82
|
+
apply_thread(void *arg)
|
83
|
+
{
|
84
|
+
struct thread_info *tinfo = arg;
|
85
|
+
ALLOCA(xnd_t, stack, tinfo->nrows);
|
86
|
+
|
87
|
+
for (int i = 0; i < tinfo->nrows; i++) {
|
88
|
+
stack[i] = tinfo->slices[i][tinfo->tnum];
|
89
|
+
}
|
90
|
+
|
91
|
+
gm_apply(tinfo->kernel, stack, tinfo->outer_dims, &tinfo->ctx);
|
92
|
+
return NULL;
|
93
|
+
}
|
94
|
+
|
95
|
+
int
|
96
|
+
gm_apply_thread(const gm_kernel_t *kernel, xnd_t stack[], int outer_dims,
|
97
|
+
uint32_t flags, const int64_t nthreads, ndt_context_t *ctx)
|
98
|
+
{
|
99
|
+
const int nrows = (int)kernel->set->sig->Function.nargs;
|
100
|
+
ALLOCA(xnd_t *, slices, nrows);
|
101
|
+
ALLOCA(int, nslices, nrows);
|
102
|
+
struct thread_info *tinfo;
|
103
|
+
int ncols, tnum;
|
104
|
+
|
105
|
+
if (nthreads <= 1 || nrows == 0 || outer_dims == 0 ||
|
106
|
+
!(flags & NDT_STRIDED)) {
|
107
|
+
return gm_apply(kernel, stack, outer_dims, ctx);
|
108
|
+
}
|
109
|
+
|
110
|
+
for (int i = 0; i < nrows; i++) {
|
111
|
+
int64_t ncols = nthreads;
|
112
|
+
slices[i] = xnd_split(&stack[i], &ncols, outer_dims, ctx);
|
113
|
+
if (ndt_err_occurred(ctx)) {
|
114
|
+
clear_all_slices(slices, nslices, i);
|
115
|
+
return -1;
|
116
|
+
}
|
117
|
+
nslices[i] = ncols;
|
118
|
+
}
|
119
|
+
|
120
|
+
ncols = nslices[0];
|
121
|
+
for (int i = 1; i < nrows; i++) {
|
122
|
+
if (nslices[i] != ncols) {
|
123
|
+
clear_all_slices(slices, nslices, nrows);
|
124
|
+
ndt_err_format(ctx, NDT_RuntimeError,
|
125
|
+
"equal subdivision in threaded apply loop failed");
|
126
|
+
return -1;
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
tinfo = ndt_calloc(nthreads, sizeof *tinfo);
|
131
|
+
if (tinfo == NULL) {
|
132
|
+
clear_all_slices(slices, nslices, nrows);
|
133
|
+
(void)ndt_memory_error(ctx);
|
134
|
+
return -1;
|
135
|
+
}
|
136
|
+
|
137
|
+
for (tnum = 0; tnum < ncols; tnum++) {
|
138
|
+
tinfo[tnum].tnum = tnum;
|
139
|
+
tinfo[tnum].kernel = kernel;
|
140
|
+
tinfo[tnum].nrows = nrows;
|
141
|
+
tinfo[tnum].ncols = ncols;
|
142
|
+
tinfo[tnum].slices = slices;
|
143
|
+
tinfo[tnum].outer_dims = outer_dims;
|
144
|
+
init_static_context(&tinfo[tnum].ctx);
|
145
|
+
|
146
|
+
int ret = pthread_create(&tinfo[tnum].tid, NULL, &apply_thread,
|
147
|
+
&tinfo[tnum]);
|
148
|
+
if (ret != 0) {
|
149
|
+
clear_all_slices(slices, nslices, nrows);
|
150
|
+
ndt_err_format(ctx, NDT_RuntimeError, "could not create thread");
|
151
|
+
return -1;
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
int ret = 0;
|
156
|
+
for (tnum = 0; tnum < ncols; tnum++) {
|
157
|
+
ret |= pthread_join(tinfo[tnum].tid, NULL);
|
158
|
+
if (ndt_err_occurred(&tinfo[tnum].ctx)) {
|
159
|
+
if (!ndt_err_occurred(ctx)) {
|
160
|
+
ndt_err_format(ctx, tinfo[tnum].ctx.err,
|
161
|
+
ndt_context_msg(&tinfo[tnum].ctx));
|
162
|
+
}
|
163
|
+
ndt_err_clear(&tinfo[tnum].ctx);
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
if (ret != 0 && !ndt_err_occurred(ctx)) {
|
168
|
+
ndt_err_format(ctx, NDT_RuntimeError, "error in thread");
|
169
|
+
}
|
170
|
+
|
171
|
+
clear_all_slices(slices, nslices, nrows);
|
172
|
+
|
173
|
+
return ndt_err_occurred(ctx) ? -1 : 0;
|
174
|
+
}
|
175
|
+
#endif
|
@@ -0,0 +1,130 @@
|
|
1
|
+
/*
|
2
|
+
* BSD 3-Clause License
|
3
|
+
*
|
4
|
+
* Copyright (c) 2017-2018, plures
|
5
|
+
* All rights reserved.
|
6
|
+
*
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
8
|
+
* modification, are permitted provided that the following conditions are met:
|
9
|
+
*
|
10
|
+
* 1. Redistributions of source code must retain the above copyright notice,
|
11
|
+
* this list of conditions and the following disclaimer.
|
12
|
+
*
|
13
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
14
|
+
* this list of conditions and the following disclaimer in the documentation
|
15
|
+
* and/or other materials provided with the distribution.
|
16
|
+
*
|
17
|
+
* 3. Neither the name of the copyright holder nor the names of its
|
18
|
+
* contributors may be used to endorse or promote products derived from
|
19
|
+
* this software without specific prior written permission.
|
20
|
+
*
|
21
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
22
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
23
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
24
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
25
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
26
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
27
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
28
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
29
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
*/
|
32
|
+
|
33
|
+
|
34
|
+
#include <stdlib.h>
|
35
|
+
#include <stdint.h>
|
36
|
+
#include <string.h>
|
37
|
+
#include <inttypes.h>
|
38
|
+
#include "ndtypes.h"
|
39
|
+
#include "xnd.h"
|
40
|
+
#include "gumath.h"
|
41
|
+
|
42
|
+
|
43
|
+
int
|
44
|
+
gm_xnd_map(const gm_xnd_kernel_t f, xnd_t stack[], const int nargs,
|
45
|
+
const int outer_dims, ndt_context_t *ctx)
|
46
|
+
{
|
47
|
+
ALLOCA(xnd_t, next, nargs);
|
48
|
+
const ndt_t *t;
|
49
|
+
|
50
|
+
if (outer_dims == 0 || nargs == 0) {
|
51
|
+
return f(stack, ctx);
|
52
|
+
}
|
53
|
+
|
54
|
+
t = stack[0].type;
|
55
|
+
|
56
|
+
switch (t->tag) {
|
57
|
+
case FixedDim: {
|
58
|
+
const int64_t shape = t->FixedDim.shape;
|
59
|
+
|
60
|
+
for (int k = 1; k < nargs; k++) {
|
61
|
+
const ndt_t *u = stack[k].type;
|
62
|
+
|
63
|
+
if (u->tag != FixedDim || u->FixedDim.shape != shape) {
|
64
|
+
ndt_err_format(ctx, NDT_RuntimeError,
|
65
|
+
"type or shape mismatch in outer dimensions");
|
66
|
+
return -1;
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
for (int64_t i = 0; i < shape; i++) {
|
71
|
+
for (int k = 0; k < nargs; k++) {
|
72
|
+
next[k] = xnd_fixed_dim_next(&stack[k], i);
|
73
|
+
}
|
74
|
+
|
75
|
+
if (gm_xnd_map(f, next, nargs, outer_dims-1, ctx) < 0) {
|
76
|
+
return -1;
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
return 0;
|
81
|
+
}
|
82
|
+
|
83
|
+
case VarDim: {
|
84
|
+
ALLOCA(int64_t, start, nargs);
|
85
|
+
ALLOCA(int64_t, step, nargs);
|
86
|
+
const int64_t shape = ndt_var_indices(&start[0], &step[0], t,
|
87
|
+
stack[0].index, ctx);
|
88
|
+
if (shape < 0) {
|
89
|
+
return -1;
|
90
|
+
}
|
91
|
+
|
92
|
+
for (int k = 1; k < nargs; k++) {
|
93
|
+
const ndt_t *u = stack[k].type;
|
94
|
+
|
95
|
+
if (u->tag != VarDim) {
|
96
|
+
ndt_err_format(ctx, NDT_RuntimeError,
|
97
|
+
"type mismatch in outer dimensions");
|
98
|
+
return -1;
|
99
|
+
}
|
100
|
+
|
101
|
+
int64_t n = ndt_var_indices(&start[k], &step[k], u, stack[k].index, ctx);
|
102
|
+
if (n < 0) {
|
103
|
+
return -1;
|
104
|
+
}
|
105
|
+
|
106
|
+
if (n != shape) {
|
107
|
+
ndt_err_format(ctx, NDT_RuntimeError,
|
108
|
+
"shape mismatch in outer dimensions");
|
109
|
+
return -1;
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
for (int64_t i = 0; i < shape; i++) {
|
114
|
+
for (int k = 0; k < nargs; k++) {
|
115
|
+
next[k] = xnd_var_dim_next(&stack[k], start[k], step[k], i);
|
116
|
+
}
|
117
|
+
|
118
|
+
if (gm_xnd_map(f, next, nargs, outer_dims-1, ctx) < 0) {
|
119
|
+
return -1;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
|
123
|
+
return 0;
|
124
|
+
}
|
125
|
+
|
126
|
+
default:
|
127
|
+
ndt_err_format(ctx, NDT_NotImplementedError, "unsupported type");
|
128
|
+
return -1;
|
129
|
+
}
|
130
|
+
}
|