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
nbxtensor/ops/neg.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Negation — pure @triton.jit kernel."""
|
|
2
|
+
|
|
3
|
+
import triton
|
|
4
|
+
import triton.language as tl
|
|
5
|
+
|
|
6
|
+
@triton.jit
|
|
7
|
+
def neg_forward_kernel(
|
|
8
|
+
input_ptr, output_ptr,
|
|
9
|
+
n_elements,
|
|
10
|
+
BLOCK_SIZE: tl.constexpr,
|
|
11
|
+
):
|
|
12
|
+
pid = tl.program_id(0).to(tl.int64)
|
|
13
|
+
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)
|
|
14
|
+
mask = offset < n_elements
|
|
15
|
+
|
|
16
|
+
x = tl.load(input_ptr + offset, mask=mask)
|
|
17
|
+
tl.store(output_ptr + offset, -x, mask=mask)
|
nbxtensor/ops/nllloss.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""NLL Loss forward kernel — extracted from FlagGems.
|
|
2
|
+
|
|
3
|
+
Pure Triton. ZERO PyTorch imports.
|
|
4
|
+
|
|
5
|
+
NLL Loss: l_n = -w_{y_n} * x_{n, y_n}
|
|
6
|
+
|
|
7
|
+
Reduction modes:
|
|
8
|
+
0 = none: per-sample loss
|
|
9
|
+
1 = mean: weighted mean
|
|
10
|
+
2 = sum: weighted sum
|
|
11
|
+
|
|
12
|
+
The kernel handles ignore_index to skip certain targets.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import triton
|
|
16
|
+
import triton.language as tl
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@triton.jit
|
|
20
|
+
def nll_loss_forward_kernel(
|
|
21
|
+
inp_ptr,
|
|
22
|
+
tgt_ptr,
|
|
23
|
+
wgt_ptr,
|
|
24
|
+
out_ptr,
|
|
25
|
+
ignore_index,
|
|
26
|
+
N,
|
|
27
|
+
C,
|
|
28
|
+
reduction: tl.constexpr,
|
|
29
|
+
BLOCK_N: tl.constexpr,
|
|
30
|
+
):
|
|
31
|
+
"""NLL Loss forward for 1D/2D input [N, C].
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
inp_ptr: Log-probability input [N, C].
|
|
35
|
+
tgt_ptr: Target class indices [N].
|
|
36
|
+
wgt_ptr: Per-class weights [C] or None.
|
|
37
|
+
out_ptr: Output. Shape depends on reduction mode.
|
|
38
|
+
ignore_index: Target index to ignore.
|
|
39
|
+
N: Batch size.
|
|
40
|
+
C: Number of classes.
|
|
41
|
+
reduction: 0=none, 1=mean, 2=sum.
|
|
42
|
+
BLOCK_N: Block size for batch dimension.
|
|
43
|
+
"""
|
|
44
|
+
pid_n = tl.program_id(0).to(tl.int64)
|
|
45
|
+
offsets_n = pid_n * BLOCK_N + tl.arange(0, BLOCK_N)
|
|
46
|
+
mask_n = offsets_n < N
|
|
47
|
+
|
|
48
|
+
tgt = tl.load(tgt_ptr + offsets_n, mask=mask_n, other=0)
|
|
49
|
+
ignore_mask = (tgt != ignore_index) & mask_n
|
|
50
|
+
|
|
51
|
+
# Load per-class weight for target, or 1.0 if no weights
|
|
52
|
+
if wgt_ptr is None:
|
|
53
|
+
wgt_tgt = ignore_mask.to(tl.float32)
|
|
54
|
+
else:
|
|
55
|
+
wgt_tgt = tl.load(wgt_ptr + tgt, mask=ignore_mask, other=0).to(tl.float32)
|
|
56
|
+
|
|
57
|
+
# Gather input at target index: inp[n, tgt[n]]
|
|
58
|
+
inp_tgt_ptrs = inp_ptr + offsets_n * C + tgt
|
|
59
|
+
inp_tgt = tl.load(inp_tgt_ptrs, mask=ignore_mask, other=0).to(tl.float32)
|
|
60
|
+
out = inp_tgt * wgt_tgt * -1
|
|
61
|
+
|
|
62
|
+
# none
|
|
63
|
+
if reduction == 0:
|
|
64
|
+
tl.store(out_ptr + offsets_n, out, mask=mask_n)
|
|
65
|
+
# mean
|
|
66
|
+
elif reduction == 1:
|
|
67
|
+
total_out = tl.sum(out)
|
|
68
|
+
total_wgt = tl.sum(wgt_tgt)
|
|
69
|
+
tl.atomic_add(out_ptr, total_out, sem="relaxed")
|
|
70
|
+
tl.atomic_add(out_ptr + 1, total_wgt, sem="relaxed")
|
|
71
|
+
tl.atomic_add(out_ptr + 2, 1, sem="release")
|
|
72
|
+
counter = tl.load(out_ptr + 2)
|
|
73
|
+
if counter == tl.num_programs(0):
|
|
74
|
+
total_out = tl.load(out_ptr)
|
|
75
|
+
total_wgt = tl.load(out_ptr + 1)
|
|
76
|
+
tl.store(out_ptr + 3, total_out / total_wgt)
|
|
77
|
+
# sum
|
|
78
|
+
else:
|
|
79
|
+
total_out = tl.sum(out)
|
|
80
|
+
tl.atomic_add(out_ptr, total_out, sem="relaxed")
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@triton.jit
|
|
84
|
+
def nll_loss_backward_kernel(
|
|
85
|
+
out_grad_ptr,
|
|
86
|
+
tgt_ptr,
|
|
87
|
+
wgt_ptr,
|
|
88
|
+
inp_grad_ptr,
|
|
89
|
+
ignore_index,
|
|
90
|
+
total_weight,
|
|
91
|
+
N,
|
|
92
|
+
C,
|
|
93
|
+
reduction: tl.constexpr,
|
|
94
|
+
BLOCK_N: tl.constexpr,
|
|
95
|
+
):
|
|
96
|
+
"""NLL Loss backward for 1D/2D input [N, C].
|
|
97
|
+
|
|
98
|
+
Computes gradient w.r.t. input: grad_input[n, tgt[n]] = -w * grad_output / total_weight.
|
|
99
|
+
"""
|
|
100
|
+
pid_n = tl.program_id(0).to(tl.int64)
|
|
101
|
+
offsets_n = pid_n * BLOCK_N + tl.arange(0, BLOCK_N)
|
|
102
|
+
mask_n = offsets_n < N
|
|
103
|
+
|
|
104
|
+
tgt = tl.load(tgt_ptr + offsets_n, mask=mask_n, other=0)
|
|
105
|
+
ignore_mask = (tgt != ignore_index) & mask_n
|
|
106
|
+
|
|
107
|
+
if wgt_ptr is None:
|
|
108
|
+
wgt_tgt = ignore_mask.to(tl.float32)
|
|
109
|
+
else:
|
|
110
|
+
wgt_tgt = tl.load(wgt_ptr + tgt, mask=ignore_mask, other=0).to(tl.float32)
|
|
111
|
+
|
|
112
|
+
if reduction == 0:
|
|
113
|
+
out_grad = tl.load(out_grad_ptr + offsets_n, mask=mask_n, other=0).to(tl.float32)
|
|
114
|
+
else:
|
|
115
|
+
out_grad = tl.load(out_grad_ptr).to(tl.float32)
|
|
116
|
+
|
|
117
|
+
if reduction == 1:
|
|
118
|
+
total_w = tl.load(total_weight).to(tl.float32)
|
|
119
|
+
else:
|
|
120
|
+
total_w = 1
|
|
121
|
+
|
|
122
|
+
inp_grad = tl.where(ignore_mask, -1 * out_grad * wgt_tgt / total_w, 0)
|
|
123
|
+
inp_grad_ptrs = inp_grad_ptr + offsets_n * C + tgt
|
|
124
|
+
tl.store(inp_grad_ptrs, inp_grad, mask=mask_n)
|
nbxtensor/ops/nonzero.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""1-D boolean-mask compaction (nonzero) — pure @triton.jit kernel.
|
|
2
|
+
|
|
3
|
+
Deterministic by construction: a SINGLE program scans the mask in
|
|
4
|
+
BLOCK-sized chunks with an in-block tl.cumsum and a running cursor, so
|
|
5
|
+
the compacted indices are emitted in ascending order without atomics.
|
|
6
|
+
Mask sizes on this path are decode-control scale (visual/attention
|
|
7
|
+
masks, thousands of elements) — the serial-block scan costs
|
|
8
|
+
microseconds there and keeps the op bit-reproducible across runs.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import triton
|
|
12
|
+
import triton.language as tl
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@triton.jit
|
|
16
|
+
def nonzero_1d_kernel(
|
|
17
|
+
mask_ptr, out_ptr, count_ptr,
|
|
18
|
+
n_elements,
|
|
19
|
+
BLOCK_SIZE: tl.constexpr,
|
|
20
|
+
):
|
|
21
|
+
cursor = tl.zeros((1,), dtype=tl.int32)
|
|
22
|
+
for start in range(0, n_elements, BLOCK_SIZE):
|
|
23
|
+
offs = start + tl.arange(0, BLOCK_SIZE)
|
|
24
|
+
in_range = offs < n_elements
|
|
25
|
+
m = tl.load(mask_ptr + offs, mask=in_range, other=0)
|
|
26
|
+
pred = (m != 0) & in_range
|
|
27
|
+
p32 = pred.to(tl.int32)
|
|
28
|
+
excl = tl.cumsum(p32, axis=0) - p32
|
|
29
|
+
base = tl.sum(cursor, axis=0)
|
|
30
|
+
tl.store(out_ptr + (base + excl).to(tl.int64), offs.to(tl.int64),
|
|
31
|
+
mask=pred)
|
|
32
|
+
cursor += tl.sum(p32, axis=0)
|
|
33
|
+
tl.store(count_ptr, tl.sum(cursor, axis=0))
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Nonzero — pure @triton.jit kernel.
|
|
2
|
+
|
|
3
|
+
Extracts indices of non-zero elements from a flattened boolean tensor.
|
|
4
|
+
Requires a pre-computed prefix sum (cumsum of bool input) to determine
|
|
5
|
+
the output position of each non-zero element.
|
|
6
|
+
|
|
7
|
+
The Python wrapper must:
|
|
8
|
+
1. Flatten and convert to bool: inp_bool = (inp != 0)
|
|
9
|
+
2. Compute prefix sum: prefix_sum = inp_bool.cumsum(0)
|
|
10
|
+
3. Allocate output: out = empty(numel, ndim, dtype=int64)
|
|
11
|
+
4. Launch this kernel
|
|
12
|
+
5. Slice to actual count: out = out[:prefix_sum[-1]]
|
|
13
|
+
|
|
14
|
+
Extracted from FlagGems (Apache 2.0).
|
|
15
|
+
|
|
16
|
+
Grid: (ceil(n_elements / BLOCK_SIZE),)
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import triton
|
|
20
|
+
import triton.language as tl
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@triton.jit
|
|
24
|
+
def nonzero_kernel(
|
|
25
|
+
inp,
|
|
26
|
+
prefix_sum,
|
|
27
|
+
out,
|
|
28
|
+
n_elements,
|
|
29
|
+
shape,
|
|
30
|
+
ndim: tl.constexpr,
|
|
31
|
+
BLOCK_SIZE: tl.constexpr,
|
|
32
|
+
):
|
|
33
|
+
"""Write indices of non-zero elements into output tensor.
|
|
34
|
+
|
|
35
|
+
For each non-zero element at flat index i, decomposes i into
|
|
36
|
+
multi-dimensional indices using the original shape, then writes
|
|
37
|
+
each dimension's index into out[prefix_sum[i]-1, dim].
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
inp: flattened boolean input (1 = nonzero)
|
|
41
|
+
prefix_sum: cumulative sum of inp (1-based output position)
|
|
42
|
+
out: output tensor of shape (n_elements, ndim), int64
|
|
43
|
+
shape: original tensor shape stored as int32 on device
|
|
44
|
+
ndim: number of dimensions (compile-time constant)
|
|
45
|
+
"""
|
|
46
|
+
pid = tl.program_id(0).to(tl.int64)
|
|
47
|
+
|
|
48
|
+
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)
|
|
49
|
+
mask = offset < n_elements
|
|
50
|
+
|
|
51
|
+
inp_vals = tl.load(inp + offset, mask=mask).to(tl.int1)
|
|
52
|
+
out_offset = tl.load(prefix_sum + offset, mask=mask) - 1
|
|
53
|
+
|
|
54
|
+
nonzero_mask = mask & inp_vals
|
|
55
|
+
|
|
56
|
+
# Decompose flat index into multi-dimensional indices
|
|
57
|
+
idx_flat = offset
|
|
58
|
+
for dim in range(ndim - 1, -1, -1):
|
|
59
|
+
dim_size = tl.load(shape + dim)
|
|
60
|
+
remainder = idx_flat % dim_size
|
|
61
|
+
idx_flat = idx_flat // dim_size
|
|
62
|
+
tl.store(out + out_offset * ndim + dim, remainder, mask=nonzero_mask)
|