Commit bd5f5d7
committed
feat(dtypes): Half/SByte/Complex coverage audit + NumPy parity fixes
Audit of "NPTypeCode.Single =>" arrow-switch expressions across 23 files
found 11 gaps where Half/SByte/Complex were missing. Fixed each and
tightened several related behaviors to strict NumPy 2.x parity.
## Core fixes (Half/SByte/Complex coverage)
- np.repeat: add SByte/Half/Complex to RepeatScalarTyped/RepeatArrayTyped
switches. Previously threw NotSupportedException for these dtypes.
- np.any / np.all axis: add SByte/Half/Complex to axis dispatch
(generic ComputePerAxis<T> already supports via unmanaged constraint).
- ILKernelGenerator.Reduction.Axis.Arg: add SByte/Half/Complex to
argmax/argmin axis dispatch. Added ArgReduceAxisHalfNaN (NumPy
first-NaN-wins semantics via double) and ArgReduceAxisComplex
(lexicographic real-then-imag, NaN propagates). sbyte added to
CompareGreater/Less.
- ReductionKernel.GetMinValue/GetMaxValue: add SByte/Half/Complex
identities (sbyte.Min/MaxValue, Half.Negative/PositiveInfinity,
Complex(inf,0) sentinels for Max/Min identity on empty arrays).
- Default.Reduction.Nan ExecuteNanAxisReductionScalar: add Half case +
ReduceNanAxisScalarHalf helper covering NanSum/NanProd/NanMin/NanMax.
Previously silently returned 0 for Half axis NaN reductions.
- ILKernelGenerator.Reduction.Axis.NaN: updated doc comment clarifying
Half/Complex route to scalar fallback (resolved by the above fix).
- Default.ATan2: add SByte/Half to ConvertToDouble/ConvertToDecimal and
Half to result-type switch. Complex excluded (NumPy arctan2 rejects
complex inputs — matches np.arctan2 TypeError).
- np.can_cast ValueFitsInType: add Half (range-checked ±65504) and
Complex (always true from real) to every `case` arm; added
`case Half h:` and `case Complex c:`. Full 13×13 can_cast matrix
now matches NumPy exactly.
- ILKernelGenerator EmitDecimalConversion: added SByte conversion via
new CachedMethods.DecimalImplicitFromSByte / DecimalToSByte. Previously
sbyte↔decimal IL conversions threw NotSupportedException.
- np.sctype2char: fix Boolean '?' (was incorrectly 'b'), add SByte 'b',
add Half 'e'. Matches NumPy 2.x np.dtype(x).char.
## Strict-parity fixes discovered during verification
- ATan2 auto-promotion now matches NumPy 2.x per-input targeting:
bool/i8/u8 → float16, i16/u16 → float32, i32+/i64+/char → float64,
float types preserved, binary takes max. Added PromoteATan2Single +
PromoteATan2Binary helpers. Previously everything except f32+f32
promoted to double.
- common_type_code rewritten to match NumPy exactly:
* Boolean input: raises TypeError "non-numeric array" (NumPy parity)
* Any Complex → Complex
* Any Decimal → Decimal (NumSharp extension)
* Any integer/char → Double (forces float64 even if smaller float present)
* Otherwise: max pure float (Half < Single < Double)
12×12 matrix now identically matches NumPy.
- Empty reduction dtype: sum/prod of empty array now uses
GetAccumulatingType() so int/bool → Int64/UInt64, floats preserved.
Previously returned input dtype (sum([], sbyte) gave SByte, NumPy
gives int64). Fixed in Default.Reduction.Add (HandleEmptyArrayReduction
+ IsEmpty path) and Default.Reduction.Product (both IsEmpty paths).
## Test additions
- test/NumSharp.UnitTest/APIs/np.common_type.BattleTest.cs:
Complete rewrite — 77 comprehensive tests covering:
- Boolean TypeError (5 tests)
- Single integer inputs → Double (9 tests)
- Single float preserved (3 tests)
- Complex/Decimal (2 tests)
- Pure float combos → max float (9 tests)
- Integer+Integer combos (7 tests)
- Integer+Float combos (10 tests)
- Complex combos (9 tests)
- Decimal combos with float/int/complex (5 tests)
- NDArray / Type overloads (12 tests)
- Argument validation (3 tests)
- test/NumSharp.UnitTest/Backends/Kernels/BinaryOpTests.cs:
8 new ATan2_* tests pinning Half/SByte/Int16 NumPy parity:
ATan2_Float16_ReturnsHalf, ATan2_Int8_ReturnsFloat16,
ATan2_UInt8_ReturnsFloat16, ATan2_Int16_ReturnsFloat32,
ATan2_Float16_Int8_ReturnsFloat16,
ATan2_Float16_Int32_ReturnsFloat64,
ATan2_Int16_Float16_ReturnsFloat32.
- test/NumSharp.UnitTest/APIs/np.type_checks.BattleTest.cs:
Updated Sctype2Char_Boolean to expect '?' (matches NumPy);
added Sctype2Char_SByte ('b') and Sctype2Char_Half ('e').
## Verification methodology
Every change verified against NumPy 2.x via python_run reference runs.
Side-by-side 13×13 can_cast grid and 12×12 common_type grid both
produce identical output to NumPy. Cast correctness (Half↔double) is
lossless per IEEE 754 and matches NumPy's internal float16 handling.
## Test results
7192 passed / 0 failed / 11 skipped on both net8.0 and net10.0.
(+63 net tests vs pre-audit; rewritten common_type suite replaced
14 older tests with 77 parity-locked ones.)
## Behavioral breaking changes (NumPy parity)
- np.sctype2char(Boolean): 'b' → '?'
- np.common_type(Boolean): returned Double → now throws TypeError
- np.arctan2(i8/u8/bool): returned Double → now returns Half
- np.arctan2(i16/u16): returned Double → now returns Single
- np.arctan2(f16): returned Double → now returns Half
- np.sum/np.prod of empty integer array: returned input dtype →
now returns Int64/UInt64 accumulating type1 parent b36555f commit bd5f5d7
17 files changed
Lines changed: 677 additions & 126 deletions
File tree
- src/NumSharp.Core
- Backends
- Default/Math
- Reduction
- Kernels
- Logic
- Manipulation
- test/NumSharp.UnitTest
- APIs
- Backends/Kernels
Lines changed: 56 additions & 26 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
78 | 61 | | |
79 | 62 | | |
80 | 63 | | |
| |||
119 | 102 | | |
120 | 103 | | |
121 | 104 | | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
122 | 146 | | |
123 | 147 | | |
124 | 148 | | |
| |||
135 | 159 | | |
136 | 160 | | |
137 | 161 | | |
| 162 | + | |
138 | 163 | | |
139 | 164 | | |
140 | 165 | | |
| |||
152 | 177 | | |
153 | 178 | | |
154 | 179 | | |
| 180 | + | |
155 | 181 | | |
156 | 182 | | |
157 | 183 | | |
158 | 184 | | |
159 | 185 | | |
160 | 186 | | |
161 | 187 | | |
| 188 | + | |
162 | 189 | | |
163 | 190 | | |
164 | 191 | | |
| 192 | + | |
165 | 193 | | |
166 | 194 | | |
167 | 195 | | |
| |||
175 | 203 | | |
176 | 204 | | |
177 | 205 | | |
| 206 | + | |
178 | 207 | | |
179 | 208 | | |
180 | 209 | | |
181 | 210 | | |
182 | 211 | | |
183 | 212 | | |
184 | 213 | | |
| 214 | + | |
185 | 215 | | |
186 | 216 | | |
187 | 217 | | |
| |||
Lines changed: 6 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
16 | 18 | | |
17 | 19 | | |
18 | 20 | | |
| |||
125 | 127 | | |
126 | 128 | | |
127 | 129 | | |
128 | | - | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
129 | 133 | | |
130 | 134 | | |
131 | 135 | | |
| |||
Lines changed: 58 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
545 | 545 | | |
546 | 546 | | |
547 | 547 | | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
548 | 551 | | |
549 | 552 | | |
550 | 553 | | |
| |||
665 | 668 | | |
666 | 669 | | |
667 | 670 | | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
668 | 726 | | |
669 | 727 | | |
670 | 728 | | |
| |||
Lines changed: 7 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
15 | 19 | | |
16 | 20 | | |
17 | 21 | | |
18 | 22 | | |
19 | 23 | | |
20 | | - | |
| 24 | + | |
| 25 | + | |
21 | 26 | | |
22 | 27 | | |
23 | 28 | | |
| |||
Lines changed: 88 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
33 | 34 | | |
34 | 35 | | |
35 | 36 | | |
36 | 37 | | |
37 | 38 | | |
38 | 39 | | |
39 | 40 | | |
| 41 | + | |
40 | 42 | | |
41 | 43 | | |
42 | 44 | | |
| 45 | + | |
43 | 46 | | |
44 | 47 | | |
45 | 48 | | |
| |||
133 | 136 | | |
134 | 137 | | |
135 | 138 | | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
136 | 147 | | |
137 | 148 | | |
138 | 149 | | |
| |||
307 | 318 | | |
308 | 319 | | |
309 | 320 | | |
| 321 | + | |
310 | 322 | | |
311 | 323 | | |
312 | 324 | | |
| |||
315 | 327 | | |
316 | 328 | | |
317 | 329 | | |
318 | | - | |
| 330 | + | |
319 | 331 | | |
320 | 332 | | |
321 | 333 | | |
| |||
325 | 337 | | |
326 | 338 | | |
327 | 339 | | |
| 340 | + | |
328 | 341 | | |
329 | 342 | | |
330 | 343 | | |
| |||
333 | 346 | | |
334 | 347 | | |
335 | 348 | | |
336 | | - | |
| 349 | + | |
337 | 350 | | |
338 | 351 | | |
339 | 352 | | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
340 | 426 | | |
341 | 427 | | |
342 | 428 | | |
0 commit comments