Skip to content

Commit

Permalink
add SPIR-V version testing (#1861)
Browse files Browse the repository at this point in the history
* basic SPIR-V 1.3 testing support

* updated script to compile for more SPIR-V versions

* switch to general SPIR-V versions test

* update copyright text and fix license

* improve output while test is running

* check for higher SPIR-V versions first

* fix formatting
  • Loading branch information
bashbaug authored Jan 30, 2024
1 parent 8bb89b1 commit d5b7d10
Show file tree
Hide file tree
Showing 18 changed files with 683 additions and 33 deletions.
23 changes: 13 additions & 10 deletions test_common/harness/testHarness.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1196,18 +1196,21 @@ Version get_device_spirv_il_version(cl_device_id device)
ASSERT_SUCCESS(err, "clGetDeviceInfo");
}

if (strstr(str.data(), "SPIR-V_1.0") != NULL)
return Version(1, 0);
else if (strstr(str.data(), "SPIR-V_1.1") != NULL)
return Version(1, 1);
else if (strstr(str.data(), "SPIR-V_1.2") != NULL)
return Version(1, 2);
else if (strstr(str.data(), "SPIR-V_1.3") != NULL)
return Version(1, 3);
// Because this query returns a space-separated list of IL version strings
// we should check for SPIR-V versions in reverse order, to return the
// highest version supported.
if (strstr(str.data(), "SPIR-V_1.5") != NULL)
return Version(1, 5);
else if (strstr(str.data(), "SPIR-V_1.4") != NULL)
return Version(1, 4);
else if (strstr(str.data(), "SPIR-V_1.5") != NULL)
return Version(1, 5);
else if (strstr(str.data(), "SPIR-V_1.3") != NULL)
return Version(1, 3);
else if (strstr(str.data(), "SPIR-V_1.2") != NULL)
return Version(1, 2);
else if (strstr(str.data(), "SPIR-V_1.1") != NULL)
return Version(1, 1);
else if (strstr(str.data(), "SPIR-V_1.0") != NULL)
return Version(1, 0);

throw std::runtime_error(std::string("Unknown SPIR-V version: ")
+ str.data());
Expand Down
58 changes: 37 additions & 21 deletions test_conformance/spirv_new/assemble_spirv.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3

#####################################################################
# Copyright (c) 2020 The Khronos Group Inc. All Rights Reserved.
# Copyright (c) 2020-2023 The Khronos Group Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -30,6 +30,16 @@
import sys
from textwrap import wrap

# sub-directories for specific SPIR-V environments
spirv_envs = [
'', # all files in the root directory are considered SPIR-V 1.0
'spv1.1',
'spv1.2',
'spv1.3',
'spv1.4',
'spv1.5',
'spv1.6',
]

