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
@@ -0,0 +1,121 @@
1
+ /*
2
+ * BSD 3-Clause License
3
+ *
4
+ * Copyright (c) 2017-2018, plures
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * 1. Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ *
13
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ *
17
+ * 3. Neither the name of the copyright holder nor the names of its
18
+ * contributors may be used to endorse or promote products derived from
19
+ * this software without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+
34
+ #include <stdint.h>
35
+ #include "ndtypes.h"
36
+
37
+
38
+ /*****************************************************************************/
39
+ /* Expose some cuda memory functions */
40
+ /*****************************************************************************/
41
+
42
+ extern "C" void *
43
+ xnd_cuda_calloc_managed(uint16_t align, int64_t size, ndt_context_t *ctx)
44
+ {
45
+ char *ptr;
46
+ cudaError_t err;
47
+
48
+ size = size == 0 ? 1 : size;
49
+
50
+ if (size < 0 || (uint64_t)size > SIZE_MAX) {
51
+ ndt_err_format(ctx, NDT_ValueError,
52
+ "cudaMallocManaged: invalid size");
53
+ return NULL;
54
+ }
55
+
56
+ err = cudaMallocManaged(&ptr, (size_t)size);
57
+ if (err != cudaSuccess) {
58
+ ndt_err_format(ctx, NDT_MemoryError,
59
+ "cudaMallocManaged: allocation failed");
60
+ return NULL;
61
+ }
62
+
63
+ if (((uintptr_t)ptr) % align != 0) {
64
+ ndt_err_format(ctx, NDT_ValueError,
65
+ "cudaMallocManaged: alignment requirement too large");
66
+ cudaFree(ptr);
67
+ return NULL;
68
+ }
69
+
70
+ memset(ptr, '\0', (size_t)size);
71
+
72
+ return ptr;
73
+ }
74
+
75
+ extern "C" void
76
+ xnd_cuda_free(void *ptr)
77
+ {
78
+ cudaError_t err;
79
+
80
+ err = cudaFree(ptr);
81
+ if (err != cudaSuccess) {
82
+ fprintf(stderr, "cudaFree: unexpected failure\n");
83
+ }
84
+ }
85
+
86
+ extern "C" int
87
+ xnd_cuda_mem_prefetch_async(const void *ptr, int64_t count, int dev,
88
+ ndt_context_t *ctx)
89
+ {
90
+ cudaError_t err;
91
+
92
+ if (count < 0 || (uint64_t)count > SIZE_MAX) {
93
+ ndt_err_format(ctx, NDT_ValueError,
94
+ "cudaMemPrefetchAsync: invalid count");
95
+ return -1;
96
+ }
97
+
98
+ err = cudaMemPrefetchAsync(ptr, (size_t)count, dev);
99
+ if (err != cudaSuccess) {
100
+ ndt_err_format(ctx, NDT_MemoryError,
101
+ "cudaMemPrefetchAsync: prefetching failed");
102
+ return -1;
103
+ }
104
+
105
+ return 0;
106
+ }
107
+
108
+ extern "C" int
109
+ xnd_cuda_device_synchronize(ndt_context_t *ctx)
110
+ {
111
+ cudaError_t err;
112
+
113
+ err = cudaDeviceSynchronize();
114
+ if (err != cudaSuccess) {
115
+ ndt_err_format(ctx, NDT_RuntimeError,
116
+ "cuda device synchronization failed");
117
+ return -1;
118
+ }
119
+
120
+ return 0;
121
+ }
@@ -0,0 +1,58 @@
1
+ /*
2
+ * BSD 3-Clause License
3
+ *
4
+ * Copyright (c) 2017-2018, plures
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * 1. Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ *
13
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ *
17
+ * 3. Neither the name of the copyright holder nor the names of its
18
+ * contributors may be used to endorse or promote products derived from
19
+ * this software without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+
34
+ #ifndef CUDA_MEMORY_H
35
+ #define CUDA_MEMORY_H
36
+
37
+ #include <stdint.h>
38
+ #include "ndtypes.h"
39
+
40
+
41
+ /*****************************************************************************/
42
+ /* Expose some cuda memory functions */
43
+ /*****************************************************************************/
44
+
45
+ #ifdef __cpplusplus
46
+ extern "C" void *xnd_cuda_calloc_managed(uint16_t align, int64_t size, ndt_context_t *ctx);
47
+ extern "C" void xnd_cuda_free(void *ptr);
48
+ extern "C" int xnd_cuda_mem_prefetch_async(const void *ptr, int64_t count, int dev, ndt_context_t *ctx);
49
+ extern "C" int xnd_cuda_device_synchronize(ndt_context_t *ctx);
50
+ #else
51
+ void *xnd_cuda_calloc_managed(uint16_t align, int64_t size, ndt_context_t *ctx);
52
+ void xnd_cuda_free(void *ptr);
53
+ int xnd_cuda_mem_prefetch_async(const void *ptr, int64_t count, int dev, ndt_context_t *ctx);
54
+ int xnd_cuda_device_synchronize(ndt_context_t *ctx);
55
+ #endif
56
+
57
+
58
+ #endif /* CUDA_MEMORY_H */
@@ -55,9 +55,7 @@ xnd_strict_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
55
55
  assert(ndt_is_concrete(t) && ndt_is_concrete(u));
