xnd 0.2.0dev6 → 0.2.0dev7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/Rakefile +1 -1
  4. data/ext/ruby_xnd/GPATH +0 -0
  5. data/ext/ruby_xnd/GRTAGS +0 -0
  6. data/ext/ruby_xnd/GTAGS +0 -0
  7. data/ext/ruby_xnd/extconf.rb +8 -5
  8. data/ext/ruby_xnd/gc_guard.c +53 -2
  9. data/ext/ruby_xnd/gc_guard.h +8 -2
  10. data/ext/ruby_xnd/include/overflow.h +147 -0
  11. data/ext/ruby_xnd/include/ruby_xnd.h +62 -0
  12. data/ext/ruby_xnd/include/xnd.h +590 -0
  13. data/ext/ruby_xnd/lib/libxnd.a +0 -0
  14. data/ext/ruby_xnd/lib/libxnd.so +1 -0
  15. data/ext/ruby_xnd/lib/libxnd.so.0 +1 -0
  16. data/ext/ruby_xnd/lib/libxnd.so.0.2.0dev3 +0 -0
  17. data/ext/ruby_xnd/ruby_xnd.c +556 -47
  18. data/ext/ruby_xnd/ruby_xnd.h +2 -1
  19. data/ext/ruby_xnd/xnd/Makefile +80 -0
  20. data/ext/ruby_xnd/xnd/config.h +26 -0
  21. data/ext/ruby_xnd/xnd/config.h.in +3 -0
  22. data/ext/ruby_xnd/xnd/config.log +421 -0
  23. data/ext/ruby_xnd/xnd/config.status +1023 -0
  24. data/ext/ruby_xnd/xnd/configure +376 -8
  25. data/ext/ruby_xnd/xnd/configure.ac +48 -7
  26. data/ext/ruby_xnd/xnd/doc/xnd/index.rst +3 -1
  27. data/ext/ruby_xnd/xnd/doc/xnd/{types.rst → xnd.rst} +3 -18
  28. data/ext/ruby_xnd/xnd/libxnd/Makefile +142 -0
  29. data/ext/ruby_xnd/xnd/libxnd/Makefile.in +43 -3
  30. data/ext/ruby_xnd/xnd/libxnd/Makefile.vc +19 -3
  31. data/ext/ruby_xnd/xnd/libxnd/bitmaps.c +42 -3
  32. data/ext/ruby_xnd/xnd/libxnd/bitmaps.o +0 -0
  33. data/ext/ruby_xnd/xnd/libxnd/bounds.c +366 -0
  34. data/ext/ruby_xnd/xnd/libxnd/bounds.o +0 -0
  35. data/ext/ruby_xnd/xnd/libxnd/contrib.h +98 -0
  36. data/ext/ruby_xnd/xnd/libxnd/contrib/bfloat16.h +213 -0
  37. data/ext/ruby_xnd/xnd/libxnd/copy.c +155 -4
  38. data/ext/ruby_xnd/xnd/libxnd/copy.o +0 -0
  39. data/ext/ruby_xnd/xnd/libxnd/cuda/cuda_memory.cu +121 -0
  40. data/ext/ruby_xnd/xnd/libxnd/cuda/cuda_memory.h +58 -0
  41. data/ext/ruby_xnd/xnd/libxnd/equal.c +195 -7
  42. data/ext/ruby_xnd/xnd/libxnd/equal.o +0 -0
  43. data/ext/ruby_xnd/xnd/libxnd/inline.h +32 -0
  44. data/ext/ruby_xnd/xnd/libxnd/libxnd.a +0 -0
  45. data/ext/ruby_xnd/xnd/libxnd/libxnd.so +1 -0
  46. data/ext/ruby_xnd/xnd/libxnd/libxnd.so.0 +1 -0
  47. data/ext/ruby_xnd/xnd/libxnd/libxnd.so.0.2.0dev3 +0 -0
  48. data/ext/ruby_xnd/xnd/libxnd/shape.c +207 -0
  49. data/ext/ruby_xnd/xnd/libxnd/shape.o +0 -0
  50. data/ext/ruby_xnd/xnd/libxnd/split.c +2 -2
  51. data/ext/ruby_xnd/xnd/libxnd/split.o +0 -0
  52. data/ext/ruby_xnd/xnd/libxnd/tests/Makefile +39 -0
  53. data/ext/ruby_xnd/xnd/libxnd/xnd.c +613 -91
  54. data/ext/ruby_xnd/xnd/libxnd/xnd.h +145 -4
  55. data/ext/ruby_xnd/xnd/libxnd/xnd.o +0 -0
  56. data/ext/ruby_xnd/xnd/python/test_xnd.py +1125 -50
  57. data/ext/ruby_xnd/xnd/python/xnd/__init__.py +609 -124
  58. data/ext/ruby_xnd/xnd/python/xnd/_version.py +1 -0
  59. data/ext/ruby_xnd/xnd/python/xnd/_xnd.c +1652 -101
  60. data/ext/ruby_xnd/xnd/python/xnd/libxnd.a +0 -0
  61. data/ext/ruby_xnd/xnd/python/xnd/libxnd.so +1 -0
  62. data/ext/ruby_xnd/xnd/python/xnd/libxnd.so.0 +1 -0
  63. data/ext/ruby_xnd/xnd/python/xnd/libxnd.so.0.2.0dev3 +0 -0
  64. data/ext/ruby_xnd/xnd/python/xnd/pyxnd.h +1 -1
  65. data/ext/ruby_xnd/xnd/python/xnd/util.h +25 -0
  66. data/ext/ruby_xnd/xnd/python/xnd/xnd.h +590 -0
  67. data/ext/ruby_xnd/xnd/python/xnd_randvalue.py +106 -6
  68. data/ext/ruby_xnd/xnd/python/xnd_support.py +4 -0
  69. data/ext/ruby_xnd/xnd/setup.py +46 -4
  70. data/lib/ruby_xnd.so +0 -0
  71. data/lib/xnd.rb +39 -3
  72. data/lib/xnd/version.rb +2 -2
  73. data/xnd.gemspec +2 -1
  74. metadata +58 -5
@@ -35,12 +35,23 @@
35
35
  #define XND_H
36
36
 
37
37
 
38
+ #ifdef __cplusplus
39
+ extern "C" {
40
+ #endif
41
+
38
42
  #include <stdlib.h>
39
43
  #include <stdint.h>
40
44
  #include <string.h>
41
45
  #include <assert.h>
42
46
  #include "ndtypes.h"
43
47
 
48
+ #ifdef __cplusplus
49
+ #include <cstdint>
50
+ #else
51
+ #include <stdint.h>
52
+ #include <inttypes.h>
53
+ #endif
54
+
44
55
 
45
56
  #ifdef _MSC_VER
46
57
  #if defined (XND_EXPORT)
@@ -50,8 +61,13 @@
50
61
  #else
51
62
  #define XND_API
52
63
  #endif
64
+
65
+ #include "malloc.h"
66
+ #define ALLOCA(type, name, nmemb) type *name = _alloca(nmemb * sizeof(type))
53
67
  #else
54
68
  #define XND_API
69
+
70
+ #define ALLOCA(type, name, nmemb) type name[nmemb]
55
71
  #endif
56
72
 
57
73
 
@@ -73,24 +89,32 @@
73
89
  #define XND_OWN_DATA 0x00000002U /* data pointer */
74
90
  #define XND_OWN_STRINGS 0x00000004U /* embedded string pointers */
75
91
  #define XND_OWN_BYTES 0x00000008U /* embedded bytes pointers */
76
- #define XND_OWN_POINTERS 0x00000010U /* embedded pointers */
92
+ #define XND_OWN_ARRAYS 0x00000010U /* embedded array pointers */
93
+ #define XND_OWN_POINTERS 0x00000020U /* embedded pointers */
94
+ #define XND_CUDA_MANAGED 0x00000040U /* cuda managed memory */
77
95
 
78
96
  #define XND_OWN_ALL (XND_OWN_TYPE | \
79
97
  XND_OWN_DATA | \
80
98
  XND_OWN_STRINGS | \
81
99
  XND_OWN_BYTES | \
100
+ XND_OWN_ARRAYS | \
82
101
  XND_OWN_POINTERS)
83
102
 
84
103
  #define XND_OWN_EMBEDDED (XND_OWN_DATA | \
85
104
  XND_OWN_STRINGS | \
86
105
  XND_OWN_BYTES | \
106
+ XND_OWN_ARRAYS | \
87
107
  XND_OWN_POINTERS)
88
108
 
89
109
 
90
110
  /* Convenience macros to extract embedded values. */
91
111
  #define XND_POINTER_DATA(ptr) (*((char **)ptr))
112
+ #define XND_STRING_DATA(ptr) ((*((const char **)ptr)) == NULL ? "" : (*((const char **)ptr)))
92
113
  #define XND_BYTES_SIZE(ptr) (((ndt_bytes_t *)ptr)->size)
93
114
  #define XND_BYTES_DATA(ptr) (((ndt_bytes_t *)ptr)->data)
115
+ #define XND_ARRAY_SHAPE(ptr) (((ndt_array_t *)ptr)->shape)
116
+ #define XND_ARRAY_DATA(ptr) (((ndt_array_t *)ptr)->data)
117
+ #define XND_UNION_TAG(ptr) (*((uint8_t *)ptr))
94
118
 
95
119
 
96
120
  /* Bitmap tree. */
@@ -142,6 +166,7 @@ typedef struct xnd_view {
142
166
 
143
167
  XND_API xnd_master_t *xnd_empty_from_string(const char *s, uint32_t flags, ndt_context_t *ctx);
144
168
  XND_API xnd_master_t *xnd_empty_from_type(const ndt_t *t, uint32_t flags, ndt_context_t *ctx);
169
+ XND_API void xnd_clear(xnd_t * const x, const uint32_t flags);
145
170
  XND_API void xnd_del(xnd_master_t *x);
146
171
 
147
172
  /* Create and delete pristine xnd_t buffers. */
@@ -153,18 +178,22 @@ XND_API void xnd_del_buffer(xnd_t *x, uint32_t flags);
153
178
  /* Traverse xnd memory blocks */
154
179
  /*****************************************************************************/
155
180
 
181
+ XND_API bool have_stored_index(const ndt_t *t);
182
+ XND_API int64_t get_stored_index(const ndt_t *t);
183
+ XND_API xnd_t apply_stored_index(const xnd_t *x, ndt_context_t *ctx);
184
+ XND_API xnd_t apply_stored_indices(const xnd_t *x, ndt_context_t *ctx);
185
+
156
186
  XND_API xnd_t xnd_subtree_index(const xnd_t *x, const int64_t *indices, int len,
157
187
  ndt_context_t *ctx);
158
188
 
159
189
  XND_API xnd_t xnd_subtree(const xnd_t *x, const xnd_index_t indices[], int len,
160
190
  ndt_context_t *ctx);
161
191
 
162
- XND_API xnd_t xnd_multikey(const xnd_t *x, const xnd_index_t indices[], int len,
163
- ndt_context_t *ctx);
164
-
165
192
  XND_API xnd_t xnd_subscript(const xnd_t *x, const xnd_index_t indices[], int len,
166
193
  ndt_context_t *ctx);
167
194
 
195
+ XND_API xnd_t xnd_reshape(const xnd_t *x, int64_t shape[], int ndim, char order, ndt_context_t *ctx);
196
+
168
197
  XND_API xnd_t *xnd_split(const xnd_t *x, int64_t *n, int max_outer, ndt_context_t *ctx);
169
198
 
170
199
  XND_API int xnd_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx);
@@ -173,6 +202,14 @@ XND_API int xnd_strict_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
173
202
  XND_API int xnd_copy(xnd_t *y, const xnd_t *x, uint32_t flags, ndt_context_t *ctx);
174
203
 
175
204
 
205
+ /*****************************************************************************/
206
+ /* Bounds checking */
207
+ /*****************************************************************************/
208
+
209
+ XND_API int xnd_bounds_check(const ndt_t *t, const int64_t linear_index,
210
+ const int64_t bufsize, ndt_context_t *ctx);
211
+
212
+
176
213
  /*****************************************************************************/
177
214
  /* Bitmaps */
178
215
  /*****************************************************************************/
@@ -193,6 +230,8 @@ XND_API int xnd_is_na(const xnd_t *x);
193
230
  XND_API extern const xnd_t xnd_error;
194
231
  XND_API extern const xnd_bitmap_t xnd_bitmap_empty;
195
232
 
233
+ XND_API int xnd_err_occurred(const xnd_t *x);
234
+
196
235
 
197
236
  /*****************************************************************************/
198
237
  /* Unstable API */
@@ -219,10 +258,43 @@ XND_API bool xnd_double_is_little_endian(void);
219
258
  XND_API bool xnd_double_is_big_endian(void);
220
259
 
221
260
 
261
+ /*****************************************************************************/
262
+ /* BFloat16 */
263
+ /*****************************************************************************/
264
+
265
+ XND_API void xnd_bfloat_pack(char *p, double x);
266
+ XND_API double xnd_bfloat_unpack(char *p);
267
+
268
+
269
+ /*****************************************************************************/
270
+ /* Cuda */
271
+ /*****************************************************************************/
272
+
273
+ void *xnd_cuda_calloc_managed(uint16_t align, int64_t size, ndt_context_t *ctx);
274
+ void xnd_cuda_free(void *ptr);
275
+ int xnd_cuda_mem_prefetch_async(const void *ptr, int64_t count, int dev, ndt_context_t *ctx);
276
+ int xnd_cuda_device_synchronize(ndt_context_t *ctx);
277
+
278
+
222
279
  /*****************************************************************************/
223
280
  /* Static inline functions */
