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.
Files changed (291) hide show
  1. nbxtensor/THIRD_PARTY_NOTICES.md +287 -0
  2. nbxtensor/__init__.py +17 -0
  3. nbxtensor/backend/__init__.py +1 -0
  4. nbxtensor/backend/capabilities.py +207 -0
  5. nbxtensor/backend/cpu/__init__.py +1 -0
  6. nbxtensor/backend/cpu/blas.py +102 -0
  7. nbxtensor/backend/cpu/pool.py +204 -0
  8. nbxtensor/backend/cpu_backend.py +162 -0
  9. nbxtensor/backend/device_facts.py +105 -0
  10. nbxtensor/backend/device_files.py +129 -0
  11. nbxtensor/backend/device_names.py +18 -0
  12. nbxtensor/backend/devices/amd/cdna.yml +228 -0
  13. nbxtensor/backend/devices/amd/cdna2.yml +228 -0
  14. nbxtensor/backend/devices/amd/cdna3.yml +227 -0
  15. nbxtensor/backend/devices/apple/apple_m1.yml +266 -0
  16. nbxtensor/backend/devices/apple/apple_m1_max.yml +266 -0
  17. nbxtensor/backend/devices/apple/apple_m1_pro.yml +266 -0
  18. nbxtensor/backend/devices/apple/apple_m1_ultra.yml +266 -0
  19. nbxtensor/backend/devices/apple/apple_m2.yml +266 -0
  20. nbxtensor/backend/devices/apple/apple_m2_max.yml +266 -0
  21. nbxtensor/backend/devices/apple/apple_m2_pro.yml +266 -0
  22. nbxtensor/backend/devices/apple/apple_m2_ultra.yml +266 -0
  23. nbxtensor/backend/devices/apple/apple_m3.yml +266 -0
  24. nbxtensor/backend/devices/apple/apple_m3_max.yml +266 -0
  25. nbxtensor/backend/devices/apple/apple_m3_pro.yml +266 -0
  26. nbxtensor/backend/devices/apple/apple_m3_ultra.yml +266 -0
  27. nbxtensor/backend/devices/apple/apple_m4.yml +266 -0
  28. nbxtensor/backend/devices/apple/apple_m4_max.yml +266 -0
  29. nbxtensor/backend/devices/apple/apple_m4_pro.yml +308 -0
  30. nbxtensor/backend/devices/apple/apple_m5.yml +269 -0
  31. nbxtensor/backend/devices/apple/apple_m5_max.yml +269 -0
  32. nbxtensor/backend/devices/apple/apple_m5_pro.yml +269 -0
  33. nbxtensor/backend/devices/apple/apple_m5_ultra.yml +269 -0
  34. nbxtensor/backend/devices/apple/apple_m6.yml +269 -0
  35. nbxtensor/backend/devices/apple/apple_silicon.yml +263 -0
  36. nbxtensor/backend/devices/nvidia/ampere.yml +214 -0
  37. nbxtensor/backend/devices/nvidia/hopper.yml +213 -0
  38. nbxtensor/backend/devices/nvidia/volta.yml +411 -0
  39. nbxtensor/backend/faults.py +151 -0
  40. nbxtensor/backend/host_memory.py +185 -0
  41. nbxtensor/backend/launcher.py +2350 -0
  42. nbxtensor/backend/launcher_contract.py +429 -0
  43. nbxtensor/backend/metal_backend.py +661 -0
  44. nbxtensor/backend/metal_device.py +1274 -0
  45. nbxtensor/backend/process_memory.py +73 -0
  46. nbxtensor/backend/replay_graph.py +322 -0
  47. nbxtensor/backend/runtime.py +409 -0
  48. nbxtensor/backend/triton_ext_driver.py +735 -0
  49. nbxtensor/dtype/__init__.py +1 -0
  50. nbxtensor/dtype/convert.py +107 -0
  51. nbxtensor/dtype/dtypes.yml +70 -0
  52. nbxtensor/dtype/itemsize.py +166 -0
  53. nbxtensor/dtype/nbx_dtype.py +72 -0
  54. nbxtensor/dtype/operands.py +158 -0
  55. nbxtensor/dtype/outputs.py +64 -0
  56. nbxtensor/dtype/policy.py +155 -0
  57. nbxtensor/dtype/policy.yml +51 -0
  58. nbxtensor/dtype/promotion.py +112 -0
  59. nbxtensor/host.py +55 -0
  60. nbxtensor/io/__init__.py +1 -0
  61. nbxtensor/io/read_rate.py +197 -0
  62. nbxtensor/io/safetensors.py +314 -0
  63. nbxtensor/memory/__init__.py +9 -0
  64. nbxtensor/memory/allocator.py +1988 -0
  65. nbxtensor/memory/arena.py +75 -0
  66. nbxtensor/memory/device_memory.py +150 -0
  67. nbxtensor/memory/device_transfer.py +154 -0
  68. nbxtensor/memory/layout.py +43 -0
  69. nbxtensor/memory/memory_pool.py +191 -0
  70. nbxtensor/memory/metal.py +96 -0
  71. nbxtensor/memory/oom_advice.py +91 -0
  72. nbxtensor/memory/pointer_tables.py +323 -0
  73. nbxtensor/memory/pool.py +507 -0
  74. nbxtensor/memory/shadow.py +43 -0
  75. nbxtensor/memory/slab.py +273 -0
  76. nbxtensor/memory/trace_replay.py +122 -0
  77. nbxtensor/memory/traces/sana-video-2b-720p.16g.2026-11-02.tsv +13610 -0
  78. nbxtensor/memory/vmm.py +118 -0
  79. nbxtensor/ops/__init__.py +1 -0
  80. nbxtensor/ops/_autotune_policy.py +90 -0
  81. nbxtensor/ops/_common.py +32 -0
  82. nbxtensor/ops/_configs.py +1041 -0
  83. nbxtensor/ops/_cost.py +231 -0
  84. nbxtensor/ops/abs.py +17 -0
  85. nbxtensor/ops/adaptive_avg_pool2d.py +161 -0
  86. nbxtensor/ops/add.py +96 -0
  87. nbxtensor/ops/addcdiv.py +29 -0
  88. nbxtensor/ops/addcmul.py +29 -0
  89. nbxtensor/ops/addmv_op.py +64 -0
  90. nbxtensor/ops/addr.py +68 -0
  91. nbxtensor/ops/all_reduce.py +83 -0
  92. nbxtensor/ops/amax.py +40 -0
  93. nbxtensor/ops/any_reduce.py +83 -0
  94. nbxtensor/ops/arange_op.py +27 -0
  95. nbxtensor/ops/argmax.py +107 -0
  96. nbxtensor/ops/argmin.py +93 -0
  97. nbxtensor/ops/atan2.py +71 -0
  98. nbxtensor/ops/attention_wrappers.py +1648 -0
  99. nbxtensor/ops/autotune_bucket.py +137 -0
  100. nbxtensor/ops/autotune_cache.py +430 -0
  101. nbxtensor/ops/autotune_certified.py +1262 -0
  102. nbxtensor/ops/autotune_refusals.py +380 -0
  103. nbxtensor/ops/autotune_settings.py +58 -0
  104. nbxtensor/ops/avg_pool2d.py +73 -0
  105. nbxtensor/ops/baddbmm_op.py +132 -0
  106. nbxtensor/ops/batch_norm.py +163 -0
  107. nbxtensor/ops/binary_strided.py +196 -0
  108. nbxtensor/ops/bitwise_and.py +26 -0
  109. nbxtensor/ops/bitwise_left_shift.py +47 -0
  110. nbxtensor/ops/bitwise_not.py +24 -0
  111. nbxtensor/ops/bitwise_or.py +26 -0
  112. nbxtensor/ops/bitwise_right_shift.py +47 -0
  113. nbxtensor/ops/bucketize.py +37 -0
  114. nbxtensor/ops/cat_op.py +87 -0
  115. nbxtensor/ops/celu.py +20 -0
  116. nbxtensor/ops/clamp.py +24 -0
  117. nbxtensor/ops/clamp_min.py +22 -0
  118. nbxtensor/ops/conv2d.py +265 -0
  119. nbxtensor/ops/conv2d_m8n8k4.py +165 -0
  120. nbxtensor/ops/conv_depthwise2d.py +154 -0
  121. nbxtensor/ops/conv_transpose2d.py +148 -0
  122. nbxtensor/ops/conv_wrappers.py +1482 -0
  123. nbxtensor/ops/copy.py +18 -0
  124. nbxtensor/ops/copy_op.py +39 -0
  125. nbxtensor/ops/cos.py +17 -0
  126. nbxtensor/ops/count_nonzero.py +64 -0
  127. nbxtensor/ops/cross_entropy.py +67 -0
  128. nbxtensor/ops/cummax.py +109 -0
  129. nbxtensor/ops/cummin.py +105 -0
  130. nbxtensor/ops/cumsum.py +244 -0
  131. nbxtensor/ops/decode_attn_vec.py +162 -0
  132. nbxtensor/ops/depthwise_conv2d.py +132 -0
  133. nbxtensor/ops/dequant_gemv.py +190 -0
  134. nbxtensor/ops/dft.py +67 -0
  135. nbxtensor/ops/dispatch.py +1228 -0
  136. nbxtensor/ops/div.py +75 -0
  137. nbxtensor/ops/dot_op.py +67 -0
  138. nbxtensor/ops/dropout.py +23 -0
  139. nbxtensor/ops/dtype_convert.py +42 -0
  140. nbxtensor/ops/elementwise_launch.py +81 -0
  141. nbxtensor/ops/elementwise_wrappers.py +2315 -0
  142. nbxtensor/ops/elu.py +20 -0
  143. nbxtensor/ops/embedding.py +69 -0
  144. nbxtensor/ops/eq.py +32 -0
  145. nbxtensor/ops/erf.py +18 -0
  146. nbxtensor/ops/exp.py +17 -0
  147. nbxtensor/ops/exp2.py +18 -0
  148. nbxtensor/ops/fft_op.py +125 -0
  149. nbxtensor/ops/fill_op.py +20 -0
  150. nbxtensor/ops/flash_attention.py +307 -0
  151. nbxtensor/ops/flash_attention_m8n8k4.py +384 -0
  152. nbxtensor/ops/flash_decode.py +78 -0
  153. nbxtensor/ops/flip_op.py +60 -0
  154. nbxtensor/ops/floor.py +90 -0
  155. nbxtensor/ops/full_op.py +24 -0
  156. nbxtensor/ops/fused_moe.py +417 -0
  157. nbxtensor/ops/fused_moe_m8n8k4.py +99 -0
  158. nbxtensor/ops/fused_upsample_conv.py +413 -0
  159. nbxtensor/ops/gather_op.py +52 -0
  160. nbxtensor/ops/ge.py +32 -0
  161. nbxtensor/ops/gelu.py +31 -0
  162. nbxtensor/ops/gemv_vec.py +80 -0
  163. nbxtensor/ops/glu.py +43 -0
  164. nbxtensor/ops/grid_sampler.py +145 -0
  165. nbxtensor/ops/group_norm_tiled.py +67 -0
  166. nbxtensor/ops/groupnorm.py +123 -0
  167. nbxtensor/ops/gt.py +32 -0
  168. nbxtensor/ops/hardsigmoid.py +18 -0
  169. nbxtensor/ops/hardswish.py +19 -0
  170. nbxtensor/ops/im2col.py +57 -0
  171. nbxtensor/ops/index_add.py +95 -0
  172. nbxtensor/ops/index_put_op.py +92 -0
  173. nbxtensor/ops/index_select.py +121 -0
  174. nbxtensor/ops/index_wrappers.py +770 -0
  175. nbxtensor/ops/isfinite.py +20 -0
  176. nbxtensor/ops/isinf.py +20 -0
  177. nbxtensor/ops/isnan.py +18 -0
  178. nbxtensor/ops/launch_keys.py +1054 -0
  179. nbxtensor/ops/launch_observer.py +54 -0
  180. nbxtensor/ops/layernorm.py +71 -0
  181. nbxtensor/ops/le.py +35 -0
  182. nbxtensor/ops/leaky_relu.py +19 -0
  183. nbxtensor/ops/lerp.py +76 -0
  184. nbxtensor/ops/linalg_wrappers.py +1370 -0
  185. nbxtensor/ops/linspace_op.py +47 -0
  186. nbxtensor/ops/log.py +17 -0
  187. nbxtensor/ops/log_sigmoid.py +23 -0
  188. nbxtensor/ops/logical_and.py +26 -0
  189. nbxtensor/ops/logical_not.py +24 -0
  190. nbxtensor/ops/logical_or.py +26 -0
  191. nbxtensor/ops/logical_xor.py +37 -0
  192. nbxtensor/ops/loss_wrappers.py +282 -0
  193. nbxtensor/ops/lt.py +32 -0
  194. nbxtensor/ops/masked_fill.py +21 -0
  195. nbxtensor/ops/matmul.py +377 -0
  196. nbxtensor/ops/matmul_m8n8k4.py +235 -0
  197. nbxtensor/ops/max_pool2d.py +74 -0
  198. nbxtensor/ops/max_pool3d.py +93 -0
  199. nbxtensor/ops/max_reduce.py +91 -0
  200. nbxtensor/ops/maximum.py +18 -0
  201. nbxtensor/ops/mean.py +40 -0
  202. nbxtensor/ops/min_reduce.py +91 -0
  203. nbxtensor/ops/minimum.py +18 -0
  204. nbxtensor/ops/mish.py +22 -0
  205. nbxtensor/ops/mma_m8n8k4.py +152 -0
  206. nbxtensor/ops/moe_align.py +195 -0
  207. nbxtensor/ops/moe_decode_vec.py +374 -0
  208. nbxtensor/ops/moe_device_residency.py +141 -0
  209. nbxtensor/ops/moe_wrappers.py +345 -0
  210. nbxtensor/ops/mse_loss.py +79 -0
  211. nbxtensor/ops/mul.py +51 -0
  212. nbxtensor/ops/nan_to_num.py +23 -0
  213. nbxtensor/ops/ne.py +32 -0
  214. nbxtensor/ops/neg.py +17 -0
  215. nbxtensor/ops/nllloss.py +124 -0
  216. nbxtensor/ops/nonzero.py +33 -0
  217. nbxtensor/ops/nonzero_op.py +62 -0
  218. nbxtensor/ops/norm_wrappers.py +579 -0
  219. nbxtensor/ops/ones_op.py +20 -0
  220. nbxtensor/ops/oracles/__init__.py +6 -0
  221. nbxtensor/ops/oracles/conv2d_fp64.py +450 -0
  222. nbxtensor/ops/pad_op.py +159 -0
  223. nbxtensor/ops/paged_decode_attn.py +215 -0
  224. nbxtensor/ops/pixel_shuffle.py +144 -0
  225. nbxtensor/ops/pixel_unshuffle.py +72 -0
  226. nbxtensor/ops/pow.py +137 -0
  227. nbxtensor/ops/prod.py +81 -0
  228. nbxtensor/ops/rand_op.py +52 -0
  229. nbxtensor/ops/random_wrappers.py +366 -0
  230. nbxtensor/ops/reciprocal.py +17 -0
  231. nbxtensor/ops/reduction_wrappers.py +845 -0
  232. nbxtensor/ops/relu.py +18 -0
  233. nbxtensor/ops/remainder.py +46 -0
  234. nbxtensor/ops/repeat_interleave.py +48 -0
  235. nbxtensor/ops/repeat_op.py +132 -0
  236. nbxtensor/ops/residual_chain.py +374 -0
  237. nbxtensor/ops/rmsnorm.py +68 -0
  238. nbxtensor/ops/rope.py +142 -0
  239. nbxtensor/ops/rsqrt.py +17 -0
  240. nbxtensor/ops/scaled_softmax.py +96 -0
  241. nbxtensor/ops/scatter_op.py +139 -0
  242. nbxtensor/ops/screen_oracle.py +479 -0
  243. nbxtensor/ops/selu.py +22 -0
  244. nbxtensor/ops/shape_wrappers.py +1032 -0
  245. nbxtensor/ops/sigmoid.py +19 -0
  246. nbxtensor/ops/silu.py +27 -0
  247. nbxtensor/ops/sin.py +17 -0
  248. nbxtensor/ops/softmax.py +169 -0
  249. nbxtensor/ops/softplus.py +27 -0
  250. nbxtensor/ops/sort_op.py +304 -0
  251. nbxtensor/ops/spectral_wrappers.py +481 -0
  252. nbxtensor/ops/sqrt.py +17 -0
  253. nbxtensor/ops/stack_op.py +84 -0
  254. nbxtensor/ops/std.py +113 -0
  255. nbxtensor/ops/strided_copy.py +200 -0
  256. nbxtensor/ops/sub.py +35 -0
  257. nbxtensor/ops/sum.py +40 -0
  258. nbxtensor/ops/tan.py +19 -0
  259. nbxtensor/ops/tanh.py +21 -0
  260. nbxtensor/ops/threshold.py +19 -0
  261. nbxtensor/ops/tiling.yml +91 -0
  262. nbxtensor/ops/tiling_policy.py +43 -0
  263. nbxtensor/ops/tiling_sizes.py +370 -0
  264. nbxtensor/ops/topk.py +267 -0
  265. nbxtensor/ops/trace_op.py +64 -0
  266. nbxtensor/ops/tril.py +64 -0
  267. nbxtensor/ops/triu.py +62 -0
  268. nbxtensor/ops/unfold_op.py +37 -0
  269. nbxtensor/ops/unique_op.py +97 -0
  270. nbxtensor/ops/upsample_bilinear2d.py +106 -0
  271. nbxtensor/ops/upsample_nearest2d.py +52 -0
  272. nbxtensor/ops/upsample_nearest3d.py +61 -0
  273. nbxtensor/ops/var.py +136 -0
  274. nbxtensor/ops/vector_norm.py +216 -0
  275. nbxtensor/ops/weight_norm.py +104 -0
  276. nbxtensor/ops/where.py +39 -0
  277. nbxtensor/ops/wrappers.py +825 -0
  278. nbxtensor/ops/zeros_op.py +20 -0
  279. nbxtensor/quant/__init__.py +1 -0
  280. nbxtensor/quant/quantized_tensor.py +187 -0
  281. nbxtensor/random/__init__.py +1 -0
  282. nbxtensor/random/mt_randn.py +154 -0
  283. nbxtensor/random/rng_pin.py +59 -0
  284. nbxtensor/random/rng_stream.py +118 -0
  285. nbxtensor/random/seeded_draw.py +223 -0
  286. nbxtensor/shape/__init__.py +157 -0
  287. nbxtensor/tensor.py +1867 -0
  288. nbxtensor-0.0.1.dist-info/METADATA +379 -0
  289. nbxtensor-0.0.1.dist-info/RECORD +291 -0
  290. nbxtensor-0.0.1.dist-info/WHEEL +4 -0
  291. nbxtensor-0.0.1.dist-info/licenses/LICENSE +189 -0
nbxtensor/ops/div.py ADDED
@@ -0,0 +1,75 @@
1
+ """Division — pure @triton.jit kernel."""
2
+
3
+ import triton
4
+ import triton.language as tl
5
+
6
+ @triton.jit
7
+ def div_forward_kernel(
8
+ x_ptr, y_ptr, output_ptr,
9
+ n_elements,
10
+ BLOCK_SIZE: tl.constexpr,
11
+ ):
12
+ """out = x / y (tensor / tensor)"""
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(x_ptr + offset, mask=mask)
18
+ y = tl.load(y_ptr + offset, mask=mask)
19
+ tl.store(output_ptr + offset, x / y, mask=mask)
20
+
21
+ @triton.jit
22
+ def div_scalar_kernel(
23
+ x_ptr, output_ptr,
24
+ n_elements,
25
+ scalar,
26
+ BLOCK_SIZE: tl.constexpr,
27
+ ):
28
+ """out = x / scalar"""
29
+ pid = tl.program_id(0).to(tl.int64)
30
+ 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)
31
+ mask = offset < n_elements
32
+
33
+ x = tl.load(x_ptr + offset, mask=mask)
34
+ tl.store(output_ptr + offset, x / scalar, mask=mask)
35
+
36
+
37
+ @triton.jit
38
+ def div_scalar_dev_kernel(
39
+ x_ptr, s_ptr, output_ptr,
40
+ n_elements,
41
+ BLOCK_SIZE: tl.constexpr,
42
+ ):
43
+ """out = x / s where s is a 0-d DEVICE tensor. Bit-exact mirror
44
+ of div_scalar_kernel (host float(s) -> f32 arg == load -> f64 ->
45
+ f32). Device-scalar increment 2026-08-15."""
46
+ pid = tl.program_id(0).to(tl.int64)
47
+ 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)
48
+ mask = offset < n_elements
49
+ s = tl.load(s_ptr).to(tl.float64).to(tl.float32)
50
+ x = tl.load(x_ptr + offset, mask=mask)
51
+ tl.store(output_ptr + offset, x / s, mask=mask)
52
+
53
+
54
+ @triton.jit
55
+ def int_div_kernel(
56
+ x_ptr, y_ptr, output_ptr,
57
+ n_elements,
58
+ FLOOR: tl.constexpr,
59
+ BLOCK_SIZE: tl.constexpr,
60
+ ):
61
+ """out = x // y on integers, computed in the integers: truncated toward zero (C), or toward
62
+ -inf when FLOOR (ATen's floor_divide). Exact at every magnitude of the dtype, where a float
63
+ round-trip is not: Metal's float32 divide is not correctly rounded (-3403868 / 13 gave
64
+ -261836.02, floor -261837; 4435 of 10000 quotients differ from IEEE, 2026-10-08)."""
65
+ pid = tl.program_id(0).to(tl.int64)
66
+ 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)
67
+ mask = offset < n_elements
68
+
69
+ x = tl.load(x_ptr + offset, mask=mask, other=0)
70
+ y = tl.load(y_ptr + offset, mask=mask, other=1)
71
+ q = x // y
72
+ if FLOOR:
73
+ r = x - q * y
74
+ q = q - ((r != 0) & ((r < 0) != (y < 0))).to(q.dtype)
75
+ tl.store(output_ptr + offset, q, mask=mask)
@@ -0,0 +1,67 @@
1
+ """Dot product — pure @triton.jit kernels.
2
+
3
+ Ported from FlagGems dot (Apache-2.0 license).
4
+ Two-phase reduction for large N: partial sums then final reduce.
5
+ Single-phase for small N.
6
+ """
7
+
8
+ import triton
9
+ import triton.language as tl
10
+
11
+
12
+ @triton.jit
13
+ def dot_kernel_small(
14
+ x_ptr, y_ptr, out_ptr,
15
+ N,
16
+ BLOCK_SIZE: tl.constexpr,
17
+ ):
18
+ """Single-block dot product for small vectors (N < 4096).
19
+
20
+ Accumulates in fp32 for numerical stability.
21
+ """
22
+ pid = tl.program_id(0).to(tl.int64)
23
+ block_start = pid * BLOCK_SIZE
24
+ offsets = block_start + tl.arange(0, BLOCK_SIZE)
25
+ mask = offsets < N
26
+
27
+ x = tl.load(x_ptr + offsets, mask=mask, other=0.0).to(tl.float32)
28
+ y = tl.load(y_ptr + offsets, mask=mask, other=0.0).to(tl.float32)
29
+
30
+ result = tl.sum(x * y)
31
+ tl.store(out_ptr, result)
32
+
33
+
34
+ @triton.jit
35
+ def dot_kernel_partial(
36
+ x_ptr, y_ptr, mid_ptr,
37
+ N,
38
+ BLOCK_SIZE: tl.constexpr,
39
+ ):
40
+ """Phase 1: compute partial dot products per block.
41
+
42
+ Each block computes sum(x[block] * y[block]) and stores to mid_ptr[pid].
43
+ """
44
+ pid = tl.program_id(0).to(tl.int64)
45
+ block_start = pid * BLOCK_SIZE
46
+ offsets = block_start + tl.arange(0, BLOCK_SIZE)
47
+ mask = offsets < N
48
+
49
+ x = tl.load(x_ptr + offsets, mask=mask, other=0.0).to(tl.float32)
50
+ y = tl.load(y_ptr + offsets, mask=mask, other=0.0).to(tl.float32)
51
+
52
+ partial_sum = tl.sum(x * y)
53
+ tl.store(mid_ptr + pid, partial_sum)
54
+
55
+
56
+ @triton.jit
57
+ def dot_kernel_reduce(
58
+ mid_ptr, out_ptr,
59
+ M,
60
+ BLOCK_MID: tl.constexpr,
61
+ ):
62
+ """Phase 2: reduce partial sums into final scalar result."""
63
+ offsets = tl.arange(0, BLOCK_MID)
64
+ mask = offsets < M
65
+ mid_val = tl.load(mid_ptr + offsets, mask=mask, other=0.0)
66
+ result = tl.sum(mid_val)
67
+ tl.store(out_ptr, result)
@@ -0,0 +1,23 @@
1
+ """Dropout — pure @triton.jit kernel.
2
+
3
+ At inference time (train=False), dropout is identity (passthrough).
4
+ This kernel implements the identity passthrough for inference mode.
5
+ Training dropout with Philox RNG would be a separate kernel.
6
+ """
7
+
8
+ import triton
9
+ import triton.language as tl
10
+
11
+ @triton.jit
12
+ def dropout_inference_kernel(
13
+ x_ptr, output_ptr,
14
+ n_elements,
15
+ BLOCK_SIZE: tl.constexpr,
16
+ ):
17
+ """Dropout at inference = identity copy."""
18
+ pid = tl.program_id(0).to(tl.int64)
19
+ 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)
20
+ mask = offset < n_elements
21
+
22
+ x = tl.load(x_ptr + offset, mask=mask)
23
+ tl.store(output_ptr + offset, x, mask=mask)
@@ -0,0 +1,42 @@
1
+ """GPU dtype conversion kernels — bf16↔fp16 via bit manipulation.
2
+
3
+ Eliminates CPU-side numpy conversion during weight loading.
4
+ Raw bf16 bytes are H2D copied as uint16, then converted on GPU.
5
+ """
6
+
7
+ import triton
8
+ import triton.language as tl
9
+
10
+
11
+ @triton.jit
12
+ def bf16_to_fp16_kernel(
13
+ src_ptr, # uint16 (bf16 raw bits) on GPU
14
+ dst_ptr, # fp16 output on GPU
15
+ N, # total number of elements
16
+ BLOCK: tl.constexpr,
17
+ ):
18
+ """Convert bf16 → fp16 on GPU via fp32 intermediate.
19
+
20
+ bf16 bits: [sign(1)][exp(8)][mantissa(7)]
21
+ fp32 bits: [sign(1)][exp(8)][mantissa(23)] ← bf16 << 16
22
+ fp16 bits: [sign(1)][exp(5)][mantissa(10)] ← GPU truncates fp32→fp16
23
+
24
+ The GPU handles fp32→fp16 truncation natively (with rounding).
25
+ """
26
+ pid = tl.program_id(0).to(tl.int64)
27
+ offs = pid.to(tl.int64) * BLOCK + tl.arange(0, BLOCK) # 64-bit from the program id (register 58)
28
+ mask = offs < N
29
+
30
+ # Load bf16 raw bits (stored as int16, same 2-byte layout)
31
+ raw_i16 = tl.load(src_ptr + offs, mask=mask, other=0)
32
+ # Mask to 16 bits to prevent sign extension when widening to uint32
33
+ raw = (raw_i16.to(tl.int32) & 0xFFFF).to(tl.uint32)
34
+
35
+ # bf16 → fp32: shift left 16 bits, bitcast to float32
36
+ fp32_bits = raw << 16
37
+ fp32_vals = fp32_bits.to(tl.float32, bitcast=True)
38
+
39
+ # fp32 → fp16: GPU truncates natively
40
+ fp16_vals = fp32_vals.to(tl.float16)
41
+
42
+ tl.store(dst_ptr + offs, fp16_vals, mask=mask)
@@ -0,0 +1,81 @@
1
+ """The launch configuration of every element-wise kernel, certified (chantier 1).
2
+
3
+ An element-wise kernel reads and writes each element once: its time is the memory's, and the program's tile and warps
4
+ move it. Measured on V100 (2026-10-23, `campaigns/2026_10_12_mq25_gate/stable/c1rest/ew_bench.json`: add, mul, exp,
5
+ silu, gelu, erf, pow and a copy, fp32 and fp16, 4 096 to 16 777 216 elements, 15 tiles x warps): at 16 M elements the
6
+ best of the 15 is within 0.3 % (max 1.4 %) for every operation of the configuration that is best for the copy; below
7
+ 65 536 elements the launch itself dominates. The OPERATION does not move the optimum — the element count does, by
8
+ class. So the element-wise kernels share ONE key: the class of the launch's element count (`autotune.buckets.elements`,
9
+ the profile's ladder, else its `default`), certified on the copy below, and every element-wise launch reads its tile
10
+ and warps through `ew_meta` — one memoized resolution per class and process, through the autotuner's own door
11
+ (`ops/_configs.nbx_autotune`: the census record, the certified directory, the refusal of a confirmation run).
12
+
13
+ The copy is in fp32 (the widest element a launch of this class commonly moves); a tile changes no bit of any
14
+ element-wise result — each element is computed alone — so its oracle is identity.
15
+ """
16
+
17
+ import triton
18
+ import triton.language as tl
19
+
20
+ from nbxtensor.ops._configs import nbx_autotune
21
+
22
+
23
+ def _ew_configs():
24
+ """Tile x warps; the configuration every element-wise launch ran before certification (1 024 x 4) is among them."""
25
+ return [triton.Config({'BLOCK_SIZE': block}, num_warps=warps)
26
+ for block in (256, 512, 1024, 2048, 4096) for warps in (2, 4, 8)]
27
+
28
+
29
+ @nbx_autotune(configs=_ew_configs(), key=['N_BUCKET'], cache_results=True)
30
+ @triton.jit
31
+ def ew_launch_kernel(x_ptr, y_ptr, n_elements, N_BUCKET, BLOCK_SIZE: tl.constexpr):
32
+ """y = x over n_elements: the element-wise class's representative."""
33
+ pid = tl.program_id(0).to(tl.int64)
34
+ offset = pid.to(tl.int64) * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
35
+ mask = offset < n_elements
36
+ tl.store(y_ptr + offset, tl.load(x_ptr + offset, mask=mask), mask=mask)
37
+
38
+
39
+ _MEMO = {} # {the element count's class: {'BLOCK_SIZE': ..., 'num_warps': ...}} — one resolution per process
40
+
41
+
42
+ def ew_bucket(n_elements: int) -> int:
43
+ """The class of an element-wise launch of `n_elements` (`autotune.buckets.elements`, else the profile's
44
+ `default`): the key `launch_keys.elementwise_launches` forms for the census."""
45
+ from nbxtensor.ops.autotune_bucket import bucket_of
46
+ return bucket_of("elements", max(1, int(n_elements)))
47
+
48
+
49
+ def ew_meta(n_elements: int) -> dict:
50
+ """The tile and warps of an element-wise launch of `n_elements`: its class's certified configuration (a
51
+ confirmation run refuses a class the directory lacks, by name; another run sweeps it once), read once per class
52
+ and process. The resolution launches the copy above at the class's floor — the fewest elements that form it, so
53
+ never more than the launch that asks — on a scratch buffer of the current device, through the autotuner's door."""
54
+ nb = ew_bucket(n_elements)
55
+ hit = _MEMO.get(nb)
56
+ if hit is not None:
57
+ return hit
58
+ from nbxtensor.ops.autotune_bucket import class_floor
59
+ from nbxtensor.tensor import NBXTensor
60
+ from nbxtensor.dtype.nbx_dtype import NBXDtype
61
+ from nbxtensor.ops.launch_observer import launch_observer
62
+ _census = launch_observer() # the application's launch observer (dry run), if any
63
+ from nbxtensor.ops.autotune_cache import key_of
64
+ rep = class_floor("elements", nb)
65
+ buf = NBXTensor.empty((rep,), dtype=NBXDtype.float32, device='cuda')
66
+ args = (buf, buf, rep, nb)
67
+ ew_launch_kernel[lambda META: (triton.cdiv(rep, META['BLOCK_SIZE']),)](*args)
68
+ cfg = ew_launch_kernel.cache.get(key_of(ew_launch_kernel, args, {}))
69
+ if cfg is None:
70
+ if _census.active(): # a census shadow launches nothing: no configuration exists, none is needed
71
+ first = ew_launch_kernel.configs[0]
72
+ return {'BLOCK_SIZE': first.kwargs['BLOCK_SIZE'], 'num_warps': first.num_warps}
73
+ raise RuntimeError(f"element-wise class {nb}: the copy's autotuner ran and holds no configuration for it")
74
+ hit = {'BLOCK_SIZE': int(cfg.kwargs['BLOCK_SIZE']), 'num_warps': int(cfg.num_warps)}
75
+ _MEMO[nb] = hit
76
+ return hit
77
+
78
+
79
+ def ew_grid(n_elements: int, meta: dict) -> tuple:
80
+ """The 1-D grid of an element-wise launch at its configuration."""
81
+ return (triton.cdiv(int(n_elements), meta['BLOCK_SIZE']),)