tensorstudio 1.0.0__tar.gz → 1.0.1__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 (126) hide show
  1. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/.github/workflows/ci.yml +12 -0
  2. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/.github/workflows/publish-testpypi.yml +1 -0
  3. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/.github/workflows/publish.yml +7 -1
  4. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/CHANGELOG.md +12 -0
  5. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/CMakeLists.txt +1 -1
  6. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/PKG-INFO +18 -10
  7. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/README.md +17 -9
  8. tensorstudio-1.0.1/benchmark_all.py +48 -0
  9. tensorstudio-1.0.1/benchmarks/__init__.py +2 -0
  10. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/benchmarks/benchmark_report.py +25 -3
  11. tensorstudio-1.0.1/benchmarks/results.md +311 -0
  12. tensorstudio-1.0.1/benchmarks/results_matmul.md +45 -0
  13. tensorstudio-1.0.1/benchmarks/results_reductions.md +75 -0
  14. tensorstudio-1.0.1/benchmarks/results_tensor_ops.md +285 -0
  15. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/Autograde/index.md +1 -1
  16. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/Benchmarks/index.md +7 -2
  17. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/Hardware/cpu-backend.md +1 -1
  18. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/Neural Networks/training.md +1 -1
  19. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/Roadmap/index.md +1 -1
  20. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/Usage/serialization.md +1 -1
  21. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/Usage/tensors.md +1 -1
  22. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/development.md +7 -0
  23. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/index.md +1 -1
  24. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/publishing.md +9 -7
  25. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/serialization.md +1 -1
  26. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/include/tensorstudio/version.hpp +1 -1
  27. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/mkdocs.yml +12 -0
  28. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/pyproject.toml +1 -1
  29. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/_version.py +1 -1
  30. tensorstudio-1.0.1/test_all.py +102 -0
  31. tensorstudio-1.0.1/tests/test_benchmark_report.py +71 -0
  32. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/tests/test_import.py +1 -1
  33. tensorstudio-1.0.0/benchmarks/results.md +0 -310
  34. tensorstudio-1.0.0/benchmarks/results_matmul.md +0 -44
  35. tensorstudio-1.0.0/benchmarks/results_reductions.md +0 -58
  36. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/.github/workflows/wheels.yml +0 -0
  37. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/.gitignore +0 -0
  38. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/.pre-commit-config.yaml +0 -0
  39. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/CONTRIBUTING.md +0 -0
  40. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/LICENSE +0 -0
  41. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/SECURITY.md +0 -0
  42. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/benchmarks/bench_activations.py +0 -0
  43. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/benchmarks/bench_autograd.py +0 -0
  44. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/benchmarks/bench_elementwise.py +0 -0
  45. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/benchmarks/bench_matmul.py +0 -0
  46. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/benchmarks/bench_reductions.py +0 -0
  47. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/benchmarks/bench_tensor_ops.py +0 -0
  48. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/benchmarks/bench_training_loop.py +0 -0
  49. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/Neural Networks/modules.md +0 -0
  50. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/Usage/numpy-interop.md +0 -0
  51. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/api.md +0 -0
  52. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/autograd.md +0 -0
  53. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/data.md +0 -0
  54. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/linux.md +0 -0
  55. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/macos.md +0 -0
  56. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/nn.md +0 -0
  57. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/optim.md +0 -0
  58. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/quickstart.md +0 -0
  59. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/tensors.md +0 -0
  60. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/docs/windows.md +0 -0
  61. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/examples/basic_tensor_ops.py +0 -0
  62. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/examples/linear_regression.py +0 -0
  63. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/examples/save_load_model.py +0 -0
  64. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/examples/tiny_mlp.py +0 -0
  65. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/include/tensorstudio/autograd.hpp +0 -0
  66. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/include/tensorstudio/device.hpp +0 -0
  67. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/include/tensorstudio/dtype.hpp +0 -0
  68. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/include/tensorstudio/errors.hpp +0 -0
  69. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/include/tensorstudio/module.hpp +0 -0
  70. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/include/tensorstudio/ops.hpp +0 -0
  71. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/include/tensorstudio/optim.hpp +0 -0
  72. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/include/tensorstudio/random.hpp +0 -0
  73. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/include/tensorstudio/serialization.hpp +0 -0
  74. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/include/tensorstudio/shape.hpp +0 -0
  75. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/include/tensorstudio/storage.hpp +0 -0
  76. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/include/tensorstudio/tensor.hpp +0 -0
  77. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/_C.pyi +0 -0
  78. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/__init__.py +0 -0
  79. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/autograd.py +0 -0
  80. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/data/__init__.py +0 -0
  81. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/data/dataloader.py +0 -0
  82. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/data/dataset.py +0 -0
  83. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/errors.py +0 -0
  84. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/grad_mode.py +0 -0
  85. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/nn/__init__.py +0 -0
  86. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/nn/functional.py +0 -0
  87. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/nn/losses.py +0 -0
  88. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/nn/modules.py +0 -0
  89. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/ops.py +0 -0
  90. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/optim/__init__.py +0 -0
  91. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/optim/adam.py +0 -0
  92. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/optim/adamw.py +0 -0
  93. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/optim/lr_scheduler.py +0 -0
  94. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/optim/sgd.py +0 -0
  95. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/optim/utils.py +0 -0
  96. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/py.typed +0 -0
  97. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/serialization.py +0 -0
  98. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/tensor.py +0 -0
  99. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/python/tensorstudio/typing.py +0 -0
  100. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/bindings/bind_autograd.cpp +0 -0
  101. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/bindings/bind_nn.cpp +0 -0
  102. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/bindings/bind_ops.cpp +0 -0
  103. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/bindings/bind_optim.cpp +0 -0
  104. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/bindings/bind_tensor.cpp +0 -0
  105. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/bindings/bindings.cpp +0 -0
  106. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/bindings/bindings.hpp +0 -0
  107. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/core/autograd.cpp +0 -0
  108. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/core/device.cpp +0 -0
  109. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/core/dtype.cpp +0 -0
  110. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/core/errors.cpp +0 -0
  111. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/core/module.cpp +0 -0
  112. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/core/ops.cpp +0 -0
  113. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/core/optim.cpp +0 -0
  114. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/core/random.cpp +0 -0
  115. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/core/serialization.cpp +0 -0
  116. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/core/shape.cpp +0 -0
  117. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/core/storage.cpp +0 -0
  118. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/src/core/tensor.cpp +0 -0
  119. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/tests/test_autograd.py +0 -0
  120. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/tests/test_data.py +0 -0
  121. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/tests/test_nn.py +0 -0
  122. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/tests/test_numpy_interop.py +0 -0
  123. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/tests/test_ops.py +0 -0
  124. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/tests/test_optim.py +0 -0
  125. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/tests/test_serialization.py +0 -0
  126. {tensorstudio-1.0.0 → tensorstudio-1.0.1}/tests/test_tensor.py +0 -0
