nbxtensor 0.0.1__py3-none-any.whl
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.
- nbxtensor/THIRD_PARTY_NOTICES.md +287 -0
- nbxtensor/__init__.py +17 -0
- nbxtensor/backend/__init__.py +1 -0
- nbxtensor/backend/capabilities.py +207 -0
- nbxtensor/backend/cpu/__init__.py +1 -0
- nbxtensor/backend/cpu/blas.py +102 -0
- nbxtensor/backend/cpu/pool.py +204 -0
- nbxtensor/backend/cpu_backend.py +162 -0
- nbxtensor/backend/device_facts.py +105 -0
- nbxtensor/backend/device_files.py +129 -0
- nbxtensor/backend/device_names.py +18 -0
- nbxtensor/backend/devices/amd/cdna.yml +228 -0
- nbxtensor/backend/devices/amd/cdna2.yml +228 -0
- nbxtensor/backend/devices/amd/cdna3.yml +227 -0
- nbxtensor/backend/devices/apple/apple_m1.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m1_max.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m1_pro.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m1_ultra.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m2.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m2_max.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m2_pro.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m2_ultra.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m3.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m3_max.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m3_pro.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m3_ultra.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m4.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m4_max.yml +266 -0
- nbxtensor/backend/devices/apple/apple_m4_pro.yml +308 -0
- nbxtensor/backend/devices/apple/apple_m5.yml +269 -0
- nbxtensor/backend/devices/apple/apple_m5_max.yml +269 -0
- nbxtensor/backend/devices/apple/apple_m5_pro.yml +269 -0
- nbxtensor/backend/devices/apple/apple_m5_ultra.yml +269 -0
- nbxtensor/backend/devices/apple/apple_m6.yml +269 -0
- nbxtensor/backend/devices/apple/apple_silicon.yml +263 -0
- nbxtensor/backend/devices/nvidia/ampere.yml +214 -0
- nbxtensor/backend/devices/nvidia/hopper.yml +213 -0
- nbxtensor/backend/devices/nvidia/volta.yml +411 -0
- nbxtensor/backend/faults.py +151 -0
- nbxtensor/backend/host_memory.py +185 -0
- nbxtensor/backend/launcher.py +2350 -0
- nbxtensor/backend/launcher_contract.py +429 -0
- nbxtensor/backend/metal_backend.py +661 -0
- nbxtensor/backend/metal_device.py +1274 -0
- nbxtensor/backend/process_memory.py +73 -0
- nbxtensor/backend/replay_graph.py +322 -0
- nbxtensor/backend/runtime.py +409 -0
- nbxtensor/backend/triton_ext_driver.py +735 -0
- nbxtensor/dtype/__init__.py +1 -0
- nbxtensor/dtype/convert.py +107 -0
- nbxtensor/dtype/dtypes.yml +70 -0
- nbxtensor/dtype/itemsize.py +166 -0
- nbxtensor/dtype/nbx_dtype.py +72 -0
- nbxtensor/dtype/operands.py +158 -0
- nbxtensor/dtype/outputs.py +64 -0
- nbxtensor/dtype/policy.py +155 -0
- nbxtensor/dtype/policy.yml +51 -0
- nbxtensor/dtype/promotion.py +112 -0
- nbxtensor/host.py +55 -0
- nbxtensor/io/__init__.py +1 -0
- nbxtensor/io/read_rate.py +197 -0
- nbxtensor/io/safetensors.py +314 -0
- nbxtensor/memory/__init__.py +9 -0
- nbxtensor/memory/allocator.py +1988 -0
- nbxtensor/memory/arena.py +75 -0
- nbxtensor/memory/device_memory.py +150 -0
- nbxtensor/memory/device_transfer.py +154 -0
- nbxtensor/memory/layout.py +43 -0
- nbxtensor/memory/memory_pool.py +191 -0
- nbxtensor/memory/metal.py +96 -0
- nbxtensor/memory/oom_advice.py +91 -0
- nbxtensor/memory/pointer_tables.py +323 -0
- nbxtensor/memory/pool.py +507 -0
- nbxtensor/memory/shadow.py +43 -0
- nbxtensor/memory/slab.py +273 -0
- nbxtensor/memory/trace_replay.py +122 -0
- nbxtensor/memory/traces/sana-video-2b-720p.16g.2026-11-02.tsv +13610 -0
- nbxtensor/memory/vmm.py +118 -0
- nbxtensor/ops/__init__.py +1 -0
- nbxtensor/ops/_autotune_policy.py +90 -0
- nbxtensor/ops/_common.py +32 -0
- nbxtensor/ops/_configs.py +1041 -0
- nbxtensor/ops/_cost.py +231 -0
- nbxtensor/ops/abs.py +17 -0
- nbxtensor/ops/adaptive_avg_pool2d.py +161 -0
- nbxtensor/ops/add.py +96 -0
- nbxtensor/ops/addcdiv.py +29 -0
- nbxtensor/ops/addcmul.py +29 -0
- nbxtensor/ops/addmv_op.py +64 -0
- nbxtensor/ops/addr.py +68 -0
- nbxtensor/ops/all_reduce.py +83 -0
- nbxtensor/ops/amax.py +40 -0
- nbxtensor/ops/any_reduce.py +83 -0
- nbxtensor/ops/arange_op.py +27 -0
- nbxtensor/ops/argmax.py +107 -0
- nbxtensor/ops/argmin.py +93 -0
- nbxtensor/ops/atan2.py +71 -0
- nbxtensor/ops/attention_wrappers.py +1648 -0
- nbxtensor/ops/autotune_bucket.py +137 -0
- nbxtensor/ops/autotune_cache.py +430 -0
- nbxtensor/ops/autotune_certified.py +1262 -0
- nbxtensor/ops/autotune_refusals.py +380 -0
- nbxtensor/ops/autotune_settings.py +58 -0
- nbxtensor/ops/avg_pool2d.py +73 -0
- nbxtensor/ops/baddbmm_op.py +132 -0
- nbxtensor/ops/batch_norm.py +163 -0
- nbxtensor/ops/binary_strided.py +196 -0
- nbxtensor/ops/bitwise_and.py +26 -0
- nbxtensor/ops/bitwise_left_shift.py +47 -0
- nbxtensor/ops/bitwise_not.py +24 -0
- nbxtensor/ops/bitwise_or.py +26 -0
- nbxtensor/ops/bitwise_right_shift.py +47 -0
- nbxtensor/ops/bucketize.py +37 -0
- nbxtensor/ops/cat_op.py +87 -0
- nbxtensor/ops/celu.py +20 -0
- nbxtensor/ops/clamp.py +24 -0
- nbxtensor/ops/clamp_min.py +22 -0
- nbxtensor/ops/conv2d.py +265 -0
- nbxtensor/ops/conv2d_m8n8k4.py +165 -0
- nbxtensor/ops/conv_depthwise2d.py +154 -0
- nbxtensor/ops/conv_transpose2d.py +148 -0
- nbxtensor/ops/conv_wrappers.py +1482 -0
- nbxtensor/ops/copy.py +18 -0
- nbxtensor/ops/copy_op.py +39 -0
- nbxtensor/ops/cos.py +17 -0
- nbxtensor/ops/count_nonzero.py +64 -0
- nbxtensor/ops/cross_entropy.py +67 -0
- nbxtensor/ops/cummax.py +109 -0
- nbxtensor/ops/cummin.py +105 -0
- nbxtensor/ops/cumsum.py +244 -0
- nbxtensor/ops/decode_attn_vec.py +162 -0
- nbxtensor/ops/depthwise_conv2d.py +132 -0
- nbxtensor/ops/dequant_gemv.py +190 -0
- nbxtensor/ops/dft.py +67 -0
- nbxtensor/ops/dispatch.py +1228 -0
- nbxtensor/ops/div.py +75 -0
- nbxtensor/ops/dot_op.py +67 -0
- nbxtensor/ops/dropout.py +23 -0
- nbxtensor/ops/dtype_convert.py +42 -0
- nbxtensor/ops/elementwise_launch.py +81 -0
- nbxtensor/ops/elementwise_wrappers.py +2315 -0
- nbxtensor/ops/elu.py +20 -0
- nbxtensor/ops/embedding.py +69 -0
- nbxtensor/ops/eq.py +32 -0
- nbxtensor/ops/erf.py +18 -0
- nbxtensor/ops/exp.py +17 -0
- nbxtensor/ops/exp2.py +18 -0
- nbxtensor/ops/fft_op.py +125 -0
- nbxtensor/ops/fill_op.py +20 -0
- nbxtensor/ops/flash_attention.py +307 -0
- nbxtensor/ops/flash_attention_m8n8k4.py +384 -0
- nbxtensor/ops/flash_decode.py +78 -0
- nbxtensor/ops/flip_op.py +60 -0
- nbxtensor/ops/floor.py +90 -0
- nbxtensor/ops/full_op.py +24 -0
- nbxtensor/ops/fused_moe.py +417 -0
- nbxtensor/ops/fused_moe_m8n8k4.py +99 -0
- nbxtensor/ops/fused_upsample_conv.py +413 -0
- nbxtensor/ops/gather_op.py +52 -0
- nbxtensor/ops/ge.py +32 -0
- nbxtensor/ops/gelu.py +31 -0
- nbxtensor/ops/gemv_vec.py +80 -0
- nbxtensor/ops/glu.py +43 -0
- nbxtensor/ops/grid_sampler.py +145 -0
- nbxtensor/ops/group_norm_tiled.py +67 -0
- nbxtensor/ops/groupnorm.py +123 -0
- nbxtensor/ops/gt.py +32 -0
- nbxtensor/ops/hardsigmoid.py +18 -0
- nbxtensor/ops/hardswish.py +19 -0
- nbxtensor/ops/im2col.py +57 -0
- nbxtensor/ops/index_add.py +95 -0
- nbxtensor/ops/index_put_op.py +92 -0
- nbxtensor/ops/index_select.py +121 -0
- nbxtensor/ops/index_wrappers.py +770 -0
- nbxtensor/ops/isfinite.py +20 -0
- nbxtensor/ops/isinf.py +20 -0
- nbxtensor/ops/isnan.py +18 -0
- nbxtensor/ops/launch_keys.py +1054 -0
- nbxtensor/ops/launch_observer.py +54 -0
- nbxtensor/ops/layernorm.py +71 -0
- nbxtensor/ops/le.py +35 -0
- nbxtensor/ops/leaky_relu.py +19 -0
- nbxtensor/ops/lerp.py +76 -0
- nbxtensor/ops/linalg_wrappers.py +1370 -0
- nbxtensor/ops/linspace_op.py +47 -0
- nbxtensor/ops/log.py +17 -0
- nbxtensor/ops/log_sigmoid.py +23 -0
- nbxtensor/ops/logical_and.py +26 -0
- nbxtensor/ops/logical_not.py +24 -0
- nbxtensor/ops/logical_or.py +26 -0
- nbxtensor/ops/logical_xor.py +37 -0
- nbxtensor/ops/loss_wrappers.py +282 -0
- nbxtensor/ops/lt.py +32 -0
- nbxtensor/ops/masked_fill.py +21 -0
- nbxtensor/ops/matmul.py +377 -0
- nbxtensor/ops/matmul_m8n8k4.py +235 -0
- nbxtensor/ops/max_pool2d.py +74 -0
- nbxtensor/ops/max_pool3d.py +93 -0
- nbxtensor/ops/max_reduce.py +91 -0
- nbxtensor/ops/maximum.py +18 -0
- nbxtensor/ops/mean.py +40 -0
- nbxtensor/ops/min_reduce.py +91 -0
- nbxtensor/ops/minimum.py +18 -0
- nbxtensor/ops/mish.py +22 -0
- nbxtensor/ops/mma_m8n8k4.py +152 -0
- nbxtensor/ops/moe_align.py +195 -0
- nbxtensor/ops/moe_decode_vec.py +374 -0
- nbxtensor/ops/moe_device_residency.py +141 -0
- nbxtensor/ops/moe_wrappers.py +345 -0
- nbxtensor/ops/mse_loss.py +79 -0
- nbxtensor/ops/mul.py +51 -0
- nbxtensor/ops/nan_to_num.py +23 -0
- nbxtensor/ops/ne.py +32 -0
- nbxtensor/ops/neg.py +17 -0
- nbxtensor/ops/nllloss.py +124 -0
- nbxtensor/ops/nonzero.py +33 -0
- nbxtensor/ops/nonzero_op.py +62 -0
- nbxtensor/ops/norm_wrappers.py +579 -0
- nbxtensor/ops/ones_op.py +20 -0
- nbxtensor/ops/oracles/__init__.py +6 -0
- nbxtensor/ops/oracles/conv2d_fp64.py +450 -0
- nbxtensor/ops/pad_op.py +159 -0
- nbxtensor/ops/paged_decode_attn.py +215 -0
- nbxtensor/ops/pixel_shuffle.py +144 -0
- nbxtensor/ops/pixel_unshuffle.py +72 -0
- nbxtensor/ops/pow.py +137 -0
- nbxtensor/ops/prod.py +81 -0
- nbxtensor/ops/rand_op.py +52 -0
- nbxtensor/ops/random_wrappers.py +366 -0
- nbxtensor/ops/reciprocal.py +17 -0
- nbxtensor/ops/reduction_wrappers.py +845 -0
- nbxtensor/ops/relu.py +18 -0
- nbxtensor/ops/remainder.py +46 -0
- nbxtensor/ops/repeat_interleave.py +48 -0
- nbxtensor/ops/repeat_op.py +132 -0
- nbxtensor/ops/residual_chain.py +374 -0
- nbxtensor/ops/rmsnorm.py +68 -0
- nbxtensor/ops/rope.py +142 -0
- nbxtensor/ops/rsqrt.py +17 -0
- nbxtensor/ops/scaled_softmax.py +96 -0
- nbxtensor/ops/scatter_op.py +139 -0
- nbxtensor/ops/screen_oracle.py +479 -0
- nbxtensor/ops/selu.py +22 -0
- nbxtensor/ops/shape_wrappers.py +1032 -0
- nbxtensor/ops/sigmoid.py +19 -0
- nbxtensor/ops/silu.py +27 -0
- nbxtensor/ops/sin.py +17 -0
- nbxtensor/ops/softmax.py +169 -0
- nbxtensor/ops/softplus.py +27 -0
- nbxtensor/ops/sort_op.py +304 -0
- nbxtensor/ops/spectral_wrappers.py +481 -0
- nbxtensor/ops/sqrt.py +17 -0
- nbxtensor/ops/stack_op.py +84 -0
- nbxtensor/ops/std.py +113 -0
- nbxtensor/ops/strided_copy.py +200 -0
- nbxtensor/ops/sub.py +35 -0
- nbxtensor/ops/sum.py +40 -0
- nbxtensor/ops/tan.py +19 -0
- nbxtensor/ops/tanh.py +21 -0
- nbxtensor/ops/threshold.py +19 -0
- nbxtensor/ops/tiling.yml +91 -0
- nbxtensor/ops/tiling_policy.py +43 -0
- nbxtensor/ops/tiling_sizes.py +370 -0
- nbxtensor/ops/topk.py +267 -0
- nbxtensor/ops/trace_op.py +64 -0
- nbxtensor/ops/tril.py +64 -0
- nbxtensor/ops/triu.py +62 -0
- nbxtensor/ops/unfold_op.py +37 -0
- nbxtensor/ops/unique_op.py +97 -0
- nbxtensor/ops/upsample_bilinear2d.py +106 -0
- nbxtensor/ops/upsample_nearest2d.py +52 -0
- nbxtensor/ops/upsample_nearest3d.py +61 -0
- nbxtensor/ops/var.py +136 -0
- nbxtensor/ops/vector_norm.py +216 -0
- nbxtensor/ops/weight_norm.py +104 -0
- nbxtensor/ops/where.py +39 -0
- nbxtensor/ops/wrappers.py +825 -0
- nbxtensor/ops/zeros_op.py +20 -0
- nbxtensor/quant/__init__.py +1 -0
- nbxtensor/quant/quantized_tensor.py +187 -0
- nbxtensor/random/__init__.py +1 -0
- nbxtensor/random/mt_randn.py +154 -0
- nbxtensor/random/rng_pin.py +59 -0
- nbxtensor/random/rng_stream.py +118 -0
- nbxtensor/random/seeded_draw.py +223 -0
- nbxtensor/shape/__init__.py +157 -0
- nbxtensor/tensor.py +1867 -0
- nbxtensor-0.0.1.dist-info/METADATA +379 -0
- nbxtensor-0.0.1.dist-info/RECORD +291 -0
- nbxtensor-0.0.1.dist-info/WHEEL +4 -0
- nbxtensor-0.0.1.dist-info/licenses/LICENSE +189 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"""Vector norm — pure @triton.jit kernels.
|
|
2
|
+
|
|
3
|
+
Computes L2, L1, L0 (count non-zero), Linf (max abs), L-inf (min abs),
|
|
4
|
+
and general Lp norms.
|
|
5
|
+
|
|
6
|
+
Two kernel variants:
|
|
7
|
+
- Row-wise: input is [M, N], computes norm over N for each of M rows
|
|
8
|
+
- Flat (two-pass): input is flat [M], first pass reduces blocks, second
|
|
9
|
+
pass reduces block results to scalar
|
|
10
|
+
|
|
11
|
+
Extracted from FlagGems reference (vector_norm.py).
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import triton
|
|
15
|
+
import triton.language as tl
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# ---------------------------------------------------------------------------
|
|
19
|
+
# Row-wise kernels: input [M, N] -> output [M]
|
|
20
|
+
# ---------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
@triton.jit
|
|
23
|
+
def l2_norm_kernel(
|
|
24
|
+
X, Out,
|
|
25
|
+
M, N,
|
|
26
|
+
BLOCK_M: tl.constexpr,
|
|
27
|
+
BLOCK_N: tl.constexpr,
|
|
28
|
+
):
|
|
29
|
+
"""L2 norm per row: out[m] = sqrt(sum(x[m,:]^2))."""
|
|
30
|
+
pid = tl.program_id(0).to(tl.int64) * BLOCK_M + tl.arange(0, BLOCK_M)[:, None]
|
|
31
|
+
X = X + pid * N
|
|
32
|
+
Out = Out + pid
|
|
33
|
+
row_mask = pid < M
|
|
34
|
+
|
|
35
|
+
_sum = tl.zeros([BLOCK_M, BLOCK_N], dtype=tl.float32)
|
|
36
|
+
for off in range(0, N, BLOCK_N):
|
|
37
|
+
cols = off + tl.arange(0, BLOCK_N)[None, :]
|
|
38
|
+
col_mask = cols < N
|
|
39
|
+
mask = row_mask & col_mask
|
|
40
|
+
a = tl.load(X + cols, mask=mask, other=0.0).to(tl.float32)
|
|
41
|
+
_sum += a * a
|
|
42
|
+
|
|
43
|
+
s = tl.sum(_sum, axis=1)
|
|
44
|
+
out = tl.sqrt(s)[:, None]
|
|
45
|
+
tl.store(Out, out, mask=row_mask)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@triton.jit
|
|
49
|
+
def l1_norm_kernel(
|
|
50
|
+
X, Out,
|
|
51
|
+
M, N,
|
|
52
|
+
BLOCK_M: tl.constexpr,
|
|
53
|
+
BLOCK_N: tl.constexpr,
|
|
54
|
+
):
|
|
55
|
+
"""L1 norm per row: out[m] = sum(|x[m,:]|)."""
|
|
56
|
+
pid = tl.program_id(0).to(tl.int64) * BLOCK_M + tl.arange(0, BLOCK_M)[:, None]
|
|
57
|
+
X = X + pid * N
|
|
58
|
+
Out = Out + pid
|
|
59
|
+
row_mask = pid < M
|
|
60
|
+
|
|
61
|
+
_sum = tl.zeros([BLOCK_M, BLOCK_N], dtype=tl.float32)
|
|
62
|
+
for off in range(0, N, BLOCK_N):
|
|
63
|
+
cols = off + tl.arange(0, BLOCK_N)[None, :]
|
|
64
|
+
col_mask = cols < N
|
|
65
|
+
mask = row_mask & col_mask
|
|
66
|
+
a = tl.load(X + cols, mask=mask, other=0.0).to(tl.float32)
|
|
67
|
+
_sum += tl.abs(a)
|
|
68
|
+
|
|
69
|
+
s = tl.sum(_sum, axis=1)
|
|
70
|
+
out = s[:, None]
|
|
71
|
+
tl.store(Out, out, mask=row_mask)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@triton.jit
|
|
75
|
+
def linf_norm_kernel(
|
|
76
|
+
X, Out,
|
|
77
|
+
M, N,
|
|
78
|
+
BLOCK_M: tl.constexpr,
|
|
79
|
+
BLOCK_N: tl.constexpr,
|
|
80
|
+
):
|
|
81
|
+
"""L-infinity norm per row: out[m] = max(|x[m,:]|)."""
|
|
82
|
+
pid = tl.program_id(0).to(tl.int64) * BLOCK_M + tl.arange(0, BLOCK_M)[:, None]
|
|
83
|
+
X = X + pid * N
|
|
84
|
+
Out = Out + pid
|
|
85
|
+
row_mask = pid < M
|
|
86
|
+
|
|
87
|
+
_max = tl.zeros([BLOCK_M, BLOCK_N], dtype=tl.float32)
|
|
88
|
+
for off in range(0, N, BLOCK_N):
|
|
89
|
+
cols = off + tl.arange(0, BLOCK_N)[None, :]
|
|
90
|
+
col_mask = cols < N
|
|
91
|
+
mask = row_mask & col_mask
|
|
92
|
+
a = tl.load(X + cols, mask=mask, other=0.0).to(tl.float32)
|
|
93
|
+
_max = tl.maximum(tl.abs(a), _max)
|
|
94
|
+
|
|
95
|
+
m = tl.max(_max, axis=1)
|
|
96
|
+
out = m[:, None]
|
|
97
|
+
tl.store(Out, out, mask=row_mask)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@triton.jit
|
|
101
|
+
def l0_norm_kernel(
|
|
102
|
+
X, Out,
|
|
103
|
+
M, N,
|
|
104
|
+
BLOCK_M: tl.constexpr,
|
|
105
|
+
BLOCK_N: tl.constexpr,
|
|
106
|
+
):
|
|
107
|
+
"""L0 norm per row: out[m] = count(x[m,:] != 0)."""
|
|
108
|
+
pid = tl.program_id(0).to(tl.int64) * BLOCK_M + tl.arange(0, BLOCK_M)[:, None]
|
|
109
|
+
X = X + pid * N
|
|
110
|
+
Out = Out + pid
|
|
111
|
+
row_mask = pid < M
|
|
112
|
+
|
|
113
|
+
_sum = tl.zeros([BLOCK_M, BLOCK_N], dtype=tl.float32)
|
|
114
|
+
for off in range(0, N, BLOCK_N):
|
|
115
|
+
cols = off + tl.arange(0, BLOCK_N)[None, :]
|
|
116
|
+
col_mask = cols < N
|
|
117
|
+
mask = row_mask & col_mask
|
|
118
|
+
a = tl.load(X + cols, mask=mask, other=0.0).to(tl.float32)
|
|
119
|
+
_sum += tl.where(a != 0, 1.0, 0.0)
|
|
120
|
+
|
|
121
|
+
s = tl.sum(_sum, axis=1)
|
|
122
|
+
out = s[:, None]
|
|
123
|
+
tl.store(Out, out, mask=row_mask)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@triton.jit(do_not_specialize=['ord'])
|
|
127
|
+
def lp_norm_kernel(
|
|
128
|
+
X, Out,
|
|
129
|
+
M, N,
|
|
130
|
+
ord,
|
|
131
|
+
BLOCK_M: tl.constexpr,
|
|
132
|
+
BLOCK_N: tl.constexpr,
|
|
133
|
+
):
|
|
134
|
+
"""General Lp norm per row: out[m] = sum(|x[m,:]|^p)^(1/p)."""
|
|
135
|
+
pid = tl.program_id(0).to(tl.int64) * BLOCK_M + tl.arange(0, BLOCK_M)[:, None]
|
|
136
|
+
X = X + pid * N
|
|
137
|
+
Out = Out + pid
|
|
138
|
+
row_mask = pid < M
|
|
139
|
+
|
|
140
|
+
_sum = tl.zeros([BLOCK_M, BLOCK_N], dtype=tl.float32)
|
|
141
|
+
for off in range(0, N, BLOCK_N):
|
|
142
|
+
cols = off + tl.arange(0, BLOCK_N)[None, :]
|
|
143
|
+
col_mask = cols < N
|
|
144
|
+
mask = row_mask & col_mask
|
|
145
|
+
a = tl.load(X + cols, mask=mask, other=0.0).to(tl.float32)
|
|
146
|
+
# |a|**ord for ord > 0 and a >= 0: exp/log is exact enough and portable.
|
|
147
|
+
# `libdevice.pow` is NVIDIA-only and fails to lower elsewhere.
|
|
148
|
+
_sum += tl.exp(ord * tl.log(tl.abs(a) + 1e-38))
|
|
149
|
+
|
|
150
|
+
s = tl.sum(_sum, axis=1)
|
|
151
|
+
out = tl.exp((1.0 / ord) * tl.log(s + 1e-38))[:, None]
|
|
152
|
+
tl.store(Out, out, mask=row_mask)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
# ---------------------------------------------------------------------------
|
|
156
|
+
# Flat two-pass kernels: input [M] -> scalar
|
|
157
|
+
# ---------------------------------------------------------------------------
|
|
158
|
+
|
|
159
|
+
@triton.jit
|
|
160
|
+
def l2_norm_pass1_kernel(
|
|
161
|
+
X, Mid,
|
|
162
|
+
M,
|
|
163
|
+
BLOCK_SIZE: tl.constexpr,
|
|
164
|
+
):
|
|
165
|
+
"""First pass of flat L2 norm: each block computes partial sum of squares."""
|
|
166
|
+
pid = tl.program_id(0).to(tl.int64)
|
|
167
|
+
offset = pid.to(tl.int64) * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE) # 64-bit from the program id: the product itself wraps past 2^31 elements (register 58)
|
|
168
|
+
mask = offset < M
|
|
169
|
+
|
|
170
|
+
x = tl.load(X + offset, mask=mask, other=0.0).to(tl.float32)
|
|
171
|
+
mid = tl.sum(x * x)
|
|
172
|
+
tl.store(Mid + pid, mid)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
@triton.jit
|
|
176
|
+
def l2_norm_pass2_kernel(
|
|
177
|
+
Mid, Out,
|
|
178
|
+
MID_SIZE,
|
|
179
|
+
BLOCK_MID: tl.constexpr,
|
|
180
|
+
):
|
|
181
|
+
"""Second pass: reduce partial sums and take sqrt."""
|
|
182
|
+
offset = tl.arange(0, BLOCK_MID)
|
|
183
|
+
mask = offset < MID_SIZE
|
|
184
|
+
mid = tl.load(Mid + offset, mask=mask, other=0.0).to(tl.float32)
|
|
185
|
+
out = tl.sqrt(tl.sum(mid))
|
|
186
|
+
tl.store(Out, out)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@triton.jit
|
|
190
|
+
def linf_norm_pass1_kernel(
|
|
191
|
+
X, Mid,
|
|
192
|
+
M,
|
|
193
|
+
BLOCK_SIZE: tl.constexpr,
|
|
194
|
+
):
|
|
195
|
+
"""First pass of flat Linf norm: each block computes partial max abs."""
|
|
196
|
+
pid = tl.program_id(0).to(tl.int64)
|
|
197
|
+
offset = pid.to(tl.int64) * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE) # 64-bit from the program id: the product itself wraps past 2^31 elements (register 58)
|
|
198
|
+
mask = offset < M
|
|
199
|
+
|
|
200
|
+
x = tl.load(X + offset, mask=mask, other=0.0).to(tl.float32)
|
|
201
|
+
mid = tl.max(tl.abs(x))
|
|
202
|
+
tl.store(Mid + pid, mid)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
@triton.jit
|
|
206
|
+
def linf_norm_pass2_kernel(
|
|
207
|
+
Mid, Out,
|
|
208
|
+
MID_SIZE,
|
|
209
|
+
BLOCK_MID: tl.constexpr,
|
|
210
|
+
):
|
|
211
|
+
"""Second pass: reduce partial maxes."""
|
|
212
|
+
offset = tl.arange(0, BLOCK_MID)
|
|
213
|
+
mask = offset < MID_SIZE
|
|
214
|
+
mid = tl.load(Mid + offset, mask=mask, other=0.0).to(tl.float32)
|
|
215
|
+
out = tl.max(mid)
|
|
216
|
+
tl.store(Out, out)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""Weight normalization (_weight_norm_interface) — pure @triton.jit kernels.
|
|
2
|
+
|
|
3
|
+
Computes w = g * v / ||v|| where g is a per-channel gain scalar.
|
|
4
|
+
Two variants: norm along dim=0 ("first") and dim=last ("last").
|
|
5
|
+
|
|
6
|
+
Ported from FlagGems weightnorm.py. Stripped FlagGems decorators.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import triton
|
|
10
|
+
import triton.language as tl
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# ---- Forward: dim = 0 (norm along first dimension, one gain per row) ----
|
|
14
|
+
|
|
15
|
+
@triton.jit
|
|
16
|
+
def weight_norm_kernel_first(
|
|
17
|
+
output_ptr,
|
|
18
|
+
norm_ptr,
|
|
19
|
+
v_ptr,
|
|
20
|
+
g_ptr,
|
|
21
|
+
M,
|
|
22
|
+
N,
|
|
23
|
+
eps,
|
|
24
|
+
BLOCK_M: tl.constexpr,
|
|
25
|
+
BLOCK_N: tl.constexpr,
|
|
26
|
+
):
|
|
27
|
+
"""Weight norm forward, normalizing along dim=0 (rows).
|
|
28
|
+
|
|
29
|
+
v: [M, N], g: [M], norm: [M], output: [M, N]
|
|
30
|
+
Each program handles BLOCK_M rows.
|
|
31
|
+
"""
|
|
32
|
+
ty = tl.arange(0, BLOCK_M)[:, None]
|
|
33
|
+
by = tl.program_id(0).to(tl.int64) * BLOCK_M
|
|
34
|
+
row_offset = by + ty
|
|
35
|
+
row_mask = row_offset < M
|
|
36
|
+
|
|
37
|
+
tx = tl.arange(0, BLOCK_N)[None, :]
|
|
38
|
+
|
|
39
|
+
# Pass 1: compute ||v|| per row
|
|
40
|
+
v_sq = tl.zeros([BLOCK_M, BLOCK_N], dtype=tl.float32)
|
|
41
|
+
for base in range(0, N, BLOCK_N):
|
|
42
|
+
col_offset = base + tx
|
|
43
|
+
mask = (col_offset < N) & row_mask
|
|
44
|
+
v_val = tl.load(v_ptr + row_offset * N + col_offset, mask=mask).to(tl.float32)
|
|
45
|
+
v_sq += v_val * v_val
|
|
46
|
+
|
|
47
|
+
norm_val = tl.sqrt(tl.sum(v_sq, axis=1) + eps)
|
|
48
|
+
tl.store(norm_ptr + row_offset, norm_val[:, None], mask=row_mask)
|
|
49
|
+
g_val = tl.load(g_ptr + row_offset, mask=row_mask).to(tl.float32)
|
|
50
|
+
|
|
51
|
+
# Pass 2: output = g * v / ||v||
|
|
52
|
+
for base in range(0, N, BLOCK_N):
|
|
53
|
+
col_offset = base + tx
|
|
54
|
+
mask = (col_offset < N) & row_mask
|
|
55
|
+
v_val = tl.load(v_ptr + row_offset * N + col_offset, mask=mask).to(tl.float32)
|
|
56
|
+
out = (v_val / norm_val[:, None]) * g_val
|
|
57
|
+
tl.store(output_ptr + row_offset * N + col_offset, out, mask=mask)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# ---- Forward: dim = last (norm along last dimension, one gain per column) ----
|
|
61
|
+
|
|
62
|
+
@triton.jit
|
|
63
|
+
def weight_norm_kernel_last(
|
|
64
|
+
output_ptr,
|
|
65
|
+
norm_ptr,
|
|
66
|
+
v_ptr,
|
|
67
|
+
g_ptr,
|
|
68
|
+
M,
|
|
69
|
+
N,
|
|
70
|
+
eps,
|
|
71
|
+
BLOCK_M: tl.constexpr,
|
|
72
|
+
BLOCK_N: tl.constexpr,
|
|
73
|
+
):
|
|
74
|
+
"""Weight norm forward, normalizing along last dim (columns).
|
|
75
|
+
|
|
76
|
+
v: [M, N], g: [N], norm: [N], output: [M, N]
|
|
77
|
+
Each program handles BLOCK_N columns.
|
|
78
|
+
"""
|
|
79
|
+
tx = tl.arange(0, BLOCK_N)[:, None]
|
|
80
|
+
bx = tl.program_id(0).to(tl.int64) * BLOCK_N
|
|
81
|
+
col_offset = bx + tx
|
|
82
|
+
col_mask = col_offset < N
|
|
83
|
+
|
|
84
|
+
ty = tl.arange(0, BLOCK_M)[None, :]
|
|
85
|
+
|
|
86
|
+
# Pass 1: compute ||v|| per column
|
|
87
|
+
v_sq = tl.zeros([BLOCK_N, BLOCK_M], dtype=tl.float32)
|
|
88
|
+
for base in range(0, M, BLOCK_M):
|
|
89
|
+
row_offset = base + ty
|
|
90
|
+
mask = (row_offset < M) & col_mask
|
|
91
|
+
v_val = tl.load(v_ptr + row_offset * N + col_offset, mask=mask).to(tl.float32)
|
|
92
|
+
v_sq += v_val * v_val
|
|
93
|
+
|
|
94
|
+
norm_val = tl.sqrt(tl.sum(v_sq, axis=1) + eps)
|
|
95
|
+
tl.store(norm_ptr + col_offset, norm_val[:, None], mask=col_mask)
|
|
96
|
+
g_val = tl.load(g_ptr + col_offset, mask=col_mask).to(tl.float32)
|
|
97
|
+
|
|
98
|
+
# Pass 2: output = g * v / ||v||
|
|
99
|
+
for base in range(0, M, BLOCK_M):
|
|
100
|
+
row_offset = base + ty
|
|
101
|
+
mask = (row_offset < M) & col_mask
|
|
102
|
+
v_val = tl.load(v_ptr + row_offset * N + col_offset, mask=mask).to(tl.float32)
|
|
103
|
+
out = (v_val / norm_val[:, None]) * g_val
|
|
104
|
+
tl.store(output_ptr + row_offset * N + col_offset, out, mask=mask)
|
nbxtensor/ops/where.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Where — pure @triton.jit kernel."""
|
|
2
|
+
|
|
3
|
+
import triton
|
|
4
|
+
import triton.language as tl
|
|
5
|
+
|
|
6
|
+
@triton.jit
|
|
7
|
+
def where_forward_kernel(
|
|
8
|
+
cond_ptr, x_ptr, y_ptr, output_ptr,
|
|
9
|
+
n_elements,
|
|
10
|
+
BLOCK_SIZE: tl.constexpr,
|
|
11
|
+
):
|
|
12
|
+
"""out = where(cond, x, y)"""
|
|
13
|
+
pid = tl.program_id(0).to(tl.int64)
|
|
14
|
+
offset = pid.to(tl.int64) * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE) # 64-bit from the program id: the product itself wraps past 2^31 elements (register 58)
|
|
15
|
+
mask = offset < n_elements
|
|
16
|
+
|
|
17
|
+
cond = tl.load(cond_ptr + offset, mask=mask)
|
|
18
|
+
x = tl.load(x_ptr + offset, mask=mask)
|
|
19
|
+
y = tl.load(y_ptr + offset, mask=mask)
|
|
20
|
+
# `.to(tl.int1)` and not `cond` alone: a boolean crosses the NBX boundary in
|
|
21
|
+
# a uint8 container (that is how a bool tensor is stored), so the loaded
|
|
22
|
+
# value is an INTEGER. `tl.where` accepts that today with a deprecation
|
|
23
|
+
# warning and will raise on it in a future version — one of the two
|
|
24
|
+
# scheduled breakages a user's A40 report surfaced, four warnings per run.
|
|
25
|
+
#
|
|
26
|
+
# This is a forward-compatibility edit and it changes NO instruction: the
|
|
27
|
+
# cast `tl.where` already performed internally on a non-boolean condition is
|
|
28
|
+
# `not_equal(x, null_of(x.dtype))` (semantic.py, the is_bool() branch of
|
|
29
|
+
# cast), which is exactly what `.to(tl.int1)` emits. Proven, not asserted —
|
|
30
|
+
# the TTIR is identical to the pre-edit form
|
|
31
|
+
# (`tools/kernel_boolean_ir_equality.py`).
|
|
32
|
+
#
|
|
33
|
+
# Why NOT `cond != 0`, which was the first form written here: the Python
|
|
34
|
+
# literal `0` promotes to i32, so the comparison gains an `arith.extsi`
|
|
35
|
+
# i8 -> i32 on every element before it. Same boolean for every input —
|
|
36
|
+
# extsi maps 0 to 0 and is injective — but one extra elementwise op, on the
|
|
37
|
+
# kernel that 39 of the 56 local containers reach. "Costs nothing" was a
|
|
38
|
+
# claim nobody had checked; the instrument checked it.
|
|
39
|
+
tl.store(output_ptr + offset, tl.where(cond.to(tl.int1), x, y), mask=mask)
|