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 " pocl_tree_sitter_utils.h"
66+ #endif
67+
6168/* ****************************************************************************/
6269
6370typedef struct proxy_platform_data_s
@@ -983,6 +990,120 @@ static int get_kernel_metadata(pocl_kernel_metadata_t *meta,
983990 return CL_SUCCESS;
984991}
985992
993+ #if HAVE_TREE_SITTER
994+ // /
995+ // / Use tree sitter to populate metadata from the kernel source string.
996+ // /
997+ // / \param source [in]: String of kernel source.
998+ // / \param meta [out]: Populated with metadata of kernel.
999+ // / \param num_devices [in]: device count.
1000+ // / \param device [in]: used to populate metadata.
1001+ // / \param kernel [in]: kernel to get metadata about.
1002+ // / \return CL_SUCCESS or a CL error.
1003+ static int proxy_map_source_to_metadata (const char *source,
1004+ pocl_kernel_metadata_t *meta,
1005+ cl_uint num_devices,
1006+ cl_device_id device, cl_kernel kernel) {
1007+
1008+ char string_value[POCL_MAX_PATHNAME_LENGTH];
1009+ int err;
1010+ size_t size;
1011+
1012+ assert (meta->data == nullptr );
1013+ meta->data = (void **)calloc (num_devices, sizeof (void *));
1014+ meta->has_arg_metadata = (-1 );
1015+
1016+ err = clGetKernelInfo (kernel, CL_KERNEL_FUNCTION_NAME, 0 , nullptr , &size);
1017+ if (err != CL_SUCCESS || size == 0 ) {
1018+ POCL_MSG_PRINT_PROXY (" Could not get kernel name.\n " );
1019+ return err;
1020+ }
1021+ assert (size < POCL_MAX_PATHNAME_LENGTH);
1022+
1023+ err = clGetKernelInfo (kernel, CL_KERNEL_FUNCTION_NAME, size, string_value,
1024+ nullptr );
1025+ if (err != CL_SUCCESS) {
1026+ POCL_MSG_PRINT_PROXY (" Could not copy kernel name.\n " );
1027+ return err;
1028+ }
1029+ meta->name = (char *)malloc (size);
1030+ memcpy (meta->name , string_value, size);
1031+
1032+ err = get_kernel_info (meta, device, kernel);
1033+ if (err != CL_SUCCESS) {
1034+ POCL_MSG_PRINT_PROXY (" Could not get kernel info.\n " );
1035+ return err;
1036+ }
1037+
1038+ cl_uint num_args;
1039+
1040+ err = clGetKernelInfo (kernel, CL_KERNEL_NUM_ARGS, sizeof (num_args), &num_args,
1041+ nullptr );
1042+ if (err != CL_SUCCESS) {
1043+ POCL_MSG_PRINT_PROXY (" Could not get number of kernel args.\n " );
1044+ return err;
1045+ }
1046+
1047+ if (num_args == 0 ) {
1048+ meta->arg_info = nullptr ;
1049+ meta->num_args = 0 ;
1050+ return CL_SUCCESS;
1051+ }
1052+
1053+ assert (num_args < 10000 );
1054+
1055+ meta->num_args = num_args;
1056+ meta->arg_info =
1057+ (pocl_argument_info *)calloc (num_args, sizeof (pocl_argument_info));
1058+
1059+ char empty_buffer[MAX_TESTED_ARG_SIZE];
1060+
1061+ TSParser *parser = ts_parser_new ();
1062+ ts_parser_set_language (parser, tree_sitter_opencl ());
1063+ TSTree *tree =
1064+ ts_parser_parse_string (parser, nullptr , source, strlen (source));
1065+ TSNode root_node = ts_tree_root_node (tree);
1066+
1067+ int32_t status = 0 ;
1068+ TSNode kernel_node =
1069+ pocl_ts_find_kernel_params (source, root_node, meta->name , &status);
1070+ uint32_t child_count;
1071+ if (status != CL_SUCCESS) {
1072+ err = CL_KERNEL_ARG_INFO_NOT_AVAILABLE;
1073+ POCL_MSG_WARN (" Could not find kernel name in source.\n " );
1074+ goto TS_ERROR;
1075+ }
1076+ POCL_PRINT_TS_NODE (source, kernel_node);
1077+ child_count = ts_node_named_child_count (kernel_node);
1078+ assert (num_args == child_count);
1079+
1080+ TSNode child;
1081+ for (cl_uint i = 0 ; i < num_args; ++i) {
1082+ pocl_argument_info *pi = &meta->arg_info [i];
1083+ child = ts_node_named_child (kernel_node, i);
1084+ err = pocl_ts_map_node_to_arg_info (source, child, pi);
1085+ if (err != CL_SUCCESS) {
1086+ POCL_MSG_WARN (" Failed to parse %s arg %d.\n " , meta->name , i);
1087+ goto TS_ERROR;
1088+ }
1089+
1090+ POCL_MSG_PRINT_PROXY (" KERNEL %s ARGUMENT %u NAME %s "
1091+ " TYPENAME %s TYPE %u SIZE %u\n " ,
1092+ meta->name , i, pi->name , pi->type_name , pi->type ,
1093+ pi->type_size );
1094+ }
1095+
1096+ ts_tree_delete (tree);
1097+ ts_parser_delete (parser);
1098+ return CL_SUCCESS;
1099+
1100+ TS_ERROR:
1101+ ts_tree_delete (tree);
1102+ ts_parser_delete (parser);
1103+ return err;
1104+ }
1105+ #endif
1106+
9861107static void
9871108set_build_log (cl_device_id proxy_dev, cl_program program,
9881109 cl_program proxy_prog, unsigned device_i)
@@ -1401,8 +1522,8 @@ pocl_proxy_setup_metadata (cl_device_id device, cl_program program,
14011522 cl_program proxy_prog = (cl_program)program->data [program_device_i];
14021523
14031524 // 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 )))
1525+ if (!(d->backend ->provides_metadata || HAVE_TREE_SITTER ||
1526+ (d->backend ->supports_il && program->program_il_size > 0 )))
14061527 return 0 ;
14071528
14081529 assert (program->kernel_meta == NULL );
@@ -1471,8 +1592,9 @@ pocl_proxy_setup_metadata (cl_device_id device, cl_program program,
14711592 index++;
14721593 }
14731594
1474- } else {
1595+ } else if (d-> backend -> provides_metadata ) {
14751596 for (cl_uint i = 0 ; i < num_kernels; ++i) {
1597+
14761598 err = get_kernel_metadata (p + i, program->num_devices , proxy_prog,
14771599 d->device_id , kernels[i]);
14781600 if (err != CL_SUCCESS) {
@@ -1484,6 +1606,25 @@ pocl_proxy_setup_metadata (cl_device_id device, cl_program program,
14841606 assert (err == CL_SUCCESS);
14851607 }
14861608 }
1609+ #if HAVE_TREE_SITTER
1610+ else {
1611+ for (cl_uint i = 0 ; i < num_kernels; i++) {
1612+
1613+ err = proxy_map_source_to_metadata (program->source , p + i,
1614+ program->num_devices , d->device_id ,
1615+ kernels[i]);
1616+ if (err != CL_SUCCESS) {
1617+ POCL_MSG_WARN (" Failed to kernel metadata for index %d.\n " , i);
1618+ return 0 ;
1619+ }
1620+
1621+ err = clReleaseKernel (kernels[i]);
1622+ }
1623+ }
1624+ #else
1625+ else
1626+ return 0 ;
1627+ #endif
14871628
14881629 program->kernel_meta = p;
14891630
0 commit comments