58
58
#error This driver cannot be built when pocl is to be linked against ICD
59
59
#endif
60
60
61
+ #ifdef HAVE_TREE_SITTER
62
+ #include " bindings/c/tree-sitter-opencl.h"
63
+ #include " pocl_tree_sitter_utils.h"
64
+ #endif
65
+
61
66
/* ****************************************************************************/
62
67
63
68
typedef struct proxy_platform_data_s
@@ -983,6 +988,120 @@ static int get_kernel_metadata(pocl_kernel_metadata_t *meta,
983
988
return CL_SUCCESS;
984
989
}
985
990
991
+ #ifdef HAVE_TREE_SITTER
992
+ /* *
993
+ * Use tree sitter to populate metadata from the kernel source string.
994
+ *
995
+ * @param source [in]: String of kernel source.
996
+ * @param meta [out]: Populated with metadata of kernel.
997
+ * @param num_devices [in]: device count.
998
+ * @param device [in]: used to populate metadata.
999
+ * @return CL_SUCCESS or a CL error.
1000
+ */
1001
+ static int proxy_map_source_to_metadata (const char *source,
1002
+ pocl_kernel_metadata_t *meta,
1003
+ cl_uint num_devices,
1004
+ cl_device_id device, cl_kernel kernel) {
1005
+
1006
+ char string_value[POCL_MAX_PATHNAME_LENGTH];
1007
+ int err;
1008
+ size_t size;
1009
+
1010
+ assert (meta->data == nullptr );
1011
+ meta->data = (void **)calloc (num_devices, sizeof (void *));
1012
+ meta->has_arg_metadata = (-1 );
1013
+
1014
+ err = clGetKernelInfo (kernel, CL_KERNEL_FUNCTION_NAME, 0 , nullptr , &size);
1015
+ if (err != CL_SUCCESS || size == 0 ) {
1016
+ POCL_MSG_PRINT_PROXY (" Could not get kernel name.\n " );
1017
+ return err;
1018
+ }
1019
+ assert (size < POCL_MAX_PATHNAME_LENGTH);
1020
+
1021
+ err = clGetKernelInfo (kernel, CL_KERNEL_FUNCTION_NAME, size, string_value,
1022
+ nullptr );
1023
+ if (err != CL_SUCCESS) {
1024
+ POCL_MSG_PRINT_PROXY (" Could not copy kernel name.\n " );
1025
+ return err;
1026
+ }
1027
+ meta->name = (char *)malloc (size);
1028
+ memcpy (meta->name , string_value, size);
1029
+
1030
+ err = get_kernel_info (meta, device, kernel);
1031
+ if (err != CL_SUCCESS) {
1032
+ POCL_MSG_PRINT_PROXY (" Could not get kernel info.\n " );
1033
+ return err;
1034
+ }
1035
+
1036
+ cl_uint num_args;
1037
+
1038
+ err = clGetKernelInfo (kernel, CL_KERNEL_NUM_ARGS, sizeof (num_args), &num_args,
1039
+ nullptr );
1040
+ if (err != CL_SUCCESS) {
1041
+ POCL_MSG_PRINT_PROXY (" Could not get number of kernel args.\n " );
1042
+ return err;
1043
+ }
1044
+
1045
+ if (num_args == 0 ) {
1046
+ meta->arg_info = nullptr ;
1047
+ meta->num_args = 0 ;
1048
+ return CL_SUCCESS;
1049
+ }
1050
+
1051
+ assert (num_args < 10000 );
1052
+
1053
+ meta->num_args = num_args;
1054
+ meta->arg_info =
1055
+ (pocl_argument_info *)calloc (num_args, sizeof (pocl_argument_info));
1056
+
1057
+ char empty_buffer[MAX_TESTED_ARG_SIZE];
1058
+
1059
+ TSParser *parser = ts_parser_new ();
1060
+ ts_parser_set_language (parser, tree_sitter_opencl ());
1061
+ TSTree *tree =
1062
+ ts_parser_parse_string (parser, nullptr , source, strlen (source));
1063
+ TSNode root_node = ts_tree_root_node (tree);
1064
+
1065
+ int32_t status = 0 ;
1066
+ TSNode kernel_node =
1067
+ pocl_ts_find_kernel_params (source, root_node, meta->name , &status);
1068
+ uint32_t child_count;
1069
+ if (status != CL_SUCCESS) {
1070
+ err = CL_KERNEL_ARG_INFO_NOT_AVAILABLE;
1071
+ POCL_MSG_WARN (" Could not find kernel name in source.\n " );
1072
+ goto TS_ERROR;
1073
+ }
1074
+ POCL_PRINT_TS_NODE (source, kernel_node);
1075
+ child_count = ts_node_named_child_count (kernel_node);
1076
+ assert (num_args == child_count);
1077
+
1078
+ TSNode child;
1079
+ for (cl_uint i = 0 ; i < num_args; ++i) {
1080
+ pocl_argument_info *pi = &meta->arg_info [i];
1081
+ child = ts_node_named_child (kernel_node, i);
1082
+ err = pocl_ts_map_node_to_arg_info (source, child, pi );
1083
+ if (err != CL_SUCCESS) {
1084
+ POCL_MSG_WARN (" Failed to parse %s arg %d.\n " , meta->name , i);
1085
+ goto TS_ERROR;
1086
+ }
1087
+
1088
+ POCL_MSG_PRINT_PROXY (" KERNEL %s ARGUMENT %u NAME %s "
1089
+ " TYPENAME %s TYPE %u SIZE %u\n " ,
1090
+ meta->name , i, pi ->name , pi ->type_name , pi ->type ,
1091
+ pi ->type_size );
1092
+ }
1093
+
1094
+ ts_tree_delete (tree);
1095
+ ts_parser_delete (parser);
1096
+ return CL_SUCCESS;
1097
+
1098
+ TS_ERROR:
1099
+ ts_tree_delete (tree);
1100
+ ts_parser_delete (parser);
1101
+ return err;
1102
+ }
1103
+ #endif
1104
+
986
1105
static void
987
1106
set_build_log (cl_device_id proxy_dev, cl_program program,
988
1107
cl_program proxy_prog, unsigned device_i)
@@ -1401,8 +1520,8 @@ pocl_proxy_setup_metadata (cl_device_id device, cl_program program,
1401
1520
cl_program proxy_prog = (cl_program)program->data [program_device_i];
1402
1521
1403
1522
// 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 )))
1523
+ if (!(d->backend ->provides_metadata || HAVE_TREE_SITTER ||
1524
+ (d->backend ->supports_il && program->program_il_size > 0 )))
1406
1525
return 0 ;
1407
1526
1408
1527
assert (program->kernel_meta == NULL );
@@ -1471,8 +1590,9 @@ pocl_proxy_setup_metadata (cl_device_id device, cl_program program,
1471
1590
index ++;
1472
1591
}
1473
1592
1474
- } else {
1593
+ } else if (d-> backend -> provides_metadata ) {
1475
1594
for (cl_uint i = 0 ; i < num_kernels; ++i) {
1595
+
1476
1596
err = get_kernel_metadata (p + i, program->num_devices , proxy_prog,
1477
1597
d->device_id , kernels[i]);
1478
1598
if (err != CL_SUCCESS) {
@@ -1484,6 +1604,24 @@ pocl_proxy_setup_metadata (cl_device_id device, cl_program program,
1484
1604
assert (err == CL_SUCCESS);
1485
1605
}
1486
1606
}
1607
+ #ifdef HAVE_TREE_SITTER
1608
+ else if (HAVE_TREE_SITTER) {
1609
+ for (cl_uint i = 0 ; i < num_kernels; i++) {
1610
+
1611
+ err = proxy_map_source_to_metadata (program->source , p + i,
1612
+ program->num_devices , d->device_id ,
1613
+ kernels[i]);
1614
+ if (err != CL_SUCCESS) {
1615
+ POCL_MSG_WARN (" Failed to kernel metadata for index %d.\n " , i);
1616
+ return 0 ;
1617
+ }
1618
+
1619
+ err = clReleaseKernel (kernels[i]);
1620
+ }
1621
+ }
1622
+ #endif
1623
+ else
1624
+ return 0 ;
1487
1625
1488
1626
program->kernel_meta = p;
1489
1627
0 commit comments