tensorstudio 1.3.4__tar.gz → 1.3.5__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.4 → tensorstudio-1.3.5}/CHANGELOG.md +10 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/PKG-INFO +4 -2
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/README.md +3 -1
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Autograde/index.md +1 -1
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Benchmarks/index.md +1 -1
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Hardware/cpu-backend.md +1 -1
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Neural Networks/training.md +1 -1
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Roadmap/index.md +2 -2
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Usage/api.md +6 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Usage/interchange.md +1 -1
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Usage/serialization.md +1 -1
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Usage/tensors.md +4 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/index.md +5 -4
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/publishing.md +4 -4
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/quickstart.md +1 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/include/tensorstudio/ops.hpp +4 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/include/tensorstudio/version.hpp +1 -1
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/pyproject.toml +1 -1
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/_C.pyi +4 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/__init__.py +4 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/_version.py +1 -1
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/ops.py +10 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/bindings/bind_ops.cpp +14 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/bindings/bind_tensor.cpp +30 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/bindings/bindings.hpp +7 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/core/ops.cpp +69 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_import.py +1 -1
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_ops.py +42 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/.github/workflows/ci.yml +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/.github/workflows/publish-testpypi.yml +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/.github/workflows/publish.yml +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/.github/workflows/wheels.yml +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/.gitignore +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/.pre-commit-config.yaml +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/CMakeLists.txt +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/CONTRIBUTING.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/LICENSE +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/SECURITY.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmark_all.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/__init__.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/bench_activations.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/bench_autograd.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/bench_conv2d.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/bench_elementwise.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/bench_matmul.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/bench_pooling.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/bench_reductions.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/bench_tensor_ops.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/bench_training_loop.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/benchmark_report.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/results.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/results_conv2d.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/results_matmul.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/results_pooling.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/results_reductions.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/benchmarks/results_tensor_ops.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Autograde/autograd.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Hardware/linux.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Hardware/macos.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Hardware/windows.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Neural Networks/modules.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Neural Networks/nn.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Projects/index.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Usage/data.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Usage/numpy-interop.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Usage/optim.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/Vision/index.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/development.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/docs/serialization.md +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/examples/basic_tensor_ops.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/examples/export_onnx.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/examples/image_folder_classification.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/examples/linear_regression.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/examples/project_training.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/examples/save_load_model.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/examples/tiny_mlp.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/examples/vision_classifier.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/include/tensorstudio/autograd.hpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/include/tensorstudio/device.hpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/include/tensorstudio/dtype.hpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/include/tensorstudio/errors.hpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/include/tensorstudio/module.hpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/include/tensorstudio/optim.hpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/include/tensorstudio/random.hpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/include/tensorstudio/serialization.hpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/include/tensorstudio/shape.hpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/include/tensorstudio/storage.hpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/include/tensorstudio/tensor.hpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/mkdocs.yml +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/autograd.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/data/__init__.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/data/dataloader.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/data/dataset.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/dtypes.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/errors.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/grad_mode.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/interchange/__init__.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/interchange/onnx.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/math.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/nn/__init__.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/nn/functional.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/nn/losses.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/nn/modules.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/optim/__init__.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/optim/adam.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/optim/adamw.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/optim/lr_scheduler.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/optim/sgd.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/optim/utils.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/project/__init__.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/project/checkpoint.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/project/config.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/project/trainer.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/py.typed +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/serialization.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/tensor.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/typing.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/vision/__init__.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/vision/datasets.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/vision/io.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/vision/metrics.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/vision/models.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/vision/transforms.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/python/tensorstudio/vision/visualization.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/bindings/bind_autograd.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/bindings/bind_nn.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/bindings/bind_optim.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/bindings/bindings.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/core/autograd.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/core/device.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/core/dtype.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/core/errors.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/core/module.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/core/optim.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/core/random.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/core/serialization.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/core/shape.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/core/storage.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/src/core/tensor.cpp +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/test_all.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_autograd.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_benchmark_report.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_broadcasting.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_data.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_interchange.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_nn.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_numpy_interop.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_optim.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_project.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_serialization.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_tensor.py +0 -0
- {tensorstudio-1.3.4 → tensorstudio-1.3.5}/tests/test_vision.py +0 -0
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 1.3.5 - 2026-07-07
|
|
6
|
+
|
|
7
|
+
- Completed the next ordered correctness-roadmap item with native C++
|
|
8
|
+
`argmax` and `argmin` operations.
|
|
9
|
+
- Added Tensor methods, functional ops, top-level Python exports, and type
|
|
10
|
+
stubs for arg reductions.
|
|
11
|
+
- Added NumPy parity tests for all-element and axis arg reductions, including
|
|
12
|
+
`keepdims`, negative axes, first-tie behavior, dtype, and error cases.
|
|
13
|
+
- Documented arg-reduction semantics and limitations.
|
|
14
|
+
|
|
5
15
|
## 1.3.4 - 2026-07-07
|
|
6
16
|
|
|
7
17
|
- Completed the next ordered correctness-roadmap item with tuple/list-axis
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: tensorstudio
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.5
|
|
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.5` 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
|
|
@@ -474,6 +474,8 @@ tokens or print secrets.
|
|
|
474
474
|
- ONNX support is export-only for a limited set of TensorStudio modules.
|
|
475
475
|
- Reductions support all-element, single-axis, and tuple/list-axis reductions
|
|
476
476
|
for `sum`, `mean`, `max`, and `min`.
|
|
477
|
+
- Arg reductions support all-element flat indices or one axis at a time for
|
|
478
|
+
`argmax` and `argmin`.
|
|
477
479
|
- No sparse tensors or advanced indexing.
|
|
478
480
|
- Dtype casting is basic and does not include a full promotion/casting policy.
|
|
479
481
|
- Experimental performance; benchmarks are local references only.
|
|
@@ -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.5` 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
|
|
@@ -410,6 +410,8 @@ tokens or print secrets.
|
|
|
410
410
|
- ONNX support is export-only for a limited set of TensorStudio modules.
|
|
411
411
|
- Reductions support all-element, single-axis, and tuple/list-axis reductions
|
|
412
412
|
for `sum`, `mean`, `max`, and `min`.
|
|
413
|
+
- Arg reductions support all-element flat indices or one axis at a time for
|
|
414
|
+
`argmax` and `argmin`.
|
|
413
415
|
- No sparse tensors or advanced indexing.
|
|
414
416
|
- Dtype casting is basic and does not include a full promotion/casting policy.
|
|
415
417
|
- Experimental performance; benchmarks are local references only.
|
|
@@ -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.5` 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.5`; 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.5` 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
|
|
@@ -23,7 +23,7 @@ tensor semantics.
|
|
|
23
23
|
operator overload paths.
|
|
24
24
|
- Completed in `1.3.4`: add tuple-axis reductions for `sum`, `mean`,
|
|
25
25
|
`max`, and `min`.
|
|
26
|
-
-
|
|
26
|
+
- Completed in `1.3.5`: add arg reductions: `argmax` and `argmin`.
|
|
27
27
|
- Add `where`, `maximum`, `minimum`, `clip`, and richer comparison helpers.
|
|
28
28
|
- Add full NumPy-style indexing and slicing for common cases.
|
|
29
29
|
- Add more view/layout operations: `squeeze`, `unsqueeze`, `permute`, and
|
|
@@ -146,10 +146,16 @@ Math:
|
|
|
146
146
|
- `mean(axis=None, keepdims=False)`
|
|
147
147
|
- `max(axis=None, keepdims=False)`
|
|
148
148
|
- `min(axis=None, keepdims=False)`
|
|
149
|
+
- `argmax(axis=None, keepdims=False)`
|
|
150
|
+
- `argmin(axis=None, keepdims=False)`
|
|
149
151
|
|
|
150
152
|
For reductions, `axis` may be `None`, an int, or a tuple/list of ints.
|
|
151
153
|
Negative axes are normalized against the input rank, duplicate axes are
|
|
152
154
|
rejected, and `axis=()` is a no-op identity.
|
|
155
|
+
|
|
156
|
+
For arg reductions, `axis` may be `None` or an int. All-element arg reductions
|
|
157
|
+
return the flat index of the first selected value. Axis arg reductions return
|
|
158
|
+
`int64` indices along that axis and are not differentiable.
|
|
153
159
|
- `relu()`
|
|
154
160
|
- `sigmoid()`
|
|
155
161
|
- `tanh()`
|
|
@@ -184,6 +184,8 @@ Matrix and reductions:
|
|
|
184
184
|
- `mean`
|
|
185
185
|
- `max`
|
|
186
186
|
- `min`
|
|
187
|
+
- `argmax`
|
|
188
|
+
- `argmin`
|
|
187
189
|
|
|
188
190
|
Reductions operate over all elements by default and support an int axis or a
|
|
189
191
|
tuple/list of axes with `keepdims`:
|
|
@@ -194,6 +196,8 @@ x.sum(axis=1)
|
|
|
194
196
|
x.mean(axis=0, keepdims=True)
|
|
195
197
|
x.max(axis=-1)
|
|
196
198
|
x.reshape((1, 2, 3)).sum(axis=(0, 2))
|
|
199
|
+
x.argmax()
|
|
200
|
+
x.argmin(axis=1)
|
|
197
201
|
```
|
|
198
202
|
|
|
199
203
|
Higher-level helpers in `tensorstudio.math` include variance, standard
|
|
@@ -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.5` 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
|
|
|
@@ -27,9 +27,10 @@ TensorStudio is:
|
|
|
27
27
|
`*_like` helpers.
|
|
28
28
|
- NumPy-style broadcasting for binary elementwise operations.
|
|
29
29
|
- Arithmetic, comparisons, matrix multiplication, all-element, single-axis, and
|
|
30
|
-
tuple-axis reductions, common activations, trigonometric
|
|
31
|
-
trigonometric functions, `log1p`, `sqrt`, `rsqrt`, `abs`,
|
|
32
|
-
`conv2d`, `max_pool2d`, `avg_pool2d`, reshape, flatten,
|
|
30
|
+
tuple-axis reductions, arg reductions, common activations, trigonometric
|
|
31
|
+
functions, inverse trigonometric functions, `log1p`, `sqrt`, `rsqrt`, `abs`,
|
|
32
|
+
`clamp`, CPU NCHW `conv2d`, `max_pool2d`, `avg_pool2d`, reshape, flatten,
|
|
33
|
+
and 2D transpose.
|
|
33
34
|
- Higher-level `tensorstudio.math` helpers for variance, standard deviation,
|
|
34
35
|
norms, square, and reciprocal.
|
|
35
36
|
- Basic dtype casting plus native `concat` and `stack`.
|
|
@@ -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.5
|
|
26
|
+
git push origin v1.3.5
|
|
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.5
|
|
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.5
|
|
78
78
|
python -c "import tensorstudio as ts; import tensorstudio._C; print(ts.__version__)"
|
|
79
79
|
deactivate
|
|
80
80
|
```
|
|
@@ -117,6 +117,7 @@ print(x.sum().item())
|
|
|
117
117
|
print(x.mean(axis=0).tolist())
|
|
118
118
|
print(x.max(axis=1, keepdims=True).tolist())
|
|
119
119
|
print(ts.arange(24).reshape((2, 3, 4)).sum(axis=(0, 2)).tolist())
|
|
120
|
+
print(x.argmax().item())
|
|
120
121
|
```
|
|
121
122
|
|
|
122
123
|
Tensors can be cast, concatenated, and stacked:
|
|
@@ -66,6 +66,10 @@ Tensor max(const Tensor& input);
|
|
|
66
66
|
Tensor max(const Tensor& input, int64_t axis, bool keepdims = false);
|
|
67
67
|
Tensor min(const Tensor& input);
|
|
68
68
|
Tensor min(const Tensor& input, int64_t axis, bool keepdims = false);
|
|
69
|
+
Tensor argmax(const Tensor& input, bool keepdims = false);
|
|
70
|
+
Tensor argmax(const Tensor& input, int64_t axis, bool keepdims = false);
|
|
71
|
+
Tensor argmin(const Tensor& input, bool keepdims = false);
|
|
72
|
+
Tensor argmin(const Tensor& input, int64_t axis, bool keepdims = false);
|
|
69
73
|
Tensor relu(const Tensor& input);
|
|
70
74
|
Tensor sigmoid(const Tensor& input);
|
|
71
75
|
Tensor tanh(const Tensor& input);
|
|
@@ -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.5"
|
|
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"
|
|
@@ -29,6 +29,8 @@ class Tensor:
|
|
|
29
29
|
def mean(self, axis: AxisLike = None, keepdims: bool = False) -> Tensor: ...
|
|
30
30
|
def max(self, axis: AxisLike = None, keepdims: bool = False) -> Tensor: ...
|
|
31
31
|
def min(self, axis: AxisLike = None, keepdims: bool = False) -> Tensor: ...
|
|
32
|
+
def argmax(self, axis: int | None = None, keepdims: bool = False) -> Tensor: ...
|
|
33
|
+
def argmin(self, axis: int | None = None, keepdims: bool = False) -> Tensor: ...
|
|
32
34
|
def relu(self) -> Tensor: ...
|
|
33
35
|
def sigmoid(self) -> Tensor: ...
|
|
34
36
|
def tanh(self) -> Tensor: ...
|
|
@@ -146,6 +148,8 @@ def sum(input: Tensor, axis: AxisLike = None, keepdims: bool = False) -> Tensor:
|
|
|
146
148
|
def mean(input: Tensor, axis: AxisLike = None, keepdims: bool = False) -> Tensor: ...
|
|
147
149
|
def max(input: Tensor, axis: AxisLike = None, keepdims: bool = False) -> Tensor: ...
|
|
148
150
|
def min(input: Tensor, axis: AxisLike = None, keepdims: bool = False) -> Tensor: ...
|
|
151
|
+
def argmax(input: Tensor, axis: int | None = None, keepdims: bool = False) -> Tensor: ...
|
|
152
|
+
def argmin(input: Tensor, axis: int | None = None, keepdims: bool = False) -> Tensor: ...
|
|
149
153
|
def relu(input: Tensor) -> Tensor: ...
|
|
150
154
|
def sigmoid(input: Tensor) -> Tensor: ...
|
|
151
155
|
def tanh(input: Tensor) -> Tensor: ...
|
|
@@ -9,6 +9,8 @@ from .grad_mode import is_grad_enabled, no_grad, set_grad_enabled
|
|
|
9
9
|
from .interchange import export_onnx
|
|
10
10
|
from .ops import (
|
|
11
11
|
acos,
|
|
12
|
+
argmax,
|
|
13
|
+
argmin,
|
|
12
14
|
asin,
|
|
13
15
|
astype,
|
|
14
16
|
atan,
|
|
@@ -50,6 +52,8 @@ __all__ = [
|
|
|
50
52
|
"Tensor",
|
|
51
53
|
"__version__",
|
|
52
54
|
"acos",
|
|
55
|
+
"argmax",
|
|
56
|
+
"argmin",
|
|
53
57
|
"arange",
|
|
54
58
|
"asin",
|
|
55
59
|
"astype",
|
|
@@ -164,6 +164,14 @@ def min(input: Tensor, axis: AxisLike = None, keepdims: bool = False) -> Tensor:
|
|
|
164
164
|
return _C.min(input, axis, keepdims)
|
|
165
165
|
|
|
166
166
|
|
|
167
|
+
def argmax(input: Tensor, axis: int | None = None, keepdims: bool = False) -> Tensor:
|
|
168
|
+
return _C.argmax(input, axis, keepdims)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def argmin(input: Tensor, axis: int | None = None, keepdims: bool = False) -> Tensor:
|
|
172
|
+
return _C.argmin(input, axis, keepdims)
|
|
173
|
+
|
|
174
|
+
|
|
167
175
|
def relu(input: Tensor) -> Tensor:
|
|
168
176
|
return _C.relu(input)
|
|
169
177
|
|
|
@@ -260,6 +268,8 @@ __all__ = [
|
|
|
260
268
|
"add",
|
|
261
269
|
"abs",
|
|
262
270
|
"acos",
|
|
271
|
+
"argmax",
|
|
272
|
+
"argmin",
|
|
263
273
|
"asin",
|
|
264
274
|
"astype",
|
|
265
275
|
"atan",
|
|
@@ -101,6 +101,20 @@ void bind_ops(py::module_& module) {
|
|
|
101
101
|
return min(tensor, normalized_axis, keep);
|
|
102
102
|
});
|
|
103
103
|
}, py::arg("input"), py::arg("axis") = py::none(), py::arg("keepdims") = false);
|
|
104
|
+
module.def("argmax", [](const Tensor& input, py::object axis, bool keepdims) {
|
|
105
|
+
return arg_reduce_from_py(input, std::move(axis), keepdims, "argmax", [](const Tensor& tensor, bool keep) {
|
|
106
|
+
return argmax(tensor, keep);
|
|
107
|
+
}, [](const Tensor& tensor, int64_t normalized_axis, bool keep) {
|
|
108
|
+
return argmax(tensor, normalized_axis, keep);
|
|
109
|
+
});
|
|
110
|
+
}, py::arg("input"), py::arg("axis") = py::none(), py::arg("keepdims") = false);
|
|
111
|
+
module.def("argmin", [](const Tensor& input, py::object axis, bool keepdims) {
|
|
112
|
+
return arg_reduce_from_py(input, std::move(axis), keepdims, "argmin", [](const Tensor& tensor, bool keep) {
|
|
113
|
+
return argmin(tensor, keep);
|
|
114
|
+
}, [](const Tensor& tensor, int64_t normalized_axis, bool keep) {
|
|
115
|
+
return argmin(tensor, normalized_axis, keep);
|
|
116
|
+
});
|
|
117
|
+
}, py::arg("input"), py::arg("axis") = py::none(), py::arg("keepdims") = false);
|
|
104
118
|
module.def("relu", &relu);
|
|
105
119
|
module.def("sigmoid", &sigmoid);
|
|
106
120
|
module.def("tanh", &tanh);
|
|
@@ -305,6 +305,22 @@ Tensor reduce_from_py(
|
|
|
305
305
|
return result;
|
|
306
306
|
}
|
|
307
307
|
|
|
308
|
+
Tensor arg_reduce_from_py(
|
|
309
|
+
const Tensor& input,
|
|
310
|
+
py::object axis,
|
|
311
|
+
bool keepdims,
|
|
312
|
+
const std::string& op_name,
|
|
313
|
+
const std::function<Tensor(const Tensor&, bool)>& reduce_all,
|
|
314
|
+
const std::function<Tensor(const Tensor&, int64_t, bool)>& reduce_axis) {
|
|
315
|
+
if (axis.is_none()) {
|
|
316
|
+
return reduce_all(input, keepdims);
|
|
317
|
+
}
|
|
318
|
+
if (!py::isinstance<py::int_>(axis)) {
|
|
319
|
+
throw ShapeError(op_name + " axis must be None or an int");
|
|
320
|
+
}
|
|
321
|
+
return reduce_axis(input, normalize_reduction_axis(input, py::cast<int64_t>(axis), op_name), keepdims);
|
|
322
|
+
}
|
|
323
|
+
|
|
308
324
|
py::array tensor_to_numpy(const Tensor& tensor) {
|
|
309
325
|
py::array array(numpy_dtype(tensor.dtype()), ssize_shape(tensor.shape()));
|
|
310
326
|
if (tensor.is_contiguous()) {
|
|
@@ -398,6 +414,20 @@ void bind_tensor(py::module_& module) {
|
|
|
398
414
|
return min(input, normalized_axis, keep);
|
|
399
415
|
});
|
|
400
416
|
}, py::arg("axis") = py::none(), py::arg("keepdims") = false)
|
|
417
|
+
.def("argmax", [](const Tensor& self, py::object axis, bool keepdims) {
|
|
418
|
+
return arg_reduce_from_py(self, std::move(axis), keepdims, "argmax", [](const Tensor& input, bool keep) {
|
|
419
|
+
return argmax(input, keep);
|
|
420
|
+
}, [](const Tensor& input, int64_t normalized_axis, bool keep) {
|
|
421
|
+
return argmax(input, normalized_axis, keep);
|
|
422
|
+
});
|
|
423
|
+
}, py::arg("axis") = py::none(), py::arg("keepdims") = false)
|
|
424
|
+
.def("argmin", [](const Tensor& self, py::object axis, bool keepdims) {
|
|
425
|
+
return arg_reduce_from_py(self, std::move(axis), keepdims, "argmin", [](const Tensor& input, bool keep) {
|
|
426
|
+
return argmin(input, keep);
|
|
427
|
+
}, [](const Tensor& input, int64_t normalized_axis, bool keep) {
|
|
428
|
+
return argmin(input, normalized_axis, keep);
|
|
429
|
+
});
|
|
430
|
+
}, py::arg("axis") = py::none(), py::arg("keepdims") = false)
|
|
401
431
|
.def("relu", &relu)
|
|
402
432
|
.def("sigmoid", &sigmoid)
|
|
403
433
|
.def("tanh", &tanh)
|
|
@@ -27,6 +27,13 @@ Tensor reduce_from_py(
|
|
|
27
27
|
const std::string& op_name,
|
|
28
28
|
const std::function<Tensor(const Tensor&)>& reduce_all,
|
|
29
29
|
const std::function<Tensor(const Tensor&, int64_t, bool)>& reduce_axis);
|
|
30
|
+
Tensor arg_reduce_from_py(
|
|
31
|
+
const Tensor& input,
|
|
32
|
+
py::object axis,
|
|
33
|
+
bool keepdims,
|
|
34
|
+
const std::string& op_name,
|
|
35
|
+
const std::function<Tensor(const Tensor&, bool)>& reduce_all,
|
|
36
|
+
const std::function<Tensor(const Tensor&, int64_t, bool)>& reduce_axis);
|
|
30
37
|
|
|
31
38
|
void bind_tensor(py::module_& module);
|
|
32
39
|
void bind_ops(py::module_& module);
|
|
@@ -1922,6 +1922,59 @@ Tensor min_impl(const Tensor& input, bool track_grad) {
|
|
|
1922
1922
|
return out;
|
|
1923
1923
|
}
|
|
1924
1924
|
|
|
1925
|
+
Tensor arg_extreme_impl(const Tensor& input, bool keepdims, bool is_max, const std::string& op_name) {
|
|
1926
|
+
if (input.numel() == 0) {
|
|
1927
|
+
throw ShapeError(op_name + " is undefined for empty tensors");
|
|
1928
|
+
}
|
|
1929
|
+
Shape out_shape;
|
|
1930
|
+
if (keepdims) {
|
|
1931
|
+
out_shape.assign(input.shape().size(), 1);
|
|
1932
|
+
}
|
|
1933
|
+
Tensor out(out_shape, DType::Int64, false);
|
|
1934
|
+
int64_t best_index = 0;
|
|
1935
|
+
double best_value = input.value_at_logical(0);
|
|
1936
|
+
for (int64_t i = 1; i < input.numel(); ++i) {
|
|
1937
|
+
const double value = input.value_at_logical(i);
|
|
1938
|
+
if (is_max ? value > best_value : value < best_value) {
|
|
1939
|
+
best_value = value;
|
|
1940
|
+
best_index = i;
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
out.set_value_at_logical(0, static_cast<double>(best_index));
|
|
1944
|
+
return out;
|
|
1945
|
+
}
|
|
1946
|
+
|
|
1947
|
+
Tensor arg_extreme_axis_impl(
|
|
1948
|
+
const Tensor& input,
|
|
1949
|
+
int64_t axis,
|
|
1950
|
+
bool keepdims,
|
|
1951
|
+
bool is_max,
|
|
1952
|
+
const std::string& op_name) {
|
|
1953
|
+
const int64_t normalized_axis = normalize_axis(axis, input.shape(), op_name);
|
|
1954
|
+
if (input.shape()[static_cast<std::size_t>(normalized_axis)] == 0) {
|
|
1955
|
+
throw ShapeError(op_name + " is undefined for empty reduction axes");
|
|
1956
|
+
}
|
|
1957
|
+
const Shape out_shape = reduction_output_shape(input.shape(), normalized_axis, keepdims);
|
|
1958
|
+
Tensor out(out_shape, DType::Int64, false);
|
|
1959
|
+
std::vector<int64_t> best_indices(static_cast<std::size_t>(out.numel()), -1);
|
|
1960
|
+
std::vector<double> best_values(static_cast<std::size_t>(out.numel()), 0.0);
|
|
1961
|
+
for (int64_t i = 0; i < input.numel(); ++i) {
|
|
1962
|
+
const Shape input_coords = coordinates_from_linear(i, input.shape());
|
|
1963
|
+
const int64_t out_linear =
|
|
1964
|
+
reduction_output_linear(input_coords, input.shape(), out_shape, normalized_axis, keepdims);
|
|
1965
|
+
const auto out_index = static_cast<std::size_t>(out_linear);
|
|
1966
|
+
const double value = input.value_at_logical(i);
|
|
1967
|
+
if (best_indices[out_index] == -1 || (is_max ? value > best_values[out_index] : value < best_values[out_index])) {
|
|
1968
|
+
best_values[out_index] = value;
|
|
1969
|
+
best_indices[out_index] = input_coords[static_cast<std::size_t>(normalized_axis)];
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
for (int64_t i = 0; i < out.numel(); ++i) {
|
|
1973
|
+
out.set_value_at_logical(i, static_cast<double>(best_indices[static_cast<std::size_t>(i)]));
|
|
1974
|
+
}
|
|
1975
|
+
return out;
|
|
1976
|
+
}
|
|
1977
|
+
|
|
1925
1978
|
Tensor relu_impl(const Tensor& input, bool track_grad) {
|
|
1926
1979
|
Tensor out = elementwise_unary_impl(input, input.dtype(), [](double value) { return std::max(0.0, value); });
|
|
1927
1980
|
if (track_grad) {
|
|
@@ -2378,6 +2431,22 @@ Tensor min(const Tensor& input, int64_t axis, bool keepdims) {
|
|
|
2378
2431
|
return min_axis_impl(input, axis, keepdims, true);
|
|
2379
2432
|
}
|
|
2380
2433
|
|
|
2434
|
+
Tensor argmax(const Tensor& input, bool keepdims) {
|
|
2435
|
+
return arg_extreme_impl(input, keepdims, true, "argmax");
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2438
|
+
Tensor argmax(const Tensor& input, int64_t axis, bool keepdims) {
|
|
2439
|
+
return arg_extreme_axis_impl(input, axis, keepdims, true, "argmax");
|
|
2440
|
+
}
|
|
2441
|
+
|
|
2442
|
+
Tensor argmin(const Tensor& input, bool keepdims) {
|
|
2443
|
+
return arg_extreme_impl(input, keepdims, false, "argmin");
|
|
2444
|
+
}
|
|
2445
|
+
|
|
2446
|
+
Tensor argmin(const Tensor& input, int64_t axis, bool keepdims) {
|
|
2447
|
+
return arg_extreme_axis_impl(input, axis, keepdims, false, "argmin");
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2381
2450
|
Tensor relu(const Tensor& input) {
|
|
2382
2451
|
return relu_impl(input, true);
|
|
2383
2452
|
}
|
|
@@ -271,6 +271,48 @@ def test_tuple_axis_reductions_match_numpy() -> None:
|
|
|
271
271
|
x.max(axis=(0, "bad")) # type: ignore[arg-type]
|
|
272
272
|
|
|
273
273
|
|
|
274
|
+
def test_arg_reductions_match_numpy() -> None:
|
|
275
|
+
values = np.array(
|
|
276
|
+
[
|
|
277
|
+
[[1.0, 4.0, 4.0], [7.0, -2.0, 5.0]],
|
|
278
|
+
[[3.0, 3.0, 9.0], [0.0, -5.0, 9.0]],
|
|
279
|
+
],
|
|
280
|
+
dtype=np.float32,
|
|
281
|
+
)
|
|
282
|
+
x = ts.from_numpy(values)
|
|
283
|
+
|
|
284
|
+
assert x.argmax().dtype == "int64"
|
|
285
|
+
assert x.argmin().dtype == "int64"
|
|
286
|
+
assert x.argmax().item() == int(np.argmax(values))
|
|
287
|
+
assert x.argmin().item() == int(np.argmin(values))
|
|
288
|
+
np.testing.assert_array_equal(x.argmax(axis=0).numpy(), np.argmax(values, axis=0))
|
|
289
|
+
np.testing.assert_array_equal(x.argmin(axis=1).numpy(), np.argmin(values, axis=1))
|
|
290
|
+
np.testing.assert_array_equal(
|
|
291
|
+
x.argmax(axis=-1, keepdims=True).numpy(),
|
|
292
|
+
np.argmax(values, axis=-1, keepdims=True),
|
|
293
|
+
)
|
|
294
|
+
np.testing.assert_array_equal(
|
|
295
|
+
ts.ops.argmin(x, axis=2, keepdims=True).numpy(),
|
|
296
|
+
np.argmin(values, axis=2, keepdims=True),
|
|
297
|
+
)
|
|
298
|
+
np.testing.assert_array_equal(
|
|
299
|
+
ts.argmax(x, keepdims=True).numpy(),
|
|
300
|
+
np.argmax(values, keepdims=True),
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
ties = ts.tensor([2.0, 5.0, 5.0, 1.0])
|
|
304
|
+
assert ties.argmax().item() == 1
|
|
305
|
+
|
|
306
|
+
with pytest.raises(Exception, match="out of range"):
|
|
307
|
+
x.argmax(axis=3)
|
|
308
|
+
with pytest.raises(Exception, match="axis must be None or an int"):
|
|
309
|
+
x.argmin(axis=(0, 1)) # type: ignore[arg-type]
|
|
310
|
+
with pytest.raises(Exception, match="empty"):
|
|
311
|
+
ts.tensor([], dtype="float32").argmax()
|
|
312
|
+
with pytest.raises(Exception, match="empty reduction axes"):
|
|
313
|
+
ts.empty((2, 0)).argmin(axis=1)
|
|
314
|
+
|
|
315
|
+
|
|
274
316
|
def test_cast_concat_and_stack_match_numpy() -> None:
|
|
275
317
|
x = ts.tensor([1.2, 2.8, -3.1])
|
|
276
318
|
as_int = x.astype("int32")
|
|
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
|