Skip to content

Commit 84e0246

Browse files
committed
feat: add write_tensor
Signed-off-by: YdrMaster <ydrml@hotmail.com>
1 parent cbffaa2 commit 84e0246

File tree

5 files changed

+124
-7
lines changed

5 files changed

+124
-7
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,8 @@ jobs:
2626
- name: Checkout code
2727
uses: actions/checkout@v4
2828

29-
- name: Use beta toolchain
30-
run: |
31-
rustup toolchain install beta --component rustfmt clippy
32-
rustup default beta
29+
- name: Use latest toolchain
30+
run: rustup update
3331

3432
- name: Check format
3533
run: cargo fmt --check

CHANGELOG.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.2.1] - 2025-03-28
9+
10+
### Added
11+
12+
- Add `write_array` to write Nd array to `fmt::Formatter`;
13+
814
## [0.2.0] - 2025-02-23
915

1016
### Added
1117

12-
- Add `num_elements` to calculate the number of elements in array.
13-
- Add `element_offset` to calculate the offset of element at the given index.
18+
- Add `num_elements` to calculate the number of elements in array;
19+
- Add `element_offset` to calculate the offset of element at the given index;
1420

1521
### Changed
1622

@@ -20,4 +26,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2026

2127
- Fix merging dims with length 1;
2228

29+
[0.2.1]: https://github.com/InfiniTensor/ndarray-layout/compare/v0.2.0...v0.2.1
2330
[0.2.0]: https://github.com/InfiniTensor/ndarray-layout/releases/tag/v0.2.0

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "ndarray-layout"
33
description = "This crate provides definitions and transformations for multi-dimensional array data layouts."
4-
version = "0.2.0"
4+
version = "0.2.1"
55
edition = "2024"
66
authors = ["YdrMaster <ydrml@hotmail.com>"]
77
repository = "https://github.com/InfiniTensor/ndarray-layout.git"

src/fmt.rs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
use crate::ArrayLayout;
2+
use std::fmt;
3+
4+
impl<const N: usize> ArrayLayout<N> {
5+
/// 高维数组格式化。
6+
pub fn write_array<T: fmt::Display>(
7+
&self,
8+
f: &mut fmt::Formatter,
9+
ptr: *const T,
10+
) -> fmt::Result {
11+
match self.ndim() {
12+
0 => {
13+
write!(f, "array<> = [{}]", unsafe {
14+
ptr.byte_offset(self.offset()).read_unaligned()
15+
})
16+
}
17+
1 => {
18+
let &[n] = self.shape() else { unreachable!() };
19+
let &[s] = self.strides() else { unreachable!() };
20+
21+
writeln!(f, "array<{n}>[")?;
22+
let ptr = unsafe { ptr.byte_offset(self.offset()) };
23+
for i in 0..n as isize {
24+
writeln!(f, " {}", unsafe {
25+
ptr.byte_offset(i * s).read_unaligned()
26+
})?
27+
}
28+
writeln!(f, "]")?;
29+
Ok(())
30+
}
31+
_ => {
32+
let mut title = "array<".to_string();
33+
for d in self.shape() {
34+
title.push_str(&format!("{d}x"))
35+
}
36+
assert_eq!(title.pop(), Some('x'));
37+
title.push('>');
38+
39+
let mut stack = Vec::with_capacity(self.ndim() - 2);
40+
self.write_recursive(f, ptr, &title, &mut stack)
41+
}
42+
}
43+
}
44+
45+
fn write_recursive<T: fmt::Display>(
46+
&self,
47+
f: &mut fmt::Formatter,
48+
ptr: *const T,
49+
title: &str,
50+
indices: &mut Vec<usize>,
51+
) -> fmt::Result {
52+
match *self.shape() {
53+
[] | [_] => unreachable!(),
54+
[rows, cols] => {
55+
write!(f, "{title}[")?;
56+
for i in indices {
57+
write!(f, "{i}, ")?
58+
}
59+
writeln!(f, "..]")?;
60+
61+
let &[rs, cs] = self.strides() else {
62+
unreachable!()
63+
};
64+
65+
let ptr = unsafe { ptr.byte_offset(self.offset()) };
66+
for r in 0..rows as isize {
67+
for c in 0..cols as isize {
68+
write!(f, "{} ", unsafe {
69+
ptr.byte_offset(r * rs + c * cs).read_unaligned()
70+
})?
71+
}
72+
writeln!(f)?
73+
}
74+
}
75+
[batch, ..] => {
76+
for i in 0..batch {
77+
indices.push(i);
78+
self.index(0, i).write_recursive(f, ptr, title, indices)?;
79+
indices.pop();
80+
}
81+
}
82+
}
83+
Ok(())
84+
}
85+
}
86+
87+
#[test]
88+
fn test() {
89+
const DATA: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
90+
91+
struct Tensor(ArrayLayout<4>);
92+
93+
impl fmt::Display for Tensor {
94+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95+
self.0.write_array(f, DATA.as_ptr())
96+
}
97+
}
98+
99+
let tensor = Tensor(ArrayLayout::<4>::new_contiguous(
100+
&[DATA.len()],
101+
crate::Endian::BigEndian,
102+
1,
103+
));
104+
println!("{}", tensor);
105+
106+
let tensor = Tensor(tensor.0.tile_be(0, &[1, DATA.len()]).broadcast(0, 6));
107+
println!("{}", tensor);
108+
109+
let tensor = Tensor(tensor.0.tile_be(0, &[2, 3]).tile_be(2, &[5, 2]));
110+
println!("{}", tensor);
111+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ impl<const N: usize> ArrayLayout<N> {
184184
}
185185
}
186186

187+
mod fmt;
187188
mod transform;
188189
pub use transform::{BroadcastArg, IndexArg, MergeArg, SliceArg, Split, TileArg};
189190

0 commit comments

Comments
 (0)