Skip to content

Commit c9fe9ca

Browse files
authored
Fix subgroup_arithmetic benchmark for flexible subgroup sizes (#46)
Set up source data values according to the subgroupSize device property. But inside the shader, measure the actual subgroup size, and pass it out of the shader. Then, adjust the verification logic to take that actual subgroup size into account. This still does the same amount of arithmetic as in the original code, and it does it in the same shape. Fixes: #45
1 parent 90866c8 commit c9fe9ca

3 files changed

Lines changed: 27 additions & 16 deletions

File tree

benchmarks/subgroup/subgroup_arithmetic_intrinsic.glsl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#extension GL_KHR_shader_subgroup_basic : enable
1818
#extension GL_KHR_shader_subgroup_arithmetic : enable
19+
#extension GL_KHR_shader_subgroup_ballot : enable
1920

2021
layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
2122

@@ -28,12 +29,13 @@ layout(set = 0, binding = 0) buffer InputBuffer {
2829
// Use an output buffer of the same size to make sure we use each element
2930
// in the input buffer.
3031
layout(set = 0, binding = 1) buffer OutputBuffer {
32+
uint actual_subgroup_size;
3133
float output_values[kArraySize];
3234
};
3335

3436
void main() {
3537
uint index = gl_GlobalInvocationID.x;
36-
uint count = gl_SubgroupSize;
38+
uint subgroup_size = subgroupBallotBitCount(subgroupBallot(true));
3739
float value = 0.f;
3840

3941
#ifdef ARITHMETIC_ADD
@@ -48,6 +50,7 @@ void main() {
4850
value = input_values[index];
4951
}
5052

53+
actual_subgroup_size = subgroup_size;
5154
output_values[index] = value;
5255
}
5356

benchmarks/subgroup/subgroup_arithmetic_loop.glsl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#version 450 core
1616

1717
#extension GL_KHR_shader_subgroup_basic : enable
18+
#extension GL_KHR_shader_subgroup_ballot : enable
1819

1920
layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
2021

@@ -27,12 +28,14 @@ layout(set = 0, binding = 0) buffer InputBuffer {
2728
// Use an output buffer of the same size to make sure we use each element
2829
// in the input buffer.
2930
layout(set = 0, binding = 1) buffer OutputBuffer {
31+
uint actual_subgroup_size;
3032
float output_values[kArraySize];
3133
};
3234

3335
void main() {
3436
uint index = gl_GlobalInvocationID.x;
35-
uint count = gl_SubgroupSize;
37+
uint subgroup_size = subgroupBallotBitCount(subgroupBallot(true));
38+
uint count = subgroup_size;
3639
float value = 0.f;
3740

3841
if (subgroupElect()) {
@@ -50,5 +53,6 @@ void main() {
5053
value = input_values[index];
5154
}
5255

56+
actual_subgroup_size = subgroup_size;
5357
output_values[index] = value;
5458
}

benchmarks/subgroup/subgroup_arithmetic_main.cc

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static void CalculateSubgroupArithmetic(
7474
::benchmark::State &state, ::uvkc::vulkan::Device *device,
7575
const ::uvkc::benchmark::LatencyMeasure *latency_measure,
7676
const uint32_t *code, size_t code_num_words, int num_elements,
77-
uint32_t subgroup_size, Arithmetic arith_op) {
77+
uint32_t proposed_subgroup_size, Arithmetic arith_op) {
7878
size_t buffer_num_bytes = num_elements * sizeof(float);
7979

8080
//===-------------------------------------------------------------------===/
@@ -116,10 +116,11 @@ static void CalculateSubgroupArithmetic(
116116
//===-------------------------------------------------------------------===/
117117

118118
// +: fill the whole buffer as 1.0f.
119-
// *: fill with alternating subgroup_size and (1 / subgroup_size).
119+
// *: fill with alternating values of proposed_subgroup_size and
120+
// (1 / proposed_subgroup_size).
120121
BM_CHECK_OK(::uvkc::benchmark::SetDeviceBufferViaStagingBuffer(
121122
device, src_buffer.get(), buffer_num_bytes,
122-
[arith_op, subgroup_size](void *ptr, size_t num_bytes) {
123+
[arith_op, proposed_subgroup_size](void *ptr, size_t num_bytes) {
123124
float *src_float_buffer = reinterpret_cast<float *>(ptr);
124125
switch (arith_op) {
125126
case Arithmetic::Add: {
@@ -129,8 +130,8 @@ static void CalculateSubgroupArithmetic(
129130
} break;
130131
case Arithmetic::Mul: {
131132
for (int i = 0; i < num_bytes / sizeof(float); i += 2) {
132-
src_float_buffer[i] = subgroup_size;
133-
src_float_buffer[i + 1] = 1.0f / subgroup_size;
133+
src_float_buffer[i] = proposed_subgroup_size;
134+
src_float_buffer[i + 1] = 1.0f / proposed_subgroup_size;
134135
}
135136
} break;
136137
}
@@ -171,14 +172,17 @@ static void CalculateSubgroupArithmetic(
171172

172173
BM_CHECK_OK(::uvkc::benchmark::GetDeviceBufferViaStagingBuffer(
173174
device, dst_buffer.get(), buffer_num_bytes,
174-
[arith_op, subgroup_size](void *ptr, size_t num_bytes) {
175-
float *dst_float_buffer = reinterpret_cast<float *>(ptr);
175+
[arith_op, proposed_subgroup_size](void *ptr, size_t num_bytes) {
176+
const uint32_t actual_subgroup_size =
177+
reinterpret_cast<uint32_t *>(ptr)[0];
178+
float *dst_float_buffer = reinterpret_cast<float *>(ptr) + 1;
179+
const auto num_floats = (num_bytes / sizeof(float)) - 1;
176180
switch (arith_op) {
177181
case Arithmetic::Add: {
178-
for (int i = 0; i < num_bytes / sizeof(float); ++i) {
182+
for (int i = 0; i < num_floats; ++i) {
179183
float expected_value = 1.0f;
180-
if (i % subgroup_size == 0) {
181-
expected_value = subgroup_size;
184+
if (i % actual_subgroup_size == 0) {
185+
expected_value = actual_subgroup_size;
182186
}
183187

184188
BM_CHECK_EQ(dst_float_buffer[i], expected_value)
@@ -188,14 +192,14 @@ static void CalculateSubgroupArithmetic(
188192
}
189193
} break;
190194
case Arithmetic::Mul: {
191-
for (int i = 0; i < num_bytes / sizeof(float); ++i) {
195+
for (int i = 0; i < num_floats; ++i) {
192196
float expected_value = 0.0f;
193-
if (i % subgroup_size == 0) {
197+
if (i % actual_subgroup_size == 0) {
194198
expected_value = 1.0f;
195199
} else if (i % 2 == 0) {
196-
expected_value = subgroup_size;
200+
expected_value = proposed_subgroup_size;
197201
} else {
198-
expected_value = 1.0f / subgroup_size;
202+
expected_value = 1.0f / proposed_subgroup_size;
199203
}
200204

201205
BM_CHECK_EQ(dst_float_buffer[i], expected_value)

0 commit comments

Comments
 (0)