diff --git a/Makefile b/Makefile index 6aef16a9..5dcaae6f 100644 --- a/Makefile +++ b/Makefile @@ -512,9 +512,11 @@ $(MANHTMLDIR)/intro.html: $(REFPATH)/intro.txt $(MANCOPYRIGHT) REGISTRY = $(ROOTDIR)/xml APIXML = $(REGISTRY)/cl.xml +CFEATURES = c/features.txt GENSCRIPT = $(SCRIPTS)/gencl.py DICTSCRIPT = $(SCRIPTS)/gen_dictionaries.py VERSIONSCRIPT = $(SCRIPTS)/gen_version_notes.py +CFEATSCRIPT = $(SCRIPTS)/gen_c_feature_dictionary.py GENSCRIPTOPTS = $(VERSIONOPTIONS) $(EXTOPTIONS) $(GENSCRIPTEXTRA) -registry $(APIXML) GENSCRIPTEXTRA = @@ -540,6 +542,7 @@ extinc: $(METADEPEND) $(METADEPEND): $(APIXML) $(GENSCRIPT) $(QUIET)$(MKDIR) $(METAPATH) $(QUIET)$(PYTHON) $(GENSCRIPT) $(GENSCRIPTOPTS) -o $(METAPATH) extinc + $(QUIET)$(PYTHON) $(CFEATSCRIPT) -features $(CFEATURES) -o $(METAPATH)/c-feature-dictionary.asciidoc # This generates a single file containing asciidoc attributes for each # extension in the spec being built. diff --git a/c/feature-dictionary.asciidoc b/c/feature-dictionary.asciidoc index e8375eb5..6e558f24 100644 --- a/c/feature-dictionary.asciidoc +++ b/c/feature-dictionary.asciidoc @@ -10,162 +10,4 @@ ifndef::backend-html5[] :opencl_c_feature_name: pass:q[`\__opencl_c_​<feature_​name>`] endif::[] -// opencl_c_3d_image_writes -ifdef::backend-html5[] -:opencl_c_3d_image_writes: pass:q[`\__opencl_c_3d_image_writes`] -endif::[] -ifndef::backend-html5[] -:opencl_c_3d_image_writes: pass:q[`\__opencl_c_​3d_​image_​writes`] -endif::[] - -// opencl_c_atomic_order_acq_rel -ifdef::backend-html5[] -:opencl_c_atomic_order_acq_rel: pass:q[`\__opencl_c_atomic_order_acq_rel`] -endif::[] -ifndef::backend-html5[] -:opencl_c_atomic_order_acq_rel: pass:q[`\__opencl_c_​atomic_​order_​​`] -endif::[] - -// opencl_c_atomic_order_seq_cst -ifdef::backend-html5[] -:opencl_c_atomic_order_seq_cst: pass:q[`\__opencl_c_atomic_order_seq_cst`] -endif::[] -ifndef::backend-html5[] -:opencl_c_atomic_order_seq_cst: pass:q[`\__opencl_c_​atomic_​order_​seq_​cst`] -endif::[] - -// opencl_c_atomic_scope_device -ifdef::backend-html5[] -:opencl_c_atomic_scope_device: pass:q[`\__opencl_c_atomic_scope_device`] -endif::[] -ifndef::backend-html5[] -:opencl_c_atomic_scope_device: pass:q[`\__opencl_c_​atomic_​scope_​device`] -endif::[] - -// opencl_c_atomic_scope_all_devices -ifdef::backend-html5[] -:opencl_c_atomic_scope_all_devices: pass:q[`\__opencl_c_atomic_scope_all_devices`] -endif::[] -ifndef::backend-html5[] -:opencl_c_atomic_scope_all_devices: pass:q[`\__opencl_c_​atomic_​scope_​all_​devices`] -endif::[] - -// opencl_c_device_enqueue -ifdef::backend-html5[] -:opencl_c_device_enqueue: pass:q[`\__opencl_c_device_enqueue`] -endif::[] -ifndef::backend-html5[] -:opencl_c_device_enqueue: pass:q[`\__opencl_c_​device_​enqueue`] -endif::[] - -// opencl_c_generic_address_space -ifdef::backend-html5[] -:opencl_c_generic_address_space: pass:q[`\__opencl_c_generic_address_space`] -endif::[] -ifndef::backend-html5[] -:opencl_c_generic_address_space: pass:q[`\__opencl_c_​generic_​address_​space`] -endif::[] - -// opencl_c_fp64 -ifdef::backend-html5[] -:opencl_c_fp64: pass:q[`\__opencl_c_fp64`] -endif::[] -ifndef::backend-html5[] -:opencl_c_fp64: pass:q[`\__opencl_c_​fp64`] -endif::[] - -// opencl_c_images -ifdef::backend-html5[] -:opencl_c_images: pass:q[`\__opencl_c_images`] -endif::[] -ifndef::backend-html5[] -:opencl_c_images: pass:q[`\__opencl_c_​images`] -endif::[] - -// opencl_c_int64 -ifdef::backend-html5[] -:opencl_c_int64: pass:q[`\__opencl_c_int64`] -endif::[] -ifndef::backend-html5[] -:opencl_c_int64: pass:q[`\__opencl_c_​int64`] -endif::[] - -// opencl_c_pipes -ifdef::backend-html5[] -:opencl_c_pipes: pass:q[`\__opencl_c_pipes`] -endif::[] -ifndef::backend-html5[] -:opencl_c_pipes: pass:q[`\__opencl_c_​pipes`] -endif::[] - -// opencl_c_program_scope_global_variables -ifdef::backend-html5[] -:opencl_c_program_scope_global_variables: pass:q[`\__opencl_c_program_scope_global_variables`] -endif::[] -ifndef::backend-html5[] -:opencl_c_program_scope_global_variables: pass:q[`\__opencl_c_​program_​scope_​global_​variables`] -endif::[] - -// opencl_c_read_write_images -ifdef::backend-html5[] -:opencl_c_read_write_images: pass:q[`\__opencl_c_read_write_images`] -endif::[] -ifndef::backend-html5[] -:opencl_c_read_write_images: pass:q[`\__opencl_c_​read_​write_​images`] -endif::[] - -// opencl_c_subgroups -ifdef::backend-html5[] -:opencl_c_subgroups: pass:q[`\__opencl_c_subgroups`] -endif::[] -ifndef::backend-html5[] -:opencl_c_subgroups: pass:q[`\__opencl_c_​subgroups`] -endif::[] - -// opencl_c_work_group_collective_functions -ifdef::backend-html5[] -:opencl_c_work_group_collective_functions: pass:q[`\__opencl_c_work_group_collective_functions`] -endif::[] -ifndef::backend-html5[] -:opencl_c_work_group_collective_functions: pass:q[`\__opencl_c_​work_​group_​collective_​functions`] -endif::[] - -// opencl_c_integer_dot_product_input_4x8bit -ifdef::backend-html5[] -:opencl_c_integer_dot_product_input_4x8bit: pass:q[`\__opencl_c_integer_dot_product_input_4x8bit`] -endif::[] -ifndef::backend-html5[] -:opencl_c_integer_dot_product_input_4x8bit: pass:q[`\__opencl_c_​integer_​dot_​product_​input_​4x8bit`] -endif::[] - -// opencl_c_integer_dot_product_input_4x8bit_packed -ifdef::backend-html5[] -:opencl_c_integer_dot_product_input_4x8bit_packed: pass:q[`\__opencl_c_integer_dot_product_input_4x8bit_packed`] -endif::[] -ifndef::backend-html5[] -:opencl_c_integer_dot_product_input_4x8bit_packed: pass:q[`\__opencl_c_​integer_​dot_​product_​input_​4x8bit_​packed`] -endif::[] - -// opencl_c_kernel_clock_scope_device -ifdef::backend-html5[] -:opencl_c_kernel_clock_scope_device: pass:q[`\__opencl_c_kernel_clock_scope_device`] -endif::[] -ifndef::backend-html5[] -:opencl_c_kernel_clock_scope_device: pass:q[`\__opencl_c_​kernel_​clock_​scope_​device`] -endif::[] - -// opencl_c_kernel_clock_scope_work_group -ifdef::backend-html5[] -:opencl_c_kernel_clock_scope_work_group: pass:q[`\__opencl_c_kernel_clock_scope_work_group`] -endif::[] -ifndef::backend-html5[] -:opencl_c_kernel_clock_scope_work_group: pass:q[`\__opencl_c_​kernel_​clock_​scope_​work_​group`] -endif::[] - -// opencl_c_kernel_clock_scope_sub_group -ifdef::backend-html5[] -:opencl_c_kernel_clock_scope_sub_group: pass:q[`\__opencl_c_kernel_clock_scope_sub_group`] -endif::[] -ifndef::backend-html5[] -:opencl_c_kernel_clock_scope_sub_group: pass:q[`\__opencl_c_​kernel_​clock_​scope_​sub_​group`] -endif::[] +include::{generated}/meta/c-feature-dictionary.asciidoc[] diff --git a/c/features.txt b/c/features.txt new file mode 100644 index 00000000..b7e636dd --- /dev/null +++ b/c/features.txt @@ -0,0 +1,20 @@ +__opencl_c_3d_image_writes +__opencl_c_atomic_order_acq_rel +__opencl_c_atomic_order_seq_cst +__opencl_c_atomic_scope_device +__opencl_c_atomic_scope_all_devices +__opencl_c_device_enqueue +__opencl_c_generic_address_space +__opencl_c_fp64 +__opencl_c_images +__opencl_c_int64 +__opencl_c_pipes +__opencl_c_program_scope_global_variables +__opencl_c_read_write_images +__opencl_c_subgroups +__opencl_c_work_group_collective_functions +__opencl_c_integer_dot_product_input_4x8bit +__opencl_c_integer_dot_product_input_4x8bit_packed +__opencl_c_kernel_clock_scope_device +__opencl_c_kernel_clock_scope_work_group +__opencl_c_kernel_clock_scope_sub_group diff --git a/scripts/gen_c_feature_dictionary.py b/scripts/gen_c_feature_dictionary.py new file mode 100644 index 00000000..f9b07173 --- /dev/null +++ b/scripts/gen_c_feature_dictionary.py @@ -0,0 +1,87 @@ +#!/usr/bin/python3 + +# Copyright 2024 The Khronos Group Inc. +# SPDX-License-Identifier: Apache-2.0 + +from collections import OrderedDict + +import argparse +import sys + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument('-features', action='store', + default='', + help='File with OpenCL C features to generate, one per line') + parser.add_argument('-o', action='store', default='', + help='Output file in which to store the feature dictionary. stdout is used if no file is provided.') + + args = parser.parse_args() + + features = [] + if len(args.features) > 0: + print('Generating feature dictionaries from: ' + args.features) + with open(args.features) as f: + features = f.readlines() + else: + print('Reading feature dictionaries from stdin...') + for line in sys.stdin: + features.append(line) + print('Generating...\n') + + numberOfFeatures = 0 + + if args.o: + outfile = open(args.o, 'w') + else: + outfile = sys.stdout + + for name in features: + name = name.strip() + if len(name) == 0: + continue + + # OpenCL C features start with __opencl_c + if name.startswith('__opencl_c'): + #print('found enum: ' + name) + + # Create a variant of the name that precedes underscores with + # "zero width" spaces. This causes some long names to be + # broken at more intuitive places. + htmlName = name[:10] + name[10:].replace("_", "_") + otherName = name[:10] + name[10:].replace("_", "_​") + + # Remove the leading underscores. + name = name[2:] + + # Example: + # + # // opencl_c_images + # ifdef::backend-html5[] + # :opencl_c_images: pass:q[`\__opencl_c_images`] + # endif::[] + # ifndef::backend-html5[] + # :opencl_c_images: pass:q[`\__opencl_c_​images`] + # endif::[] + outfile.write('// ' + name + '\n') + outfile.write('ifdef::backend-html5[]\n') + outfile.write(':' + name + ': pass:q[`\\' + htmlName + '`]\n') + outfile.write('endif::[]\n') + outfile.write('ifndef::backend-html5[]\n') + outfile.write(':' + name + ': pass:q[`\\' + otherName + '`]\n') + outfile.write('endif::[]\n') + + numberOfFeatures = numberOfFeatures + 1 + + # everything else is a function + else: + print('Unexpected feature name: ' + name + ', features should start with __opencl_c!') + sys.exit(1) + + outfile.write('\n') + + if args.o: + outfile.close() + + print('Found ' + str(numberOfFeatures) + ' features.')