xnd 0.2.0dev6 → 0.2.0dev7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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