224
281
  /*****************************************************************************/
225
282
 
283
+ /* Check index bounds and adjust negative indices. */
284
+ static inline int64_t
285
+ adjust_index(const int64_t i, const int64_t shape, ndt_context_t *ctx)
286
+ {
287
+ const int64_t k = i < 0 ? i + shape : i;
288
+
289
+ if (k < 0 || k >= shape || k > XND_SSIZE_MAX) {
290
+ ndt_err_format(ctx, NDT_IndexError,
291
+ "index with value %" PRIi64 " out of bounds", i);
292
+ return -1;
293
+ }
294
+
295
+ return k;
296
+ }
297
+
226
298
  /*
227
299
  * This looks inefficient, but both gcc and clang clean up unused xnd_t members.
228
300
  */
@@ -258,6 +330,14 @@ xnd_fixed_shape(const xnd_t *x)
258
330
  return t->FixedDim.shape;
259
331
  }
260
332
 
333
+ static inline int64_t
334
+ xnd_fixed_step(const xnd_t *x)
335
+ {
336
+ const ndt_t *t = x->type;
337
+ assert(t->tag == FixedDim);
338
+ return t->Concrete.FixedDim.step;
339
+ }
340
+
261
341
  static inline int64_t
262
342
  xnd_fixed_shape_at(const xnd_t *x, const int i)
263
343
  {
@@ -339,6 +419,25 @@ xnd_record_next(const xnd_t *x, const int64_t i, ndt_context_t *ctx)
339
419
  return next;
340
420
  }
341
421
 
422
+ static inline xnd_t
423
+ xnd_union_next(const xnd_t *x, ndt_context_t *ctx)
424
+ {
425
+ uint8_t i = XND_UNION_TAG(x->ptr);
426
+ const ndt_t *t = x->type;
427
+ xnd_t next;
428
+
429
+ next.bitmap = xnd_bitmap_next(x, i, ctx);
430
+ if (ndt_err_occurred(ctx)) {
431
+ return xnd_error;
432
+ }
433
+
434
+ next.index = 0;
435
+ next.type = t->Union.types[i];
436
+ next.ptr = x->ptr+1;
437
+
438
+ return next;
439
+ }
440
+
342
441
  static inline xnd_t
343
442
  xnd_ref_next(const xnd_t *x, ndt_context_t *ctx)
344
443
  {
@@ -393,6 +492,23 @@ xnd_nominal_next(const xnd_t *x, ndt_context_t *ctx)
393
492
  return next;
394
493
  }
395
494
 
495
+ static inline xnd_t
496
+ xnd_array_next(const xnd_t *x, const int64_t i)
497
+ {
498
+ const ndt_t *t = x->type;
499
+ const ndt_t *u = t->Array.type;
500
+ xnd_t next;
501
+
502
+ assert(t->tag == Array);
503
+
504
+ next.bitmap = x->bitmap;
505
+ next.index = 0;
506
+ next.type = u;
507
+ next.ptr = XND_ARRAY_DATA(x->ptr) + i * next.type->datasize;
508
+
509
+ return next;
510
+ }
511
+
396
512
  #if NDT_SYS_BIG_ENDIAN == 1
397
513
  #define XND_REV_COND NDT_LITTLE_ENDIAN
398
514
  #else
@@ -445,5 +561,30 @@ le(uint32_t flags)
445
561
  dest = _x; \
446
562
  } while (0)
447
563
 
564
+ #define APPLY_STORED_INDICES_INT(x) \
565
+ xnd_t _##x##tail; \
566
+ if (have_stored_index(x->type)) { \
567
+ _##x##tail = apply_stored_indices(x, ctx); \
568
+ if (xnd_err_occurred(&_##x##tail)) { \
569
+ return -1; \
570
+ } \
571
+ x = &_##x##tail; \
572
+ }
573
+
574
+ #define APPLY_STORED_INDICES_XND(x) \
575
+ xnd_t _##x##tail; \
576
+ if (have_stored_index(x->type)) { \
577
+ _##x##tail = apply_stored_indices(x, ctx); \
578
+ if (xnd_err_occurred(&_##x##tail)) { \
579
+ return xnd_error; \
580
+ } \
581
+ x = &_##x##tail; \
582
+ }
583
+
584
+
585
+ #ifdef __cplusplus
586
+ } /* END extern "C" */
587
+ #endif
588
+
448
589
 
449
590
  #endif /* XND_H */
@@ -33,11 +33,12 @@
33
33
  import sys, unittest, argparse
34
34
  from math import isinf, isnan
35
35
  from ndtypes import ndt, typedef
36
- from xnd import xnd, XndEllipsis
36
+ from xnd import xnd, XndEllipsis, data_shapes
37
37
  from xnd._xnd import _test_view_subscript, _test_view_new
38
38
  from xnd_support import *
39
39
  from xnd_randvalue import *
40
40
  from _testbuffer import ndarray, ND_WRITABLE
41
+ import random
41
42
 
42
43
 
43
44
  try:
@@ -59,6 +60,24 @@ def check_buffer(x):
59
60
  del x
60
61
  y.tobytes()
61
62
 
63
+ def check_copy_contiguous(self, x):
64
+ y = x.copy_contiguous()
65
+ xv = x.value
66
+ yv = y.value
67
+ if have_none(xv) and have_none(yv):
68
+ self.assertEqual(xv, yv)
69
+ else:
70
+ self.assertEqual(x, y)
71
+
72
+ dtype = maxtype.get(x.dtype)
73
+ if dtype is not None:
74
+ y = x.copy_contiguous(dtype=dtype)
75
+ yv = y.value
76
+ if have_none(xv) and have_none(yv):
77
+ self.assertEqual(xv, yv)
78
+ else:
79
+ self.assertEqual(x, y)
80
+
62
81
 
63
82
  class XndTestCase(unittest.TestCase):
64
83
 
@@ -68,7 +87,17 @@ class XndTestCase(unittest.TestCase):
68
87
 
69
88
  def assertNotStrictEqual(self, x, y):
70
89
  self.assertFalse(x.strict_equal(y))
71
- self.assertNotEqual(x, y)
90
+
91
+ def check_serialize(self, x):
92
+ try:
93
+ b = x.serialize()
94
+ except NotImplementedError:
95
+ return
96
+ try:
97
+ y = x.deserialize(b)
98
+ except NotImplementedError:
99
+ return
100
+ self.assertEqual(x, y)
72
101
 
73
102
 
74
103
  class TestModule(XndTestCase):
@@ -145,6 +174,12 @@ class TestFixedDim(XndTestCase):
145
174
  self.assertEqual(x.type, t)
146
175
  self.assertEqual(x.value, vv)
147
176
  self.assertEqual(len(x), len(vv))
177
+ self.assertTrue(x.type.is_c_contiguous())
178
+
179
+ self.assertRaises(ValueError, xnd.empty, "?3 * int64")
180
+ self.assertRaises(ValueError, xnd.empty, "?2 * 3 * int64")
181
+ self.assertRaises(ValueError, xnd.empty, "2 * ?3 * int64")
182
+ self.assertRaises(ValueError, xnd.empty, "?2 * ?3 * int64")
148
183
 
149
184
  def test_fixed_dim_subscript(self):
150
185
  test_cases = [
@@ -161,6 +196,8 @@ class TestFixedDim(XndTestCase):
161
196
  t = ndt(s)
162
197
  x = xnd(v, type=t)
163
198
  check_buffer(x)
199
+ self.check_serialize(x)
200
+ self.assertTrue(x.type.is_c_contiguous())
164
201
 
165
202
  for i in range(3):
166
203
  self.assertEqual(x[i].value, nd[i])
@@ -175,9 +212,11 @@ class TestFixedDim(XndTestCase):
175
212
  for start in list(range(-3, 4)) + [None]:
176
213
  for stop in list(range(-3, 4)) + [None]:
177
214
  for step in list(range(-3, 0)) + list(range(1, 4)) + [None]:
178
- s = slice(start, stop, step)
179
- self.assertEqual(x[s].value, nd[s])
180
- check_buffer(x[s])
215
+ sl = slice(start, stop, step)
216
+ self.assertEqual(x[sl].value, nd[sl])
217
+ check_buffer(x[sl])
218
+ self.check_serialize(x[sl])
219
+ check_copy_contiguous(self, x[sl])
181
220
 
182
221
  self.assertEqual(x[:, 0].value, nd[:, 0])
183
222
  self.assertEqual(x[:, 1].value, nd[:, 1])
@@ -368,6 +407,13 @@ class TestFixedDim(XndTestCase):
368
407
  y[indices] = w
369
408
  self.assertNotStrictEqual(x, y)
370
409
 
410
+ def test_fixed_dim_equal(self):
411
+ x = xnd([1,2,3], dtype='int64')
412
+ y = xnd([1,2,3], dtype='float32')
413
+
414
+ self.assertEqual(x, y)
415
+ self.assertNotStrictEqual(x, y)
416
+
371
417
 
372
418
  class TestFortran(XndTestCase):
373
419
 
@@ -396,6 +442,7 @@ class TestFortran(XndTestCase):
396
442
  self.assertEqual(x.type, t)
397
443
  self.assertEqual(x.value, vv)
398
444
  self.assertEqual(len(x), len(vv))
445
+ self.assertTrue(x.type.is_f_contiguous())
399
446
 
400
447
  def test_fortran_subscript(self):
401
448
  test_cases = [
@@ -412,6 +459,8 @@ class TestFortran(XndTestCase):
412
459
  t = ndt(s)
413
460
  x = xnd(v, type=t)
414
461
  check_buffer(x)
462
+ self.check_serialize(x)
463
+ self.assertTrue(x.type.is_f_contiguous())
415
464
 
416
465
  for i in range(3):
417
466
  self.assertEqual(x[i].value, nd[i])
@@ -426,9 +475,11 @@ class TestFortran(XndTestCase):
426
475
  for start in list(range(-3, 4)) + [None]:
427
476
  for stop in list(range(-3, 4)) + [None]:
428
477
  for step in list(range(-3, 0)) + list(range(1, 4)) + [None]:
429
- s = slice(start, stop, step)
430
- self.assertEqual(x[s].value, nd[s])
431
- check_buffer(x[s])
478
+ sl = slice(start, stop, step)
479
+ self.assertEqual(x[sl].value, nd[sl])
480
+ check_buffer(x[sl])
481
+ self.check_serialize(x[sl])
482
+ check_copy_contiguous(self, x[sl])
432
483
 
433
484
  self.assertEqual(x[:, 0].value, nd[:, 0])
434
485
  self.assertEqual(x[:, 1].value, nd[:, 1])
@@ -642,6 +693,14 @@ class TestVarDim(XndTestCase):
642
693
  self.assertEqual(x.type, t)
643
694
  self.assertEqual(x.value, vv)
644
695
  self.assertEqual(len(x), len(vv))
696
+ self.assertTrue(x.type.is_var_contiguous())
697
+ check_copy_contiguous(self, x)
698
+ self.check_serialize(x)
699
+
700
+ self.assertRaises(NotImplementedError, xnd.empty, "?var(offsets=[0, 3]) * int64")
701
+ self.assertRaises(NotImplementedError, xnd.empty, "?var(offsets=[0, 2]) * var(offsets=[0, 3, 10]) * int64")
702
+ self.assertRaises(NotImplementedError, xnd.empty, "var(offsets=[0, 2]) * ?var(offsets=[0, 3, 10]) * int64")
703
+ self.assertRaises(NotImplementedError, xnd.empty, "?var(offsets=[0, 2]) * ?var(offsets=[0, 3, 10]) * int64")
645
704
 
646
705
  def test_var_dim_assign(self):
647
706
  ### Regular data ###
@@ -712,39 +771,41 @@ class TestVarDim(XndTestCase):
712
771
  x = xnd([0, 1, 2, 3, 4], type="var(offsets=[0,5]) * complex128")
713
772
  sig = ndt("var... * complex128 -> var... * complex128")
714
773
 
715
- spec = sig.apply([x.type])
716
- self.assertTrue(type_equal(spec.out_types[0], x.type))
774
+ spec = sig.apply(x.type)
775
+ self.assertTrue(type_equal(spec.types[1], x.type))
717
776
 
718
777
  y = x[::-1]
719
- spec = sig.apply([y.type])
720
- self.assertTrue(type_equal(spec.out_types[0], y.type))
778
+ spec = sig.apply(y.type)
779
+ self.assertTrue(type_equal(spec.types[1], y.type))
721
780
 
722
781
  y = x[1:3:-1]
723
- spec = sig.apply([y.type])
724
- self.assertTrue(type_equal(spec.out_types[0], y.type))
782
+ spec = sig.apply(y.type)
783
+ self.assertTrue(type_equal(spec.types[1], y.type))
725
784
 
726
785
  sig = ndt("var... * complex128, var... * complex128 -> var... * complex128")
727
- spec = sig.apply([x.type, x.type])
728
- self.assertTrue(type_equal(spec.out_types[0], x.type))
786
+ spec = sig.apply(x.type, x.type)
787
+ self.assertTrue(type_equal(spec.types[1], x.type))
729
788
 
730
789
  y = x[::-1]
731
790
  sig = ndt("var... * complex128, var... * complex128 -> var... * complex128")
732
- spec = sig.apply([x.type, y.type])
733
- self.assertTrue(type_equal(spec.out_types[0], x.type))
791
+ spec = sig.apply(x.type, y.type)
792
+ self.assertTrue(type_equal(spec.types[1], x.type))
734
793
 
735
794
  x = xnd([[0], [1, 2], [3, 4, 5]], dtype="complex128")
736
795
  y = xnd([[3, 4, 5], [1, 2], [0]], dtype="complex128")
737
796
  z = y[::-1]
738
797
  sig = ndt("var... * complex128, var... * complex128 -> var... * complex128")
739
- spec = sig.apply([x.type, z.type])
740
- self.assertTrue(type_equal(spec.out_types[0], x.type))
798
+ spec = sig.apply(x.type, z.type)
799
+ self.assertTrue(type_equal(spec.types[1], x.type))
800
+ self.assertEqual(x.dtype, ndt("complex128"))
741
801
 
742
802
  x = xnd([[0], [1, 2], [3, 4, 5]], dtype="complex128")
743
803
  y = xnd([[5, 4, 3], [2, 1], [0]], dtype="complex128")
744
804
  z = y[::-1, ::-1]
745
805
  sig = ndt("var... * complex128, var... * complex128 -> var... * complex128")
746
- spec = sig.apply([x.type, z.type])
747
- self.assertTrue(type_equal(spec.out_types[0], x.type))
806
+ spec = sig.apply(x.type, z.type)
807
+ self.assertTrue(type_equal(spec.types[1], x.type))
808
+ self.assertEqual(x.dtype, ndt("complex128"))
748
809
 
749
810
  def test_var_dim_richcompare(self):
750
811
 
@@ -786,13 +847,19 @@ class TestVarDim(XndTestCase):
786
847
  x = xnd([[1], [4,5], [6,7,8], [9,10,11,12]])
787
848
 
788
849
  y = xnd([[1], [6,7,8]])
789
- self.assertStrictEqual(x[::2], y)
850
+ z = x[::2]
851
+ self.assertStrictEqual(z, y)
852
+ self.assertFalse(z.type.is_var_contiguous())
790
853
 
791
854
  y = xnd([[9,10,11,12], [4,5]])
792
- self.assertStrictEqual(x[::-2], y)
855
+ z = x[::-2]
856
+ self.assertStrictEqual(z, y)
857
+ self.assertFalse(z.type.is_var_contiguous())
793
858
 
794
859
  y = xnd([[12,11,10,9], [5,4]])
795
- self.assertStrictEqual(x[::-2, ::-1], y)
860
+ z = x[::-2, ::-1]
861
+ self.assertStrictEqual(z, y)
862
+ self.assertFalse(z.type.is_var_contiguous())
796
863
 
797
864
  # Test corner cases and many dtypes.
798
865
  for v, t, u, _, _ in EQUAL_TEST_CASES:
@@ -807,11 +874,15 @@ class TestVarDim(XndTestCase):
807
874
  x = xnd(vv, type=ttt)
808
875
  y = xnd(vv, type=ttt)
809
876
  self.assertStrictEqual(x, y)
877
+ check_copy_contiguous(self, x)
878
+ self.check_serialize(x)
810
879
 
811
880
  if u is not None:
812
881
  uuu = ndt(uu)
813
882
  y = xnd(vv, type=uuu)
814
883
  self.assertStrictEqual(x, y)
884
+ check_copy_contiguous(self, y)
885
+ self.check_serialize(y)
815
886
 
816
887
  for v, t, u, w, eq in EQUAL_TEST_CASES:
817
888
  for vv, tt, uu, indices in [
@@ -836,6 +907,8 @@ class TestVarDim(XndTestCase):
836
907
  else:
837
908
  self.assertNotStrictEqual(x, y)
838
909
 
910
+ check_copy_contiguous(self, x)
911
+
839
912
  if u is not None:
840
913
  uuu = ndt(uu)
841
914
  y = xnd(vv, type=uuu)
@@ -844,6 +917,8 @@ class TestVarDim(XndTestCase):
844
917
  else:
845
918
  self.assertNotStrictEqual(x, y)
846
919
 
920
+ check_copy_contiguous(self, y)
921
+
847
922
  if w is not None:
848
923
  y = xnd(vv, type=ttt)
849
924
  y[indices] = w
@@ -853,6 +928,47 @@ class TestVarDim(XndTestCase):
853
928
  y[indices] = w
854
929
  self.assertNotStrictEqual(x, y)
855
930
 
931
+ check_copy_contiguous(self, y)
932
+
933
+ def test_var_dim_nested(self):
934
+
935
+ t = "var(offsets=[0,2]) * var(offsets=[0,1,3]) * (var(offsets=[0,2]) * var(offsets=[0,3,7]) * float32, int64)"
936
+ v = [[([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0, 6.0]], -1)],
937
+ [([[7.0, 8.0, 9.0], [10.0, 11.0, 12.0, 13.0]], -2),
938
+ ([[14.0, 15.0, 16.0], [17.0, 18.0, 19.0, 20.0]], -3)]]
939
+
940
+ x = xnd(v, type=t)
941
+
942
+ self.assertEqual(x, v)
943
+ self.assertEqual(x.value, v)
944
+
945
+ self.assertEqual(x[0], v[0])
946
+ self.assertEqual(x[1], v[1])
947
+
948
+ self.assertEqual(x[0,0], v[0][0])
949
+ self.assertEqual(x[1,0], v[1][0])
950
+ self.assertEqual(x[1,1], v[1][1])
951
+
952
+ self.assertEqual(x[0,0,0], v[0][0][0])
953
+ self.assertEqual(x[0,0,1], v[0][0][1])
954
+
955
+ self.assertEqual(x[1,0,0], v[1][0][0])
956
+ self.assertEqual(x[1,0,1], v[1][0][1])
957
+
958
+ self.assertEqual(x[1,1,0], v[1][1][0])
959
+ self.assertEqual(x[1,1,1], v[1][1][1])
960
+
961
+ self.assertEqual(x[0,0,0,0], v[0][0][0][0])
962
+ self.assertEqual(x[0,0,0,1], v[0][0][0][1])
963
+
964
+ self.assertEqual(x[0,0,0,0], v[0][0][0][0])
965
+ self.assertEqual(x[0,0,0,1], v[0][0][0][1])
966
+
967
+ self.assertEqual(x[1,0,0,0,1], v[1][0][0][0][1])
968
+ self.assertEqual(x[1,0,0,0,1], v[1][0][0][0][1])
969
+
970
+ check_copy_contiguous(self, x)
971
+
856
972
 
857
973
  class TestSymbolicDim(XndTestCase):
858
974
 
@@ -925,17 +1041,20 @@ class TestTuple(XndTestCase):
925
1041
  x[1] = v[1]
926
1042
  x[2] = v[2]
927
1043
  self.assertEqual(x.value, v)
1044
+ check_copy_contiguous(self, x)
928
1045
 
929
1046
  v = (-2.5+125j, None, None)
930
1047
  x[0] = v[0]
931
1048
  x[1] = v[1]
932
1049
  x[2] = v[2]
933
1050
  self.assertEqual(x.value, v)
1051
+ check_copy_contiguous(self, x)
934
1052
 
935
1053
  x = xnd([("a", 100, 10.5), ("a", 100, 10.5)])
936
1054
  x[0][1] = 20000000
937
1055
  self.assertEqual(x[0][1], 20000000)
938
1056
  self.assertEqual(x[0, 1], 20000000)
1057
+ check_copy_contiguous(self, x)
939
1058
 
940
1059
  def test_tuple_overflow(self):
941
1060
  # Type cannot be created.
@@ -955,6 +1074,7 @@ class TestTuple(XndTestCase):
955
1074
  lst = [(None, 1, 2), (3, None, 4), (5, 6, None)]
956
1075
  x = xnd(lst, dtype="(?int64, ?int64, ?int64)")
957
1076
  self.assertEqual(x.value, lst)
1077
+ self.assertEqual(x.dtype, ndt("(?int64, ?int64, ?int64)"))
958
1078
 
959
1079
  def test_tuple_richcompare(self):
960
1080
 
@@ -998,6 +1118,7 @@ class TestTuple(XndTestCase):
998
1118
  x = xnd(v, type=t)
999
1119
  y = xnd(v, type=t)
1000
1120
  self.assertStrictEqual(x, y)
1121
+ check_copy_contiguous(self, x)
1001
1122
 
1002
1123
  w = y[0].value
1003
1124
  y[0] = 11
@@ -1040,6 +1161,7 @@ class TestTuple(XndTestCase):
1040
1161
  x = xnd(vv, type=ttt)
1041
1162
  y = xnd(vv, type=ttt)
1042
1163
  self.assertStrictEqual(x, y)
1164
+ check_copy_contiguous(self, x)
1043
1165
 
1044
1166
  if u is not None:
1045
1167
  uuu = ndt(uu)
@@ -1065,6 +1187,8 @@ class TestTuple(XndTestCase):
1065
1187
  else:
1066
1188
  self.assertNotStrictEqual(x, y)
1067
1189
 
1190
+ check_copy_contiguous(self, x)
1191
+
1068
1192
  if u is not None:
1069
1193
  uuu = ndt(uu)
1070
1194
  y = xnd(vv, type=uuu)
@@ -1112,6 +1236,7 @@ class TestRecord(XndTestCase):
1112
1236
  x['z'] = v['z']
1113
1237
 
1114
1238
  self.assertEqual(x.value, v)
1239
+ check_copy_contiguous(self, x)
1115
1240
 
1116
1241
  ### Optional data ###
1117
1242
  x = xnd.empty("{x: complex64, y: ?bytes, z: ?string}")
@@ -1121,17 +1246,20 @@ class TestRecord(XndTestCase):
1121
1246
  x['y'] = v['y']
1122
1247
  x['z'] = v['z']
1123
1248
  self.assertEqual(x.value, v)
1249
+ check_copy_contiguous(self, x)
1124
1250
 
1125
1251
  v = R['x': -2.5+125j, 'y': None, 'z': None]
1126
1252
  x['x'] = v['x']
1127
1253
  x['y'] = v['y']
1128
1254
  x['z'] = v['z']
1129
1255
  self.assertEqual(x.value, v)
1256
+ check_copy_contiguous(self, x)
1130
1257
 
1131
1258
  x = xnd([R['x': "abc", 'y': 100, 'z': 10.5]])
1132
1259
  x[0][1] = 20000000
1133
1260
  self.assertEqual(x[0][1], 20000000)
1134
1261
  self.assertEqual(x[0, 1], 20000000)
1262
+ check_copy_contiguous(self, x)
1135
1263
 
1136
1264
  def test_record_overflow(self):
1137
1265
  # Type cannot be created.
@@ -1152,6 +1280,8 @@ class TestRecord(XndTestCase):
1152
1280
  R['a': 5, 'b': 6, 'c': None]]
1153
1281
  x = xnd(lst, dtype="{a: ?int64, b: ?int64, c: ?int64}")
1154
1282
  self.assertEqual(x.value, lst)
1283
+ check_copy_contiguous(self, x)
1284
+ self.assertEqual(x.dtype, ndt("{a: ?int64, b: ?int64, c: ?int64}"))
1155
1285
 
1156
1286
  def test_record_richcompare(self):
1157
1287
 
@@ -1197,12 +1327,14 @@ class TestRecord(XndTestCase):
1197
1327
  x = xnd(v, type=t)
1198
1328
  y = xnd(v, type=t)
1199
1329
  self.assertStrictEqual(x, y)
1330
+ check_copy_contiguous(self, x)
1200
1331
 
1201
1332
  w = y[0].value
1202
1333
  y[0] = 11
1203
1334
  self.assertNotStrictEqual(x, y)
1204
1335
  y[0] = w
1205
1336
  self.assertStrictEqual(x, y)
1337
+ check_copy_contiguous(self, x)
1206
1338
 
1207
1339
  w = y[1].value
1208
1340
  y[1] = "\U00001234\U00001001abx"
@@ -1237,6 +1369,7 @@ class TestRecord(XndTestCase):
1237
1369
  ttt = ndt(tt)
1238
1370
 
1239
1371
  x = xnd(vv, type=ttt)
1372
+ check_copy_contiguous(self, x)
1240
1373
 
1241
1374
  y = xnd(vv, type=ttt)
1242
1375
  self.assertStrictEqual(x, y)
@@ -1245,6 +1378,7 @@ class TestRecord(XndTestCase):
1245
1378
  uuu = ndt(uu)
1246
1379
  y = xnd(vv, type=uuu)
1247
1380
  self.assertStrictEqual(x, y)
1381
+ check_copy_contiguous(self, y)
1248
1382
 
1249
1383
  for v, t, u, w, eq in EQUAL_TEST_CASES:
1250
1384
  for vv, tt, uu, indices in [
@@ -1257,6 +1391,7 @@ class TestRecord(XndTestCase):
1257
1391
  uuu = ndt(uu)
1258
1392
 
1259
1393
  x = xnd(vv, type=ttt)
1394
+ check_copy_contiguous(self, x)
1260
1395
 
1261
1396
  y = xnd(vv, type=ttt)
1262
1397
  if eq:
@@ -1270,11 +1405,490 @@ class TestRecord(XndTestCase):
1270
1405
  self.assertStrictEqual(x, y)
1271
1406
  else:
1272
1407
  self.assertNotStrictEqual(x, y)
1408
+ check_copy_contiguous(self, y)
1273
1409
 
1274
1410
  if w is not None:
1275
1411
  y = xnd(vv, type=ttt)
1276
1412
  y[indices] = w
1277
1413
  self.assertNotStrictEqual(x, y)
1414
+ check_copy_contiguous(self, y)
1415
+
1416
+
1417
+ class TestUnion(XndTestCase):
1418
+
1419
+ def test_union_empty(self):
1420
+ for v, s in DTYPE_EMPTY_TEST_CASES:
1421
+ for vv, ss in [
1422
+ (('X', v), "[X of %s]" % s),
1423
+ (('X', {'y': v}), "[X of {y: %s}]" % s),
1424
+
1425
+ (('X', 0 * [v]), "[X of 0 * %s]" % s),
1426
+ (('X', {'y': 0 * [v]}), "[X of {y: 0 * %s}]" % s),
1427
+ (('X', 1 * [v]), "[X of 1 * %s]" % s),
1428
+ (('X', 3 * [v]), "[X of 3 * %s]" % s),
1429
+ (('X', 3 * [v]), "[X of 3 * %s | Y of complex128]" % s)]:
1430
+
1431
+ if "ref" in ss or "&" in ss:
1432
+ # unsupported types for union members
1433
+ continue
1434
+
1435
+ t = ndt(ss)
1436
+ x = xnd.empty(ss)
1437
+ self.assertEqual(x.type, t)
1438
+ self.assertEqual(x.value, vv)
1439
+
1440
+ def test_union_assign(self):
1441
+ ### Regular data ###
1442
+ x = xnd.empty("[X of complex64 | Y of bytes | Z of string]")
1443
+
1444
+ v = ('X', 1+20j)
1445
+ x[()] = v
1446
+ self.assertEqual(x.value, v)
1447
+ check_copy_contiguous(self, x)
1448
+
1449
+ v = ('Y', b"abc")
1450
+ x[()] = v
1451
+ self.assertEqual(x.value, v)
1452
+ check_copy_contiguous(self, x)
1453
+
1454
+ v = ('Z', "abc")
1455
+ x[()] = v
1456
+ self.assertEqual(x.value, v)
1457
+ check_copy_contiguous(self, x)
1458
+
1459
+ def test_union_indexing(self):
1460
+ ### Regular data ###
1461
+ x = xnd.empty("[X of complex64 | Y of bytes | Z of string]")
1462
+
1463
+ v = ('X', 1+20j)
1464
+ x[()] = v
1465
+ self.assertEqual(x[0], v[1])
1466
+ self.assertEqual(x['X'], v[1])
1467
+ self.assertRaises(ValueError, x.__getitem__, 1)
1468
+ self.assertRaises(ValueError, x.__getitem__, 'Y')
1469
+ self.assertRaises(ValueError, x.__getitem__, 2)
1470
+ self.assertRaises(ValueError, x.__getitem__, 'Z')
1471
+ self.assertRaises(ValueError, x.__getitem__, -1)
1472
+ self.assertRaises(IndexError, x.__getitem__, 3)
1473
+ self.assertRaises(ValueError, x.__getitem__, 'A')
1474
+
1475
+ def test_union_overflow(self):
1476
+ # Type cannot be created.
1477
+ s = "[a: 4611686018427387904 * uint8, b: 4611686018427387904 * uint8}"
1478
+ self.assertRaises(ValueError, xnd.empty, s)
1479
+
1480
+ if HAVE_64_BIT:
1481
+ # Allocation fails.
1482
+ s = "[A of 2 * uint8 | B of 9223372036854775808 * uint8]"
1483
+ self.assertRaises(ValueError, xnd.empty, s)
1484
+ else:
1485
+ # Allocation fails.
1486
+ s = "[A of 2 * uint8 | B of 2147483648 * uint8}"
1487
+ self.assertRaises(ValueError, xnd.empty, s)
1488
+
1489
+ def test_union_optional_values(self):
1490
+ lst = [('A', None), ('B', 10), ('C', (None, "abc"))]
1491
+ x = xnd(lst, dtype="[A of ?int64 | B of int64 | C of (?int64, string)]")
1492
+ self.assertEqual(x.value, lst)
1493
+ check_copy_contiguous(self, x)
1494
+ self.assertEqual(x.dtype, ndt("[A of ?int64 | B of int64 | C of (?int64, string)]"))
1495
+
1496
+ def test_union_richcompare(self):
1497
+
1498
+ # Simple tests.
1499
+ x = xnd(('Record', R['a': 1, 'b': 2.0, 'c': "3", 'd': b"123"]),
1500
+ type="[Int of int64 | Record of {a: uint8, b: float32, c: string, d: bytes}]")
1501
+
1502
+ self.assertIs(x.__lt__(x), NotImplemented)
1503
+ self.assertIs(x.__le__(x), NotImplemented)
1504
+ self.assertIs(x.__gt__(x), NotImplemented)
1505
+ self.assertIs(x.__ge__(x), NotImplemented)
1506
+
1507
+ y = x.copy_contiguous()
1508
+ self.assertStrictEqual(x, y)
1509
+
1510
+ self.assertNotStrictEqual(x, xnd(R['z': 1, 'b': 2.0, 'c': "3", 'd': b"123"]))
1511
+ self.assertNotStrictEqual(x, xnd(R['a': 2, 'b': 2.0, 'c': "3", 'd': b"123"]))
1512
+ self.assertNotStrictEqual(x, xnd(R['a': 1, 'b': 2.1, 'c': "3", 'd': b"123"]))
1513
+ self.assertNotStrictEqual(x, xnd(R['a': 1, 'b': 2.0, 'c': "", 'd': b"123"]))
1514
+ self.assertNotStrictEqual(x, xnd(R['a': 1, 'b': 2.0, 'c': "345", 'd': "123"]))
1515
+ self.assertNotStrictEqual(x, xnd(R['a': 1, 'b': 2.0, 'c': "3", 'd': b""]))
1516
+ self.assertNotStrictEqual(x, xnd(R['a': 1, 'b': 2.0, 'c': "3", 'd': b"12345"]))
1517
+
1518
+ # Nested structures.
1519
+ t = """
1520
+ {a: uint8,
1521
+ b: fixed_string(100, 'utf32'),
1522
+ c: {x: complex128,
1523
+ y: 2 * 3 * {v: [Int of int64 | Tuple of (bytes, string)],
1524
+ u: bytes}},
1525
+ d: ref(string)}
1526
+ """
1527
+
1528
+ v = R['a': 10,
1529
+ 'b': "\U00001234\U00001001abc",
1530
+ 'c': R['x': 12.1e244+3j,
1531
+ 'y': [[R['v': ('Tuple', (b"123", "456")), 'u': 10 * b"22"],
1532
+ R['v': ('Int', 10), 'u': 10 * b"23"],
1533
+ R['v': ('Int', 20), 'u': 10 * b"24"]],
1534
+ [R['v': ('Int', 30), 'u': b"a"],
1535
+ R['v': ('Tuple', (b"01234", "56789")), 'u': b"ab"],
1536
+ R['v': ('Tuple', (b"", "")), 'u': b"abc"]]]],
1537
+ 'd': "xyz"]
1538
+
1539
+ x = xnd(v, type=t)
1540
+ y = xnd(v, type=t)
1541
+ self.assertStrictEqual(x, y)
1542
+ check_copy_contiguous(self, x)
1543
+
1544
+ w = y['c', 'y', 0, 0, 'v'].value
1545
+ y['c', 'y', 0, 0, 'v'] = ('Int', 12345)
1546
+ self.assertNotStrictEqual(x, y)
1547
+ y['c', 'y', 0, 0, 'v'] = w
1548
+ self.assertStrictEqual(x, y)
1549
+ check_copy_contiguous(self, x)
1550
+
1551
+ # Test corner cases and many dtypes.
1552
+ for v, t, u, _, _ in EQUAL_TEST_CASES:
1553
+ for vv, tt, uu in [
1554
+ (('Some', 0 * [v]), "[Int of int64 | Some of 0 * %s]" % t, "[Int of int64 | Some of 0 * %s]" % u),
1555
+ (('Some', {'y': 0 * [v]}), "[Float of float16 | Some of {y: 0 * %s}]" % t, "[Float of float16 | Some of {y: 0 * %s}]" % u)]:
1556
+
1557
+ if "ref" in tt or "&" in tt:
1558
+ # unsupported types for union members
1559
+ continue
1560
+
1561
+ if "ref" in uu or "&" in uu:
1562
+ # unsupported types for union members
1563
+ continue
1564
+
1565
+ ttt = ndt(tt)
1566
+
1567
+ x = xnd(vv, type=ttt)
1568
+ check_copy_contiguous(self, x)
1569
+
1570
+ y = xnd(vv, type=ttt)
1571
+ self.assertStrictEqual(x, y)
1572
+
1573
+ if u is not None:
1574
+ uuu = ndt(uu)
1575
+ y = xnd(vv, type=uuu)
1576
+ self.assertStrictEqual(x, y)
1577
+ check_copy_contiguous(self, y)
1578
+
1579
+ for v, t, u, w, eq in EQUAL_TEST_CASES:
1580
+ for vv, tt, uu, indices in [
1581
+ (('Some', v), "[Some of %s]" % t, "[Some of %s]" % u, (0,)),
1582
+ (('Some', 3 * [v]), "[Some of 3 * %s]" % t, "[Some of 3 * %s]" % u, (0, 2))]:
1583
+
1584
+ if "ref" in tt or "&" in tt:
1585
+ # unsupported types for union members
1586
+ continue
1587
+
1588
+ if "ref" in uu or "&" in uu:
1589
+ # unsupported types for union members
1590
+ continue
1591
+
1592
+ ttt = ndt(tt)
1593
+ uuu = ndt(uu)
1594
+
1595
+ x = xnd(vv, type=ttt)
1596
+ check_copy_contiguous(self, x)
1597
+
1598
+ y = xnd(vv, type=ttt)
1599
+ if eq:
1600
+ self.assertStrictEqual(x, y)
1601
+ else:
1602
+ self.assertNotStrictEqual(x, y)
1603
+
1604
+ if u is not None:
1605
+ y = xnd(vv, type=uuu)
1606
+ if eq:
1607
+ self.assertStrictEqual(x, y)
1608
+ else:
1609
+ self.assertNotStrictEqual(x, y)
1610
+ check_copy_contiguous(self, y)
1611
+
1612
+
1613
+ class TestArray(XndTestCase):
1614
+
1615
+ def test_array_empty(self):
1616
+ for v, s in DTYPE_EMPTY_TEST_CASES:
1617
+ for _, ss in [
1618
+ (0 * [v], "array * %s" % s),
1619
+ (1 * [v], "array * %s" % s),
1620
+ (2 * [v], "array * %s" % s),
1621
+ (1000 * [v], "array * %s" % s),
1622
+
1623
+ (0 * [0 * [v]], "array * array * %s" % s),
1624
+ (0 * [1 * [v]], "array * array * %s" % s),
1625
+ (1 * [0 * [v]], "array * array * %s" % s),
1626
+
1627
+ (1 * [1 * [v]], "array * array * %s" % s),
1628
+ (1 * [2 * [v]], "array * array * %s" % s),
1629
+ (2 * [1 * [v]], "array * array * %s" % s),
1630
+ (2 * [2 * [v]], "array * array * %s" % s),
1631
+ (2 * [3 * [v]], "array * array * %s" % s),
1632
+ (3 * [2 * [v]], "array * array * %s" % s),
1633
+ (3 * [40 * [v]], "array * array * %s" % s)]:
1634
+
1635
+ if "?" in ss or "ref" in ss or "&" in ss:
1636
+ continue
1637
+
1638
+ t = ndt(ss)
1639
+ x = xnd.empty(ss)
1640
+ self.assertEqual(x.type, t)
1641
+ self.assertEqual(x.value, [])
1642
+ self.assertEqual(len(x), len([]))
1643
+ self.assertFalse(x.type.is_c_contiguous())
1644
+
1645
+ def test_array_subscript(self):
1646
+ test_cases = [
1647
+ ([[11.12-2.3j, -1222+20e8j],
1648
+ [complex("inf"), -0.00002j],
1649
+ [0.201+1j, -1+1e301j]], "array * array * complex128"),
1650
+ ]
1651
+
1652
+ for v, s in test_cases:
1653
+ nd = NDArray(v)
1654
+ t = ndt(s)
1655
+ x = xnd(v, type=t)
1656
+ self.assertFalse(x.type.is_c_contiguous())
1657
+
1658
+ for i in range(3):
1659
+ self.assertEqual(x[i].value, nd[i])
1660
+
1661
+ for i in range(3):
1662
+ for k in range(2):
1663
+ self.assertEqual(x[i][k], nd[i][k])
1664
+ self.assertEqual(x[i, k], nd[i][k])
1665
+
1666
+ self.assertEqual(x[()].value, nd[:])
1667
+
1668
+ def test_array_assign(self):
1669
+ x = xnd.empty("array * array * float64")
1670
+ v = [[0.0, 1.0, 2.0, 3.0], [4.0, 5.0, 6.0, 7.0]]
1671
+
1672
+ # Full slice
1673
+ x[()] = v
1674
+ self.assertEqual(x.value, v)
1675
+
1676
+ # Subarray, variable shapes
1677
+ x[0] = v[0] = [1.2, -3e45, float("inf")]
1678
+ self.assertEqual(x.value, v)
1679
+
1680
+ x[1] = v[1] = [-11.25, 3.355e301, -0.000002, -5000.2, -322.25]
1681
+ self.assertEqual(x.value, v)
1682
+
1683
+ # Subarray, fixed shapes
1684
+ x[0] = v[0] = [1.2, -3e45, float("inf"), -322.25]
1685
+ self.assertEqual(x.value, v)
1686
+
1687
+ x[1] = v[1] = [-11.25, 3.355e301, -0.000002, -5000.2]
1688
+ self.assertEqual(x.value, v)
1689
+
1690
+ # Single values
1691
+ for i in range(2):
1692
+ for j in range(4):
1693
+ x[i][j] = v[i][j] = 3.22 * i + j
1694
+ self.assertEqual(x.value, v)
1695
+
1696
+ # Tuple indexing
1697
+ for i in range(2):
1698
+ for j in range(4):
1699
+ x[i, j] = v[i][j] = -3.002e1 * i + j
1700
+ self.assertEqual(x.value, v)
1701
+
1702
+ def test_array_richcompare(self):
1703
+
1704
+ x = xnd([1,2,3,4], type="array * int64")
1705
+
1706
+ self.assertIs(x.__lt__(x), NotImplemented)
1707
+ self.assertIs(x.__le__(x), NotImplemented)
1708
+ self.assertIs(x.__gt__(x), NotImplemented)
1709
+ self.assertIs(x.__ge__(x), NotImplemented)
1710
+
1711
+ self.assertStrictEqual(x, xnd([1,2,3,4], type="array * int64"))
1712
+
1713
+ # Different type, shape and/or data.
1714
+ self.assertNotStrictEqual(x, xnd([1,2,3,100]))
1715
+ self.assertNotStrictEqual(x, xnd([1,2,3,100], type="array * int64"))
1716
+ self.assertNotStrictEqual(x, xnd([1,2,3], type="array * int64"))
1717
+ self.assertNotStrictEqual(x, xnd([1,2,3,4,5], type="array * int64"))
1718
+
1719
+ self.assertStrictEqual(x[()], x)
1720
+
1721
+ # Simple multidimensional arrays.
1722
+ x = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], type="array * array * int64")
1723
+ y = xnd([[1,2,3], [4,5,6], [7,8,9], [10,11,12]], type="array * array * int64")
1724
+ self.assertStrictEqual(x, y)
1725
+
1726
+ for i in range(4):
1727
+ for k in range(3):
1728
+ v = y[i, k]
1729
+ y[i, k] = 100
1730
+ self.assertNotStrictEqual(x, y)
1731
+ y[i, k] = v
1732
+
1733
+ # Flexible multidimensional arrays.
1734
+ x = xnd([[1], [4,5], [7,8,9]], type="array * array * int64")
1735
+ y = xnd([[1], [4,5], [7,8,9]], type="array * array * int64")
1736
+ self.assertStrictEqual(x, y)
1737
+
1738
+ for i in range(3):
1739
+ v = y[i, 0]
1740
+ y[i, 0] = 100
1741
+ self.assertNotStrictEqual(x, y)
1742
+ y[i, 0] = v
1743
+
1744
+ # Test corner cases and many dtypes.
1745
+ for v, t, u, _, _ in EQUAL_TEST_CASES:
1746
+ for vv, tt, uu in [
1747
+ (0 * [v], "array * %s" % t, "array * %s" % u),
1748
+ (0 * [0 * [v]], "array * array * %s" % t, "array * array * %s" % u),
1749
+ (0 * [1 * [v]], "array * array * %s" % t, "array * array * %s" % u),
1750
+ (1 * [0 * [v]], "array * array * %s" % t, "array * array * %s" % u)]:
1751
+
1752
+ if "?" in tt or "ref" in tt or "&" in tt:
1753
+ continue
1754
+ if "?" in uu or "ref" in uu or "&" in uu:
1755
+ continue
1756
+
1757
+ ttt = ndt(tt)
1758
+
1759
+ x = xnd(vv, type=ttt)
1760
+ y = xnd(vv, type=ttt)
1761
+ self.assertStrictEqual(x, y)
1762
+
1763
+ if u is not None:
1764
+ uuu = ndt(uu)
1765
+ y = xnd(vv, type=uuu)
1766
+ self.assertStrictEqual(x, y)
1767
+
1768
+ for v, t, u, w, eq in EQUAL_TEST_CASES:
1769
+ for vv, tt, uu, indices in [
1770
+ (1 * [v], "array * %s" % t, "array * %s" % u, (0,)),
1771
+ (2 * [v], "array * %s" % t, "array * %s" % u, (1,)),
1772
+ (1000 * [v], "array * %s" % t, "array * %s" % u, (961,))]:
1773
+
1774
+ if "?" in tt or "ref" in tt or "&" in tt:
1775
+ continue
1776
+ if "?" in uu or "ref" in uu or "&" in uu:
1777
+ continue
1778
+
1779
+ ttt = ndt(tt)
1780
+ uuu = ndt(uu)
1781
+
1782
+ x = xnd(vv, type=ttt)
1783
+
1784
+ y = xnd(vv, type=ttt)
1785
+ if eq:
1786
+ self.assertStrictEqual(x, y)
1787
+ else:
1788
+ self.assertNotStrictEqual(x, y)
1789
+
1790
+ if u is not None:
1791
+ y = xnd(vv, type=uuu)
1792
+ if eq:
1793
+ self.assertStrictEqual(x, y)
1794
+ else:
1795
+ self.assertNotStrictEqual(x, y)
1796
+
1797
+ if w is not None:
1798
+ y = xnd(vv, type=ttt)
1799
+ y[indices] = w
1800
+ self.assertNotStrictEqual(x, y)
1801
+
1802
+ y = xnd(vv, type=uuu)
1803
+ y[indices] = w
1804
+ self.assertNotStrictEqual(x, y)
1805
+
1806
+ def test_array_equal(self):
1807
+ x = xnd([1,2,3], type='array * int64')
1808
+ y = xnd([1,2,3], type='array * float32')
1809
+
1810
+ self.assertEqual(x, y)
1811
+ self.assertNotStrictEqual(x, y)
1812
+
1813
+ def test_array_geojson_tuple(self):
1814
+ v = { "type": "FeatureCollection",
1815
+ "features": (
1816
+ { "type": "Feature",
1817
+ "geometry": { "type": "Point",
1818
+ "coordinates": [110.0, 0.7] },
1819
+ "properties": {"prop0": "value0"} },
1820
+ { "type": "Feature",
1821
+ "geometry": { "type": "LineString",
1822
+ "coordinates": [[102.1, 0.1], [103.2, 1.1], [104.3, 0.1], [105.5, 1.1]] },
1823
+ "properties": {"prop0": "value0", "prop1": 0} }
1824
+ ),
1825
+ }
1826
+
1827
+ t = """
1828
+ { type: string,
1829
+ features: (
1830
+ { type: string,
1831
+ geometry: { type: string,
1832
+ coordinates: array * float64 },
1833
+ properties: { prop0: string } },
1834
+ { type: string,
1835
+ geometry: { type: string,
1836
+ coordinates: array * array * float64 },
1837
+ properties: { prop0: string, prop1: int64 } }
1838
+ )
1839
+ }
1840
+ """
1841
+
1842
+ x = xnd(v, type=t)
1843
+
1844
+ p = [110.0, 0.7]
1845
+ ls = [[102.1, 0.1], [103.2, 1.1], [104.3, 0.1], [105.5, 1.1]]
1846
+
1847
+ self.assertEqual(x['features', 0, 'geometry', 'coordinates'], p)
1848
+ self.assertEqual(x['features', 1, 'geometry', 'coordinates'], ls)
1849
+
1850
+ p = [110.0, 0.7, 1.1, 200]
1851
+ ls = [[102.1, 0.1], [103.2, 1.1], [104.3, 0.1], [105.5, 1.1], [107, 1.2]]
1852
+ x['features', 0, 'geometry', 'coordinates'] = p
1853
+ x['features', 1, 'geometry', 'coordinates'] = ls
1854
+
1855
+ self.assertEqual(x['features', 0, 'geometry', 'coordinates', 3], 200)
1856
+ self.assertEqual(x['features', 1, 'geometry', 'coordinates', 4, 1], 1.2)
1857
+
1858
+ def test_array_geojson_union(self):
1859
+ typedef("id",
1860
+ """[
1861
+ String of string
1862
+ | Int of int64
1863
+ ]""")
1864
+
1865
+ typedef("position", "array * float64")
1866
+
1867
+ typedef("geometry",
1868
+ """[
1869
+ Point of position
1870
+ | MultiPoint of array * position
1871
+ | LineString of array * position
1872
+ | MultiLineString of array * array * position
1873
+ | Polygon of array * position
1874
+ | MultiPolygon of array * array * position
1875
+ ]""")
1876
+
1877
+ v = [ ("Point", [110.0, 0.7]),
1878
+ ("LineString", [[102.1, 0.1], [103.2, 1.1], [104.3, 0.1], [105.5, 1.1]])]
1879
+
1880
+ x = xnd(v, type="array * geometry")
1881
+
1882
+ p = [110.0, 0.7]
1883
+ ls = [[102.1, 0.1], [103.2, 1.1], [104.3, 0.1], [105.5, 1.1]]
1884
+
1885
+ self.assertEqual(x[0, 'Point'], p)
1886
+ self.assertEqual(x[1, 'LineString'], ls)
1887
+
1888
+ p = [110.0, 0.7, 1.1, 200]
1889
+ ls = [[102.1, 0.1], [103.2, 1.1], [104.3, 0.1], [105.5, 1.1], [107, 1.2]]
1890
+ x[0, 'Point'] = p
1891
+ x[1, 'LineString'] = ls
1278
1892
 
1279
1893
 
1280
1894
  class TestRef(XndTestCase):
@@ -1327,6 +1941,8 @@ class TestRef(XndTestCase):
1327
1941
  v = 2 * [3 * [inner]]
1328
1942
 
1329
1943
  x = xnd(v, type="2 * 3 * ref(4 * 5 * string)")
1944
+ check_copy_contiguous(self, x)
1945
+ self.assertEqual(x.dtype, ndt("ref(4 * 5 * string)"))
1330
1946
 
1331
1947
  for i in range(2):
1332
1948
  for j in range(3):
@@ -1334,6 +1950,7 @@ class TestRef(XndTestCase):
1334
1950
  for l in range(5):
1335
1951
  self.assertEqual(x[i][j][k][l], inner[k][l])
1336
1952
  self.assertEqual(x[i, j, k, l], inner[k][l])
1953
+ check_copy_contiguous(self, x[i, j, k, l])
1337
1954
 
1338
1955
  def test_ref_assign(self):
1339
1956
  # If a ref is a dtype but contains an array itself, assigning through
@@ -1388,6 +2005,7 @@ class TestRef(XndTestCase):
1388
2005
  ttt = ndt(tt)
1389
2006
 
1390
2007
  x = xnd(vv, type=ttt)
2008
+ check_copy_contiguous(self, x)
1391
2009
 
1392
2010
  y = xnd(vv, type=ttt)
1393
2011
  self.assertStrictEqual(x, y)
@@ -1472,6 +2090,7 @@ class TestConstr(XndTestCase):
1472
2090
  v = 2 * [3 * [inner]]
1473
2091
 
1474
2092
  x = xnd(v, type="2 * 3 * InnerArray(4 * 5 * string)")
2093
+ check_copy_contiguous(self, x)
1475
2094
 
1476
2095
  for i in range(2):
1477
2096
  for j in range(3):
@@ -1479,6 +2098,7 @@ class TestConstr(XndTestCase):
1479
2098
  for l in range(5):
1480
2099
  self.assertEqual(x[i][j][k][l], inner[k][l])
1481
2100
  self.assertEqual(x[i, j, k, l], inner[k][l])
2101
+ check_copy_contiguous(self, x[i, j, k, l])
1482
2102
 
1483
2103
  def test_constr_assign(self):
1484
2104
  # If a constr is a dtype but contains an array itself, assigning through
@@ -1622,6 +2242,7 @@ class TestNominal(XndTestCase):
1622
2242
  v = 2 * [3 * [inner]]
1623
2243
 
1624
2244
  x = xnd(v, type="2 * 3 * inner")
2245
+ check_copy_contiguous(self, x)
1625
2246
 
1626
2247
  for i in range(2):
1627
2248
  for j in range(3):
@@ -1731,6 +2352,7 @@ class TestCategorical(XndTestCase):
1731
2352
  def test_categorical_richcompare(self):
1732
2353
  t = "3 * categorical(NA, 'January', 'August')"
1733
2354
  x = xnd(['August', 'January', 'January'], type=t)
2355
+ check_copy_contiguous(self, x)
1734
2356
 
1735
2357
  y = xnd(['August', 'January', 'January'], type=t)
1736
2358
  self.assertStrictEqual(x, y)
@@ -1773,12 +2395,14 @@ class TestFixedString(XndTestCase):
1773
2395
  v = ["\u1111\u2222\u3333", "\u1112\u2223\u3334"]
1774
2396
  x = xnd(v, type=t)
1775
2397
  self.assertEqual(x.value, v)
2398
+ check_copy_contiguous(self, x)
1776
2399
 
1777
2400
 
1778
2401
  t = "2 * fixed_string(3, 'utf32')"
1779
2402
  v = ["\U00011111\U00022222\U00033333", "\U00011112\U00022223\U00033334"]
1780
2403
  x = xnd(v, type=t)
1781
2404
  self.assertEqual(x.value, v)
2405
+ check_copy_contiguous(self, x)
1782
2406
 
1783
2407
  def test_fixed_string_assign(self):
1784
2408
  t = "2 * fixed_string(3, 'utf32')"
@@ -1826,6 +2450,7 @@ class TestFixedString(XndTestCase):
1826
2450
  self.assertStrictEqual(x, y)
1827
2451
  y[()] = w
1828
2452
  self.assertNotStrictEqual(x, y)
2453
+ check_copy_contiguous(self, x)
1829
2454
 
1830
2455
 
1831
2456
  class TestFixedBytesKind(XndTestCase):
@@ -1861,7 +2486,7 @@ class TestFixedBytes(XndTestCase):
1861
2486
 
1862
2487
  x[0] = b"xyz"
1863
2488
  self.assertEqual(x.value, [b"xyz", b"123"])
1864
-
2489
+ check_copy_contiguous(self, x)
1865
2490
 
1866
2491
  t = "2 * fixed_bytes(size=3, align=1)"
1867
2492
  v = [b"abc", b"123"]
@@ -1941,6 +2566,7 @@ class TestString(XndTestCase):
1941
2566
 
1942
2567
  self.assertEqual(x[0]['b'], "thisguy")
1943
2568
  self.assertEqual(x[1]['b'], "thatguy")
2569
+ check_copy_contiguous(self, x)
1944
2570
 
1945
2571
  def test_string_assign(self):
1946
2572
  t = '2 * {a: complex128, b: string}'
@@ -1987,6 +2613,8 @@ class TestBytes(XndTestCase):
1987
2613
  v = 2 * [inner]
1988
2614
 
1989
2615
  x = xnd(v, type=t)
2616
+ check_copy_contiguous(self, x)
2617
+
1990
2618
  for i in range(2):
1991
2619
  for k in range(3):
1992
2620
  x[i, k] = inner[k] = bytes(chr(ord('x') + k), "ascii")
@@ -2009,9 +2637,11 @@ class TestBool(XndTestCase):
2009
2637
  # From bool.
2010
2638
  x = xnd(True, type="bool")
2011
2639
  self.assertIs(x.value, True)
2640
+ check_copy_contiguous(self, x)
2012
2641
 
2013
2642
  x = xnd(False, type="bool")
2014
2643
  self.assertIs(x.value, False)
2644
+ check_copy_contiguous(self, x)
2015
2645
 
2016
2646
  # From int.
2017
2647
  x = xnd(1, type="bool")
@@ -2023,6 +2653,7 @@ class TestBool(XndTestCase):
2023
2653
  # From object (for numpy compat: np.bool([1,2,3]))
2024
2654
  x = xnd([1,2,3], type="bool")
2025
2655
  self.assertIs(x.value, True)
2656
+ check_copy_contiguous(self, x)
2026
2657
 
2027
2658
  x = xnd(None, type="?bool")
2028
2659
  self.assertIs(x.value, None)
@@ -2074,6 +2705,7 @@ class TestSigned(XndTestCase):
2074
2705
  t = "int%d" % n
2075
2706
  x = xnd(i, type=t)
2076
2707
  self.assertEqual(x.value, 10)
2708
+ check_copy_contiguous(self, x)
2077
2709
 
2078
2710
  # Test broken input.
2079
2711
  for n in (8, 16, 32, 64):
@@ -2123,6 +2755,7 @@ class TestUnsigned(XndTestCase):
2123
2755
  t = "uint%d" % n
2124
2756
  x = xnd(i, type=t)
2125
2757
  self.assertEqual(x.value, 10)
2758
+ check_copy_contiguous(self, x)
2126
2759
 
2127
2760
  # Test broken input.
2128
2761
  for n in (8, 16, 32, 64):
@@ -2151,6 +2784,63 @@ class TestFloatKind(XndTestCase):
2151
2784
 
2152
2785
  class TestFloat(XndTestCase):
2153
2786
 
2787
+ def test_bfloat16(self):
2788
+ fromhex = float.fromhex
2789
+
2790
+ # Test bounds.
2791
+ DENORM_MIN = fromhex("0x1p-133")
2792
+ LOWEST = fromhex("-0x1.fep127")
2793
+ MAX = fromhex("0x1.fep127")
2794
+
2795
+ x = xnd(DENORM_MIN, type="bfloat16")
2796
+ self.assertEqual(x.value, DENORM_MIN)
2797
+ check_copy_contiguous(self, x)
2798
+
2799
+ x = xnd(LOWEST, type="bfloat16")
2800
+ self.assertEqual(x.value, LOWEST)
2801
+ check_copy_contiguous(self, x)
2802
+
2803
+ x = xnd(MAX, type="bfloat16")
2804
+ self.assertEqual(x.value, MAX)
2805
+ check_copy_contiguous(self, x)
2806
+
2807
+ # Test special values.
2808
+ x = xnd(float("inf"), type="bfloat16")
2809
+ self.assertTrue(isinf(x.value))
2810
+
2811
+ x = xnd(float("nan"), type="bfloat16")
2812
+ self.assertTrue(isnan(x.value))
2813
+
2814
+ # Richcompare.
2815
+ self.assertStrictEqual(xnd(1.2e7, type="bfloat16"), xnd(1.2e7, type="bfloat16"))
2816
+ self.assertStrictEqual(xnd(float("inf"), type="bfloat16"), xnd(float("inf"), type="bfloat16"))
2817
+ self.assertStrictEqual(xnd(float("-inf"), type="bfloat16"), xnd(float("-inf"), type="bfloat16"))
2818
+
2819
+ self.assertNotStrictEqual(xnd(1.2e7, type="bfloat16"), xnd(-1.2e7, type="bfloat16"))
2820
+ self.assertNotStrictEqual(xnd(float("inf"), type="bfloat16"), xnd(float("-inf"), type="bfloat16"))
2821
+ self.assertNotStrictEqual(xnd(float("-inf"), type="bfloat16"), xnd(float("inf"), type="bfloat16"))
2822
+ self.assertNotStrictEqual(xnd(float("nan"), type="bfloat16"), xnd(float("nan"), type="bfloat16"))
2823
+
2824
+ def test_bfloat16_compare_tf(self):
2825
+ TEST_CASES = [
2826
+ ("0x1p-133", 9.183549615799121e-41),
2827
+ ("0x1p-134", 0.0),
2828
+ ("0x0.1p-134", 0.0),
2829
+ ("-0x1.fep127", -3.3895313892515355e+38),
2830
+ ("-0x1.fep128", float("-inf")),
2831
+ ("0x1.fep127", 3.3895313892515355e+38),
2832
+ ("0x1.fep128", float("inf")),
2833
+ ("-0x2", -2.0),
2834
+ ("-0x1.1", -1.0625),
2835
+ ("-0x1.12345p22", -4489216.0),
2836
+ ("0x7.2p37", 979252543488.0)]
2837
+
2838
+ for s, ans in TEST_CASES:
2839
+ d = float.fromhex(s)
2840
+ x = xnd(d, type="bfloat16")
2841
+ self.assertEqual(x, ans)
2842
+ self.assertEqual(x.value, ans)
2843
+
2154
2844
  @requires_py36
2155
2845
  def test_float16(self):
2156
2846
  fromhex = float.fromhex
@@ -2170,12 +2860,15 @@ class TestFloat(XndTestCase):
2170
2860
 
2171
2861
  x = xnd(DENORM_MIN, type="float16")
2172
2862
  self.assertEqual(x.value, DENORM_MIN)
2863
+ check_copy_contiguous(self, x)
2173
2864
 
2174
2865
  x = xnd(LOWEST, type="float16")
2175
2866
  self.assertEqual(x.value, LOWEST)
2867
+ check_copy_contiguous(self, x)
2176
2868
 
2177
2869
  x = xnd(MAX, type="float16")
2178
2870
  self.assertEqual(x.value, MAX)
2871
+ check_copy_contiguous(self, x)
2179
2872
 
2180
2873
  self.assertRaises(OverflowError, xnd, INF, type="float16")
2181
2874
  self.assertRaises(OverflowError, xnd, -INF, type="float16")
@@ -2208,12 +2901,15 @@ class TestFloat(XndTestCase):
2208
2901
 
2209
2902
  x = xnd(DENORM_MIN, type="float32")
2210
2903
  self.assertEqual(x.value, DENORM_MIN)
2904
+ check_copy_contiguous(self, x)
2211
2905
 
2212
2906
  x = xnd(LOWEST, type="float32")
2213
2907
  self.assertEqual(x.value, LOWEST)
2908
+ check_copy_contiguous(self, x)
2214
2909
 
2215
2910
  x = xnd(MAX, type="float32")
2216
2911
  self.assertEqual(x.value, MAX)
2912
+ check_copy_contiguous(self, x)
2217
2913
 
2218
2914
  self.assertRaises(OverflowError, xnd, INF, type="float32")
2219
2915
  self.assertRaises(OverflowError, xnd, -INF, type="float32")
@@ -2245,12 +2941,15 @@ class TestFloat(XndTestCase):
2245
2941
 
2246
2942
  x = xnd(DENORM_MIN, type="float64")
2247
2943
  self.assertEqual(x.value, DENORM_MIN)
2944
+ check_copy_contiguous(self, x)
2248
2945
 
2249
2946
  x = xnd(LOWEST, type="float64")
2250
2947
  self.assertEqual(x.value, LOWEST)
2948
+ check_copy_contiguous(self, x)
2251
2949
 
2252
2950
  x = xnd(MAX, type="float64")
2253
2951
  self.assertEqual(x.value, MAX)
2952
+ check_copy_contiguous(self, x)
2254
2953
 
2255
2954
  # Test special values.
2256
2955
  x = xnd(float("inf"), type="float64")
@@ -2298,14 +2997,17 @@ class TestComplex(XndTestCase):
2298
2997
  v = complex(DENORM_MIN, DENORM_MIN)
2299
2998
  x = xnd(v, type="complex32")
2300
2999
  self.assertEqual(x.value, v)
3000
+ check_copy_contiguous(self, x)
2301
3001
 
2302
3002
  v = complex(LOWEST, LOWEST)
2303
3003
  x = xnd(v, type="complex32")
2304
3004
  self.assertEqual(x.value, v)
3005
+ check_copy_contiguous(self, x)
2305
3006
 
2306
3007
  v = complex(MAX, MAX)
2307
3008
  x = xnd(v, type="complex32")
2308
3009
  self.assertEqual(x.value, v)
3010
+ check_copy_contiguous(self, x)
2309
3011
 
2310
3012
  v = complex(INF, INF)
2311
3013
  self.assertRaises(OverflowError, xnd, v, type="complex32")
@@ -2348,14 +3050,17 @@ class TestComplex(XndTestCase):
2348
3050
  v = complex(DENORM_MIN, DENORM_MIN)
2349
3051
  x = xnd(v, type="complex64")
2350
3052
  self.assertEqual(x.value, v)
3053
+ check_copy_contiguous(self, x)
2351
3054
 
2352
3055
  v = complex(LOWEST, LOWEST)
2353
3056
  x = xnd(v, type="complex64")
2354
3057
  self.assertEqual(x.value, v)
3058
+ check_copy_contiguous(self, x)
2355
3059
 
2356
3060
  v = complex(MAX, MAX)
2357
3061
  x = xnd(v, type="complex64")
2358
3062
  self.assertEqual(x.value, v)
3063
+ check_copy_contiguous(self, x)
2359
3064
 
2360
3065
  v = complex(INF, INF)
2361
3066
  self.assertRaises(OverflowError, xnd, INF, type="complex64")
@@ -2401,10 +3106,12 @@ class TestComplex(XndTestCase):
2401
3106
  v = complex(LOWEST, LOWEST)
2402
3107
  x = xnd(v, type="complex128")
2403
3108
  self.assertEqual(x.value, v)
3109
+ check_copy_contiguous(self, x)
2404
3110
 
2405
3111
  v = complex(MAX, MAX)
2406
3112
  x = xnd(v, type="complex128")
2407
3113
  self.assertEqual(x.value, v)
3114
+ check_copy_contiguous(self, x)
2408
3115
 
2409
3116
  # Test special values.
2410
3117
  x = xnd(complex("inf"), type="complex128")
@@ -2441,6 +3148,7 @@ class TestPrimitive(XndTestCase):
2441
3148
  x = xnd.empty(ts)
2442
3149
  self.assertEqual(x.value, value)
2443
3150
  self.assertEqual(x.type, ndt(ts))
3151
+ check_copy_contiguous(self, x)
2444
3152
 
2445
3153
 
2446
3154
  class TestTypevar(XndTestCase):
@@ -2453,6 +3161,93 @@ class TestTypevar(XndTestCase):
2453
3161
 
2454
3162
  class TestTypeInference(XndTestCase):
2455
3163
 
3164
+ def test_data_shape_extraction(self):
3165
+
3166
+ test_cases = [
3167
+ (None, [None], []),
3168
+ (1, [1], []),
3169
+ ((1, 2), [(1, 2)], []),
3170
+ ([], [], [[0]]),
3171
+ ([None], [None], [[1]]),
3172
+ ([1], [1], [[1]]),
3173
+ ([()], [()], [[1]]),
3174
+ ([(1, 2)], [(1, 2)], [[1]]),
3175
+ ([[]], [], [[0], [1]]),
3176
+ ([[None]], [None], [[1], [1]]),
3177
+ ([[None, 1]], [None, 1], [[2], [1]]),
3178
+ ([[1, None]], [1, None], [[2], [1]]),
3179
+ ([None, []], [], [[None, 0], [2]]),
3180
+ ([[], None], [], [[0, None], [2]]),
3181
+ ([[None], None], [None], [[1, None], [2]]),
3182
+ ([None, [None]], [None], [[None, 1], [2]]),
3183
+ ([None, [1]], [1], [[None, 1], [2]]),
3184
+ ([[1], None], [1], [[1, None], [2]]),
3185
+ ([[], []], [], [[0, 0], [2]]),
3186
+ ([[1], []], [1], [[1, 0], [2]]),
3187
+ ([[], [1]], [1], [[0, 1], [2]]),
3188
+ ([[1], [2]], [1, 2], [[1, 1], [2]]),
3189
+ ([[2], [1]], [2, 1], [[1, 1], [2]]),
3190
+ ([[1], [2, 3]], [1, 2, 3], [[1, 2], [2]]),
3191
+ ([[1, 2], [3]], [1, 2, 3], [[2, 1], [2]]),
3192
+ ([None, [1], [2, 3]], [1, 2, 3], [[None, 1, 2], [3]]),
3193
+ ([[1], None, [2, 3]], [1, 2, 3], [[1, None, 2], [3]]),
3194
+ ([[1], [2, 3], None], [1, 2, 3], [[1, 2, None], [3]]),
3195
+ ([None, [[1], []], [[2, 3]]], [1, 2, 3], [[1, 0, 2], [None, 2, 1], [3]]),
3196
+ ([[[1], []], None, [[2, 3]]], [1, 2, 3], [[1, 0, 2], [ 2, None, 1], [3]]),
3197
+ ([[[1], []], [[2, 3]], None], [1, 2, 3], [[1, 0, 2], [2, 1, None], [3]]),
3198
+ ]
3199
+
3200
+ for v, expected_data, expected_shapes in test_cases:
3201
+ data, shapes = data_shapes(v)
3202
+ self.assertEqual(data, expected_data)
3203
+ self.assertEqual(shapes, expected_shapes)
3204
+
3205
+ v = [1]
3206
+ for i in range(127):
3207
+ v = [v]
3208
+ data, shapes = data_shapes(v)
3209
+ self.assertEqual(data, [1])
3210
+ self.assertEqual(shapes, [[1]] * 128)
3211
+
3212
+ # Exceptions:
3213
+ v = [1, []]
3214
+ self.assertRaises(ValueError, data_shapes, v)
3215
+
3216
+ v = [[], 1]
3217
+ self.assertRaises(ValueError, data_shapes, v)
3218
+
3219
+ v = [[[1,2]], [3, 4]]
3220
+ self.assertRaises(ValueError, data_shapes, v)
3221
+
3222
+ v = [[1, 2], [[3, 4]]]
3223
+ self.assertRaises(ValueError, data_shapes, v)
3224
+
3225
+ v = [1]
3226
+ for i in range(128):
3227
+ v = [v]
3228
+ self.assertRaises(ValueError, data_shapes, v)
3229
+
3230
+ def test_fixed_dimension(self):
3231
+ d = [(None, 10), (None, 20), ("x", 30)]
3232
+ typeof_d = "3 * (?string, int64)"
3233
+
3234
+ test_cases = [
3235
+ ((), "()"),
3236
+ (((),), "(())"),
3237
+ (((), ()), "((), ())"),
3238
+ ((((),), ()), "((()), ())"),
3239
+ ((((),), ((), ())), "((()), ((), ()))"),
3240
+ ((1, 2, 3), "(int64, int64, int64)"),
3241
+ ((1.0, 2, "str"), "(float64, int64, string)"),
3242
+ ((1.0, 2, ("str", b"bytes", d)),
3243
+ "(float64, int64, (string, bytes, %s))" % typeof_d)
3244
+ ]
3245
+
3246
+ for v, t in test_cases:
3247
+ x = xnd(v)
3248
+ self.assertEqual(x.type, ndt(t))
3249
+ self.assertEqual(x.value, v)
3250
+
2456
3251
  def test_tuple(self):
2457
3252
  d = R['a': (2.0, b"bytes"), 'b': ("str", float('inf'))]
2458
3253
  typeof_d = "{a: (float64, bytes), b: (string, float64)}"
@@ -2492,6 +3287,25 @@ class TestTypeInference(XndTestCase):
2492
3287
  self.assertEqual(x.type, ndt(t))
2493
3288
  self.assertEqual(x.value, v)
2494
3289
 
3290
+ def test_bool(self):
3291
+ t = [True, None, False]
3292
+ typeof_t = "3 * ?bool"
3293
+
3294
+ test_cases = [
3295
+ ([0], "1 * int64"),
3296
+ ([0, 1], "2 * int64"),
3297
+ ([[0], [1]], "2 * 1 * int64"),
3298
+
3299
+ (t, typeof_t),
3300
+ ([t] * 2, "2 * %s" % typeof_t),
3301
+ ([[t] * 2] * 10, "10 * 2 * %s" % typeof_t)
3302
+ ]
3303
+
3304
+ for v, t in test_cases:
3305
+ x = xnd(v)
3306
+ self.assertEqual(x.type, ndt(t))
3307
+ self.assertEqual(x.value, v)
3308
+
2495
3309
  def test_float64(self):
2496
3310
  d = R['a': 2.221e100, 'b': float('inf')]
2497
3311
  typeof_d = "{a: float64, b: float64}"
@@ -2760,21 +3574,12 @@ class TestBuffer(XndTestCase):
2760
3574
  x = np.array([(1000, 400.25, 'abc'), (-23, -1e10, 'cba')],
2761
3575
  dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'S3')])
