blob: 4b0b8babd781ff110cee96a3601f45a655e4fe09 [file] [log] [blame]
COPYRIGHT = """\
/*
* Copyright 2021 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
"""
import argparse
import os
from grl_parser import parse_grl_file
from mako.template import Template
TEMPLATE_H = Template(COPYRIGHT + """
/* This file generated from ${filename}, don't edit directly. */
#ifndef GRL_CL_KERNEL_H
#define GRL_CL_KERNEL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "genxml/gen_macros.h"
#include "compiler/brw_kernel.h"
enum grl_cl_kernel {
% for k in kernels:
GRL_CL_KERNEL_${k.upper()},
% endfor
GRL_CL_KERNEL_MAX,
};
const char *grl_cl_kernel_name(enum grl_cl_kernel kernel);
const char *genX(grl_get_cl_kernel_sha1)(enum grl_cl_kernel id);
void genX(grl_get_cl_kernel)(struct brw_kernel *kernel, enum grl_cl_kernel id);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* INTEL_GRL_H */
""", output_encoding='utf-8')
TEMPLATE_C = Template(COPYRIGHT + """
/* This file generated from ${filename}, don't edit directly. */
#include "grl_cl_kernel.h"
% for k in kernels:
#include "${prefix}_${k}.h"
% endfor
const char *
grl_cl_kernel_name(enum grl_cl_kernel kernel)
{
switch (kernel) {
% for k in kernels:
case GRL_CL_KERNEL_${k.upper()}: return "${k}";
% endfor
default: return "unknown";
}
}
const char *
genX(grl_get_cl_kernel_sha1)(enum grl_cl_kernel id)
{
switch (id) {
% for k in kernels:
case GRL_CL_KERNEL_${k.upper()}: return ${prefix}_${k}_sha1;
% endfor
default:
unreachable("Invalid GRL kernel enum");
}
};
void
${prefix}_grl_get_cl_kernel(struct brw_kernel *kernel, enum grl_cl_kernel id)
{
switch (id) {
% for k in kernels:
case GRL_CL_KERNEL_${k.upper()}:
*kernel = ${prefix}_${k};
break;
% endfor
default:
unreachable("Invalid GRL kernel enum");
}
}
""", output_encoding='utf-8')
def get_libraries_files(kernel_module):
lib_files = []
for item in kernel_module[3]:
if item[0] != 'library':
continue
default_file = None
fallback_file = None
path_directory = None
for props in item[2]:
if props[0] == 'fallback':
fallback_file = props[1]
elif props[0] == 'default':
default_file = props[1]
elif props[0] == 'path':
path_directory = props[1]
assert path_directory
assert default_file or fallback_file
if fallback_file:
lib_files.append(os.path.join(path_directory, fallback_file))
else:
lib_files.append(os.path.join(path_directory, default_file))
return lib_files
def add_kernels(kernels, cl_file, entrypoint, libs):
assert cl_file.endswith('.cl')
for lib_file in libs:
assert lib_file.endswith('.cl')
kernels.append((cl_file, entrypoint, ','.join(libs)))
def get_kernels(grl_nodes):
kernels = []
for item in grl_nodes:
assert isinstance(item, tuple)
if item[0] == 'kernel':
ann = item[2]
add_kernels(kernels, ann['source'], ann['kernelFunction'], [])
elif item[0] == 'kernel-module':
cl_file = item[2]
libfiles = get_libraries_files(item)
for kernel_def in item[3]:
if kernel_def[0] == 'kernel':
ann = kernel_def[2]
add_kernels(kernels, cl_file, ann['kernelFunction'], libfiles)
return kernels
def parse_libraries(filenames):
libraries = {}
for fname in filenames:
lib_package = parse_grl_file(fname, [])
for lib in lib_package:
assert lib[0] == 'library'
# Add the directory of the library so that CL files can be found.
lib[2].append(('path', os.path.dirname(fname)))
libraries[lib[1]] = lib
return libraries
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--out-c', help='Output C file')
parser.add_argument('--out-h', help='Output H file')
parser.add_argument('--ls-kernels', action='store_const', const=True,
help='List all openCL kernels')
parser.add_argument('--prefix', help='Prefix')
parser.add_argument('--library', dest='libraries', action='append',
default=[], help='Libraries to include')
parser.add_argument('files', type=str, nargs='*', help='GRL files')
args = parser.parse_args()
libraries = parse_libraries(args.libraries)
kernels = []
for fname in args.files:
kernels += get_kernels(parse_grl_file(fname, libraries))
# Make the list of kernels unique and sorted
kernels = sorted(list(set(kernels)))
if args.ls_kernels:
for cl_file, entrypoint, libs in kernels:
if not os.path.isabs(cl_file):
cl_file = os.path.join(os.path.dirname(fname), cl_file)
print('{}:{}:{}'.format(cl_file, entrypoint, libs))
kernel_c_names = []
for cl_file, entrypoint, libs in kernels:
cl_file = os.path.splitext(cl_file)[0]
cl_file_name = cl_file.replace('/', '_')
kernel_c_names.append('_'.join([cl_file_name, entrypoint]))
try:
if args.out_h:
with open(args.out_h, 'wb') as f:
f.write(TEMPLATE_H.render(kernels=kernel_c_names,
filename=os.path.basename(__file__)))
if args.out_c:
with open(args.out_c, 'wb') as f:
f.write(TEMPLATE_C.render(kernels=kernel_c_names,
prefix=args.prefix,
filename=os.path.basename(__file__)))
except Exception:
# In the event there's an error, this imports some helpers from mako
# to print a useful stack trace and prints it, then exits with
# status 1, if python is run with debug; otherwise it just raises
# the exception
if __debug__:
import sys
from mako import exceptions
sys.stderr.write(exceptions.text_error_template().render() + '\n')
sys.exit(1)
raise
if __name__ == '__main__':
main()