Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
34 changes: 33 additions & 1 deletion crates/onnx-runtime-session/src/executor/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,13 @@ impl Executor {
.iter()
.enumerate()
.map(|(i, v)| {
v.and_then(|vid| self.shape_input_i64(vid, &input_shapes[i], input_dtypes[i]))
v.and_then(|vid| {
if node.is_default_domain() && node.op_type == "Compress" && i == 1 {
self.compress_condition_i64(vid, &input_shapes[i], input_dtypes[i])
} else {
self.shape_input_i64(vid, &input_shapes[i], input_dtypes[i])
}
})
})
.collect();
// Only materialize a *float* input value for the specific inputs an
Expand Down Expand Up @@ -1045,6 +1051,32 @@ impl Executor {
self.input_i64(vid, shape, dtype)
}

fn compress_condition_i64(
&self,
vid: ValueId,
shape: &[usize],
dtype: DataType,
) -> Option<Vec<i64>> {
if !bounded_compress_condition(dtype, shape) {
return None;
}
let max_bytes = shape[0].checked_mul(dtype.byte_size())?;
if let Some(view) = self.views.get(&vid) {
let source = self.buffers.get(&view.source)?;
if source.len() > max_bytes {
return None;
}
}
if self
.seq_elem_values
.get(&vid)
.is_some_and(|elem| elem.root_len() > max_bytes)
{
return None;
}
self.input_i64(vid, shape, dtype)
}

pub(super) fn shape_input_f64(
&self,
vid: ValueId,
Expand Down
8 changes: 8 additions & 0 deletions crates/onnx-runtime-session/src/executor/geometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,14 @@ pub(super) fn bounded_shape_input(dtype: DataType, shape: &[usize]) -> bool {
.is_some_and(|count| count <= MAX_SHAPE_DATA_ELEMS)
}

const MAX_COMPRESS_CONDITION_ELEMS: usize = 1 << 20;

/// `Compress` is data-dependent on its full boolean condition, which can be
/// larger than ordinary scalar/vector shape metadata for image models.
pub(super) fn bounded_compress_condition(dtype: DataType, shape: &[usize]) -> bool {
dtype == DataType::Bool && shape.len() == 1 && shape[0] <= MAX_COMPRESS_CONDITION_ELEMS
}

/// Whether a node needs a float runtime input to resolve a data-dependent
/// output extent. The list is deliberately explicit, so shape propagation never
/// copies unrelated tensor data to host.
Expand Down
18 changes: 18 additions & 0 deletions crates/onnx-runtime-session/src/executor/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3352,6 +3352,24 @@ fn dynamic_output_shapes_compress_counts_selected_values() {
);
}

#[test]
fn compress_condition_allows_image_sized_boolean_vectors() {
let image_condition = MAX_SHAPE_DATA_ELEMS + 1;
assert!(bounded_compress_condition(
DataType::Bool,
&[image_condition]
));
assert!(!bounded_shape_input(DataType::Bool, &[image_condition]));
assert!(!bounded_compress_condition(
DataType::Int64,
&[image_condition]
));
assert!(!bounded_compress_condition(
DataType::Bool,
&[(1 << 20) + 1]
));
}

/// The data-dependent shape sizer must return exactly one shape per output
/// so the run loop's `out_shapes[oi]` indexing can never misindex. Slice is
/// single-output, so it returns a 1-element Vec; the run loop additionally
Expand Down
Loading