Skip to content

Commit 85d0169

Browse files
committed
Merge branch 'main' into antoine/dataframe-column-visibility
2 parents 02f0e6b + e12e809 commit 85d0169

File tree

7 files changed

+144
-28
lines changed

7 files changed

+144
-28
lines changed

Cargo.lock

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3529,22 +3529,24 @@ checksum = "308d96db8debc727c3fd9744aac51751243420e46edf401010908da7f8d5e57c"
35293529

35303530
[[package]]
35313531
name = "ndarray"
3532-
version = "0.15.6"
3532+
version = "0.16.1"
35333533
source = "registry+https://github.com/rust-lang/crates.io-index"
3534-
checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32"
3534+
checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841"
35353535
dependencies = [
35363536
"matrixmultiply",
35373537
"num-complex",
35383538
"num-integer",
35393539
"num-traits",
3540+
"portable-atomic",
3541+
"portable-atomic-util",
35403542
"rawpointer",
35413543
]
35423544

35433545
[[package]]
35443546
name = "ndarray-rand"
3545-
version = "0.14.0"
3547+
version = "0.15.0"
35463548
source = "registry+https://github.com/rust-lang/crates.io-index"
3547-
checksum = "65608f937acc725f5b164dcf40f4f0bc5d67dc268ab8a649d3002606718c4588"
3549+
checksum = "f093b3db6fd194718dcdeea6bd8c829417deae904e3fcc7732dabcd4416d25d8"
35483550
dependencies = [
35493551
"ndarray",
35503552
"rand",
@@ -4348,9 +4350,18 @@ checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2"
43484350

43494351
[[package]]
43504352
name = "portable-atomic"
4351-
version = "1.5.1"
4353+
version = "1.7.0"
4354+
source = "registry+https://github.com/rust-lang/crates.io-index"
4355+
checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265"
4356+
4357+
[[package]]
4358+
name = "portable-atomic-util"
4359+
version = "0.2.2"
43524360
source = "registry+https://github.com/rust-lang/crates.io-index"
4353-
checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b"
4361+
checksum = "fcdd8420072e66d54a407b3316991fe946ce3ab1083a7f575b2463866624704d"
4362+
dependencies = [
4363+
"portable-atomic",
4364+
]
43544365

43554366
[[package]]
43564367
name = "powerfmt"

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ mime_guess2 = "2.0" # infer MIME type by file extension, and map mime to file ex
198198
mint = "0.5.9"
199199
mp4 = "0.14.0"
200200
natord = "1.0.9"
201-
ndarray = "0.15"
202-
ndarray-rand = "0.14"
201+
ndarray = "0.16"
202+
ndarray-rand = "0.15"
203203
never = "0.1"
204204
nohash-hasher = "0.2"
205205
notify = "6.0"

crates/store/re_types/src/archetypes/image.rs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/store/re_types/src/datatypes/tensor_data_ext.rs

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ use crate::archetypes::EncodedImage;
88

99
use super::{TensorBuffer, TensorData, TensorDimension};
1010

11-
// Much of the following duplicates code from: `crates/re_components/src/tensor.rs`, which
12-
// will eventually go away as the Tensor migration is completed.
13-
1411
// ----------------------------------------------------------------------------
1512

1613
impl TensorData {
@@ -169,7 +166,6 @@ macro_rules! tensor_from_ndarray {
169166
type Error = TensorCastError;
170167

171168
fn try_from(value: ndarray::Array<$type, D>) -> Result<Self, Self::Error> {
172-
let value = value.as_standard_layout();
173169
let shape = value
174170
.shape()
175171
.iter()
@@ -178,13 +174,26 @@ macro_rules! tensor_from_ndarray {
178174
name: None,
179175
})
180176
.collect();
181-
value
182-
.is_standard_layout()
183-
.then(|| TensorData {
184-
shape,
185-
buffer: TensorBuffer::$variant(value.to_owned().into_raw_vec().into()),
186-
})
187-
.ok_or(TensorCastError::NotContiguousStdOrder)
177+
178+
let vec = if value.is_standard_layout() {
179+
let (mut vec, offset) = value.into_raw_vec_and_offset();
180+
// into_raw_vec_and_offset() guarantees that the logical element order (.iter()) matches the internal
181+
// storage order in the returned vector if the array is in standard layout.
182+
if let Some(offset) = offset {
183+
vec.drain(..offset);
184+
vec
185+
} else {
186+
debug_assert!(vec.is_empty());
187+
vec
188+
}
189+
} else {
190+
value.into_iter().collect::<Vec<_>>()
191+
};
192+
193+
Ok(Self {
194+
shape,
195+
buffer: TensorBuffer::$variant(vec.into()),
196+
})
188197
}
189198
}
190199

@@ -311,13 +320,18 @@ impl<D: ::ndarray::Dimension> TryFrom<::ndarray::Array<half::f16, D>> for Tensor
311320
})
312321
.collect();
313322
if value.is_standard_layout() {
323+
let (vec, offset) = value.into_raw_vec_and_offset();
324+
// into_raw_vec_and_offset() guarantees that the logical element order (.iter()) matches the internal
325+
// storage order in the returned vector if the array is in standard layout.
326+
let vec_slice = if let Some(offset) = offset {
327+
&vec[offset..]
328+
} else {
329+
debug_assert!(vec.is_empty());
330+
&vec
331+
};
314332
Ok(Self {
315333
shape,
316-
buffer: TensorBuffer::F16(
317-
bytemuck::cast_slice(value.into_raw_vec().as_slice())
318-
.to_vec()
319-
.into(),
320-
),
334+
buffer: TensorBuffer::F16(Vec::from(bytemuck::cast_slice(vec_slice)).into()),
321335
})
322336
} else {
323337
Ok(Self {

crates/store/re_types/tests/types/tensor.rs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ fn convert_tensor_to_ndarray_f32() {
106106
}
107107

108108
#[test]
109-
fn convert_ndarray_u8_to_tensor() {
109+
fn convert_ndarray_f64_to_tensor() {
110110
let n = ndarray::array![[1., 2., 3.], [4., 5., 6.]];
111111
let t = TensorData::try_from(n).unwrap();
112112

@@ -125,6 +125,97 @@ fn convert_ndarray_slice_to_tensor() {
125125
assert_eq!(t.shape(), &[TensorDimension::unnamed(2)]);
126126
}
127127

128+
#[test]
129+
fn convert_ndarray_to_tensor_both_layouts() {
130+
#[rustfmt::skip]
131+
let row_major_vec = vec![
132+
1, 2, 3,
133+
4, 5, 6,
134+
7, 8, 9
135+
];
136+
#[rustfmt::skip]
137+
let col_major_vec = vec![
138+
1, 4, 7,
139+
2, 5, 8,
140+
3, 6, 9
141+
];
142+
143+
let shape = ndarray::Ix2(3, 3);
144+
145+
let row_major = ndarray::Array::from_vec(row_major_vec)
146+
.into_shape_with_order((shape, ndarray::Order::RowMajor))
147+
.unwrap();
148+
149+
let col_major = ndarray::Array::from_vec(col_major_vec)
150+
.into_shape_with_order((shape, ndarray::Order::ColumnMajor))
151+
.unwrap();
152+
153+
assert!(row_major.is_standard_layout());
154+
assert!(!col_major.is_standard_layout());
155+
156+
// make sure that the offset is in fact zero, in case ndarray behavior changes
157+
let rm = row_major.clone();
158+
let cm = col_major.clone();
159+
let (_, rm_offset) = rm.into_raw_vec_and_offset();
160+
let (_, cm_offset) = cm.into_raw_vec_and_offset();
161+
assert_eq!(rm_offset.unwrap(), 0);
162+
assert_eq!(cm_offset.unwrap(), 0);
163+
164+
let tensor_row_major = TensorData::try_from(row_major).unwrap();
165+
let tensor_col_major = TensorData::try_from(col_major).unwrap();
166+
167+
assert_eq!(tensor_row_major, tensor_col_major);
168+
}
169+
170+
#[test]
171+
fn convert_ndarray_to_tensor_both_layouts_nonzero_offset() {
172+
#[rustfmt::skip]
173+
let row_major_vec = vec![
174+
1, 2, 3,
175+
4, 5, 6,
176+
7, 8, 9
177+
];
178+
#[rustfmt::skip]
179+
let col_major_vec = vec![
180+
1, 4, 7,
181+
2, 5, 8,
182+
3, 6, 9
183+
];
184+
185+
let shape = ndarray::Ix2(3, 3);
186+
187+
let row_major = ndarray::Array::from_vec(row_major_vec)
188+
.into_shape_with_order((shape, ndarray::Order::RowMajor))
189+
.unwrap();
190+
assert!(row_major.is_standard_layout());
191+
let row_major_nonzero_offset = row_major.slice_move(ndarray::s![1.., ..]);
192+
193+
let col_major = ndarray::Array::from_vec(col_major_vec)
194+
.into_shape_with_order((shape, ndarray::Order::ColumnMajor))
195+
.unwrap();
196+
assert!(!col_major.is_standard_layout());
197+
let col_major_nonzero_offset = col_major.slice_move(ndarray::s![1.., ..]);
198+
199+
assert!(row_major_nonzero_offset.is_standard_layout());
200+
assert!(!col_major_nonzero_offset.is_standard_layout());
201+
202+
// make sure that the offset is in fact non-zero, in case ndarray behavior changes
203+
let rmno = row_major_nonzero_offset.clone();
204+
let cmno = col_major_nonzero_offset.clone();
205+
let (_, rm_offset) = rmno.into_raw_vec_and_offset();
206+
let (_, cm_offset) = cmno.into_raw_vec_and_offset();
207+
assert!(rm_offset.unwrap() > 0);
208+
assert!(cm_offset.unwrap() > 0);
209+
210+
let tensor_row_major_nonzero_offset = TensorData::try_from(row_major_nonzero_offset).unwrap();
211+
let tensor_col_major_nonzero_offset = TensorData::try_from(col_major_nonzero_offset).unwrap();
212+
213+
assert_eq!(
214+
tensor_row_major_nonzero_offset,
215+
tensor_col_major_nonzero_offset
216+
);
217+
}
218+
128219
#[test]
129220
fn check_slices() {
130221
let t = TensorData::new(

crates/viewer/re_space_view_tensor/src/space_view_class.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ pub fn selected_tensor_slice<'a, T: Copy>(
424424
// This is important for above width/height conversion to work since this assumes at least 2 dimensions.
425425
tensor
426426
.view()
427-
.into_shape(ndarray::IxDyn(&[tensor.len(), 1]))
427+
.into_shape_with_order(ndarray::IxDyn(&[tensor.len(), 1]))
428428
.unwrap()
429429
} else {
430430
tensor.view()

docs/snippets/all/archetypes/image_send_columns.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
3131

3232
// Split up the image data into several components referencing the underlying data.
3333
let image_size_in_bytes = width * height * 3;
34-
let blob = rerun::datatypes::Blob::from(images.into_raw_vec());
34+
let blob = rerun::datatypes::Blob::from(images.into_raw_vec_and_offset().0);
3535
let image_column = times
3636
.iter()
3737
.map(|&t| {

0 commit comments

Comments
 (0)