Skip to content

Tensor shape and dimension names are now separate arrow fields #8376

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
49c7d92
Pixi: install ninja and clang on Mac
emilk Dec 10, 2024
94c4069
Update instructions for how to run snippet tests
emilk Dec 10, 2024
921efb5
Update Cargo.lock
emilk Dec 10, 2024
1f32440
Split dimension shape and names into different fields
emilk Dec 9, 2024
15df7b7
Make it clear when a panic is only in debug builds
emilk Dec 9, 2024
aa92631
Start python migration
emilk Dec 9, 2024
103eb6f
Defer to existing tensor->arrow serialization
emilk Dec 10, 2024
fdd0b50
Mirate Rust tests
emilk Dec 10, 2024
f907fc8
fix re-export
emilk Dec 10, 2024
97fc773
Port C++
emilk Dec 10, 2024
c6e125c
Log result of compare-command
emilk Dec 10, 2024
44252ab
fix compare snippets
emilk Dec 10, 2024
7e8711e
Rust clippy fix
emilk Dec 10, 2024
45fbdc1
Try to port Python
emilk Dec 10, 2024
698f1c3
Python fixes
emilk Dec 10, 2024
eedd110
Try to fix Python by randomly changing character and waiting for CI
emilk Dec 10, 2024
416ba00
Revert change to rountrip utils
emilk Dec 10, 2024
895a6ba
Grasping at straws
emilk Dec 10, 2024
953e4c5
I hate Python so much
emilk Dec 10, 2024
d793373
Fix instructions
emilk Dec 10, 2024
2529e62
Fix py-test
emilk Dec 10, 2024
5125cff
Fix `shape` arrow type (nullability)
emilk Dec 10, 2024
8eeb23d
Also fix `names`
emilk Dec 10, 2024
789503b
Fix the struct arrow type
emilk Dec 10, 2024
d32ae98
Another fix bites the dust
emilk Dec 10, 2024
a967691
FUCK YOU PYTHON, I WIN
emilk Dec 10, 2024
0eb9bae
fix mypy
abey79 Dec 10, 2024
dfc53c1
Merge branch 'main' into emilk/refactor-tensor
emilk Dec 10, 2024
97106ee
Revert "Pixi: install ninja and clang on Mac"
emilk Dec 10, 2024
7080638
Fix
emilk Dec 10, 2024
fc0c595
Fix unit test
emilk Dec 10, 2024
5ef9844
Fix checklist
emilk Dec 10, 2024
3654591
Merge branch 'main' into emilk/refactor-tensor
emilk Dec 11, 2024
7f6c1f0
Add entry to migration guide
emilk Dec 11, 2024
eeb8585
Clarify what happens if the number of names is wrong
emilk Dec 17, 2024
fa515e5
Merge branch 'main' into emilk/refactor-tensor
emilk Dec 17, 2024
6a3b3c6
Merge branch 'main' into emilk/refactor-tensor
emilk Dec 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/store/re_chunk/src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ impl Chunk {
Err(err) => {
if cfg!(debug_assertions) {
panic!(
"deserialization failed for {}, data discarded: {}",
"[DEBUG-ONLY] deserialization failed for {}, data discarded: {}",
C::name(),
re_error::format_ref(&err),
);
Expand Down
1 change: 0 additions & 1 deletion crates/store/re_types/definitions/rerun/datatypes.fbs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,15 @@ table TensorData (
"attr.python.array_aliases": "npt.ArrayLike",
"attr.rust.derive": "PartialEq,"
) {
/// The shape of the tensor, including optional names for each dimension.
shape: [rerun.datatypes.TensorDimension] (order: 200);
/// The shape of the tensor, i.e. the length of each dimension.
shape: [uint64] (order: 200);

/// The names of the dimensions of the tensor (optional).
///
/// If set, should be the same length as [datatypes.TensorData.shape].
///
/// Example: `["height", "width", "channel", "batch"]`.
names: [string] (order: 250, nullable);

/// The content/data.
buffer: rerun.datatypes.TensorBuffer (order: 300);
Expand Down

This file was deleted.

10 changes: 4 additions & 6 deletions crates/store/re_types/src/archetypes/depth_image_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,19 @@ impl DepthImage {
let tensor_data: TensorData = data
.try_into()
.map_err(ImageConstructionError::TensorDataConversion)?;
let shape = tensor_data.shape;
let TensorData { shape, buffer, .. } = tensor_data;

let non_empty_dim_inds = find_non_empty_dim_indices(&shape);

if non_empty_dim_inds.len() != 2 {
return Err(ImageConstructionError::BadImageShape(shape));
}

let (blob, datatype) = blob_and_datatype_from_tensor(tensor_data.buffer);
let (blob, datatype) = blob_and_datatype_from_tensor(buffer);

let (height, width) = (&shape[non_empty_dim_inds[0]], &shape[non_empty_dim_inds[1]]);
let height = height.size as u32;
let width = width.size as u32;
let (height, width) = (shape[non_empty_dim_inds[0]], shape[non_empty_dim_inds[1]]);

let image_format = ImageFormat::depth([width, height], datatype);
let image_format = ImageFormat::depth([width as u32, height as u32], datatype);

Ok(Self {
buffer: blob.into(),
Expand Down
16 changes: 7 additions & 9 deletions crates/store/re_types/src/archetypes/image_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,33 +33,31 @@ impl Image {
let tensor_data: TensorData = data
.try_into()
.map_err(ImageConstructionError::TensorDataConversion)?;
let shape = tensor_data.shape;
let TensorData { shape, buffer, .. } = tensor_data;

let non_empty_dim_inds = find_non_empty_dim_indices(&shape);

let is_shape_correct = match color_model {
ColorModel::L => non_empty_dim_inds.len() == 2,
ColorModel::RGB | ColorModel::BGR => {
non_empty_dim_inds.len() == 3 && shape[non_empty_dim_inds[2]].size == 3
non_empty_dim_inds.len() == 3 && shape[non_empty_dim_inds[2]] == 3
}
ColorModel::RGBA | ColorModel::BGRA => {
non_empty_dim_inds.len() == 3 && shape[non_empty_dim_inds[2]].size == 4
non_empty_dim_inds.len() == 3 && shape[non_empty_dim_inds[2]] == 4
}
};

if !is_shape_correct {
return Err(ImageConstructionError::BadImageShape(shape));
}

let (blob, datatype) = blob_and_datatype_from_tensor(tensor_data.buffer);
let (blob, datatype) = blob_and_datatype_from_tensor(buffer);

let (height, width) = (&shape[non_empty_dim_inds[0]], &shape[non_empty_dim_inds[1]]);
let height = height.size as u32;
let width = width.size as u32;
let (height, width) = (shape[non_empty_dim_inds[0]], shape[non_empty_dim_inds[1]]);

let image_format = ImageFormat {
width,
height,
width: width as _,
height: height as _,
pixel_format: None,
channel_datatype: Some(datatype),
color_model: Some(color_model),
Expand Down
10 changes: 4 additions & 6 deletions crates/store/re_types/src/archetypes/segmentation_image_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,19 @@ impl SegmentationImage {
let tensor_data: TensorData = data
.try_into()
.map_err(ImageConstructionError::TensorDataConversion)?;
let shape = tensor_data.shape;
let TensorData { shape, buffer, .. } = tensor_data;

let non_empty_dim_inds = find_non_empty_dim_indices(&shape);

if non_empty_dim_inds.len() != 2 {
return Err(ImageConstructionError::BadImageShape(shape));
}

let (blob, datatype) = blob_and_datatype_from_tensor(tensor_data.buffer);
let (blob, datatype) = blob_and_datatype_from_tensor(buffer);

let (height, width) = (&shape[non_empty_dim_inds[0]], &shape[non_empty_dim_inds[1]]);
let height = height.size as u32;
let width = width.size as u32;
let (height, width) = (shape[non_empty_dim_inds[0]], shape[non_empty_dim_inds[1]]);

let image_format = ImageFormat::segmentation([width, height], datatype);
let image_format = ImageFormat::segmentation([width as _, height as _], datatype);

Ok(Self {
buffer: blob.into(),
Expand Down
40 changes: 9 additions & 31 deletions crates/store/re_types/src/archetypes/tensor_ext.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::datatypes::{TensorData, TensorDimension};
use crate::datatypes::TensorData;

use re_types_core::ArrowString;

Expand All @@ -24,37 +24,15 @@ impl Tensor {

/// Update the `names` of the contained [`TensorData`] dimensions.
///
/// Any existing Dimension names will be overwritten.
/// Any existing names will be overwritten.
///
/// If too many, or too few names are provided, this function will warn and only
/// update the subset of names that it can.
pub fn with_dim_names(self, names: impl IntoIterator<Item = impl Into<ArrowString>>) -> Self {
let names: Vec<_> = names.into_iter().map(|x| Some(x.into())).collect();
if names.len() != self.data.0.shape.len() {
re_log::warn_once!(
"Wrong number of names provided for tensor dimension. {} provided but {} expected.",
names.len(),
self.data.0.shape.len(),
);
}
Self {
data: TensorData {
shape: self
.data
.0
.shape
.into_iter()
.zip(names.into_iter().chain(std::iter::repeat(None)))
.map(|(dim, name)| TensorDimension {
size: dim.size,
name: name.or(dim.name),
})
.collect(),
buffer: self.data.0.buffer,
}
.into(),
value_range: None,
}
/// If too few or too many names are provided, this function will warn and return.
pub fn with_dim_names(
mut self,
names: impl IntoIterator<Item = impl Into<ArrowString>>,
) -> Self {
self.data.0 = self.data.0.with_dim_names(names);
self
}
}

Expand Down
1 change: 0 additions & 1 deletion crates/store/re_types/src/datatypes/.gitattributes

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions crates/store/re_types/src/datatypes/mod.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading