19 #if !defined(__TBB_show_deprecation_message_flow_graph_opencl_node_H) && defined(__TBB_show_deprecated_header_message)
20 #define __TBB_show_deprecation_message_flow_graph_opencl_node_H
21 #pragma message("TBB Warning: tbb/flow_graph_opencl_node.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.")
24 #if defined(__TBB_show_deprecated_header_message)
25 #undef __TBB_show_deprecated_header_message
28 #ifndef __TBB_flow_graph_opencl_node_H
29 #define __TBB_flow_graph_opencl_node_H
31 #define __TBB_flow_graph_opencl_node_H_include_area
35 #if __TBB_PREVIEW_OPENCL_NODE
48 #include <OpenCL/opencl.h>
56 namespace interface11 {
58 template <
typename DeviceFilter>
61 namespace opencl_info {
65 template <
typename Factory>
69 if (err != CL_SUCCESS) {
70 std::cerr << msg <<
"; error code: " << err << std::endl;
78 enforce_cl_retcode(clGetEventInfo(e, i,
sizeof(res), &res, NULL),
"Failed to get OpenCL event information");
85 enforce_cl_retcode(clGetDeviceInfo(
d, i,
sizeof(res), &res, NULL),
"Failed to get OpenCL device information");
90 inline std::string device_info<std::string>(cl_device_id
d, cl_device_info i) {
92 enforce_cl_retcode(clGetDeviceInfo(
d, i, 0, NULL, &required),
"Failed to get OpenCL device information");
94 char *buff = (
char*)alloca(required);
95 enforce_cl_retcode(clGetDeviceInfo(
d, i, required, buff, NULL),
"Failed to get OpenCL device information");
100 template <
typename T>
103 enforce_cl_retcode(clGetPlatformInfo(
p, i,
sizeof(res), &res, NULL),
"Failed to get OpenCL platform information");
108 inline std::string platform_info<std::string>(cl_platform_id
p, cl_platform_info i) {
110 enforce_cl_retcode(clGetPlatformInfo(
p, i, 0, NULL, &required),
"Failed to get OpenCL platform information");
112 char *buff = (
char*)alloca(required);
113 enforce_cl_retcode(clGetPlatformInfo(
p, i, required, buff, NULL),
"Failed to get OpenCL platform information");
127 opencl_device() : my_device_id( unknown ), my_cl_device_id( NULL ), my_cl_command_queue( NULL ) {}
129 opencl_device( cl_device_id d_id ) : my_device_id( unknown ), my_cl_device_id( d_id ), my_cl_command_queue( NULL ) {}
131 opencl_device( cl_device_id cl_d_id,
device_id_type device_id ) : my_device_id( device_id ), my_cl_device_id( cl_d_id ), my_cl_command_queue( NULL ) {}
134 return platform_info<std::string>( platform_id(), CL_PLATFORM_PROFILE );
137 return platform_info<std::string>( platform_id(), CL_PLATFORM_VERSION );
140 return platform_info<std::string>( platform_id(), CL_PLATFORM_NAME );
143 return platform_info<std::string>( platform_id(), CL_PLATFORM_VENDOR );
146 return platform_info<std::string>( platform_id(), CL_PLATFORM_EXTENSIONS );
149 template <
typename T>
150 void info( cl_device_info i, T &t )
const {
151 t = device_info<T>( my_cl_device_id, i );
155 return device_info<std::string>( my_cl_device_id, CL_DEVICE_VERSION );
159 std::sscanf( version().c_str(),
"OpenCL %d", &major );
164 std::sscanf( version().c_str(),
"OpenCL %d.%d", &major, &minor );
169 if ( major_version() >= 2 )
170 return (device_info<cl_command_queue_properties>( my_cl_device_id, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES ) & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) != 0;
173 return (device_info<cl_command_queue_properties>( my_cl_device_id, CL_DEVICE_QUEUE_PROPERTIES ) & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) != 0;
177 if ( major_version() >= 2 )
178 return (device_info<cl_command_queue_properties>( my_cl_device_id, CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES ) & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) != 0;
184 return device_info<std::array<size_t, 3>>( my_cl_device_id, CL_DEVICE_MAX_WORK_ITEM_SIZES );
187 return device_info<size_t>( my_cl_device_id, CL_DEVICE_MAX_WORK_GROUP_SIZE );
190 const std::string semi =
";";
192 return (semi + built_in_kernels() + semi).find( semi + k + semi ) != std::string::npos;
195 return device_info<std::string>( my_cl_device_id, CL_DEVICE_BUILT_IN_KERNELS );
198 return device_info<std::string>( my_cl_device_id, CL_DEVICE_NAME );
201 return device_info<cl_bool>( my_cl_device_id, CL_DEVICE_AVAILABLE );
204 return device_info<cl_bool>( my_cl_device_id, CL_DEVICE_COMPILER_AVAILABLE );
207 return device_info<cl_bool>( my_cl_device_id, CL_DEVICE_LINKER_AVAILABLE );
210 const std::string space =
" ";
212 return (space + extensions() + space).find( space + ext + space ) != std::string::npos;
215 return device_info<std::string>( my_cl_device_id, CL_DEVICE_EXTENSIONS );
219 return device_info<cl_device_type>( my_cl_device_id, CL_DEVICE_TYPE );
223 return device_info<std::string>( my_cl_device_id, CL_DEVICE_VENDOR );
227 return device_info<cl_uint>( my_cl_device_id, CL_DEVICE_ADDRESS_BITS );
231 return my_cl_device_id;
235 return my_cl_command_queue;
239 my_cl_command_queue = cmd_queue;
243 return device_info<cl_platform_id>( my_cl_device_id, CL_DEVICE_PLATFORM );
254 template <
typename DeviceFilter>
256 template <
typename Factory>
258 template <
typename Factory>
262 template <
typename T,
typename Factory>
279 bool empty()
const {
return my_container.empty(); }
297 cl_uint num_platforms;
298 enforce_cl_retcode(clGetPlatformIDs(0, NULL, &num_platforms),
"clGetPlatformIDs failed");
300 std::vector<cl_platform_id> platforms(num_platforms);
301 enforce_cl_retcode(clGetPlatformIDs(num_platforms, platforms.data(), NULL),
"clGetPlatformIDs failed");
304 std::vector<cl_platform_id>::iterator platforms_it = platforms.begin();
305 cl_uint num_all_devices = 0;
306 while (platforms_it != platforms.end()) {
307 cl_int err = clGetDeviceIDs(*platforms_it, CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
308 if (err == CL_DEVICE_NOT_FOUND) {
309 platforms_it = platforms.erase(platforms_it);
313 num_all_devices += num_devices;
318 std::vector<cl_device_id> devices(num_all_devices);
319 std::vector<cl_device_id>::iterator devices_it = devices.begin();
320 for (
auto p = platforms.begin();
p != platforms.end(); ++
p) {
321 enforce_cl_retcode(clGetDeviceIDs((*
p), CL_DEVICE_TYPE_ALL, (cl_uint)std::distance(devices_it, devices.end()), &*devices_it, &num_devices),
"clGetDeviceIDs failed");
322 devices_it += num_devices;
325 for (
auto d = devices.begin();
d != devices.end(); ++
d) {
329 return opencl_devices;
335 namespace opencl_info {
348 virtual void call() = 0;
352 template <
typename Callback,
typename T>
364 template <
typename T,
typename Factory = opencl_info::default_opencl_factory>
383 if ( my_is_event && wait ) {
391 const T&
data(
bool wait =
true )
const {
392 if ( my_is_event && wait ) {
401 my_data(dmsg.my_data), my_event(dmsg.my_event), my_is_event( dmsg.my_is_event ),
402 my_callback_flag_ptr(dmsg.my_callback_flag_ptr)
409 my_data(std::
move(dmsg.my_data)), my_event(dmsg.my_event), my_is_event(dmsg.my_is_event),
410 my_callback_flag_ptr( std::
move(dmsg.my_callback_flag_ptr) )
412 dmsg.my_is_event =
false;
439 cl_event
const *
get_event()
const {
return my_is_event ? &my_event : NULL; }
442 cl_command_queue cq = event_info<cl_command_queue>( my_event, CL_EVENT_COMMAND_QUEUE );
443 if ( cq != event_info<cl_command_queue>( e, CL_EVENT_COMMAND_QUEUE ) )
449 clRetainEvent( my_event );
454 enforce_cl_retcode( clFlush( event_info<cl_command_queue>( my_event, CL_EVENT_COMMAND_QUEUE ) ),
"Failed to flush an OpenCL command queue" );
460 template <
typename Callback>
462 __TBB_ASSERT( my_is_event,
"The OpenCL event is not set" );
466 operator T&() {
return data(); }
467 operator const T&()
const {
return data(); }
474 if (! my_callback_flag_ptr->fetch_and_store(
true)) {
477 register_callback([a](
const T& t)
mutable {
491 __TBB_ASSERT( event_command_exec_status == CL_COMPLETE, NULL );
500 mutable bool my_is_event =
false;
505 template <
typename K,
typename T,
typename Factory>
508 const T &t = dmsg.
data(
false );
510 return key_from_message<K, T>( t );
513 template <
typename Factory>
571 my_factory->enqueue_unmap_buffer(device, *
this,
d);
601 template <
typename Factory>
614 cl_buffer_region region = { index,
size };
615 this->
my_cl_mem = clCreateSubBuffer( m, 0, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &err );
624 this->
my_factory->enqueue_map_buffer( device, *
this, dmsg );
628 template <
typename,
typename>
639 template <
typename T,
typename Factory = opencl_info::default_opencl_factory>
643 template <
typename T,
typename Factory = opencl_info::default_opencl_factory>
653 template <access_type a>
655 T* ptr = (T*)my_impl->get_host_ptr();
660 T*
data()
const {
return &access<read_write>()[0]; }
662 template <access_type a = read_write>
665 template <access_type a = read_write>
668 size_t size()
const {
return my_impl->size()/
sizeof(T); }
670 T& operator[] ( ptrdiff_t k ) {
return begin()[k]; }
677 return my_impl->get_cl_mem();
687 const cl_event *e =
d.get_event();
694 const cl_event *e =
d.get_event();
714 template <
typename,
typename>
718 template <
typename T,
typename Factory>
725 opencl_buffer<T, Factory>( *owner.my_impl->factory(), owner.native_object(), index,
size ), my_owner( owner ) {}
728 template <
typename T,
typename Factory>
734 #define is_typedef(type) \
735 template <typename T> \
737 template <typename C> \
738 static std::true_type check( typename C::type* ); \
739 template <typename C> \
740 static std::false_type check( ... ); \
742 static const bool value = decltype(check<T>(0))::value; \
748 template <
typename T>
750 return t.native_object();
753 template <
typename T>
759 template <
typename T,
typename Factory>
761 const T &t = dmsg.
data(
false );
762 typedef typename T::memory_object_type mem_obj_t;
763 mem_obj_t mem_obj = t.memory_object();
766 mem_obj.send( device,
d );
767 if (
d.get_event() ) dmsg.
set_event( *
d.get_event() );
770 template <
typename T>
772 typedef typename T::memory_object_type mem_obj_t;
773 mem_obj_t mem_obj = t.memory_object();
775 mem_obj.send( device, dmsg );
778 template <
typename T>
782 template <
typename T,
typename Factory>
784 const T &t = dmsg.
data(
false );
785 typedef typename T::memory_object_type mem_obj_t;
786 mem_obj_t mem_obj = t.memory_object();
789 mem_obj.receive(
d );
790 if (
d.get_event() ) dmsg.
set_event( *
d.get_event() );
793 template <
typename T>
801 template <
typename G = std::initializer_list<
int>,
typename L = std::initializer_list<
int>,
802 typename =
typename std::enable_if<!std::is_same<
typename std::decay<G>::type, opencl_range>::value>::type>
803 opencl_range(G&& global_work = std::initializer_list<int>({ 0 }), L&& local_work = std::initializer_list<int>({ 0, 0, 0 })) {
804 auto g_it = global_work.begin();
805 auto l_it = local_work.begin();
806 my_global_work_size = { {size_t(-1), size_t(-1), size_t(-1)} };
808 for (
int s = 0;
s < 3 && g_it != global_work.end(); ++g_it, ++l_it, ++
s) {
809 __TBB_ASSERT(l_it != local_work.end(),
"global_work & local_work must have same size");
810 my_global_work_size[
s] = *g_it;
811 my_local_work_size[
s] = *l_it;
823 template <
typename DeviceFilter>
835 std::vector<char> kernel_name;
836 for (
size_t curr_size = 32;; curr_size <<= 1 ) {
837 kernel_name.resize( curr_size <<= 1 );
838 enforce_cl_retcode( clGetKernelInfo( k.
my_cl_kernel, CL_KERNEL_FUNCTION_NAME, curr_size, kernel_name.data(), &ret_size ),
"Failed to get kernel info" );
839 if ( ret_size < curr_size )
break;
862 template <
typename DeviceFilter_>
865 template <
typename Factory>
877 if ( my_devices.size() ) {
878 for (
auto d = my_devices.begin();
d != my_devices.end(); ++
d ) {
879 enforce_cl_retcode( clReleaseCommandQueue( (*d).my_cl_command_queue ),
"Failed to release a command queue" );
881 enforce_cl_retcode( clReleaseContext( my_cl_context ),
"Failed to release a context" );
887 if ( !my_devices.size() ) {
888 my_devices = device_list;
896 template <
typename Factory>
902 e1 == NULL ? 0 : 1, e1, &e2, &err );
904 dmsg.
data(
false ) = ptr;
910 template <
typename Factory>
916 "Failed to unmap a buffer" );
922 template <
size_t NUM_ARGS,
typename T>
925 enforce_cl_retcode( clSetKernelArg(kernel.my_cl_kernel, place++,
sizeof(
p), &
p),
"Failed to set a kernel argument" );
928 template <
size_t NUM_ARGS,
typename T,
typename F>
930 __TBB_ASSERT((
static_cast<typename std::array<cl_event, NUM_ARGS>::size_type
>(num_events) < events.size()), NULL);
932 const cl_event *
const e = msg.
get_event();
934 events[num_events++] = *e;
937 process_one_arg( kernel, events, num_events, place, msg.
data(
false) );
940 template <
size_t NUM_ARGS,
typename T,
typename ...Rest>
941 void process_arg_list(
const kernel_type& kernel, std::array<cl_event, NUM_ARGS>& events,
int& num_events,
int& place,
const T& t,
const Rest&... args ) {
942 process_one_arg( kernel, events, num_events, place, t );
943 process_arg_list( kernel, events, num_events, place, args... );
946 template <
size_t NUM_ARGS>
949 template <
typename T>
952 template <
typename T,
typename F>
957 template <
typename T,
typename ...Rest>
959 update_one_arg( e, t );
960 update_arg_list( e, args... );
966 template <
typename ...Args>
968 std::array<cl_event,
sizeof...(Args)> events;
971 process_arg_list( kernel, events, num_events, place, args... );
973 const cl_event e = send_kernel_impl( device, kernel.my_cl_kernel, work_size, num_events, events.data() );
975 update_arg_list(e, args...);
982 template <
typename T,
typename ...Rest>
985 send_data( device, args... );
993 const range_type& work_size, cl_uint num_events, cl_event* event_list ) {
998 for (
s = 1;
s < 3 && g_size[
s] != size_t(-1); ++
s) {}
1002 g_offset.data(), g_size.data(), l_size[0] ? l_size.data() : NULL, num_events, num_events ? event_list : NULL, &
event ),
1003 "Failed to enqueue a kernel" );
1008 template <
typename T>
1013 template <
typename T,
typename F>
1015 cl_event
const *e_ptr = msg.
get_event();
1017 if ( e_ptr != NULL ) {
1025 template <
typename T,
typename ...Rest>
1027 if ( get_event_from_one_arg( e, t ) ) {
1031 return get_event_from_args( e, args... );
1041 virtual void operator() () {}
1044 template<
typename Fn>
1053 __TBB_ASSERT(event_command_exec_status == CL_COMPLETE, NULL);
1055 finalize_fn *
const fn_ptr =
static_cast<finalize_fn*
>(
data);
1056 __TBB_ASSERT(fn_ptr != NULL,
"Invalid finalize function pointer");
1063 template <
typename FinalizeFn,
typename ...Args>
1067 if ( get_event_from_args( e, args... ) ) {
1069 new finalize_fn_leaf<FinalizeFn>(
fn) ),
"Failed to set a callback" );
1094 return my_cl_context;
1100 if (!my_devices.size())
1104 enforce_cl_retcode(my_devices.size() ? CL_SUCCESS : CL_INVALID_DEVICE,
"No devices in the device list");
1105 cl_platform_id platform_id = my_devices.begin()->platform_id();
1107 enforce_cl_retcode(it->platform_id() == platform_id ? CL_SUCCESS : CL_INVALID_PLATFORM,
"All devices should be in the same platform");
1109 std::vector<cl_device_id> cl_device_ids;
1110 for (
auto d = my_devices.begin();
d != my_devices.end(); ++
d) {
1111 cl_device_ids.push_back((*d).my_cl_device_id);
1114 cl_context_properties context_properties[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform_id, (cl_context_properties)NULL };
1116 cl_context ctx = clCreateContext(context_properties,
1117 (cl_uint)cl_device_ids.size(),
1118 cl_device_ids.data(),
1121 my_cl_context = ctx;
1123 size_t device_counter = 0;
1124 for (
auto d = my_devices.begin();
d != my_devices.end();
d++) {
1125 (*d).my_device_id = device_counter++;
1127 cl_command_queue cq;
1129 if ((*d).major_version() >= 2) {
1130 if ((*d).out_of_order_exec_mode_on_host_present()) {
1131 cl_queue_properties props[] = { CL_QUEUE_PROPERTIES, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, 0 };
1132 cq = clCreateCommandQueueWithProperties(ctx, (*d).my_cl_device_id, props, &err2);
1134 cl_queue_properties props[] = { 0 };
1135 cq = clCreateCommandQueueWithProperties(ctx, (*d).my_cl_device_id, props, &err2);
1140 cl_command_queue_properties props = (*d).out_of_order_exec_mode_on_host_present() ? CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE : 0;
1142 #if __TBB_GCC_WARNING_SUPPRESSION_PRESENT
1143 #pragma GCC diagnostic push
1144 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1146 #if _MSC_VER || __INTEL_COMPILER
1147 #pragma warning( push )
1148 #if __INTEL_COMPILER
1149 #pragma warning (disable: 1478)
1151 #pragma warning (disable: 4996)
1154 cq = clCreateCommandQueue(ctx, (*d).my_cl_device_id, props, &err2);
1155 #if _MSC_VER || __INTEL_COMPILER
1156 #pragma warning( pop )
1158 #if __TBB_GCC_WARNING_SUPPRESSION_PRESENT
1159 #pragma GCC diagnostic pop
1163 (*d).my_cl_command_queue = cq;
1173 template <
typename Factory>
1175 template <
typename Factory>
1177 template <
typename Factory>
1182 namespace opencl_info {
1186 template <
typename Factory>
1189 __TBB_ASSERT(!f.devices().empty(),
"No available devices");
1190 return *(f.devices().begin());
1197 cl_platform_id platform_id = devices.
begin()->platform_id();
1199 if (it->platform_id() == platform_id) {
1224 template <
typename T,
typename Factory>
1234 template <
typename Factory = opencl_info::default_opencl_factory>
1250 std::call_once( my_do_once_flag, [](){} );
1254 return kernel_type( get_cl_kernel(k), my_factory );
1258 opencl_program( Factory& factory, cl_program program ) : my_factory( factory ), my_cl_program( program ) {
1260 std::call_once( my_do_once_flag, [](){} );
1264 std::call_once( my_do_once_flag, [
this, &k](){ this->init( k ); } );
1266 cl_kernel kernel = clCreateKernel( my_cl_program, k.c_str(), &err );
1274 std::ifstream file_descriptor( filepath, std::ifstream::binary );
1275 if ( !file_descriptor.is_open() ) {
1276 std::string str = std::string(
"Could not open file: " ) + filepath;
1277 std::cerr << str << std::endl;
1280 file_descriptor.seekg( 0, file_descriptor.end );
1281 size_t length = size_t( file_descriptor.tellg() );
1282 file_descriptor.seekg( 0, file_descriptor.beg );
1283 my_content.resize(
length );
1284 char*
begin = &*my_content.begin();
1286 file_descriptor.close();
1288 const char*
content() {
return &*my_content.cbegin(); }
1289 size_t length() {
return my_content.length(); }
1296 typedef void (CL_CALLBACK *cl_callback_type)(cl_program,
void*);
1298 cl_uint num_devices, cl_device_id* device_list,
1299 const char* options, cl_callback_type
callback,
1301 cl_int err = clBuildProgram( program, num_devices, device_list, options,
1303 if( err == CL_SUCCESS )
1305 std::string str = std::string(
"Failed to build program: " ) +
name;
1306 if ( err == CL_BUILD_PROGRAM_FAILURE ) {
1308 for (
auto d = devices.
begin();
d != devices.
end(); ++
d ) {
1309 std::cerr <<
"Build log for device: " << (*d).name() << std::endl;
1311 cl_int query_err = clGetProgramBuildInfo(
1312 program, (*d).my_cl_device_id, CL_PROGRAM_BUILD_LOG, 0, NULL,
1316 std::vector<char> output;
1317 output.resize( log_size );
1318 query_err = clGetProgramBuildInfo(
1319 program, (*d).my_cl_device_id, CL_PROGRAM_BUILD_LOG,
1320 output.size(), output.data(), NULL );
1322 std::cerr << output.data() << std::endl;
1324 std::cerr <<
"No build log available" << std::endl;
1334 template<
typename Filter>
1336 Filter
filter,
const char* message ) {
1337 for ( cl_uint i = 0; i < num_devices; ++i )
1338 if (
filter(device_list[i]) ) {
1339 device_list[i--] = device_list[--num_devices];
1346 void init(
const std::string& )
const {
1347 cl_uint num_devices;
1348 enforce_cl_retcode( clGetContextInfo( my_factory.context(), CL_CONTEXT_NUM_DEVICES,
sizeof( num_devices ), &num_devices, NULL ),
1349 "Failed to get OpenCL context info" );
1352 cl_device_id *device_list = (cl_device_id *)alloca( num_devices*
sizeof( cl_device_id ) );
1353 enforce_cl_retcode( clGetContextInfo( my_factory.context(), CL_CONTEXT_DEVICES, num_devices*
sizeof( cl_device_id ), device_list, NULL ),
1354 "Failed to get OpenCL context info" );
1355 const char *options = NULL;
1356 switch ( my_type ) {
1359 const char *
s[] = { fr.
content() };
1360 const size_t l[] = { fr.
length() };
1362 my_cl_program = clCreateProgramWithSource( my_factory.context(), 1,
s, l, &err );
1365 num_devices, device_list,
1367 return !
d.compiler_available() || !
d.linker_available();
1368 },
"No one device supports building program from sources" );
1370 my_factory, my_arg_str, my_cl_program, num_devices, device_list,
1371 options, NULL, NULL );
1375 options =
"-x spir";
1378 std::vector<const unsigned char*>
s(
1379 num_devices,
reinterpret_cast<const unsigned char*
>(fr.
content()) );
1380 std::vector<size_t> l( num_devices, fr.
length() );
1381 std::vector<cl_int> bin_statuses( num_devices, -1 );
1383 my_cl_program = clCreateProgramWithBinary( my_factory.context(), num_devices,
1384 device_list, l.data(),
s.data(),
1385 bin_statuses.data(), &err );
1386 if( err != CL_SUCCESS ) {
1387 std::string statuses_str;
1388 for (
auto st = bin_statuses.begin(); st != bin_statuses.end(); ++st) {
1389 statuses_str += std::to_string((*st));
1392 enforce_cl_retcode( err, std::string(
"Failed to create program, error " + std::to_string( err ) +
" : " ) + my_arg_str +
1393 std::string(
", binary_statuses = " ) + statuses_str );
1396 my_factory, my_arg_str, my_cl_program, num_devices, device_list,
1397 options, NULL, NULL );
1411 template <
typename DeviceFilter>
1414 friend class Factory::kernel;
1417 template<
typename... Args>
1420 template<
typename JP,
typename Factory,
typename... Ports>
1428 :
base_type( g, kernel, opencl_info::default_device_selector< opencl_info::default_opencl_factory >(), opencl_info::
default_factory() )
1434 :
base_type( g, kernel, opencl_info::default_device_selector <Factory >(), f )
1439 template <
typename DeviceSelector>
1447 template<
typename JP,
typename... Ports>
1449 opencl_node< tuple<Ports...>, JP > :
public opencl_node < tuple<Ports...>, JP, opencl_info::default_opencl_factory > {
1455 :
base_type( g, kernel, opencl_info::default_device_selector< opencl_info::default_opencl_factory >(), opencl_info::
default_factory() )
1458 template <
typename DeviceSelector>
1464 template<
typename... Ports>
1466 opencl_node< tuple<Ports...> > :
public opencl_node < tuple<Ports...>, queueing, opencl_info::default_opencl_factory > {
1472 :
base_type( g, kernel, opencl_info::default_device_selector< opencl_info::default_opencl_factory >(), opencl_info::
default_factory() )
1475 template <
typename DeviceSelector>
1487 using interface11::opencl_buffer;
1489 using interface11::opencl_device;
1490 using interface11::opencl_device_list;
1491 using interface11::opencl_program;
1493 using interface11::opencl_async_msg;
1494 using interface11::opencl_factory;
1495 using interface11::opencl_range;
1502 #undef __TBB_flow_graph_opencl_node_H_include_area
1504 #endif // __TBB_flow_graph_opencl_node_H