Skip to content

Commit 4fd4215

Browse files
authored
add testing for SPIR-V 1.5 (#2208)
fixes #2140 Adds testing for SPIR-V 1.5 features: * Adds a test for bitcasts between pointers and vectors of integers. Note, SPIR-V 1.5 only supports bitcasts to vectors of two 32-bit integers. Therefore, the SPIR-V 1.5 behavior will only be exercised on devices with 64-bit pointers. The test will run on devices with 32-bit pointers, but will instead bitcast to scalars. * Adds a test for OpGroupNonUniformBroadcast with a dynamic index. Note, this is not an exhaustive test, and only unsigned integer types are tested, to avoid duplicating testing for cl_khr_subgroup_ballot.
1 parent 74cb5cd commit 4fd4215

File tree

6 files changed

+290
-0
lines changed

6 files changed

+290
-0
lines changed

test_conformance/spirv_new/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ set(${MODULE_NAME}_SOURCES
2828
test_op_vector_insert.cpp
2929
test_op_vector_times_scalar.cpp
3030
test_spirv_14.cpp
31+
test_spirv_15.cpp
3132
)
3233

3334
set(TEST_HARNESS_SOURCES
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; SPIR-V
2+
; Version: 1.5
3+
; Reference:
4+
; kernel void non_uniform_broadcast_dynamic_index_test(global uint* dst_base) {
5+
; uint id = get_global_id(0);
6+
; uint index = get_group_id(0);
7+
; uint value = sub_group_non_uniform_broadcast(id, index);
8+
; dst_base[id] = value;
9+
; }
10+
OpCapability Addresses
11+
OpCapability Kernel
12+
OpCapability GroupNonUniformBallot
13+
OpMemoryModel Physical32 OpenCL
14+
OpEntryPoint Kernel %kernel "non_uniform_broadcast_dynamic_index_test" %pglobalid %pgroupid
15+
OpDecorate %pglobalid BuiltIn GlobalInvocationId
16+
OpDecorate %pgroupid BuiltIn WorkgroupId
17+
%uint = OpTypeInt 32 0
18+
%sg_scope = OpConstant %uint 3
19+
%uint3 = OpTypeVector %uint 3
20+
%void = OpTypeVoid
21+
%iptr_uint3 = OpTypePointer Input %uint3
22+
%gptr_uint = OpTypePointer CrossWorkgroup %uint
23+
%kernel_sig = OpTypeFunction %void %gptr_uint
24+
%pglobalid = OpVariable %iptr_uint3 Input
25+
%pgroupid = OpVariable %iptr_uint3 Input
26+
%kernel = OpFunction %void None %kernel_sig
27+
%dst_base = OpFunctionParameter %gptr_uint
28+
%entry = OpLabel
29+
%globalid = OpLoad %uint3 %pglobalid Aligned 32
30+
%id = OpCompositeExtract %uint %globalid 0
31+
%groupid = OpLoad %uint3 %pgroupid Aligned 32
32+
%index = OpCompositeExtract %uint %groupid 0
33+
%value = OpGroupNonUniformBroadcast %uint %sg_scope %id %index
34+
%dst = OpInBoundsPtrAccessChain %gptr_uint %dst_base %id
35+
OpStore %dst %value
36+
OpReturn
37+
OpFunctionEnd
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; SPIR-V
2+
; Version: 1.5
3+
; Reference:
4+
; kernel void non_uniform_broadcast_dynamic_index_test(global uint* dst_base) {
5+
; uint id = get_global_id(0);
6+
; uint index = get_group_id(0);
7+
; uint value = sub_group_non_uniform_broadcast(id, index);
8+
; dst_base[id] = value;
9+
; }
10+
OpCapability Addresses
11+
OpCapability Kernel
12+
OpCapability Int64
13+
OpCapability GroupNonUniformBallot
14+
OpMemoryModel Physical64 OpenCL
15+
OpEntryPoint Kernel %kernel "non_uniform_broadcast_dynamic_index_test" %pglobalid %pgroupid
16+
OpDecorate %pglobalid BuiltIn GlobalInvocationId
17+
OpDecorate %pgroupid BuiltIn WorkgroupId
18+
%uint = OpTypeInt 32 0
19+
%sg_scope = OpConstant %uint 3
20+
%ulong = OpTypeInt 64 0
21+
%ulong3 = OpTypeVector %ulong 3
22+
%void = OpTypeVoid
23+
%iptr_ulong3 = OpTypePointer Input %ulong3
24+
%gptr_uint = OpTypePointer CrossWorkgroup %uint
25+
%kernel_sig = OpTypeFunction %void %gptr_uint
26+
%pglobalid = OpVariable %iptr_ulong3 Input
27+
%pgroupid = OpVariable %iptr_ulong3 Input
28+
%kernel = OpFunction %void None %kernel_sig
29+
%dst_base = OpFunctionParameter %gptr_uint
30+
%entry = OpLabel
31+
%globalid = OpLoad %ulong3 %pglobalid Aligned 32
32+
%globalid0 = OpCompositeExtract %ulong %globalid 0
33+
%id = OpUConvert %uint %globalid0
34+
%groupid = OpLoad %ulong3 %pgroupid Aligned 32
35+
%groupid0 = OpCompositeExtract %ulong %groupid 0
36+
%index = OpUConvert %uint %groupid0
37+
%value = OpGroupNonUniformBroadcast %uint %sg_scope %id %index
38+
%dst = OpInBoundsPtrAccessChain %gptr_uint %dst_base %globalid0
39+
OpStore %dst %value
40+
OpReturn
41+
OpFunctionEnd
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; SPIR-V
2+
; Version: 1.5
3+
OpCapability Addresses
4+
OpCapability Kernel
5+
OpMemoryModel Physical32 OpenCL
6+
OpEntryPoint Kernel %kernel "ptr_bitcast_test"
7+
%uint = OpTypeInt 32 0
8+
%void = OpTypeVoid
9+
%pptr_int = OpTypePointer Function %uint
10+
%gptr_uint = OpTypePointer CrossWorkgroup %uint
11+
%kernel_sig = OpTypeFunction %void %gptr_uint %gptr_uint
12+
%uint_42 = OpConstant %uint 42
13+
%kernel = OpFunction %void None %kernel_sig
14+
%dst_uint0 = OpFunctionParameter %gptr_uint
15+
%dst_uint1 = OpFunctionParameter %gptr_uint
16+
%entry = OpLabel
17+
%pvalue = OpVariable %pptr_int Function %uint_42
18+
%uint_ptr = OpBitcast %uint %pvalue
19+
OpStore %dst_uint0 %uint_ptr
20+
OpStore %dst_uint1 %uint_ptr
21+
OpReturn
22+
OpFunctionEnd
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; SPIR-V
2+
; Version: 1.5
3+
OpCapability Addresses
4+
OpCapability Kernel
5+
OpCapability Int64
6+
OpMemoryModel Physical64 OpenCL
7+
OpEntryPoint Kernel %kernel "ptr_bitcast_test"
8+
%uint = OpTypeInt 32 0
9+
%ulong = OpTypeInt 64 0
10+
%uint2 = OpTypeVector %uint 2
11+
%void = OpTypeVoid
12+
%pptr_int = OpTypePointer Function %uint
13+
%gptr_ulong = OpTypePointer CrossWorkgroup %ulong
14+
%gptr_uint2 = OpTypePointer CrossWorkgroup %uint2
15+
%kernel_sig = OpTypeFunction %void %gptr_ulong %gptr_uint2
16+
%uint_42 = OpConstant %uint 42
17+
%kernel = OpFunction %void None %kernel_sig
18+
%dst_ulong = OpFunctionParameter %gptr_ulong
19+
%dst_uint2 = OpFunctionParameter %gptr_uint2
20+
%entry = OpLabel
21+
%pvalue = OpVariable %pptr_int Function %uint_42
22+
%ulong_ptr = OpBitcast %ulong %pvalue
23+
OpStore %dst_ulong %ulong_ptr
24+
%uint2_ptr = OpBitcast %uint2 %pvalue
25+
OpStore %dst_uint2 %uint2_ptr
26+
OpReturn
27+
OpFunctionEnd
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
//
2+
// Copyright (c) 2024 The Khronos Group Inc.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
17+
#include "testBase.h"
18+
#include "spirvInfo.hpp"
19+
#include "types.hpp"
20+
21+
#include <algorithm>
22+
#include <cinttypes>
23+
#include <vector>
24+
25+
REGISTER_TEST(spirv15_ptr_bitcast)
26+
{
27+
if (!is_spirv_version_supported(device, "SPIR-V_1.5"))
28+
{
29+
log_info("SPIR-V 1.5 not supported; skipping tests.\n");
30+
return TEST_SKIPPED_ITSELF;
31+
}
32+
33+
cl_int error = CL_SUCCESS;
34+
35+
cl_uint address_bits;
36+
error = clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(cl_uint),
37+
&address_bits, NULL);
38+
SPIRV_CHECK_ERROR(error, "Failed to get address bits");
39+
40+
clProgramWrapper prog;
41+
error = get_program_with_il(prog, device, context, "spv1.5/ptr_bitcast");
42+
SPIRV_CHECK_ERROR(error, "Failed to compile spv program");
43+
44+
clKernelWrapper kernel = clCreateKernel(prog, "ptr_bitcast_test", &error);
45+
SPIRV_CHECK_ERROR(error, "Failed to create spv kernel");
46+
47+
cl_ulong result_ulong =
48+
address_bits == 32 ? 0xAAAAAAAAUL : 0xAAAAAAAAAAAAAAAAUL;
49+
cl_ulong result_uint2 =
50+
address_bits == 32 ? 0x55555555UL : 0x5555555555555555UL;
51+
52+
clMemWrapper dst_ulong =
53+
clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
54+
sizeof(result_ulong), &result_ulong, &error);
55+
SPIRV_CHECK_ERROR(error, "Failed to create dst_ulong buffer");
56+
57+
clMemWrapper dst_uint2 =
58+
clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
59+
sizeof(result_uint2), &result_uint2, &error);
60+
SPIRV_CHECK_ERROR(error, "Failed to create dst_uint2 buffer");
61+
62+
error |= clSetKernelArg(kernel, 0, sizeof(dst_ulong), &dst_ulong);
63+
error |= clSetKernelArg(kernel, 1, sizeof(dst_uint2), &dst_uint2);
64+
SPIRV_CHECK_ERROR(error, "Failed to set kernel args");
65+
66+
size_t global = 1;
67+
error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, NULL, 0,
68+
NULL, NULL);
69+
SPIRV_CHECK_ERROR(error, "Failed to enqueue kernel");
70+
71+
error =
72+
clEnqueueReadBuffer(queue, dst_ulong, CL_TRUE, 0, sizeof(result_ulong),
73+
&result_ulong, 0, NULL, NULL);
74+
SPIRV_CHECK_ERROR(error, "Unable to read dst_ulong buffer");
75+
76+
error =
77+
clEnqueueReadBuffer(queue, dst_uint2, CL_TRUE, 0, sizeof(result_uint2),
78+
&result_uint2, 0, NULL, NULL);
79+
SPIRV_CHECK_ERROR(error, "Unable to read dst_uint2 buffer");
80+
81+
if (result_ulong != result_uint2)
82+
{
83+
log_error("Results mismatch! ulong = 0x%016" PRIx64
84+
" vs. uint2 = 0x%016" PRIx64 "\n",
85+
result_ulong, result_uint2);
86+
return TEST_FAIL;
87+
}
88+
89+
return TEST_PASS;
90+
}
91+
92+
REGISTER_TEST(spirv15_non_uniform_broadcast)
93+
{
94+
if (!is_spirv_version_supported(device, "SPIR-V_1.5"))
95+
{
96+
log_info("SPIR-V 1.5 not supported; skipping tests.\n");
97+
return TEST_SKIPPED_ITSELF;
98+
}
99+
100+
if (!is_extension_available(device, "cl_khr_subgroup_ballot"))
101+
{
102+
log_info("cl_khr_subgroup_ballot is not supported; skipping tests.\n");
103+
return TEST_SKIPPED_ITSELF;
104+
}
105+
106+
cl_int error = CL_SUCCESS;
107+
108+
clProgramWrapper prog;
109+
error = get_program_with_il(prog, device, context,
110+
"spv1.5/non_uniform_broadcast_dynamic_index");
111+
SPIRV_CHECK_ERROR(error, "Failed to compile spv program");
112+
113+
clKernelWrapper kernel = clCreateKernel(
114+
prog, "non_uniform_broadcast_dynamic_index_test", &error);
115+
SPIRV_CHECK_ERROR(error, "Failed to create spv kernel");
116+
117+
// Get the local work-group size for one sub-group per work-group.
118+
size_t lws = 0;
119+
size_t one = 1;
120+
error = clGetKernelSubGroupInfo(
121+
kernel, device, CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT,
122+
sizeof(size_t), &one, sizeof(size_t), &lws, NULL);
123+
SPIRV_CHECK_ERROR(error, "Failed to get local work size for one sub-group");
124+
125+
// Use four work-groups, unless the local-group size is less than four.
126+
size_t wgcount = std::min<size_t>(lws, 4);
127+
size_t gws = wgcount * lws;
128+
clMemWrapper dst = clCreateBuffer(context, CL_MEM_READ_WRITE,
129+
sizeof(cl_int) * gws, NULL, &error);
130+
SPIRV_CHECK_ERROR(error, "Failed to create dst buffer");
131+
132+
error |= clSetKernelArg(kernel, 0, sizeof(dst), &dst);
133+
SPIRV_CHECK_ERROR(error, "Failed to set kernel args");
134+
135+
error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &gws, &lws, 0, NULL,
136+
NULL);
137+
SPIRV_CHECK_ERROR(error, "Failed to enqueue kernel");
138+
139+
std::vector<cl_int> results(gws);
140+
error = clEnqueueReadBuffer(queue, dst, CL_TRUE, 0, sizeof(cl_int) * gws,
141+
results.data(), 0, NULL, NULL);
142+
SPIRV_CHECK_ERROR(error, "Unable to read destination buffer");
143+
144+
// Remember: the test kernel did:
145+
// sub_group_non_uniform_broadcast(get_global_id(0), get_group_id(0))
146+
for (size_t g = 0; g < wgcount; g++)
147+
{
148+
for (size_t l = 0; l < lws; l++)
149+
{
150+
size_t index = g * lws + l;
151+
size_t check = g * lws + g;
152+
if (results[index] != static_cast<cl_int>(check))
153+
{
154+
log_error("Result mismatch at index %zu! Got %d, Wanted %zu\n",
155+
index, results[index], check);
156+
return TEST_FAIL;
157+
}
158+
}
159+
}
160+
161+
return TEST_PASS;
162+
}

0 commit comments

Comments
 (0)