Skip to content

Commit d8191d8

Browse files
authored
WIP: API Document Update (#67)
* core -- add lifetime annotation to TensorRefAPI / TensorRefMutAPI * core -- add macro tensor_from_nested * docs -- incooperate rstsr-core API specification document into rstsr * core -- split tensor/manuplication * doc -- try to add doc of to_broadcast * core -- changed tensor_from_nested to allow input of device * common -- refactor error handling code to allow backtrace * common -- use rstsr_unwrap in most cases instead of unwrap * linalg-traits, sci-traits -- use rstsr_unwrap in most cases instead of unwrap * core -- fix allclose to make it accept two tensors broadcasting * doc -- to_broadcast * doc -- to_broadcast variants * doc -- broadcast_arrays * doc -- expand_dims * core -- changed impl of tensor_from_nested * core -- fix bug in expand_dims * doc -- reshape * common and doc -- changes to AxesIndex, add unittest of flip - no_std for rstsr-common and rstsr-native-impl - do not depend `use_std` feature for crate itertools - add TryInto impl of AxesIndex<u/isize> - add function `normalize_axes_index` (similar to numpy.normalize_axis_tuple) - fix the case where flip can accept multiple same dimensions, and changes behavior of zero-sized axes to be the same to numpy - add some unittests to flip - add .gitignore to ignore repomix file (for LLM) * meta -- further fix no_std * doc -- flip * doc and common -- into_dim - in rstsr-common, changed prelude_dev exports - in rstsr-common, let `const_ndims` to be member function instead of associated function to type itself * cargo fmt * common -- use std::backtrace::Backtrace instead of String for error data-structure representation
1 parent 45daaa8 commit d8191d8

63 files changed

Lines changed: 4483 additions & 2214 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/rstsr-core-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
steps:
2222
- uses: actions/checkout@v4
2323
- name: unittest
24-
run: cargo test -p rstsr-core --lib --release --no-default-features --features="std faer rayon col_major faer_as_default"
24+
run: cargo test -p rstsr-core --lib --release --no-default-features --features="std backtrace faer rayon col_major faer_as_default"
2525

2626
integration-tests:
2727
runs-on: ubuntu-latest

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ tarpaulin-report.html
88
.idea
99
book
1010
*.npy
11+
repomix-output*
1112

1213
# bindgen
1314
blas_bindgen.h

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ rstsr-blis-ffi = { version = "0.2", default-features = false, features = ["lapac
5555
rstsr-aocl-ffi = { version = "0.2", default-features = false, features = ["blis", "lapack"] }
5656
rstsr-kml-ffi = { version = "0.2", default-features = false, features = ["kblas", "lapack"] }
5757
# basic dependencies
58-
num = { version = "0.4" }
59-
itertools = { version = "0.13" }
60-
half = { version = "2.4", features = ["num-traits"] }
58+
num = { version = "0.4", default-features = false, features = ["alloc", "libm"] }
59+
itertools = { version = "0.13", default-features = false, features = ["use_alloc"] }
60+
half = { version = "2.7", default-features = false, features = ["alloc", "num-traits"] }
6161
libm = { version = "0.2" }
62-
derive_builder = { version = "0.20" }
62+
derive_builder = { version = "0.20", default-features = false, features = ["alloc"] }
6363
duplicate = { version = "2.0" }
6464
# optional dependencies
6565
rayon = { version = ">=1.10" }

rstsr-common/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ rstsr-core = { path = "../rstsr-core", default-features = false }
2121

2222
[features]
2323
std = []
24+
backtrace = ["std"]
2425
rayon = ["dep:rayon"]
2526

2627
# Row-major or Col-major will be contractidary features.

rstsr-common/src/axis_index.rs

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ impl<T> AsRef<[T]> for AxesIndex<T> {
1515
}
1616
}
1717

18-
/* #region AxisIndex self-type from */
18+
/* #region AxesIndex self-type from */
1919

2020
impl<T> From<T> for AxesIndex<T> {
2121
fn from(value: T) -> Self {
@@ -84,25 +84,30 @@ where
8484
}
8585
}
8686

87-
impl TryFrom<()> for AxesIndex<usize> {
87+
#[duplicate_item(T; [usize]; [isize])]
88+
impl TryFrom<()> for AxesIndex<T> {
8889
type Error = Error;
8990

9091
fn try_from(_: ()) -> Result<Self> {
9192
Ok(AxesIndex::Vec(vec![]))
9293
}
9394
}
9495

95-
impl TryFrom<()> for AxesIndex<isize> {
96+
#[duplicate_item(T; [usize]; [isize])]
97+
impl TryFrom<Option<T>> for AxesIndex<T> {
9698
type Error = Error;
9799

98-
fn try_from(_: ()) -> Result<Self> {
99-
Ok(AxesIndex::Vec(vec![]))
100+
fn try_from(value: Option<T>) -> Result<Self> {
101+
match value {
102+
Some(v) => Ok(AxesIndex::Val(v)),
103+
None => Ok(AxesIndex::Vec(vec![])),
104+
}
100105
}
101106
}
102107

103-
/* #endregion AxisIndex self-type from */
108+
/* #endregion AxesIndex self-type from */
104109

105-
/* #region AxisIndex other-type from */
110+
/* #region AxesIndex other-type from */
106111

107112
macro_rules! impl_try_from_axes_index {
108113
($t1:ty, $($t2:ty),*) => {
@@ -129,7 +134,7 @@ macro_rules! impl_try_from_axes_index {
129134
fn try_from(value: Vec<$t2>) -> Result<Self> {
130135
let value = value
131136
.into_iter()
132-
.map(|v| v.try_into().map_err(|_| Error::TryFromIntError(String::new())))
137+
.map(|v| v.try_into().map_err(|_| rstsr_error!(TryFromIntError)))
133138
.collect::<Result<Vec<$t1>>>()?;
134139
Ok(AxesIndex::Vec(value))
135140
}
@@ -173,9 +178,9 @@ macro_rules! impl_try_from_axes_index {
173178
impl_try_from_axes_index!(usize, isize, u32, u64, i32, i64);
174179
impl_try_from_axes_index!(isize, usize, u32, u64, i32, i64);
175180

176-
/* #endregion AxisIndex other-type from */
181+
/* #endregion AxesIndex other-type from */
177182

178-
/* #region AxisIndex tuple-type from */
183+
/* #region AxesIndex tuple-type from */
179184

180185
// it seems that this directly implementing arbitary AxesIndex<T> will cause
181186
// conflicting implementation so make a macro for this task
@@ -372,4 +377,45 @@ macro_rules! impl_from_tuple_to_axes_index {
372377
impl_from_tuple_to_axes_index!(isize);
373378
impl_from_tuple_to_axes_index!(usize);
374379

375-
/* #endregion AxisIndex tuple-type from */
380+
/* #endregion AxesIndex tuple-type from */
381+
382+
/* #region utilities for AxesIndex */
383+
384+
/// Normalize axes argument into a tuple of non-negative integer axes.
385+
pub fn normalize_axes_index(axes: AxesIndex<isize>, ndim: usize, allow_duplicate: bool) -> Result<Vec<isize>> {
386+
// generate the normalized axes vector
387+
let vec = match axes {
388+
AxesIndex::Val(axis) => {
389+
let axis = if axis < 0 { (ndim as isize) + axis } else { axis };
390+
if axis < 0 || axis >= ndim as isize {
391+
rstsr_raise!(InvalidValue, "Axis index {axis} is out of bounds for tensor with {ndim} dimensions.")?;
392+
}
393+
vec![axis]
394+
},
395+
AxesIndex::Vec(axes) => {
396+
let mut normalized_axes = Vec::with_capacity(axes.len());
397+
for &axis in axes.iter() {
398+
let norm_axis = if axis < 0 { (ndim as isize) + axis } else { axis };
399+
if norm_axis < 0 || norm_axis >= ndim as isize {
400+
rstsr_raise!(
401+
InvalidValue,
402+
"Axis index {axis} is out of bounds for tensor with {ndim} dimensions."
403+
)?;
404+
}
405+
normalized_axes.push(norm_axis);
406+
}
407+
normalized_axes.sort();
408+
normalized_axes
409+
},
410+
};
411+
if !allow_duplicate {
412+
for i in 1..vec.len() {
413+
if vec[i] == vec[i - 1] {
414+
rstsr_raise!(InvalidValue, "Duplicate axis index {} found in axes argument.", vec[i])?;
415+
}
416+
}
417+
}
418+
Ok(vec)
419+
}
420+
421+
/* #endregion */

0 commit comments

Comments
 (0)