@@ -308,18 +308,14 @@ void WebGPUGraph::build(
308308 int constant_id = vk_tensor->constant_id ();
309309 int mem_obj_id = vk_tensor->mem_obj_id ();
310310
311- // Constants are dedicated. A prepack-routed constant is recorded as a
312- // ConstantSource (materialized once by its prepack node); if it is used
313- // ONLY via prepack it is deferred (no eager GPU buffer).
311+ // Constants are dedicated. Every constant is recorded as a
312+ // ConstantSource and materialized via materialize_constant (one
313+ // CPU->GPU write); a constant consumed ONLY via prepack is deferred
314+ // (no eager buffer -- its prepack node performs that one write).
314315 if (constant_id >= 0 || mem_obj_id < 0 ) {
315316 tensor_mem_obj_ids_[i] = -1 ;
316317
317- // Record the source for every prepack-routed constant (metadata only,
318- // resolved straight from the constants table) so materialize_constant
319- // always has a source -- independent of the defer decision below.
320- const bool is_prepack_src =
321- constant_id >= 0 && prepack_src_ids.count (i) != 0 ;
322- if (is_prepack_src) {
318+ if (constant_id >= 0 ) {
323319 const auto * constants = graph->constants ();
324320 if (!constants ||
325321 constant_id >= static_cast <int >(constants->size ())) {
@@ -342,7 +338,8 @@ void WebGPUGraph::build(
342338 }
343339
344340 // Defer constants consumed solely via prepack: skip the eager buffer.
345- const bool defer = is_prepack_src && direct_use_ids.count (i) == 0 ;
341+ const bool defer = constant_id >= 0 &&
342+ prepack_src_ids.count (i) != 0 && direct_use_ids.count (i) == 0 ;
346343 if (!defer) {
347344 WGPUBufferDescriptor buf_desc = {};
348345 buf_desc.size = std::max (tensor.nbytes , size_t (4 ));
@@ -351,50 +348,10 @@ void WebGPUGraph::build(
351348 buf_desc.mappedAtCreation = false ;
352349 tensor.buffer = wgpuDeviceCreateBuffer (device_, &buf_desc);
353350
354- if (constant_id >= 0 && constant_data && tensor.nbytes > 0 ) {
355- const auto * constants = graph->constants ();
356- if (constants &&
357- constant_id < static_cast <int >(constants->size ())) {
358- const auto * vk_bytes = constants->Get (constant_id);
359- if (vk_bytes->offset () != UINT64_MAX ) {
360- const uint8_t * src = constant_data + vk_bytes->offset ();
361- wgpuQueueWriteBuffer (
362- queue_, tensor.buffer , 0 , src, tensor.nbytes );
363- } else if (
364- vk_bytes->named_key () != nullptr &&
365- named_data_map != nullptr ) {
366- // Constant stored in the PTE named-data map.
367- auto buf =
368- named_data_map->get_data (vk_bytes->named_key ()->c_str ());
369- if (!buf.ok ()) {
370- throw std::runtime_error (
371- std::string (" WebGPU: named constant '" ) +
372- vk_bytes->named_key ()->c_str () +
373- " ' not found in NamedDataMap" );
374- }
375- if (buf->size () < tensor.nbytes ) {
376- throw std::runtime_error (
377- std::string (" WebGPU: named constant '" ) +
378- vk_bytes->named_key ()->c_str () + " ' undersized: have " +
379- std::to_string (buf->size ()) + " bytes, need " +
380- std::to_string (tensor.nbytes ));
381- }
382- wgpuQueueWriteBuffer (
383- queue_, tensor.buffer , 0 , buf->data (), tensor.nbytes );
384- buf->Free ();
385- } else {
386- throw std::runtime_error (
387- " WebGPU: constant has no inline offset and no named-data key" );
388- }
389- } else {
390- throw std::runtime_error (
391- " WebGPU: constant_id set but the constants table is missing "
392- " or the id is out of range" );
393- }
394- } else if (constant_id >= 0 && tensor.nbytes > 0 ) {
395- // constant_id set but constant_data null -> fail loud.
396- throw std::runtime_error (
397- " WebGPU: constant_id set but constant_data is null" );
351+ // Same single CPU->GPU write the prepack node uses (no
352+ // duplication).
353+ if (constant_id >= 0 ) {
354+ materialize_constant (i, tensor.buffer );
398355 }
399356 }
400357 } else {
@@ -544,7 +501,7 @@ void WebGPUGraph::materialize_constant(int const_value_id, WGPUBuffer dst) {
544501 auto it = constant_sources_.find (const_value_id);
545502 if (it == constant_sources_.end ()) {
546503 throw std::runtime_error (
547- " WebGPU prepack : no source recorded for constant id " +
504+ " WebGPU: no source recorded for constant id " +
548505 std::to_string (const_value_id));
549506 }
550507 const ConstantSource& cs = it->second ;
@@ -553,24 +510,24 @@ void WebGPUGraph::materialize_constant(int const_value_id, WGPUBuffer dst) {
553510 }
554511 if (cs.inline_offset != UINT64_MAX ) {
555512 if (constant_data_ == nullptr ) {
556- throw std::runtime_error (" WebGPU prepack : inline constant data is null" );
513+ throw std::runtime_error (" WebGPU: inline constant data is null" );
557514 }
558515 wgpuQueueWriteBuffer (
559516 queue_, dst, 0 , constant_data_ + cs.inline_offset , cs.nbytes );
560517 } else if (!cs.named_key .empty () && named_data_map_ != nullptr ) {
561518 auto buf = named_data_map_->get_data (cs.named_key .c_str ());
562519 if (!buf.ok ()) {
563520 throw std::runtime_error (
564- " WebGPU prepack : named constant '" + cs.named_key + " ' not found" );
521+ " WebGPU: named constant '" + cs.named_key + " ' not found" );
565522 }
566523 if (buf->size () < cs.nbytes ) {
567524 throw std::runtime_error (
568- " WebGPU prepack : named constant '" + cs.named_key + " ' undersized" );
525+ " WebGPU: named constant '" + cs.named_key + " ' undersized" );
569526 }
570527 wgpuQueueWriteBuffer (queue_, dst, 0 , buf->data (), cs.nbytes );
571528 buf->Free ();
572529 } else {
573- throw std::runtime_error (" WebGPU prepack : constant has no source" );
530+ throw std::runtime_error (" WebGPU: constant has no source" );
574531 }
575532}
576533
0 commit comments