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,54 @@
|
|
|
1
|
+
"""An optional observer of kernel launches, and a dry-run mode behind it.
|
|
2
|
+
|
|
3
|
+
An application may install ONE observer (`set_launch_observer`). Every autotuned launch hands its key to
|
|
4
|
+
`record(tuned, key)`, live or dry (an application's record of the keys a run forms). While `active()` answers True the
|
|
5
|
+
library runs dry: an autotuned kernel launches nothing — it calls `shadow_run(...)` in place of the benchmark and the
|
|
6
|
+
launch — and a count the library would read back from the device is taken from the operation's own contract instead
|
|
7
|
+
(`index_wrappers.nonzero_1d_wrapper`). This is how an application enumerates the kernel keys a model forms without a
|
|
8
|
+
device (NeuroBrix: its certification census).
|
|
9
|
+
|
|
10
|
+
With no observer installed, or one whose `active()` answers False, nothing changes: every launch runs. The observer is
|
|
11
|
+
read at call time, never cached, so one installed after the kernels were defined is the one consulted.
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from typing import Any, Optional
|
|
16
|
+
|
|
17
|
+
__all__ = ["set_launch_observer", "launch_observer"]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class _NoObserver:
|
|
21
|
+
"""No observer: never dry, records nothing."""
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def active() -> bool:
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def record(tuned, key) -> None:
|
|
29
|
+
return None # every launch is offered to the observer; with none, nothing observes it
|
|
30
|
+
|
|
31
|
+
@staticmethod
|
|
32
|
+
def shadow_run(*args, **kwargs):
|
|
33
|
+
raise RuntimeError("nbxtensor: a dry run was asked with no launch observer installed")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
_OBSERVER: Any = _NoObserver
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def set_launch_observer(observer: Optional[Any]) -> None:
|
|
40
|
+
"""Install `observer` (an object with `active()`, `record(tuned, key)` and `shadow_run(*args, **kwargs)`), or remove
|
|
41
|
+
it (None). Installing one with a missing method is refused by name."""
|
|
42
|
+
global _OBSERVER
|
|
43
|
+
if observer is None:
|
|
44
|
+
_OBSERVER = _NoObserver
|
|
45
|
+
return
|
|
46
|
+
missing = [m for m in ("active", "record", "shadow_run") if not callable(getattr(observer, m, None))]
|
|
47
|
+
if missing:
|
|
48
|
+
raise TypeError(f"set_launch_observer: the observer has no callable {', '.join(missing)}")
|
|
49
|
+
_OBSERVER = observer
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def launch_observer():
|
|
53
|
+
"""The observer in force (the no-observer when none is installed)."""
|
|
54
|
+
return _OBSERVER
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""LayerNorm — pure @triton.jit kernel. Ported from attorch (MIT)."""
|
|
2
|
+
|
|
3
|
+
import triton
|
|
4
|
+
import triton.language as tl
|
|
5
|
+
from triton import next_power_of_2
|
|
6
|
+
|
|
7
|
+
from nbxtensor.ops._configs import nbx_autotune, row_program_configs, prune_row_programs
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# rows per program and warps: the certified configuration of the key (workstream 1), the key the derived census forms
|
|
11
|
+
# (`launch_keys.layer_norm_launches`)
|
|
12
|
+
@nbx_autotune(configs=row_program_configs(), key=['BATCH_BUCKET', 'FEAT_BUCKET', 'scale_by_weight', 'add_bias', 'save_stats'],
|
|
13
|
+
prune_configs_by={'early_config_prune': prune_row_programs}, cache_results=True)
|
|
14
|
+
@triton.heuristics({
|
|
15
|
+
'BLOCK_SIZE_FEAT': lambda args: next_power_of_2(args['feat_dim']),
|
|
16
|
+
})
|
|
17
|
+
@triton.jit
|
|
18
|
+
def layer_norm_forward_kernel(
|
|
19
|
+
input_ptr, weight_ptr, bias_ptr,
|
|
20
|
+
mean_ptr, inv_std_ptr, output_ptr,
|
|
21
|
+
batch_dim, feat_dim, BATCH_BUCKET, FEAT_BUCKET,
|
|
22
|
+
input_batch_stride, input_feat_stride,
|
|
23
|
+
output_batch_stride, output_feat_stride,
|
|
24
|
+
eps,
|
|
25
|
+
scale_by_weight: tl.constexpr,
|
|
26
|
+
add_bias: tl.constexpr,
|
|
27
|
+
save_stats: tl.constexpr,
|
|
28
|
+
BLOCK_SIZE_BATCH: tl.constexpr,
|
|
29
|
+
BLOCK_SIZE_FEAT: tl.constexpr,
|
|
30
|
+
):
|
|
31
|
+
"""Layer normalization forward.
|
|
32
|
+
|
|
33
|
+
input: [batch_dim, feat_dim]
|
|
34
|
+
weight: [feat_dim] (optional)
|
|
35
|
+
bias: [feat_dim] (optional)
|
|
36
|
+
output: [batch_dim, feat_dim]
|
|
37
|
+
mean, inv_std: [batch_dim] (optional, for backward)
|
|
38
|
+
"""
|
|
39
|
+
batch_pid = tl.program_id(0).to(tl.int64)
|
|
40
|
+
|
|
41
|
+
batch_offset = batch_pid * BLOCK_SIZE_BATCH + tl.arange(0, BLOCK_SIZE_BATCH)
|
|
42
|
+
feat_offset = tl.arange(0, BLOCK_SIZE_FEAT)
|
|
43
|
+
|
|
44
|
+
batch_mask = batch_offset < batch_dim
|
|
45
|
+
feat_mask = feat_offset < feat_dim
|
|
46
|
+
|
|
47
|
+
input_ptr += (input_batch_stride * batch_offset[:, None] +
|
|
48
|
+
input_feat_stride * feat_offset[None, :])
|
|
49
|
+
output_ptr += (output_batch_stride * batch_offset[:, None] +
|
|
50
|
+
output_feat_stride * feat_offset[None, :])
|
|
51
|
+
|
|
52
|
+
inp = tl.load(input_ptr,
|
|
53
|
+
mask=batch_mask[:, None] & feat_mask[None, :]).to(tl.float32)
|
|
54
|
+
mean = tl.sum(inp, axis=1) / feat_dim
|
|
55
|
+
diff = tl.where(feat_mask[None, :], inp - mean[:, None], 0)
|
|
56
|
+
inv_std = tl.rsqrt(tl.sum(diff * diff, axis=1) / feat_dim + eps)
|
|
57
|
+
|
|
58
|
+
if save_stats:
|
|
59
|
+
tl.store(mean_ptr + batch_offset, mean, mask=batch_mask)
|
|
60
|
+
tl.store(inv_std_ptr + batch_offset, inv_std, mask=batch_mask)
|
|
61
|
+
|
|
62
|
+
output = diff * inv_std[:, None]
|
|
63
|
+
if scale_by_weight:
|
|
64
|
+
weight = tl.load(weight_ptr + feat_offset, mask=feat_mask)
|
|
65
|
+
output *= weight
|
|
66
|
+
if add_bias:
|
|
67
|
+
bias = tl.load(bias_ptr + feat_offset, mask=feat_mask)
|
|
68
|
+
output += bias
|
|
69
|
+
|
|
70
|
+
tl.store(output_ptr, output,
|
|
71
|
+
mask=batch_mask[:, None] & feat_mask[None, :])
|
nbxtensor/ops/le.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Less than or equal — pure @triton.jit kernel.
|
|
2
|
+
|
|
3
|
+
Logic from FlagGems le.py. Both tensor-tensor and scalar variants.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import triton
|
|
7
|
+
import triton.language as tl
|
|
8
|
+
|
|
9
|
+
@triton.jit
|
|
10
|
+
def le_forward_kernel(
|
|
11
|
+
x_ptr, y_ptr, output_ptr,
|
|
12
|
+
n_elements,
|
|
13
|
+
BLOCK_SIZE: tl.constexpr,
|
|
14
|
+
):
|
|
15
|
+
pid = tl.program_id(0).to(tl.int64)
|
|
16
|
+
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)
|
|
17
|
+
mask = offset < n_elements
|
|
18
|
+
|
|
19
|
+
x = tl.load(x_ptr + offset, mask=mask)
|
|
20
|
+
y = tl.load(y_ptr + offset, mask=mask)
|
|
21
|
+
tl.store(output_ptr + offset, (x.to(tl.float32) <= y.to(tl.float32)).to(tl.int1), mask=mask)
|
|
22
|
+
|
|
23
|
+
@triton.jit
|
|
24
|
+
def le_scalar_kernel(
|
|
25
|
+
x_ptr, output_ptr,
|
|
26
|
+
n_elements,
|
|
27
|
+
scalar,
|
|
28
|
+
BLOCK_SIZE: tl.constexpr,
|
|
29
|
+
):
|
|
30
|
+
pid = tl.program_id(0).to(tl.int64)
|
|
31
|
+
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)
|
|
32
|
+
mask = offset < n_elements
|
|
33
|
+
|
|
34
|
+
x = tl.load(x_ptr + offset, mask=mask)
|
|
35
|
+
tl.store(output_ptr + offset, (x.to(tl.float32) <= scalar).to(tl.int1), mask=mask)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Leaky ReLU — pure @triton.jit kernel."""
|
|
2
|
+
|
|
3
|
+
import triton
|
|
4
|
+
import triton.language as tl
|
|
5
|
+
|
|
6
|
+
@triton.jit
|
|
7
|
+
def leaky_relu_forward_kernel(
|
|
8
|
+
input_ptr, output_ptr,
|
|
9
|
+
n_elements,
|
|
10
|
+
negative_slope,
|
|
11
|
+
BLOCK_SIZE: tl.constexpr,
|
|
12
|
+
):
|
|
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
|
+
x = tl.load(input_ptr + offset, mask=mask)
|
|
18
|
+
out = tl.maximum(0, x) + negative_slope * tl.minimum(0, x)
|
|
19
|
+
tl.store(output_ptr + offset, out, mask=mask)
|
nbxtensor/ops/lerp.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Lerp (linear interpolation) kernel — extracted from FlagGems.
|
|
2
|
+
|
|
3
|
+
Pure Triton. ZERO PyTorch imports.
|
|
4
|
+
|
|
5
|
+
Tensor variant: result = where(|w| < 0.5, a + w*(b-a), b - (b-a)*(1-w))
|
|
6
|
+
Scalar variant (head): result = a + w*(b-a)
|
|
7
|
+
Scalar variant (tail): result = b - (b-a)*(1-w)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import triton
|
|
11
|
+
import triton.language as tl
|
|
12
|
+
|
|
13
|
+
@triton.jit
|
|
14
|
+
def lerp_tensor_forward_kernel(
|
|
15
|
+
input_ptr,
|
|
16
|
+
end_ptr,
|
|
17
|
+
weight_ptr,
|
|
18
|
+
output_ptr,
|
|
19
|
+
n_elements,
|
|
20
|
+
BLOCK_SIZE: tl.constexpr,
|
|
21
|
+
):
|
|
22
|
+
"""Lerp with tensor weight: numerically stable two-branch formula."""
|
|
23
|
+
pid = tl.program_id(0).to(tl.int64)
|
|
24
|
+
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)
|
|
25
|
+
mask = offset < n_elements
|
|
26
|
+
|
|
27
|
+
a = tl.load(input_ptr + offset, mask=mask)
|
|
28
|
+
b = tl.load(end_ptr + offset, mask=mask)
|
|
29
|
+
w = tl.load(weight_ptr + offset, mask=mask)
|
|
30
|
+
|
|
31
|
+
result = tl.where(
|
|
32
|
+
tl.abs(w) < 0.5,
|
|
33
|
+
a + w * (b - a),
|
|
34
|
+
b - (b - a) * (1 - w),
|
|
35
|
+
)
|
|
36
|
+
tl.store(output_ptr + offset, result, mask=mask)
|
|
37
|
+
|
|
38
|
+
@triton.jit
|
|
39
|
+
def lerp_scalar_head_kernel(
|
|
40
|
+
input_ptr,
|
|
41
|
+
end_ptr,
|
|
42
|
+
output_ptr,
|
|
43
|
+
n_elements,
|
|
44
|
+
weight,
|
|
45
|
+
BLOCK_SIZE: tl.constexpr,
|
|
46
|
+
):
|
|
47
|
+
"""Lerp with scalar weight < 0.5: a + w*(b-a)."""
|
|
48
|
+
pid = tl.program_id(0).to(tl.int64)
|
|
49
|
+
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)
|
|
50
|
+
mask = offset < n_elements
|
|
51
|
+
|
|
52
|
+
a = tl.load(input_ptr + offset, mask=mask)
|
|
53
|
+
b = tl.load(end_ptr + offset, mask=mask)
|
|
54
|
+
|
|
55
|
+
result = a + weight * (b - a)
|
|
56
|
+
tl.store(output_ptr + offset, result, mask=mask)
|
|
57
|
+
|
|
58
|
+
@triton.jit
|
|
59
|
+
def lerp_scalar_tail_kernel(
|
|
60
|
+
input_ptr,
|
|
61
|
+
end_ptr,
|
|
62
|
+
output_ptr,
|
|
63
|
+
n_elements,
|
|
64
|
+
weight,
|
|
65
|
+
BLOCK_SIZE: tl.constexpr,
|
|
66
|
+
):
|
|
67
|
+
"""Lerp with scalar weight >= 0.5: b - (b-a)*(1-w)."""
|
|
68
|
+
pid = tl.program_id(0).to(tl.int64)
|
|
69
|
+
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)
|
|
70
|
+
mask = offset < n_elements
|
|
71
|
+
|
|
72
|
+
a = tl.load(input_ptr + offset, mask=mask)
|
|
73
|
+
b = tl.load(end_ptr + offset, mask=mask)
|
|
74
|
+
|
|
75
|
+
result = b - (b - a) * (1 - weight)
|
|
76
|
+
tl.store(output_ptr + offset, result, mask=mask)
|