2762
3576
  y = xnd.from_buffer(x)
3577
+ check_copy_contiguous(self, y)
2763
3578
 
2764
3579
  for i in range(2):
2765
3580
  for k in ['x', 'y', 'z']:
2766
3581
  self.assertEqual(y[i][k], x[i][k])
2767
3582
 
2768
- @unittest.skipIf(np is None, "numpy not found")
2769
- def test_unsafe_from_buffer(self):
2770
- x = np.array([[[0,1,2],
2771
- [3,4,5]],
2772
- [[6,7,8],
2773
- [9,10,11]]], dtype="int64")
2774
-
2775
- y = xnd.unsafe_from_data(obj=x, type="12 * int64")
2776
- np.testing.assert_equal(y, x.reshape(12))
2777
-
2778
3583
  @unittest.skipIf(np is None, "numpy not found")
2779
3584
  def test_endian(self):
2780
3585
  standard = [
@@ -2783,10 +3588,11 @@ class TestBuffer(XndTestCase):
2783
3588
  'h', 'i', 'l', 'q',
2784
3589
  'H', 'I', 'L', 'Q',
2785
3590
  'f', 'd',
3591
+ 'F', 'D',
2786
3592
  ]
2787
3593
 
2788
3594
  if HAVE_PYTHON_36:
