tensorstudio 1.3.1__tar.gz → 1.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/CHANGELOG.md +9 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/PKG-INFO +2 -2
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/README.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Autograde/index.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Benchmarks/index.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Hardware/cpu-backend.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Neural Networks/training.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Roadmap/index.md +4 -2
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Usage/interchange.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Usage/serialization.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/index.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/publishing.md +4 -4
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/include/tensorstudio/version.hpp +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/pyproject.toml +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/_version.py +1 -1
- tensorstudio-1.3.2/tests/test_broadcasting.py +106 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/tests/test_import.py +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/.github/workflows/ci.yml +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/.github/workflows/publish-testpypi.yml +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/.github/workflows/publish.yml +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/.github/workflows/wheels.yml +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/.gitignore +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/.pre-commit-config.yaml +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/CMakeLists.txt +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/CONTRIBUTING.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/LICENSE +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/SECURITY.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmark_all.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/bench_activations.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/bench_autograd.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/bench_conv2d.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/bench_elementwise.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/bench_matmul.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/bench_pooling.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/bench_reductions.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/bench_tensor_ops.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/bench_training_loop.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/benchmark_report.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/results.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/results_conv2d.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/results_matmul.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/results_pooling.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/results_reductions.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/benchmarks/results_tensor_ops.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Autograde/autograd.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Hardware/linux.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Hardware/macos.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Hardware/windows.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Neural Networks/modules.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Neural Networks/nn.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Projects/index.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Usage/api.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Usage/data.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Usage/numpy-interop.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Usage/optim.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Usage/tensors.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/Vision/index.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/development.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/quickstart.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/docs/serialization.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/examples/basic_tensor_ops.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/examples/export_onnx.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/examples/image_folder_classification.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/examples/linear_regression.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/examples/project_training.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/examples/save_load_model.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/examples/tiny_mlp.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/examples/vision_classifier.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/include/tensorstudio/autograd.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/include/tensorstudio/device.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/include/tensorstudio/dtype.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/include/tensorstudio/errors.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/include/tensorstudio/module.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/include/tensorstudio/ops.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/include/tensorstudio/optim.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/include/tensorstudio/random.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/include/tensorstudio/serialization.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/include/tensorstudio/shape.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/include/tensorstudio/storage.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/include/tensorstudio/tensor.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/mkdocs.yml +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/_C.pyi +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/autograd.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/data/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/data/dataloader.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/data/dataset.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/dtypes.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/errors.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/grad_mode.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/interchange/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/interchange/onnx.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/math.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/nn/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/nn/functional.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/nn/losses.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/nn/modules.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/ops.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/optim/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/optim/adam.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/optim/adamw.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/optim/lr_scheduler.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/optim/sgd.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/optim/utils.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/project/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/project/checkpoint.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/project/config.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/project/trainer.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/py.typed +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/serialization.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/tensor.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/typing.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/vision/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/vision/datasets.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/vision/io.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/vision/metrics.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/vision/models.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/vision/transforms.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/python/tensorstudio/vision/visualization.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/bindings/bind_autograd.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/bindings/bind_nn.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/bindings/bind_ops.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/bindings/bind_optim.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/bindings/bind_tensor.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/bindings/bindings.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/bindings/bindings.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/core/autograd.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/core/device.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/core/dtype.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/core/errors.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/core/module.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/core/ops.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/core/optim.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/core/random.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/core/serialization.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/core/shape.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/core/storage.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/src/core/tensor.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/test_all.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/tests/test_autograd.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/tests/test_benchmark_report.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/tests/test_data.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/tests/test_interchange.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/tests/test_nn.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/tests/test_numpy_interop.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/tests/test_ops.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/tests/test_optim.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/tests/test_project.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/tests/test_serialization.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/tests/test_tensor.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.2}/tests/test_vision.py +0 -0
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 1.3.2 - 2026-07-07
|
|
6
|
+
|
|
7
|
+
- Completed the second ordered roadmap item with exhaustive binary
|
|
8
|
+
elementwise broadcasting tests.
|
|
9
|
+
- Added NumPy comparison coverage for broadcasted `add`, `sub`, `mul`, `div`,
|
|
10
|
+
equality, inequality, and ordered comparisons.
|
|
11
|
+
- Added incompatible-broadcast error tests and operator-overload broadcasting
|
|
12
|
+
parity tests.
|
|
13
|
+
|
|
5
14
|
## 1.3.1 - 2026-07-07
|
|
6
15
|
|
|
7
16
|
- Started the ordered roadmap release train with the dtype-promotion contract.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: tensorstudio
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.2
|
|
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,7 +71,7 @@ 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.3.
|
|
74
|
+
TensorStudio `1.3.2` is a CPU-only stable API foundation. It is eager-only,
|
|
75
75
|
intentionally small, and not a replacement for mature ML frameworks.
|
|
76
76
|
|
|
77
77
|
## Install
|
|
@@ -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.3.
|
|
10
|
+
TensorStudio `1.3.2` 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
|
|
@@ -55,7 +55,7 @@ equivalents where available.
|
|
|
55
55
|
## Interpreting Results
|
|
56
56
|
|
|
57
57
|
Expect NumPy and PyTorch to be faster for many medium and large operations
|
|
58
|
-
because they use highly optimized native kernels. TensorStudio `1.3.
|
|
58
|
+
because they use highly optimized native kernels. TensorStudio `1.3.2` still
|
|
59
59
|
favors clarity, portability, and a compact C++ implementation over full kernel
|
|
60
60
|
library performance.
|
|
61
61
|
|
|
@@ -80,7 +80,7 @@ w = ts.randn((4, 4), seed=123)
|
|
|
80
80
|
|
|
81
81
|
## Practical Tips
|
|
82
82
|
|
|
83
|
-
- Keep tensors modest in `1.3.
|
|
83
|
+
- Keep tensors modest in `1.3.2`; kernels are simple CPU loops.
|
|
84
84
|
- Prefer `float32` unless you need `float64`.
|
|
85
85
|
- Compare with NumPy in tests for expected numerical values.
|
|
86
86
|
- Watch shape errors carefully around broadcasting and matrix multiplication.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Roadmap
|
|
2
2
|
|
|
3
|
-
TensorStudio `1.3.
|
|
3
|
+
TensorStudio `1.3.2` is a CPU-first tensor, autograd, neural-network, vision,
|
|
4
4
|
project, serialization, and ONNX-export foundation. The long-term direction is
|
|
5
5
|
to become a strong compact ML framework for learning, experimentation, and
|
|
6
6
|
lightweight workloads while staying honest about the scale of mature systems
|
|
@@ -18,7 +18,9 @@ tensor semantics.
|
|
|
18
18
|
- Completed in `1.3.1`: define, expose, test, and document dtype promotion
|
|
19
19
|
rules across binary arithmetic, division, matrix multiplication, and
|
|
20
20
|
comparisons.
|
|
21
|
-
-
|
|
21
|
+
- Completed in `1.3.2`: add exhaustive broadcasting tests for every binary
|
|
22
|
+
elementwise arithmetic and comparison operation, including functional and
|
|
23
|
+
operator overload paths.
|
|
22
24
|
- Add tuple-axis reductions for `sum`, `mean`, `max`, and `min`.
|
|
23
25
|
- Add arg reductions: `argmax` and `argmin`.
|
|
24
26
|
- Add `where`, `maximum`, `minimum`, `clip`, and richer comparison helpers.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
TensorStudio is a compact C++ tensor and autograd engine with a Python API for
|
|
4
4
|
learning, experimentation, and lightweight ML workloads.
|
|
5
5
|
|
|
6
|
-
`1.3.
|
|
6
|
+
`1.3.2` is a CPU-only stable API foundation for the tensor, autograd,
|
|
7
7
|
neural-network, optimizer, data, project, serialization, ONNX export, vision,
|
|
8
8
|
docs, packaging, and wheel workflows.
|
|
9
9
|
|
|
@@ -22,8 +22,8 @@ Windows, Linux, and macOS.
|
|
|
22
22
|
After the release checklist passes, tag the stable release:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
git tag v1.3.
|
|
26
|
-
git push origin v1.3.
|
|
25
|
+
git tag v1.3.2
|
|
26
|
+
git push origin v1.3.2
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
Stable release notes must avoid unsupported performance claims. Publish measured
|
|
@@ -63,7 +63,7 @@ clean environment:
|
|
|
63
63
|
python -m venv .venv-testpypi
|
|
64
64
|
. .venv-testpypi/bin/activate
|
|
65
65
|
python -m pip install -U pip
|
|
66
|
-
python -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ tensorstudio==1.3.
|
|
66
|
+
python -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ tensorstudio==1.3.2
|
|
67
67
|
python -c "import tensorstudio as ts; import tensorstudio._C; print(ts.__version__)"
|
|
68
68
|
deactivate
|
|
69
69
|
```
|
|
@@ -74,7 +74,7 @@ On Windows PowerShell:
|
|
|
74
74
|
python -m venv .venv-testpypi
|
|
75
75
|
.\.venv-testpypi\Scripts\Activate.ps1
|
|
76
76
|
python -m pip install -U pip
|
|
77
|
-
python -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ tensorstudio==1.3.
|
|
77
|
+
python -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ tensorstudio==1.3.2
|
|
78
78
|
python -c "import tensorstudio as ts; import tensorstudio._C; print(ts.__version__)"
|
|
79
79
|
deactivate
|
|
80
80
|
```
|
|
@@ -7,7 +7,7 @@ build-backend = "scikit_build_core.build"
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "tensorstudio"
|
|
10
|
-
version = "1.3.
|
|
10
|
+
version = "1.3.2"
|
|
11
11
|
description = "TensorStudio is a compact C++ tensor and autograd engine with a Python API for learning, experimentation, and lightweight ML workloads."
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
requires-python = ">=3.10"
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import pytest
|
|
7
|
+
import tensorstudio as ts
|
|
8
|
+
from tensorstudio import ops
|
|
9
|
+
|
|
10
|
+
TensorBinary = Callable[[ts.Tensor, ts.Tensor], ts.Tensor]
|
|
11
|
+
NumpyBinary = Callable[[np.ndarray, np.ndarray], np.ndarray]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _broadcast_cases() -> list[tuple[np.ndarray, np.ndarray]]:
|
|
15
|
+
return [
|
|
16
|
+
(
|
|
17
|
+
np.array(2.0, dtype=np.float64),
|
|
18
|
+
np.array([[1.0, -2.0, 4.0]], dtype=np.float64),
|
|
19
|
+
),
|
|
20
|
+
(
|
|
21
|
+
np.array([1.0, -2.0, 4.0], dtype=np.float64),
|
|
22
|
+
np.array([[0.5, 2.0, -1.0], [3.0, -4.0, 5.0]], dtype=np.float64),
|
|
23
|
+
),
|
|
24
|
+
(
|
|
25
|
+
np.array([[1.0, -2.0, 4.0]], dtype=np.float64),
|
|
26
|
+
np.array([[0.5], [2.0]], dtype=np.float64),
|
|
27
|
+
),
|
|
28
|
+
(
|
|
29
|
+
np.arange(6, dtype=np.float64).reshape(2, 1, 3) - 2.0,
|
|
30
|
+
np.arange(4, dtype=np.float64).reshape(1, 4, 1) + 1.0,
|
|
31
|
+
),
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@pytest.mark.parametrize(
|
|
36
|
+
("name", "tensor_op", "numpy_op"),
|
|
37
|
+
[
|
|
38
|
+
("add", ops.add, np.add),
|
|
39
|
+
("sub", ops.sub, np.subtract),
|
|
40
|
+
("mul", ops.mul, np.multiply),
|
|
41
|
+
("div", ops.div, np.divide),
|
|
42
|
+
("equal", ops.equal, np.equal),
|
|
43
|
+
("not_equal", ops.not_equal, np.not_equal),
|
|
44
|
+
("less", ops.less, np.less),
|
|
45
|
+
("less_equal", ops.less_equal, np.less_equal),
|
|
46
|
+
("greater", ops.greater, np.greater),
|
|
47
|
+
("greater_equal", ops.greater_equal, np.greater_equal),
|
|
48
|
+
],
|
|
49
|
+
)
|
|
50
|
+
@pytest.mark.parametrize(("left_np", "right_np"), _broadcast_cases())
|
|
51
|
+
def test_binary_elementwise_broadcasting_matches_numpy(
|
|
52
|
+
name: str,
|
|
53
|
+
tensor_op: TensorBinary,
|
|
54
|
+
numpy_op: NumpyBinary,
|
|
55
|
+
left_np: np.ndarray,
|
|
56
|
+
right_np: np.ndarray,
|
|
57
|
+
) -> None:
|
|
58
|
+
left = ts.from_numpy(left_np)
|
|
59
|
+
right = ts.from_numpy(right_np)
|
|
60
|
+
|
|
61
|
+
actual = tensor_op(left, right).numpy()
|
|
62
|
+
expected = numpy_op(left_np, right_np)
|
|
63
|
+
|
|
64
|
+
if expected.dtype == np.bool_:
|
|
65
|
+
np.testing.assert_array_equal(actual, expected, err_msg=name)
|
|
66
|
+
else:
|
|
67
|
+
np.testing.assert_allclose(actual, expected, rtol=1e-7, atol=1e-7, err_msg=name)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@pytest.mark.parametrize(
|
|
71
|
+
("name", "tensor_op"),
|
|
72
|
+
[
|
|
73
|
+
("add", ops.add),
|
|
74
|
+
("sub", ops.sub),
|
|
75
|
+
("mul", ops.mul),
|
|
76
|
+
("div", ops.div),
|
|
77
|
+
("equal", ops.equal),
|
|
78
|
+
("not_equal", ops.not_equal),
|
|
79
|
+
("less", ops.less),
|
|
80
|
+
("less_equal", ops.less_equal),
|
|
81
|
+
("greater", ops.greater),
|
|
82
|
+
("greater_equal", ops.greater_equal),
|
|
83
|
+
],
|
|
84
|
+
)
|
|
85
|
+
def test_binary_elementwise_broadcast_errors_are_consistent(
|
|
86
|
+
name: str,
|
|
87
|
+
tensor_op: TensorBinary,
|
|
88
|
+
) -> None:
|
|
89
|
+
with pytest.raises(Exception, match="broadcast"):
|
|
90
|
+
tensor_op(ts.ones((2, 3)), ts.ones((4,)))
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_operator_broadcasting_paths_match_functional_ops() -> None:
|
|
94
|
+
left = ts.tensor([[1.0, 2.0, 3.0]])
|
|
95
|
+
right = ts.tensor([[10.0], [20.0]])
|
|
96
|
+
|
|
97
|
+
np.testing.assert_allclose((left + right).numpy(), ops.add(left, right).numpy())
|
|
98
|
+
np.testing.assert_allclose((left - right).numpy(), ops.sub(left, right).numpy())
|
|
99
|
+
np.testing.assert_allclose((left * right).numpy(), ops.mul(left, right).numpy())
|
|
100
|
+
np.testing.assert_allclose((left / right).numpy(), ops.div(left, right).numpy())
|
|
101
|
+
np.testing.assert_array_equal((left == right).numpy(), ops.equal(left, right).numpy())
|
|
102
|
+
np.testing.assert_array_equal((left != right).numpy(), ops.not_equal(left, right).numpy())
|
|
103
|
+
np.testing.assert_array_equal((left < right).numpy(), ops.less(left, right).numpy())
|
|
104
|
+
np.testing.assert_array_equal((left <= right).numpy(), ops.less_equal(left, right).numpy())
|
|
105
|
+
np.testing.assert_array_equal((left > right).numpy(), ops.greater(left, right).numpy())
|
|
106
|
+
np.testing.assert_array_equal((left >= right).numpy(), ops.greater_equal(left, right).numpy())
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|