def fatal(message):
"""Print an error message and exit with a non-zero status, to
Expand All @@ -39,7 +49,7 @@ def fatal(message):
sys.exit(1)


def assemble_spirv(asm_dir, bin_dir, spirv_as, verbose):
def assemble_spirv(asm_dir, bin_dir, spirv_as, spirv_env, verbose):
"""Assemble SPIR-V source into binaries."""

if not os.path.exists(bin_dir):
Expand All @@ -57,8 +67,8 @@ def assemble_spirv(asm_dir, bin_dir, spirv_as, verbose):
bin_file = asm_file_root + asm_file_ext.replace('asm', '')
bin_file_path = os.path.join(bin_dir, bin_file)

command = '"{}" --target-env spv1.0 "{}" -o "{}"'.format(
spirv_as, asm_file_path, bin_file_path)
command = '"{}" --target-env "{}" "{}" -o "{}"'.format(
spirv_as, spirv_env, asm_file_path, bin_file_path)
if subprocess.call(command, shell=True) != 0:
assembly_failures = True
print('ERROR: Failure assembling {}: '
Expand All @@ -72,7 +82,7 @@ def assemble_spirv(asm_dir, bin_dir, spirv_as, verbose):
'messages from the assembler, if any.')))


def validate_spirv(bin_dir, spirv_val, verbose):
def validate_spirv(bin_dir, spirv_val, spirv_env, verbose):
"""Validates SPIR-V binaries. Ignores known failures."""

validation_failures = False
Expand All @@ -83,8 +93,8 @@ def validate_spirv(bin_dir, spirv_val, verbose):
if verbose:
print(' Validating {}'.format(bin_file))

command = '"{}" "{}"'.format(
spirv_val, bin_file_path)
command = '"{}" --target-env "{}" "{}"'.format(
spirv_val, spirv_env, bin_file_path)
if subprocess.call(command, shell=True) != 0:
print('ERROR: Failure validating {}: '
'see above output.'.format(
Expand All @@ -95,8 +105,6 @@ def validate_spirv(bin_dir, spirv_val, verbose):
if validation_failures:
fatal('ERROR: Validation failure(s) found. '
'See above for validation output.')
else:
print('All SPIR-V binaries validated successfully.')


def parse_args():
Expand Down Expand Up @@ -144,18 +152,26 @@ def main():

args = parse_args()

print('Assembling SPIR-V source into binaries...')
assemble_spirv(args.source_dir, args.output_dir, args.assembler,
args.verbose)
print('Finished assembling SPIR-V binaries.')
print()

if args.skip_validation:
print('Skipping validation of SPIR-V binaries as requested.')
else:
print('Validating SPIR-V binaries...')
validate_spirv(args.output_dir, args.validator, args.verbose)
print()
for subdir in spirv_envs:
src_dir = os.path.join(args.source_dir, subdir)
out_dir = os.path.join(args.output_dir, subdir)
spirv_env = 'spv1.0' if subdir == '' else subdir
print('Assembling SPIR-V source into binaries for target {}...'.
format(spirv_env))
assemble_spirv(src_dir, out_dir, args.assembler,
spirv_env, args.verbose)
print('Finished assembling SPIR-V binaries.')
print()

if args.skip_validation:
print('Skipping validation of SPIR-V binaries as requested.')
else:
print('Validating SPIR-V binaries for target {}...'.
format(spirv_env))
validate_spirv(out_dir, args.validator,
spirv_env, args.verbose)
print('All SPIR-V binaries validated successfully.')
print()

print('Done.')

Expand Down
15 changes: 13 additions & 2 deletions test_conformance/spirv_new/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ const std::string slash = "/";
#endif

const std::string spvExt = ".spv";
bool gVersionSkip = false;
std::string gAddrWidth = "";
std::string spvBinariesPath = "spirv_bin";
std::string spvBinariesPathArg = "--spirv-binaries-path";

const std::string spvBinariesPathArg = "--spirv-binaries-path";
const std::string spvVersionSkipArg = "--skip-spirv-version-check";

std::vector<unsigned char> readBinary(const char *file_name)
{
Expand Down Expand Up @@ -227,7 +230,10 @@ test_status InitCL(cl_device_id id)

void printUsage() {
log_info("Reading SPIR-V files from default '%s' path.\n", spvBinariesPath.c_str());
log_info("In case you want to set other directory use '%s' argument.\n", spvBinariesPathArg.c_str());
log_info("In case you want to set other directory use '%s' argument.\n",
spvBinariesPathArg.c_str());
log_info("To skip the SPIR-V version check use the '%s' argument.\n",
spvVersionSkipArg.c_str());
}

int main(int argc, const char *argv[])
Expand All @@ -246,6 +252,11 @@ int main(int argc, const char *argv[])
modifiedSpvBinariesPath = true;
}
}
if (argv[i] == spvVersionSkipArg)
{
gVersionSkip = true;
argsRemoveNum++;
}

if (argsRemoveNum > 0) {
for (int j = i; j < (argc - argsRemoveNum); ++j)
Expand Down
33 changes: 33 additions & 0 deletions test_conformance/spirv_new/spirv_asm/basic.spvasm32
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos LLVM/SPIR-V Translator; 14
; Bound: 18
; Schema: 0
OpCapability Addresses
OpCapability Linkage
OpCapability Kernel
%1 = OpExtInstImport "OpenCL.std"
OpMemoryModel Physical32 OpenCL
OpEntryPoint Kernel %9 "test_basic" %gl_GlobalInvocationID
OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
OpDecorate %gl_GlobalInvocationID Constant
OpDecorate %gl_GlobalInvocationID LinkageAttributes "__spirv_BuiltInGlobalInvocationId" Import
%uint = OpTypeInt 32 0
%v3uint = OpTypeVector %uint 3
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
%void = OpTypeVoid
%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint
%8 = OpTypeFunction %void %_ptr_CrossWorkgroup_uint %_ptr_CrossWorkgroup_uint
%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
%9 = OpFunction %void None %8
%10 = OpFunctionParameter %_ptr_CrossWorkgroup_uint
%11 = OpFunctionParameter %_ptr_CrossWorkgroup_uint
%12 = OpLabel
%13 = OpLoad %v3uint %gl_GlobalInvocationID Aligned 16
%14 = OpCompositeExtract %uint %13 0
%15 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint %11 %14
%16 = OpLoad %uint %15 Aligned 4
%17 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint %10 %14
OpStore %17 %16 Aligned 4
OpReturn
OpFunctionEnd
38 changes: 38 additions & 0 deletions test_conformance/spirv_new/spirv_asm/basic.spvasm64
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos LLVM/SPIR-V Translator; 14
; Bound: 22
; Schema: 0
OpCapability Addresses
OpCapability Linkage
OpCapability Kernel
OpCapability Int64
%1 = OpExtInstImport "OpenCL.std"
OpMemoryModel Physical64 OpenCL
OpEntryPoint Kernel %10 "test_basic" %gl_GlobalInvocationID
OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
OpDecorate %gl_GlobalInvocationID Constant
OpDecorate %gl_GlobalInvocationID LinkageAttributes "__spirv_BuiltInGlobalInvocationId" Import
%ulong = OpTypeInt 64 0
%uint = OpTypeInt 32 0
%v3ulong = OpTypeVector %ulong 3
%_ptr_Input_v3ulong = OpTypePointer Input %v3ulong
%void = OpTypeVoid
%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint
%9 = OpTypeFunction %void %_ptr_CrossWorkgroup_uint %_ptr_CrossWorkgroup_uint
%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3ulong Input
%10 = OpFunction %void None %9
%11 = OpFunctionParameter %_ptr_CrossWorkgroup_uint
%12 = OpFunctionParameter %_ptr_CrossWorkgroup_uint
%13 = OpLabel
%14 = OpLoad %v3ulong %gl_GlobalInvocationID Aligned 32
%15 = OpCompositeExtract %ulong %14 0
%16 = OpUConvert %uint %15
%17 = OpSConvert %ulong %16
%18 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint %12 %17
%19 = OpLoad %uint %18 Aligned 4
%20 = OpSConvert %ulong %16
%21 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint %11 %20
OpStore %21 %19 Aligned 4
OpReturn
OpFunctionEnd
33 changes: 33 additions & 0 deletions test_conformance/spirv_new/spirv_asm/spv1.1/basic.spvasm32
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
; SPIR-V
; Version: 1.1
; Generator: Khronos LLVM/SPIR-V Translator; 14
; Bound: 18
; Schema: 0
OpCapability Addresses
OpCapability Linkage
OpCapability Kernel
%1 = OpExtInstImport "OpenCL.std"
OpMemoryModel Physical32 OpenCL
OpEntryPoint Kernel %9 "test_basic" %gl_GlobalInvocationID
OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
OpDecorate %gl_GlobalInvocationID Constant
OpDecorate %gl_GlobalInvocationID LinkageAttributes "__spirv_BuiltInGlobalInvocationId" Import
%uint = OpTypeInt 32 0
%v3uint = OpTypeVector %uint 3
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
%void = OpTypeVoid
%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint
%8 = OpTypeFunction %void %_ptr_CrossWorkgroup_uint %_ptr_CrossWorkgroup_uint
%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
%9 = OpFunction %void None %8
%10 = OpFunctionParameter %_ptr_CrossWorkgroup_uint
%11 = OpFunctionParameter %_ptr_CrossWorkgroup_uint
%12 = OpLabel
%13 = OpLoad %v3uint %gl_GlobalInvocationID Aligned 16
%14 = OpCompositeExtract %uint %13 0
%15 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint %11 %14
%16 = OpLoad %uint %15 Aligned 4
%17 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint %10 %14
OpStore %17 %16 Aligned 4
OpReturn
OpFunctionEnd
38 changes: 38 additions & 0 deletions test_conformance/spirv_new/spirv_asm/spv1.1/basic.spvasm64
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
; SPIR-V
; Version: 1.1
; Generator: Khronos LLVM/SPIR-V Translator; 14
; Bound: 22
; Schema: 0
OpCapability Addresses
OpCapability Linkage
OpCapability Kernel
OpCapability Int64
%1 = OpExtInstImport "OpenCL.std"
OpMemoryModel Physical64 OpenCL
OpEntryPoint Kernel %10 "test_basic" %gl_GlobalInvocationID
OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
OpDecorate %gl_GlobalInvocationID Constant
OpDecorate %gl_GlobalInvocationID LinkageAttributes "__spirv_BuiltInGlobalInvocationId" Import
%ulong = OpTypeInt 64 0
%uint = OpTypeInt 32 0
%v3ulong = OpTypeVector %ulong 3
%_ptr_Input_v3ulong = OpTypePointer Input %v3ulong
%void = OpTypeVoid
%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint
%9 = OpTypeFunction %void %_ptr_CrossWorkgroup_uint %_ptr_CrossWorkgroup_uint
%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3ulong Input
%10 = OpFunction %void None %9
%11 = OpFunctionParameter %_ptr_CrossWorkgroup_uint
%12 = OpFunctionParameter %_ptr_CrossWorkgroup_uint
%13 = OpLabel
%14 = OpLoad %v3ulong %gl_GlobalInvocationID Aligned 32
%15 = OpCompositeExtract %ulong %14 0
%16 = OpUConvert %uint %15
%17 = OpSConvert %ulong %16
%18 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint %12 %17
%19 = OpLoad %uint %18 Aligned 4
%20 = OpSConvert %ulong %16
%21 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint %11 %20
OpStore %21 %19 Aligned 4
OpReturn
OpFunctionEnd
33 changes: 33 additions & 0 deletions test_conformance/spirv_new/spirv_asm/spv1.2/basic.spvasm32
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
; SPIR-V
; Version: 1.2
; Generator: Khronos LLVM/SPIR-V Translator; 14
; Bound: 18
; Schema: 0
OpCapability Addresses
OpCapability Linkage
OpCapability Kernel
%1 = OpExtInstImport "OpenCL.std"
OpMemoryModel Physical32 OpenCL
OpEntryPoint Kernel %9 "test_basic" %gl_GlobalInvocationID
OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
OpDecorate %gl_GlobalInvocationID Constant
OpDecorate %gl_GlobalInvocationID LinkageAttributes "__spirv_BuiltInGlobalInvocationId" Import
%uint = OpTypeInt 32 0
%v3uint = OpTypeVector %uint 3
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
%void = OpTypeVoid
%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint
%8 = OpTypeFunction %void %_ptr_CrossWorkgroup_uint %_ptr_CrossWorkgroup_uint
%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
%9 = OpFunction %void None %8
%10 = OpFunctionParameter %_ptr_CrossWorkgroup_uint
%11 = OpFunctionParameter %_ptr_CrossWorkgroup_uint
%12 = OpLabel
%13 = OpLoad %v3uint %gl_GlobalInvocationID Aligned 16
%14 = OpCompositeExtract %uint %13 0
%15 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint %11 %14
%16 = OpLoad %uint %15 Aligned 4
%17 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint %10 %14
OpStore %17 %16 Aligned 4
OpReturn
OpFunctionEnd
Loading

0 comments on commit d5b7d10

Please sign in to comment.