@@ -1348,25 +1348,56 @@ int c_dbcsr_acc_opencl_flags_atomics(const c_dbcsr_acc_opencl_device_t* devinfo,
13481348}
13491349
13501350
1351- int c_dbcsr_acc_opencl_flags (
1352- const char build_params [], const char build_options [], const char try_build_options [], char buffer [], size_t buffer_size ) {
1351+ int c_dbcsr_acc_opencl_defines (const char defines [], char buffer [], size_t buffer_size , int cleanup ) {
13531352 const c_dbcsr_acc_opencl_device_t * const devinfo = & c_dbcsr_acc_opencl_config .device ;
1354- int result = EXIT_SUCCESS ;
1355- assert (NULL != devinfo -> context );
1356- if (NULL != buffer ) {
1353+ int result = 0 ;
1354+ if (NULL != buffer && NULL != devinfo -> context ) {
13571355 const int std_clevel = 100 * devinfo -> std_clevel [0 ] + 10 * devinfo -> std_clevel [1 ];
13581356 const int std_level = 100 * devinfo -> std_level [0 ] + 10 * devinfo -> std_level [1 ];
1359- const int nchar = LIBXSMM_SNPRINTF (buffer , buffer_size , "%s -DACC_OPENCL_VERSION=%u -DACC_OPENCL_C_VERSION=%u %s %s %s %s" ,
1360- devinfo -> std_flag , std_level , std_clevel , 0 != c_dbcsr_acc_opencl_config .debug ? "-DNDEBUG" : "" ,
1361- NULL != build_options ? build_options : "" , NULL != build_params ? build_params : "" ,
1362- NULL != try_build_options ? try_build_options : "" );
1363- if (0 < nchar && (int )buffer_size > nchar ) {
1364- char * replace = strpbrk (buffer , "\"" ); /* more portable (system/cpp needs quotes to protect braces) */
1365- for (; NULL != replace ; replace = strpbrk (replace + 1 , "\"" )) * replace = ' ' ;
1357+ result = LIBXSMM_SNPRINTF (buffer , buffer_size , " -DACC_OPENCL_VERSION=%u -DACC_OPENCL_C_VERSION=%u%s" , std_level , std_clevel ,
1358+ 0 == c_dbcsr_acc_opencl_config .debug ? " -DNDEBUG" : "" );
1359+ if (0 < result && (int )buffer_size > result ) {
1360+ const int n = LIBXSMM_SNPRINTF (
1361+ buffer + result , buffer_size - result , ' ' != buffer [result - 1 ] ? " %s" : "%s" , NULL != defines ? defines : "" );
1362+ if (0 <= n ) {
1363+ if ((int )buffer_size > (result += n ) && 0 != cleanup ) {
1364+ char * replace = strpbrk (buffer + result - n , "\"" ); /* more portable (system/cpp needs quotes to protect braces) */
1365+ for (; NULL != replace ; replace = strpbrk (replace + 1 , "\"" )) * replace = ' ' ;
1366+ }
1367+ }
1368+ else result = -1 ;
13661369 }
1367- else {
1368- result = EXIT_FAILURE ;
1369- * buffer = '\0' ;
1370+ }
1371+ else result = -1 ;
1372+ return result ;
1373+ }
1374+
1375+
1376+ int c_dbcsr_acc_opencl_kernel_flags (const char build_params [], const char build_options [], const char try_options [],
1377+ cl_program program , char buffer [], size_t buffer_size ) {
1378+ const c_dbcsr_acc_opencl_device_t * const devinfo = & c_dbcsr_acc_opencl_config .device ;
1379+ int result = EXIT_SUCCESS , nchar = 0 ;
1380+ assert (NULL != program && (NULL != buffer || 0 == buffer_size ));
1381+ nchar = c_dbcsr_acc_opencl_defines (build_params , buffer , buffer_size , 1 /*cleanup*/ );
1382+ if (0 <= nchar && (int )buffer_size > nchar ) {
1383+ const int debug = (0 != c_dbcsr_acc_opencl_config .debug && 0 != devinfo -> intel && CL_DEVICE_TYPE_CPU != devinfo -> type );
1384+ int n = LIBXSMM_SNPRINTF (buffer + nchar , buffer_size - nchar , " %s%s %s" , 0 == debug ? "" : "-gline-tables-only " ,
1385+ devinfo -> std_flag , NULL != build_options ? build_options : "" );
1386+ if (0 <= n ) {
1387+ nchar += n ;
1388+ if (NULL != try_options && '\0' != * try_options ) { /* length is not reported in result */
1389+ n = LIBXSMM_SNPRINTF (buffer + nchar , buffer_size - nchar , " %s" , try_options );
1390+ if (0 > n || (int )buffer_size <= (nchar + n )) buffer [nchar ] = '\0' ;
1391+ }
1392+ }
1393+ else nchar = n ;
1394+ }
1395+ if (0 <= nchar && (int )buffer_size > nchar ) { /* check if internal flags apply */
1396+ const cl_device_id device_id = c_dbcsr_acc_opencl_config .devices [c_dbcsr_acc_opencl_config .device_id ];
1397+ result = clBuildProgram (program , 1 /*num_devices*/ , & device_id , buffer , NULL /*callback*/ , NULL /*user_data*/ );
1398+ if (EXIT_SUCCESS != result ) { /* failed to apply internal flags */
1399+ ACC_OPENCL_EXPECT (EXIT_SUCCESS == clReleaseProgram (program )); /* avoid unclean state */
1400+ buffer [nchar ] = '\0' ; /* remove internal flags */
13701401 }
13711402 }
13721403 else result = EXIT_FAILURE ;
@@ -1375,13 +1406,13 @@ int c_dbcsr_acc_opencl_flags(
13751406
13761407
13771408int c_dbcsr_acc_opencl_kernel (int source_is_file , const char source [], const char kernel_name [], const char build_params [],
1378- const char build_options [], const char try_build_options [], int * try_ok , const char * const extnames [], size_t num_exts ,
1409+ const char build_options [], const char try_options [], int * try_ok , const char * const extnames [], size_t num_exts ,
13791410 cl_kernel * kernel ) {
13801411 char buffer [ACC_OPENCL_BUFFERSIZE ] = "" , buffer_name [ACC_OPENCL_MAXSTRLEN * 2 ];
1381- int ok = EXIT_SUCCESS , source_is_cl = 1 , nchar ;
1382- int result = ((NULL != source && NULL != kernel_name && '\0' != * kernel_name ) ? EXIT_SUCCESS : EXIT_FAILURE );
13831412 const cl_device_id device_id = c_dbcsr_acc_opencl_config .devices [c_dbcsr_acc_opencl_config .device_id ];
13841413 const c_dbcsr_acc_opencl_device_t * const devinfo = & c_dbcsr_acc_opencl_config .device ;
1414+ int result = ((NULL != source && NULL != kernel_name && '\0' != * kernel_name ) ? EXIT_SUCCESS : EXIT_FAILURE );
1415+ int ok = EXIT_SUCCESS , source_is_cl = 1 , nchar = 0 ;
13851416 size_t size_src = 0 , size = 0 ;
13861417 cl_program program = NULL ;
13871418 FILE * file_src = NULL ;
@@ -1434,9 +1465,6 @@ int c_dbcsr_acc_opencl_kernel(int source_is_file, const char source[], const cha
14341465 if (NULL != ext_source_buffer ) {
14351466 for (n = 0 ; 0 < num_exts ; -- num_exts ) {
14361467 if (NULL != extnames [num_exts - 1 ]) {
1437- # if !defined(NDEBUG )
1438- const cl_device_id device_id = c_dbcsr_acc_opencl_config .devices [c_dbcsr_acc_opencl_config .device_id ];
1439- # endif
14401468 const char * const end = buffer_name + strlen (extnames [num_exts - 1 ]); /* before strtok */
14411469 char * ext = strtok (
14421470 strncpy (buffer_name , extnames [num_exts - 1 ], ACC_OPENCL_MAXSTRLEN * 2 - 1 ), ACC_OPENCL_DELIMS " \t" );
@@ -1516,8 +1544,6 @@ int c_dbcsr_acc_opencl_kernel(int source_is_file, const char source[], const cha
15161544 }
15171545# if defined(ACC_OPENCL_CPPBIN )
15181546 if (NULL != file_cpp && 0 <= file_dmp ) { /* preprocess source-code */
1519- const int std_clevel = 100 * devinfo -> std_clevel [0 ] + 10 * devinfo -> std_clevel [1 ];
1520- const int std_level = 100 * devinfo -> std_level [0 ] + 10 * devinfo -> std_level [1 ];
15211547 const char * sed_pattern = "" ;
15221548# if defined(ACC_OPENCL_SEDBIN )
15231549 FILE * const file_sed = fopen (ACC_OPENCL_SEDBIN , "rb" );
@@ -1526,10 +1552,16 @@ int c_dbcsr_acc_opencl_kernel(int source_is_file, const char source[], const cha
15261552 fclose (file_sed ); /* existence-check */
15271553 }
15281554# endif
1529- nchar = LIBXSMM_SNPRINTF (buffer , ACC_OPENCL_BUFFERSIZE ,
1530- ACC_OPENCL_CPPBIN " -P -C -nostdinc -DACC_OPENCL_VERSION=%u -DACC_OPENCL_C_VERSION=%u %s %s %s %s >%s" , std_level ,
1531- std_clevel , 0 == devinfo -> nv ? "" : "-D__NV_CL_C_VERSION" , NULL != build_params ? build_params : "" , buffer_name ,
1532- sed_pattern , dump_filename );
1555+ nchar = LIBXSMM_SNPRINTF (
1556+ buffer , ACC_OPENCL_BUFFERSIZE , ACC_OPENCL_CPPBIN " -P -C -nostdinc %s" , 0 == devinfo -> nv ? "" : "-D__NV_CL_C_VERSION " );
1557+ if (0 < nchar && ACC_OPENCL_BUFFERSIZE > nchar ) {
1558+ int n = c_dbcsr_acc_opencl_defines (build_params , buffer + nchar , ACC_OPENCL_BUFFERSIZE - nchar , 0 /*cleanup*/ );
1559+ if (0 <= n && ACC_OPENCL_BUFFERSIZE > (nchar += n )) {
1560+ n = LIBXSMM_SNPRINTF (buffer + nchar , ACC_OPENCL_BUFFERSIZE - nchar ,
1561+ ' ' != buffer [nchar - 1 ] ? " %s %s >%s" : "%s %s >%s" , buffer_name , sed_pattern , dump_filename );
1562+ }
1563+ nchar = (0 <= n ? nchar : 0 ) + n ;
1564+ }
15331565 if (0 < nchar && ACC_OPENCL_BUFFERSIZE > nchar && EXIT_SUCCESS == system (buffer )) {
15341566 FILE * const file = fopen (dump_filename , "r" );
15351567 if (NULL != file ) {
@@ -1559,44 +1591,20 @@ int c_dbcsr_acc_opencl_kernel(int source_is_file, const char source[], const cha
15591591 }
15601592 }
15611593 program = clCreateProgramWithSource (devinfo -> context , 1 /*nlines*/ , & ext_source , NULL , & result );
1594+ assert (EXIT_SUCCESS != result || NULL != program );
15621595 if (EXIT_SUCCESS == result ) {
1563- assert (NULL != program );
1564- if (0 != devinfo -> intel && 0x0bd0 <= devinfo -> uid && 0x0bdb >= devinfo -> uid ) {
1565- nchar = LIBXSMM_SNPRINTF (buffer , ACC_OPENCL_BUFFERSIZE , "-igc_opts 'VISAOptions=-PVCSendWARWA'" );
1566- }
1567- else nchar = 0 ; /* no need to apply/check internal flags */
1568- if (0 < nchar && ACC_OPENCL_BUFFERSIZE > nchar ) { /* check if internal flags apply */
1569- result = c_dbcsr_acc_opencl_flags (build_params , build_options , NULL , buffer + nchar , ACC_OPENCL_BUFFERSIZE - nchar );
1570- if (EXIT_SUCCESS == result ) {
1571- result = clBuildProgram (program , 1 /*num_devices*/ , & device_id , buffer + nchar , NULL /*callback*/ , NULL /*user_data*/ );
1572- if (EXIT_SUCCESS == result ) {
1573- ACC_OPENCL_EXPECT (EXIT_SUCCESS == clReleaseProgram (program )); /* avoid unclean state */
1574- program = clCreateProgramWithSource (devinfo -> context , 1 /*nlines*/ , & ext_source , NULL , & result );
1575- assert (EXIT_SUCCESS != result || NULL != program );
1576- }
1577- else nchar = 0 ; /* failed to apply internal flags */
1578- }
1579- }
1580- if (EXIT_SUCCESS == result ) {
1581- result = c_dbcsr_acc_opencl_flags (
1582- build_params , build_options , try_build_options , buffer + nchar , ACC_OPENCL_BUFFERSIZE - nchar );
1583- }
1584- if (EXIT_SUCCESS == result ) {
1585- result = clBuildProgram (program , 1 /*num_devices*/ , & device_id , buffer + nchar , NULL /*callback*/ , NULL /*user_data*/ );
1586- }
1587- if (EXIT_SUCCESS != result && NULL != try_build_options && '\0' != * try_build_options ) {
1588- result = c_dbcsr_acc_opencl_flags (
1589- build_params , build_options , NULL /*try_build_options*/ , buffer + nchar , ACC_OPENCL_BUFFERSIZE );
1596+ ok = c_dbcsr_acc_opencl_kernel_flags (build_params , build_options , try_options , program , buffer , ACC_OPENCL_BUFFERSIZE );
1597+ if (EXIT_SUCCESS == ok ) result = ok ;
1598+ else {
1599+ program = clCreateProgramWithSource (devinfo -> context , 1 /*nlines*/ , & ext_source , NULL , & result );
1600+ assert (EXIT_SUCCESS != result || NULL != program );
15901601 if (EXIT_SUCCESS == result ) {
1591- ACC_OPENCL_EXPECT (EXIT_SUCCESS == clReleaseProgram (program )); /* avoid unclean state */
1592- program = clCreateProgramWithSource (devinfo -> context , 1 /*nlines*/ , & ext_source , NULL , & result );
1593- assert (EXIT_SUCCESS != result || NULL != program );
1594- if (EXIT_SUCCESS == result ) {
1595- result = clBuildProgram (program , 1 /*num_devices*/ , & device_id , buffer + nchar , NULL /*callback*/ , NULL /*user_data*/ );
1596- }
1602+ result = clBuildProgram (program , 1 /*num_devices*/ , & device_id , buffer , NULL /*callback*/ , NULL /*user_data*/ );
1603+ ok = EXIT_FAILURE ;
15971604 }
1598- ok = EXIT_FAILURE ;
15991605 }
1606+ }
1607+ if (EXIT_SUCCESS == result ) {
16001608 if (source != ext_source ) {
16011609 void * p = NULL ;
16021610 LIBXSMM_ASSIGN127 (& p , & ext_source );
@@ -1648,44 +1656,38 @@ int c_dbcsr_acc_opencl_kernel(int source_is_file, const char source[], const cha
16481656 program = clCreateProgramWithBinary (
16491657 devinfo -> context , 1 , & device_id , & size_src , (const unsigned char * * )& source , NULL /*binary_status*/ , & result );
16501658 }
1659+ assert (EXIT_SUCCESS != result || NULL != program );
16511660 if (EXIT_SUCCESS == result ) {
1652- assert (NULL != program );
1653- result = c_dbcsr_acc_opencl_flags (build_params , build_options , try_build_options , buffer , ACC_OPENCL_BUFFERSIZE );
1654- if (EXIT_SUCCESS == result ) {
1655- result = clBuildProgram (program , 1 /*num_devices*/ , & device_id , buffer , NULL /*callback*/ , NULL /*user_data*/ );
1656- }
1657- if (EXIT_SUCCESS != result && NULL != try_build_options && '\0' != * try_build_options ) {
1658- result = c_dbcsr_acc_opencl_flags (build_params , build_options , NULL /*try_build_options*/ , buffer , ACC_OPENCL_BUFFERSIZE );
1659- if (EXIT_SUCCESS == result ) {
1660- ACC_OPENCL_EXPECT (EXIT_SUCCESS == clReleaseProgram (program )); /* avoid unclean state */
1661+ ok = c_dbcsr_acc_opencl_kernel_flags (build_params , build_options , try_options , program , buffer , ACC_OPENCL_BUFFERSIZE );
1662+ if (EXIT_SUCCESS == ok ) result = ok ;
1663+ else {
16611664# if defined(CL_VERSION_2_1 )
1662- if (0 != c_dbcsr_acc_opencl_config .dump ) program = clCreateProgramWithIL (devinfo -> context , source , size_src , & result );
1663- else
1665+ if (0 != c_dbcsr_acc_opencl_config .dump ) program = clCreateProgramWithIL (devinfo -> context , source , size_src , & result );
1666+ else
16641667# endif
1665- {
1666- program = clCreateProgramWithBinary (
1667- devinfo -> context , 1 , & device_id , & size_src , (const unsigned char * * )& source , NULL /*binary_status*/ , & result );
1668- }
1669- assert (EXIT_SUCCESS != result || NULL != program );
1670- if (EXIT_SUCCESS == result ) {
1671- result = clBuildProgram (program , 1 /*num_devices*/ , & device_id , buffer , NULL /*callback*/ , NULL /*user_data*/ );
1672- }
1668+ {
1669+ program = clCreateProgramWithBinary (
1670+ devinfo -> context , 1 , & device_id , & size_src , (const unsigned char * * )& source , NULL /*binary_status*/ , & result );
1671+ }
1672+ assert (EXIT_SUCCESS != result || NULL != program );
1673+ if (EXIT_SUCCESS == result ) {
1674+ result = clBuildProgram (program , 1 /*num_devices*/ , & device_id , buffer , NULL /*callback*/ , NULL /*user_data*/ );
1675+ ok = EXIT_FAILURE ;
16731676 }
1674- ok = EXIT_FAILURE ;
16751677 }
1676- if (EXIT_SUCCESS == result ) {
1677- * kernel = clCreateKernel (program , kernel_name , & result );
1678+ }
1679+ if (EXIT_SUCCESS == result ) {
1680+ * kernel = clCreateKernel (program , kernel_name , & result );
16781681# if defined(CL_VERSION_1_2 )
1679- /* error creating kernel: discover available kernels in program, and adopt the last kernel listed */
1680- if (EXIT_SUCCESS != result &&
1681- EXIT_SUCCESS == clGetProgramInfo (program , CL_PROGRAM_KERNEL_NAMES , sizeof (char * ), buffer , NULL ) && '\0' != * buffer )
1682- {
1683- const char * const semicolon = strrchr (buffer , ';' ), * const name = (NULL == semicolon ? buffer : (semicolon + 1 ));
1684- * kernel = clCreateKernel (program , name , & result );
1685- }
1686- # endif
1687- assert (EXIT_SUCCESS != result || NULL != * kernel );
1682+ /* error creating kernel: discover available kernels in program, and adopt the last kernel listed */
1683+ if (EXIT_SUCCESS != result &&
1684+ EXIT_SUCCESS == clGetProgramInfo (program , CL_PROGRAM_KERNEL_NAMES , sizeof (char * ), buffer , NULL ) && '\0' != * buffer )
1685+ {
1686+ const char * const semicolon = strrchr (buffer , ';' ), * const name = (NULL == semicolon ? buffer : (semicolon + 1 ));
1687+ * kernel = clCreateKernel (program , name , & result );
16881688 }
1689+ # endif
1690+ assert (EXIT_SUCCESS != result || NULL != * kernel );
16891691 }
16901692 }
16911693 if (NULL != file_src ) {
0 commit comments