gumath 0.2.0dev5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +61 -0
  3. data/Gemfile +5 -0
  4. data/History.md +0 -0
  5. data/README.md +5 -0
  6. data/Rakefile +105 -0
  7. data/ext/ruby_gumath/examples.c +126 -0
  8. data/ext/ruby_gumath/extconf.rb +97 -0
  9. data/ext/ruby_gumath/functions.c +106 -0
  10. data/ext/ruby_gumath/gufunc_object.c +79 -0
  11. data/ext/ruby_gumath/gufunc_object.h +55 -0
  12. data/ext/ruby_gumath/gumath/AUTHORS.txt +5 -0
  13. data/ext/ruby_gumath/gumath/INSTALL.txt +42 -0
  14. data/ext/ruby_gumath/gumath/LICENSE.txt +29 -0
  15. data/ext/ruby_gumath/gumath/MANIFEST.in +3 -0
  16. data/ext/ruby_gumath/gumath/Makefile.in +62 -0
  17. data/ext/ruby_gumath/gumath/README.rst +20 -0
  18. data/ext/ruby_gumath/gumath/config.guess +1530 -0
  19. data/ext/ruby_gumath/gumath/config.h.in +52 -0
  20. data/ext/ruby_gumath/gumath/config.sub +1782 -0
  21. data/ext/ruby_gumath/gumath/configure +5049 -0
  22. data/ext/ruby_gumath/gumath/configure.ac +167 -0
  23. data/ext/ruby_gumath/gumath/doc/_static/copybutton.js +66 -0
  24. data/ext/ruby_gumath/gumath/doc/conf.py +26 -0
  25. data/ext/ruby_gumath/gumath/doc/gumath/functions.rst +62 -0
  26. data/ext/ruby_gumath/gumath/doc/gumath/index.rst +26 -0
  27. data/ext/ruby_gumath/gumath/doc/index.rst +45 -0
  28. data/ext/ruby_gumath/gumath/doc/libgumath/data-structures.rst +130 -0
  29. data/ext/ruby_gumath/gumath/doc/libgumath/functions.rst +78 -0
  30. data/ext/ruby_gumath/gumath/doc/libgumath/index.rst +25 -0
  31. data/ext/ruby_gumath/gumath/doc/libgumath/kernels.rst +41 -0
  32. data/ext/ruby_gumath/gumath/doc/releases/index.rst +11 -0
  33. data/ext/ruby_gumath/gumath/install-sh +527 -0
  34. data/ext/ruby_gumath/gumath/libgumath/Makefile.in +170 -0
  35. data/ext/ruby_gumath/gumath/libgumath/Makefile.vc +160 -0
  36. data/ext/ruby_gumath/gumath/libgumath/apply.c +201 -0
  37. data/ext/ruby_gumath/gumath/libgumath/extending/bfloat16.c +130 -0
  38. data/ext/ruby_gumath/gumath/libgumath/extending/examples.c +176 -0
  39. data/ext/ruby_gumath/gumath/libgumath/extending/graph.c +393 -0
  40. data/ext/ruby_gumath/gumath/libgumath/extending/pdist.c +140 -0
  41. data/ext/ruby_gumath/gumath/libgumath/extending/quaternion.c +156 -0
  42. data/ext/ruby_gumath/gumath/libgumath/func.c +177 -0
  43. data/ext/ruby_gumath/gumath/libgumath/gumath.h +205 -0
  44. data/ext/ruby_gumath/gumath/libgumath/kernels/binary.c +547 -0
  45. data/ext/ruby_gumath/gumath/libgumath/kernels/unary.c +449 -0
  46. data/ext/ruby_gumath/gumath/libgumath/nploops.c +219 -0
  47. data/ext/ruby_gumath/gumath/libgumath/tbl.c +223 -0
  48. data/ext/ruby_gumath/gumath/libgumath/thread.c +175 -0
  49. data/ext/ruby_gumath/gumath/libgumath/xndloops.c +130 -0
  50. data/ext/ruby_gumath/gumath/python/extending.py +24 -0
  51. data/ext/ruby_gumath/gumath/python/gumath/__init__.py +74 -0
  52. data/ext/ruby_gumath/gumath/python/gumath/_gumath.c +577 -0
  53. data/ext/ruby_gumath/gumath/python/gumath/examples.c +93 -0
  54. data/ext/ruby_gumath/gumath/python/gumath/functions.c +77 -0
  55. data/ext/ruby_gumath/gumath/python/gumath/pygumath.h +95 -0
  56. data/ext/ruby_gumath/gumath/python/test_gumath.py +405 -0
  57. data/ext/ruby_gumath/gumath/setup.py +298 -0
  58. data/ext/ruby_gumath/gumath/vcbuild/INSTALL.txt +36 -0
  59. data/ext/ruby_gumath/gumath/vcbuild/vcbuild32.bat +21 -0
  60. data/ext/ruby_gumath/gumath/vcbuild/vcbuild64.bat +21 -0
  61. data/ext/ruby_gumath/gumath/vcbuild/vcclean.bat +10 -0
  62. data/ext/ruby_gumath/gumath/vcbuild/vcdistclean.bat +11 -0
  63. data/ext/ruby_gumath/include/gumath.h +205 -0
  64. data/ext/ruby_gumath/include/ruby_gumath.h +41 -0
  65. data/ext/ruby_gumath/lib/libgumath.a +0 -0
  66. data/ext/ruby_gumath/lib/libgumath.so +1 -0
  67. data/ext/ruby_gumath/lib/libgumath.so.0 +1 -0
  68. data/ext/ruby_gumath/lib/libgumath.so.0.2.0dev3 +0 -0
  69. data/ext/ruby_gumath/ruby_gumath.c +295 -0
  70. data/ext/ruby_gumath/ruby_gumath.h +41 -0
  71. data/ext/ruby_gumath/ruby_gumath_internal.h +45 -0
  72. data/ext/ruby_gumath/util.c +68 -0
  73. data/ext/ruby_gumath/util.h +48 -0
  74. data/gumath.gemspec +47 -0
  75. data/lib/gumath.rb +7 -0
  76. data/lib/gumath/version.rb +5 -0
  77. data/lib/ruby_gumath.so +0 -0
  78. metadata +206 -0
@@ -0,0 +1,140 @@
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 <math.h>
38
+ #include <complex.h>
39
+ #include <inttypes.h>
40
+ #include "ndtypes.h"
41
+ #include "xnd.h"
42
+ #include "gumath.h"
43
+
44
+
45
+ /*****************************************************************************/
46
+ /* Euclidian pairwise distance */
47
+ /*****************************************************************************/
48
+
49
+ /* Numerically unstable: This is just an example for the constraint feature. */
50
+
51
+ static int
52
+ pdist(xnd_t stack[], ndt_context_t *ctx)
53
+ {
54
+ const ndt_t *t = stack[0].type;
55
+ const ndt_t *u = t->FixedDim.type;
56
+ const int64_t N = t->FixedDim.shape;
57
+ const int64_t M = u->FixedDim.shape;
58
+ int64_t l = 0;
59
+ (void)ctx;
60
+
61
+ for (int64_t i = 0; i < N; i++) {
62
+ const xnd_t vector1 = xnd_fixed_dim_next(&stack[0], i);
63
+ for (int64_t j = i+1; j < N; j++) {
64
+ const xnd_t vector2 = xnd_fixed_dim_next(&stack[0], j);
65
+ double sum = 0.0;
66
+ for (int64_t k = 0; k < M; k++) {
67
+ const xnd_t value1 = xnd_fixed_dim_next(&vector1, k);
68
+ const xnd_t value2 = xnd_fixed_dim_next(&vector2, k);
69
+ const double v1 = *(double *)value1.ptr;
70
+ const double v2 = *(double *)value2.ptr;
71
+ sum += pow(v1-v2, 2);
72
+ }
73
+ const xnd_t res = xnd_fixed_dim_next(&stack[1], l++);
74
+ *(double *)res.ptr = sqrt(sum);
75
+ }
76
+ }
77
+
78
+ return 0;
79
+ }
80
+
81
+ /*
82
+ * Validate N, M and compute unknown output dimension P.
83
+ *
84
+ * shape[0] = N
85
+ * shape[1] = N
86
+ * shape[2] = P
87
+ *
88
+ * 'args' is unused here. Other functions may inspect the incoming xnd
89
+ * arguments in order to resolve further constraints based on values.
90
+ */
91
+ static int
92
+ pdist_constraint(int64_t *shapes, const void *args, ndt_context_t *ctx)
93
+ {
94
+ (void)args;
95
+
96
+ if (shapes[0] == 0 || shapes[1] == 0) {
97
+ ndt_err_format(ctx, NDT_ValueError,
98
+ "euclidian_pdist() requires a non-empty matrix");
99
+ return -1;
100
+ }
101
+
102
+ shapes[2] = (shapes[0] * (shapes[0]-1)) / 2;
103
+ return 0;
104
+ }
105
+
106
+ static const ndt_constraint_t constraint = {
107
+ .f = pdist_constraint,
108
+ .nin = 2,
109
+ .nout = 1,
110
+ .symbols = {"N", "M", "P"}
111
+ };
112
+
113
+
114
+ static const gm_kernel_init_t kernels[] = {
115
+ { .name = "euclidian_pdist",
116
+ .sig = "N * M * float64 -> P * float64",
117
+ .constraint = &constraint,
118
+ .Xnd = pdist },
119
+
120
+ { .name = NULL, .sig = NULL }
121
+ };
122
+
123
+
124
+ /****************************************************************************/
125
+ /* Initialize kernel table */
126
+ /****************************************************************************/
127
+
128
+ int
129
+ gm_init_pdist_kernels(gm_tbl_t *tbl, ndt_context_t *ctx)
130
+ {
131
+ const gm_kernel_init_t *k;
132
+
133
+ for (k = kernels; k->name != NULL; k++) {
134
+ if (gm_add_kernel(tbl, k, ctx) < 0) {
135
+ return -1;
136
+ }
137
+ }
138
+
139
+ return 0;
140
+ }
@@ -0,0 +1,156 @@
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 <math.h>
38
+ #include <complex.h>
39
+ #include <inttypes.h>
40
+ #include "ndtypes.h"
41
+ #include "xnd.h"
42
+ #include "gumath.h"
43
+
44
+
45
+ static int
46
+ gm_multiply_strided_1D_q64_q64(char *args[], intptr_t dimensions[], intptr_t steps[],
47
+ void *data GM_UNUSED)
48
+ {
49
+ const char *src1 = args[0];
50
+ const char *src2 = args[1];
51
+ char *dest = args[2];
52
+ const ndt_complex64_t (*s1)[2];
53
+ const ndt_complex64_t (*s2)[2];
54
+ ndt_complex64_t (*d1)[2];
55
+ intptr_t n = dimensions[0];
56
+ intptr_t i, j, k, l;
57
+
58
+ for (i = 0; i < n; i++) {
59
+ s1 = (const ndt_complex64_t (*)[2])src1;
60
+ s2 = (const ndt_complex64_t (*)[2])src2;
61
+ d1 = (ndt_complex64_t (*)[2])dest;
62
+ for (j = 0; j < 2; j++){
63
+ for (k = 0; k < 2; k++) {
64
+ ndt_complex64_t sum = 0;
65
+ for (l = 0; l < 2; l++) {
66
+ sum += s1[j][l] * s2[l][k];
67
+ }
68
+ d1[j][k] = sum;
69
+ }
70
+ }
71
+ src1 += steps[0];
72
+ src2 += steps[1];
73
+ dest += steps[2];
74
+ }
75
+
76
+ return 0;
77
+ }
78
+
79
+ static int
80
+ gm_multiply_strided_1D_q128_q128(char *args[], intptr_t dimensions[], intptr_t steps[],
81
+ void *data GM_UNUSED)
82
+ {
83
+ const char *src1 = args[0];
84
+ const char *src2 = args[1];
85
+ char *dest = args[2];
86
+ const ndt_complex128_t (*s1)[2];
87
+ const ndt_complex128_t (*s2)[2];
88
+ ndt_complex128_t (*d1)[2];
89
+ intptr_t n = dimensions[0];
90
+ intptr_t i, j, k, l;
91
+
92
+ for (i = 0; i < n; i++) {
93
+ s1 = (const ndt_complex128_t (*)[2])src1;
94
+ s2 = (const ndt_complex128_t (*)[2])src2;
95
+ d1 = (ndt_complex128_t (*)[2])dest;
96
+ for (j = 0; j < 2; j++){
97
+ for (k = 0; k < 2; k++) {
98
+ ndt_complex128_t sum = 0;
99
+ for (l = 0; l < 2; l++) {
100
+ sum += s1[j][l] * s2[l][k];
101
+ }
102
+ d1[j][k] = sum;
103
+ }
104
+ }
105
+ src1 += steps[0];
106
+ src2 += steps[1];
107
+ dest += steps[2];
108
+ }
109
+
110
+ return 0;
111
+ }
112
+
113
+
114
+ static const gm_typedef_init_t typedefs[] = {
115
+ { .name = "quaternion64", .type = "2 * 2 * complex64", .meth=NULL },
116
+ { .name = "quaternion128", .type = "2 * 2 * complex128", .meth=NULL },
117
+ { .name = NULL, .type = NULL }
118
+ };
119
+
120
+ static const gm_kernel_init_t kernels[] = {
121
+ { .name = "multiply",
122
+ .sig = "... * N * quaternion64, ... * N * quaternion64 -> ... * N * quaternion64",
123
+ .Strided = gm_multiply_strided_1D_q64_q64 },
124
+
125
+ { .name = "multiply",
126
+ .sig = "... * N * quaternion128, ... * N * quaternion128 -> ... * N * quaternion128",
127
+ .Strided = gm_multiply_strided_1D_q128_q128 },
128
+
129
+ { .name = NULL, .sig = NULL }
130
+ };
131
+
132
+
133
+ /****************************************************************************/
134
+ /* Initialize kernel table */
135
+ /****************************************************************************/
136
+
137
+ int
138
+ gm_init_quaternion_kernels(gm_tbl_t *tbl, ndt_context_t *ctx)
139
+ {
140
+ const gm_typedef_init_t *t;
141
+ const gm_kernel_init_t *k;
142
+
143
+ for (t = typedefs; t->name != NULL; t++) {
144
+ if (ndt_typedef_from_string(t->name, t->type, t->meth, ctx) < 0) {
145
+ return -1;
146
+ }
147
+ }
148
+
149
+ for (k = kernels; k->name != NULL; k++) {
150
+ if (gm_add_kernel(tbl, k, ctx) < 0) {
151
+ return -1;
152
+ }
153
+ }
154
+
155
+ return 0;
156
+ }
@@ -0,0 +1,177 @@
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 <string.h>
36
+ #include <stdint.h>
37
+ #include <inttypes.h>
38
+ #include <stdbool.h>
39
+ #include <complex.h>
40
+ #include <assert.h>
41
+ #include "ndtypes.h"
42
+ #include "gumath.h"
43
+
44
+
45
+ /******************************************************************************/
46
+ /* Type allocation/deallocation */
47
+ /******************************************************************************/
48
+
49
+ gm_func_t *
50
+ gm_func_new(const char *name, ndt_context_t *ctx)
51
+ {
52
+ gm_func_t *f;
53
+
54
+ f = ndt_alloc_size(sizeof *f);
55
+ if (f == NULL) {
56
+ return ndt_memory_error(ctx);
57
+ }
58
+
59
+ f->name = ndt_strdup(name, ctx);
60
+ if (f->name == NULL) {
61
+ ndt_free(f);
62
+ return NULL;
63
+ }
64
+ f->typecheck = NULL;
65
+ f->nkernels = 0;
66
+
67
+ return f;
68
+ }
69
+
70
+ void
71
+ gm_func_del(gm_func_t *f)
72
+ {
73
+ ndt_free(f->name);
74
+
75
+ for (int i = 0; i < f->nkernels; i++) {
76
+ ndt_del(f->kernels[i].sig);
77
+ }
78
+
79
+ ndt_free(f);
80
+ }
81
+
82
+ gm_func_t *
83
+ gm_add_func(gm_tbl_t *tbl, const char *name, ndt_context_t *ctx)
84
+ {
85
+ gm_func_t *f = gm_func_new(name, ctx);
86
+
87
+ if (f == NULL) {
88
+ return NULL;
89
+ }
90
+
91
+ if (gm_tbl_add(tbl, name, f, ctx) < 0) {
92
+ gm_func_del(f);
93
+ return NULL;
94
+ }
95
+
96
+ return f;
97
+ }
98
+
99
+ int
100
+ gm_add_kernel(gm_tbl_t *tbl, const gm_kernel_init_t *k, ndt_context_t *ctx)
101
+ {
102
+ gm_func_t *f = gm_tbl_find(tbl, k->name, ctx);
103
+ gm_kernel_set_t kernel;
104
+ ndt_t *t;
105
+
106
+ if (f == NULL) {
107
+ ndt_err_clear(ctx);
108
+ f = gm_add_func(tbl, k->name, ctx);
109
+ if (f == NULL) {
110
+ return -1;
111
+ }
112
+ }
113
+
114
+ t = ndt_from_string_v(k->sig, ctx);
115
+ if (t == NULL) {
116
+ return -1;
117
+ }
118
+
119
+ if (f->nkernels == GM_MAX_KERNELS) {
120
+ ndt_del(t);
121
+ ndt_err_format(ctx, NDT_RuntimeError,
122
+ "%s: maximum number of kernels reached for", f->name);
123
+ return -1;
124
+ }
125
+
126
+ kernel.sig = t;
127
+ kernel.constraint = k->constraint;
128
+ kernel.Opt = k->Opt;
129
+ kernel.C = k->C;
130
+ kernel.Fortran = k->Fortran;
131
+ kernel.Strided = k->Strided;
132
+ kernel.Xnd = k->Xnd;
133
+
134
+ f->kernels[f->nkernels++] = kernel;
135
+ return 0;
136
+ }
137
+
138
+ int
139
+ gm_add_kernel_typecheck(gm_tbl_t *tbl, const gm_kernel_init_t *k, ndt_context_t *ctx,
140
+ gm_typecheck_t typecheck)
141
+ {
142
+ gm_func_t *f = gm_tbl_find(tbl, k->name, ctx);
143
+ gm_kernel_set_t kernel;
144
+ ndt_t *t;
145
+
146
+ if (f == NULL) {
147
+ ndt_err_clear(ctx);
148
+ f = gm_add_func(tbl, k->name, ctx);
149
+ if (f == NULL) {
150
+ return -1;
151
+ }
152
+ f->typecheck = typecheck;
153
+ }
154
+
155
+ t = ndt_from_string_v(k->sig, ctx);
156
+ if (t == NULL) {
157
+ return -1;
158
+ }
159
+
160
+ if (f->nkernels == GM_MAX_KERNELS) {
161
+ ndt_del(t);
162
+ ndt_err_format(ctx, NDT_RuntimeError,
163
+ "%s: maximum number of kernels reached for", f->name);
164
+ return -1;
165
+ }
166
+
167
+ kernel.sig = t;
168
+ kernel.constraint = k->constraint;
169
+ kernel.Opt = k->Opt;
170
+ kernel.C = k->C;
171
+ kernel.Fortran = k->Fortran;
172
+ kernel.Strided = k->Strided;
173
+ kernel.Xnd = k->Xnd;
174
+
175
+ f->kernels[f->nkernels++] = kernel;
176
+ return 0;
177
+ }