@@ -111,8 +111,9 @@ void reduce_impl(
111111
112112 const uint32_t wg_size =
113113 utils::clamp_workgroup_size (device, kReduceWorkgroupSizeX );
114- const uint32_t workgroup_count = utils::compute_1d_workgroup_count (
115- device, static_cast <uint32_t >(outputs), wg_size, op_name);
114+ // Cooperative reduction: one workgroup per output element (2D-folded grid).
115+ const utils::WgCount workgroup_count = utils::compute_2d_workgroup_count (
116+ device, static_cast <uint32_t >(outputs), 1u , op_name);
116117
117118 ReduceParams params = {};
118119 params.outer = outer;
@@ -190,8 +191,8 @@ void reduce_impl(
190191 bg_desc.entries = bg_entries;
191192 WGPUBindGroup bind_group = wgpuDeviceCreateBindGroup (device, &bg_desc);
192193
193- const size_t dispatch_idx =
194- graph. add_dispatch ( {pipeline, bind_group, workgroup_count, op_name});
194+ const size_t dispatch_idx = graph. add_dispatch (
195+ {pipeline, bind_group, workgroup_count. x , op_name, workgroup_count. y });
195196
196197 // Dynamic shapes: recompute the decomposition for the reduced dim + dispatch.
197198 WGPUBuffer params_buf = uniform_buffer;
@@ -205,7 +206,6 @@ void reduce_impl(
205206 keepdim,
206207 is_mean_u,
207208 build_outputs,
208- wg_size,
209209 dispatch_idx,
210210 params_buf](WebGPUGraph& g) {
211211 const auto & d = g.cur_dims (in_id);
@@ -225,12 +225,13 @@ void reduce_impl(
225225 p.inner = n;
226226 p.is_mean = is_mean_u;
227227 wgpuQueueWriteBuffer (g.queue (), params_buf, 0 , &p, sizeof (p));
228- g.dispatch_at (dispatch_idx).workgroup_count_x =
229- utils::compute_1d_workgroup_count (
230- g.device (),
231- static_cast <uint32_t >(live_outputs),
232- wg_size,
233- " reduce(resize)" );
228+ const utils::WgCount wgc = utils::compute_2d_workgroup_count (
229+ g.device (),
230+ static_cast <uint32_t >(live_outputs),
231+ 1u ,
232+ " reduce(resize)" );
233+ g.dispatch_at (dispatch_idx).workgroup_count_x = wgc.x ;
234+ g.dispatch_at (dispatch_idx).workgroup_count_y = wgc.y ;
234235 // Propagate reduced output dims for downstream resize hooks.
235236 int64_t nd = static_cast <int64_t >(d.size ());
236237 int64_t rd = dim < 0 ? dim + nd : dim;
0 commit comments