numkong 7.4.3 → 7.4.4
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.
- package/README.md +49 -49
- package/binding.gyp +3 -0
- package/include/numkong/capabilities.h +1 -1
- package/include/numkong/each/haswell.h +4 -4
- package/include/numkong/types.h +15 -9
- package/numkong.gypi +3 -0
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -391,24 +391,24 @@ Float16 prioritizes __precision over range__ (10 vs 7 mantissa bits), making it
|
|
|
391
391
|
On x86, older CPUs use __F16C extensions__ (Ivy Bridge+) for fast Float16 → Float32 conversion; Sapphire Rapids+ adds native __AVX-512-FP16__ with dedicated Float16 arithmetic.
|
|
392
392
|
On Arm, ARMv8.4-A adds __FMLAL/FMLAL2__ instructions for fused Float16 → Float32 widening multiply-accumulate, reducing the total latency from 7 cycles to 4 cycles and achieving 20–48% speedup over the separate convert-then-FMA path.
|
|
393
393
|
|
|
394
|
-
| Platform
|
|
395
|
-
|
|
|
396
|
-
| __x86__
|
|
397
|
-
| Diamond
|
|
398
|
-
| Sapphire
|
|
399
|
-
| Genoa
|
|
400
|
-
| Skylake
|
|
401
|
-
| Haswell
|
|
402
|
-
| __Arm__
|
|
403
|
-
| Apple M2
|
|
404
|
-
| Graviton 3
|
|
405
|
-
| Apple M1
|
|
406
|
-
| Graviton 2
|
|
407
|
-
| Graviton 1
|
|
408
|
-
| __RISC-V__
|
|
409
|
-
| RVV
|
|
410
|
-
| RVV
|
|
411
|
-
| RVV
|
|
394
|
+
| Platform | BFloat16 Path | Step | Float16 Path | Step |
|
|
395
|
+
| :--------------- | :------------------------- | ---: | :--------------------- | ---: |
|
|
396
|
+
| __x86__ | | | | |
|
|
397
|
+
| Diamond, '26 | ↓ Genoa | 32 | `VDPPHPS` widening dot | 32 |
|
|
398
|
+
| Sapphire, '23 | ↓ Genoa | 32 | ↓ Skylake | 16 |
|
|
399
|
+
| Genoa, '22 | `VDPBF16PS` widening dot | 32 | ↓ Skylake | 16 |
|
|
400
|
+
| Skylake, '15 | `SLLI` + `VFMADD` | 16 | `VCVTPH2PS` + `VFMADD` | 16 |
|
|
401
|
+
| Haswell, '13 | `SLLI` + `VFMADD` | 8 | `VCVTPH2PS` + `VFMADD` | 8 |
|
|
402
|
+
| __Arm__ | | | | |
|
|
403
|
+
| Apple M2+, '22 | `BFDOT` widening dot | 8 | ↓ FP16FML | 8 |
|
|
404
|
+
| Graviton 3+, '21 | `SVBFDOT` widening dot | 4–32 | `SVCVT` → `SVFMLA` | 4–32 |
|
|
405
|
+
| Apple M1, '20 | ↓ NEON | 8 | `FMLAL` widening FMA | 8 |
|
|
406
|
+
| Graviton 2, '19 | ↓ NEON | 8 | `FCVTL` + `FMLA` | 4 |
|
|
407
|
+
| Graviton 1, '18 | `SHLL` + `FMLA` | 8 | bit-manip → `FMLA` | 8 |
|
|
408
|
+
| __RISC-V__ | | | | |
|
|
409
|
+
| RVV+Zvfbfwma | `VFWMACCBF16` widening FMA | 4–32 | ↓ RVV | 4–32 |
|
|
410
|
+
| RVV+Zvfh | ↓ RVV | 4–32 | `VFWMACC` widening FMA | 4–32 |
|
|
411
|
+
| RVV | shift + `VFMACC` | 4–32 | convert + `VFMACC` | 4–32 |
|
|
412
412
|
|
|
413
413
|
> BFloat16 shares Float32's 8-bit exponent, so upcasting is a 16-bit left shift (`SLLI` on x86, `SHLL` on Arm) that zero-pads the truncated mantissa — essentially free.
|
|
414
414
|
> Float16 has a different exponent width (5 vs 8 bits), requiring a dedicated convert: `VCVTPH2PS` (x86 F16C) or `FCVTL` (Arm NEON).
|
|
@@ -444,22 +444,22 @@ E4M3FN (no infinities, NaN only) is preferred for __training__ where precision n
|
|
|
444
444
|
On x86 Genoa/Sapphire Rapids, E4M3/E5M2 values upcast to BFloat16 via lookup tables, then use native __DPBF16PS__ for 2-per-lane dot products accumulating to Float32.
|
|
445
445
|
On Arm Graviton 3+, the same BFloat16 upcast happens via NEON table lookups, then __BFDOT__ instructions complete the computation.
|
|
446
446
|
|
|
447
|
-
| Platform
|
|
448
|
-
|
|
|
449
|
-
| __x86__
|
|
450
|
-
| Diamond
|
|
451
|
-
| Genoa
|
|
452
|
-
| Ice Lake
|
|
453
|
-
| Skylake
|
|
454
|
-
| Haswell
|
|
455
|
-
| __Arm__
|
|
456
|
-
| NEON
|
|
457
|
-
| NEON
|
|
458
|
-
| NEON
|
|
459
|
-
| __RISC-V__
|
|
460
|
-
| RVV
|
|
461
|
-
| RVV
|
|
462
|
-
| RVV
|
|
447
|
+
| Platform | E5M2 Path | Step | E4M3 Path | Step |
|
|
448
|
+
| :---------------- | :----------------------------- | ---: | :----------------------------- | ---: |
|
|
449
|
+
| __x86__ | | | | |
|
|
450
|
+
| Diamond, '26 | `VCVTBF82PH` → F16 + `VDPPHPS` | 32 | `VCVTHF82PH` → F16 + `VDPPHPS` | 32 |
|
|
451
|
+
| Genoa, '22 | → BF16 + `VDPBF16PS` | 32 | ↓ Ice Lake | 64 |
|
|
452
|
+
| Ice Lake, '19 | ↓ Skylake | 16 | octave LUT + `VPDPBUSD` | 64 |
|
|
453
|
+
| Skylake, '15 | rebias → F32 FMA | 16 | rebias → F32 FMA | 16 |
|
|
454
|
+
| Haswell, '13 | rebias → F32 FMA | 8 | rebias → F32 FMA | 8 |
|
|
455
|
+
| __Arm__ | | | | |
|
|
456
|
+
| NEON+FP8DOT, '26 | native `FDOT` | 16 | native `FDOT` | 16 |
|
|
457
|
+
| NEON+FP16FML, '20 | SHL → F16 + `FMLAL` | 16 | LUT → F16 + `FMLAL` | 16 |
|
|
458
|
+
| NEON, '18 | SHL + `FCVTL` + FMA | 8 | → F16 + `FCVTL` + FMA | 8 |
|
|
459
|
+
| __RISC-V__ | | | | |
|
|
460
|
+
| RVV+Zvfbfwma | rebias → BF16 + `VFWMACCBF16` | 4–32 | LUT → BF16 + `VFWMACCBF16` | 4–32 |
|
|
461
|
+
| RVV+Zvfh | SHL → F16 + `VFWMACC` | 4–32 | LUT → F16 + `VFWMACC` | 4–32 |
|
|
462
|
+
| RVV | rebias → F32 + `VFMACC` | 4–32 | LUT → F32 + `VFMACC` | 4–32 |
|
|
463
463
|
|
|
464
464
|
> E5M2 shares Float16's exponent bias (15), so E5M2 → Float16 conversion is a single left-shift by 8 bits (`SHL 8`).
|
|
465
465
|
> E4M3 on Ice Lake uses "octave decomposition": the 4-bit exponent splits into 2 octave + 2 remainder bits, yielding 7 integer accumulators post-scaled by powers of 2.
|
|
@@ -469,23 +469,23 @@ Their smaller range allows scaling to exact integers that fit in `i8`/`i16`, ena
|
|
|
469
469
|
Float16 can also serve as an accumulator, accurately representing ~50 products of E3M2FN pairs or ~20 products of E2M3FN pairs before overflow.
|
|
470
470
|
On Arm, NEON FHM extensions bring widening `FMLAL` dot-products for Float16 — both faster and more widely available than `BFDOT` for BFloat16.
|
|
471
471
|
|
|
472
|
-
| Platform
|
|
473
|
-
|
|
|
474
|
-
| __x86__
|
|
475
|
-
| Sierra Forest
|
|
476
|
-
| Alder Lake
|
|
477
|
-
| Ice Lake
|
|
478
|
-
| Skylake
|
|
479
|
-
| Haswell
|
|
480
|
-
| __Arm__
|
|
481
|
-
| NEON
|
|
482
|
-
| NEON
|
|
483
|
-
| NEON
|
|
484
|
-
| __RISC-V__
|
|
485
|
-
| RVV
|
|
472
|
+
| Platform | E3M2 Path | Step | E2M3 Path | Step |
|
|
473
|
+
| :----------------- | :------------------------ | ---: | :----------------------- | ---: |
|
|
474
|
+
| __x86__ | | | | |
|
|
475
|
+
| Sierra Forest, '24 | ↓ Haswell | 32 | `VPSHUFB` + `VPDPBSSD` | 32 |
|
|
476
|
+
| Alder Lake, '21 | ↓ Haswell | 32 | `VPSHUFB` + `VPDPBUSD` | 32 |
|
|
477
|
+
| Ice Lake, '19 | `VPERMW` + `VPMADDWD` | 32 | `VPERMB` + `VPDPBUSD` | 64 |
|
|
478
|
+
| Skylake, '15 | `VPSHUFB` + `VPMADDWD` | 64 | `VPSHUFB` + `VPMADDUBSW` | 64 |
|
|
479
|
+
| Haswell, '13 | `VPSHUFB` + `VPMADDWD` | 32 | `VPSHUFB` + `VPMADDUBSW` | 32 |
|
|
480
|
+
| __Arm__ | | | | |
|
|
481
|
+
| NEON+FP8DOT, '26 | → E5M2 + `FDOT` | 16 | → E4M3 + `FDOT` | 16 |
|
|
482
|
+
| NEON+DotProd, '19 | `VQTBL2` + `SMLAL` | 16 | `VQTBL2` + `SDOT` | 16 |
|
|
483
|
+
| NEON, '18 | → F16 + `FCVTL` + FMA | 16 | → F16 + `FCVTL` + FMA | 16 |
|
|
484
|
+
| __RISC-V__ | | | | |
|
|
485
|
+
| RVV | I16 gather LUT + `VWMACC` | 4–32 | U8 gather LUT + `VWMACC` | 4–32 |
|
|
486
486
|
|
|
487
487
|
> E3M2/E2M3 values map to exact integers via 32-entry LUTs (magnitudes up to 448 for E3M2, 120 for E2M3), enabling integer accumulation with no rounding error.
|
|
488
|
-
> On NEON
|
|
488
|
+
> On NEON+FP8DOT, E3M2 is first promoted to E5M2 and E2M3 to E4M3 before the hardware `FDOT` instruction.
|
|
489
489
|
> Sierra Forest and Alder Lake use native `VPDPBSSD` (signed×signed) and `VPDPBUSD` (unsigned×signed) respectively for E2M3.
|
|
490
490
|
|
|
491
491
|
E4M3 and E5M2 cannot use the integer path.
|
package/binding.gyp
CHANGED
|
@@ -196,7 +196,7 @@ NK_PUBLIC void nk_each_sum_f16_haswell(nk_f16_t const *a, nk_f16_t const *b, nk_
|
|
|
196
196
|
__m256 a_f32x8 = _mm256_cvtph_ps(a_f16x8);
|
|
197
197
|
__m256 b_f32x8 = _mm256_cvtph_ps(b_f16x8);
|
|
198
198
|
__m256 result_f32x8 = _mm256_add_ps(a_f32x8, b_f32x8);
|
|
199
|
-
__m128i result_f16x8 = _mm256_cvtps_ph(result_f32x8, _MM_FROUND_TO_NEAREST_INT
|
|
199
|
+
__m128i result_f16x8 = _mm256_cvtps_ph(result_f32x8, _MM_FROUND_TO_NEAREST_INT);
|
|
200
200
|
_mm_storeu_si128((__m128i *)(result + i), result_f16x8);
|
|
201
201
|
}
|
|
202
202
|
|
|
@@ -223,7 +223,7 @@ NK_PUBLIC void nk_each_scale_f16_haswell(nk_f16_t const *a, nk_size_t n, nk_f32_
|
|
|
223
223
|
__m128i a_f16x8 = _mm_loadu_si128((__m128i const *)(a + i));
|
|
224
224
|
__m256 a_f32x8 = _mm256_cvtph_ps(a_f16x8);
|
|
225
225
|
__m256 result_f32x8 = _mm256_fmadd_ps(a_f32x8, alpha_f32x8, beta_f32x8);
|
|
226
|
-
__m128i result_f16x8 = _mm256_cvtps_ph(result_f32x8, _MM_FROUND_TO_NEAREST_INT
|
|
226
|
+
__m128i result_f16x8 = _mm256_cvtps_ph(result_f32x8, _MM_FROUND_TO_NEAREST_INT);
|
|
227
227
|
_mm_storeu_si128((__m128i *)(result + i), result_f16x8);
|
|
228
228
|
}
|
|
229
229
|
|
|
@@ -271,7 +271,7 @@ NK_PUBLIC void nk_each_blend_f16_haswell( //
|
|
|
271
271
|
__m256 b_f32x8 = _mm256_cvtph_ps(b_f16x8);
|
|
272
272
|
__m256 a_scaled_f32x8 = _mm256_mul_ps(a_f32x8, alpha_f32x8);
|
|
273
273
|
__m256 result_f32x8 = _mm256_fmadd_ps(b_f32x8, beta_f32x8, a_scaled_f32x8);
|
|
274
|
-
__m128i result_f16x8 = _mm256_cvtps_ph(result_f32x8, _MM_FROUND_TO_NEAREST_INT
|
|
274
|
+
__m128i result_f16x8 = _mm256_cvtps_ph(result_f32x8, _MM_FROUND_TO_NEAREST_INT);
|
|
275
275
|
_mm_storeu_si128((__m128i *)(result + i), result_f16x8);
|
|
276
276
|
}
|
|
277
277
|
|
|
@@ -451,7 +451,7 @@ NK_PUBLIC void nk_each_fma_f16_haswell( //
|
|
|
451
451
|
__m256 ab_f32x8 = _mm256_mul_ps(a_f32x8, b_f32x8);
|
|
452
452
|
__m256 abc_f32x8 = _mm256_mul_ps(ab_f32x8, alpha_f32x8);
|
|
453
453
|
__m256 result_f32x8 = _mm256_fmadd_ps(c_f32x8, beta_f32x8, abc_f32x8);
|
|
454
|
-
__m128i result_f16x8 = _mm256_cvtps_ph(result_f32x8, _MM_FROUND_TO_NEAREST_INT
|
|
454
|
+
__m128i result_f16x8 = _mm256_cvtps_ph(result_f32x8, _MM_FROUND_TO_NEAREST_INT);
|
|
455
455
|
_mm_storeu_si128((__m128i *)(result + i), result_f16x8);
|
|
456
456
|
}
|
|
457
457
|
|
package/include/numkong/types.h
CHANGED
|
@@ -119,6 +119,12 @@
|
|
|
119
119
|
#define NK_MAY_ALIAS_
|
|
120
120
|
#endif
|
|
121
121
|
|
|
122
|
+
#if defined(__has_builtin)
|
|
123
|
+
#define nk_has_builtin_(x) __has_builtin(x)
|
|
124
|
+
#else
|
|
125
|
+
#define nk_has_builtin_(x) 0
|
|
126
|
+
#endif
|
|
127
|
+
|
|
122
128
|
// Allow SIMD kernels to redirect small inputs to serial implementations.
|
|
123
129
|
// Enabled by default for production use. Tests and benchmarks may disable
|
|
124
130
|
// this to isolate SIMD path behavior on small inputs.
|
|
@@ -425,7 +431,7 @@
|
|
|
425
431
|
// AppleClang 17 exposes SME sub-features through `arm_sme.h` builtin aliases,
|
|
426
432
|
// not dedicated `__ARM_FEATURE_*` predefines for every matrix subtype.
|
|
427
433
|
#if !defined(NK_TARGET_SMEF64) || (NK_TARGET_SMEF64 && !NK_TARGET_ARM64_)
|
|
428
|
-
#if defined(__ARM_FEATURE_SME_F64F64) || (
|
|
434
|
+
#if defined(__ARM_FEATURE_SME_F64F64) || nk_has_builtin_(__builtin_sme_svmopa_za64_f64_m)
|
|
429
435
|
#define NK_TARGET_SMEF64 1
|
|
430
436
|
#else
|
|
431
437
|
#undef NK_TARGET_SMEF64
|
|
@@ -434,39 +440,39 @@
|
|
|
434
440
|
#endif // !defined(NK_TARGET_SMEF64) || ...
|
|
435
441
|
|
|
436
442
|
#if !defined(NK_TARGET_SMEBI32) || (NK_TARGET_SMEBI32 && !NK_TARGET_ARM64_)
|
|
437
|
-
#if
|
|
443
|
+
#if nk_has_builtin_(__builtin_sme_svbmopa_za32_u32_m)
|
|
438
444
|
#define NK_TARGET_SMEBI32 1
|
|
439
445
|
#else
|
|
440
446
|
#undef NK_TARGET_SMEBI32
|
|
441
447
|
#define NK_TARGET_SMEBI32 0
|
|
442
|
-
#endif //
|
|
448
|
+
#endif // nk_has_builtin_(__builtin_sme_svbmopa_za32_u32_m)
|
|
443
449
|
#endif // !defined(NK_TARGET_SMEBI32) || ...
|
|
444
450
|
|
|
445
451
|
#if !defined(NK_TARGET_SMEHALF) || (NK_TARGET_SMEHALF && !NK_TARGET_ARM64_)
|
|
446
|
-
#if defined(__ARM_FEATURE_SME_F16F16) || (
|
|
452
|
+
#if defined(__ARM_FEATURE_SME_F16F16) || nk_has_builtin_(__builtin_sme_svmopa_za32_f16_m)
|
|
447
453
|
#define NK_TARGET_SMEHALF 1
|
|
448
454
|
#else
|
|
449
455
|
#undef NK_TARGET_SMEHALF
|
|
450
456
|
#define NK_TARGET_SMEHALF 0
|
|
451
|
-
#endif //
|
|
457
|
+
#endif // nk_has_builtin_(__builtin_sme_svmopa_za32_f16_m)
|
|
452
458
|
#endif // !defined(NK_TARGET_SMEHALF) || ...
|
|
453
459
|
|
|
454
460
|
#if !defined(NK_TARGET_SMEBF16) || (NK_TARGET_SMEBF16 && !NK_TARGET_ARM64_)
|
|
455
|
-
#if
|
|
461
|
+
#if nk_has_builtin_(__builtin_sme_svmopa_za32_bf16_m)
|
|
456
462
|
#define NK_TARGET_SMEBF16 1
|
|
457
463
|
#else
|
|
458
464
|
#undef NK_TARGET_SMEBF16
|
|
459
465
|
#define NK_TARGET_SMEBF16 0
|
|
460
|
-
#endif //
|
|
466
|
+
#endif // nk_has_builtin_(__builtin_sme_svmopa_za32_bf16_m)
|
|
461
467
|
#endif // !defined(NK_TARGET_SMEBF16) || ...
|
|
462
468
|
|
|
463
469
|
#if !defined(NK_TARGET_SMELUT2) || (NK_TARGET_SMELUT2 && !NK_TARGET_ARM64_)
|
|
464
|
-
#if
|
|
470
|
+
#if nk_has_builtin_(__builtin_sme_svluti2_lane_zt_u8)
|
|
465
471
|
#define NK_TARGET_SMELUT2 1
|
|
466
472
|
#else
|
|
467
473
|
#undef NK_TARGET_SMELUT2
|
|
468
474
|
#define NK_TARGET_SMELUT2 0
|
|
469
|
-
#endif //
|
|
475
|
+
#endif // nk_has_builtin_(__builtin_sme_svluti2_lane_zt_u8)
|
|
470
476
|
#endif // !defined(NK_TARGET_SMELUT2) || ...
|
|
471
477
|
|
|
472
478
|
// Compiling for Arm: NK_TARGET_SMEFA64 (FEAT_SME_FA64, full SVE2 in streaming mode)
|
package/numkong.gypi
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "numkong",
|
|
3
|
-
"version": "7.4.
|
|
3
|
+
"version": "7.4.4",
|
|
4
4
|
"description": "Portable mixed-precision math, linear-algebra, & retrieval library with 2000+ SIMD kernels for x86, Arm, RISC-V, LoongArch, Power, & WebAssembly",
|
|
5
5
|
"homepage": "https://github.com/ashvardanian/NumKong",
|
|
6
6
|
"author": "Ash Vardanian",
|
|
@@ -98,11 +98,11 @@
|
|
|
98
98
|
"printWidth": 120
|
|
99
99
|
},
|
|
100
100
|
"optionalDependencies": {
|
|
101
|
-
"@numkong/darwin-arm64": "7.4.
|
|
102
|
-
"@numkong/darwin-x64": "7.4.
|
|
103
|
-
"@numkong/linux-arm64": "7.4.
|
|
104
|
-
"@numkong/linux-x64": "7.4.
|
|
105
|
-
"@numkong/win32-arm64": "7.4.
|
|
106
|
-
"@numkong/win32-x64": "7.4.
|
|
101
|
+
"@numkong/darwin-arm64": "7.4.4",
|
|
102
|
+
"@numkong/darwin-x64": "7.4.4",
|
|
103
|
+
"@numkong/linux-arm64": "7.4.4",
|
|
104
|
+
"@numkong/linux-x64": "7.4.4",
|
|
105
|
+
"@numkong/win32-arm64": "7.4.4",
|
|
106
|
+
"@numkong/win32-x64": "7.4.4"
|
|
107
107
|
}
|
|
108
108
|
}
|