ndtypes 0.2.0dev5 → 0.2.0dev6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +12 -0
  3. data/Rakefile +8 -0
  4. data/ext/ruby_ndtypes/GPATH +0 -0
  5. data/ext/ruby_ndtypes/GRTAGS +0 -0
  6. data/ext/ruby_ndtypes/GTAGS +0 -0
  7. data/ext/ruby_ndtypes/extconf.rb +1 -1
  8. data/ext/ruby_ndtypes/include/ndtypes.h +231 -122
  9. data/ext/ruby_ndtypes/include/ruby_ndtypes.h +1 -1
  10. data/ext/ruby_ndtypes/lib/libndtypes.a +0 -0
  11. data/ext/ruby_ndtypes/lib/libndtypes.so.0.2.0dev3 +0 -0
  12. data/ext/ruby_ndtypes/ndtypes/Makefile +87 -0
  13. data/ext/ruby_ndtypes/ndtypes/config.h +68 -0
  14. data/ext/ruby_ndtypes/ndtypes/config.log +477 -0
  15. data/ext/ruby_ndtypes/ndtypes/config.status +1027 -0
  16. data/ext/ruby_ndtypes/ndtypes/doc/_static/style.css +7 -0
  17. data/ext/ruby_ndtypes/ndtypes/doc/_templates/layout.html +2 -0
  18. data/ext/ruby_ndtypes/ndtypes/doc/conf.py +40 -4
  19. data/ext/ruby_ndtypes/ndtypes/doc/images/xndlogo.png +0 -0
  20. data/ext/ruby_ndtypes/ndtypes/doc/ndtypes/types.rst +1 -1
  21. data/ext/ruby_ndtypes/ndtypes/doc/requirements.txt +2 -0
  22. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile +287 -0
  23. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.in +20 -4
  24. data/ext/ruby_ndtypes/ndtypes/libndtypes/Makefile.vc +22 -3
  25. data/ext/ruby_ndtypes/ndtypes/libndtypes/alloc.c +1 -1
  26. data/ext/ruby_ndtypes/ndtypes/libndtypes/alloc.o +0 -0
  27. data/ext/ruby_ndtypes/ndtypes/libndtypes/attr.o +0 -0
  28. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/Makefile +73 -0
  29. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.c +246 -229
  30. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.h +15 -11
  31. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.o +0 -0
  32. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bpgrammar.y +38 -28
  33. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.c +91 -91
  34. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.h +1 -1
  35. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.l +4 -3
  36. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/bplexer.o +0 -0
  37. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/export.c +8 -7
  38. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/export.o +0 -0
  39. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/import.c +2 -2
  40. data/ext/ruby_ndtypes/ndtypes/libndtypes/compat/import.o +0 -0
  41. data/ext/ruby_ndtypes/ndtypes/libndtypes/context.o +0 -0
  42. data/ext/ruby_ndtypes/ndtypes/libndtypes/copy.c +263 -182
  43. data/ext/ruby_ndtypes/ndtypes/libndtypes/copy.o +0 -0
  44. data/ext/ruby_ndtypes/ndtypes/libndtypes/encodings.o +0 -0
  45. data/ext/ruby_ndtypes/ndtypes/libndtypes/equal.c +67 -7
  46. data/ext/ruby_ndtypes/ndtypes/libndtypes/equal.o +0 -0
  47. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.c +1112 -1000
  48. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.h +69 -58
  49. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.o +0 -0
  50. data/ext/ruby_ndtypes/ndtypes/libndtypes/grammar.y +150 -99
  51. data/ext/ruby_ndtypes/ndtypes/libndtypes/io.c +185 -15
  52. data/ext/ruby_ndtypes/ndtypes/libndtypes/io.o +0 -0
  53. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.c +301 -276
  54. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.h +1 -1
  55. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.l +9 -4
  56. data/ext/ruby_ndtypes/ndtypes/libndtypes/lexer.o +0 -0
  57. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.a +0 -0
  58. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.so +1 -0
  59. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.so.0 +1 -0
  60. data/ext/ruby_ndtypes/ndtypes/libndtypes/libndtypes.so.0.2.0dev3 +0 -0
  61. data/ext/ruby_ndtypes/ndtypes/libndtypes/match.c +729 -228
  62. data/ext/ruby_ndtypes/ndtypes/libndtypes/match.o +0 -0
  63. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.c +768 -403
  64. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.h +1002 -0
  65. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.h.in +231 -122
  66. data/ext/ruby_ndtypes/ndtypes/libndtypes/ndtypes.o +0 -0
  67. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.c +176 -84
  68. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.h +26 -14
  69. data/ext/ruby_ndtypes/ndtypes/libndtypes/parsefuncs.o +0 -0
  70. data/ext/ruby_ndtypes/ndtypes/libndtypes/parser.c +57 -35
  71. data/ext/ruby_ndtypes/ndtypes/libndtypes/parser.o +0 -0
  72. data/ext/ruby_ndtypes/ndtypes/libndtypes/primitive.c +420 -0
  73. data/ext/ruby_ndtypes/ndtypes/libndtypes/primitive.o +0 -0
  74. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.c +8 -8
  75. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.h +1 -1
  76. data/ext/ruby_ndtypes/ndtypes/libndtypes/seq.o +0 -0
  77. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/Makefile +48 -0
  78. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/deserialize.c +200 -116
  79. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/deserialize.o +0 -0
  80. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/serialize.c +46 -4
  81. data/ext/ruby_ndtypes/ndtypes/libndtypes/serialize/serialize.o +0 -0
  82. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.c +58 -27
  83. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.h +1 -1
  84. data/ext/ruby_ndtypes/ndtypes/libndtypes/substitute.o +0 -0
  85. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.c +3 -5
  86. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.h +12 -4
  87. data/ext/ruby_ndtypes/ndtypes/libndtypes/symtable.o +0 -0
  88. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile +55 -0
  89. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.in +8 -8
  90. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/Makefile.vc +5 -5
  91. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/runtest.c +274 -172
  92. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test.h +24 -4
  93. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_array.c +2 -2
  94. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_buffer.c +14 -14
  95. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_match.c +32 -30
  96. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse.c +37 -0
  97. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_error.c +36 -0
  98. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_parse_roundtrip.c +16 -0
  99. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_record.c +5 -5
  100. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_typecheck.c +706 -253
  101. data/ext/ruby_ndtypes/ndtypes/libndtypes/tests/test_unify.c +132 -0
  102. data/ext/ruby_ndtypes/ndtypes/libndtypes/unify.c +703 -0
  103. data/ext/ruby_ndtypes/ndtypes/libndtypes/unify.o +0 -0
  104. data/ext/ruby_ndtypes/ndtypes/libndtypes/util.c +335 -127
  105. data/ext/ruby_ndtypes/ndtypes/libndtypes/util.o +0 -0
  106. data/ext/ruby_ndtypes/ndtypes/libndtypes/values.c +2 -2
  107. data/ext/ruby_ndtypes/ndtypes/libndtypes/values.o +0 -0
  108. data/ext/ruby_ndtypes/ndtypes/python/ndt_randtype.py +88 -71
  109. data/ext/ruby_ndtypes/ndtypes/python/ndt_support.py +0 -1
  110. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/__init__.py +10 -13
  111. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/_ndtypes.c +395 -314
  112. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.a +0 -0
  113. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.so +1 -0
  114. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.so.0 +1 -0
  115. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/libndtypes.so.0.2.0dev3 +0 -0
  116. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/ndtypes.h +1002 -0
  117. data/ext/ruby_ndtypes/ndtypes/python/ndtypes/pyndtypes.h +15 -33
  118. data/ext/ruby_ndtypes/ndtypes/python/test_ndtypes.py +340 -132
  119. data/ext/ruby_ndtypes/ndtypes/setup.py +11 -2
  120. data/ext/ruby_ndtypes/ruby_ndtypes.c +364 -241
  121. data/ext/ruby_ndtypes/ruby_ndtypes.h +1 -1
  122. data/ext/ruby_ndtypes/ruby_ndtypes_internal.h +0 -1
  123. data/lib/ndtypes.rb +11 -0
  124. data/lib/ndtypes/version.rb +2 -2
  125. data/lib/ruby_ndtypes.so +0 -0
  126. data/ndtypes.gemspec +3 -0
  127. data/spec/ndtypes_spec.rb +6 -0
  128. metadata +98 -4
  129. data/ext/ruby_ndtypes/gc_guard.c +0 -36
  130. data/ext/ruby_ndtypes/gc_guard.h +0 -12
@@ -42,6 +42,7 @@ from distutils.sysconfig import get_python_lib
42
42
  from glob import glob
43
43
  import platform
44
44
  import subprocess
45
+ import argparse
45
46
  import shutil
46
47
 
47
48
  try:
@@ -81,6 +82,13 @@ Links
81
82
  * http://xnd.readthedocs.io/en/latest/
82
83
  """
83
84
 
85
+ # Pre-parse and remove the '-j' argument from sys.argv.
86
+ parser = argparse.ArgumentParser()
87
+ parser.add_argument('-j', default=None)
88
+ values, rest = parser.parse_known_args()
89
+ PARALLEL = values.j
90
+ sys.argv = sys.argv[:1] + rest
91
+
84
92
 
85
93
  if sys.platform == "darwin":
86
94
  LIBNAME = "libndtypes.dylib"
@@ -230,10 +238,11 @@ def ndtypes_ext():
230
238
  runtime_library_dirs = ["$ORIGIN"]
231
239
 
232
240
  if BUILD_ALL:
241
+ make = "make -j%d" % int(PARALLEL) if PARALLEL else "make"
233
242
  if WITH_VALGRIND:
234
- os.system("./configure --with-valgrind && make")
243
+ os.system("./configure --with-valgrind && %s" % make)
235
244
  else:
236
- os.system("./configure && make")
245
+ os.system("./configure && %s" % make)
237
246
 
238
247
  return Extension (
239
248
  "ndtypes._ndtypes",
@@ -8,7 +8,6 @@
8
8
  /* ---------- Interal declarations ---------- */
9
9
  /* data_type_t variables. */
10
10
  static const rb_data_type_t NdtObject_type;
11
- static const rb_data_type_t ResourceBufferObject_type;
12
11
 
13
12
  /* Class declarations. */
14
13
  VALUE cNDTypes;
@@ -82,148 +81,14 @@ seterr(ndt_context_t *ctx)
82
81
  return exc;
83
82
  }
84
83
 
85
- /******************************************************************************/
86
- /************************* Resource Buffer Object *****************************/
87
-
88
- /* A ResourceBufferObject is passed around various NDT objects for storing
89
- * internal state. It might or might not be duplicated across other NDT
90
- * objects.
91
- */
92
- typedef struct ResourceBufferObject {
93
- ndt_meta_t *m;
94
- } ResourceBufferObject;
95
-
96
- #define GET_RBUF(obj, rbuf_p) do { \
97
- TypedData_Get_Struct((obj), ResourceBufferObject, \
98
- &ResourceBufferObject_type, (rbuf_p)); \
99
- } while (0)
100
- #define RBUF_NDT_M(rbuf_p) ((ndt_meta_t*)(rbuf_p->m))
101
- #define MAKE_RBUF(self, rbuf_p) TypedData_Make_Struct(self, ResourceBufferObject, \
102
- &ResourceBufferObject_type, rbuf_p)
103
- #define WRAP_RBUF(self, rbuf_p) TypedData_Wrap_Struct(self, \
104
- &ResourceBufferObject_type, rbuf_p)
105
-
106
- /* GC free the ResourceBufferObject struct. */
107
- static void
108
- ResourceBufferObject_dfree(void * self)
109
- {
110
- ResourceBufferObject * rbf = (ResourceBufferObject*)self;
111
-
112
- ndt_meta_del(rbf->m);
113
- rbf->m = NULL;
114
- xfree(rbf);
115
- }
116
-
117
- /* Calculate the size of the object. */
118
- static size_t
119
- ResourceBufferObject_dsize(const void *self)
120
- {
121
- return sizeof(ResourceBufferObject);
122
- }
123
-
124
- static const rb_data_type_t ResourceBufferObject_type = {
125
- .wrap_struct_name = "ResourceBufferObject",
126
- .function = {
127
- .dmark = 0,
128
- .dfree = ResourceBufferObject_dfree,
129
- .dsize = ResourceBufferObject_dsize,
130
- .reserved = {0,0},
131
- },
132
- .parent = 0,
133
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
134
- };
135
-
136
- /* FIXME: change this to rbuf_alloc to reflect that its not called by Ruby alloc. */
137
- static VALUE
138
- rbuf_allocate(void)
139
- {
140
- NDT_STATIC_CONTEXT(ctx);
141
- ResourceBufferObject *self;
142
-
143
- self = ALLOC(ResourceBufferObject);
144
-
145
- self->m = ndt_meta_new(&ctx);
146
- if (self->m == NULL) {
147
- rb_raise(rb_eNoMemError, "cannot allocate rbuf object.");
148
- }
149
-
150
- return WRAP_RBUF(cNDTypes_RBuf, self);
151
- }
152
-
153
- static int
154
- rbuf_init_from_offset_list(ResourceBufferObject *rbuf, VALUE list)
155
- {
156
- ndt_meta_t * const m = rbuf->m;
157
- VALUE lst;
158
-
159
- Check_Type(list, T_ARRAY);
160
-
161
- const int64_t n = RARRAY_LEN(list);
162
- if (n < 1 || n > NDT_MAX_DIM) {
163
- rb_raise(rb_eValueError, "number of offset lists must be in [1, %d].",
164
- NDT_MAX_DIM);
165
- }
166
-
167
- m->ndims = 0;
168
- for (int64_t i = n-1; i >= 0; i--) {
169
- lst = rb_ary_entry(list, i);
170
- if (!RB_TYPE_P(lst, T_ARRAY)) {
171
- rb_raise(rb_eTypeError, "expected a list of offset lists.");
172
- }
173
-
174
- const int64_t noffsets = RARRAY_LEN(lst);
175
- if (noffsets < 2 || noffsets > INT32_MAX) {
176
- rb_raise(rb_eValueError, "length of a single offset must be in [2, INT32_MAX].");
177
- }
178
-
179
- int32_t * const offsets = ndt_alloc(noffsets, sizeof(int32_t));
180
- if (offsets == NULL) {
181
- rb_raise(rb_eNoMemError, "could not allocate offsets.");
182
- }
183
-
184
- for (int32_t k = 0; k < noffsets; k++) {
185
- long long x = NUM2LL(rb_ary_entry(lst, k));
186
- if (x == -1 || x < 0 || x > INT32_MAX) {
187
- ndt_free(offsets);
188
- rb_raise(rb_eValueError, "offset must be in [0, INT32_MAX].");
189
- }
190
-
191
- offsets[k] = (int32_t)x;
192
- }
193
-
194
- m->noffsets[m->ndims] = (int32_t)noffsets;
195
- m->offsets[m->ndims] = offsets;
196
- m->ndims++;
197
- }
198
-
199
- return 0;
200
- }
201
-
202
- static VALUE
203
- rbuf_from_offset_lists(VALUE list)
204
- {
205
- VALUE rbuf;
206
- ResourceBufferObject * rbuf_p;
207
-
208
- rbuf = rbuf_allocate();
209
- GET_RBUF(rbuf, rbuf_p);
210
- rbuf_init_from_offset_list(rbuf_p, list);
211
-
212
- return rbuf;
213
- }
214
-
215
- /******************************************************************************/
216
-
217
84
  /******************************************************************************/
218
85
  /************************* NDT struct object **********************************/
219
86
 
220
87
  typedef struct NdtObject {
221
- VALUE rbuf; /* resource buffer */
222
- ndt_t *ndt; /* type */
88
+ const ndt_t *ndt; /* type */
223
89
  } NdtObject;
224
90
 
225
91
  #define NDT(v) (((NdtObject *)v)->ndt)
226
- #define RBUF(v) (((NdtObject *)v)->rbuf)
227
92
  #define GET_NDT(obj, ndt_p) do { \
228
93
  TypedData_Get_Struct((obj), NdtObject, \
229
94
  &NdtObject_type, (ndt_p)); \
@@ -232,20 +97,6 @@ typedef struct NdtObject {
232
97
  &NdtObject_type, ndt_p)
233
98
  #define WRAP_NDT(self, ndt_p) TypedData_Wrap_Struct(self, &NdtObject_type, ndt_p)
234
99
  #define NDT_CHECK_TYPE(obj) (CLASS_OF(obj) == cNDTypes)
235
-
236
- /* Get the metatdata of the ResourceBufferObject within this NDT Ruby object. */
237
- static ndt_meta_t *
238
- rbuf_ndt_meta(VALUE ndt)
239
- {
240
- NdtObject *ndt_p;
241
- ResourceBufferObject *rbuf_p;
242
-
243
- GET_NDT(ndt, ndt_p);
244
- GET_RBUF(ndt_p->rbuf, rbuf_p);
245
-
246
- return rbuf_p->m;
247
- }
248
-
249
100
  /* Allocate an NdtObject, initialize members and return wrapped as a Ruby object. */
250
101
  static VALUE
251
102
  NdtObject_alloc(void)
@@ -253,8 +104,6 @@ NdtObject_alloc(void)
253
104
  NdtObject *ndt_p;
254
105
 
255
106
  ndt_p = ZALLOC(NdtObject);
256
-
257
- ndt_p->rbuf = 0;
258
107
  ndt_p->ndt = NULL;
259
108
 
260
109
  return WRAP_NDT(cNDTypes, ndt_p);
@@ -263,20 +112,13 @@ NdtObject_alloc(void)
263
112
  /* GC mark the NdtObject struct. */
264
113
  /* TODO: verify that there are no more object allocations happening inside ndt. */
265
114
  static void
266
- NdtObject_dmark(void * self)
267
- {
268
- NdtObject * ndt = (NdtObject*)self;
269
-
270
- rb_gc_mark(ndt->rbuf);
271
- }
115
+ NdtObject_dmark(void * self) {}
272
116
 
273
117
  /* GC free the NdtObject struct. */
274
118
  static void
275
119
  NdtObject_dfree(void * self)
276
120
  {
277
121
  NdtObject * ndt = (NdtObject*)self;
278
-
279
- rb_ndtypes_gc_guard_unregister(ndt);
280
122
  xfree(ndt);
281
123
  }
282
124
 
@@ -333,13 +175,81 @@ NDTYPES_BOOL_FUNC(ndt_is_complex)
333
175
 
334
176
  NDTYPES_BOOL_FUNC(ndt_is_c_contiguous)
335
177
  NDTYPES_BOOL_FUNC(ndt_is_f_contiguous)
178
+ NDTYPES_BOOL_FUNC(ndt_is_var_contiguous)
179
+
180
+ static int
181
+ offsets_from_array(ndt_meta_t *m, VALUE array)
182
+ {
183
+ NDT_STATIC_CONTEXT(ctx);
184
+ VALUE temp;
185
+
186
+ Check_Type(array, T_ARRAY);
187
+
188
+ const int n = RARRAY_LEN(array);
189
+ if (n < 1 || n > NDT_MAX_DIM) {
190
+ rb_raise(rb_eValueError, "number of offsets arrays must be in [1, %d].", NDT_MAX_DIM);
191
+ }
192
+
193
+ m->ndims = 0;
194
+ for (int i = n-1; i >= 0; i--) {
195
+ temp = rb_ary_entry(array, i);
196
+ if (!RB_TYPE_P(temp, T_ARRAY)) {
197
+ rb_raise(rb_eValueError, "expected a list of offset lists.");
198
+ }
199
+
200
+ const int64_t noffsets = RARRAY_LEN(temp);
201
+ if (noffsets < 2 || noffsets > INT32_MAX) {
202
+ rb_raise(rb_eValueError, "length of a single offset list be in [2, INT32_MAX].");
203
+ }
204
+
205
+ int32_t * const offsets = ndt_alloc(noffsets, sizeof(int32_t));
206
+ if (offsets == NULL) {
207
+ rb_raise(rb_eNoMemError, "no memory to allocate offsets.");
208
+ }
209
+
210
+ for (int32_t k = 0; k < noffsets; k++) {
211
+ long long x = NUM2LL(rb_ary_entry(temp, k));
212
+
213
+ if (x < 0 || x > INT32_MAX) {
214
+ ndt_free(offsets);
215
+ rb_raise(rb_eValueError, "offset must be in [0, INT32_MAX].");
216
+ }
217
+ offsets[k] = (int32_t)x;
218
+ }
219
+
220
+ m->offsets[m->ndims] = ndt_offsets_from_ptr(offsets, (int32_t)noffsets, &ctx);
221
+ if (m->offsets[m->ndims] == NULL) {
222
+ seterr(&ctx);
223
+ raise_error();
224
+ }
225
+ m->ndims++;
226
+ }
227
+
228
+ return 0;
229
+ }
230
+
231
+ static VALUE
232
+ array_from_int64(int64_t x[NDT_MAX_DIM], int ndim)
233
+ {
234
+ VALUE array;
235
+ int i;
236
+
237
+ array = rb_ary_new2(ndim);
238
+
239
+ for (i = 0; i < ndim; ++i) {
240
+ VALUE v = LL2NUM(x[i]);
241
+ rb_ary_store(array, i, v);
242
+ }
243
+
244
+ return array;
245
+ }
336
246
 
337
247
  static VALUE
338
248
  NDTypes_from_object(VALUE self, VALUE type)
339
249
  {
340
250
  NDT_STATIC_CONTEXT(ctx);
341
251
  const char *cp;
342
- NdtObject *ndt_p;
252
+ NdtObject *self_p;
343
253
 
344
254
  if (NDT_CHECK_TYPE(type)) {
345
255
  return rb_funcall(type, rb_intern("dup"), 0, NULL);
@@ -347,16 +257,10 @@ NDTypes_from_object(VALUE self, VALUE type)
347
257
 
348
258
  cp = StringValuePtr(type);
349
259
 
350
- GET_NDT(self, ndt_p);
351
- RBUF(ndt_p) = rbuf_allocate();
352
- if (RBUF(ndt_p) == NULL) {
353
- rb_raise(rb_eNoMemError, "problem in allocating RBUF object.");
354
- }
355
-
356
- rb_ndtypes_gc_guard_register(ndt_p, RBUF(ndt_p));
260
+ GET_NDT(self, self_p);
357
261
 
358
- NDT(ndt_p) = ndt_from_string_fill_meta(rbuf_ndt_meta(self), cp, &ctx);
359
- if (NDT(ndt_p) == NULL) {
262
+ NDT(self_p) = ndt_from_string(cp, &ctx);
263
+ if (NDT(self_p) == NULL) {
360
264
  seterr(&ctx);
361
265
  raise_error();
362
266
  }
@@ -365,23 +269,33 @@ NDTypes_from_object(VALUE self, VALUE type)
365
269
  }
366
270
 
367
271
  static VALUE
368
- NDTypes_from_offsets_and_dtype(VALUE offsets, VALUE type)
272
+ NDTypes_from_offsets_and_dtype(VALUE self, VALUE offsets, VALUE type)
369
273
  {
370
274
  NDT_STATIC_CONTEXT(ctx);
371
- VALUE self;
372
275
  NdtObject *self_p;
276
+ ndt_meta_t m = {.ndims = 0, .offsets = {NULL}};
373
277
  const char *cp;
374
278
 
375
279
  Check_Type(type, T_STRING);
280
+ Check_Type(offsets, T_ARRAY);
376
281
 
377
282
  cp = StringValuePtr(type);
378
283
 
379
- self = NdtObject_alloc();
380
284
  GET_NDT(self, self_p);
381
- RBUF(self_p) = rbuf_from_offset_lists(offsets);
382
- NDT(self_p) = ndt_from_metadata_and_dtype(rbuf_ndt_meta(self_p), cp, &ctx);
383
285
 
384
- rb_ndtypes_gc_guard_register(self_p, RBUF(self_p));
286
+ if (offsets_from_array(&m, offsets) < 0) {
287
+ ndt_meta_clear(&m);
288
+ seterr(&ctx);
289
+ raise_error();
290
+ }
291
+
292
+ NDT(self_p) = ndt_from_metadata_and_dtype(&m, cp, &ctx);
293
+ ndt_meta_clear(&m);
294
+
295
+ if (NDT(self_p) == NULL) {
296
+ seterr(&ctx);
297
+ raise_error();
298
+ }
385
299
 
386
300
  return self;
387
301
  }
@@ -407,7 +321,7 @@ NDTypes_initialize(int argc, VALUE *argv, VALUE self)
407
321
  return NDTypes_from_object(self, type);
408
322
  }
409
323
 
410
- return NDTypes_from_offsets_and_dtype(offsets, type);
324
+ return NDTypes_from_offsets_and_dtype(self, offsets, type);
411
325
  }
412
326
 
413
327
  /* String representation of the type. */
@@ -436,15 +350,15 @@ NDTypes_to_s(VALUE self)
436
350
  static VALUE
437
351
  NDTypes_serialize(VALUE self)
438
352
  {
439
- NdtObject *ndt;
353
+ NdtObject *self_p;
440
354
  char *bytes;
441
355
  int64_t size;
442
356
  VALUE str;
443
357
 
444
358
  NDT_STATIC_CONTEXT(ctx);
445
- GET_NDT(self, ndt);
359
+ GET_NDT(self, self_p);
446
360
 
447
- size = ndt_serialize(&bytes, NDT(ndt), &ctx);
361
+ size = ndt_serialize(&bytes, NDT(self_p), &ctx);
448
362
  if (size < 0) {
449
363
  seterr(&ctx);
450
364
  raise_error();
@@ -467,7 +381,7 @@ NDTypes_ndim(VALUE self)
467
381
  const ndt_t *t = NDT(ndt_p);
468
382
 
469
383
  if (ndt_is_abstract(t)) {
470
- rb_raise(rb_eTypeError, "abstract type has no ndim.");
384
+ rb_raise(rb_eNoMethodError, "abstract type has no ndim.");
471
385
  }
472
386
 
473
387
  return LL2NUM(t->ndim);
@@ -502,7 +416,7 @@ NDTypes_itemsize(VALUE self)
502
416
  const ndt_t *t = NDT(ndt_p);
503
417
 
504
418
  if (ndt_is_abstract(t)) {
505
- rb_raise(rb_eTypeError, "abstract type has no datasize.");
419
+ rb_raise(rb_eNoMethodError, "abstract type has no datasize.");
506
420
  }
507
421
 
508
422
  switch (t->tag) {
@@ -531,7 +445,7 @@ NDTypes_align(VALUE self)
531
445
  const ndt_t *t = NDT(ndt_p);
532
446
 
533
447
  if (ndt_is_abstract(t)) {
534
- rb_raise(rb_eTypeError, "abstract type has no datasize.");
448
+ rb_raise(rb_eNoMethodError, "abstract type has no datasize.");
535
449
  }
536
450
 
537
451
  return LL2NUM(t->align);
@@ -631,6 +545,7 @@ NDTypes_match(VALUE self, VALUE other)
631
545
  return INT2BOOL(res);
632
546
  }
633
547
 
548
+ /* Implemented NDT#ast */
634
549
  static VALUE
635
550
  NDTypes_ast(VALUE self)
636
551
  {
@@ -675,47 +590,241 @@ NDTypes_pretty(VALUE self)
675
590
  return result;
676
591
  }
677
592
 
678
- /****************************************************************************/
679
- /* Class methods */
680
- /****************************************************************************/
593
+ /* NDT#shape */
594
+ static VALUE
595
+ NDTypes_shape(VALUE self)
596
+ {
597
+ NDT_STATIC_CONTEXT(ctx);
598
+ ndt_ndarray_t x;
599
+ NdtObject *self_p;
600
+
601
+ GET_NDT(self, self_p);
602
+
603
+ if (ndt_as_ndarray(&x, NDT(self_p), &ctx) < 0) {
604
+ seterr(&ctx);
605
+ raise_error();
606
+ }
607
+
608
+ return array_from_int64(x.shape, x.ndim);
609
+ }
681
610
 
682
- /* Deserialize a byte string into an NDTypes object. */
683
611
  static VALUE
684
- NDTypes_s_deserialize(VALUE klass, VALUE str)
612
+ NDTypes_strides(VALUE self)
685
613
  {
686
- NdtObject *ndt_p;
687
- ResourceBufferObject *rbuf_p;
688
- VALUE ndt, rbuf;
689
- char *cp;
690
- int64_t len;
691
614
  NDT_STATIC_CONTEXT(ctx);
615
+ ndt_ndarray_t x;
616
+ NdtObject *self_p;
692
617
 
693
- Check_Type(str, T_STRING);
618
+ GET_NDT(self, self_p);
694
619
 
695
- cp = StringValuePtr(str);
696
- if (cp == NULL) {
697
- // raise
620
+ if (ndt_as_ndarray(&x, NDT(self_p), &ctx) < 0) {
621
+ seterr(&ctx);
622
+ raise_error();
623
+ }
624
+
625
+ return array_from_int64(x.strides, x.ndim);
626
+ }
627
+
628
+ static int
629
+ parse_apply_args(const ndt_t* types[NDT_MAX_ARGS], int *num_intypes, int *num_outtypes,
630
+ int *num_args, VALUE input_types, VALUE out_types) {
631
+ size_t nin, nout;
632
+ if (RARRAY_LEN(input_types) == 0) {
633
+ rb_raise(rb_eArgError, "must specify more than 0 input types.");
634
+ }
635
+
636
+ nin = RARRAY_LEN(input_types);
637
+ if (nin > NDT_MAX_ARGS) {
638
+ rb_raise(rb_eArgError, "maximum number of arguments cannot exceed %d, got %d.",
639
+ NDT_MAX_ARGS, nin);
640
+ }
641
+
642
+ for (int i = 0; i < nin; ++i) {
643
+ VALUE v = rb_ary_entry(input_types, i);
644
+ NdtObject *v_p;
645
+
646
+ if (!NDT_CHECK_TYPE(v)) {
647
+ rb_raise(rb_eArgError, "every argument must be of type NDT.");
648
+ }
649
+
650
+ GET_NDT(v, v_p);
651
+ types[i] = NDT(v_p);
698
652
  }
699
- len = RSTRING_LEN(str);
700
653
 
701
- rbuf_p = ALLOC(ResourceBufferObject);
702
- rbuf_p->m = ndt_meta_new(&ctx);
703
- if (rbuf_p->m == NULL) {
704
- /* TODO: cannot alloc meta data */
654
+ if (out_types == Qnil) {
655
+ nout = 0;
656
+ }
657
+ else {
658
+ if (NDT_CHECK_TYPE(out_types)) {
659
+ NdtObject *out_p;
660
+ nout = 1;
661
+ if (nin + nout > NDT_MAX_ARGS) {
662
+ rb_raise(rb_eTypeError, "max number of args is %d, got %d.", NDT_MAX_ARGS, nin+nout);
663
+ }
664
+ GET_NDT(out_types, out_p);
665
+ types[nin] = NDT(out_p);
666
+ }
667
+ else if (TYPE(out_types) == T_ARRAY) {
668
+ nout = RARRAY_LEN(out_types);
669
+ if (nout > NDT_MAX_ARGS || nin+nout > NDT_MAX_ARGS) {
670
+ rb_raise(rb_eTypeError, "max number of args is %d, got %d.", NDT_MAX_ARGS, nin+nout);
671
+ }
672
+
673
+ for (int i = 0; i < nout; ++i) {
674
+ NdtObject *v_p;
675
+ VALUE v = rb_ary_entry(out_types, i);
676
+ if (!NDT_CHECK_TYPE(v)) {
677
+ rb_raise(rb_eTypeError, "expected NDT arguments for all out types.");
678
+ }
679
+ GET_NDT(v, v_p);
680
+ types[nin+i] = NDT(v_p);
681
+ }
682
+ }
683
+ else {
684
+ rb_raise(rb_eTypeError, "'out' argument must be ndt or a tuple of ndt.");
685
+ }
705
686
  }
706
687
 
707
- ndt_p = ALLOC(NdtObject);
708
- NDT(ndt_p) = ndt_deserialize(RBUF_NDT_M(rbuf_p), cp, len, &ctx);
709
- if (NDT(ndt_p) == NULL) {
710
- /* TODO: raise error for cannot deserialize */
688
+ for (int i = 0; i < nin+nout; ++i) {
689
+ ndt_incref(types[i]);
711
690
  }
712
691
 
713
- rbuf = WRAP_RBUF(cNDTypes_RBuf, rbuf_p);
714
- RBUF(ndt_p) = rbuf;
715
- rb_ndtypes_gc_guard_register(ndt_p, rbuf);
716
- ndt = WRAP_NDT(cNDTypes, ndt_p);
692
+ *num_intypes = (int)nin;
693
+ *num_outtypes = (int)nout;
694
+ *num_args = (int)nin + (int)nout;
695
+
696
+ return 0;
697
+
698
+ }
699
+
700
+ static VALUE
701
+ NDTypes_apply(VALUE self, VALUE input_types, VALUE out_types)
702
+ {
703
+ NDT_STATIC_CONTEXT(ctx);
704
+ const ndt_t *types[NDT_MAX_ARGS] = {NULL};
705
+ const int64_t li[NDT_MAX_ARGS] = {0};
706
+ ndt_apply_spec_t spec = ndt_apply_spec_empty;
707
+ VALUE res, flags, outer_dims, nin, nout, nargs, lst;
708
+ int ret;
709
+ int num_intypes, num_outtypes, num_args;
710
+ NdtObject *self_p;
711
+
712
+ Check_Type(input_types, T_ARRAY);
713
+
714
+ parse_apply_args(types, &num_intypes, &num_outtypes, &num_args, input_types, out_types);
715
+ GET_NDT(self, self_p);
716
+ const ndt_t * sig = NDT(self_p);
717
+ ret = ndt_typecheck(&spec, sig, types, li, num_intypes, num_outtypes, false,
718
+ NULL, NULL, &ctx);
719
+ ndt_type_array_clear(types, num_args);
717
720
 
718
- return ndt;
721
+ if (ret < 0) {
722
+ seterr(&ctx);
723
+ raise_error();
724
+ }
725
+
726
+ flags = rb_str_new2(ndt_apply_flags_as_string(&spec));
727
+ lst = rb_ary_new2(spec.nargs);
728
+
729
+ for (int i = 0; i < spec.nargs; ++i) {
730
+ VALUE x = NdtObject_alloc();
731
+ NdtObject *x_p;
732
+ GET_NDT(x, x_p);
733
+
734
+ NDT(x_p) = spec.types[i];
735
+ rb_ary_store(lst, i, x);
736
+ }
737
+
738
+ outer_dims = LL2NUM(spec.outer_dims);
739
+ nin = LL2NUM(spec.nin);
740
+ nout = LL2NUM(spec.nout);
741
+ nargs = LL2NUM(spec.nargs);
742
+
743
+ return rb_funcall(rb_const_get(cNDTypes, rb_intern("ApplySpec")), rb_intern("new"),
744
+ 6, flags, outer_dims, nin, nout, nargs, lst);
745
+ }
746
+
747
+ static const ndt_t *
748
+ from_string(VALUE v)
749
+ {
750
+ NDT_STATIC_CONTEXT(ctx);
751
+ const char *cp;
752
+ const ndt_t *t;
753
+
754
+ Check_Type(v, T_STRING);
755
+
756
+ cp = RSTRING_PTR(v);
757
+ t = ndt_from_string(cp, &ctx);
758
+ if (t == NULL) {
759
+ seterr(&ctx);
760
+ raise_error();
761
+ }
762
+
763
+ return t;
764
+ }
765
+
766
+ /* Implement NDT#_at */
767
+ static VALUE
768
+ NDTypes_at(VALUE self, VALUE obj_n, VALUE dtype)
769
+ {
770
+ NDT_STATIC_CONTEXT(ctx);
771
+ int n = FIX2INT(obj_n);
772
+ VALUE res;
773
+ const ndt_t *t, *dt;
774
+ NdtObject *dtype_p, *self_p;
775
+
776
+ if (dtype == Qnil) {
777
+ dt = NULL;
778
+ }
779
+ else if (NDT_CHECK_TYPE(dtype)) {
780
+ GET_NDT(dtype, dtype_p);
781
+ dt = NDT(dtype_p);
782
+ ndt_incref(dt);
783
+ }
784
+ else if (TYPE(dtype) == T_STRING) {
785
+ dt = from_string(dtype);
786
+ }
787
+ else {
788
+ rb_raise(rb_eTypeError, "dtype argument must be 'ndt' or 'str'");
789
+ }
790
+
791
+ GET_NDT(self, self_p);
792
+ t = ndt_copy_contiguous_at(NDT(self_p), n, dt, &ctx);
793
+
794
+ if (dt != NULL) {
795
+ ndt_decref(dt);
796
+ }
797
+ if (t == NULL) {
798
+ seterr(&ctx);
799
+ raise_error();
800
+ }
801
+
802
+ res = rb_ndtypes_from_type(t);
803
+ ndt_decref(t);
804
+
805
+ return res;
806
+ }
807
+
808
+ /****************************************************************************/
809
+ /* Class methods */
810
+ /****************************************************************************/
811
+
812
+ /* Deserialize a byte string into an NDTypes object. */
813
+ static VALUE
814
+ NDTypes_s_deserialize(VALUE klass, VALUE str)
815
+ {
816
+ NDT_STATIC_CONTEXT(ctx);
817
+ VALUE self;
818
+ NdtObject *self_p;
819
+
820
+ Check_Type(str, T_STRING);
821
+
822
+ self = NdtObject_alloc();
823
+ GET_NDT(self, self_p);
824
+
825
+ NDT(self_p) = ndt_deserialize(RSTRING_PTR(str), RSTRING_LEN(str), &ctx);
826
+
827
+ return self;
719
828
  }
720
829
 
721
830
  /* Create a typedef */
@@ -730,22 +839,17 @@ NDTypes_s_typedef(VALUE klass, VALUE new_type, VALUE old_type)
730
839
  Check_Type(old_type, T_STRING);
731
840
 
732
841
  cname = StringValueCStr(new_type);
733
- if (cname == NULL) {
734
-
735
- }
736
-
737
842
  ctype = StringValueCStr(old_type);
738
- if (ctype == NULL) {
739
-
740
- }
741
843
 
742
844
  t = ndt_from_string(ctype, &ctx);
743
845
  if (t == NULL) {
744
-
846
+ seterr(&ctx);
847
+ raise_error();
745
848
  }
746
849
 
747
850
  if (ndt_typedef(cname, t, NULL, &ctx) < 0) {
748
-
851
+ seterr(&ctx);
852
+ raise_error();
749
853
  }
750
854
 
751
855
  return Qnil;
@@ -757,7 +861,7 @@ NDTypes_s_instantiate(VALUE klass, VALUE name, VALUE type)
757
861
  {
758
862
  const char *cname;
759
863
  char *cp;
760
- ndt_t *t, *tp;
864
+ const ndt_t *t;//, *tp;
761
865
  NdtObject *type_p;
762
866
  NDT_STATIC_CONTEXT(ctx);
763
867
 
@@ -777,29 +881,53 @@ NDTypes_s_instantiate(VALUE klass, VALUE name, VALUE type)
777
881
 
778
882
  GET_NDT(type, type_p);
779
883
 
780
- tp = ndt_copy(NDT(type_p), &ctx);
781
- if (tp == NULL) {
782
- ndt_free(cp);
884
+ t = ndt_nominal(cp, NDT(type_p), false, &ctx);
885
+ if (t == NULL) {
783
886
  seterr(&ctx);
784
887
  raise_error();
785
888
  }
786
889
 
787
- t = ndt_nominal(cp, tp, &ctx);
788
- if (t == NULL) {
890
+ VALUE ret = rb_ndtypes_from_type(t);
891
+ ndt_decref(t);
892
+
893
+ return ret;
894
+ }
895
+
896
+ static VALUE
897
+ NDTypes_s_from_format(VALUE klass, VALUE format)
898
+ {
899
+ NDT_STATIC_CONTEXT(ctx);
900
+ VALUE self;
901
+ NdtObject *self_p;
902
+ const char *cp;
903
+
904
+ Check_Type(format, T_STRING);
905
+
906
+ cp = StringValueCStr(format);
907
+ self = NdtObject_alloc();
908
+
909
+ GET_NDT(self, self_p);
910
+
911
+ NDT(self_p) = ndt_from_bpformat(cp, &ctx);
912
+ if (NDT(self_p) == NULL) {
789
913
  seterr(&ctx);
790
914
  raise_error();
791
915
  }
792
916
 
793
- return rb_ndtypes_move_subtree(type, t);
917
+ return self;
794
918
  }
795
919
 
920
+
796
921
  /****************************************************************************/
797
922
  /* Public C API */
798
923
  /****************************************************************************/
799
924
 
800
925
  /* Create NDT object from ndt_t type struct. */
926
+ /* Increments the refcnt of the NDT so can be thought of as making
927
+ * a copy of the object.
928
+ */
801
929
  VALUE
802
- rb_ndtypes_from_type(ndt_t *type)
930
+ rb_ndtypes_from_type(const ndt_t *type)
803
931
  {
804
932
  VALUE self;
805
933
  NdtObject *self_p;
@@ -807,6 +935,7 @@ rb_ndtypes_from_type(ndt_t *type)
807
935
  self = NdtObject_alloc();
808
936
  GET_NDT(self, self_p);
809
937
 
938
+ ndt_incref(type);
810
939
  NDT(self_p) = type;
811
940
 
812
941
  return self;
@@ -889,11 +1018,6 @@ rb_ndtypes_move_subtree(VALUE src, ndt_t *t)
889
1018
  rb_raise(rb_eNoMemError, "could not allocate memory for ndt_copy().");
890
1019
  }
891
1020
 
892
- GET_NDT(src, src_p);
893
- RBUF(dest_p) = RBUF(src_p);
894
-
895
- rb_ndtypes_gc_guard_register(dest_p, RBUF(dest_p));
896
-
897
1021
  return dest;
898
1022
  }
899
1023
 
@@ -924,16 +1048,12 @@ rb_ndtypes_from_object(VALUE type)
924
1048
 
925
1049
  copy = NdtObject_alloc();
926
1050
  GET_NDT(copy, copy_p);
1051
+ NDT(copy_p) = ndt_from_string(cp, &ctx);
927
1052
 
928
- RBUF(copy_p) = rbuf_allocate();
929
- NDT(copy_p) = ndt_from_string_fill_meta(
930
- rbuf_ndt_meta(copy),
931
- cp, &ctx);
932
1053
  if (NDT(copy_p) == NULL) {
933
1054
  seterr(&ctx);
934
1055
  raise_error();
935
1056
  }
936
- rb_ndtypes_gc_guard_register(copy_p, RBUF(copy_p));
937
1057
 
938
1058
  return copy;
939
1059
  }
@@ -974,6 +1094,10 @@ void Init_ruby_ndtypes(void)
974
1094
  rb_define_method(cNDTypes, "match", NDTypes_match, 1);
975
1095
  rb_define_method(cNDTypes, "ast", NDTypes_ast, 0);
976
1096
  rb_define_method(cNDTypes, "pretty", NDTypes_pretty, 0);
1097
+ rb_define_method(cNDTypes, "shape", NDTypes_shape, 0);
1098
+ rb_define_method(cNDTypes, "strides", NDTypes_strides, 0);
1099
+ rb_define_method(cNDTypes, "_apply", NDTypes_apply, 2);
1100
+ rb_define_method(cNDTypes, "_at", NDTypes_at, 2);
977
1101
 
978
1102
  /* Boolean functions */
979
1103
  rb_define_method(cNDTypes, "concrete?", NDTypes_ndt_is_concrete, 0);
@@ -986,6 +1110,7 @@ void Init_ruby_ndtypes(void)
986
1110
  rb_define_method(cNDTypes, "complex?", NDTypes_ndt_is_complex, 0);
987
1111
  rb_define_method(cNDTypes, "c_contiguous?", NDTypes_ndt_is_c_contiguous, 0);
988
1112
  rb_define_method(cNDTypes, "f_contiguous?", NDTypes_ndt_is_f_contiguous, 0);
1113
+ rb_define_method(cNDTypes, "var_contiguous?", NDTypes_ndt_is_var_contiguous, 0);
989
1114
  rb_define_method(cNDTypes, "==", NDTypes_eqeq, 1);
990
1115
  rb_define_method(cNDTypes, "!=", NDTypes_neq, 1);
991
1116
 
@@ -993,11 +1118,9 @@ void Init_ruby_ndtypes(void)
993
1118
  rb_define_singleton_method(cNDTypes, "deserialize", NDTypes_s_deserialize, 1);
994
1119
  rb_define_singleton_method(cNDTypes, "typedef", NDTypes_s_typedef, 2);
995
1120
  rb_define_singleton_method(cNDTypes, "instantiate", NDTypes_s_instantiate, 2);
1121
+ rb_define_singleton_method(cNDTypes, "from_format", NDTypes_s_from_format, 1);
996
1122
 
997
1123
  /* Constants */
998
1124
  rb_define_const(cNDTypes, "MAX_DIM", INT2NUM(NDT_MAX_DIM));
999
-
1000
- /* GC guard init */
1001
- rb_ndtypes_init_gc_guard();
1002
1125
  }
1003
1126