Skip to content

Commit 7754797

Browse files
committed
[ET-VK] 5/n Split dispatches between multiple command buffers. Track previously submitted command buffers in context and add function to execute all previous command buffers.
The diff adds changes to store command buffers submitted with final_use set to false. Storing these buffers is necessary for `execute()` function. Since, `encode_execute()` function is typically called once but `execute()` can be called multiple times, `submit_all_non_final_cmds` function is added so all recorded command buffers with `final_use = False` can be called multiple times in `execute()`. #### Key Changes * Added a flag `execute_pending_first_submission` to the `ComputeGraph` class to track whether execute nodes have been freshly encoded and need to be submitted first. * Added a new function `submit_all_non_final_cmds` to the `Context` class, which submits all non-final command buffers to the GPU. * Modified the `submit_cmd_to_gpu` function to add the submitted command buffer to the `non_final_cmds_` list if it's not marked as final use. * Updated the `execute` function in `ComputeGraph` to submit all non-final command buffers before executing the graph. Differential Revision: [D78360038](https://our.internmc.facebook.com/intern/diff/D78360038/) ghstack-source-id: 296432758 Pull Request resolved: #12527
1 parent a88956d commit 7754797

File tree

4 files changed

+51
-4
lines changed

4 files changed

+51
-4
lines changed

backends/vulkan/runtime/api/Context.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,31 @@ void Context::submit_cmd_to_gpu(VkFence fence_handle, const bool final_use) {
214214

215215
submit_count_ = 0u;
216216
}
217+
218+
if (!final_use) {
219+
non_final_cmds_.emplace_back(std::move(cmd_));
220+
}
221+
}
222+
223+
void Context::submit_all_non_final_cmds(VkFence fence_handle) {
224+
VkSemaphore local_prev_semaphore = VK_NULL_HANDLE;
225+
226+
for (uint32_t i = 0; i < non_final_cmds_.size(); i++) {
227+
auto& cmd = non_final_cmds_[i];
228+
VkSemaphore wait_semaphore = local_prev_semaphore;
229+
VkSemaphore signal_semaphore = cmd.get_signal_semaphore();
230+
local_prev_semaphore = signal_semaphore;
231+
232+
if (cmd) {
233+
cmd.end();
234+
adapter_p_->submit_cmd(
235+
queue_,
236+
cmd.get_submit_handle(false),
237+
i == (non_final_cmds_.size() - 1) ? fence_handle : VK_NULL_HANDLE,
238+
wait_semaphore,
239+
signal_semaphore);
240+
}
241+
}
217242
}
218243

219244
void Context::flush() {
@@ -222,6 +247,11 @@ void Context::flush() {
222247
command_pool_.flush();
223248
descriptor_pool_.flush();
224249

250+
for (auto& cmd : non_final_cmds_) {
251+
cmd.invalidate();
252+
}
253+
non_final_cmds_.clear();
254+
225255
// If there is an existing command buffer, invalidate it
226256
if (cmd_) {
227257
cmd_.invalidate();

backends/vulkan/runtime/api/Context.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ class Context final {
6868
// Command buffers submission
6969
std::mutex cmd_mutex_;
7070
vkapi::CommandBuffer cmd_;
71+
// List of submitted command buffers, not marked as final use.
72+
std::vector<vkapi::CommandBuffer> non_final_cmds_;
7173
// Semaphore for the previously submitted command buffer, if any
7274
VkSemaphore prev_semaphore_;
7375
uint32_t submit_count_;
@@ -230,6 +232,8 @@ class Context final {
230232
VkFence fence_handle = VK_NULL_HANDLE,
231233
const bool final_use = false);
232234

235+
void submit_all_non_final_cmds(VkFence fence_handle = VK_NULL_HANDLE);
236+
233237
void flush();
234238

235239
#ifdef VULKAN_DEBUG

backends/vulkan/runtime/graph/ComputeGraph.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -815,13 +815,22 @@ void ComputeGraph::encode_execute() {
815815
for (std::unique_ptr<ExecuteNode>& node : execute_nodes_) {
816816
node->encode(this);
817817
}
818+
819+
// Indicate execute nodes have been freshly encoded and needs to be submitted
820+
// first
821+
execute_pending_first_submission = true;
818822
}
819823

820824
void ComputeGraph::execute() {
821-
vkapi::VulkanFence fence = context_->fences().get_fence();
822-
context_->submit_cmd_to_gpu(fence.get_submit_handle());
823-
fence.wait();
824-
context_->fences().return_fence(fence);
825+
if (execute_pending_first_submission) {
826+
submit_current_cmd_and_wait(/*final_use=*/false);
827+
execute_pending_first_submission = false;
828+
} else {
829+
vkapi::VulkanFence fence = context_->fences().get_fence();
830+
context_->submit_all_non_final_cmds(fence.get_submit_handle());
831+
fence.wait();
832+
context_->fences().return_fence(fence);
833+
}
825834
execute_count_++;
826835
}
827836

backends/vulkan/runtime/graph/ComputeGraph.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ class ComputeGraph final {
198198
// current Context's command buffer is submitted now.
199199
size_t staging_nbytes_in_cmd_ = 0;
200200

201+
// Flag to indicate if execute nodes have been freshly encoded and have not
202+
// been submitted yet.
203+
bool execute_pending_first_submission = true;
204+
201205
public:
202206
//
203207
// Accessors

0 commit comments

Comments
 (0)