Fix data race in mutable command buffer simultaneous execution test (#2434)

Prior to this change, both `clEnqueueReadBuffer` calls before and after
updating the command buffer were writing to the same `output_buffer`,
causing a data race condition and the first call's result to be
overwritten. This commit introduces separate destination vectors
(`output_buffer` and `updated_output_buffer`) for these operations and
verifies both results independently to ensure test integrity.
This commit is contained in:
Yilong Guo
2025-08-06 00:13:05 +08:00
committed by GitHub
parent dacb944cf3
commit e7e753f1a9

View File

@@ -297,6 +297,7 @@ struct SimultaneousMutableDispatchTest : public BasicMutableCommandBufferTest
{ {
cl_int offset; cl_int offset;
std::vector<cl_int> output_buffer; std::vector<cl_int> output_buffer;
std::vector<cl_int> updated_output_buffer;
// 0:user event, 1:offset-buffer fill event, 2:kernel done event // 0:user event, 1:offset-buffer fill event, 2:kernel done event
clEventWrapper wait_events[3]; clEventWrapper wait_events[3];
}; };
@@ -375,7 +376,7 @@ struct SimultaneousMutableDispatchTest : public BasicMutableCommandBufferTest
error = clEnqueueReadBuffer(work_queue, new_out_mem, CL_FALSE, error = clEnqueueReadBuffer(work_queue, new_out_mem, CL_FALSE,
pd.offset * sizeof(cl_int), data_size(), pd.offset * sizeof(cl_int), data_size(),
pd.output_buffer.data(), 1, pd.updated_output_buffer.data(), 1,
&pd.wait_events[2], nullptr); &pd.wait_events[2], nullptr);
test_error(error, "clEnqueueReadBuffer failed"); test_error(error, "clEnqueueReadBuffer failed");
@@ -390,8 +391,10 @@ struct SimultaneousMutableDispatchTest : public BasicMutableCommandBufferTest
cl_int offset = static_cast<cl_int>(num_elements); cl_int offset = static_cast<cl_int>(num_elements);
std::vector<SimulPassData> simul_passes = { std::vector<SimulPassData> simul_passes = {
{ 0, std::vector<cl_int>(num_elements) }, { 0, std::vector<cl_int>(num_elements),
{ offset, std::vector<cl_int>(num_elements) } std::vector<cl_int>(num_elements) },
{ offset, std::vector<cl_int>(num_elements),
std::vector<cl_int>(num_elements) }
}; };
for (auto&& pass : simul_passes) for (auto&& pass : simul_passes)
@@ -409,13 +412,26 @@ struct SimultaneousMutableDispatchTest : public BasicMutableCommandBufferTest
test_error(error, "clFinish failed"); test_error(error, "clFinish failed");
// verify the result buffers // verify the result buffers
for (auto&& pass : simul_passes) auto& first_pass_output = simul_passes[0].output_buffer;
auto& first_pass_updated_output = simul_passes[0].updated_output_buffer;
auto& second_pass_output = simul_passes[1].output_buffer;
auto& second_pass_updated_output =
simul_passes[1].updated_output_buffer;
for (size_t i = 0; i < num_elements; i++)
{ {
auto& res_data = pass.output_buffer; // First pass:
for (size_t i = 0; i < num_elements; i++) // Before updating, out_mem is copied from in_mem (pattern_pri)
{ CHECK_VERIFICATION_ERROR(pattern_pri, first_pass_output[i], i);
CHECK_VERIFICATION_ERROR(pattern_pri, res_data[i], i); // After updating, new_out_mem is copied from in_mem (pattern_pri)
} CHECK_VERIFICATION_ERROR(pattern_pri, first_pass_updated_output[i],
i);
// Second pass:
// Before updating, out_mem is filled with overwritten_pattern
CHECK_VERIFICATION_ERROR(overwritten_pattern, second_pass_output[i],
i);
// After updating, new_out_mem is copied from in_mem (pattern_pri)
CHECK_VERIFICATION_ERROR(pattern_pri, second_pass_updated_output[i],
i);
} }
return CL_SUCCESS; return CL_SUCCESS;