test(agc-driver): add a split-lane case with per-lane operands to the LDS mixed-width atomic test
On RADV the race between ds_add_u64 under the workgroup lock and a concurrent ds_add_u32 only shows when the lanes get their operands from per-lane buffer loads: with v_mov_b32 constants or loads from one address no increment is lost there. The new case has the split-lane kernel's parity split and loads each lane's (0xffffffff, 0, 1, 0) row from the input buffer at tid * 16 with buffer_load_dwordx4, so the input buffer now holds 256 rows. With SpirvMemoryInstructions.cpp reverted it fails on RADV and on the RTX 3080; with the change it passes on both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fnrk5Dazjb2tLooVSpdRQq
This commit is contained in:
parent
5253c499dc
commit
60301adc6d
|
|
@ -21,7 +21,14 @@ constexpr std::uint32_t Iterations = 16;
|
|||
constexpr std::uint32_t Repeats = 32;
|
||||
constexpr std::uint32_t LdsDwords = 4;
|
||||
alignas(256) std::array<std::uint32_t, Threads * 2> Output{};
|
||||
alignas(256) std::array<std::uint32_t, 4> Unused{};
|
||||
alignas(256) std::array<std::uint32_t, Threads * 4> Input = [] {
|
||||
std::array<std::uint32_t, Threads * 4> rows{};
|
||||
for (std::uint32_t tid = 0; tid < Threads; ++tid) {
|
||||
rows[tid * 4u] = 0xffffffffu;
|
||||
rows[tid * 4u + 2u] = 1u;
|
||||
}
|
||||
return rows;
|
||||
}();
|
||||
|
||||
template<std::uint32_t Count, std::size_t Head, std::size_t Body, std::size_t Tail>
|
||||
constexpr auto Unrolled(const std::array<std::uint32_t, Head>& head, const std::array<std::uint32_t, Body>& body, const std::array<std::uint32_t, Tail>& tail) {
|
||||
|
|
@ -125,6 +132,37 @@ alignas(256) constexpr auto ParityCode = Unrolled<1>(
|
|||
0xbf810000,
|
||||
}));
|
||||
|
||||
alignas(256) constexpr auto LoadedParityCode = Unrolled<1>(
|
||||
std::to_array<std::uint32_t>({
|
||||
0x34100083,
|
||||
0x340a0084,
|
||||
0x7e020280,
|
||||
0xe0381000, 0x80000c05,
|
||||
0x7e0c0280,
|
||||
0x7e0e0280,
|
||||
0xd9340000, 0x00000601,
|
||||
0xbf8c0070,
|
||||
0xbf8a0000,
|
||||
0xbe89037e,
|
||||
}),
|
||||
std::to_array<std::uint32_t>({
|
||||
0xbefe03ff, 0x55555555,
|
||||
0xd9000000, 0x00000c01,
|
||||
0xbf8cc07f,
|
||||
0xbefe03ff, 0xaaaaaaaa,
|
||||
0xd8000004, 0x00000e01,
|
||||
0xbf8cc07f,
|
||||
}),
|
||||
std::to_array<std::uint32_t>({
|
||||
0xbefe0309,
|
||||
0xbf8cc07f,
|
||||
0xbf8a0000,
|
||||
0xd9d80000, 0x0a000001,
|
||||
0xbf8cc07f,
|
||||
0xe0741000, 0x80010a08,
|
||||
0xbf810000,
|
||||
}));
|
||||
|
||||
std::array<std::uint32_t, 4> BufferDescriptor(const void* data, std::uint32_t bytes) {
|
||||
const auto address = reinterpret_cast<std::uintptr_t>(data);
|
||||
return {static_cast<std::uint32_t>(address), static_cast<std::uint32_t>((address >> 32u) & 0xffffu), bytes, 0x31016facu};
|
||||
|
|
@ -146,7 +184,7 @@ void Check(const char* name, std::uint64_t operations, std::uint32_t run) {
|
|||
|
||||
void Run(AgcDriver::VulkanDevice& device, std::span<const std::uint32_t> code, const char* name, std::uint64_t operations, std::uint32_t repeats) {
|
||||
std::vector<std::uint32_t> userData(8, 0u);
|
||||
const auto input = BufferDescriptor(Unused.data(), static_cast<std::uint32_t>(Unused.size() * 4u));
|
||||
const auto input = BufferDescriptor(Input.data(), static_cast<std::uint32_t>(Input.size() * 4u));
|
||||
const auto output = BufferDescriptor(Output.data(), static_cast<std::uint32_t>(Output.size() * 4u));
|
||||
std::copy(input.begin(), input.end(), userData.begin());
|
||||
std::copy(output.begin(), output.end(), userData.begin() + 4);
|
||||
|
|
@ -177,6 +215,7 @@ int main() {
|
|||
Run(*device, UniformCode, "uniform", static_cast<std::uint64_t>(Threads) * Iterations, 1);
|
||||
Run(*device, DivergentCode, "divergent", static_cast<std::uint64_t>(Threads) / 2u * Iterations, 1);
|
||||
Run(*device, ParityCode, "split lanes", Threads / 2u, Repeats);
|
||||
Run(*device, LoadedParityCode, "split lanes with per-lane operands", Threads / 2u, Repeats);
|
||||
std::puts("lds mixed width atomics tests passed");
|
||||
return 0;
|
||||
} catch (const std::exception& error) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue