tensorstudio 1.3.1__tar.gz → 1.3.3__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.3}/CHANGELOG.md +15 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/PKG-INFO +2 -2
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/README.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Autograde/index.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Benchmarks/index.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Hardware/cpu-backend.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Neural Networks/training.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Roadmap/index.md +4 -2
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Usage/interchange.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Usage/serialization.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/index.md +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/publishing.md +4 -4
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/include/tensorstudio/version.hpp +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/pyproject.toml +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/_version.py +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/vision/transforms.py +2 -2
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/vision/visualization.py +4 -1
- tensorstudio-1.3.3/tests/test_broadcasting.py +106 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/tests/test_import.py +1 -1
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/.github/workflows/ci.yml +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/.github/workflows/publish-testpypi.yml +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/.github/workflows/publish.yml +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/.github/workflows/wheels.yml +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/.gitignore +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/.pre-commit-config.yaml +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/CMakeLists.txt +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/CONTRIBUTING.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/LICENSE +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/SECURITY.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmark_all.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/bench_activations.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/bench_autograd.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/bench_conv2d.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/bench_elementwise.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/bench_matmul.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/bench_pooling.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/bench_reductions.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/bench_tensor_ops.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/bench_training_loop.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/benchmark_report.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/results.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/results_conv2d.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/results_matmul.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/results_pooling.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/results_reductions.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/benchmarks/results_tensor_ops.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Autograde/autograd.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Hardware/linux.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Hardware/macos.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Hardware/windows.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Neural Networks/modules.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Neural Networks/nn.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Projects/index.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Usage/api.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Usage/data.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Usage/numpy-interop.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Usage/optim.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Usage/tensors.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/Vision/index.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/development.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/quickstart.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/docs/serialization.md +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/examples/basic_tensor_ops.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/examples/export_onnx.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/examples/image_folder_classification.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/examples/linear_regression.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/examples/project_training.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/examples/save_load_model.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/examples/tiny_mlp.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/examples/vision_classifier.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/include/tensorstudio/autograd.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/include/tensorstudio/device.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/include/tensorstudio/dtype.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/include/tensorstudio/errors.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/include/tensorstudio/module.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/include/tensorstudio/ops.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/include/tensorstudio/optim.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/include/tensorstudio/random.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/include/tensorstudio/serialization.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/include/tensorstudio/shape.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/include/tensorstudio/storage.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/include/tensorstudio/tensor.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/mkdocs.yml +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/_C.pyi +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/autograd.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/data/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/data/dataloader.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/data/dataset.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/dtypes.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/errors.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/grad_mode.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/interchange/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/interchange/onnx.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/math.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/nn/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/nn/functional.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/nn/losses.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/nn/modules.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/ops.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/optim/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/optim/adam.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/optim/adamw.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/optim/lr_scheduler.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/optim/sgd.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/optim/utils.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/project/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/project/checkpoint.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/project/config.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/project/trainer.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/py.typed +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/serialization.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/tensor.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/typing.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/vision/__init__.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/vision/datasets.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/vision/io.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/vision/metrics.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/python/tensorstudio/vision/models.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/bindings/bind_autograd.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/bindings/bind_nn.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/bindings/bind_ops.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/bindings/bind_optim.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/bindings/bind_tensor.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/bindings/bindings.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/bindings/bindings.hpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/core/autograd.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/core/device.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/core/dtype.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/core/errors.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/core/module.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/core/ops.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/core/optim.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/core/random.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/core/serialization.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/core/shape.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/core/storage.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/src/core/tensor.cpp +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/test_all.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/tests/test_autograd.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/tests/test_benchmark_report.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/tests/test_data.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/tests/test_interchange.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/tests/test_nn.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/tests/test_numpy_interop.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/tests/test_ops.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/tests/test_optim.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/tests/test_project.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/tests/test_serialization.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/tests/test_tensor.py +0 -0
- {tensorstudio-1.3.1 → tensorstudio-1.3.3}/tests/test_vision.py +0 -0
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 1.3.3 - 2026-07-07
|
|
6
|
+
|
|
7
|
+
- Hardened CI type checks for newer Python/mypy combinations by annotating
|
|
8
|
+
NumPy temporaries in vision transform and visualization helpers.
|
|
9
|
+
- This patch does not change runtime behavior.
|
|
10
|
+
|
|
11
|
+
## 1.3.2 - 2026-07-07
|
|
12
|
+
|
|
13
|
+
- Completed the second ordered roadmap item with exhaustive binary
|
|
14
|
+
elementwise broadcasting tests.
|
|
15
|
+
- Added NumPy comparison coverage for broadcasted `add`, `sub`, `mul`, `div`,
|
|
16
|
+
equality, inequality, and ordered comparisons.
|
|
17
|
+
- Added incompatible-broadcast error tests and operator-overload broadcasting
|
|
18
|
+
parity tests.
|
|
19
|
+
|
|
5
20
|
## 1.3.1 - 2026-07-07
|
|
6
21
|
|
|
7
22
|
- 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.3
|
|
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.3` 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.3` 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.3` 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.3`; 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.3` 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.3` 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.3
|
|
26
|
+
git push origin v1.3.3
|
|
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.3
|
|
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.3
|
|
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.3"
|
|
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"
|
|
@@ -278,7 +278,7 @@ def resize_bilinear(image: Any, size: int | tuple[int, int]) -> np.ndarray | Ten
|
|
|
278
278
|
height_axis, width_axis = _spatial_axes(array)
|
|
279
279
|
height = array.shape[height_axis]
|
|
280
280
|
width = array.shape[width_axis]
|
|
281
|
-
working = np.moveaxis(array, (height_axis, width_axis), (0, 1)).astype(np.float64)
|
|
281
|
+
working: np.ndarray = np.moveaxis(array, (height_axis, width_axis), (0, 1)).astype(np.float64)
|
|
282
282
|
|
|
283
283
|
y_coords = np.zeros(out_h) if out_h == 1 else np.linspace(0, height - 1, out_h)
|
|
284
284
|
x_coords = np.zeros(out_w) if out_w == 1 else np.linspace(0, width - 1, out_w)
|
|
@@ -365,7 +365,7 @@ def rgb_to_grayscale(image: Any) -> np.ndarray | Tensor:
|
|
|
365
365
|
return _same_kind(image, array)
|
|
366
366
|
if array.shape[channel_axis] < 3:
|
|
367
367
|
raise ValueError("RGB grayscale conversion requires at least three channels")
|
|
368
|
-
moved = np.moveaxis(array, channel_axis, -1).astype(np.float64)
|
|
368
|
+
moved: np.ndarray = np.moveaxis(array, channel_axis, -1).astype(np.float64)
|
|
369
369
|
gray = (
|
|
370
370
|
moved[..., 0] * 0.299
|
|
371
371
|
+ moved[..., 1] * 0.587
|
|
@@ -36,7 +36,10 @@ def draw_bounding_boxes(
|
|
|
36
36
|
array = np.clip(array, 0, 255).astype(np.uint8)
|
|
37
37
|
pil_image = Image.fromarray(array)
|
|
38
38
|
draw = ImageDraw.Draw(pil_image)
|
|
39
|
-
box_array = np.asarray(
|
|
39
|
+
box_array: np.ndarray = np.asarray(
|
|
40
|
+
boxes.numpy() if isinstance(boxes, Tensor) else boxes,
|
|
41
|
+
dtype=np.float64,
|
|
42
|
+
)
|
|
40
43
|
if box_array.ndim != 2 or box_array.shape[1] != 4:
|
|
41
44
|
raise ValueError("boxes must have shape (N, 4)")
|
|
42
45
|
if labels is not None and len(labels) != box_array.shape[0]:
|
|
@@ -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
|