[WebGPU] Direct CPU->GPU buffer upload for UMA - #23910
Conversation
This eliminates the using of staging buffers when uploading data from CPU to GPU for UMA. The data is directly copied to the GPU buffer. The major challenge of enabling this feature is to avoid waiting for the mapping of the dest GPU buffer. The idea is to map the dest GPU buffers in advance, so that when the uploading starts, the dest GPU is always mapped. This is achieved by: 1. using map-at-creation for all storage buffers. 2. mapping the buffer once it's returned, and marking it as ready for reuse after the mapping is done. 3. checking to unmap the buffer whereever it's used by the command encoder.
|
@xhcao PTAL |
|
@jchen10 thank you for the optimization! I checked the document of the feature. As it described, this feature allows to map the data on the storage buffer and makes it possible to get rid of the staging buffer for uploading/downloading. For downloading it looks like this feature is a simple optimization. However for uploading the situation became a little bit complicated. As already mentioned in the description of this PR, to enable this feature for uploading, we need the buffer to be in "mapped" state. If we call
I think the real problem is that the current implementation of ORT does not give the context information to allocator so There may need more discussion about how to use this feature in ORT. |
|
@fs-eire Thanks for the comment. Absolutely it would be perfect if ORT could give more context info to the buffer manager. Let's investigate this further. With UMA: |
| // Check if the buffer was created by the class with the extended map usages. | ||
| bool IsUMABuffer(WGPUBuffer buffer) const; | ||
| // All the buffers created by the class with the extended map usages. | ||
| std::unordered_map<WGPUBuffer, bool> uma_buffers_; |
There was a problem hiding this comment.
In fact, when usage is usage & wgpu::BufferUsage::Storage, we will use UMA buffer. So remove IsUMABuffer and uma_buffers_, instead to use WGPUBufferUsage wgpuBufferGetUsage(WGPUBuffer buffer) == wgpu::BufferUsage::Storage where need to verify whether the buffer is UMA. If so, the code will be simple and clean.
There was a problem hiding this comment.
Good point. It would be simpler. Thanks!
|
/azp run ONNX Runtime Web CI Pipeline,Windows GPU CI Pipeline,Linux Android Emulator QNN CI Pipeline |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
|
/azp run Linux CPU CI Pipeline,Linux CPU Minimal Build E2E CI Pipeline,Linux GPU CI Pipeline,Linux GPU TensorRT CI Pipeline, Linux OpenVINO CI Pipeline,Linux QNN CI Pipeline,MacOS CI Pipeline,Windows ARM64 QNN CI Pipeline,Windows CPU CI Pipeline |
|
/azp run Windows GPU TensorRT CI Pipeline,onnxruntime-binary-size-checks-ci-pipeline,orttraining-linux-ci-pipeline,orttraining-linux-gpu-ci-pipeline,orttraining-ortmodule-distributed,Windows x64 QNN CI Pipeline,Big Models |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
|
/azp run Windows GPU CUDA CI Pipeline,Windows GPU DML CI Pipeline,Windows GPU Doc Gen CI Pipeline, Win_TRT_Minimal_CUDA_Test_CI |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
1 similar comment
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
This eliminates the using of staging buffers when uploading data from CPU to GPU for UMA. The data is directly copied to the GPU buffer. The major challenge of enabling this feature is to avoid waiting for the mapping of the dest GPU buffer. The idea is to map the dest GPU buffers in advance, so that when the uploading starts, the dest GPU is always mapped. This is achieved by: