5858#error This driver cannot be built when pocl is to be linked against ICD
5959#endif
6060
61+ #ifndef HAVE_TREE_SITTER
62+ #define HAVE_TREE_SITTER 0
63+ #endif
64+ #if HAVE_TREE_SITTER
65+ #include " bindings/c/tree-sitter-opencl.h"
66+ #include " pocl_tree_sitter_utils.h"
67+ #endif
68+
6169/* ****************************************************************************/
6270
6371typedef struct proxy_platform_data_s
@@ -983,6 +991,120 @@ static int get_kernel_metadata(pocl_kernel_metadata_t *meta,
983991 return CL_SUCCESS;
984992}
985993
994+ #if HAVE_TREE_SITTER
995+ // /
996+ // / Use tree sitter to populate metadata from the kernel source string.
997+ // /
998+ // / \param source [in]: String of kernel source.
999+ // / \param meta [out]: Populated with metadata of kernel.
1000+ // / \param num_devices [in]: device count.
1001+ // / \param device [in]: used to populate metadata.
1002+ // / \param kernel [in]: kernel to get metadata about.
1003+ // / \return CL_SUCCESS or a CL error.
1004+ static int proxy_map_source_to_metadata (const char *source,
1005+ pocl_kernel_metadata_t *meta,
1006+ cl_uint num_devices,
1007+ cl_device_id device, cl_kernel kernel) {
1008+
1009+ char string_value[POCL_MAX_PATHNAME_LENGTH];
1010+ int err;
1011+ size_t size;
1012+
1013+ assert (meta->data == nullptr );
1014+ meta->data = (void **)calloc (num_devices, sizeof (void *));
1015+ meta->has_arg_metadata = (-1 );
1016+
1017+ err = clGetKernelInfo (kernel, CL_KERNEL_FUNCTION_NAME, 0 , nullptr , &size);
1018+ if (err != CL_SUCCESS || size == 0 ) {
1019+ POCL_MSG_PRINT_PROXY (" Could not get kernel name.\n " );
1020+ return err;
1021+ }
1022+ assert (size < POCL_MAX_PATHNAME_LENGTH);
1023+
1024+ err = clGetKernelInfo (kernel, CL_KERNEL_FUNCTION_NAME, size, string_value,
1025+ nullptr );
1026+ if (err != CL_SUCCESS) {
1027+ POCL_MSG_PRINT_PROXY (" Could not copy kernel name.\n " );
1028+ return err;
1029+ }
1030+ meta->name = (char *)malloc (size);
1031+ memcpy (meta->name , string_value, size);
1032+
1033+ err = get_kernel_info (meta, device, kernel);
1034+ if (err != CL_SUCCESS) {
1035+ POCL_MSG_PRINT_PROXY (" Could not get kernel info.\n " );
1036+ return err;
1037+ }
1038+
1039+ cl_uint num_args;
1040+
1041+ err = clGetKernelInfo (kernel, CL_KERNEL_NUM_ARGS, sizeof (num_args), &num_args,
1042+ nullptr );
1043+ if (err != CL_SUCCESS) {
1044+ POCL_MSG_PRINT_PROXY (" Could not get number of kernel args.\n " );
1045+ return err;
1046+ }
1047+
1048+ if (num_args == 0 ) {
1049+ meta->arg_info = nullptr ;
1050+ meta->num_args = 0 ;
1051+ return CL_SUCCESS;
1052+ }
1053+
1054+ assert (num_args < 10000 );
1055+
1056+ meta->num_args = num_args;
1057+ meta->arg_info =
1058+ (pocl_argument_info *)calloc (num_args, sizeof (pocl_argument_info));
1059+
1060+ char empty_buffer[MAX_TESTED_ARG_SIZE];
1061+
1062+ TSParser *parser = ts_parser_new ();
1063+ ts_parser_set_language (parser, tree_sitter_opencl ());
1064+ TSTree *tree =
1065+ ts_parser_parse_string (parser, nullptr , source, strlen (source));
1066+ TSNode root_node = ts_tree_root_node (tree);
1067+
1068+ int32_t status = 0 ;
1069+ TSNode kernel_node =
1070+ pocl_ts_find_kernel_params (source, root_node, meta->name , &status);
1071+ uint32_t child_count;
1072+ if (status != CL_SUCCESS) {
1073+ err = CL_KERNEL_ARG_INFO_NOT_AVAILABLE;
1074+ POCL_MSG_WARN (" Could not find kernel name in source.\n " );
1075+ goto TS_ERROR;
1076+ }
1077+ POCL_PRINT_TS_NODE (source, kernel_node);
1078+ child_count = ts_node_named_child_count (kernel_node);
1079+ assert (num_args == child_count);
1080+
1081+ TSNode child;
1082+ for (cl_uint i = 0 ; i < num_args; ++i) {
1083+ pocl_argument_info *pi = &meta->arg_info [i];
1084+ child = ts_node_named_child (kernel_node, i);
1085+ err = pocl_ts_map_node_to_arg_info (source, child, pi);
1086+ if (err != CL_SUCCESS) {
1087+ POCL_MSG_WARN (" Failed to parse %s arg %d.\n " , meta->name , i);
1088+ goto TS_ERROR;
1089+ }
1090+
1091+ POCL_MSG_PRINT_PROXY (" KERNEL %s ARGUMENT %u NAME %s "
1092+ " TYPENAME %s TYPE %u SIZE %u\n " ,
1093+ meta->name , i, pi->name , pi->type_name , pi->type ,
1094+ pi->type_size );
1095+ }
1096+
1097+ ts_tree_delete (tree);
1098+ ts_parser_delete (parser);
1099+ return CL_SUCCESS;
1100+
1101+ TS_ERROR:
1102+ ts_tree_delete (tree);
1103+ ts_parser_delete (parser);
1104+ return err;
1105+ }
1106+ #endif
1107+
9861108static void
9871109set_build_log (cl_device_id proxy_dev, cl_program program,
9881110 cl_program proxy_prog, unsigned device_i)
@@ -1401,8 +1523,8 @@ pocl_proxy_setup_metadata (cl_device_id device, cl_program program,
14011523 cl_program proxy_prog = (cl_program)program->data [program_device_i];
14021524
14031525 // Return if there is no metadata and we are not building using a binary.
1404- if (!(d->backend ->provides_metadata ||
1405- (d->backend ->supports_il && program->program_il_size > 0 )))
1526+ if (!(d->backend ->provides_metadata || HAVE_TREE_SITTER ||
1527+ (d->backend ->supports_il && program->program_il_size > 0 )))
14061528 return 0 ;
14071529
14081530 assert (program->kernel_meta == NULL );
@@ -1471,8 +1593,9 @@ pocl_proxy_setup_metadata (cl_device_id device, cl_program program,
14711593 index++;
14721594 }
14731595
1474- } else {
1596+ } else if (d-> backend -> provides_metadata ) {
14751597 for (cl_uint i = 0 ; i < num_kernels; ++i) {
1598+
14761599 err = get_kernel_metadata (p + i, program->num_devices , proxy_prog,
14771600 d->device_id , kernels[i]);
14781601 if (err != CL_SUCCESS) {
@@ -1484,6 +1607,25 @@ pocl_proxy_setup_metadata (cl_device_id device, cl_program program,
14841607 assert (err == CL_SUCCESS);
14851608 }
14861609 }
1610+ #if HAVE_TREE_SITTER
1611+ else {
1612+ for (cl_uint i = 0 ; i < num_kernels; i++) {
1613+
1614+ err = proxy_map_source_to_metadata (program->source , p + i,
1615+ program->num_devices , d->device_id ,
1616+ kernels[i]);
1617+ if (err != CL_SUCCESS) {
1618+ POCL_MSG_WARN (" Failed to kernel metadata for index %d.\n " , i);
1619+ return 0 ;
1620+ }
1621+
1622+ err = clReleaseKernel (kernels[i]);
1623+ }
1624+ }
1625+ #else
1626+ else
1627+ return 0 ;
1628+ #endif
14871629
14881630 program->kernel_meta = p;
14891631
0 commit comments