2789
- standard += 'e'
3595
+ standard += ['e']
2790
3596
 
2791
3597
  modifiers = ['', '<', '>']
2792
3598
 
@@ -2802,6 +3608,7 @@ class TestBuffer(XndTestCase):
2802
3608
  x = np.array([(1000, 400.25, 'abc'), (-23, -1e10, 'cba')],
2803
3609
  dtype=[('x', '<i4'), ('y', '>f4'), ('z', 'S3')])
2804
3610
  y = xnd.from_buffer(x)
3611
+ check_copy_contiguous(self, y)
2805
3612
 
2806
3613
  for i in range(2):
2807
3614
  for k in ['x', 'y', 'z']:
@@ -2816,6 +3623,61 @@ class TestBuffer(XndTestCase):
2816
3623
  y = xnd.from_buffer(x)
2817
3624
  y[:] = [1000, 2000, 3000]
2818
3625
  self.assertEqual(x.tolist(), [1000, 2000, 3000])
3626
+ check_copy_contiguous(self, y)
3627
+
3628
+ @unittest.skipIf(np is None, "numpy not found")
3629
+ def test_complex(self):
3630
+ x = xnd([1, 2, 3], dtype="complex64")
3631
+ y = np.array(x)
3632
+ self.assertEqual(memoryview(y).format, "Zf")
3633
+
3634
+ x = xnd([1, 2, 3], dtype="complex128")
3635
+ y = np.array(x)
3636
+ self.assertEqual(memoryview(y).format, "Zd")
3637
+
3638
+ x = np.array([1, 2, 3], dtype="complex64")
3639
+ y = xnd.from_buffer(x)
3640
+ self.assertEqual(memoryview(y).format, "=Zf")
3641
+
3642
+ x = np.array([1, 2, 3], dtype="complex128")
3643
+ y = xnd.from_buffer(x)
3644
+ self.assertEqual(memoryview(y).format, "=Zd")
3645
+
3646
+ @unittest.skipIf(np is None, "numpy not found")
3647
+ def test_from_buffer_and_type(self):
3648
+ x = np.array([[[0,1,2],
3649
+ [3,4,5]],
3650
+ [[6,7,8],
3651
+ [9,10,11]]], dtype="float32")
3652
+
3653
+ b = memoryview(x).cast("B")
3654
+ t = ndt("2 * 2 * 3 * float32")
3655
+ ans = xnd.from_buffer_and_type(b, t)
3656
+ np.testing.assert_equal(ans, x)
3657
+
3658
+ t = ndt("2 * 2 * 4 * float32")
3659
+ self.assertRaises(ValueError, xnd.from_buffer_and_type, b, t)
3660
+
3661
+ b = b"12345678"
3662
+
3663
+ t = ndt("3 * 3 * int8")
3664
+ self.assertRaises(ValueError, xnd.from_buffer_and_type, b, t)
3665
+
3666
+ x = xnd.empty("2 * 2 * 2 * int8")
3667
+ y = x[::-1]
3668
+ self.assertRaises(ValueError, xnd.from_buffer_and_type, b, y.type)
3669
+
3670
+
3671
+ class TestReshape(XndTestCase):
3672
+
3673
+ def test_reshape_api(self):
3674
+ x = xnd([[1,2,3], [4,5,6]], type="!2 * 3 * float32")
3675
+ self.assertRaises(ValueError, x.reshape, 2**32, 2**32)
3676
+
3677
+ def test_reshape_fortran(self):
3678
+ x = xnd([[1,2,3], [4,5,6]], type="!2 * 3 * float32")
3679
+ y = x.reshape(3,2,order='F')
3680
+ self.assertEqual(y, [[1,5], [4,3], [2,6]])
2819
3681
 