@@ -30,6 +30,10 @@ jobs:
30
30
  run: mypy --python-version ${{ matrix.python-version }} python/tensorstudio
31
31
  - name: Tests
32
32
  run: pytest -q
33
+ - name: Runner scripts
34
+ run: |
35
+ python test_all.py --help
36
+ python benchmark_all.py --help
33
37
  - name: Example
34
38
  run: python examples/basic_tensor_ops.py
35
39
 
@@ -59,6 +63,10 @@ jobs:
59
63
  run: mypy --python-version ${{ matrix.python-version }} python/tensorstudio
60
64
  - name: Tests
61
65
  run: pytest -q
66
+ - name: Runner scripts
67
+ run: |
68
+ python test_all.py --help
69
+ python benchmark_all.py --help
62
70
  - name: Example
63
71
  run: python examples/basic_tensor_ops.py
64
72
 
@@ -88,5 +96,9 @@ jobs:
88
96
  run: mypy --python-version ${{ matrix.python-version }} python/tensorstudio
89
97
  - name: Tests
90
98
  run: pytest -q
99
+ - name: Runner scripts
100
+ run: |
101
+ python test_all.py --help
102
+ python benchmark_all.py --help
91
103
  - name: Example
92
104
  run: python examples/basic_tensor_ops.py
@@ -106,3 +106,4 @@ jobs:
106
106
  uses: pypa/gh-action-pypi-publish@release/v1
107
107
  with:
108
108
  repository-url: https://test.pypi.org/legacy/
109
+ skip-existing: true
@@ -6,7 +6,7 @@ on:
6
6
  types: [published]
