tensorstudio 1.0.1__tar.gz → 1.2.0__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 (148) hide show
  1. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/.github/workflows/publish.yml +10 -4
  2. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/CHANGELOG.md +38 -0
  3. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/PKG-INFO +104 -18
  4. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/README.md +97 -17
  5. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/benchmark_all.py +2 -0
  6. tensorstudio-1.2.0/benchmarks/bench_conv2d.py +8 -0
  7. tensorstudio-1.2.0/benchmarks/bench_pooling.py +8 -0
  8. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/benchmarks/benchmark_report.py +220 -5
  9. tensorstudio-1.2.0/benchmarks/results.md +353 -0
  10. tensorstudio-1.2.0/benchmarks/results_conv2d.md +39 -0
  11. tensorstudio-1.2.0/benchmarks/results_pooling.md +45 -0
  12. tensorstudio-1.2.0/benchmarks/results_tensor_ops.md +309 -0
  13. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/docs/Autograde/index.md +1 -1
  14. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/docs/Benchmarks/index.md +25 -4
  15. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/docs/Hardware/cpu-backend.md +1 -1
  16. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/docs/Neural Networks/modules.md +40 -0
  17. tensorstudio-1.0.1/docs/nn.md → tensorstudio-1.2.0/docs/Neural Networks/nn.md +45 -0
  18. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/docs/Neural Networks/training.md +1 -1
  19. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/docs/Roadmap/index.md +8 -7
  20. {tensorstudio-1.0.1/docs → tensorstudio-1.2.0/docs/Usage}/api.md +72 -6
  21. tensorstudio-1.2.0/docs/Usage/interchange.md +68 -0
  22. tensorstudio-1.2.0/docs/Usage/serialization.md +78 -0
  23. {tensorstudio-1.0.1/docs → tensorstudio-1.2.0/docs/Usage}/tensors.md +32 -1
  24. tensorstudio-1.2.0/docs/Vision/index.md +83 -0
  25. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/docs/development.md +1 -1
  26. tensorstudio-1.2.0/docs/index.md +76 -0
  27. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/docs/publishing.md +13 -10
  28. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/docs/quickstart.md +85 -1
  29. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/docs/serialization.md +25 -4
  30. tensorstudio-1.2.0/examples/export_onnx.py +29 -0
  31. tensorstudio-1.2.0/examples/vision_classifier.py +30 -0
  32. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/include/tensorstudio/ops.hpp +36 -0
  33. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/include/tensorstudio/version.hpp +1 -1
  34. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/mkdocs.yml +11 -9
  35. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/pyproject.toml +9 -1
  36. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/_C.pyi +45 -8
  37. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/__init__.py +15 -2
  38. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/_version.py +1 -1
  39. tensorstudio-1.2.0/python/tensorstudio/interchange/__init__.py +7 -0
  40. tensorstudio-1.2.0/python/tensorstudio/interchange/onnx.py +299 -0
  41. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/nn/__init__.py +20 -1
  42. tensorstudio-1.2.0/python/tensorstudio/nn/functional.py +167 -0
  43. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/nn/losses.py +14 -1
  44. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/nn/modules.py +165 -0
  45. tensorstudio-1.2.0/python/tensorstudio/ops.py +262 -0
  46. tensorstudio-1.2.0/python/tensorstudio/serialization.py +136 -0
  47. tensorstudio-1.2.0/python/tensorstudio/vision/__init__.py +15 -0
  48. tensorstudio-1.2.0/python/tensorstudio/vision/models.py +59 -0
  49. tensorstudio-1.2.0/python/tensorstudio/vision/transforms.py +184 -0
  50. tensorstudio-1.2.0/src/bindings/bind_ops.cpp +118 -0
  51. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/bindings/bind_tensor.cpp +30 -4
  52. tensorstudio-1.2.0/src/core/ops.cpp +2356 -0
  53. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/test_all.py +2 -6
  54. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/tests/test_autograd.py +82 -0
  55. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/tests/test_import.py +3 -1
  56. tensorstudio-1.2.0/tests/test_interchange.py +43 -0
  57. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/tests/test_nn.py +97 -0
  58. tensorstudio-1.2.0/tests/test_ops.py +314 -0
  59. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/tests/test_serialization.py +26 -0
  60. tensorstudio-1.2.0/tests/test_vision.py +52 -0
  61. tensorstudio-1.0.1/benchmarks/results.md +0 -311
  62. tensorstudio-1.0.1/benchmarks/results_tensor_ops.md +0 -285
  63. tensorstudio-1.0.1/docs/Usage/serialization.md +0 -43
  64. tensorstudio-1.0.1/docs/Usage/tensors.md +0 -139
  65. tensorstudio-1.0.1/docs/index.md +0 -67
  66. tensorstudio-1.0.1/python/tensorstudio/nn/functional.py +0 -75
  67. tensorstudio-1.0.1/python/tensorstudio/ops.py +0 -157
  68. tensorstudio-1.0.1/python/tensorstudio/serialization.py +0 -34
  69. tensorstudio-1.0.1/src/bindings/bind_ops.cpp +0 -40
  70. tensorstudio-1.0.1/src/core/ops.cpp +0 -1136
  71. tensorstudio-1.0.1/tests/test_ops.py +0 -63
  72. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/.github/workflows/ci.yml +0 -0
  73. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/.github/workflows/publish-testpypi.yml +0 -0
  74. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/.github/workflows/wheels.yml +0 -0
  75. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/.gitignore +0 -0
  76. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/.pre-commit-config.yaml +0 -0
  77. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/CMakeLists.txt +0 -0
  78. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/CONTRIBUTING.md +0 -0
  79. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/LICENSE +0 -0
  80. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/SECURITY.md +0 -0
  81. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/benchmarks/__init__.py +0 -0
  82. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/benchmarks/bench_activations.py +0 -0
  83. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/benchmarks/bench_autograd.py +0 -0
  84. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/benchmarks/bench_elementwise.py +0 -0
  85. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/benchmarks/bench_matmul.py +0 -0
  86. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/benchmarks/bench_reductions.py +0 -0
  87. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/benchmarks/bench_tensor_ops.py +0 -0
  88. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/benchmarks/bench_training_loop.py +0 -0
  89. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/benchmarks/results_matmul.md +0 -0
  90. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/benchmarks/results_reductions.md +0 -0
  91. {tensorstudio-1.0.1/docs → tensorstudio-1.2.0/docs/Autograde}/autograd.md +0 -0
  92. {tensorstudio-1.0.1/docs → tensorstudio-1.2.0/docs/Hardware}/linux.md +0 -0
  93. {tensorstudio-1.0.1/docs → tensorstudio-1.2.0/docs/Hardware}/macos.md +0 -0
  94. {tensorstudio-1.0.1/docs → tensorstudio-1.2.0/docs/Hardware}/windows.md +0 -0
  95. {tensorstudio-1.0.1/docs → tensorstudio-1.2.0/docs/Usage}/data.md +0 -0
  96. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/docs/Usage/numpy-interop.md +0 -0
  97. {tensorstudio-1.0.1/docs → tensorstudio-1.2.0/docs/Usage}/optim.md +0 -0
  98. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/examples/basic_tensor_ops.py +0 -0
  99. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/examples/linear_regression.py +0 -0
  100. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/examples/save_load_model.py +0 -0
  101. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/examples/tiny_mlp.py +0 -0
  102. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/include/tensorstudio/autograd.hpp +0 -0
  103. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/include/tensorstudio/device.hpp +0 -0
  104. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/include/tensorstudio/dtype.hpp +0 -0
  105. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/include/tensorstudio/errors.hpp +0 -0
  106. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/include/tensorstudio/module.hpp +0 -0
  107. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/include/tensorstudio/optim.hpp +0 -0
  108. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/include/tensorstudio/random.hpp +0 -0
  109. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/include/tensorstudio/serialization.hpp +0 -0
  110. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/include/tensorstudio/shape.hpp +0 -0
  111. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/include/tensorstudio/storage.hpp +0 -0
  112. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/include/tensorstudio/tensor.hpp +0 -0
  113. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/autograd.py +0 -0
  114. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/data/__init__.py +0 -0
  115. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/data/dataloader.py +0 -0
  116. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/data/dataset.py +0 -0
  117. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/errors.py +0 -0
  118. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/grad_mode.py +0 -0
  119. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/optim/__init__.py +0 -0
  120. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/optim/adam.py +0 -0
  121. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/optim/adamw.py +0 -0
  122. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/optim/lr_scheduler.py +0 -0
  123. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/optim/sgd.py +0 -0
  124. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/optim/utils.py +0 -0
  125. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/py.typed +0 -0
  126. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/tensor.py +0 -0
  127. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/python/tensorstudio/typing.py +0 -0
  128. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/bindings/bind_autograd.cpp +0 -0
  129. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/bindings/bind_nn.cpp +0 -0
  130. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/bindings/bind_optim.cpp +0 -0
  131. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/bindings/bindings.cpp +0 -0
  132. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/bindings/bindings.hpp +0 -0
  133. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/core/autograd.cpp +0 -0
  134. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/core/device.cpp +0 -0
  135. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/core/dtype.cpp +0 -0
  136. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/core/errors.cpp +0 -0
  137. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/core/module.cpp +0 -0
  138. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/core/optim.cpp +0 -0
  139. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/core/random.cpp +0 -0
  140. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/core/serialization.cpp +0 -0
  141. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/core/shape.cpp +0 -0
  142. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/core/storage.cpp +0 -0
  143. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/src/core/tensor.cpp +0 -0
  144. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/tests/test_benchmark_report.py +0 -0
  145. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/tests/test_data.py +0 -0
  146. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/tests/test_numpy_interop.py +0 -0
  147. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/tests/test_optim.py +0 -0
  148. {tensorstudio-1.0.1 → tensorstudio-1.2.0}/tests/test_tensor.py +0 -0
@@ -4,9 +4,6 @@ on:
4
4
  workflow_dispatch:
5
5
  release:
6
6
  types: [published]
7
- push:
8
- tags:
9
- - "v*"
10
7
 
11
8
  permissions:
12
9
  contents: read
@@ -97,6 +94,8 @@ jobs:
97
94
  needs: [windows_wheels, linux_wheels, macos_wheels, build_sdist]
98
95
  runs-on: ubuntu-latest
99
96
  environment: pypi
97
+ env:
98
+ HAS_PYPI_TOKEN: ${{ secrets.PYPI_TOKEN != '' }}
100
99
  steps:
101
100
  - uses: actions/download-artifact@v4
102
101
  with:
@@ -107,7 +106,14 @@ jobs:
107
106
  run: |
108
107
  python -m pip install -U twine
109
108
  python -m twine check dist/*
110
- - name: Publish to PyPI
109
+ - name: Publish to PyPI with configured API token
110
+ if: env.HAS_PYPI_TOKEN == 'true'
111
+ uses: pypa/gh-action-pypi-publish@release/v1
112
+ with:
113
+ password: ${{ secrets.PYPI_TOKEN }}
114
+ skip-existing: true
115
+ - name: Publish to PyPI with Trusted Publishing
116
+ if: env.HAS_PYPI_TOKEN != 'true'
111
117
  uses: pypa/gh-action-pypi-publish@release/v1
112
118
  with:
113
119
  skip-existing: true
@@ -1,5 +1,43 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ ## 1.2.0 - 2026-07-07
6
+
7
+ - Added `save_npz` and `load_npz` for non-pickle tensor and flat
8
+ `state_dict` files using NumPy NPZ archives plus TensorStudio JSON metadata.
9
+ - Added optional ONNX export through `tensorstudio.export_onnx` and
10
+ `tensorstudio.interchange.export_onnx` for supported Sequential module
11
+ stacks.
12
+ - Added `tensorstudio.vision` with image-to-tensor conversion, normalization,
13
+ center crop, nearest-neighbor resize, and a small `TinyConvClassifier`.
14
+ - Added tests for NPZ roundtrips, ONNX graph validation, and vision classifier
15
+ forward/backward behavior.
16
+ - Updated README and MkDocs pages for file formats, ONNX limits, and vision
17
+ workflows.
18
+
19
+ ## 1.1.0 - 2026-07-07
20
+
21
+ - Added native CPU NCHW `conv2d` with stride, padding, dilation, optional bias,
22
+ and reverse-mode gradients for input, weight, and bias.
23
+ - Added `tensorstudio.conv2d`, `tensorstudio.ops.conv2d`,
24
+ `tensorstudio.nn.functional.conv2d`, and `tensorstudio.nn.Conv2d`.
25
+ - Added convolution tests, finite-difference autograd coverage, and a
26
+ standalone convolution benchmark script.
27
+ - Added convolution rows to the full benchmark report and updated docs to mark
28
+ convolution as partially implemented rather than missing.
29
+ - Added native CPU NCHW `max_pool2d` and `avg_pool2d` operations with autograd,
30
+ Python top-level and functional APIs, `nn.MaxPool2d`, `nn.AvgPool2d`, tests,
31
+ docs, and benchmark coverage.
32
+ - Added native single-axis `sum`, `mean`, `max`, and `min` reductions with
33
+ `keepdims` and reverse-mode gradients.
34
+ - Added a typed contiguous 2D fast path for common axis `sum`/`mean`
35
+ reductions.
36
+ - Added `nn.softmax`, `nn.log_softmax`, `nn.cross_entropy`, and
37
+ `nn.CrossEntropyLoss` for small multiclass classification workloads.
38
+ - Added native `astype`, `concat`, and `stack` operations with Python wrappers,
39
+ Tensor methods for casting, and autograd support for floating tensors.
40
+
3
41
  ## 1.0.1
4
42
 
5
43
  - Added `test_all.py` for one-command local release checks covering lint,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tensorstudio
3
- Version: 1.0.1
3
+ Version: 1.2.0
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
@@ -51,9 +51,15 @@ Requires-Dist: ruff>=0.6; extra == "dev"
51
51
  Requires-Dist: mypy>=1.10; extra == "dev"
52
52
  Requires-Dist: cibuildwheel>=2.19; extra == "dev"
53
53
  Requires-Dist: pre-commit>=3.7; extra == "dev"
54
+ Requires-Dist: onnx>=1.16; extra == "dev"
55
+ Requires-Dist: Pillow>=10; extra == "dev"
54
56
  Provides-Extra: docs
55
57
  Requires-Dist: mkdocs>=1.6; extra == "docs"
56
58
  Requires-Dist: mkdocs-material>=9.5; extra == "docs"
59
+ Provides-Extra: onnx
60
+ Requires-Dist: onnx>=1.16; extra == "onnx"
61
+ Provides-Extra: vision
62
+ Requires-Dist: Pillow>=10; extra == "vision"
57
63
  Description-Content-Type: text/markdown
58
64
 
59
65
  # TensorStudio
@@ -65,7 +71,7 @@ Description-Content-Type: text/markdown
65
71
  TensorStudio is a compact C++ tensor and autograd engine with a Python API for
66
72
  learning, experimentation, and lightweight ML workloads.
67
73
 
68
- TensorStudio `1.0.1` is a CPU-only stable API foundation. It is eager-only,
74
+ TensorStudio `1.2.0` is a CPU-only stable API foundation. It is eager-only,
69
75
  intentionally small, and not a replacement for mature ML frameworks.
70
76
 
71
77
  ## Install
@@ -83,6 +89,12 @@ python -m pip install -U pip
83
89
  python -m pip install -e ".[dev]"
84
90
  ```
85
91
 
92
+ Install optional extras for ONNX export and Pillow-backed image inputs:
93
+
94
+ ```bash
95
+ python -m pip install "tensorstudio[onnx,vision]"
96
+ ```
97
+
86
98
  Build source and wheel distributions:
87
99
 
88
100
  ```bash
@@ -152,6 +164,8 @@ d = ts.linspace(0.0, 1.0, 5)
152
164
 
153
165
  print(a.shape, a.strides, a.device, a.is_contiguous)
154
166
  print((b.clamp(0.2, 0.8) + 1).mean().item())
167
+ print(b.sum(axis=1).tolist())
168
+ print(ts.concat([b, b], axis=0).shape, b.astype("float64").dtype)
155
169
  print(c.tolist(), d.tolist())
156
170
  print(ts.zeros_like(b).shape, ts.randn_like(b, seed=11).dtype)
157
171
  ```
@@ -204,6 +218,32 @@ print(model.state_dict().keys())
204
218
  print(model.parameter_count())
205
219
  ```
206
220
 
221
+ ## Vision
222
+
223
+ TensorStudio includes a small vision namespace for image preprocessing and
224
+ compact CNN classifiers. Image file decoding remains the job of Pillow or other
225
+ image libraries; TensorStudio converts image-like arrays into channel-first
226
+ tensors and runs the model with its native Conv2d and pooling kernels.
227
+
228
+ ```python
229
+ import numpy as np
230
+ import tensorstudio as ts
231
+ from tensorstudio import nn, optim
232
+
233
+ image = np.zeros((8, 8, 3), dtype=np.uint8)
234
+ x = ts.vision.to_tensor(image).reshape((1, 3, 8, 8))
235
+ x = ts.vision.normalize(x, mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5))
236
+
237
+ model = ts.vision.TinyConvClassifier((3, 8, 8), num_classes=2)
238
+ target = ts.tensor([1], dtype="int64")
239
+ optimizer = optim.SGD(model.parameters(), lr=0.01)
240
+
241
+ optimizer.zero_grad()
242
+ loss = nn.CrossEntropyLoss()(model(x), target)
243
+ loss.backward()
244
+ optimizer.step()
245
+ ```
246
+
207
247
  ## DataLoader
208
248
 
209
249
  ```python
@@ -235,12 +275,15 @@ python benchmarks/benchmark_report.py
235
275
  columns for NumPy, TensorFlow, PyTorch, and JAX when those libraries are
236
276
  available locally.
237
277
 
238
- On one Windows CPython 3.10 run for `1.0.1`, TensorStudio beat NumPy on 13
239
- small activation/reduction benchmark cases and lost on 76 NumPy-comparable
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
242
- dispatch overhead dominates; larger matrix multiplication, larger transcendental
243
- activations, and larger autograd workloads remain faster in PyTorch and NumPy.
278
+ On one Windows CPython 3.10 development run reporting `1.2.0`, TensorStudio
279
+ beat NumPy on 26 small operation benchmark cases and lost on 77
280
+ NumPy-comparable cases. Against PyTorch CPU `2.12.1+cpu`, TensorStudio won 75
281
+ local cases and lost 33. The strongest local wins were small eager operations,
282
+ small contiguous axis reductions, and the simple NumPy convolution/pooling
283
+ references where framework dispatch or Python loops dominate; larger matrix
284
+ multiplication, PyTorch convolution and pooling, larger axis reductions, larger
285
+ transcendental activations, and larger autograd workloads remain faster in
286
+ PyTorch and NumPy.
244
287
  See `benchmarks/results.md` for the full table, platform details, and exact
245
288
  timings.
246
289
 
@@ -248,11 +291,15 @@ Snapshot from that local run:
248
291
 
249
292
  | operation | shape | TensorStudio | NumPy | PyTorch CPU | TS vs NumPy | TS vs PyTorch |
250
293
  |---|---:|---:|---:|---:|---:|---:|
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 |
294
+ | `sigmoid` | `(32,)` | 0.0017 ms | 0.0038 ms | 0.0614 ms | 2.1691x | 35.3154x |
295
+ | `mean` | `(32,)` | 0.0029 ms | 0.0131 ms | 0.0186 ms | 4.5638x | 6.4709x |
296
+ | `sum_axis1` | `(16, 16)` | 0.0027 ms | 0.0029 ms | 0.0085 ms | 1.0894x | 3.1408x |
297
+ | `chain_relu` | `(128,)` | 0.0112 ms | 0.0051 ms | 0.0726 ms | 0.4575x | 6.4533x |
298
+ | `matmul` | `(256, 256)` | 4.4121 ms | 0.3779 ms | 0.1669 ms | 0.0856x | 0.0378x |
299
+ | `conv2d_3x3_padding1` | `(1, 1, 8, 8)` | 0.2374 ms | 1.7112 ms | 0.0186 ms | 7.2091x | 0.0784x |
300
+ | `max_pool2d_2x2` | `(1, 1, 16, 16)` | 0.0237 ms | 0.2764 ms | 0.0082 ms | 11.6685x | 0.3462x |
301
+ | `avg_pool2d_2x2` | `(1, 1, 16, 16)` | 0.0198 ms | 0.7431 ms | 0.0073 ms | 37.4930x | 0.3662x |
302
+ | `elementwise_backward` | `(1024,)` | 3.0196 ms | n/a | 0.2254 ms | n/a | 0.0746x |
256
303
 
257
304
  Speedup is `competitor median / TensorStudio median`, so values above `1.0x`
258
305
  favor TensorStudio.
@@ -274,6 +321,39 @@ checkpoint = ts.load("checkpoint.tsmodel")
274
321
  Serialization uses pickle. Loading pickle files from untrusted sources is
275
322
  unsafe because pickle can execute arbitrary code.
276
323
 
324
+ For safer tensor and `state_dict` interchange, use TensorStudio's non-pickle
325
+ NPZ helpers:
326
+
327
+ ```python
328
+ state = model.state_dict()
329
+ ts.save_npz(state, "weights.tsnpz")
330
+ model.load_state_dict(ts.load_npz("weights.tsnpz"))
331
+ ```
332
+
333
+ ## ONNX Export
334
+
335
+ TensorStudio can export a supported `nn.Sequential` graph to ONNX when the
336
+ optional `onnx` extra is installed:
337
+
338
+ ```python
339
+ import tensorstudio as ts
340
+ from tensorstudio import nn
341
+
342
+ model = nn.Sequential(
343
+ nn.Conv2d(1, 2, kernel_size=3, padding=1),
344
+ nn.ReLU(),
345
+ nn.MaxPool2d(2),
346
+ nn.Flatten(),
347
+ nn.Linear(2 * 2 * 2, 3),
348
+ )
349
+
350
+ ts.export_onnx(model, "classifier.onnx", input_shape=(1, 1, 4, 4))
351
+ ```
352
+
353
+ The v1.2 exporter supports `Linear`, `Conv2d`, `Flatten`, `ReLU`, `Sigmoid`,
354
+ `Tanh`, `MaxPool2d`, and `AvgPool2d`. It is an exporter, not an ONNX runtime or
355
+ importer.
356
+
277
357
  ## Development
278
358
 
279
359
  ```bash
@@ -318,9 +398,15 @@ tokens or print secrets.
318
398
  - No CUDA or Metal backend yet.
319
399
  - No BLAS-backed matrix multiplication yet.
320
400
  - No graph compiler or distributed runtime.
321
- - No convolution layers yet.
401
+ - Convolution and pooling support are currently limited to CPU NCHW
402
+ `conv2d`, `max_pool2d`, and `avg_pool2d` style workloads.
403
+ - Vision utilities are preprocessing and small CNN helpers, not a full computer
404
+ vision library.
405
+ - ONNX support is export-only for a limited set of TensorStudio modules.
406
+ - Reductions support all-element or single-axis reductions, not tuple-axis
407
+ reductions yet.
322
408
  - No sparse tensors or advanced indexing.
323
- - Limited dtype casting.
409
+ - Dtype casting is basic and does not include a full promotion/casting policy.
324
410
  - Experimental performance; benchmarks are local references only.
325
411
  - Pickle serialization is for trusted TensorStudio objects only.
326
412
 
@@ -328,10 +414,10 @@ tokens or print secrets.
328
414
 
329
415
  - CUDA backend
330
416
  - Graph/JIT mode
331
- - Convolution ops
332
- - Dataset utilities
417
+ - Broader convolution ops, adaptive/global pooling, and image-model examples
418
+ - Richer dataset utilities
333
419
  - Model zoo examples
334
- - ONNX import/export
420
+ - ONNX import and broader export coverage
335
421
  - Improved memory allocator
336
422
  - SIMD kernels
337
423
  - Multithreaded ops
@@ -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.1` is a CPU-only stable API foundation. It is eager-only,
10
+ TensorStudio `1.2.0` 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
@@ -25,6 +25,12 @@ python -m pip install -U pip
25
25
  python -m pip install -e ".[dev]"
26
26
  ```
27
27
 
28
+ Install optional extras for ONNX export and Pillow-backed image inputs:
29
+
30
+ ```bash
31
+ python -m pip install "tensorstudio[onnx,vision]"
32
+ ```
33
+
28
34
  Build source and wheel distributions:
29
35
 
30
36
  ```bash
@@ -94,6 +100,8 @@ d = ts.linspace(0.0, 1.0, 5)
94
100
 
95
101
  print(a.shape, a.strides, a.device, a.is_contiguous)
96
102
  print((b.clamp(0.2, 0.8) + 1).mean().item())
103
+ print(b.sum(axis=1).tolist())
104
+ print(ts.concat([b, b], axis=0).shape, b.astype("float64").dtype)
97
105
  print(c.tolist(), d.tolist())
98
106
  print(ts.zeros_like(b).shape, ts.randn_like(b, seed=11).dtype)
99
107
  ```
@@ -146,6 +154,32 @@ print(model.state_dict().keys())
146
154
  print(model.parameter_count())
147
155
  ```
148
156
 
157
+ ## Vision
158
+
159
+ TensorStudio includes a small vision namespace for image preprocessing and
160
+ compact CNN classifiers. Image file decoding remains the job of Pillow or other
161
+ image libraries; TensorStudio converts image-like arrays into channel-first
162
+ tensors and runs the model with its native Conv2d and pooling kernels.
163
+
164
+ ```python
165
+ import numpy as np
166
+ import tensorstudio as ts
167
+ from tensorstudio import nn, optim
168
+
169
+ image = np.zeros((8, 8, 3), dtype=np.uint8)
170
+ x = ts.vision.to_tensor(image).reshape((1, 3, 8, 8))
171
+ x = ts.vision.normalize(x, mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5))
172
+
173
+ model = ts.vision.TinyConvClassifier((3, 8, 8), num_classes=2)
174
+ target = ts.tensor([1], dtype="int64")
175
+ optimizer = optim.SGD(model.parameters(), lr=0.01)
176
+
177
+ optimizer.zero_grad()
178
+ loss = nn.CrossEntropyLoss()(model(x), target)
179
+ loss.backward()
180
+ optimizer.step()
181
+ ```
182
+
149
183
  ## DataLoader
150
184
 
151
185
  ```python
@@ -177,12 +211,15 @@ python benchmarks/benchmark_report.py
177
211
  columns for NumPy, TensorFlow, PyTorch, and JAX when those libraries are
178
212
  available locally.
179
213
 
180
- On one Windows CPython 3.10 run for `1.0.1`, TensorStudio beat NumPy on 13
181
- small activation/reduction benchmark cases and lost on 76 NumPy-comparable
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
184
- dispatch overhead dominates; larger matrix multiplication, larger transcendental
185
- activations, and larger autograd workloads remain faster in PyTorch and NumPy.
214
+ On one Windows CPython 3.10 development run reporting `1.2.0`, TensorStudio
215
+ beat NumPy on 26 small operation benchmark cases and lost on 77
216
+ NumPy-comparable cases. Against PyTorch CPU `2.12.1+cpu`, TensorStudio won 75
217
+ local cases and lost 33. The strongest local wins were small eager operations,
218
+ small contiguous axis reductions, and the simple NumPy convolution/pooling
219
+ references where framework dispatch or Python loops dominate; larger matrix
220
+ multiplication, PyTorch convolution and pooling, larger axis reductions, larger
221
+ transcendental activations, and larger autograd workloads remain faster in
222
+ PyTorch and NumPy.
186
223
  See `benchmarks/results.md` for the full table, platform details, and exact
187
224
  timings.
188
225
 
@@ -190,11 +227,15 @@ Snapshot from that local run:
190
227
 
191
228
  | operation | shape | TensorStudio | NumPy | PyTorch CPU | TS vs NumPy | TS vs PyTorch |
192
229
  |---|---:|---:|---:|---:|---:|---:|
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 |
230
+ | `sigmoid` | `(32,)` | 0.0017 ms | 0.0038 ms | 0.0614 ms | 2.1691x | 35.3154x |
231
+ | `mean` | `(32,)` | 0.0029 ms | 0.0131 ms | 0.0186 ms | 4.5638x | 6.4709x |
232
+ | `sum_axis1` | `(16, 16)` | 0.0027 ms | 0.0029 ms | 0.0085 ms | 1.0894x | 3.1408x |
233
+ | `chain_relu` | `(128,)` | 0.0112 ms | 0.0051 ms | 0.0726 ms | 0.4575x | 6.4533x |
234
+ | `matmul` | `(256, 256)` | 4.4121 ms | 0.3779 ms | 0.1669 ms | 0.0856x | 0.0378x |
235
+ | `conv2d_3x3_padding1` | `(1, 1, 8, 8)` | 0.2374 ms | 1.7112 ms | 0.0186 ms | 7.2091x | 0.0784x |
236
+ | `max_pool2d_2x2` | `(1, 1, 16, 16)` | 0.0237 ms | 0.2764 ms | 0.0082 ms | 11.6685x | 0.3462x |
237
+ | `avg_pool2d_2x2` | `(1, 1, 16, 16)` | 0.0198 ms | 0.7431 ms | 0.0073 ms | 37.4930x | 0.3662x |
238
+ | `elementwise_backward` | `(1024,)` | 3.0196 ms | n/a | 0.2254 ms | n/a | 0.0746x |
198
239
 
199
240
  Speedup is `competitor median / TensorStudio median`, so values above `1.0x`
200
241
  favor TensorStudio.
@@ -216,6 +257,39 @@ checkpoint = ts.load("checkpoint.tsmodel")
216
257
  Serialization uses pickle. Loading pickle files from untrusted sources is
217
258
  unsafe because pickle can execute arbitrary code.
218
259
 
260
+ For safer tensor and `state_dict` interchange, use TensorStudio's non-pickle
261
+ NPZ helpers:
262
+
263
+ ```python
264
+ state = model.state_dict()
265
+ ts.save_npz(state, "weights.tsnpz")
266
+ model.load_state_dict(ts.load_npz("weights.tsnpz"))
267
+ ```
268
+
269
+ ## ONNX Export
270
+
271
+ TensorStudio can export a supported `nn.Sequential` graph to ONNX when the
272
+ optional `onnx` extra is installed:
273
+
274
+ ```python
275
+ import tensorstudio as ts
276
+ from tensorstudio import nn
277
+
278
+ model = nn.Sequential(
279
+ nn.Conv2d(1, 2, kernel_size=3, padding=1),
280
+ nn.ReLU(),
281
+ nn.MaxPool2d(2),
282
+ nn.Flatten(),
283
+ nn.Linear(2 * 2 * 2, 3),
284
+ )
285
+
286
+ ts.export_onnx(model, "classifier.onnx", input_shape=(1, 1, 4, 4))
287
+ ```
288
+
289
+ The v1.2 exporter supports `Linear`, `Conv2d`, `Flatten`, `ReLU`, `Sigmoid`,
290
+ `Tanh`, `MaxPool2d`, and `AvgPool2d`. It is an exporter, not an ONNX runtime or
291
+ importer.
292
+
219
293
  ## Development
220
294
 
221
295
  ```bash
@@ -260,9 +334,15 @@ tokens or print secrets.
260
334
  - No CUDA or Metal backend yet.
261
335
  - No BLAS-backed matrix multiplication yet.
262
336
  - No graph compiler or distributed runtime.
263
- - No convolution layers yet.
337
+ - Convolution and pooling support are currently limited to CPU NCHW
338
+ `conv2d`, `max_pool2d`, and `avg_pool2d` style workloads.
339
+ - Vision utilities are preprocessing and small CNN helpers, not a full computer
340
+ vision library.
341
+ - ONNX support is export-only for a limited set of TensorStudio modules.
342
+ - Reductions support all-element or single-axis reductions, not tuple-axis
343
+ reductions yet.
264
344
  - No sparse tensors or advanced indexing.
265
- - Limited dtype casting.
345
+ - Dtype casting is basic and does not include a full promotion/casting policy.
266
346
  - Experimental performance; benchmarks are local references only.
267
347
  - Pickle serialization is for trusted TensorStudio objects only.
268
348
 
@@ -270,10 +350,10 @@ tokens or print secrets.
270
350
 
271
351
  - CUDA backend
272
352
  - Graph/JIT mode
273
- - Convolution ops
274
- - Dataset utilities
353
+ - Broader convolution ops, adaptive/global pooling, and image-model examples
354
+ - Richer dataset utilities
275
355
  - Model zoo examples
276
- - ONNX import/export
356
+ - ONNX import and broader export coverage
277
357
  - Improved memory allocator
278
358
  - SIMD kernels
279
359
  - Multithreaded ops
@@ -8,6 +8,8 @@ from benchmarks.benchmark_report import run_benchmarks
8
8
  ALL_SECTIONS = {
9
9
  "elementwise",
10
10
  "matmul",
11
+ "conv2d",
12
+ "pooling",
11
13
  "reductions",
12
14
  "activations",
13
15
  "autograd",
@@ -0,0 +1,8 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ from benchmark_report import run_benchmarks
6
+
7
+ if __name__ == "__main__":
8
+ print(run_benchmarks({"conv2d"}, Path(__file__).with_name("results_conv2d.md")))
@@ -0,0 +1,8 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ from benchmark_report import run_benchmarks
6
+
7
+ if __name__ == "__main__":
8
+ print(run_benchmarks({"pooling"}, Path(__file__).with_name("results_pooling.md")))