Skip to content

Commit e19c52a

Browse files
committed
Add envelope checks (rquires_size_in_bytes, offset_bounds)
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
1 parent fb579ad commit e19c52a

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

cuda_core/tests/test_strided_layout.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,30 @@ def _cmp_layout_from_dense_vs_from_np(layout: StridedLayout, np_ref: np.ndarray,
120120
assert layout_from_np.strides_in_bytes == layout.strides_in_bytes
121121

122122

123+
def _check_envelope(layout: StridedLayout, layout_spec: LayoutSpec):
124+
orignal_vol = math.prod(layout_spec.shape)
125+
min_offset, max_offset = layout.offset_bounds
126+
if layout.volume == 0:
127+
assert min_offset == 0
128+
assert max_offset == -1
129+
else:
130+
assert min_offset >= 0
131+
assert min_offset <= max_offset
132+
assert max_offset <= orignal_vol - 1
133+
if layout.is_dense:
134+
assert min_offset == 0
135+
assert max_offset == math.prod(layout.shape) - 1
136+
else:
137+
shape, strides = layout.shape, layout.strides
138+
ref_min_offset = ref_max_offset = layout.slice_offset
139+
ref_min_offset += sum(strides[i] * (shape[i] - 1) for i in range(layout.ndim) if strides[i] < 0)
140+
ref_max_offset += sum(strides[i] * (shape[i] - 1) for i in range(layout.ndim) if strides[i] > 0)
141+
assert min_offset == ref_min_offset
142+
assert max_offset == ref_max_offset
143+
assert 0 <= layout.required_size_in_bytes() <= orignal_vol * layout_spec.itemsize
144+
assert layout.required_size_in_bytes() == (max_offset + 1) * layout.itemsize
145+
146+
123147
def _cmp_slice_offset(
124148
layout_0: StridedLayout,
125149
layout_1: StridedLayout,
@@ -149,6 +173,7 @@ def test_dense_with_permutation_as_stride_order(layout_spec):
149173
layout, np_ref = _setup_layout_and_np_ref(layout_spec)
150174
_cmp_layout_and_array(layout, np_ref, False)
151175
_cmp_layout_from_dense_vs_from_np(layout, np_ref, False)
176+
_check_envelope(layout, layout_spec)
152177
assert layout.stride_order == layout_spec.stride_order
153178

154179

@@ -182,6 +207,7 @@ def test_permuted(layout_spec):
182207
layout, np_ref = _transform(layout, np_ref, layout_spec)
183208
_cmp_layout_and_array(layout, np_ref, layout_spec.has_no_strides_transformed())
184209
_cmp_layout_from_dense_vs_from_np(layout, np_ref, layout_spec.has_no_strides_transformed())
210+
_check_envelope(layout, layout_spec)
185211
unit_dims_count = sum(dim == 1 for dim in np_ref.shape)
186212
if unit_dims_count <= 1:
187213
# stride order with multiple unit dimensions is not unique
@@ -277,6 +303,7 @@ def test_slice(layout_spec, error_msg):
277303
_cmp_layout_and_array(sliced, sliced_ref, False)
278304
_cmp_layout_from_dense_vs_from_np(sliced, sliced_ref, False)
279305
_cmp_slice_offset(layout, sliced, np_ref, sliced_ref)
306+
_check_envelope(sliced, layout_spec)
280307
layout = sliced
281308
np_ref = sliced_ref
282309
else:
@@ -406,6 +433,7 @@ def test_reshape(layout_spec, new_shape, error_msg):
406433
reshaped_ref = np_ref.reshape(new_shape, copy=False)
407434
_cmp_layout_and_array(reshaped, reshaped_ref, False)
408435
_cmp_layout_from_dense_vs_from_np(reshaped, reshaped_ref, False)
436+
_check_envelope(reshaped, layout_spec)
409437
else:
410438
# sanity check that numpy is not able to reshape without
411439
# a copy as well
@@ -473,6 +501,7 @@ def test_flatten(
473501
layout, np_ref = _transform(layout, np_ref, layout_spec)
474502
_cmp_layout_and_array(layout, np_ref, layout_spec.has_no_strides_transformed())
475503
_cmp_layout_from_dense_vs_from_np(layout, np_ref, layout_spec.has_no_strides_transformed())
504+
_check_envelope(layout, layout_spec)
476505

477506
mask = flatten_mask2str(layout.flattened_axis_mask(), layout.ndim)
478507
assert mask == expected_axis_mask
@@ -583,6 +612,8 @@ def test_flatten_together(
583612

584613
flattened_0 = layout_0.flattened(mask=mask)
585614
flattened_1 = layout_1.flattened(mask=mask)
615+
_check_envelope(flattened_0, layout_spec_0)
616+
_check_envelope(flattened_1, layout_spec_1)
586617

587618
for flattened, expected_layout in zip([flattened_0, flattened_1], [expected_layout_0, expected_layout_1]):
588619
assert flattened == expected_layout
@@ -640,6 +671,7 @@ def test_squeezed(layout_spec):
640671
assert squeezed.shape == (0,)
641672
assert squeezed.strides == (0,)
642673
assert squeezed.slice_offset == layout.slice_offset
674+
_check_envelope(squeezed, layout_spec)
643675

644676

645677
@pytest.mark.parametrize(
@@ -681,6 +713,7 @@ def test_unsqueezed_layout(layout_spec, axes):
681713
has_no_strides = layout_spec.has_no_strides_transformed() and len(axes) == 0
682714
_cmp_layout_and_array(unsqueezed, unsqueezed_ref, has_no_strides)
683715
_cmp_layout_from_dense_vs_from_np(unsqueezed, unsqueezed_ref, has_no_strides)
716+
_check_envelope(unsqueezed, layout_spec)
684717

685718

686719
@pytest.mark.parametrize(
@@ -748,11 +781,13 @@ def test_packed_unpacked(
748781
has_no_strides = layout_spec.has_no_strides_transformed() and layout.itemsize == new_itemsize
749782
_cmp_layout_and_array(packed, packed_ref, has_no_strides)
750783
_cmp_layout_from_dense_vs_from_np(packed, packed_ref, has_no_strides)
784+
_check_envelope(packed, layout_spec)
751785
vec_size = new_itemsize // layout.itemsize
752786
assert packed.slice_offset * vec_size == layout.slice_offset
753787
unpacked = packed.repacked(layout.itemsize, axis=axis)
754788
_cmp_layout_and_array(unpacked, np_ref, has_no_strides)
755789
_cmp_layout_from_dense_vs_from_np(unpacked, np_ref, has_no_strides)
790+
_check_envelope(unpacked, layout_spec)
756791

757792

758793
@pytest.mark.parametrize(
@@ -801,6 +836,7 @@ def test_broadcast_layout(
801836
broadcasted_ref = np.broadcast_to(np_ref, new_shape)
802837
_cmp_layout_and_array(broadcasted, broadcasted_ref, False)
803838
_cmp_layout_from_dense_vs_from_np(broadcasted, broadcasted_ref, False)
839+
_check_envelope(broadcasted, layout_spec)
804840
assert layout.is_unique
805841
ndim_diff = len(broadcasted_ref.shape) - len(np_ref.shape)
806842
expect_unique = all(broadcasted_ref.shape[i] == 1 for i in range(ndim_diff))
@@ -875,3 +911,7 @@ def test_to_dense(layout_spec, new_stride_order):
875911
dense_ref = np_ref.transpose(new_stride_order).copy(order="C").transpose(inv_permutation(new_stride_order))
876912
_cmp_layout_and_array(dense, dense_ref, False)
877913
_cmp_layout_from_dense_vs_from_np(dense, dense_ref, False)
914+
915+
assert dense.is_dense
916+
assert dense.required_size_in_bytes() == np_ref.size * layout.itemsize
917+
assert dense.offset_bounds == (0, np_ref.size - 1)

0 commit comments

Comments
 (0)