7
7
  push:
8
8
  tags:
9
- - "v1.0.0"
9
+ - "v*"
10
10
 
11
11
  permissions:
12
12
  contents: read
@@ -103,5 +103,11 @@ jobs:
103
103
  pattern: dist-*
104
104
  path: dist
105
105
  merge-multiple: true
106
+ - name: Verify artifacts
107
+ run: |
108
+ python -m pip install -U twine
109
+ python -m twine check dist/*
106
110
  - name: Publish to PyPI
107
111
  uses: pypa/gh-action-pypi-publish@release/v1
112
+ with:
113
+ skip-existing: true
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.1
4
+
5
+ - Added `test_all.py` for one-command local release checks covering lint,
6
+ typing, tests, examples, docs, build, and package metadata validation.
7
+ - Added `benchmark_all.py` for one-command full benchmark report generation.
8
+ - Added explicit benchmark win columns for NumPy, TensorFlow, PyTorch, and JAX,
9
+ plus fastest-library reporting for each benchmark case.
10
+ - Hardened release publishing triggers so future `v*` tags are eligible for
11
+ the publish workflow instead of only `v1.0.0`.
12
+ - Updated docs to describe benchmark interpretation, local release checks, and
13
+ site navigation for benchmark, hardware, roadmap, and usage pages.
14
+
3
15
  ## 1.0.0
4
16
 
5
17
  - Promoted the CPU-only stable API foundation from release candidate status.
@@ -1,6 +1,6 @@
1
1
  cmake_minimum_required(VERSION 3.18)
2
2
 
3
- project(tensorstudio VERSION 1.0.0 LANGUAGES CXX)
3
+ project(tensorstudio VERSION 1.0.1 LANGUAGES CXX)
4
4
 
5
5
  find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)
6
6
  set(PYBIND11_FINDPYTHON ON)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tensorstudio
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: TensorStudio is a compact C++ tensor and autograd engine with a Python API for learning, experimentation, and lightweight ML workloads.
5
5
  Keywords: tensor,autograd,machine-learning,cpp,pybind11
6
6
  Author: TensorStudio contributors
@@ -65,7 +65,7 @@ Description-Content-Type: text/markdown
65
65
  TensorStudio is a compact C++ tensor and autograd engine with a Python API for
66
66
  learning, experimentation, and lightweight ML workloads.
67
67
 
68
- TensorStudio `1.0.0` is a CPU-only stable API foundation. It is eager-only,
68
+ TensorStudio `1.0.1` is a CPU-only stable API foundation. It is eager-only,
69
69
  intentionally small, and not a replacement for mature ML frameworks.
70
70
 
71
71
  ## Install
@@ -227,13 +227,18 @@ performance is still experimental. Benchmarks live in `benchmarks/` and can be
227
227
  run locally:
228
228
 
229
229
  ```bash
230
+ python benchmark_all.py
230
231
  python benchmarks/benchmark_report.py
231
232
  ```
232
233
 
233
- On one Windows CPython 3.10 run for `1.0.0`, TensorStudio beat NumPy on 13
234
+ `benchmark_all.py` writes `benchmarks/results.md` and includes explicit win
235
+ columns for NumPy, TensorFlow, PyTorch, and JAX when those libraries are
236
+ available locally.
237
+
238
+ On one Windows CPython 3.10 run for `1.0.1`, TensorStudio beat NumPy on 13
234
239
  small activation/reduction benchmark cases and lost on 76 NumPy-comparable
235
- cases. Against PyTorch CPU `2.12.1+cpu`, TensorStudio won 68 local cases and
236
- lost 26. The strongest local wins were small eager operations where framework
240
+ cases. Against PyTorch CPU `2.12.1+cpu`, TensorStudio won 71 local cases and
241
+ lost 23. The strongest local wins were small eager operations where framework
237
242
  dispatch overhead dominates; larger matrix multiplication, larger transcendental
238
243
  activations, and larger autograd workloads remain faster in PyTorch and NumPy.
239
244
  See `benchmarks/results.md` for the full table, platform details, and exact
@@ -243,11 +248,11 @@ Snapshot from that local run:
243
248
 
244
249
  | operation | shape | TensorStudio | NumPy | PyTorch CPU | TS vs NumPy | TS vs PyTorch |
245
250
  |---|---:|---:|---:|---:|---:|---:|
246
- | `sigmoid` | `(32,)` | 0.0018 ms | 0.0049 ms | 0.0638 ms | 2.7548x | 35.6408x |
247
- | `mean` | `(32,)` | 0.0016 ms | 0.0071 ms | 0.0110 ms | 4.3608x | 6.7855x |
248
- | `chain_relu` | `(128,)` | 0.0089 ms | 0.0039 ms | 0.0545 ms | 0.4410x | 6.1384x |
249
- | `matmul` | `(256, 256)` | 3.0180 ms | 0.4115 ms | 0.1392 ms | 0.1363x | 0.0461x |
250
- | `elementwise_backward` | `(1024,)` | 2.3844 ms | n/a | 0.1830 ms | n/a | 0.0767x |
251
+ | `sigmoid` | `(32,)` | 0.0018 ms | 0.0036 ms | 0.0575 ms | 2.0414x | 32.2110x |
252
+ | `mean` | `(32,)` | 0.0016 ms | 0.0069 ms | 0.0112 ms | 4.4051x | 7.1262x |
253
+ | `chain_relu` | `(128,)` | 0.0086 ms | 0.0039 ms | 0.0567 ms | 0.4488x | 6.5977x |
254
+ | `matmul` | `(256, 256)` | 2.4215 ms | 0.4027 ms | 0.0832 ms | 0.1663x | 0.0343x |
255
+ | `elementwise_backward` | `(1024,)` | 2.3527 ms | n/a | 0.1887 ms | n/a | 0.0802x |
251
256
 
252
257
  Speedup is `competitor median / TensorStudio median`, so values above `1.0x`
253
258
  favor TensorStudio.
@@ -273,6 +278,7 @@ unsafe because pickle can execute arbitrary code.
273
278
 
274
279
  ```bash
275
280
  python -m pip install -e ".[dev,docs]"
281
+ python test_all.py --skip-build
276
282
  ruff check .
277
283
  mypy python/tensorstudio
278
284
  pytest -q
@@ -285,6 +291,7 @@ scikit-build-core, and C++20.
285
291
 
286
292
  ## Release Checklist
287
293
 
294
+ - `python test_all.py` passes locally.
288
295
  - `ruff check .` passes.
289
296
  - `mypy python/tensorstudio` passes.
290
297
  - `pytest -q` passes on Windows, Linux, and macOS.
@@ -309,6 +316,7 @@ tokens or print secrets.
309
316
  - CPU backend only.
310
317
  - Eager execution only.
311
318
  - No CUDA or Metal backend yet.
319
+ - No BLAS-backed matrix multiplication yet.
312
320
  - No graph compiler or distributed runtime.
313
321
  - No convolution layers yet.
314
322
  - No sparse tensors or advanced indexing.
@@ -7,7 +7,7 @@
7
7
  TensorStudio is a compact C++ tensor and autograd engine with a Python API for
8
8
  learning, experimentation, and lightweight ML workloads.
9
9
 
10
- TensorStudio `1.0.0` is a CPU-only stable API foundation. It is eager-only,
10
+ TensorStudio `1.0.1` is a CPU-only stable API foundation. It is eager-only,
11
11
  intentionally small, and not a replacement for mature ML frameworks.
12
12
 
13
13
  ## Install
@@ -169,13 +169,18 @@ performance is still experimental. Benchmarks live in `benchmarks/` and can be
169
169
  run locally:
170
170
 
171
171
  ```bash
172
+ python benchmark_all.py
172
173
  python benchmarks/benchmark_report.py
173
174
  ```
174
175
 
175
- On one Windows CPython 3.10 run for `1.0.0`, TensorStudio beat NumPy on 13
176
+ `benchmark_all.py` writes `benchmarks/results.md` and includes explicit win
177
+ columns for NumPy, TensorFlow, PyTorch, and JAX when those libraries are
178
+ available locally.
179
+
180
+ On one Windows CPython 3.10 run for `1.0.1`, TensorStudio beat NumPy on 13
176
181
  small activation/reduction benchmark cases and lost on 76 NumPy-comparable
177
- cases. Against PyTorch CPU `2.12.1+cpu`, TensorStudio won 68 local cases and
178
- lost 26. The strongest local wins were small eager operations where framework
182
+ cases. Against PyTorch CPU `2.12.1+cpu`, TensorStudio won 71 local cases and
183
+ lost 23. The strongest local wins were small eager operations where framework
179
184
  dispatch overhead dominates; larger matrix multiplication, larger transcendental
180
185
  activations, and larger autograd workloads remain faster in PyTorch and NumPy.
181
186
  See `benchmarks/results.md` for the full table, platform details, and exact
@@ -185,11 +190,11 @@ Snapshot from that local run:
185
190
 
186
191
  | operation | shape | TensorStudio | NumPy | PyTorch CPU | TS vs NumPy | TS vs PyTorch |
187
192
  |---|---:|---:|---:|---:|---:|---:|
188
- | `sigmoid` | `(32,)` | 0.0018 ms | 0.0049 ms | 0.0638 ms | 2.7548x | 35.6408x |
189
- | `mean` | `(32,)` | 0.0016 ms | 0.0071 ms | 0.0110 ms | 4.3608x | 6.7855x |
190
- | `chain_relu` | `(128,)` | 0.0089 ms | 0.0039 ms | 0.0545 ms | 0.4410x | 6.1384x |
191
- | `matmul` | `(256, 256)` | 3.0180 ms | 0.4115 ms | 0.1392 ms | 0.1363x | 0.0461x |
192
- | `elementwise_backward` | `(1024,)` | 2.3844 ms | n/a | 0.1830 ms | n/a | 0.0767x |
193
+ | `sigmoid` | `(32,)` | 0.0018 ms | 0.0036 ms | 0.0575 ms | 2.0414x | 32.2110x |
194
+ | `mean` | `(32,)` | 0.0016 ms | 0.0069 ms | 0.0112 ms | 4.4051x | 7.1262x |
195
+ | `chain_relu` | `(128,)` | 0.0086 ms | 0.0039 ms | 0.0567 ms | 0.4488x | 6.5977x |
196
+ | `matmul` | `(256, 256)` | 2.4215 ms | 0.4027 ms | 0.0832 ms | 0.1663x | 0.0343x |
197
+ | `elementwise_backward` | `(1024,)` | 2.3527 ms | n/a | 0.1887 ms | n/a | 0.0802x |
193
198
 
194
199
  Speedup is `competitor median / TensorStudio median`, so values above `1.0x`
195
200
  favor TensorStudio.
@@ -215,6 +220,7 @@ unsafe because pickle can execute arbitrary code.
215
220
 
216
221
  ```bash
217
222
  python -m pip install -e ".[dev,docs]"
223
+ python test_all.py --skip-build
218
224
  ruff check .
219
225
  mypy python/tensorstudio
220
226
  pytest -q
@@ -227,6 +233,7 @@ scikit-build-core, and C++20.
227
233
 
228
234
  ## Release Checklist
229
235
 
236
+ - `python test_all.py` passes locally.
230
237
  - `ruff check .` passes.
231
238
  - `mypy python/tensorstudio` passes.
232
239
  - `pytest -q` passes on Windows, Linux, and macOS.
@@ -251,6 +258,7 @@ tokens or print secrets.
251
258
  - CPU backend only.
252
259
  - Eager execution only.
253
260
  - No CUDA or Metal backend yet.
261
+ - No BLAS-backed matrix multiplication yet.
254
262
  - No graph compiler or distributed runtime.
255
263
  - No convolution layers yet.
256
264
  - No sparse tensors or advanced indexing.
@@ -0,0 +1,48 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ from pathlib import Path
5
+
6
+ from benchmarks.benchmark_report import run_benchmarks
7
+
8
+ ALL_SECTIONS = {
9
+ "elementwise",
10
+ "matmul",
11
+ "reductions",
12
+ "activations",
13
+ "autograd",
14
+ "training_loop",
15
+ }
16
+
17
+
18
+ def main() -> None:
19
+ parser = argparse.ArgumentParser(description="Run every TensorStudio benchmark section.")
20
+ parser.add_argument(
21
+ "--section",
22
+ action="append",
23
+ choices=sorted(ALL_SECTIONS),
24
+ help="Run only the selected section. Repeat for multiple sections.",
25
+ )
26
+ parser.add_argument(
27
+ "--output",
28
+ type=Path,
29
+ default=Path("benchmarks") / "results.md",
30
+ help="Markdown report path. Defaults to benchmarks/results.md.",
31
+ )
32
+ parser.add_argument(
33
+ "--print",
34
+ action="store_true",
35
+ help="Print the full Markdown report after writing it.",
36
+ )
37
+ args = parser.parse_args()
38
+
39
+ selected_sections = set(args.section or ALL_SECTIONS)
40
+ report = run_benchmarks(selected_sections, args.output)
41
+ if args.print:
42
+ print(report)
43
+ else:
44
+ print(f"Wrote benchmark report to {args.output}")
45
+
46
+
47
+ if __name__ == "__main__":
48
+ main()
@@ -0,0 +1,2 @@
1
+ """Local TensorStudio benchmark helpers."""
2
+
@@ -539,12 +539,24 @@ def _format_float(value: float | None) -> str:
539
539
  return f"{value:.4f}"
540
540
 
541
541
 
542
+ def _format_win(value: float | None) -> str:
543
+ if value is None:
544
+ return "n/a"
545
+ return "yes" if value > 1.0 else "no"
546
+
547
+
542
548
  def _speedup(ts_ms: float | None, competitor_ms: float | None) -> float | None:
543
549
  if ts_ms is None or competitor_ms is None or ts_ms <= 0:
544
550
  return None
545
551
  return competitor_ms / ts_ms
546
552
 
547
553
 
554
+ def _fastest_library(medians: dict[str, float]) -> str:
555
+ if not medians:
556
+ return "n/a"
557
+ return min(medians.items(), key=lambda item: item[1])[0]
558
+
559
+
548
560
  def _run_cases(cases: Iterable[BenchmarkCase], libraries: list[Library]) -> dict[str, Stats]:
549
561
  results: dict[str, Stats] = {}
550
562
  for case in cases:
@@ -640,10 +652,13 @@ def _render_report(
640
652
  lines.append("")
641
653
  lines.append(
642
654
  "| category | operation | shape | library | median ms | mean ms | min ms | "
643
- "max ms | std ms | TS vs NumPy | TS vs TensorFlow | TS vs PyTorch | TS vs JAX | result |"
655
+ "max ms | std ms | TS vs NumPy | TS vs TensorFlow | TS vs PyTorch | TS vs JAX | "
656
+ "win vs NumPy | win vs TensorFlow | win vs PyTorch | win vs JAX | "
657
+ "fastest library | result |"
644
658
  )
645
659
  lines.append(
646
- "|---|---|---:|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---|"
660
+ "|---|---|---:|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|"
661
+ "---|---|---|---|---|---|"
647
662
  )
648
663
 
649
664
  for case in cases:
@@ -668,6 +683,7 @@ def _render_report(
668
683
  medians.get("JAX CPU dispatch"),
669
684
  ),
670
685
  }
686
+ fastest = _fastest_library(medians)
671
687
  for library in libraries:
672
688
  stats = results.get(_result_key(case, library.name))
673
689
  if stats is None:
@@ -692,13 +708,19 @@ def _render_report(
692
708
  f"{_format_float(speedups['NumPy'])} | "
693
709
  f"{_format_float(speedups['TensorFlow CPU eager'])} | "
694
710
  f"{_format_float(speedups['PyTorch CPU'])} | "
695
- f"{_format_float(speedups['JAX CPU dispatch'])} | {result} |"
711
+ f"{_format_float(speedups['JAX CPU dispatch'])} | "
712
+ f"{_format_win(speedups['NumPy'])} | "
713
+ f"{_format_win(speedups['TensorFlow CPU eager'])} | "
714
+ f"{_format_win(speedups['PyTorch CPU'])} | "
715
+ f"{_format_win(speedups['JAX CPU dispatch'])} | "
716
+ f"{fastest} | {result} |"
696
717
  )
697
718
  lines.append("")
698
719
  lines.append(
699
720
  "Speedup columns are `competitor median / TensorStudio median`; values above 1.0 mean"
700
721
  )
701
722
  lines.append("TensorStudio was faster for that specific case.")
723
+ lines.append("Win columns say whether that same speedup is above 1.0 for the competitor.")
702
724
  lines.append("")
703
725
  return "\n".join(lines)
704
726