@@ -94,7 +94,6 @@ using bioimage_cpp::detail::checked_label_to_node;
9494using bioimage_cpp::detail::Edge;
9595using bioimage_cpp::detail::EdgeHash;
9696using bioimage_cpp::detail::edge_key;
97- using bioimage_cpp::detail::valid_axis_range;
9897
9998using EdgeSet = std::unordered_set<Edge, EdgeHash>;
10099using EdgeStatsMap = std::unordered_map<Edge, PartialStats, EdgeHash>;
@@ -152,104 +151,14 @@ inline void validate_owned_box(
152151 }
153152}
154153
155- // Sweep reference nodes over the owned box on a 2D grid, calling
156- // `body(node, target)` with flat C-order indices into the outer array for each
157- // reference node whose `+offset` neighbor stays inside the outer array. Axis 0
158- // is additionally restricted to the absolute slab `[slab_begin, slab_end)`
159- // (the caller's thread chunk, already inside the owned box).
160- template <class Body >
161- void sweep_owned_box_2d (
162- const std::ptrdiff_t dy,
163- const std::ptrdiff_t dx,
164- const std::size_t outer_h,
165- const std::size_t outer_w,
166- const std::int64_t own_begin_y,
167- const std::int64_t own_begin_x,
168- const std::int64_t own_shape_y,
169- const std::int64_t own_shape_x,
170- const std::size_t slab_begin,
171- const std::size_t slab_end,
172- const Body &body
173- ) {
174- std::size_t y_lo_v, y_hi_v, x_lo_v, x_hi_v;
175- valid_axis_range (dy, outer_h, y_lo_v, y_hi_v);
176- valid_axis_range (dx, outer_w, x_lo_v, x_hi_v);
177-
178- const auto y_lo = std::max ({y_lo_v, static_cast <std::size_t >(own_begin_y), slab_begin});
179- const auto y_hi = std::min ({y_hi_v, static_cast <std::size_t >(own_begin_y + own_shape_y), slab_end});
180- const auto x_lo = std::max (x_lo_v, static_cast <std::size_t >(own_begin_x));
181- const auto x_hi = std::min (x_hi_v, static_cast <std::size_t >(own_begin_x + own_shape_x));
182- if (y_lo >= y_hi || x_lo >= x_hi) {
183- return ;
184- }
185-
186- const auto offset_stride = dy * static_cast <std::ptrdiff_t >(outer_w) + dx;
187- for (std::size_t y = y_lo; y < y_hi; ++y) {
188- const auto row_offset = y * outer_w;
189- for (std::size_t x = x_lo; x < x_hi; ++x) {
190- const auto node = row_offset + x;
191- const auto target = static_cast <std::uint64_t >(
192- static_cast <std::ptrdiff_t >(node) + offset_stride
193- );
194- body (static_cast <std::uint64_t >(node), target);
195- }
196- }
197- }
198-
199- // 3D variant of `sweep_owned_box_2d`.
200- template <class Body >
201- void sweep_owned_box_3d (
202- const std::ptrdiff_t dz,
203- const std::ptrdiff_t dy,
204- const std::ptrdiff_t dx,
205- const std::size_t outer_d,
206- const std::size_t outer_h,
207- const std::size_t outer_w,
208- const std::int64_t own_begin_z,
209- const std::int64_t own_begin_y,
210- const std::int64_t own_begin_x,
211- const std::int64_t own_shape_z,
212- const std::int64_t own_shape_y,
213- const std::int64_t own_shape_x,
214- const std::size_t slab_begin,
215- const std::size_t slab_end,
216- const Body &body
217- ) {
218- std::size_t z_lo_v, z_hi_v, y_lo_v, y_hi_v, x_lo_v, x_hi_v;
219- valid_axis_range (dz, outer_d, z_lo_v, z_hi_v);
220- valid_axis_range (dy, outer_h, y_lo_v, y_hi_v);
221- valid_axis_range (dx, outer_w, x_lo_v, x_hi_v);
222-
223- const auto z_lo = std::max ({z_lo_v, static_cast <std::size_t >(own_begin_z), slab_begin});
224- const auto z_hi = std::min ({z_hi_v, static_cast <std::size_t >(own_begin_z + own_shape_z), slab_end});
225- const auto y_lo = std::max (y_lo_v, static_cast <std::size_t >(own_begin_y));
226- const auto y_hi = std::min (y_hi_v, static_cast <std::size_t >(own_begin_y + own_shape_y));
227- const auto x_lo = std::max (x_lo_v, static_cast <std::size_t >(own_begin_x));
228- const auto x_hi = std::min (x_hi_v, static_cast <std::size_t >(own_begin_x + own_shape_x));
229- if (z_lo >= z_hi || y_lo >= y_hi || x_lo >= x_hi) {
230- return ;
231- }
232-
233- const auto slice_size = outer_h * outer_w;
234- const auto offset_stride =
235- dz * static_cast <std::ptrdiff_t >(slice_size) +
236- dy * static_cast <std::ptrdiff_t >(outer_w) + dx;
237- for (std::size_t z = z_lo; z < z_hi; ++z) {
238- const auto slice_offset = z * slice_size;
239- for (std::size_t y = y_lo; y < y_hi; ++y) {
240- const auto row_offset = slice_offset + y * outer_w;
241- for (std::size_t x = x_lo; x < x_hi; ++x) {
242- const auto node = row_offset + x;
243- const auto target = static_cast <std::uint64_t >(
244- static_cast <std::ptrdiff_t >(node) + offset_stride
245- );
246- body (static_cast <std::uint64_t >(node), target);
247- }
248- }
249- }
250- }
251-
252- // Dispatch the owned-box sweep for one offset over the correct grid rank.
154+ // Dispatch the owned-box sweep for one offset over the correct grid rank:
155+ // `body(node, target)` is called with flat C-order indices into the outer
156+ // array for each reference node inside the owned box whose `+offset` neighbor
157+ // stays inside the outer array. Axis 0 is additionally restricted to the
158+ // absolute slab `[slab_begin, slab_end)` (the caller's thread chunk, already
159+ // inside the owned box). The loop itself is the shared
160+ // `detail/grid.hxx::sweep_clipped_box_{2d,3d}`; the owned box and slab fold
161+ // into its clip box.
253162template <class Body >
254163void sweep_owned_box (
255164 const std::vector<std::ptrdiff_t > &offset,
@@ -260,18 +169,27 @@ void sweep_owned_box(
260169 const std::size_t slab_end,
261170 const Body &body
262171) {
172+ const auto lo = [&](const std::size_t axis) {
173+ return static_cast <std::size_t >(own_begin[axis]);
174+ };
175+ const auto hi = [&](const std::size_t axis) {
176+ return static_cast <std::size_t >(own_begin[axis] + own_shape[axis]);
177+ };
263178 if (outer_dims.size () == 2 ) {
264- sweep_owned_box_2d (
179+ bioimage_cpp::detail::sweep_clipped_box_2d (
265180 offset[0 ], offset[1 ], outer_dims[0 ], outer_dims[1 ],
266- own_begin[0 ], own_begin[1 ], own_shape[0 ], own_shape[1 ],
267- slab_begin, slab_end, body
181+ std::max (lo (0 ), slab_begin), std::min (hi (0 ), slab_end),
182+ lo (1 ), hi (1 ),
183+ body
268184 );
269185 } else {
270- sweep_owned_box_3d (
271- offset[0 ], offset[1 ], offset[2 ], outer_dims[0 ], outer_dims[1 ], outer_dims[2 ],
272- own_begin[0 ], own_begin[1 ], own_begin[2 ],
273- own_shape[0 ], own_shape[1 ], own_shape[2 ],
274- slab_begin, slab_end, body
186+ bioimage_cpp::detail::sweep_clipped_box_3d (
187+ offset[0 ], offset[1 ], offset[2 ],
188+ outer_dims[0 ], outer_dims[1 ], outer_dims[2 ],
189+ std::max (lo (0 ), slab_begin), std::min (hi (0 ), slab_end),
190+ lo (1 ), hi (1 ),
191+ lo (2 ), hi (2 ),
192+ body
275193 );
276194 }
277195}
0 commit comments