@@ -1013,7 +1013,7 @@ pub trait ReifyView: sealed::Sealed {
1013
1013
1014
1014
/// Reify multiple views as a union of selections in the
1015
1015
/// coordinate system of `self`.
1016
- fn reify_views ( & self , views : & [ & Slice ] ) -> Result < Selection , SliceError > ;
1016
+ fn reify_views < V : AsRef < [ Slice ] > > ( & self , views : V ) -> Result < Selection , SliceError > ;
1017
1017
}
1018
1018
1019
1019
impl ReifyView for Slice {
@@ -1030,7 +1030,6 @@ impl ReifyView for Slice {
1030
1030
/// # Errors
1031
1031
///
1032
1032
/// Returns an error if:
1033
- /// - The number of dimensions in the view does not match the base
1034
1033
/// - The view lies outside the bounds of the base slice
1035
1034
///
1036
1035
/// # Example
@@ -1044,16 +1043,14 @@ impl ReifyView for Slice {
1044
1043
/// let selection = base.reify_view(view).unwrap();
1045
1044
/// ```
1046
1045
fn reify_view ( & self , view : & Slice ) -> Result < Selection , SliceError > {
1047
- if view. num_dim ( ) != self . num_dim ( ) {
1048
- return Err ( SliceError :: InvalidDims {
1049
- expected : self . num_dim ( ) ,
1050
- got : view. num_dim ( ) ,
1051
- } ) ;
1052
- }
1053
1046
if view. is_empty ( ) {
1054
1047
return Ok ( dsl:: false_ ( ) ) ;
1055
1048
}
1056
1049
1050
+ if view. num_dim ( ) != self . num_dim ( ) {
1051
+ return Selection :: of_ranks ( self , & view. iter ( ) . collect :: < BTreeSet < usize > > ( ) ) ;
1052
+ }
1053
+
1057
1054
let origin = self . coordinates ( view. offset ( ) ) ?;
1058
1055
let mut acc = dsl:: true_ ( ) ;
1059
1056
for ( & start, & len) in origin. iter ( ) . zip ( view. sizes ( ) ) . rev ( ) {
@@ -1076,7 +1073,6 @@ impl ReifyView for Slice {
1076
1073
/// # Errors
1077
1074
///
1078
1075
/// Returns an error if any view:
1079
- /// - Has a different number of dimensions than the base slice
1080
1076
/// - Refers to coordinates not contained within the base
1081
1077
///
1082
1078
/// # Example
@@ -1087,15 +1083,22 @@ impl ReifyView for Slice {
1087
1083
/// let shape = ndslice::shape!(x = 4, y = 4);
1088
1084
/// let base = shape.slice();
1089
1085
///
1090
- /// let a = ndslice::select!(shape, x = 0..2, y = 0..2).unwrap();
1091
- /// let b = ndslice::select!(shape, x = 2..4, y = 2..4).unwrap();
1086
+ /// let a = ndslice::select!(shape, x = 0..2, y = 0..2)
1087
+ /// .unwrap()
1088
+ /// .slice()
1089
+ /// .clone();
1090
+ /// let b = ndslice::select!(shape, x = 2..4, y = 2..4)
1091
+ /// .unwrap()
1092
+ /// .slice()
1093
+ /// .clone();
1092
1094
///
1093
- /// let sel = base.reify_views(&[a.slice() , b.slice() ]).unwrap();
1095
+ /// let sel = base.reify_views(&[a, b]).unwrap();
1094
1096
/// ```
1095
- fn reify_views ( & self , views : & [ & Slice ] ) -> Result < Selection , SliceError > {
1097
+ fn reify_views < V : AsRef < [ Slice ] > > ( & self , views : V ) -> Result < Selection , SliceError > {
1098
+ let views = views. as_ref ( ) ;
1096
1099
let mut selections = Vec :: with_capacity ( views. len ( ) ) ;
1097
1100
1098
- for & view in views {
1101
+ for view in views {
1099
1102
if view. is_empty ( ) {
1100
1103
continue ;
1101
1104
}
@@ -2157,6 +2160,28 @@ mod tests {
2157
2160
) ;
2158
2161
}
2159
2162
2163
+ #[ test]
2164
+ fn test_reify_view_dimension_mismatch ( ) {
2165
+ let shape = shape ! ( host = 2 , gpu = 4 ) ;
2166
+ let base = shape. slice ( ) ;
2167
+
2168
+ // Select the 3rd GPU (index 2) across both hosts i.e. flat
2169
+ // indices [2, 6]
2170
+ let indices = vec ! [
2171
+ base. location( & [ 0 , 2 ] ) . unwrap( ) ,
2172
+ base. location( & [ 1 , 2 ] ) . unwrap( ) ,
2173
+ ] ;
2174
+
2175
+ let view = Slice :: new ( indices[ 0 ] , vec ! [ indices. len( ) ] , vec ! [ 4 ] ) . unwrap ( ) ;
2176
+ let selection = base. reify_view ( & view) . unwrap ( ) ;
2177
+
2178
+ let expected = Selection :: of_ranks ( base, & indices. iter ( ) . cloned ( ) . collect ( ) ) . unwrap ( ) ;
2179
+ assert_structurally_eq ! ( & selection, expected) ;
2180
+
2181
+ let actual: Vec < _ > = selection. eval ( & EvalOpts :: strict ( ) , base) . unwrap ( ) . collect ( ) ;
2182
+ assert_eq ! ( actual, indices) ;
2183
+ }
2184
+
2160
2185
#[ test]
2161
2186
fn test_union_of_slices_empty ( ) {
2162
2187
let base = Slice :: new_row_major ( [ 2 ] ) ;
@@ -2175,7 +2200,7 @@ mod tests {
2175
2200
let shape = shape ! ( x = 3 ) ;
2176
2201
let base = shape. slice ( ) ;
2177
2202
let selected = select ! ( shape, x = 1 ) . unwrap ( ) ;
2178
- let view = selected. slice ( ) ;
2203
+ let view = selected. slice ( ) . clone ( ) ;
2179
2204
2180
2205
let selection = base. reify_views ( & [ view] ) . unwrap ( ) ;
2181
2206
let expected = range ( 1 ..=1 , true_ ( ) ) ;
@@ -2197,11 +2222,11 @@ mod tests {
2197
2222
2198
2223
// View A: (0, *)
2199
2224
let a = select ! ( shape, x = 0 ) . unwrap ( ) ;
2200
- let view_a = a. slice ( ) ;
2225
+ let view_a = a. slice ( ) . clone ( ) ;
2201
2226
2202
2227
// View B: (1, *)
2203
2228
let b = select ! ( shape, x = 1 ) . unwrap ( ) ;
2204
- let view_b = b. slice ( ) ;
2229
+ let view_b = b. slice ( ) . clone ( ) ;
2205
2230
2206
2231
let selection = base. reify_views ( & [ view_a, view_b] ) . unwrap ( ) ;
2207
2232
let expected = union (
@@ -2224,10 +2249,10 @@ mod tests {
2224
2249
let base = shape. slice ( ) ;
2225
2250
2226
2251
let selected1 = select ! ( shape, y = 0 ..2 ) . unwrap ( ) ;
2227
- let view1 = selected1. slice ( ) ;
2252
+ let view1 = selected1. slice ( ) . clone ( ) ;
2228
2253
2229
2254
let selected2 = select ! ( shape, y = 1 ..4 ) . unwrap ( ) ;
2230
- let view2 = selected2. slice ( ) ;
2255
+ let view2 = selected2. slice ( ) . clone ( ) ;
2231
2256
2232
2257
let selection = base. reify_views ( & [ view1, view2] ) . unwrap ( ) ;
2233
2258
let expected = union (
0 commit comments