nbxtensor 0.0.1__tar.gz → 0.0.2__tar.gz

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 (340) hide show
  1. nbxtensor-0.0.2/.github/PULL_REQUEST_TEMPLATE/certificate.md +28 -0
  2. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/CHANGELOG.md +24 -1
  3. nbxtensor-0.0.2/CONTRIBUTING.md +37 -0
  4. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/PKG-INFO +159 -37
  5. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/README.md +161 -39
  6. nbxtensor-0.0.2/assets/logo.png +0 -0
  7. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/pyproject.toml +2 -2
  8. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/__init__.py +1 -1
  9. nbxtensor-0.0.2/src/nbxtensor/__main__.py +29 -0
  10. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/capabilities.py +8 -6
  11. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/amd/cdna3.yml +2 -3
  12. nbxtensor-0.0.2/src/nbxtensor/backend/devices/amd/cdna4.yml +217 -0
  13. nbxtensor-0.0.2/src/nbxtensor/backend/devices/amd/rdna3.yml +218 -0
  14. nbxtensor-0.0.2/src/nbxtensor/backend/devices/amd/rdna4.yml +218 -0
  15. nbxtensor-0.0.2/src/nbxtensor/backend/devices/intel/bmg.yml +203 -0
  16. nbxtensor-0.0.2/src/nbxtensor/backend/devices/intel/dg2.yml +203 -0
  17. nbxtensor-0.0.2/src/nbxtensor/backend/devices/intel/lnl.yml +203 -0
  18. nbxtensor-0.0.2/src/nbxtensor/backend/devices/intel/pvc.yml +203 -0
  19. nbxtensor-0.0.2/src/nbxtensor/backend/install_help.py +130 -0
  20. nbxtensor-0.0.2/src/nbxtensor/backend/install_steps.yml +36 -0
  21. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/launcher.py +385 -112
  22. nbxtensor-0.0.2/src/nbxtensor/backend/level_zero.py +634 -0
  23. nbxtensor-0.0.2/src/nbxtensor/backend/level_zero_driver.py +202 -0
  24. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/metal_device.py +1 -0
  25. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/runtime.py +39 -12
  26. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/allocator.py +0 -12
  27. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/device_memory.py +3 -1
  28. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/_configs.py +4 -4
  29. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/attention_wrappers.py +6 -20
  30. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/autotune_cache.py +2 -2
  31. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/autotune_certified.py +32 -8
  32. nbxtensor-0.0.2/src/nbxtensor/ops/certified_index.py +105 -0
  33. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/conv_wrappers.py +2 -4
  34. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/dequant_gemv.py +2 -2
  35. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/launch_keys.py +3 -3
  36. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/linalg_wrappers.py +1 -6
  37. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/matmul.py +2 -2
  38. nbxtensor-0.0.2/tests/test_a_triton_kernel_compiles_for_amd_and_launches_through_hip.py +115 -0
  39. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_device_memory.py +1 -1
  40. nbxtensor-0.0.2/tests/test_no_environment_switch_changes_a_kernel.py +24 -0
  41. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_readme.py +14 -2
  42. nbxtensor-0.0.2/tests/test_the_compiler_key_is_prewarmed.py +23 -0
  43. nbxtensor-0.0.2/tests/test_the_hip_driver_keeps_the_launch_contract.py +174 -0
  44. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_the_launcher_refuses_a_backend_it_has_no_driver_for.py +10 -3
  45. nbxtensor-0.0.2/tests/test_the_level_zero_backend_keeps_its_contracts.py +403 -0
  46. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/LICENSE +0 -0
  47. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/THIRD_PARTY_NOTICES.md +0 -0
  48. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/__init__.py +0 -0
  49. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/cpu/__init__.py +0 -0
  50. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/cpu/blas.py +0 -0
  51. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/cpu/pool.py +0 -0
  52. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/cpu_backend.py +0 -0
  53. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/device_facts.py +0 -0
  54. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/device_files.py +0 -0
  55. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/device_names.py +0 -0
  56. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/amd/cdna.yml +0 -0
  57. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/amd/cdna2.yml +0 -0
  58. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m1.yml +0 -0
  59. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m1_max.yml +0 -0
  60. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m1_pro.yml +0 -0
  61. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m1_ultra.yml +0 -0
  62. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m2.yml +0 -0
  63. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m2_max.yml +0 -0
  64. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m2_pro.yml +0 -0
  65. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m2_ultra.yml +0 -0
  66. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m3.yml +0 -0
  67. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m3_max.yml +0 -0
  68. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m3_pro.yml +0 -0
  69. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m3_ultra.yml +0 -0
  70. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m4.yml +0 -0
  71. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m4_max.yml +0 -0
  72. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m4_pro.yml +0 -0
  73. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m5.yml +0 -0
  74. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m5_max.yml +0 -0
  75. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m5_pro.yml +0 -0
  76. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m5_ultra.yml +0 -0
  77. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_m6.yml +0 -0
  78. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/apple/apple_silicon.yml +0 -0
  79. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/nvidia/ampere.yml +0 -0
  80. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/nvidia/hopper.yml +0 -0
  81. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/devices/nvidia/volta.yml +0 -0
  82. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/faults.py +0 -0
  83. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/host_memory.py +0 -0
  84. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/launcher_contract.py +0 -0
  85. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/metal_backend.py +0 -0
  86. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/process_memory.py +0 -0
  87. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/replay_graph.py +0 -0
  88. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/backend/triton_ext_driver.py +0 -0
  89. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/dtype/__init__.py +0 -0
  90. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/dtype/convert.py +0 -0
  91. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/dtype/dtypes.yml +0 -0
  92. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/dtype/itemsize.py +0 -0
  93. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/dtype/nbx_dtype.py +0 -0
  94. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/dtype/operands.py +0 -0
  95. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/dtype/outputs.py +0 -0
  96. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/dtype/policy.py +0 -0
  97. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/dtype/policy.yml +0 -0
  98. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/dtype/promotion.py +0 -0
  99. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/host.py +0 -0
  100. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/io/__init__.py +0 -0
  101. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/io/read_rate.py +0 -0
  102. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/io/safetensors.py +0 -0
  103. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/__init__.py +0 -0
  104. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/arena.py +0 -0
  105. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/device_transfer.py +0 -0
  106. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/layout.py +0 -0
  107. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/memory_pool.py +0 -0
  108. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/metal.py +0 -0
  109. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/oom_advice.py +0 -0
  110. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/pointer_tables.py +0 -0
  111. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/pool.py +0 -0
  112. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/shadow.py +0 -0
  113. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/slab.py +0 -0
  114. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/trace_replay.py +0 -0
  115. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/traces/sana-video-2b-720p.16g.2026-11-02.tsv +0 -0
  116. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/memory/vmm.py +0 -0
  117. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/__init__.py +0 -0
  118. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/_autotune_policy.py +0 -0
  119. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/_common.py +0 -0
  120. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/_cost.py +0 -0
  121. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/abs.py +0 -0
  122. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/adaptive_avg_pool2d.py +0 -0
  123. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/add.py +0 -0
  124. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/addcdiv.py +0 -0
  125. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/addcmul.py +0 -0
  126. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/addmv_op.py +0 -0
  127. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/addr.py +0 -0
  128. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/all_reduce.py +0 -0
  129. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/amax.py +0 -0
  130. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/any_reduce.py +0 -0
  131. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/arange_op.py +0 -0
  132. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/argmax.py +0 -0
  133. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/argmin.py +0 -0
  134. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/atan2.py +0 -0
  135. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/autotune_bucket.py +0 -0
  136. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/autotune_refusals.py +0 -0
  137. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/autotune_settings.py +0 -0
  138. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/avg_pool2d.py +0 -0
  139. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/baddbmm_op.py +0 -0
  140. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/batch_norm.py +0 -0
  141. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/binary_strided.py +0 -0
  142. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/bitwise_and.py +0 -0
  143. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/bitwise_left_shift.py +0 -0
  144. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/bitwise_not.py +0 -0
  145. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/bitwise_or.py +0 -0
  146. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/bitwise_right_shift.py +0 -0
  147. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/bucketize.py +0 -0
  148. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/cat_op.py +0 -0
  149. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/celu.py +0 -0
  150. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/clamp.py +0 -0
  151. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/clamp_min.py +0 -0
  152. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/conv2d.py +0 -0
  153. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/conv2d_m8n8k4.py +0 -0
  154. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/conv_depthwise2d.py +0 -0
  155. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/conv_transpose2d.py +0 -0
  156. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/copy.py +0 -0
  157. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/copy_op.py +0 -0
  158. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/cos.py +0 -0
  159. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/count_nonzero.py +0 -0
  160. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/cross_entropy.py +0 -0
  161. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/cummax.py +0 -0
  162. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/cummin.py +0 -0
  163. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/cumsum.py +0 -0
  164. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/decode_attn_vec.py +0 -0
  165. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/depthwise_conv2d.py +0 -0
  166. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/dft.py +0 -0
  167. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/dispatch.py +0 -0
  168. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/div.py +0 -0
  169. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/dot_op.py +0 -0
  170. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/dropout.py +0 -0
  171. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/dtype_convert.py +0 -0
  172. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/elementwise_launch.py +0 -0
  173. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/elementwise_wrappers.py +0 -0
  174. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/elu.py +0 -0
  175. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/embedding.py +0 -0
  176. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/eq.py +0 -0
  177. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/erf.py +0 -0
  178. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/exp.py +0 -0
  179. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/exp2.py +0 -0
  180. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/fft_op.py +0 -0
  181. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/fill_op.py +0 -0
  182. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/flash_attention.py +0 -0
  183. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/flash_attention_m8n8k4.py +0 -0
  184. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/flash_decode.py +0 -0
  185. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/flip_op.py +0 -0
  186. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/floor.py +0 -0
  187. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/full_op.py +0 -0
  188. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/fused_moe.py +0 -0
  189. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/fused_moe_m8n8k4.py +0 -0
  190. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/fused_upsample_conv.py +0 -0
  191. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/gather_op.py +0 -0
  192. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/ge.py +0 -0
  193. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/gelu.py +0 -0
  194. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/gemv_vec.py +0 -0
  195. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/glu.py +0 -0
  196. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/grid_sampler.py +0 -0
  197. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/group_norm_tiled.py +0 -0
  198. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/groupnorm.py +0 -0
  199. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/gt.py +0 -0
  200. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/hardsigmoid.py +0 -0
  201. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/hardswish.py +0 -0
  202. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/im2col.py +0 -0
  203. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/index_add.py +0 -0
  204. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/index_put_op.py +0 -0
  205. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/index_select.py +0 -0
  206. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/index_wrappers.py +0 -0
  207. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/isfinite.py +0 -0
  208. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/isinf.py +0 -0
  209. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/isnan.py +0 -0
  210. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/launch_observer.py +0 -0
  211. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/layernorm.py +0 -0
  212. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/le.py +0 -0
  213. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/leaky_relu.py +0 -0
  214. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/lerp.py +0 -0
  215. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/linspace_op.py +0 -0
  216. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/log.py +0 -0
  217. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/log_sigmoid.py +0 -0
  218. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/logical_and.py +0 -0
  219. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/logical_not.py +0 -0
  220. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/logical_or.py +0 -0
  221. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/logical_xor.py +0 -0
  222. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/loss_wrappers.py +0 -0
  223. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/lt.py +0 -0
  224. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/masked_fill.py +0 -0
  225. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/matmul_m8n8k4.py +0 -0
  226. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/max_pool2d.py +0 -0
  227. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/max_pool3d.py +0 -0
  228. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/max_reduce.py +0 -0
  229. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/maximum.py +0 -0
  230. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/mean.py +0 -0
  231. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/min_reduce.py +0 -0
  232. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/minimum.py +0 -0
  233. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/mish.py +0 -0
  234. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/mma_m8n8k4.py +0 -0
  235. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/moe_align.py +0 -0
  236. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/moe_decode_vec.py +0 -0
  237. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/moe_device_residency.py +0 -0
  238. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/moe_wrappers.py +0 -0
  239. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/mse_loss.py +0 -0
  240. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/mul.py +0 -0
  241. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/nan_to_num.py +0 -0
  242. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/ne.py +0 -0
  243. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/neg.py +0 -0
  244. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/nllloss.py +0 -0
  245. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/nonzero.py +0 -0
  246. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/nonzero_op.py +0 -0
  247. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/norm_wrappers.py +0 -0
  248. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/ones_op.py +0 -0
  249. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/oracles/__init__.py +0 -0
  250. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/oracles/conv2d_fp64.py +0 -0
  251. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/pad_op.py +0 -0
  252. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/paged_decode_attn.py +0 -0
  253. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/pixel_shuffle.py +0 -0
  254. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/pixel_unshuffle.py +0 -0
  255. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/pow.py +0 -0
  256. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/prod.py +0 -0
  257. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/rand_op.py +0 -0
  258. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/random_wrappers.py +0 -0
  259. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/reciprocal.py +0 -0
  260. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/reduction_wrappers.py +0 -0
  261. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/relu.py +0 -0
  262. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/remainder.py +0 -0
  263. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/repeat_interleave.py +0 -0
  264. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/repeat_op.py +0 -0
  265. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/residual_chain.py +0 -0
  266. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/rmsnorm.py +0 -0
  267. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/rope.py +0 -0
  268. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/rsqrt.py +0 -0
  269. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/scaled_softmax.py +0 -0
  270. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/scatter_op.py +0 -0
  271. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/screen_oracle.py +0 -0
  272. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/selu.py +0 -0
  273. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/shape_wrappers.py +0 -0
  274. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/sigmoid.py +0 -0
  275. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/silu.py +0 -0
  276. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/sin.py +0 -0
  277. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/softmax.py +0 -0
  278. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/softplus.py +0 -0
  279. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/sort_op.py +0 -0
  280. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/spectral_wrappers.py +0 -0
  281. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/sqrt.py +0 -0
  282. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/stack_op.py +0 -0
  283. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/std.py +0 -0
  284. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/strided_copy.py +0 -0
  285. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/sub.py +0 -0
  286. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/sum.py +0 -0
  287. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/tan.py +0 -0
  288. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/tanh.py +0 -0
  289. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/threshold.py +0 -0
  290. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/tiling.yml +0 -0
  291. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/tiling_policy.py +0 -0
  292. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/tiling_sizes.py +0 -0
  293. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/topk.py +0 -0
  294. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/trace_op.py +0 -0
  295. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/tril.py +0 -0
  296. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/triu.py +0 -0
  297. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/unfold_op.py +0 -0
  298. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/unique_op.py +0 -0
  299. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/upsample_bilinear2d.py +0 -0
  300. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/upsample_nearest2d.py +0 -0
  301. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/upsample_nearest3d.py +0 -0
  302. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/var.py +0 -0
  303. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/vector_norm.py +0 -0
  304. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/weight_norm.py +0 -0
  305. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/where.py +0 -0
  306. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/wrappers.py +0 -0
  307. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/ops/zeros_op.py +0 -0
  308. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/quant/__init__.py +0 -0
  309. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/quant/quantized_tensor.py +0 -0
  310. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/random/__init__.py +0 -0
  311. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/random/mt_randn.py +0 -0
  312. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/random/rng_pin.py +0 -0
  313. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/random/rng_stream.py +0 -0
  314. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/random/seeded_draw.py +0 -0
  315. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/shape/__init__.py +0 -0
  316. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/src/nbxtensor/tensor.py +0 -0
  317. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_a_small_tensor_never_pins_a_large_block.py +0 -0
  318. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_a_sweep_refused_everywhere_says_so.py +0 -0
  319. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_allocator_interceptor.py +0 -0
  320. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_array_api_promotion.py +0 -0
  321. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_cpu_pool.py +0 -0
  322. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_device_facts.py +0 -0
  323. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_device_files.py +0 -0
  324. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_dtype_convert.py +0 -0
  325. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_dtype_outputs.py +0 -0
  326. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_dtype_promotion.py +0 -0
  327. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_host.py +0 -0
  328. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_io_bf16_split.py +0 -0
  329. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_io_read_rate.py +0 -0
  330. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_nbx_dtype.py +0 -0
  331. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_ops_cost.py +0 -0
  332. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_policy.py +0 -0
  333. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_shape.py +0 -0
  334. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_the_malloc_trace_names_the_wrapper.py +0 -0
  335. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_the_metal_dispatch_facts_are_declared_or_refused.py +0 -0
  336. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_third_party_notices.py +0 -0
  337. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tests/test_version.py +0 -0
  338. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tools/device_key_census.py +0 -0
  339. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tools/device_key_trace.py +0 -0
  340. {nbxtensor-0.0.1 → nbxtensor-0.0.2}/tools/scatter_scan.py +0 -0
@@ -0,0 +1,28 @@
1
+ ## Certificates for a GPU class
2
+
3
+ **GPU model** (as `nvidia-smi -L` or the system reports it):
4
+ **Driver version:**
5
+ **Operating system / Python:**
6
+ **Versions** (`pip show nbxtensor neurobrix triton`):
7
+
8
+ **Models run** (the `neurobrix run` commands whose keys were certified):
9
+
10
+ ```
11
+ neurobrix run ...
12
+ ```
13
+
14
+ **Certification command:**
15
+
16
+ ```
17
+ neurobrix autotune certify --profile <profile> --keys <...> --out <dir>
18
+ ```
19
+
20
+ **Check — the certified-only run, served from these certificates** (paste its `[autotune] certified directory:` line and
21
+ the output's sha256):
22
+
23
+ ```
24
+ NEUROBRIX_AUTOTUNE_CERTIFIED_DIR=<dir> neurobrix run ... --certified-only
25
+ ```
26
+
27
+ - [ ] the files are added under `src/neurobrix/config/autotune/<vendor>/<profile>/` of the NeuroBrix repository
28
+ - [ ] the certified-only run above served every key (0 swept at runtime) and its output matches the uncertified run
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.0.2] - 2026-11-06
11
+
12
+ ### Added
13
+ - **`backend.launcher.prewarm_compiler()`**: computes Triton's cache key (`triton_key`, the sha256 of libtriton and of Triton's sources, about 1.3 s on a V100 host) in a daemon thread, so a process's first kernel compile no longer waits for it; an application calls it at start, while it loads weights.
14
+ - **Intel GPUs through Level Zero** (`backend.level_zero`, `backend.level_zero_driver`; the `xpu` backend, chosen when the system's Level Zero loader reports a GPU): a runtime over Level Zero that serves the allocator (device and page-locked host memory, in-order command lists as streams, timed events), and a launch driver for the SPIR-V kernels Intel's Triton build compiles, with Intel's own argument ABI; the compile target is built without torch or SYCL (Level Zero's counts, the OpenCL ICD's extensions, the device file's architecture name). Proven against stand-ins of libze_loader and the OpenCL ICD: no Intel card has run it yet.
15
+ - **What to install when a GPU is present and unusable** (`backend.install_help`, `python -m nbxtensor doctor`): for every NVIDIA, AMD or Intel GPU on the PCI bus, whether its runtime library and its Triton backend are installed, with the vendor's install commands when one is not; the refusal when no GPU runtime answers carries the same steps instead of a bare error. The README's "Install on AMD / Intel GPUs" section gives them.
16
+ - **Device files** for AMD CDNA4 (gfx950), RDNA3 (gfx11xx) and RDNA4 (gfx120x), and Intel Data Center GPU Max (pvc), Arc A-series and Flex (dg2), Arc B-series (bmg) and Lunar Lake (lnl), every value with its source.
17
+ - **A HIP launch driver for AMD GPUs** (`backend.launcher.HipDriver`, chosen when the runtime detects HIP): the HIP module API through the HIP runtime library the runtime already loaded, the launch Triton's own AMD launcher performs (hsaco code objects, `hipModuleLaunchKernel`, the kernel's arguments then the scratch pointers, a block of the code object's wavefront times the kernel's warps), one module per device and code object, the argument count read from the code object's own metadata and a list of another length refused, shared memory past the device's per-block maximum refused as Triton's own AMD launcher refuses it, the wavefront read from the code object and the device file (never defaulted), the launcher contract's `compile` surface shared with the CUDA driver, every missing symbol refused by name; page-locked host memory is asked of `hipHostMalloc` with its flags word. Its tests compile real Triton kernels for gfx90a, gfx942, gfx950, gfx1100 and gfx1201 on a machine without an AMD card and launch them through a stand-in HIP library: no AMD card has run it yet.
18
+
19
+ ### Removed
20
+ - **Nine environment switches that changed a kernel**: `NBX_MM_MAX_OUTPUT_ELEMS` (the matrix product's output split, fixed by an int32 element offset), `NBX_FLASH_BLOCK_M_VOLTA` (Volta's flash Q tile, 64, the measured floor of correctness), `NBX_CONV3D_EAGER_FREE_BYTES` (when a 3-D convolution frees its buffers early), `NBX_FLASH_NUM_WARPS` and `NBX_FLASH_NUM_STAGES` (the flash kernel's launch, which its device file's flash rows state), `NBX_DGEMV_ADAPT` (the dequantising GEMV's width adaptation, set by `dequant_gemv.min_programs`), `NBX_D128_DETOUR` (the power-of-two head-dim detour, decided by `flash.pow2_head_dim_correct`; `launch_keys.flash_headdim_detour` loses its `enabled` argument), `NBX_DEPTHWISE_DISABLE` (the depthwise convolution route) and `NBX_GC_ON_OOM` (a garbage-collecting retry of a refused allocation, which is raised, never rescued). A value a kernel needs is a fact of its device file or of a certificate, never a host setting.
21
+
22
+ ### Changed
23
+ - **A certified file is parsed and validated once, then read from its compiled index** (`ops.certified_index`): the directory stays JSON, the source contributors edit; the first launch after a change validates a file and writes, per memory class, a binary index of the entries that class is served (length-prefixed keys and certifications, a SHA-256 trailer, never a pickle), named by the fingerprint of everything the validation read; later launches read the index and parse a certification only when its key is asked. A corrupt index is refused by name.
24
+ - **The launch recorder receives each pointer's extent** (`backend.launcher.set_launch_recorder`: `fn(prepared, grid, params, extents)`): the byte extent of each pointer's tensor that a driver binding by extent is handed, None for a driver that binds by address — a replay can now launch exactly what was launched.
25
+ - **The README opens with what the library is and `pip install nbxtensor`**: the 0.0.1 README began its installation with `pip install -e nbxtensor` from the engine's repository, which PyPI showed as the package's description; it now opens with its title, what it does, the install from PyPI (the repository install is below, for contributors), a GPU example its tests run, why the library exists (no PyTorch, any Triton GPU, the V100's tensor cores back in use with their measured gains, planned memory, certified tuning) and the hardware tested and expected, and it links its API and backend references in the NeuroBrix repository, where they live (they were relative links to files the library's repository does not hold). The package's one-line description no longer names a CPU backend, which the library does not have.
26
+
27
+ ### Fixed
28
+ - **CDNA3's shared memory per block is 64 KB**, not 160 KB (the device file had CDNA4's figure; Triton 3.8's AMD target features state 64 KB for gfx942): an autotune config needing more is no longer kept for an MI300.
29
+
30
+
10
31
  ## [0.0.1] - 2026-11-05
11
32
 
12
33
  The first release of nbxtensor: an inference-first tensor library whose kernels are written in Triton and which never
@@ -61,6 +82,7 @@ memory; the fix is in test).
61
82
  - **nbxtensor names the device in force publicly**: `nbxtensor.backend.device_files.in_force()`, `for_arch(arch)` and `forget()`, and `nbxtensor.backend.launcher.bind_target(target)` for a derivation that launches nothing; the engine's key census and paged KV cache read them instead of the library's private configuration module.
62
83
 
63
84
  ### Changed
85
+ - **The launch recorder receives each pointer's extent** (`backend.launcher.set_launch_recorder`: `fn(prepared, grid, params, extents)`): the byte extent of each pointer's tensor that a driver binding by extent is handed, None for a driver that binds by address — a replay can now launch exactly what was launched.
64
86
  - **Every device file states the tolerance an integer kernel output is certified at**: `autotune_screen_rtol.int64: 0.0` — met exactly (the MoE alignment's routing tables); the certifier invents no tolerance and refused every alignment key without it.
65
87
  - **The MoE alignment's three stages take their chunk widths and warps from their certificates**: `moe_align_stage{1,2,3}_kernel` ran per-backend literal widths (128 or the experts' count on CUDA, 32-64 on Metal) at 4 warps; each is now certified per key (the block, the padded expert count, the layer's pairs in the profile's `elements` classes), its candidates pruned to the blocks that fit the profile's `memory.max_shared_memory_per_block`. Every candidate computes the same routing; the choice is speed only.
66
88
  - **`nbxtensor.memory.pointer_tables.build_ptr_tables` is public**: the expert pointer tables a MoE kernel reads (on Metal captured under a pinned scope), built by the engine's MoE layer and by its certifier alike; it was the private `_build_ptr_tables`.
@@ -115,5 +137,6 @@ memory; the fix is in test).
115
137
  - **`flash_decode_split_kernel` and its route**: armed only by an environment switch (`NBX_FLASH_DECODE`, with `NBX_FD_BLOCK_N` and `NBX_FD_SEG`) and measured slower than the vector decode kernels; `flash_decode.py` keeps the fixed-order reduce they share.
116
138
  - **`conv1d_forward_kernel`**: launched by no route (a 1-D convolution runs through `conv2d`).
117
139
 
118
- [Unreleased]: https://github.com/NeuroBrix/nbxtensor/compare/v0.0.1...HEAD
140
+ [Unreleased]: https://github.com/NeuroBrix/nbxtensor/compare/v0.0.2...HEAD
141
+ [0.0.2]: https://github.com/NeuroBrix/nbxtensor/compare/v0.0.1...v0.0.2
119
142
  [0.0.1]: https://github.com/NeuroBrix/nbxtensor/releases/tag/v0.0.1
@@ -0,0 +1,37 @@
1
+ # Contributing to nbxtensor
2
+
3
+ nbxtensor is open source under the Apache 2.0 license. Issues, fixes, new device files and certificates are welcome.
4
+
5
+ ## Issues
6
+
7
+ Found a bug on your hardware? [Open an issue](https://github.com/NeuroBrix/nbxtensor/issues) with:
8
+
9
+ - your GPU model, its driver version, your operating system and Python version;
10
+ - `pip show nbxtensor triton` (the versions installed);
11
+ - the smallest code or command that shows the problem, and its full output.
12
+
13
+ ## Pull requests
14
+
15
+ 1. Fork the repository and branch from `main`.
16
+ 2. Keep a change complete: the code, its test (seen failing before the fix, passing after), and one line under
17
+ `## [Unreleased]` in `CHANGELOG.md` when a user would notice the change (a bold title, the cause and the effect).
18
+ 3. Run the library's tests: `pip install -e ".[test]"` then `pytest tests`. On a machine with a GPU the examples of the
19
+ README that launch a kernel run too.
20
+ 4. Open the pull request.
21
+
22
+ The library's source lives in `nbxtensor/` of the [NeuroBrix repository](https://github.com/NeuroBrix/neurobrix) and is
23
+ exported here; a pull request on either repository is fine — we carry it across.
24
+
25
+ ## Style
26
+
27
+ - **No torch.** nbxtensor never imports torch, not even optionally or inside a `try`.
28
+ - **No guessed value.** A fact the library needs (a tile, a tolerance, a limit of the device) is read from the device's
29
+ file (`src/nbxtensor/backend/devices/<vendor>/<name>.yml`) or measured; a missing fact is an error that names it,
30
+ never a default.
31
+ - **No model knowledge.** The library knows tensors, kernels and devices, never a model by name.
32
+ - English in code, comments and documentation.
33
+
34
+ ## Certificates
35
+
36
+ Certificates are the proven kernel settings of a GPU class: see [Certify your own hardware](README.md#certify-your-own-hardware)
37
+ for how to make them and share them. Open the pull request with the `certificate` template.
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: nbxtensor
3
- Version: 0.0.1
4
- Summary: An inference-first tensor library, torch-free: planned memory, Triton kernels that declare their cost, CUDA / Apple Metal / CPU backends.
3
+ Version: 0.0.2
4
+ Summary: Run AI models without PyTorch: tensors, Triton kernels, planned memory and certified tuning, on NVIDIA and Apple GPUs.
5
5
  Project-URL: Homepage, https://github.com/NeuroBrix/nbxtensor
6
6
  Project-URL: Source, https://github.com/NeuroBrix/nbxtensor
7
7
  Project-URL: Issues, https://github.com/NeuroBrix/nbxtensor/issues
@@ -18,33 +18,106 @@ Provides-Extra: test
18
18
  Requires-Dist: pytest; extra == 'test'
19
19
  Description-Content-Type: text/markdown
20
20
 
21
- # nbxtensor
21
+ <p align="center"><img src="https://raw.githubusercontent.com/NeuroBrix/nbxtensor/main/assets/logo.png" alt="NeuroBrix" width="240"></p>
22
22
 
23
- An inference-first tensor library, torch-free.
23
+ # nbxtensor — the torch-free tensor library for inference
24
24
 
25
- PyTorch is a general framework built for research and training in eager mode: dynamic graphs, autograd, a generic
26
- dispatcher, a caching allocator that discovers memory as the program runs. Inference is a narrower problem, and a
27
- better-informed one: the graph and the shapes are known before the first run. nbxtensor is built for that case.
25
+ Run AI models without PyTorch, on any GPU Triton supports: tensors, Triton kernels, planned memory and certified tuning.
28
26
 
29
- - **Memory is planned, not discovered.** Allocators per device behind one interface, and a static planner that
30
- assigns every buffer before the first run.
31
- - **Every kernel declares its cost.** Outputs, workspace and scratch with their lifetimes, bytes moved, flops. A
32
- planner prices a model from these declarations instead of guessing what the allocator will do.
33
- - **Capture and replay are first-class.** A repeated sequence of launches is recorded, verified byte-equal and
34
- replayed.
35
- - **One table of facts.** One dtype table, one view rule, one conversion per pair of dtypes, one capability table per
36
- backend — declared, never guessed.
37
- - **Backends:** NVIDIA CUDA, Apple Metal (through triton-ext), CPU.
38
- - **No torch, ever.** nbxtensor never imports torch, not even optionally. Exchange with any tensor library goes
39
- through the DLPack protocol (`__dlpack__`, `from_dlpack`), so a torch user writes `torch.from_dlpack(t)` on their
40
- side.
27
+ Runs wherever Triton runs — NVIDIA, AMD, Intel and Apple Silicon GPUs. Inference first; training is not in this
28
+ release. Found a bug on your hardware? [Open an issue](https://github.com/NeuroBrix/nbxtensor/issues) — we fix fast.
41
29
 
42
- nbxtensor is extracted from NeuroBrix, the universal inference engine whose Triton engine is its first client. It
43
- lives in `nbxtensor/` of the NeuroBrix repository until the extraction is complete, then in its own repository.
30
+ [![PyPI](https://img.shields.io/pypi/v/nbxtensor)](https://pypi.org/project/nbxtensor/)
31
+ [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue)](https://github.com/NeuroBrix/nbxtensor/blob/main/LICENSE)
32
+ [![Python](https://img.shields.io/pypi/pyversions/nbxtensor)](https://pypi.org/project/nbxtensor/)
33
+ ![torch-free](https://img.shields.io/badge/torch-free-success)
34
+ ![Triton](https://img.shields.io/badge/kernels-Triton-orange)
35
+
36
+ ```
37
+ pip install nbxtensor
38
+ ```
39
+
40
+ <!-- needs-gpu -->
41
+ ```python
42
+ import numpy as np
43
+ from nbxtensor.tensor import NBXTensor
44
+ from nbxtensor.ops.linalg_wrappers import mm
45
+
46
+ rng = np.random.default_rng(0)
47
+ a = rng.standard_normal((256, 512)).astype(np.float16)
48
+ b = rng.standard_normal((512, 128)).astype(np.float16)
49
+ c = mm(NBXTensor.from_numpy(a), NBXTensor.from_numpy(b)) # a Triton kernel on the GPU, no torch
50
+ ref = a.astype(np.float32) @ b.astype(np.float32)
51
+ assert c.shape == (256, 128) and np.allclose(c.numpy().astype(np.float32), ref, rtol=2e-2, atol=2e-1)
52
+ ```
53
+
54
+ ## Why nbxtensor
55
+
56
+ - **No PyTorch.** nbxtensor never imports torch, not even optionally; its tests, kernels and NeuroBrix's models run in
57
+ an environment where torch is not installed. Exchange with any tensor library goes through DLPack (`__dlpack__`,
58
+ `from_dlpack`), so a torch user writes `torch.from_dlpack(t)` on their side.
59
+ - **Runs wherever Triton runs.** The kernels are Triton; a device is described by a file of facts (tiles, shared
60
+ memory, the matrix unit, the autotune ladders), never by code.
61
+ - **Fast.** Faster than PyTorch on many models (in NeuroBrix's gate of 2026-11-05, the Triton engine on nbxtensor beat
62
+ the PyTorch engine on 18 of 49 models on a 16 GB V100 and 17 of 49 on a 32 GB one). Still running V100s? Triton leaves
63
+ their tensor cores idle (`tl.dot` compiles to FMA on sm_70); nbxtensor turns them back on with its own `mma.m8n8k4`
64
+ kernels (matrix products, convolutions, flash attention, the fused mixture-of-experts GEMM), chosen by the certificate
65
+ only where they measured faster — an 80 x 4096 x 4096 fp16 product 0.404 -> 0.191 ms, the fused MoE prefill 2.49 ->
66
+ 0.96 ms (DeepSeek, 20 tokens) and 7.24 -> 1.40 ms (Qwen3, 512 tokens), fp32 1 x 1 convolutions 1.26-1.95 times faster
67
+ (V100, the measures recorded in [the 0.0.1 changelog](https://github.com/NeuroBrix/nbxtensor/blob/main/CHANGELOG.md#001---2026-11-05)).
68
+ - **Lightweight.** nbxtensor itself is 1 MB; the whole install, Triton included, is about 1 GB — PyTorch's is 5.6 GB.
69
+ - **Certified tuning.** Kernel settings are measured once per GPU class against a float64 oracle and shipped — no
70
+ autotuning at run time for the shapes we cover. We are certifying every model we can, so you never have to autotune.
71
+ Certified your GPU? [Share your certificates](#certify-your-own-hardware).
72
+ - **Memory is planned, not discovered.** Allocators per device behind one interface, a static planner that assigns every
73
+ buffer before the first run, and every kernel declares its cost (outputs, workspace, scratch, bytes moved, flops) so a
74
+ planner prices a model before running it. Capture and replay of a repeated sequence of launches, verified byte-equal.
75
+
76
+ ## Certify your own hardware
77
+
78
+ A kernel setting is certified per launch key (the kernel, its shape class and dtypes) and per GPU class. The keys a GPU
79
+ class has no certificate for are swept at run time and kept on your machine; certifying them makes them permanent and
80
+ shareable. Certification runs through [NeuroBrix](https://github.com/NeuroBrix/neurobrix), the engine whose models form
81
+ the keys (`pip install neurobrix`), with these commands (run as written on a clean machine, 2026-11-06):
82
+
83
+ 1. Run the models you use. Every key no certificate covers is swept and kept in `~/.neurobrix/replay_cache/`:
84
+
85
+ ```
86
+ neurobrix run --model TinyLlama-1.1B-Chat-v1.0 --triton --prompt "Hello" --max-tokens 32
87
+ ```
88
+
89
+ 2. Certify the keys your card formed — every candidate setting is run against a float64 oracle and timed; the proofs are
90
+ written into `--out`, one file per kernel and dtype under `<vendor>/<profile>/` (the profile is your GPU's device
91
+ file, e.g. `volta`):
92
+
93
+ ```
94
+ neurobrix autotune certify --profile volta \
95
+ --keys ~/.neurobrix/replay_cache/autotune_configs_cuda-70-triton_3.8.0.json --out ./my-certificates
96
+ ```
97
+
98
+ 3. Check that they are served: a certified-only run uses only certificates and fails, naming the key, if one is missing:
99
+
100
+ ```
101
+ NEUROBRIX_AUTOTUNE_CERTIFIED_DIR=./my-certificates neurobrix run --model TinyLlama-1.1B-Chat-v1.0 --triton \
102
+ --prompt "Hello" --max-tokens 32 --certified-only
103
+ ```
104
+
105
+ Its `[autotune] certified directory:` line says `0 swept at runtime`, and its output is the same as step 1's.
106
+
107
+ 4. Share them: fork [NeuroBrix](https://github.com/NeuroBrix/neurobrix), add the files of `./my-certificates/<vendor>/<profile>/`
108
+ under `src/neurobrix/config/autotune/<vendor>/<profile>/`, and open a pull request with the `certificate` template:
109
+ your GPU model, driver, the commands above and the output of step 3. Certified your GPU? Share your certificates —
110
+ every class certified is a class nobody autotunes again.
111
+
112
+
113
+ **Links:** [API reference](https://github.com/NeuroBrix/neurobrix/blob/main/docs/nbxtensor/API.md) ·
114
+ [release notes](https://github.com/NeuroBrix/nbxtensor/blob/main/CHANGELOG.md) ·
115
+ [NeuroBrix](https://github.com/NeuroBrix/neurobrix), the inference engine whose Triton engine is nbxtensor's first
116
+ client; nbxtensor's source lives in its `nbxtensor/` directory and is exported here.
44
117
 
45
118
  ## Status
46
119
 
47
- Every area below is in the library, and every public name is documented in `docs/nbxtensor/API.md` (the list of
120
+ Every area below is in the library, and every public name is documented in [`docs/nbxtensor/API.md`](https://github.com/NeuroBrix/neurobrix/blob/main/docs/nbxtensor/API.md) (the list of
48
121
  undocumented names is empty and a test keeps it so). This README documents what is in the library TODAY; every example below is executed by
49
122
  `nbxtensor/tests/test_readme.py`, so an example that stops working fails a test. The target API is
50
123
  `docs/nbxtensor/API.md`.
@@ -67,10 +140,20 @@ attempt to import torch, caught ones included, and recorded none). Python 3.10 o
67
140
  pyyaml and Triton.
68
141
 
69
142
  ```
70
- pip install -e nbxtensor # from the NeuroBrix repository
143
+ pip install nbxtensor
71
144
  ```
72
145
 
73
- **Linux, NVIDIA (CUDA).** Triton comes from PyPI with the install above.
146
+ **Linux, NVIDIA (CUDA).** Triton and the CUDA runtime library come from PyPI with the install above; the NVIDIA driver
147
+ is the only other requirement.
148
+
149
+ **Linux, AMD (ROCm) and Intel (Level Zero).** The system's GPU runtime and a Triton that compiles for the card are
150
+ needed: see [Install on AMD / Intel GPUs](#install-on-amd--intel-gpus).
151
+
152
+ **Which GPU, and what is missing.** `python -m nbxtensor doctor` names the backend in force and, for every NVIDIA, AMD
153
+ or Intel GPU on the PCI bus, whether its runtime library and its Triton backend are installed — with the vendor's
154
+ install commands when one is not.
155
+
156
+ **From the NeuroBrix repository** (contributors): `pip install -e nbxtensor`.
74
157
 
75
158
  **macOS, Apple silicon (Metal).** PyPI publishes no Triton for macOS, so Triton and its Metal backend are built from
76
159
  source, then nbxtensor is installed into that environment:
@@ -83,6 +166,46 @@ source, then nbxtensor is installed into that environment:
83
166
 
84
167
  `nbxtensor.dtype` and `nbxtensor.shape` need neither a device nor Triton.
85
168
 
169
+ ## Install on AMD / Intel GPUs
170
+
171
+ The library speaks to the card through the vendor's own runtime library, loaded at run time, and compiles its kernels
172
+ with the Triton backend for that card. When a card is present and either is missing, the library refuses with the
173
+ steps below (the same text `python -m nbxtensor doctor` prints). The commands are the vendors' (Ubuntu 24.04).
174
+
175
+ **AMD (ROCm, HIP).** The ROCm runtime, from AMD's
176
+ [quick start](https://rocm.docs.amd.com/projects/install-on-linux/en/latest/install/quick-start.html):
177
+
178
+ ```
179
+ wget https://repo.radeon.com/amdgpu-install/6.4.3/ubuntu/noble/amdgpu-install_6.4.60403-1_all.deb
180
+ sudo apt install ./amdgpu-install_6.4.60403-1_all.deb
181
+ sudo apt update && sudo apt install rocm
182
+ sudo usermod -a -G render,video $LOGNAME # then log out and in (or reboot)
183
+ pip install nbxtensor # the Triton wheel on PyPI carries the AMD backend
184
+ ```
185
+
186
+ Targets: CDNA (gfx908, gfx90a, gfx942, gfx950) and RDNA 3 / 4 (gfx11xx, gfx120x); the hardware profile states the
187
+ card's gfx arch. Triton 3.8 compiles the library's kernels for these targets on a machine without the card (the
188
+ library's tests do it).
189
+
190
+ **Intel (Level Zero).** Intel's GPU driver, from Intel's
191
+ [package guide](https://dgpu-docs.intel.com/installation-guides/installing-packages-from-the-intel-ppa.html), then
192
+ Intel's Triton build (the PyPI Triton has no Intel backend):
193
+
194
+ ```
195
+ sudo add-apt-repository -y ppa:kobuk-team/intel-graphics
196
+ sudo apt-get install -y libze-intel-gpu1 libze1 intel-opencl-icd clinfo intel-gsc
197
+ sudo usermod -a -G render $LOGNAME # then log out and in
198
+ pip install triton-xpu --index-url https://download.pytorch.org/whl/xpu
199
+ pip install nbxtensor
200
+ ```
201
+
202
+ Devices: Data Center GPU Max (Ponte Vecchio), Arc A-series and Data Center GPU Flex (Alchemist), Arc B-series
203
+ (Battlemage), Core Ultra 200V graphics (Lunar Lake); the card's PCI id selects its device file.
204
+
205
+ **Status.** The AMD and Intel drivers are written to the level of the NVIDIA and Apple ones and proven against
206
+ stand-ins of the vendors' libraries; no AMD or Intel card has run them yet. [Open an
207
+ issue](https://github.com/NeuroBrix/nbxtensor/issues) with what your card does — we fix fast.
208
+
86
209
  ## Concepts
87
210
 
88
211
  **Plain data at the edges.** A dtype is named by its table name (`"float16"`, `"bfloat16"` …), a shape is a tuple of
@@ -337,22 +460,21 @@ The host conversions of a weight at load are split the same way, across the load
337
460
 
338
461
  ## Hardware
339
462
 
340
- | hardware | backend | state |
341
- |---|---|---|
342
- | NVIDIA Tesla V100 (Volta, sm_70) | CUDA (`CudaDriver`, `AbiMemory`) | **proven**: the library's tests and the reference models' outputs identical to their judged sha, on a 4 x V100 rack, 2026-10-29 |
343
- | Apple M4 Pro (Apple silicon, 24 GB unified) | Metal through triton-ext (`TritonExtDriver`, `MetalMemory`) | **proven**: the library's tests, the reference models' outputs identical to their judged sha, in an environment where torch is not installed, 2026-10-29 |
344
- | NVIDIA Ampere, Hopper | CUDA | **written, not proven here**: device files exist (`backend/devices/nvidia/`), no such card on our machines |
345
- | Apple M1, M2, M3, M5 families and the other M4 chips | Metal | **written, not proven here**: device files exist (`backend/devices/apple/`); only the M4 Pro is measured |
346
- | AMD Instinct (CDNA, CDNA2, CDNA3) | HIP through the CUDA-style C ABI (`AbiMemory`) | **interface ready, not tested for lack of hardware**: memory primitives and device files exist; the HIP launch driver is still to write (`docs/nbxtensor/BACKENDS.md` section 6) |
347
- | Intel GPUs (XPU) | Level Zero (not the CUDA ABI) | **interface ready, not tested for lack of hardware**: the backend contract is documented; its `DeviceMemory` over Level Zero and its launch driver are to write (BACKENDS.md section 6) |
348
- | a CPU | none yet | **not supported** for the kernels: host work (loading, conversions) runs with numpy on every core (`backend.cpu.pool`); a CPU kernel backend is not part of 0.0.1 |
349
- | hardware with no Triton backend (NPUs, phones) | none | **not supported**: covering it needs a Triton backend for it and the five pieces of `docs/nbxtensor/BACKENDS.md` |
463
+ | vendor | backend | devices | state |
464
+ |---|---|---|---|
465
+ | NVIDIA | `cuda` (the CUDA driver and runtime) | Volta to Hopper (sm_70 to sm_90) | V100 16 GB and 32 GB: every release's gate |
466
+ | Apple | `metal` (Metal through triton-ext) | M1 to M5 | M4 Pro: every release's gate |
467
+ | AMD | `hip` (ROCm's HIP runtime) | CDNA 1 to 4, RDNA 3 and 4 | written and proven against a stand-in; no card has run it |
468
+ | Intel | `xpu` (Level Zero) | Data Center GPU Max, Arc A and B, Lunar Lake | written and proven against a stand-in; no card has run it |
469
+
470
+ Each device has a device file (`nbxtensor/backend/devices/<vendor>/*.yml`): its shared memory, warp size, tiles and
471
+ tuning screens, every value with its source.
350
472
 
351
473
  ## Backends
352
474
 
353
- CUDA (NVIDIA) and Apple Metal through triton-ext; what a new backend provides is `docs/nbxtensor/BACKENDS.md`, and
475
+ CUDA (NVIDIA), HIP (AMD), Level Zero (Intel) and Apple Metal through triton-ext; what a new backend provides is [`docs/nbxtensor/BACKENDS.md`](https://github.com/NeuroBrix/neurobrix/blob/main/docs/nbxtensor/BACKENDS.md), and
354
476
  `tests/nbxtensor_backend_conformance` is what it must pass. The backend in force is public API:
355
- `nbxtensor.backend.runtime.gpu_backend()` names it ("cuda", "hip", "metal"), `gpu_runtime()` is its runtime,
477
+ `nbxtensor.backend.runtime.gpu_backend()` names it ("cuda", "hip", "xpu", "metal"), `gpu_runtime()` is its runtime,
356
478
  `backend_table()` its entry points, `device_memory()` its memory primitives, and `set_device(tensor)` binds the
357
479
  driver to a tensor's device before a launch.
358
480
 
@@ -370,7 +492,7 @@ with the tensor class (API.md §4).
370
492
 
371
493
  ## Versions
372
494
 
373
- The first publication is **0.0.1** (this version); each fix published after it increments the number (0.0.2, 0.0.3,
495
+ The first publication was **0.0.1**; this is **0.0.2**. Each fix published after it increments the number (0.0.3,
374
496
  …), with no alpha or beta label. The rewrite of the core in Rust will be **2.0.0**. `nbxtensor.__version__` is the
375
497
  installed version.
376
498
 
@@ -1,30 +1,103 @@
1
- # nbxtensor
2
-
3
- An inference-first tensor library, torch-free.
4
-
5
- PyTorch is a general framework built for research and training in eager mode: dynamic graphs, autograd, a generic
6
- dispatcher, a caching allocator that discovers memory as the program runs. Inference is a narrower problem, and a
7
- better-informed one: the graph and the shapes are known before the first run. nbxtensor is built for that case.
8
-
9
- - **Memory is planned, not discovered.** Allocators per device behind one interface, and a static planner that
10
- assigns every buffer before the first run.
11
- - **Every kernel declares its cost.** Outputs, workspace and scratch with their lifetimes, bytes moved, flops. A
12
- planner prices a model from these declarations instead of guessing what the allocator will do.
13
- - **Capture and replay are first-class.** A repeated sequence of launches is recorded, verified byte-equal and
14
- replayed.
15
- - **One table of facts.** One dtype table, one view rule, one conversion per pair of dtypes, one capability table per
16
- backend — declared, never guessed.
17
- - **Backends:** NVIDIA CUDA, Apple Metal (through triton-ext), CPU.
18
- - **No torch, ever.** nbxtensor never imports torch, not even optionally. Exchange with any tensor library goes
19
- through the DLPack protocol (`__dlpack__`, `from_dlpack`), so a torch user writes `torch.from_dlpack(t)` on their
20
- side.
21
-
22
- nbxtensor is extracted from NeuroBrix, the universal inference engine whose Triton engine is its first client. It
23
- lives in `nbxtensor/` of the NeuroBrix repository until the extraction is complete, then in its own repository.
1
+ <p align="center"><img src="https://raw.githubusercontent.com/NeuroBrix/nbxtensor/main/assets/logo.png" alt="NeuroBrix" width="240"></p>
2
+
3
+ # nbxtensor — the torch-free tensor library for inference
4
+
5
+ Run AI models without PyTorch, on any GPU Triton supports: tensors, Triton kernels, planned memory and certified tuning.
6
+
7
+ Runs wherever Triton runs — NVIDIA, AMD, Intel and Apple Silicon GPUs. Inference first; training is not in this
8
+ release. Found a bug on your hardware? [Open an issue](https://github.com/NeuroBrix/nbxtensor/issues) — we fix fast.
9
+
10
+ [![PyPI](https://img.shields.io/pypi/v/nbxtensor)](https://pypi.org/project/nbxtensor/)
11
+ [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue)](https://github.com/NeuroBrix/nbxtensor/blob/main/LICENSE)
12
+ [![Python](https://img.shields.io/pypi/pyversions/nbxtensor)](https://pypi.org/project/nbxtensor/)
13
+ ![torch-free](https://img.shields.io/badge/torch-free-success)
14
+ ![Triton](https://img.shields.io/badge/kernels-Triton-orange)
15
+
16
+ ```
17
+ pip install nbxtensor
18
+ ```
19
+
20
+ <!-- needs-gpu -->
21
+ ```python
22
+ import numpy as np
23
+ from nbxtensor.tensor import NBXTensor
24
+ from nbxtensor.ops.linalg_wrappers import mm
25
+
26
+ rng = np.random.default_rng(0)
27
+ a = rng.standard_normal((256, 512)).astype(np.float16)
28
+ b = rng.standard_normal((512, 128)).astype(np.float16)
29
+ c = mm(NBXTensor.from_numpy(a), NBXTensor.from_numpy(b)) # a Triton kernel on the GPU, no torch
30
+ ref = a.astype(np.float32) @ b.astype(np.float32)
31
+ assert c.shape == (256, 128) and np.allclose(c.numpy().astype(np.float32), ref, rtol=2e-2, atol=2e-1)
32
+ ```
33
+
34
+ ## Why nbxtensor
35
+
36
+ - **No PyTorch.** nbxtensor never imports torch, not even optionally; its tests, kernels and NeuroBrix's models run in
37
+ an environment where torch is not installed. Exchange with any tensor library goes through DLPack (`__dlpack__`,
38
+ `from_dlpack`), so a torch user writes `torch.from_dlpack(t)` on their side.
39
+ - **Runs wherever Triton runs.** The kernels are Triton; a device is described by a file of facts (tiles, shared
40
+ memory, the matrix unit, the autotune ladders), never by code.
41
+ - **Fast.** Faster than PyTorch on many models (in NeuroBrix's gate of 2026-11-05, the Triton engine on nbxtensor beat
42
+ the PyTorch engine on 18 of 49 models on a 16 GB V100 and 17 of 49 on a 32 GB one). Still running V100s? Triton leaves
43
+ their tensor cores idle (`tl.dot` compiles to FMA on sm_70); nbxtensor turns them back on with its own `mma.m8n8k4`
44
+ kernels (matrix products, convolutions, flash attention, the fused mixture-of-experts GEMM), chosen by the certificate
45
+ only where they measured faster — an 80 x 4096 x 4096 fp16 product 0.404 -> 0.191 ms, the fused MoE prefill 2.49 ->
46
+ 0.96 ms (DeepSeek, 20 tokens) and 7.24 -> 1.40 ms (Qwen3, 512 tokens), fp32 1 x 1 convolutions 1.26-1.95 times faster
47
+ (V100, the measures recorded in [the 0.0.1 changelog](https://github.com/NeuroBrix/nbxtensor/blob/main/CHANGELOG.md#001---2026-11-05)).
48
+ - **Lightweight.** nbxtensor itself is 1 MB; the whole install, Triton included, is about 1 GB — PyTorch's is 5.6 GB.
49
+ - **Certified tuning.** Kernel settings are measured once per GPU class against a float64 oracle and shipped — no
50
+ autotuning at run time for the shapes we cover. We are certifying every model we can, so you never have to autotune.
51
+ Certified your GPU? [Share your certificates](#certify-your-own-hardware).
52
+ - **Memory is planned, not discovered.** Allocators per device behind one interface, a static planner that assigns every
53
+ buffer before the first run, and every kernel declares its cost (outputs, workspace, scratch, bytes moved, flops) so a
54
+ planner prices a model before running it. Capture and replay of a repeated sequence of launches, verified byte-equal.
55
+
56
+ ## Certify your own hardware
57
+
58
+ A kernel setting is certified per launch key (the kernel, its shape class and dtypes) and per GPU class. The keys a GPU
59
+ class has no certificate for are swept at run time and kept on your machine; certifying them makes them permanent and
60
+ shareable. Certification runs through [NeuroBrix](https://github.com/NeuroBrix/neurobrix), the engine whose models form
61
+ the keys (`pip install neurobrix`), with these commands (run as written on a clean machine, 2026-11-06):
62
+
63
+ 1. Run the models you use. Every key no certificate covers is swept and kept in `~/.neurobrix/replay_cache/`:
64
+
65
+ ```
66
+ neurobrix run --model TinyLlama-1.1B-Chat-v1.0 --triton --prompt "Hello" --max-tokens 32
67
+ ```
68
+
69
+ 2. Certify the keys your card formed — every candidate setting is run against a float64 oracle and timed; the proofs are
70
+ written into `--out`, one file per kernel and dtype under `<vendor>/<profile>/` (the profile is your GPU's device
71
+ file, e.g. `volta`):
72
+
73
+ ```
74
+ neurobrix autotune certify --profile volta \
75
+ --keys ~/.neurobrix/replay_cache/autotune_configs_cuda-70-triton_3.8.0.json --out ./my-certificates
76
+ ```
77
+
78
+ 3. Check that they are served: a certified-only run uses only certificates and fails, naming the key, if one is missing:
79
+
80
+ ```
81
+ NEUROBRIX_AUTOTUNE_CERTIFIED_DIR=./my-certificates neurobrix run --model TinyLlama-1.1B-Chat-v1.0 --triton \
82
+ --prompt "Hello" --max-tokens 32 --certified-only
83
+ ```
84
+
85
+ Its `[autotune] certified directory:` line says `0 swept at runtime`, and its output is the same as step 1's.
86
+
87
+ 4. Share them: fork [NeuroBrix](https://github.com/NeuroBrix/neurobrix), add the files of `./my-certificates/<vendor>/<profile>/`
88
+ under `src/neurobrix/config/autotune/<vendor>/<profile>/`, and open a pull request with the `certificate` template:
89
+ your GPU model, driver, the commands above and the output of step 3. Certified your GPU? Share your certificates —
90
+ every class certified is a class nobody autotunes again.
91
+
92
+
93
+ **Links:** [API reference](https://github.com/NeuroBrix/neurobrix/blob/main/docs/nbxtensor/API.md) ·
94
+ [release notes](https://github.com/NeuroBrix/nbxtensor/blob/main/CHANGELOG.md) ·
95
+ [NeuroBrix](https://github.com/NeuroBrix/neurobrix), the inference engine whose Triton engine is nbxtensor's first
96
+ client; nbxtensor's source lives in its `nbxtensor/` directory and is exported here.
24
97
 
25
98
  ## Status
26
99
 
27
- Every area below is in the library, and every public name is documented in `docs/nbxtensor/API.md` (the list of
100
+ Every area below is in the library, and every public name is documented in [`docs/nbxtensor/API.md`](https://github.com/NeuroBrix/neurobrix/blob/main/docs/nbxtensor/API.md) (the list of
28
101
  undocumented names is empty and a test keeps it so). This README documents what is in the library TODAY; every example below is executed by
29
102
  `nbxtensor/tests/test_readme.py`, so an example that stops working fails a test. The target API is
30
103
  `docs/nbxtensor/API.md`.
@@ -47,10 +120,20 @@ attempt to import torch, caught ones included, and recorded none). Python 3.10 o
47
120
  pyyaml and Triton.
48
121
 
49
122
  ```
50
- pip install -e nbxtensor # from the NeuroBrix repository
123
+ pip install nbxtensor
51
124
  ```
52
125
 
53
- **Linux, NVIDIA (CUDA).** Triton comes from PyPI with the install above.
126
+ **Linux, NVIDIA (CUDA).** Triton and the CUDA runtime library come from PyPI with the install above; the NVIDIA driver
127
+ is the only other requirement.
128
+
129
+ **Linux, AMD (ROCm) and Intel (Level Zero).** The system's GPU runtime and a Triton that compiles for the card are
130
+ needed: see [Install on AMD / Intel GPUs](#install-on-amd--intel-gpus).
131
+
132
+ **Which GPU, and what is missing.** `python -m nbxtensor doctor` names the backend in force and, for every NVIDIA, AMD
133
+ or Intel GPU on the PCI bus, whether its runtime library and its Triton backend are installed — with the vendor's
134
+ install commands when one is not.
135
+
136
+ **From the NeuroBrix repository** (contributors): `pip install -e nbxtensor`.
54
137
 
55
138
  **macOS, Apple silicon (Metal).** PyPI publishes no Triton for macOS, so Triton and its Metal backend are built from
56
139
  source, then nbxtensor is installed into that environment:
@@ -63,6 +146,46 @@ source, then nbxtensor is installed into that environment:
63
146
 
64
147
  `nbxtensor.dtype` and `nbxtensor.shape` need neither a device nor Triton.
65
148
 
149
+ ## Install on AMD / Intel GPUs
150
+
151
+ The library speaks to the card through the vendor's own runtime library, loaded at run time, and compiles its kernels
152
+ with the Triton backend for that card. When a card is present and either is missing, the library refuses with the
153
+ steps below (the same text `python -m nbxtensor doctor` prints). The commands are the vendors' (Ubuntu 24.04).
154
+
155
+ **AMD (ROCm, HIP).** The ROCm runtime, from AMD's
156
+ [quick start](https://rocm.docs.amd.com/projects/install-on-linux/en/latest/install/quick-start.html):
157
+
158
+ ```
159
+ wget https://repo.radeon.com/amdgpu-install/6.4.3/ubuntu/noble/amdgpu-install_6.4.60403-1_all.deb
160
+ sudo apt install ./amdgpu-install_6.4.60403-1_all.deb
161
+ sudo apt update && sudo apt install rocm
162
+ sudo usermod -a -G render,video $LOGNAME # then log out and in (or reboot)
163
+ pip install nbxtensor # the Triton wheel on PyPI carries the AMD backend
164
+ ```
165
+
166
+ Targets: CDNA (gfx908, gfx90a, gfx942, gfx950) and RDNA 3 / 4 (gfx11xx, gfx120x); the hardware profile states the
167
+ card's gfx arch. Triton 3.8 compiles the library's kernels for these targets on a machine without the card (the
168
+ library's tests do it).
169
+
170
+ **Intel (Level Zero).** Intel's GPU driver, from Intel's
171
+ [package guide](https://dgpu-docs.intel.com/installation-guides/installing-packages-from-the-intel-ppa.html), then
172
+ Intel's Triton build (the PyPI Triton has no Intel backend):
173
+
174
+ ```
175
+ sudo add-apt-repository -y ppa:kobuk-team/intel-graphics
176
+ sudo apt-get install -y libze-intel-gpu1 libze1 intel-opencl-icd clinfo intel-gsc
177
+ sudo usermod -a -G render $LOGNAME # then log out and in
178
+ pip install triton-xpu --index-url https://download.pytorch.org/whl/xpu
179
+ pip install nbxtensor
180
+ ```
181
+
182
+ Devices: Data Center GPU Max (Ponte Vecchio), Arc A-series and Data Center GPU Flex (Alchemist), Arc B-series
183
+ (Battlemage), Core Ultra 200V graphics (Lunar Lake); the card's PCI id selects its device file.
184
+
185
+ **Status.** The AMD and Intel drivers are written to the level of the NVIDIA and Apple ones and proven against
186
+ stand-ins of the vendors' libraries; no AMD or Intel card has run them yet. [Open an
187
+ issue](https://github.com/NeuroBrix/nbxtensor/issues) with what your card does — we fix fast.
188
+
66
189
  ## Concepts
67
190
 
68
191
  **Plain data at the edges.** A dtype is named by its table name (`"float16"`, `"bfloat16"` …), a shape is a tuple of
@@ -317,22 +440,21 @@ The host conversions of a weight at load are split the same way, across the load
317
440
 
318
441
  ## Hardware
319
442
 
320
- | hardware | backend | state |
321
- |---|---|---|
322
- | NVIDIA Tesla V100 (Volta, sm_70) | CUDA (`CudaDriver`, `AbiMemory`) | **proven**: the library's tests and the reference models' outputs identical to their judged sha, on a 4 x V100 rack, 2026-10-29 |
323
- | Apple M4 Pro (Apple silicon, 24 GB unified) | Metal through triton-ext (`TritonExtDriver`, `MetalMemory`) | **proven**: the library's tests, the reference models' outputs identical to their judged sha, in an environment where torch is not installed, 2026-10-29 |
324
- | NVIDIA Ampere, Hopper | CUDA | **written, not proven here**: device files exist (`backend/devices/nvidia/`), no such card on our machines |
325
- | Apple M1, M2, M3, M5 families and the other M4 chips | Metal | **written, not proven here**: device files exist (`backend/devices/apple/`); only the M4 Pro is measured |
326
- | AMD Instinct (CDNA, CDNA2, CDNA3) | HIP through the CUDA-style C ABI (`AbiMemory`) | **interface ready, not tested for lack of hardware**: memory primitives and device files exist; the HIP launch driver is still to write (`docs/nbxtensor/BACKENDS.md` section 6) |
327
- | Intel GPUs (XPU) | Level Zero (not the CUDA ABI) | **interface ready, not tested for lack of hardware**: the backend contract is documented; its `DeviceMemory` over Level Zero and its launch driver are to write (BACKENDS.md section 6) |
328
- | a CPU | none yet | **not supported** for the kernels: host work (loading, conversions) runs with numpy on every core (`backend.cpu.pool`); a CPU kernel backend is not part of 0.0.1 |
329
- | hardware with no Triton backend (NPUs, phones) | none | **not supported**: covering it needs a Triton backend for it and the five pieces of `docs/nbxtensor/BACKENDS.md` |
443
+ | vendor | backend | devices | state |
444
+ |---|---|---|---|
445
+ | NVIDIA | `cuda` (the CUDA driver and runtime) | Volta to Hopper (sm_70 to sm_90) | V100 16 GB and 32 GB: every release's gate |
446
+ | Apple | `metal` (Metal through triton-ext) | M1 to M5 | M4 Pro: every release's gate |
447
+ | AMD | `hip` (ROCm's HIP runtime) | CDNA 1 to 4, RDNA 3 and 4 | written and proven against a stand-in; no card has run it |
448
+ | Intel | `xpu` (Level Zero) | Data Center GPU Max, Arc A and B, Lunar Lake | written and proven against a stand-in; no card has run it |
449
+
450
+ Each device has a device file (`nbxtensor/backend/devices/<vendor>/*.yml`): its shared memory, warp size, tiles and
451
+ tuning screens, every value with its source.
330
452
 
331
453
  ## Backends
332
454
 
333
- CUDA (NVIDIA) and Apple Metal through triton-ext; what a new backend provides is `docs/nbxtensor/BACKENDS.md`, and
455
+ CUDA (NVIDIA), HIP (AMD), Level Zero (Intel) and Apple Metal through triton-ext; what a new backend provides is [`docs/nbxtensor/BACKENDS.md`](https://github.com/NeuroBrix/neurobrix/blob/main/docs/nbxtensor/BACKENDS.md), and
334
456
  `tests/nbxtensor_backend_conformance` is what it must pass. The backend in force is public API:
335
- `nbxtensor.backend.runtime.gpu_backend()` names it ("cuda", "hip", "metal"), `gpu_runtime()` is its runtime,
457
+ `nbxtensor.backend.runtime.gpu_backend()` names it ("cuda", "hip", "xpu", "metal"), `gpu_runtime()` is its runtime,
336
458
  `backend_table()` its entry points, `device_memory()` its memory primitives, and `set_device(tensor)` binds the
337
459
  driver to a tensor's device before a launch.
338
460
 
@@ -350,7 +472,7 @@ with the tensor class (API.md §4).
350
472
 
351
473
  ## Versions
352
474
 
353
- The first publication is **0.0.1** (this version); each fix published after it increments the number (0.0.2, 0.0.3,
475
+ The first publication was **0.0.1**; this is **0.0.2**. Each fix published after it increments the number (0.0.3,
354
476
  …), with no alpha or beta label. The rewrite of the core in Rust will be **2.0.0**. `nbxtensor.__version__` is the
355
477
  installed version.
356
478
 
Binary file