Skip to content

Commit

Permalink
Generate OpenCL C feature dictionary (KhronosGroup#1212)
Browse files Browse the repository at this point in the history
* Generate OpenCL C feature dictionary

Features are stored in a text file for now. Ultimately, we probably
want to use the XML registry for this.

Generation script taken from KhronosGroup#1174 with a few modifications.

Contributes to KhronosGroup#1166.

Signed-off-by: Ben Ashbaugh <[email protected]>
Signed-off-by: Kevin Petit <[email protected]>
Change-Id: Ie2c14148d75457030aa1a97cf601daba2c007397

* Update scripts/gen_c_feature_dictionary.py

Co-authored-by: Ben Ashbaugh <[email protected]>

* define __opencl_c_<feature_name> outside of the list of features

Signed-off-by: Kevin Petit <[email protected]>
Change-Id: I8e0947c30775338dd70803d09c7059d340e86f5a

---------

Signed-off-by: Ben Ashbaugh <[email protected]>
Signed-off-by: Kevin Petit <[email protected]>
Co-authored-by: Ben Ashbaugh <[email protected]>
  • Loading branch information
kpet and bashbaug authored Aug 13, 2024
1 parent aca3750 commit 47dd749
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 159 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 =

Expand All @@ -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.
Expand Down
160 changes: 1 addition & 159 deletions c/feature-dictionary.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,162 +10,4 @@ ifndef::backend-html5[]
:opencl_c_feature_name: pass:q[`\__opencl_c_&#8203;&lt;feature_&#8203;name&gt;`]
endif::[]

// opencl_c_3d_image_writes
ifdef::backend-html5[]
:opencl_c_3d_image_writes: pass:q[`\__opencl_c_<wbr>3d_<wbr>image_<wbr>writes`]
endif::[]
ifndef::backend-html5[]
:opencl_c_3d_image_writes: pass:q[`\__opencl_c_&#8203;3d_&#8203;image_&#8203;writes`]
endif::[]

// opencl_c_atomic_order_acq_rel
ifdef::backend-html5[]
:opencl_c_atomic_order_acq_rel: pass:q[`\__opencl_c_<wbr>atomic_<wbr>order_<wbr>acq_<wbr>rel`]
endif::[]
ifndef::backend-html5[]
:opencl_c_atomic_order_acq_rel: pass:q[`\__opencl_c_&#8203;atomic_&#8203;order_&#8203;&#8203;`]
endif::[]

// opencl_c_atomic_order_seq_cst
ifdef::backend-html5[]
:opencl_c_atomic_order_seq_cst: pass:q[`\__opencl_c_<wbr>atomic_<wbr>order_<wbr>seq_<wbr>cst`]
endif::[]
ifndef::backend-html5[]
:opencl_c_atomic_order_seq_cst: pass:q[`\__opencl_c_&#8203;atomic_&#8203;order_&#8203;seq_&#8203;cst`]
endif::[]

// opencl_c_atomic_scope_device
ifdef::backend-html5[]
:opencl_c_atomic_scope_device: pass:q[`\__opencl_c_<wbr>atomic_<wbr>scope_<wbr>device`]
endif::[]
ifndef::backend-html5[]
:opencl_c_atomic_scope_device: pass:q[`\__opencl_c_&#8203;atomic_&#8203;scope_&#8203;device`]
endif::[]

// opencl_c_atomic_scope_all_devices
ifdef::backend-html5[]
:opencl_c_atomic_scope_all_devices: pass:q[`\__opencl_c_<wbr>atomic_<wbr>scope_<wbr>all_<wbr>devices`]
endif::[]
ifndef::backend-html5[]
:opencl_c_atomic_scope_all_devices: pass:q[`\__opencl_c_&#8203;atomic_&#8203;scope_&#8203;all_&#8203;devices`]
endif::[]

// opencl_c_device_enqueue
ifdef::backend-html5[]
:opencl_c_device_enqueue: pass:q[`\__opencl_c_<wbr>device_<wbr>enqueue`]
endif::[]
ifndef::backend-html5[]
:opencl_c_device_enqueue: pass:q[`\__opencl_c_&#8203;device_&#8203;enqueue`]
endif::[]

// opencl_c_generic_address_space
ifdef::backend-html5[]
:opencl_c_generic_address_space: pass:q[`\__opencl_c_<wbr>generic_<wbr>address_<wbr>space`]
endif::[]
ifndef::backend-html5[]
:opencl_c_generic_address_space: pass:q[`\__opencl_c_&#8203;generic_&#8203;address_&#8203;space`]
endif::[]

// opencl_c_fp64
ifdef::backend-html5[]
:opencl_c_fp64: pass:q[`\__opencl_c_<wbr>fp64`]
endif::[]
ifndef::backend-html5[]
:opencl_c_fp64: pass:q[`\__opencl_c_&#8203;fp64`]
endif::[]

// opencl_c_images
ifdef::backend-html5[]
:opencl_c_images: pass:q[`\__opencl_c_<wbr>images`]
endif::[]
ifndef::backend-html5[]
:opencl_c_images: pass:q[`\__opencl_c_&#8203;images`]
endif::[]

// opencl_c_int64
ifdef::backend-html5[]
:opencl_c_int64: pass:q[`\__opencl_c_<wbr>int64`]
endif::[]
ifndef::backend-html5[]
:opencl_c_int64: pass:q[`\__opencl_c_&#8203;int64`]
endif::[]

// opencl_c_pipes
ifdef::backend-html5[]
:opencl_c_pipes: pass:q[`\__opencl_c_<wbr>pipes`]
endif::[]
ifndef::backend-html5[]
:opencl_c_pipes: pass:q[`\__opencl_c_&#8203;pipes`]
endif::[]

// opencl_c_program_scope_global_variables
ifdef::backend-html5[]
:opencl_c_program_scope_global_variables: pass:q[`\__opencl_c_<wbr>program_<wbr>scope_<wbr>global_<wbr>variables`]
endif::[]
ifndef::backend-html5[]
:opencl_c_program_scope_global_variables: pass:q[`\__opencl_c_&#8203;program_&#8203;scope_&#8203;global_&#8203;variables`]
endif::[]

// opencl_c_read_write_images
ifdef::backend-html5[]
:opencl_c_read_write_images: pass:q[`\__opencl_c_<wbr>read_<wbr>write_<wbr>images`]
endif::[]
ifndef::backend-html5[]
:opencl_c_read_write_images: pass:q[`\__opencl_c_&#8203;read_&#8203;write_&#8203;images`]
endif::[]

// opencl_c_subgroups
ifdef::backend-html5[]
:opencl_c_subgroups: pass:q[`\__opencl_c_<wbr>subgroups`]
endif::[]
ifndef::backend-html5[]
:opencl_c_subgroups: pass:q[`\__opencl_c_&#8203;subgroups`]
endif::[]

// opencl_c_work_group_collective_functions
ifdef::backend-html5[]
:opencl_c_work_group_collective_functions: pass:q[`\__opencl_c_<wbr>work_<wbr>group_<wbr>collective_<wbr>functions`]
endif::[]
ifndef::backend-html5[]
:opencl_c_work_group_collective_functions: pass:q[`\__opencl_c_&#8203;work_&#8203;group_&#8203;collective_&#8203;functions`]
endif::[]

// opencl_c_integer_dot_product_input_4x8bit
ifdef::backend-html5[]
:opencl_c_integer_dot_product_input_4x8bit: pass:q[`\__opencl_c_<wbr>integer_<wbr>dot_<wbr>product_<wbr>input_<wbr>4x8bit`]
endif::[]
ifndef::backend-html5[]
:opencl_c_integer_dot_product_input_4x8bit: pass:q[`\__opencl_c_&#8203;integer_&#8203;dot_&#8203;product_&#8203;input_&#8203;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_<wbr>integer_<wbr>dot_<wbr>product_<wbr>input_<wbr>4x8bit_<wbr>packed`]
endif::[]
ifndef::backend-html5[]
:opencl_c_integer_dot_product_input_4x8bit_packed: pass:q[`\__opencl_c_&#8203;integer_&#8203;dot_&#8203;product_&#8203;input_&#8203;4x8bit_&#8203;packed`]
endif::[]

// opencl_c_kernel_clock_scope_device
ifdef::backend-html5[]
:opencl_c_kernel_clock_scope_device: pass:q[`\__opencl_c_<wbr>kernel_<wbr>clock_<wbr>scope_<wbr>device`]
endif::[]
ifndef::backend-html5[]
:opencl_c_kernel_clock_scope_device: pass:q[`\__opencl_c_&#8203;kernel_&#8203;clock_&#8203;scope_&#8203;device`]
endif::[]

// opencl_c_kernel_clock_scope_work_group
ifdef::backend-html5[]
:opencl_c_kernel_clock_scope_work_group: pass:q[`\__opencl_c_<wbr>kernel_<wbr>clock_<wbr>scope_<wbr>work_<wbr>group`]
endif::[]
ifndef::backend-html5[]
:opencl_c_kernel_clock_scope_work_group: pass:q[`\__opencl_c_&#8203;kernel_&#8203;clock_&#8203;scope_&#8203;work_&#8203;group`]
endif::[]

// opencl_c_kernel_clock_scope_sub_group
ifdef::backend-html5[]
:opencl_c_kernel_clock_scope_sub_group: pass:q[`\__opencl_c_<wbr>kernel_<wbr>clock_<wbr>scope_<wbr>sub_<wbr>group`]
endif::[]
ifndef::backend-html5[]
:opencl_c_kernel_clock_scope_sub_group: pass:q[`\__opencl_c_&#8203;kernel_&#8203;clock_&#8203;scope_&#8203;sub_&#8203;group`]
endif::[]
include::{generated}/meta/c-feature-dictionary.asciidoc[]
20 changes: 20 additions & 0 deletions c/features.txt
Original file line number Diff line number Diff line change
@@ -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
87 changes: 87 additions & 0 deletions scripts/gen_c_feature_dictionary.py
Original file line number Diff line number Diff line change
@@ -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("_", "_<wbr>")
otherName = name[:10] + name[10:].replace("_", "_&#8203;")

# Remove the leading underscores.
name = name[2:]

# Example:
#
# // opencl_c_images
# ifdef::backend-html5[]
# :opencl_c_images: pass:q[`\__opencl_c_<wbr>images`]
# endif::[]
# ifndef::backend-html5[]
# :opencl_c_images: pass:q[`\__opencl_c_&#8203;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.')

0 comments on commit 47dd749

Please sign in to comment.