56
56
 
57
57
  if (t->tag != u->tag) {
58
- ndt_err_format(ctx, NDT_TypeError,
59
- "mixed type comparisons are not implemented");
60
- return -1;
58
+ return 0;
61
59
  }
62
60
 
63
61
  if (xnd_is_na(x) || xnd_is_na(y)) {
@@ -111,6 +109,20 @@ xnd_strict_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
111
109
  return 1;
112
110
  }
113
111
 
112
+ case VarDimElem: {
113
+ const xnd_t xnext = apply_stored_index(x, ctx);
114
+ if (xnd_err_occurred(&xnext)) {
115
+ return -1;
116
+ }
117
+
118
+ const xnd_t ynext = apply_stored_index(y, ctx);
119
+ if (xnd_err_occurred(&ynext)) {
120
+ return -1;
121
+ }
122
+
123
+ return xnd_strict_equal(&xnext, &ynext, ctx);
124
+ }
125
+
114
126
  case Tuple: {
115
127
  if (u->Tuple.shape != t->Tuple.shape) {
116
128
  return 0;
@@ -161,6 +173,20 @@ xnd_strict_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
161
173
  return 1;
162
174
  }
163
175
 
176
+ case Union: {
177
+ const xnd_t xnext = xnd_union_next(x, ctx);
178
+ if (xnext.ptr == NULL) {
179
+ return -1;
180
+ }
181
+
182
+ const xnd_t ynext = xnd_union_next(y, ctx);
183
+ if (ynext.ptr == NULL) {
184
+ return -1;
185
+ }
186
+
187
+ return xnd_strict_equal(&xnext, &ynext, ctx);
188
+ }
189
+
164
190
  case Ref: {
165
191
  const xnd_t xnext = xnd_ref_next(x, ctx);
166
192
  if (xnext.ptr == NULL) {
@@ -296,6 +322,12 @@ xnd_strict_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
296
322
  return a == b;
297
323
  }
298
324
 
325
+ case BFloat16: {
326
+ double a = xnd_bfloat_unpack(x->ptr);
327
+ double b = xnd_bfloat_unpack(y->ptr);
328
+ return a == b;
329
+ }
330
+
299
331
  case Float16: {
300
332
  double a = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
301
333
  double b = xnd_float_unpack2((unsigned char *)y->ptr, le(u->flags));
@@ -314,6 +346,19 @@ xnd_strict_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
314
346
  return a == b;
315
347
  }
316
348
 
349
+ case BComplex32: {
350
+ double a_real, a_imag;
351
+ double b_real, b_imag;
352
+
353
+ a_real = xnd_bfloat_unpack(x->ptr);
354
+ a_imag = xnd_bfloat_unpack(x->ptr+2);
355
+
356
+ b_real = xnd_bfloat_unpack(y->ptr);
357
+ b_imag = xnd_bfloat_unpack(y->ptr+2);
358
+
359
+ return a_real == b_real && a_imag == b_imag;
360
+ }
361
+
317
362
  case Complex32: {
318
363
  double a_real, a_imag;
319
364
  double b_real, b_imag;
@@ -371,8 +416,8 @@ xnd_strict_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
371
416
  }
372
417
 
373
418
  case String: {
374
- const char *a = XND_POINTER_DATA(x->ptr);
375
- const char *b = XND_POINTER_DATA(y->ptr);
419
+ const char *a = XND_STRING_DATA(x->ptr);
420
+ const char *b = XND_STRING_DATA(y->ptr);
376
421
  return strcmp(a, b) == 0;
377
422
  }
378
423
 
@@ -393,6 +438,26 @@ xnd_strict_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
393
438
  return memcmp(a, b, (size_t)asize) == 0;
394
439
  }
395
440
 
441
+ case Array: {
442
+ int64_t ashape, bshape;
443
+
444
+ ashape = XND_ARRAY_SHAPE(x->ptr);
445
+ bshape = XND_ARRAY_SHAPE(y->ptr);
446
+
447
+ if (ashape != bshape) {
448
+ return 0;
449
+ }
450
+
451
+ for (int64_t i = 0; i < ashape; i++) {
452
+ const xnd_t xnext = xnd_array_next(x, i);
453
+ const xnd_t ynext = xnd_array_next(y, i);
454
+ n = xnd_strict_equal(&xnext, &ynext, ctx);
455
+ if (n <= 0) return n;
456
+ }
457
+
458
+ return 1;
459
+ }
460
+
396
461
  /* NOT REACHED: xnd types must be concrete. */
397
462
  case Module: case Function:
398
463
  case AnyKind: case SymbolicDim: case EllipsisDim: case Typevar:
@@ -495,6 +560,11 @@ equal_int64(const int64_t a, const xnd_t * const x)
495
560
  return a >= 0 ? (uint64_t)a == b : 0;
496
561
  }
