Repository: microsoft/onnxruntime
File: onnxruntime/core/providers/webgpu/webgpu_kernel.cc (C++)

Code before:

  if (webgpu_context_.ValidationMode() >= ValidationMode::Full) {
    ORT_RETURN_IF_ERROR(webgpu_context_.PopErrorScope());
  }

  return s;
}

Status WebGpuKernel::PrePack(const Tensor& tensor, int input_idx, AllocatorPtr /*alloc*/,
                             /*out*/ bool& is_packed, /*out*/ PrePackedWeights* /* prepacked_weights */) {
  ComputeContextBase context{webgpu_context_, ep_, *this};

  if (webgpu_context_.ValidationMode() >= ValidationMode::Full) {
    webgpu_context_.PushErrorScope();
  }

  // Currently, ORT does not allow using prepacked weights in non-CPU EPs.
  // So we do not pass prepacked_weights to PrePackInternal.
  // Kernel implementation that supports prepacking should manage its own storage.
  // Use the EP's prepack allocator which creates unmapped GPU buffers.

  Status s = PrePackInternal(context, tensor, input_idx, ep_.PrepackAllocator(), is_packed);

  // Flush pending commands to ensure GPU buffer creations are completed.
  // This allows the initializer buffer manager to release temporary buffers and reduce memory usage.
  webgpu_context_.Flush(webgpu_context_.InitializerBufferManager());

  if (webgpu_context_.ValidationMode() >= ValidationMode::Full) {
    ORT_RETURN_IF_ERROR(webgpu_context_.PopErrorScope());
  }

  return s;
}

Status WebGpuKernel::PrePackInternal(ComputeContextBase& /*context*/,
                                     const Tensor& /*tensor*/,
                                     int /*input_idx*/,
                                     AllocatorPtr /*alloc*/,
                                     /*out*/ bool& is_packed) {
  is_packed = false;
  return Status::OK();
}

}  // namespace webgpu
}  // namespace onnxruntime


Review comment (suggestion):
```suggestion
  if (is_packed) {
    // Flush pending commands to ensure GPU buffer creations are completed.
    // This allows the initializer buffer manager to release temporary buffers and reduce memory usage.
    webgpu_context_.Flush(webgpu_context_.InitializerBufferManager());
  }
```

Code after:

  if (webgpu_context_.ValidationMode() >= ValidationMode::Full) {
    ORT_RETURN_IF_ERROR(webgpu_context_.PopErrorScope());
  }

  return s;
}

Status WebGpuKernel::PrePack(const Tensor& tensor, int input_idx, AllocatorPtr /*alloc*/,
                             /*out*/ bool& is_packed, /*out*/ PrePackedWeights* /* prepacked_weights */) {
  ComputeContextBase context{webgpu_context_, ep_, *this};

  if (webgpu_context_.ValidationMode() >= ValidationMode::Full) {
    webgpu_context_.PushErrorScope();
  }

  // Currently, ORT does not allow using prepacked weights in non-CPU EPs.
  // So we do not pass prepacked_weights to PrePackInternal.
  // Kernel implementation that supports prepacking should manage its own storage.
  // Use the EP's prepack allocator which creates unmapped GPU buffers.

  Status s = PrePackInternal(context, tensor, input_idx, ep_.PrepackAllocator(), is_packed);

  if (is_packed) {
    // Flush pending commands to ensure GPU buffer creations are completed.
    // This allows the initializer buffer manager to release temporary buffers and reduce memory usage.
    webgpu_context_.Flush(webgpu_context_.InitializerBufferManager());
  }

  if (webgpu_context_.ValidationMode() >= ValidationMode::Full) {
    ORT_RETURN_IF_ERROR(webgpu_context_.PopErrorScope());
  }

  return s;
}

Status WebGpuKernel::PrePackInternal(ComputeContextBase& /*context*/,
                                     const Tensor& /*tensor*/,
                                     int /*input_idx*/,
                                     AllocatorPtr /*alloc*/,
                                     /*out*/ bool& is_packed) {
  is_packed = false;
  return Status::OK();
}

}  // namespace webgpu
}  // namespace onnxruntime