tensorstudio 1.5.0__tar.gz → 1.6.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.
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/CHANGELOG.md +37 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/CMakeLists.txt +18 -1
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/PKG-INFO +45 -26
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/README.md +44 -25
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmark_all.py +30 -2
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/benchmark_report.py +50 -2
- tensorstudio-1.6.0/benchmarks/results.md +347 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/results_conv2d.md +39 -39
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/results_matmul.md +45 -45
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/results_pooling.md +45 -45
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/results_reductions.md +75 -75
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/results_tensor_ops.md +309 -309
- tensorstudio-1.6.0/benchmarks/thresholds.json +49 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/autograd/coverage.md +1 -1
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/core/api-reference.md +5 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/core/broadcasting.md +6 -4
- tensorstudio-1.6.0/docs/hardware/cpu-backend.md +84 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/hardware/linux.md +18 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/hardware/macos.md +15 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/hardware/windows.md +22 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/index.md +1 -1
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/interchange/onnx.md +1 -1
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/interchange/serialization.md +1 -1
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/nn/training.md +2 -1
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/performance/benchmarks.md +21 -7
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/performance/optimization.md +24 -6
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/release/publishing.md +4 -4
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/release/versioning.md +2 -2
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/roadmap/roadmap.md +20 -13
- tensorstudio-1.6.0/include/tensorstudio/perf.hpp +34 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/include/tensorstudio/storage.hpp +2 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/include/tensorstudio/version.hpp +1 -1
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/pyproject.toml +1 -1
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/_C.pyi +3 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/__init__.py +4 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/_version.py +1 -1
- tensorstudio-1.6.0/python/tensorstudio/performance.py +39 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/bindings/bind_tensor.cpp +45 -10
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/bindings/bindings.cpp +15 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/core/dtype.cpp +8 -1
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/core/ops.cpp +364 -82
- tensorstudio-1.6.0/src/core/perf.cpp +250 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/core/shape.cpp +17 -5
- tensorstudio-1.6.0/src/core/storage.cpp +116 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/core/tensor.cpp +3 -1
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_benchmark_report.py +26 -1
- tensorstudio-1.6.0/tests/test_errors.py +61 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_import.py +1 -1
- tensorstudio-1.6.0/tests/test_performance.py +43 -0
- tensorstudio-1.5.0/benchmarks/results.md +0 -343
- tensorstudio-1.5.0/docs/hardware/cpu-backend.md +0 -40
- tensorstudio-1.5.0/src/core/storage.cpp +0 -29
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/.gitattributes +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/.github/workflows/ci.yml +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/.github/workflows/publish-testpypi.yml +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/.github/workflows/publish.yml +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/.github/workflows/wheels.yml +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/.gitignore +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/.pre-commit-config.yaml +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/CONTRIBUTING.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/LICENSE +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/SECURITY.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/__init__.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/bench_activations.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/bench_autograd.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/bench_conv2d.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/bench_elementwise.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/bench_matmul.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/bench_pooling.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/bench_reductions.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/bench_tensor_ops.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/benchmarks/bench_training_loop.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/autograd/gradient-notes.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/autograd/overview.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/core/native-cpp-core.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/core/tensors.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/data/dataloader-patterns.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/data/datasets-and-dataloaders.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/data/tensor-datasets.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/development/contributing.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/development/cpp-first.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/getting-started/installation.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/getting-started/quickstart.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/getting-started/source-build.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/interchange/model-formats.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/interchange/numpy-interop.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/interchange/trusted-serialization.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/nn/modules.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/nn/optimizers.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/nn/overview.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/performance/profiling.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/project/checkpoints.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/project/project-layout.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/project/workflows.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/release/checklist.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/roadmap/milestones.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/roadmap/priorities.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/vision/dataset-creation.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/docs/vision/overview.md +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/examples/basic_tensor_ops.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/examples/export_onnx.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/examples/image_folder_classification.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/examples/linear_regression.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/examples/project_training.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/examples/save_load_model.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/examples/tiny_mlp.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/examples/vision_classifier.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/include/tensorstudio/autograd.hpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/include/tensorstudio/device.hpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/include/tensorstudio/dtype.hpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/include/tensorstudio/errors.hpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/include/tensorstudio/module.hpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/include/tensorstudio/ops.hpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/include/tensorstudio/optim.hpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/include/tensorstudio/random.hpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/include/tensorstudio/serialization.hpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/include/tensorstudio/shape.hpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/include/tensorstudio/tensor.hpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/mkdocs.yml +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/autograd.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/data/__init__.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/data/dataloader.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/data/dataset.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/dtypes.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/errors.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/grad_mode.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/interchange/__init__.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/interchange/onnx.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/math.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/nn/__init__.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/nn/functional.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/nn/losses.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/nn/modules.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/ops.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/optim/__init__.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/optim/adam.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/optim/adamw.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/optim/lr_scheduler.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/optim/sgd.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/optim/utils.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/project/__init__.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/project/checkpoint.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/project/config.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/project/trainer.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/py.typed +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/serialization.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/tensor.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/typing.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/vision/__init__.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/vision/datasets.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/vision/io.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/vision/metrics.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/vision/models.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/vision/transforms.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/python/tensorstudio/vision/visualization.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/bindings/bind_autograd.cpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/bindings/bind_nn.cpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/bindings/bind_ops.cpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/bindings/bind_optim.cpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/bindings/bindings.hpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/core/autograd.cpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/core/device.cpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/core/errors.cpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/core/module.cpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/core/optim.cpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/core/random.cpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/src/core/serialization.cpp +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/test_all.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_autograd.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_broadcasting.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_data.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_indexing.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_interchange.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_nn.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_numpy_interop.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_ops.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_optim.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_project.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_serialization.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_tensor.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_views.py +0 -0
- {tensorstudio-1.5.0 → tensorstudio-1.6.0}/tests/test_vision.py +0 -0
|
@@ -2,6 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 1.6.0 - 2026-07-07
|
|
6
|
+
|
|
7
|
+
- Completed the ordered CPU Performance Core roadmap section as one release
|
|
8
|
+
batch.
|
|
9
|
+
- Added optional CBLAS/Accelerate-backed `matmul` for contiguous `float32` and
|
|
10
|
+
`float64` matrices when the source build environment exposes a compatible
|
|
11
|
+
BLAS library and header; portable C++ kernels remain the fallback path.
|
|
12
|
+
- Added a small native C++ CPU thread pool, configurable with
|
|
13
|
+
`tensorstudio.set_num_threads()` and `TENSORSTUDIO_NUM_THREADS`, and used it
|
|
14
|
+
for large contiguous elementwise ops, reductions, matrix multiplication,
|
|
15
|
+
convolution, and pooling forward kernels.
|
|
16
|
+
- Added SIMD-friendly typed `float32`/`float64` contiguous kernels for common
|
|
17
|
+
elementwise arithmetic and activations, while preserving mixed-dtype fallback
|
|
18
|
+
behavior.
|
|
19
|
+
- Added a bounded C++ storage reuse pool for tensor allocations, with
|
|
20
|
+
`TENSORSTUDIO_DISABLE_STORAGE_POOL=1` and
|
|
21
|
+
`TENSORSTUDIO_STORAGE_POOL_MAX_BLOCK_BYTES` controls.
|
|
22
|
+
- Added `tensorstudio.performance_info()`, `get_num_threads()`, and
|
|
23
|
+
`set_num_threads()` diagnostics/configuration helpers.
|
|
24
|
+
- Added benchmark threshold support via `benchmark_all.py --check-thresholds`
|
|
25
|
+
and `benchmarks/thresholds.json`.
|
|
26
|
+
- Expanded performance, CPU backend, and platform docs for BLAS selection,
|
|
27
|
+
threading, storage reuse, benchmark thresholds, and honest interpretation.
|
|
28
|
+
|
|
29
|
+
## 1.5.1 - 2026-07-07
|
|
30
|
+
|
|
31
|
+
- Completed the next ordered correctness-roadmap item with clearer native
|
|
32
|
+
shape, dtype, and indexing error messages.
|
|
33
|
+
- Broadcasting errors now include the mismatched axis and dimensions.
|
|
34
|
+
- Reshape errors now include requested element counts and inferred-shape
|
|
35
|
+
context.
|
|
36
|
+
- DType errors now validate Python dtype inputs and list supported dtype names
|
|
37
|
+
and aliases.
|
|
38
|
+
- Indexing errors now include tensor shape/rank context and the unsupported
|
|
39
|
+
Python index type/value where practical.
|
|
40
|
+
- Added focused regression tests for the improved diagnostics.
|
|
41
|
+
|
|
5
42
|
## 1.5.0 - 2026-07-07
|
|
6
43
|
|
|
7
44
|
- Completed the next ordered correctness-roadmap item with native C++ view and
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
cmake_minimum_required(VERSION 3.18)
|
|
2
2
|
|
|
3
|
-
project(tensorstudio VERSION 1.
|
|
3
|
+
project(tensorstudio VERSION 1.6.0 LANGUAGES CXX)
|
|
4
4
|
|
|
5
5
|
find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)
|
|
6
6
|
set(PYBIND11_FINDPYTHON ON)
|
|
7
7
|
find_package(pybind11 CONFIG REQUIRED)
|
|
8
8
|
|
|
9
|
+
option(TENSORSTUDIO_ENABLE_BLAS "Enable optional CBLAS-backed matmul when available" ON)
|
|
10
|
+
|
|
9
11
|
set(TENSORSTUDIO_CORE_SOURCES
|
|
10
12
|
src/core/tensor.cpp
|
|
11
13
|
src/core/dtype.cpp
|
|
@@ -19,6 +21,7 @@ set(TENSORSTUDIO_CORE_SOURCES
|
|
|
19
21
|
src/core/random.cpp
|
|
20
22
|
src/core/serialization.cpp
|
|
21
23
|
src/core/errors.cpp
|
|
24
|
+
src/core/perf.cpp
|
|
22
25
|
)
|
|
23
26
|
|
|
24
27
|
set(TENSORSTUDIO_BINDING_SOURCES
|
|
@@ -38,6 +41,20 @@ pybind11_add_module(_C MODULE
|
|
|
38
41
|
target_include_directories(_C PRIVATE include src/bindings)
|
|
39
42
|
target_compile_features(_C PRIVATE cxx_std_20)
|
|
40
43
|
|
|
44
|
+
if(TENSORSTUDIO_ENABLE_BLAS)
|
|
45
|
+
find_package(BLAS)
|
|
46
|
+
if(BLAS_FOUND)
|
|
47
|
+
include(CheckIncludeFileCXX)
|
|
48
|
+
check_include_file_cxx(cblas.h TENSORSTUDIO_HAVE_CBLAS_H)
|
|
49
|
+
target_link_libraries(_C PRIVATE ${BLAS_LIBRARIES})
|
|
50
|
+
if(APPLE)
|
|
51
|
+
target_compile_definitions(_C PRIVATE TENSORSTUDIO_HAS_ACCELERATE=1)
|
|
52
|
+
elseif(TENSORSTUDIO_HAVE_CBLAS_H)
|
|
53
|
+
target_compile_definitions(_C PRIVATE TENSORSTUDIO_HAS_CBLAS=1)
|
|
54
|
+
endif()
|
|
55
|
+
endif()
|
|
56
|
+
endif()
|
|
57
|
+
|
|
41
58
|
if(MSVC)
|
|
42
59
|
target_compile_options(_C PRIVATE /W4 /permissive-)
|
|
43
60
|
else()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: tensorstudio
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.6.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
|
|
@@ -71,8 +71,10 @@ Description-Content-Type: text/markdown
|
|
|
71
71
|
TensorStudio is a compact C++ tensor and autograd engine with a Python API for
|
|
72
72
|
learning, experimentation, and lightweight ML workloads.
|
|
73
73
|
|
|
74
|
-
TensorStudio `1.
|
|
75
|
-
|
|
74
|
+
TensorStudio `1.6.0` is a CPU-only stable API foundation with native C++
|
|
75
|
+
threading, storage reuse, SIMD-friendly typed kernels, and optional
|
|
76
|
+
CBLAS/Accelerate matrix multiplication when available. It is eager-only,
|
|
77
|
+
intentionally compact, and not a replacement for mature ML frameworks.
|
|
76
78
|
|
|
77
79
|
## Install
|
|
78
80
|
|
|
@@ -344,31 +346,46 @@ python benchmarks/benchmark_report.py
|
|
|
344
346
|
columns for NumPy, TensorFlow, PyTorch, and JAX when those libraries are
|
|
345
347
|
available locally.
|
|
346
348
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
349
|
+
Useful runtime diagnostics:
|
|
350
|
+
|
|
351
|
+
```python
|
|
352
|
+
import tensorstudio as ts
|
|
353
|
+
|
|
354
|
+
print(ts.performance_info())
|
|
355
|
+
ts.set_num_threads(4)
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Run the loose local regression thresholds with:
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
python benchmark_all.py --check-thresholds
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
On one Windows CPython 3.10 development run reporting `1.6.0`, with
|
|
365
|
+
TensorStudio threads enabled, storage pooling enabled, SSE2 autovectorization
|
|
366
|
+
reported, and no BLAS provider found, TensorStudio beat NumPy on 7 local
|
|
367
|
+
benchmark cases and lost on 96 NumPy-comparable cases. JAX CPU dispatch was
|
|
368
|
+
available on that machine; TensorStudio won 39 local cases and lost 59. The
|
|
369
|
+
strongest local wins were the simple NumPy convolution/pooling reference loops
|
|
370
|
+
and some small JAX-dispatch-heavy eager cases. NumPy and JAX were faster for
|
|
371
|
+
many elementwise, reduction, matrix multiplication, larger activation, and
|
|
372
|
+
autograd workloads.
|
|
356
373
|
See `benchmarks/results.md` for the full table, platform details, and exact
|
|
357
374
|
timings.
|
|
358
375
|
|
|
359
376
|
Snapshot from that local run:
|
|
360
377
|
|
|
361
|
-
| operation | shape | TensorStudio | NumPy |
|
|
378
|
+
| operation | shape | TensorStudio | NumPy | JAX CPU dispatch | TS vs NumPy | TS vs JAX |
|
|
362
379
|
|---|---:|---:|---:|---:|---:|---:|
|
|
363
|
-
| `sigmoid` | `(32,)` | 0.
|
|
364
|
-
| `mean` | `(32,)` | 0.
|
|
365
|
-
| `sum_axis1` | `(16, 16)` | 0.
|
|
366
|
-
| `chain_relu` | `(128,)` | 0.
|
|
367
|
-
| `matmul` | `(256, 256)` |
|
|
368
|
-
| `conv2d_3x3_padding1` | `(1, 1, 8, 8)` | 0.
|
|
369
|
-
| `max_pool2d_2x2` | `(1, 1, 16, 16)` | 0.
|
|
370
|
-
| `avg_pool2d_2x2` | `(1, 1, 16, 16)` | 0.
|
|
371
|
-
| `elementwise_backward` | `(1024,)` |
|
|
380
|
+
| `sigmoid` | `(32,)` | 0.0173 ms | 0.0047 ms | 0.0719 ms | 0.2724x | 4.1608x |
|
|
381
|
+
| `mean` | `(32,)` | 0.0157 ms | 0.0082 ms | 0.0119 ms | 0.5208x | 0.7587x |
|
|
382
|
+
| `sum_axis1` | `(16, 16)` | 0.0159 ms | 0.0031 ms | 0.0131 ms | 0.1924x | 0.8231x |
|
|
383
|
+
| `chain_relu` | `(128,)` | 0.0992 ms | 0.0063 ms | 0.1113 ms | 0.0636x | 1.1219x |
|
|
384
|
+
| `matmul` | `(256, 256)` | 2.5261 ms | 0.3848 ms | 0.2288 ms | 0.1524x | 0.0906x |
|
|
385
|
+
| `conv2d_3x3_padding1` | `(1, 1, 8, 8)` | 0.2120 ms | 1.2975 ms | 0.0959 ms | 6.1191x | 0.4524x |
|
|
386
|
+
| `max_pool2d_2x2` | `(1, 1, 16, 16)` | 0.0286 ms | 0.1613 ms | n/a | 5.6321x | n/a |
|
|
387
|
+
| `avg_pool2d_2x2` | `(1, 1, 16, 16)` | 0.0304 ms | 0.5601 ms | n/a | 18.4457x | n/a |
|
|
388
|
+
| `elementwise_backward` | `(1024,)` | 2.7150 ms | n/a | n/a | n/a | n/a |
|
|
372
389
|
|
|
373
390
|
Speedup is `competitor median / TensorStudio median`, so values above `1.0x`
|
|
374
391
|
favor TensorStudio.
|
|
@@ -465,7 +482,9 @@ tokens or print secrets.
|
|
|
465
482
|
- CPU backend only.
|
|
466
483
|
- Eager execution only.
|
|
467
484
|
- No CUDA or Metal backend yet.
|
|
468
|
-
-
|
|
485
|
+
- Optional BLAS-backed matrix multiplication depends on the build environment
|
|
486
|
+
exposing a compatible CBLAS/Accelerate interface; otherwise TensorStudio uses
|
|
487
|
+
a portable C++ fallback.
|
|
469
488
|
- No graph compiler or distributed runtime.
|
|
470
489
|
- Convolution and pooling support are currently limited to CPU NCHW
|
|
471
490
|
`conv2d`, `max_pool2d`, and `avg_pool2d` style workloads.
|
|
@@ -495,9 +514,9 @@ tokens or print secrets.
|
|
|
495
514
|
- Richer dataset utilities
|
|
496
515
|
- Model zoo examples
|
|
497
516
|
- ONNX import and broader export coverage
|
|
498
|
-
-
|
|
499
|
-
-
|
|
500
|
-
-
|
|
517
|
+
- Runtime-dispatched SIMD kernels
|
|
518
|
+
- Better non-BLAS matrix multiplication tiling
|
|
519
|
+
- More threaded backward kernels
|
|
501
520
|
|
|
502
521
|
## License
|
|
503
522
|
|
|
@@ -7,8 +7,10 @@
|
|
|
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.
|
|
11
|
-
|
|
10
|
+
TensorStudio `1.6.0` is a CPU-only stable API foundation with native C++
|
|
11
|
+
threading, storage reuse, SIMD-friendly typed kernels, and optional
|
|
12
|
+
CBLAS/Accelerate matrix multiplication when available. It is eager-only,
|
|
13
|
+
intentionally compact, and not a replacement for mature ML frameworks.
|
|
12
14
|
|
|
13
15
|
## Install
|
|
14
16
|
|
|
@@ -280,31 +282,46 @@ python benchmarks/benchmark_report.py
|
|
|
280
282
|
columns for NumPy, TensorFlow, PyTorch, and JAX when those libraries are
|
|
281
283
|
available locally.
|
|
282
284
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
285
|
+
Useful runtime diagnostics:
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
import tensorstudio as ts
|
|
289
|
+
|
|
290
|
+
print(ts.performance_info())
|
|
291
|
+
ts.set_num_threads(4)
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Run the loose local regression thresholds with:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
python benchmark_all.py --check-thresholds
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
On one Windows CPython 3.10 development run reporting `1.6.0`, with
|
|
301
|
+
TensorStudio threads enabled, storage pooling enabled, SSE2 autovectorization
|
|
302
|
+
reported, and no BLAS provider found, TensorStudio beat NumPy on 7 local
|
|
303
|
+
benchmark cases and lost on 96 NumPy-comparable cases. JAX CPU dispatch was
|
|
304
|
+
available on that machine; TensorStudio won 39 local cases and lost 59. The
|
|
305
|
+
strongest local wins were the simple NumPy convolution/pooling reference loops
|
|
306
|
+
and some small JAX-dispatch-heavy eager cases. NumPy and JAX were faster for
|
|
307
|
+
many elementwise, reduction, matrix multiplication, larger activation, and
|
|
308
|
+
autograd workloads.
|
|
292
309
|
See `benchmarks/results.md` for the full table, platform details, and exact
|
|
293
310
|
timings.
|
|
294
311
|
|
|
295
312
|
Snapshot from that local run:
|
|
296
313
|
|
|
297
|
-
| operation | shape | TensorStudio | NumPy |
|
|
314
|
+
| operation | shape | TensorStudio | NumPy | JAX CPU dispatch | TS vs NumPy | TS vs JAX |
|
|
298
315
|
|---|---:|---:|---:|---:|---:|---:|
|
|
299
|
-
| `sigmoid` | `(32,)` | 0.
|
|
300
|
-
| `mean` | `(32,)` | 0.
|
|
301
|
-
| `sum_axis1` | `(16, 16)` | 0.
|
|
302
|
-
| `chain_relu` | `(128,)` | 0.
|
|
303
|
-
| `matmul` | `(256, 256)` |
|
|
304
|
-
| `conv2d_3x3_padding1` | `(1, 1, 8, 8)` | 0.
|
|
305
|
-
| `max_pool2d_2x2` | `(1, 1, 16, 16)` | 0.
|
|
306
|
-
| `avg_pool2d_2x2` | `(1, 1, 16, 16)` | 0.
|
|
307
|
-
| `elementwise_backward` | `(1024,)` |
|
|
316
|
+
| `sigmoid` | `(32,)` | 0.0173 ms | 0.0047 ms | 0.0719 ms | 0.2724x | 4.1608x |
|
|
317
|
+
| `mean` | `(32,)` | 0.0157 ms | 0.0082 ms | 0.0119 ms | 0.5208x | 0.7587x |
|
|
318
|
+
| `sum_axis1` | `(16, 16)` | 0.0159 ms | 0.0031 ms | 0.0131 ms | 0.1924x | 0.8231x |
|
|
319
|
+
| `chain_relu` | `(128,)` | 0.0992 ms | 0.0063 ms | 0.1113 ms | 0.0636x | 1.1219x |
|
|
320
|
+
| `matmul` | `(256, 256)` | 2.5261 ms | 0.3848 ms | 0.2288 ms | 0.1524x | 0.0906x |
|
|
321
|
+
| `conv2d_3x3_padding1` | `(1, 1, 8, 8)` | 0.2120 ms | 1.2975 ms | 0.0959 ms | 6.1191x | 0.4524x |
|
|
322
|
+
| `max_pool2d_2x2` | `(1, 1, 16, 16)` | 0.0286 ms | 0.1613 ms | n/a | 5.6321x | n/a |
|
|
323
|
+
| `avg_pool2d_2x2` | `(1, 1, 16, 16)` | 0.0304 ms | 0.5601 ms | n/a | 18.4457x | n/a |
|
|
324
|
+
| `elementwise_backward` | `(1024,)` | 2.7150 ms | n/a | n/a | n/a | n/a |
|
|
308
325
|
|
|
309
326
|
Speedup is `competitor median / TensorStudio median`, so values above `1.0x`
|
|
310
327
|
favor TensorStudio.
|
|
@@ -401,7 +418,9 @@ tokens or print secrets.
|
|
|
401
418
|
- CPU backend only.
|
|
402
419
|
- Eager execution only.
|
|
403
420
|
- No CUDA or Metal backend yet.
|
|
404
|
-
-
|
|
421
|
+
- Optional BLAS-backed matrix multiplication depends on the build environment
|
|
422
|
+
exposing a compatible CBLAS/Accelerate interface; otherwise TensorStudio uses
|
|
423
|
+
a portable C++ fallback.
|
|
405
424
|
- No graph compiler or distributed runtime.
|
|
406
425
|
- Convolution and pooling support are currently limited to CPU NCHW
|
|
407
426
|
`conv2d`, `max_pool2d`, and `avg_pool2d` style workloads.
|
|
@@ -431,9 +450,9 @@ tokens or print secrets.
|
|
|
431
450
|
- Richer dataset utilities
|
|
432
451
|
- Model zoo examples
|
|
433
452
|
- ONNX import and broader export coverage
|
|
434
|
-
-
|
|
435
|
-
-
|
|
436
|
-
-
|
|
453
|
+
- Runtime-dispatched SIMD kernels
|
|
454
|
+
- Better non-BLAS matrix multiplication tiling
|
|
455
|
+
- More threaded backward kernels
|
|
437
456
|
|
|
438
457
|
## License
|
|
439
458
|
|
|
@@ -3,7 +3,13 @@ from __future__ import annotations
|
|
|
3
3
|
import argparse
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
|
-
from benchmarks.benchmark_report import
|
|
6
|
+
from benchmarks.benchmark_report import (
|
|
7
|
+
evaluate_thresholds,
|
|
8
|
+
load_thresholds,
|
|
9
|
+
render_benchmark_report,
|
|
10
|
+
run_benchmark_data,
|
|
11
|
+
write_benchmark_report,
|
|
12
|
+
)
|
|
7
13
|
|
|
8
14
|
ALL_SECTIONS = {
|
|
9
15
|
"elementwise",
|
|
@@ -36,14 +42,36 @@ def main() -> None:
|
|
|
36
42
|
action="store_true",
|
|
37
43
|
help="Print the full Markdown report after writing it.",
|
|
38
44
|
)
|
|
45
|
+
parser.add_argument(
|
|
46
|
+
"--thresholds",
|
|
47
|
+
type=Path,
|
|
48
|
+
default=Path("benchmarks") / "thresholds.json",
|
|
49
|
+
help="Benchmark regression threshold file.",
|
|
50
|
+
)
|
|
51
|
+
parser.add_argument(
|
|
52
|
+
"--check-thresholds",
|
|
53
|
+
action="store_true",
|
|
54
|
+
help="Fail if TensorStudio median benchmark times exceed thresholds.",
|
|
55
|
+
)
|
|
39
56
|
args = parser.parse_args()
|
|
40
57
|
|
|
41
58
|
selected_sections = set(args.section or ALL_SECTIONS)
|
|
42
|
-
|
|
59
|
+
cases, libraries, results = run_benchmark_data(selected_sections)
|
|
60
|
+
report = render_benchmark_report(cases, libraries, results)
|
|
61
|
+
write_benchmark_report(report, args.output)
|
|
43
62
|
if args.print:
|
|
44
63
|
print(report)
|
|
45
64
|
else:
|
|
46
65
|
print(f"Wrote benchmark report to {args.output}")
|
|
66
|
+
if args.check_thresholds:
|
|
67
|
+
thresholds = load_thresholds(args.thresholds)
|
|
68
|
+
failures = evaluate_thresholds(thresholds, results)
|
|
69
|
+
if failures:
|
|
70
|
+
print("Benchmark threshold failures:")
|
|
71
|
+
for failure in failures:
|
|
72
|
+
print(f"- {failure}")
|
|
73
|
+
raise SystemExit(1)
|
|
74
|
+
print(f"Benchmark thresholds passed using {args.thresholds}")
|
|
47
75
|
|
|
48
76
|
|
|
49
77
|
if __name__ == "__main__":
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import argparse
|
|
4
4
|
import importlib
|
|
5
5
|
import io
|
|
6
|
+
import json
|
|
6
7
|
import os
|
|
7
8
|
import platform
|
|
8
9
|
import statistics
|
|
@@ -794,6 +795,12 @@ def _render_report(
|
|
|
794
795
|
lines.append(f"- Processor: `{platform.processor() or 'unknown'}`")
|
|
795
796
|
lines.append(f"- Python: `{sys.version.split()[0]}`")
|
|
796
797
|
lines.append(f"- TensorStudio: `{ts.__version__}`")
|
|
798
|
+
with suppress(Exception):
|
|
799
|
+
perf_info = ts.performance_info()
|
|
800
|
+
lines.append(f"- TensorStudio threads: `{perf_info['num_threads']}`")
|
|
801
|
+
lines.append(f"- TensorStudio BLAS enabled: `{perf_info['blas_enabled']}`")
|
|
802
|
+
lines.append(f"- TensorStudio SIMD level: `{perf_info['simd_level']}`")
|
|
803
|
+
lines.append(f"- TensorStudio storage pool enabled: `{perf_info['storage_pool_enabled']}`")
|
|
797
804
|
lines.append(f"- NumPy: `{np.__version__}`")
|
|
798
805
|
for library in libraries:
|
|
799
806
|
if library.name in {"TensorStudio", "NumPy"}:
|
|
@@ -925,14 +932,55 @@ def _render_report(
|
|
|
925
932
|
return "\n".join(lines)
|
|
926
933
|
|
|
927
934
|
|
|
928
|
-
def
|
|
935
|
+
def run_benchmark_data(
|
|
936
|
+
sections: set[str],
|
|
937
|
+
) -> tuple[list[BenchmarkCase], list[Library], dict[str, Stats]]:
|
|
929
938
|
libraries = _load_libraries()
|
|
930
939
|
cases = _build_cases(sections)
|
|
931
940
|
results = _run_cases(cases, libraries)
|
|
932
|
-
|
|
941
|
+
return cases, libraries, results
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
def render_benchmark_report(
|
|
945
|
+
cases: list[BenchmarkCase],
|
|
946
|
+
libraries: list[Library],
|
|
947
|
+
results: dict[str, Stats],
|
|
948
|
+
) -> str:
|
|
949
|
+
return _render_report(cases, libraries, results)
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
def write_benchmark_report(report: str, output: Path | None) -> None:
|
|
933
953
|
if output is not None:
|
|
934
954
|
output.parent.mkdir(parents=True, exist_ok=True)
|
|
935
955
|
output.write_text(report, encoding="utf-8")
|
|
956
|
+
|
|
957
|
+
|
|
958
|
+
def load_thresholds(path: Path) -> dict[str, Any]:
|
|
959
|
+
return json.loads(path.read_text(encoding="utf-8"))
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
def evaluate_thresholds(thresholds: dict[str, Any], results: dict[str, Stats]) -> list[str]:
|
|
963
|
+
failures: list[str] = []
|
|
964
|
+
for item in thresholds.get("cases", []):
|
|
965
|
+
category = str(item["category"])
|
|
966
|
+
operation = str(item["operation"])
|
|
967
|
+
shape = str(item["shape"])
|
|
968
|
+
max_ms = float(item["max_median_ms"])
|
|
969
|
+
key = f"{category}|{operation}|{shape}|TensorStudio"
|
|
970
|
+
stats = results.get(key)
|
|
971
|
+
label = f"{category}/{operation}/{shape}"
|
|
972
|
+
if stats is None:
|
|
973
|
+
failures.append(f"{label}: no TensorStudio benchmark result was recorded")
|
|
974
|
+
continue
|
|
975
|
+
if stats.median_ms > max_ms:
|
|
976
|
+
failures.append(f"{label}: median {stats.median_ms:.4f} ms exceeded {max_ms:.4f} ms")
|
|
977
|
+
return failures
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
def run_benchmarks(sections: set[str], output: Path | None) -> str:
|
|
981
|
+
cases, libraries, results = run_benchmark_data(sections)
|
|
982
|
+
report = _render_report(cases, libraries, results)
|
|
983
|
+
write_benchmark_report(report, output)
|
|
936
984
|
return report
|
|
937
985
|
|
|
938
986
|
|