2820
3682
 
2821
3683
  class TestSplit(XndTestCase):
@@ -2847,6 +3709,69 @@ class TestSplit(XndTestCase):
2847
3709
  self.assertEqual(a, b)
2848
3710
 
2849
3711
 
3712
+ class TestTranspose(XndTestCase):
3713
+
3714
+ def test_api(self):
3715
+
3716
+ x = xnd([])
3717
+ y = x.transpose()
3718
+ self.assertEqual(y, x)
3719
+ y = x.transpose(permute=[0])
3720
+ self.assertEqual(y, x)
3721
+ self.assertRaises(ValueError, x.transpose, permute=[])
3722
+ self.assertRaises(ValueError, x.transpose, permute=[0, 0])
3723
+ self.assertRaises(ValueError, x.transpose, permute=[0, 1])
3724
+
3725
+ x = xnd([1, 2, 3])
3726
+ y = x.transpose()
3727
+ self.assertEqual(y, x)
3728
+ y = x.transpose(permute=[0])
3729
+ self.assertEqual(y, x)
3730
+ self.assertRaises(ValueError, x.transpose, permute=[-1])
3731
+ self.assertRaises(ValueError, x.transpose, permute=[2])
3732
+ self.assertRaises(ValueError, x.transpose, permute=[0, 1])
3733
+
3734
+ x = xnd([[1], [2, 3]])
3735
+ self.assertRaises(TypeError, x.transpose)
3736
+
3737
+ x = xnd([[1, 2, 3], [4, 5, 6]])
3738
+ y = xnd([[1, 4], [2, 5], [3, 6]])
3739
+
3740
+ z = x.transpose()
3741
+ self.assertEqual(z, y)
3742
+
3743
+ z = x.transpose([0, 1])
3744
+ self.assertEqual(z, x)
3745
+
3746
+ z = x.transpose([1, 0])
3747
+ self.assertEqual(z, y)
3748
+
3749
+ self.assertRaises(ValueError, x.transpose, permute=[1, 1])
3750
+ self.assertRaises(ValueError, x.transpose, permute=[10, 1])
3751
+
3752
+ def test_nd(self):
3753
+
3754
+ lst = [[[0, 1, 3, 3],
3755
+ [4, 5, 6, 7],
3756
+ [8, 9, 10, 11]],
3757
+ [[12, 13, 14, 15],
3758
+ [16, 17, 18, 19],
3759
+ [20, 21, 22, 23]]]
3760
+
3761
+ x = xnd(lst)
3762
+
3763
+ ans = [x[:, 0, :].value,
3764
+ x[:, 1, :].value,
3765
+ x[:, 2, :].value]
3766
+ self.assertEqual(x.transpose(permute=(1, 0, 2)), ans)
3767
+
3768
+ ans = [x[:, :, 0].value,
3769
+ x[:, :, 1].value,
3770
+ x[:, :, 2].value,
3771
+ x[:, :, 3].value]
3772
+ self.assertEqual(x.transpose(permute=(2, 0, 1)), ans)
3773
+
3774
+
2850
3775
  class TestView(XndTestCase):
2851
3776
 
2852
3777
  def test_view_subscript(self):
@@ -2863,13 +3788,28 @@ class TestView(XndTestCase):
2863
3788
  self.assertEqual(x, xnd([1.1, 2.2, 3.3]))
2864
3789
 
2865
3790
 
3791
+ class TestCopy(XndTestCase):
3792
+
3793
+ def test_copy_contiguous(self):
3794
+ x = xnd([[1,2,3], [4,5,6]], dtype="int8")
3795
+ y = x.copy_contiguous()
3796
+ self.assertEqual(x, y)
3797
+
3798
+ y = x.copy_contiguous(dtype="int64")
3799
+ self.assertEqual(x, y)
3800
+
3801
+ x = xnd([1, 2, 2**63-1], dtype="int64")
3802
+ self.assertRaises(ValueError, x.copy_contiguous, dtype="int8")
3803
+
3804
+
2866
3805
  class TestSpec(XndTestCase):
2867
3806
 
2868
- def __init__(self, *, constr,
3807
+ def __init__(self, *, constr, ndarray,
2869
3808
  values, value_generator,
2870
3809
  indices_generator, indices_generator_args):
2871
3810
  super().__init__()
2872
3811
  self.constr = constr
3812
+ self.ndarray = ndarray
2873
3813
  self.values = values
2874
3814
  self.value_generator = value_generator
2875
3815
  self.indices_generator = indices_generator
@@ -2880,7 +3820,11 @@ class TestSpec(XndTestCase):
2880
3820
  """Dump an error as a Python script for debugging."""
2881
3821
 
2882
3822
  sys.stderr.write("\n\nfrom xnd import *\n")
2883
- sys.stderr.write("from test_xnd import NDArray\n")
3823
+ if self.ndarray == NDArray:
3824
+ sys.stderr.write("from test_xnd import NDArray\n")
3825
+ else:
3826
+ sys.stderr.write("import numpy as np\n")
3827
+ sys.stderr.write("NDArray = np.array\n")
2884
3828
  sys.stderr.write("lst = %s\n\n" % value)
2885
3829
  sys.stderr.write("x0 = xnd(lst)\n")
2886
3830
  sys.stderr.write("y0 = NDArray(lst)\n" % value)
@@ -2891,6 +3835,84 @@ class TestSpec(XndTestCase):
2891
3835
 
2892
3836
  sys.stderr.write("\n")
2893
3837
 
3838
+ def run_reshape(self, nd, d):
3839
+ if not isinstance(nd, xnd) or not isinstance(d, np.ndarray):
3840
+ return
3841
+
3842
+ s = randshape(d.shape)
3843
+
3844
+ x = nd_exception = None
3845
+ try:
3846
+ x = nd.reshape(*s)
3847
+ except Exception as e:
3848
+ nd_exception = e
3849
+
3850
+ y = def_exception = None
3851
+ try:
3852
+ y = d.view()
3853
+ y.shape = s
3854
+ except Exception as e:
3855
+ def_exception = e
3856
+
3857
+ if nd_exception or def_exception:
3858
+ if nd_exception.__class__ is ValueError and \
3859
+ def_exception.__class__ is AttributeError:
3860
+ return
3861
+ self.assertIs(nd_exception.__class__, def_exception.__class__,
3862
+ "shape: %s nd: %s d: %s x: %s y: %s" % (s, nd, d, x, y))
3863
+ else:
3864
+ self.assertEqual(x.value, y.tolist(),
3865
+ "shape: %s nd: %s d: %s x: %s y: %s" % (s, nd, d, x, y))
3866
+
3867
+ def run_transpose(self, nd, d):
3868
+ if not isinstance(nd, xnd) or not isinstance(d, np.ndarray):
3869
+ return
3870
+
3871
+ x = nd.transpose()
3872
+ y = d.transpose()
3873
+
3874
+ self.assertEqual(x.value, y.tolist(), "nd: %s d: %s x: %s y: %s" % (nd, d, x, y))
3875
+
3876
+ p = random.shuffle(list(range(y.ndim)))
3877
+ x = nd.transpose(permute=p)
3878
+ y = np.transpose(d, axes=p)
3879
+
3880
+ self.assertEqual(x.value, y.tolist())
3881
+
3882
+ def run_from_buffer(self, nd, d):
3883
+ if not isinstance(nd, xnd) or not isinstance(d, np.ndarray):
3884
+ return
3885
+
3886
+ x = xnd.from_buffer(d)
3887
+ y = np.array(x, copy=False)
3888
+
3889
+ self.assertEqual(x.value, d.tolist())
3890
+ self.assertEqual(x.value, y.tolist())
3891
+
3892
+ def run_tobytes(self, nd, d):
3893
+ if not isinstance(nd, xnd) or not isinstance(d, np.ndarray):
3894
+ return
3895
+
3896
+ x = nd.tobytes()
3897
+ y = d.tobytes()
3898
+
3899
+ self.assertEqual(x, y)
3900
+
3901
+ def run_serialize(self, x):
3902
+ if not isinstance(x, xnd):
3903
+ return
3904
+
3905
+ try:
3906
+ b = x.serialize()
3907
+ except NotImplementedError:
3908
+ return
3909
+ try:
3910
+ y = x.deserialize(b)
3911
+ except NotImplementedError:
3912
+ return
3913
+
3914
+ self.assertEqual(x, y)
3915
+
2894
3916
  def run_single(self, nd, d, indices):
2895
3917
  """Run a single test case."""
2896
3918
 
@@ -2900,7 +3922,7 @@ class TestSpec(XndTestCase):
2900
3922
  try:
2901
3923
  nd_result = nd[indices]
2902
3924
  except Exception as e:
2903
- nd_exception = e
3925
+ nd_exception = e
2904
3926
 
2905
3927
  def_exception = None
2906
3928
  try:
@@ -2919,12 +3941,24 @@ class TestSpec(XndTestCase):
2919
3941
 
2920
3942
  if isinstance(nd_result, xnd):
2921
3943
  nd_value = nd_result.value
3944
+ check_copy_contiguous(self, nd_result)
2922
3945
  elif np is not None and isinstance(nd_result, np.ndarray):
2923
3946
  nd_value = nd_result.tolist()
2924
3947
  else:
2925
3948
  nd_value = nd_result
2926
3949
 
2927
- self.assertEqual(nd_value, def_result)
3950
+ if np is not None and isinstance(def_result, np.ndarray):
3951
+ def_value = def_result.tolist()
3952
+ else:
3953
+ def_value = def_result
3954
+
3955
+ self.assertEqual(nd_value, def_value)
3956
+ if np is not None:
3957
+ self.run_reshape(nd_result, def_result)
3958
+ self.run_transpose(nd_result, def_result)
3959
+ self.run_from_buffer(nd_result, def_result)
3960
+ self.run_tobytes(nd_result, def_result)
3961
+
2928
3962
  return nd_result, def_result
2929
3963
 
2930
3964
  def run(self):
@@ -2943,12 +3977,14 @@ class TestSpec(XndTestCase):
2943
3977
  self.log_err(value, depth)
2944
3978
  raise e
2945
3979
 
3980
+ self.run_serialize(next_nd)
3981
+
2946
3982
  if isinstance(next_d, list): # possibly None or scalar
2947
3983
  check(next_nd, next_d, value, depth+1)
2948
3984
 
2949
3985
  for value in self.values:
2950
3986
  nd = self.constr(value)
2951
- d = NDArray(value)
3987
+ d = self.ndarray(value, dtype="int64")
2952
3988
  check(nd, d, value, 0)
2953
3989
  check_buffer(nd)
2954
3990
 
@@ -2957,7 +3993,7 @@ class TestSpec(XndTestCase):
2957
3993
  for max_shape in range(1, 8):
2958
3994
  for value in self.value_generator(max_ndim, min_shape, max_shape):
2959
3995
  nd = self.constr(value)
2960
- d = NDArray(value)
3996
+ d = self.ndarray(value, dtype="int64")
2961
3997
  check(nd, d, value, 0)
2962
3998
  check_buffer(nd)
2963
3999
 
@@ -2969,6 +4005,7 @@ class LongIndexSliceTest(XndTestCase):
2969
4005
  skip_if(SKIP_LONG, "use --long argument to enable these tests")
2970
4006
 
2971
4007
  t = TestSpec(constr=xnd,
4008
+ ndarray=NDArray,
2972
4009
  values=SUBSCRIPT_FIXED_TEST_CASES,
2973
4010
  value_generator=gen_fixed,
2974
4011
  indices_generator=genindices,
@@ -2976,6 +4013,7 @@ class LongIndexSliceTest(XndTestCase):
2976
4013
  t.run()
2977
4014
 
2978
4015
  t = TestSpec(constr=xnd,
4016
+ ndarray=NDArray,
2979
4017
  values=SUBSCRIPT_VAR_TEST_CASES,
2980
4018
  value_generator=gen_var,
2981
4019
  indices_generator=genindices,
@@ -2987,6 +4025,7 @@ class LongIndexSliceTest(XndTestCase):
2987
4025
  skip_if(SKIP_LONG, "use --long argument to enable these tests")
2988
4026
 
2989
4027
  t = TestSpec(constr=xnd,
4028
+ ndarray=NDArray,
2990
4029
  values=SUBSCRIPT_FIXED_TEST_CASES,
2991
4030
  value_generator=gen_fixed,
2992
4031
  indices_generator=randslices,
@@ -2994,6 +4033,7 @@ class LongIndexSliceTest(XndTestCase):
2994
4033
  t.run()
2995
4034
 
2996
4035
  t = TestSpec(constr=xnd,
4036
+ ndarray=NDArray,
2997
4037
  values=SUBSCRIPT_VAR_TEST_CASES,
2998
4038
  value_generator=gen_var,
2999
4039
  indices_generator=randslices,
@@ -3005,6 +4045,7 @@ class LongIndexSliceTest(XndTestCase):
3005
4045
  skip_if(SKIP_LONG, "use --long argument to enable these tests")
3006
4046
 
3007
4047
  t = TestSpec(constr=xnd,
4048
+ ndarray=NDArray,
3008
4049
  values=SUBSCRIPT_FIXED_TEST_CASES,
3009
4050
  value_generator=gen_fixed,
3010
4051
  indices_generator=gen_indices_or_slices,
@@ -3013,6 +4054,7 @@ class LongIndexSliceTest(XndTestCase):
3013
4054
 
3014
4055
 
3015
4056
  t = TestSpec(constr=xnd,
4057
+ ndarray=NDArray,
3016
4058
  values=SUBSCRIPT_VAR_TEST_CASES,
3017
4059
  value_generator=gen_var,
3018
4060
  indices_generator=gen_indices_or_slices,
@@ -3024,6 +4066,7 @@ class LongIndexSliceTest(XndTestCase):
3024
4066
  skip_if(SKIP_LONG, "use --long argument to enable these tests")
3025
4067
 
3026
4068
  t = TestSpec(constr=xnd,
4069
+ ndarray=NDArray,
3027
4070
  values=SUBSCRIPT_FIXED_TEST_CASES,
3028
4071
  value_generator=gen_fixed,
3029
4072
  indices_generator=mixed_indices,
@@ -3034,19 +4077,20 @@ class LongIndexSliceTest(XndTestCase):
3034
4077
  # Multidimensional indexing and slicing, mixed
3035
4078
  skip_if(SKIP_LONG, "use --long argument to enable these tests")
3036
4079
 
3037
- x = xnd([[1], [2, 3], [4, 5, 6]])
3038
-
3039
- indices = (0, slice(0,1,1))
3040
- self.assertRaises(IndexError, x.__getitem__, indices)
3041
-
3042
- indices = (slice(0,1,1), 0)
3043
- self.assertRaises(IndexError, x.__getitem__, indices)
4080
+ t = TestSpec(constr=xnd,
4081
+ ndarray=NDArray,
4082
+ values=SUBSCRIPT_VAR_TEST_CASES,
4083
+ value_generator=gen_var,
4084
+ indices_generator=mixed_indices,
4085
+ indices_generator_args=(5,))
4086
+ t.run()
3044
4087
 
3045
4088
  def test_slices_brute_force(self):
3046
4089
  # Test all possible slices for the given ndim and shape
3047
4090
  skip_if(SKIP_BRUTE_FORCE, "use --all argument to enable these tests")
3048
4091
 
3049
4092
  t = TestSpec(constr=xnd,
4093
+ ndarray=NDArray,
3050
4094
  values=SUBSCRIPT_FIXED_TEST_CASES,
3051
4095
  value_generator=gen_fixed,
3052
4096
  indices_generator=genslices_ndim,
@@ -3054,6 +4098,7 @@ class LongIndexSliceTest(XndTestCase):
3054
4098
  t.run()
3055
4099
 
3056
4100
  t = TestSpec(constr=xnd,
4101
+ ndarray=NDArray,
3057
4102
  values=SUBSCRIPT_VAR_TEST_CASES,
3058
4103
  value_generator=gen_var,
3059
4104
  indices_generator=genslices_ndim,
@@ -3066,6 +4111,31 @@ class LongIndexSliceTest(XndTestCase):
3066
4111
  skip_if(SKIP_LONG, "use --long argument to enable these tests")
3067
4112
 
3068
4113
  t = TestSpec(constr=np.array,
4114
+ ndarray=NDArray,
4115
+ values=SUBSCRIPT_FIXED_TEST_CASES,
4116
+ value_generator=gen_fixed,
4117
+ indices_generator=mixed_indices,
4118
+ indices_generator_args=(3,))
4119
+ t.run()
4120
+
4121
+ @unittest.skipIf(np is None, "numpy not found")
4122
+ def test_transpose_and_reshape(self):
4123
+ skip_if(SKIP_LONG, "use --long argument to enable these tests")
4124
+
4125
+ t = TestSpec(constr=xnd,
4126
+ ndarray=np.array,
4127
+ values=SUBSCRIPT_FIXED_TEST_CASES,
4128
+ value_generator=gen_fixed,
4129
+ indices_generator=mixed_indices,
4130
+ indices_generator_args=(3,))
4131
+ t.run()
4132
+
4133
+ @unittest.skipIf(np is None, "numpy not found")
4134
+ def test_from_buffer(self):
4135
+ skip_if(SKIP_LONG, "use --long argument to enable these tests")
4136
+
4137
+ t = TestSpec(constr=xnd,
4138
+ ndarray=np.array,
3069
4139
  values=SUBSCRIPT_FIXED_TEST_CASES,
3070
4140
  value_generator=gen_fixed,
3071
4141
  indices_generator=mixed_indices,
@@ -3085,6 +4155,8 @@ ALL_TESTS = [
3085
4155
  TestEllipsisDim,
3086
4156
  TestTuple,
3087
4157
  TestRecord,
4158
+ TestArray,
4159
+ TestUnion,
3088
4160
  TestRef,
3089
4161
  TestConstr,
3090
4162
  TestNominal,
@@ -3114,8 +4186,11 @@ ALL_TESTS = [
3114
4186
  TestAPI,
3115
4187
  TestRepr,
3116
4188
  TestBuffer,
4189
+ TestReshape,
3117
4190
  TestSplit,
4191
+ TestTranspose,
3118
4192
  TestView,
4193
+ TestCopy,
3119
4194
  LongIndexSliceTest,
3120
4195
  ]
3121
4196