497
562
 
563
+ case BFloat16: {
564
+ double b = xnd_bfloat_unpack(x->ptr);
565
+ return llabs(a) <= 4503599627370496LL ? (double)a == b : 0;
566
+ }
567
+
498
568
  case Float16: {
499
569
  double b = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
500
570
  return llabs(a) <= 4503599627370496LL ? (double)a == b : 0;
@@ -510,6 +580,17 @@ equal_int64(const int64_t a, const xnd_t * const x)
510
580
  return llabs(a) <= 4503599627370496LL ? (double)a == b : 0;
511
581
  }
512
582
 
583
+ case BComplex32: {
584
+ double real = xnd_bfloat_unpack(x->ptr);
585
+ double imag = xnd_bfloat_unpack(x->ptr+2);
586
+
587
+ if (imag == 0.0 && llabs(a) <= 4503599627370496LL) {
588
+ return (double)a == real;
589
+ }
590
+
591
+ return 0;
592
+ }
593
+
513
594
  case Complex32: {
514
595
  double real = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
515
596
  double imag = xnd_float_unpack2((unsigned char *)(x->ptr+2), le(t->flags));
@@ -601,6 +682,11 @@ equal_uint64(const uint64_t a, const xnd_t * const x)
601
682
  return a == b;
602
683
  }
603
684
 
685
+ case BFloat16: {
686
+ double b = xnd_bfloat_unpack(x->ptr);
687
+ return a <= 4503599627370496ULL ? (double)a == b : 0;
688
+ }
689
+
604
690
  case Float16: {
605
691
  double b = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
606
692
  return a <= 4503599627370496ULL ? (double)a == b : 0;
@@ -616,6 +702,17 @@ equal_uint64(const uint64_t a, const xnd_t * const x)
616
702
  return a <= 4503599627370496ULL ? (double)a == b : 0;
617
703
  }
618
704
 
705
+ case BComplex32: {
706
+ double real = xnd_bfloat_unpack(x->ptr);
707
+ double imag = xnd_bfloat_unpack(x->ptr+2);
708
+
709
+ if (imag == 0.0 && a <= 4503599627370496ULL) {
710
+ return (double)a == real;
711
+ }
712
+
713
+ return 0;
714
+ }
715
+
619
716
  case Complex32: {
620
717
  double real = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
621
718
  double imag = xnd_float_unpack2((unsigned char *)(x->ptr+2), le(t->flags));
@@ -707,6 +804,11 @@ equal_float64(const double a, const xnd_t * const x)
707
804
  return b <= 4503599627370496ULL ? a == (double)b : 0;
708
805
  }
709
806
 
807
+ case BFloat16: {
808
+ double b = xnd_bfloat_unpack(x->ptr);
809
+ return a == b;
810
+ }
811
+
710
812
  case Float16: {
711
813
  double b = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
712
814
  return a == b;
@@ -722,6 +824,19 @@ equal_float64(const double a, const xnd_t * const x)
722
824
  return a == b;
723
825
  }
724
826
 
827
+ case BComplex32: {
828
+ double real, imag;
829
+
830
+ real = xnd_bfloat_unpack(x->ptr);
831
+ imag = xnd_bfloat_unpack(x->ptr+2);
832
+
833
+ if (imag == 0.0) {
834
+ return a == real;
835
+ }
836
+
837
+ return 0;
838
+ }
839
+
725
840
  case Complex32: {
726
841
  double real, imag;
727
842
 
@@ -819,6 +934,11 @@ equal_complex128(const double real, const double imag, const xnd_t * const x)
819
934
  return b <= 4503599627370496ULL ? real == (double)b : 0;
820
935
  }
821
936
 
937
+ case BFloat16: {
938
+ double b = xnd_bfloat_unpack(x->ptr);
939
+ return imag == 0.0 && real == b;
940
+ }
941
+
822
942
  case Float16: {
823
943
  double b = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
824
944
  return imag == 0.0 && real == b;
@@ -834,6 +954,12 @@ equal_complex128(const double real, const double imag, const xnd_t * const x)
834
954
  return imag == 0.0 && real == b;
835
955
  }
836
956
 
957
+ case BComplex32: {
958
+ double a = xnd_bfloat_unpack(x->ptr);
959
+ double b = xnd_bfloat_unpack(x->ptr+2);
960
+ return real == a && imag == b;
961
+ }
962
+
837
963
  case Complex32: {
838
964
  double a = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
839
965
  double b = xnd_float_unpack2((unsigned char *)(x->ptr+2), le(t->flags));
@@ -859,6 +985,8 @@ equal_complex128(const double real, const double imag, const xnd_t * const x)
859
985
  int
860
986
  xnd_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
861
987
  {
988
+ APPLY_STORED_INDICES_INT(x)
989
+ APPLY_STORED_INDICES_INT(y)
862
990
  const ndt_t * const t = x->type;
863
991
  const ndt_t * const u = y->type;
864
992
  int n;
@@ -972,6 +1100,20 @@ xnd_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
972
1100
  return 1;
973
1101
  }
974
1102
 
1103
+ case Union: {
1104
+ const xnd_t xnext = xnd_union_next(x, ctx);
1105
+ if (xnext.ptr == NULL) {
1106
+ return -1;
1107
+ }
1108
+
1109
+ const xnd_t ynext = xnd_union_next(y, ctx);
1110
+ if (ynext.ptr == NULL) {
1111
+ return -1;
1112
+ }
1113
+
1114
+ return xnd_equal(&xnext, &ynext, ctx);
1115
+ }
1116
+
975
1117
  case Constr: {
976
1118
  if (u->tag != Constr || strcmp(u->Constr.name, t->Constr.name) != 0) {
977
1119
  return 0;
@@ -1094,6 +1236,11 @@ xnd_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
1094
1236
  return equal_uint64(a, y);
1095
1237
  }
1096
1238
 
1239
+ case BFloat16: {
1240
+ double a = xnd_bfloat_unpack(x->ptr);
1241
+ return equal_float64(a, y);
1242
+ }
1243
+
1097
1244
  case Float16: {
1098
1245
  double a = xnd_float_unpack2((unsigned char *)x->ptr, le(t->flags));
1099
1246
  return equal_float64(a, y);
@@ -1109,6 +1256,19 @@ xnd_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
1109
1256
  return equal_float64(a, y);
1110
1257
  }
1111
1258
 
1259
+ case BComplex32: {
1260
+ double real, imag;
1261
+
1262
+ real = xnd_bfloat_unpack(x->ptr);
1263
+ imag = xnd_bfloat_unpack(x->ptr+2);
1264
+
1265
+ if (imag == 0.0) {
1266
+ return equal_float64(real, y);
1267
+ }
1268
+
1269
+ return equal_complex128(real, imag, y);
1270
+ }
1271
+
1112
1272
  case Complex32: {
1113
1273
  double real, imag;
1114
1274
 
@@ -1172,8 +1332,8 @@ xnd_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
1172
1332
  return 0;
1173
1333
  }
1174
1334
 
1175
- const char *a = XND_POINTER_DATA(x->ptr);
1176
- const char *b = XND_POINTER_DATA(y->ptr);
1335
+ const char *a = XND_STRING_DATA(x->ptr);
1336
+ const char *b = XND_STRING_DATA(y->ptr);
1177
1337
  return strcmp(a, b) == 0;
1178
1338
  }
1179
1339
 
@@ -1198,8 +1358,36 @@ xnd_equal(const xnd_t *x, const xnd_t *y, ndt_context_t *ctx)
1198
1358
  return memcmp(a, b, (size_t)asize) == 0;
1199
1359
  }
1200
1360
 
1361
+ case Array: {
1362
+ int64_t ashape, bshape;
1363
+
1364
+ if (u->tag != Array) {
1365
+ return 0;
1366
+ }
1367
+
1368
+ ashape = XND_ARRAY_SHAPE(x->ptr);
1369
+ bshape = XND_ARRAY_SHAPE(y->ptr);
1370
+
1371
+ if (ashape != bshape) {
1372
+ return 0;
1373
+ }
1374
+
1375
+ for (int64_t i = 0; i < ashape; i++) {
1376
+ const xnd_t xnext = xnd_array_next(x, i);
1377
+ const xnd_t ynext = xnd_array_next(y, i);
1378
+ n = xnd_equal(&xnext, &ynext, ctx);
1379
+ if (n <= 0) return n;
1380
+ }
1381
+
1382
+ return 1;
1383
+ }
1384
+
1385
+ /* NOT REACHED: intercepted by apply_stored_indices(). */
1386
+ case VarDimElem:
1201
1387
  /* NOT REACHED: intercepted by equal_ref(). */
1202
1388
  case Ref:
1389
+ ndt_err_format(ctx, NDT_RuntimeError, "unexpected VarDimElem or Ref");
1390
+ return -1;
1203
1391
 
1204
1392
  /* NOT REACHED: xnd types must be concrete. */
1205
1393
  case Module: case Function: