add SPIR-V 1.4 testing for various miscellaneous additions (#2122)

This PR adds targeted testing for a few remaining miscellaneous SPIR-V
1.4 features:

* Variables in the Function storage class can have a NonWriteable
decoration.
* OpCopyMemorySized can have two optional memory operands.
* OpSelect can have composite operands that are not vectors.
This commit is contained in:
Ben Ashbaugh
2024-11-11 12:39:00 -08:00
committed by GitHub
parent 10130a1261
commit b149060d52
7 changed files with 349 additions and 0 deletions

View File

@@ -352,3 +352,162 @@ TEST_SPIRV_FUNC(spirv14_usersemantic_memberdecoratestring)
return test_usersemantic_decoration(deviceID, context, queue, true);
}
TEST_SPIRV_FUNC(spirv14_nonwriteable_decoration)
{
if (!is_spirv_version_supported(deviceID, "SPIR-V_1.4"))
{
log_info("SPIR-V 1.4 not supported; skipping tests.\n");
return TEST_SKIPPED_ITSELF;
}
cl_int error = CL_SUCCESS;
clProgramWrapper prog;
error = get_program_with_il(
prog, deviceID, context,
"spv1.4/nonwriteable_decoration_function_storage_class");
SPIRV_CHECK_ERROR(error, "Failed to compile spv program");
clKernelWrapper kernel = clCreateKernel(prog, "nonwriteable_test", &error);
SPIRV_CHECK_ERROR(error, "Failed to create spv kernel");
int result = 0;
clMemWrapper dst = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(result), nullptr, &error);
SPIRV_CHECK_ERROR(error, "Failed to create dst buffer");
error |= clSetKernelArg(kernel, 0, sizeof(dst), &dst);
SPIRV_CHECK_ERROR(error, "Failed to set kernel args");
size_t global = 1;
error = clEnqueueNDRangeKernel(queue, kernel, 1, nullptr, &global, nullptr,
0, nullptr, nullptr);
SPIRV_CHECK_ERROR(error, "Failed to enqueue kernel");
error = clEnqueueReadBuffer(queue, dst, CL_TRUE, 0, sizeof(result), &result,
0, nullptr, nullptr);
SPIRV_CHECK_ERROR(error, "Unable to read destination buffer");
int expected = 42;
if (result != expected)
{
log_error("Result mismatch! Got %d, Wanted %d\n", result, expected);
return TEST_FAIL;
}
return TEST_PASS;
}
TEST_SPIRV_FUNC(spirv14_copymemory_memory_operands)
{
if (!is_spirv_version_supported(deviceID, "SPIR-V_1.4"))
{
log_info("SPIR-V 1.4 not supported; skipping tests.\n");
return TEST_SKIPPED_ITSELF;
}
cl_int error = CL_SUCCESS;
clProgramWrapper prog;
error = get_program_with_il(prog, deviceID, context,
"spv1.4/copymemory_memory_operands");
SPIRV_CHECK_ERROR(error, "Failed to compile spv program");
clKernelWrapper kernel = clCreateKernel(prog, "copymemory_test", &error);
SPIRV_CHECK_ERROR(error, "Failed to create spv kernel");
std::vector<int> results(6);
clMemWrapper dst =
clCreateBuffer(context, CL_MEM_READ_WRITE,
results.size() * sizeof(results[0]), nullptr, &error);
SPIRV_CHECK_ERROR(error, "Failed to create dst buffer");
error |= clSetKernelArg(kernel, 0, sizeof(dst), &dst);
SPIRV_CHECK_ERROR(error, "Failed to set kernel args");
size_t global = 1;
error = clEnqueueNDRangeKernel(queue, kernel, 1, nullptr, &global, nullptr,
0, nullptr, nullptr);
SPIRV_CHECK_ERROR(error, "Failed to enqueue kernel");
error = clEnqueueReadBuffer(queue, dst, CL_TRUE, 0,
results.size() * sizeof(results[0]),
results.data(), 0, nullptr, nullptr);
SPIRV_CHECK_ERROR(error, "Unable to read destination buffer");
const int expected = 42;
for (auto result : results)
{
if (result != expected)
{
log_error("Result mismatch! Got %d, Wanted %d\n", result,
expected);
return TEST_FAIL;
}
}
return TEST_PASS;
}
TEST_SPIRV_FUNC(spirv14_select_composite)
{
constexpr size_t global_size = 16;
if (!is_spirv_version_supported(deviceID, "SPIR-V_1.4"))
{
log_info("SPIR-V 1.4 not supported; skipping tests.\n");
return TEST_SKIPPED_ITSELF;
}
cl_int error = CL_SUCCESS;
clProgramWrapper prog;
error =
get_program_with_il(prog, deviceID, context, "spv1.4/select_struct");
SPIRV_CHECK_ERROR(error, "Failed to compile spv program");
clKernelWrapper kernel = clCreateKernel(prog, "select_struct_test", &error);
SPIRV_CHECK_ERROR(error, "Failed to create spv kernel");
struct TestStruct
{
cl_int i;
cl_float f;
};
std::vector<TestStruct> results(global_size);
clMemWrapper dst =
clCreateBuffer(context, CL_MEM_READ_WRITE,
results.size() * sizeof(results[0]), nullptr, &error);
SPIRV_CHECK_ERROR(error, "Failed to create dst buffer");
error |= clSetKernelArg(kernel, 0, sizeof(dst), &dst);
SPIRV_CHECK_ERROR(error, "Failed to set kernel args");
error = clEnqueueNDRangeKernel(queue, kernel, 1, nullptr, &global_size,
nullptr, 0, nullptr, nullptr);
SPIRV_CHECK_ERROR(error, "Failed to enqueue kernel");
error = clEnqueueReadBuffer(queue, dst, CL_TRUE, 0,
results.size() * sizeof(results[0]),
results.data(), 0, nullptr, nullptr);
SPIRV_CHECK_ERROR(error, "Unable to read destination buffer");
const TestStruct struct_a{ 1024, 3.1415f };
const TestStruct struct_b{ 2048, 2.7128f };
for (size_t i = 0; i < global_size; i++)
{
const TestStruct& expected = (i & 1) ? struct_a : struct_b;
if (results[i].i != expected.i || results[i].f != expected.f)
{
log_error("Result mismatch at index %zu! Got {%d, %f}, Wanted "
"{%d, %f}\n",
i, results[i].i, results[i].f, expected.i, expected.f);
return TEST_FAIL;
}
}
return TEST_PASS;
}