OpenCL C++ Bindings
Loading...
Searching...
No Matches
opencl.hpp
Go to the documentation of this file.
1//
2// Copyright (c) 2008-2024 The Khronos Group Inc.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
324
336
392#ifndef CL_HPP_
393#define CL_HPP_
394
395/* Handle deprecated preprocessor definitions. In each case, we only check for
396 * the old name if the new name is not defined, so that user code can define
397 * both and hence work with either version of the bindings.
398 */
399#if !defined(CL_HPP_USE_DX_INTEROP) && defined(USE_DX_INTEROP)
400# pragma message("opencl.hpp: USE_DX_INTEROP is deprecated. Define CL_HPP_USE_DX_INTEROP instead")
401# define CL_HPP_USE_DX_INTEROP
402#endif
403#if !defined(CL_HPP_ENABLE_EXCEPTIONS) && defined(__CL_ENABLE_EXCEPTIONS)
404# pragma message("opencl.hpp: __CL_ENABLE_EXCEPTIONS is deprecated. Define CL_HPP_ENABLE_EXCEPTIONS instead")
405# define CL_HPP_ENABLE_EXCEPTIONS
406#endif
407#if !defined(CL_HPP_NO_STD_VECTOR) && defined(__NO_STD_VECTOR)
408# pragma message("opencl.hpp: __NO_STD_VECTOR is deprecated. Define CL_HPP_NO_STD_VECTOR instead")
409# define CL_HPP_NO_STD_VECTOR
410#endif
411#if !defined(CL_HPP_NO_STD_STRING) && defined(__NO_STD_STRING)
412# pragma message("opencl.hpp: __NO_STD_STRING is deprecated. Define CL_HPP_NO_STD_STRING instead")
413# define CL_HPP_NO_STD_STRING
414#endif
415#if defined(VECTOR_CLASS)
416# pragma message("opencl.hpp: VECTOR_CLASS is deprecated. Alias cl::vector instead")
417#endif
418#if defined(STRING_CLASS)
419# pragma message("opencl.hpp: STRING_CLASS is deprecated. Alias cl::string instead.")
420#endif
421#if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS) && defined(__CL_USER_OVERRIDE_ERROR_STRINGS)
422# pragma message("opencl.hpp: __CL_USER_OVERRIDE_ERROR_STRINGS is deprecated. Define CL_HPP_USER_OVERRIDE_ERROR_STRINGS instead")
423# define CL_HPP_USER_OVERRIDE_ERROR_STRINGS
424#endif
425
426/* Warn about features that are no longer supported
427 */
428#if defined(__USE_DEV_VECTOR)
429# pragma message("opencl.hpp: __USE_DEV_VECTOR is no longer supported. Expect compilation errors")
430#endif
431#if defined(__USE_DEV_STRING)
432# pragma message("opencl.hpp: __USE_DEV_STRING is no longer supported. Expect compilation errors")
433#endif
434
435/* Detect which version to target */
436#if !defined(CL_HPP_TARGET_OPENCL_VERSION)
437# pragma message("opencl.hpp: CL_HPP_TARGET_OPENCL_VERSION is not defined. It will default to 300 (OpenCL 3.0)")
438# define CL_HPP_TARGET_OPENCL_VERSION 300
439#endif
440#if CL_HPP_TARGET_OPENCL_VERSION != 100 && \
441 CL_HPP_TARGET_OPENCL_VERSION != 110 && \
442 CL_HPP_TARGET_OPENCL_VERSION != 120 && \
443 CL_HPP_TARGET_OPENCL_VERSION != 200 && \
444 CL_HPP_TARGET_OPENCL_VERSION != 210 && \
445 CL_HPP_TARGET_OPENCL_VERSION != 220 && \
446 CL_HPP_TARGET_OPENCL_VERSION != 300
447# pragma message("opencl.hpp: CL_HPP_TARGET_OPENCL_VERSION is not a valid value (100, 110, 120, 200, 210, 220 or 300). It will be set to 300 (OpenCL 3.0).")
448# undef CL_HPP_TARGET_OPENCL_VERSION
449# define CL_HPP_TARGET_OPENCL_VERSION 300
450#endif
451
452/* Forward target OpenCL version to C headers if necessary */
453#if defined(CL_TARGET_OPENCL_VERSION)
454/* Warn if prior definition of CL_TARGET_OPENCL_VERSION is lower than
455 * requested C++ bindings version */
456#if CL_TARGET_OPENCL_VERSION < CL_HPP_TARGET_OPENCL_VERSION
457# pragma message("CL_TARGET_OPENCL_VERSION is already defined as is lower than CL_HPP_TARGET_OPENCL_VERSION")
458#endif
459#else
460# define CL_TARGET_OPENCL_VERSION CL_HPP_TARGET_OPENCL_VERSION
461#endif
462
463#if !defined(CL_HPP_MINIMUM_OPENCL_VERSION)
464# define CL_HPP_MINIMUM_OPENCL_VERSION 200
465#endif
466#if CL_HPP_MINIMUM_OPENCL_VERSION != 100 && \
467 CL_HPP_MINIMUM_OPENCL_VERSION != 110 && \
468 CL_HPP_MINIMUM_OPENCL_VERSION != 120 && \
469 CL_HPP_MINIMUM_OPENCL_VERSION != 200 && \
470 CL_HPP_MINIMUM_OPENCL_VERSION != 210 && \
471 CL_HPP_MINIMUM_OPENCL_VERSION != 220 && \
472 CL_HPP_MINIMUM_OPENCL_VERSION != 300
473# pragma message("opencl.hpp: CL_HPP_MINIMUM_OPENCL_VERSION is not a valid value (100, 110, 120, 200, 210, 220 or 300). It will be set to 100")
474# undef CL_HPP_MINIMUM_OPENCL_VERSION
475# define CL_HPP_MINIMUM_OPENCL_VERSION 100
476#endif
477#if CL_HPP_MINIMUM_OPENCL_VERSION > CL_HPP_TARGET_OPENCL_VERSION
478# error "CL_HPP_MINIMUM_OPENCL_VERSION must not be greater than CL_HPP_TARGET_OPENCL_VERSION"
479#endif
480
481#if CL_HPP_MINIMUM_OPENCL_VERSION <= 100 && !defined(CL_USE_DEPRECATED_OPENCL_1_0_APIS)
482# define CL_USE_DEPRECATED_OPENCL_1_0_APIS
483#endif
484#if CL_HPP_MINIMUM_OPENCL_VERSION <= 110 && !defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
485# define CL_USE_DEPRECATED_OPENCL_1_1_APIS
486#endif
487#if CL_HPP_MINIMUM_OPENCL_VERSION <= 120 && !defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
488# define CL_USE_DEPRECATED_OPENCL_1_2_APIS
489#endif
490#if CL_HPP_MINIMUM_OPENCL_VERSION <= 200 && !defined(CL_USE_DEPRECATED_OPENCL_2_0_APIS)
491# define CL_USE_DEPRECATED_OPENCL_2_0_APIS
492#endif
493#if CL_HPP_MINIMUM_OPENCL_VERSION <= 210 && !defined(CL_USE_DEPRECATED_OPENCL_2_1_APIS)
494# define CL_USE_DEPRECATED_OPENCL_2_1_APIS
495#endif
496#if CL_HPP_MINIMUM_OPENCL_VERSION <= 220 && !defined(CL_USE_DEPRECATED_OPENCL_2_2_APIS)
497# define CL_USE_DEPRECATED_OPENCL_2_2_APIS
498#endif
499
500#ifdef _WIN32
501
502#include <malloc.h>
503
504#if defined(CL_HPP_USE_DX_INTEROP)
505#include <CL/cl_d3d10.h>
506#include <CL/cl_dx9_media_sharing.h>
507#endif
508#endif // _WIN32
509
510#if defined(_MSC_VER)
511#include <intrin.h>
512#endif // _MSC_VER
513
514 // Check for a valid C++ version
515
516// Need to do both tests here because for some reason __cplusplus is not
517// updated in visual studio
518#if (!defined(_MSC_VER) && __cplusplus < 201103L) || (defined(_MSC_VER) && _MSC_VER < 1700)
519#error Visual studio 2013 or another C++11-supporting compiler required
520#endif
521
522#if defined(__APPLE__) || defined(__MACOSX)
523#include <OpenCL/opencl.h>
524#else
525#include <CL/opencl.h>
526#endif // !__APPLE__
527
528#if __cplusplus >= 201703L
529# define CL_HPP_DEFINE_STATIC_MEMBER_ inline
530#elif defined(_MSC_VER)
531# define CL_HPP_DEFINE_STATIC_MEMBER_ __declspec(selectany)
532#elif defined(__MINGW32__)
533# define CL_HPP_DEFINE_STATIC_MEMBER_ __attribute__((selectany))
534#else
535# define CL_HPP_DEFINE_STATIC_MEMBER_ __attribute__((weak))
536#endif // !_MSC_VER
537
538// Define deprecated prefixes and suffixes to ensure compilation
539// in case they are not pre-defined
540#if !defined(CL_API_PREFIX__VERSION_1_1_DEPRECATED)
541#define CL_API_PREFIX__VERSION_1_1_DEPRECATED
542#endif // #if !defined(CL_API_PREFIX__VERSION_1_1_DEPRECATED)
543#if !defined(CL_API_SUFFIX__VERSION_1_1_DEPRECATED)
544#define CL_API_SUFFIX__VERSION_1_1_DEPRECATED
545#endif // #if !defined(CL_API_SUFFIX__VERSION_1_1_DEPRECATED)
546
547#if !defined(CL_API_PREFIX__VERSION_1_2_DEPRECATED)
548#define CL_API_PREFIX__VERSION_1_2_DEPRECATED
549#endif // #if !defined(CL_API_PREFIX__VERSION_1_2_DEPRECATED)
550#if !defined(CL_API_SUFFIX__VERSION_1_2_DEPRECATED)
551#define CL_API_SUFFIX__VERSION_1_2_DEPRECATED
552#endif // #if !defined(CL_API_SUFFIX__VERSION_1_2_DEPRECATED)
553
554#if !defined(CL_API_PREFIX__VERSION_2_2_DEPRECATED)
555#define CL_API_PREFIX__VERSION_2_2_DEPRECATED
556#endif // #if !defined(CL_API_PREFIX__VERSION_2_2_DEPRECATED)
557#if !defined(CL_API_SUFFIX__VERSION_2_2_DEPRECATED)
558#define CL_API_SUFFIX__VERSION_2_2_DEPRECATED
559#endif // #if !defined(CL_API_SUFFIX__VERSION_2_2_DEPRECATED)
560
561#if !defined(CL_CALLBACK)
562#define CL_CALLBACK
563#endif //CL_CALLBACK
564
565#include <utility>
566#include <limits>
567#include <iterator>
568#include <mutex>
569#include <cstring>
570#include <functional>
571
572
573// Define a size_type to represent a correctly resolved size_t
574#if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
575namespace cl {
576 using size_type = ::size_t;
577} // namespace cl
578#else // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
579namespace cl {
580 using size_type = size_t;
581} // namespace cl
582#endif // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
583
584
585#if defined(CL_HPP_ENABLE_EXCEPTIONS)
586#include <exception>
587#endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
588
589#if !defined(CL_HPP_NO_STD_VECTOR)
590#include <vector>
591namespace cl {
592 template < class T, class Alloc = std::allocator<T> >
593 using vector = std::vector<T, Alloc>;
594} // namespace cl
595#endif // #if !defined(CL_HPP_NO_STD_VECTOR)
596
597#if !defined(CL_HPP_NO_STD_STRING)
598#include <string>
599namespace cl {
600 using string = std::string;
601} // namespace cl
602#endif // #if !defined(CL_HPP_NO_STD_STRING)
603
604#if CL_HPP_TARGET_OPENCL_VERSION >= 200
605
606#if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
607#include <memory>
608namespace cl {
609 // Replace unique_ptr and allocate_pointer for internal use
610 // to allow user to replace them
611 template<class T, class D>
612 using pointer = std::unique_ptr<T, D>;
613} // namespace cl
614#endif
615#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
616#if !defined(CL_HPP_NO_STD_ARRAY)
617#include <array>
618namespace cl {
619 template < class T, size_type N >
620 using array = std::array<T, N>;
621} // namespace cl
622#endif // #if !defined(CL_HPP_NO_STD_ARRAY)
623
624// Define size_type appropriately to allow backward-compatibility
625// use of the old size_t interface class
626#if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
627namespace cl {
628 namespace compatibility {
633 template <int N>
634 class size_t
635 {
636 private:
637 size_type data_[N];
638
639 public:
641 size_t()
642 {
643 for (int i = 0; i < N; ++i) {
644 data_[i] = 0;
645 }
646 }
647
648 size_t(const array<size_type, N> &rhs)
649 {
650 for (int i = 0; i < N; ++i) {
651 data_[i] = rhs[i];
652 }
653 }
654
655 size_type& operator[](int index)
656 {
657 return data_[index];
658 }
659
660 const size_type& operator[](int index) const
661 {
662 return data_[index];
663 }
664
666 operator size_type* () { return data_; }
667
669 operator const size_type* () const { return data_; }
670
671 operator array<size_type, N>() const
672 {
673 array<size_type, N> ret;
674
675 for (int i = 0; i < N; ++i) {
676 ret[i] = data_[i];
677 }
678 return ret;
679 }
680 };
681 } // namespace compatibility
682
683 template<int N>
684 using size_t = compatibility::size_t<N>;
685} // namespace cl
686#endif // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
687
688// Helper alias to avoid confusing the macros
689namespace cl {
690 namespace detail {
691 using size_t_array = array<size_type, 3>;
692 } // namespace detail
693} // namespace cl
694
695
701namespace cl {
702
703#define CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(name) \
704 using PFN_##name = name##_fn
705
706#define CL_HPP_INIT_CL_EXT_FCN_PTR_(name) \
707 if (!pfn_##name) { \
708 pfn_##name = (PFN_##name)clGetExtensionFunctionAddress(#name); \
709 }
710
711#define CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, name) \
712 if (!pfn_##name) { \
713 pfn_##name = (PFN_##name) \
714 clGetExtensionFunctionAddressForPlatform(platform, #name); \
715 }
716
717#ifdef cl_khr_external_memory
718 enum class ExternalMemoryType : cl_external_memory_handle_type_khr;
719#endif
720
721 class Memory;
722 class Platform;
723 class Program;
724 class Device;
725 class Context;
726 class CommandQueue;
727 class DeviceCommandQueue;
728 class Memory;
729 class Buffer;
730 class Pipe;
731#ifdef cl_khr_semaphore
732 class Semaphore;
733#endif
734#if defined(cl_khr_command_buffer)
735 class CommandBufferKhr;
736 class MutableCommandKhr;
737#endif // cl_khr_command_buffer
738
739#if defined(CL_HPP_ENABLE_EXCEPTIONS)
744 class Error : public std::exception
745 {
746 private:
747 cl_int err_;
748 const char * errStr_;
749 public:
759 Error(cl_int err, const char * errStr = nullptr) : err_(err), errStr_(errStr)
760 {}
761
766 const char * what() const noexcept override
767 {
768 if (errStr_ == nullptr) {
769 return "empty";
770 }
771 else {
772 return errStr_;
773 }
774 }
775
780 cl_int err(void) const { return err_; }
781 };
782#define CL_HPP_ERR_STR_(x) #x
783#else
784#define CL_HPP_ERR_STR_(x) nullptr
785#endif // CL_HPP_ENABLE_EXCEPTIONS
786
787
788namespace detail
789{
790#if defined(CL_HPP_ENABLE_EXCEPTIONS)
791static inline cl_int errHandler (
792 cl_int err,
793 const char * errStr = nullptr)
794{
795 if (err != CL_SUCCESS) {
796 throw Error(err, errStr);
797 }
798 return err;
799}
800#else
801static inline cl_int errHandler (cl_int err, const char * errStr = nullptr)
802{
803 (void) errStr; // suppress unused variable warning
804 return err;
805}
806#endif // CL_HPP_ENABLE_EXCEPTIONS
807}
808
809
810
812#if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS)
813#define __GET_DEVICE_INFO_ERR CL_HPP_ERR_STR_(clGetDeviceInfo)
814#define __GET_PLATFORM_INFO_ERR CL_HPP_ERR_STR_(clGetPlatformInfo)
815#define __GET_DEVICE_IDS_ERR CL_HPP_ERR_STR_(clGetDeviceIDs)
816#define __GET_PLATFORM_IDS_ERR CL_HPP_ERR_STR_(clGetPlatformIDs)
817#define __GET_CONTEXT_INFO_ERR CL_HPP_ERR_STR_(clGetContextInfo)
818#define __GET_EVENT_INFO_ERR CL_HPP_ERR_STR_(clGetEventInfo)
819#define __GET_EVENT_PROFILE_INFO_ERR CL_HPP_ERR_STR_(clGetEventProfileInfo)
820#define __GET_MEM_OBJECT_INFO_ERR CL_HPP_ERR_STR_(clGetMemObjectInfo)
821#define __GET_IMAGE_INFO_ERR CL_HPP_ERR_STR_(clGetImageInfo)
822#define __GET_SAMPLER_INFO_ERR CL_HPP_ERR_STR_(clGetSamplerInfo)
823#define __GET_KERNEL_INFO_ERR CL_HPP_ERR_STR_(clGetKernelInfo)
824#if CL_HPP_TARGET_OPENCL_VERSION >= 120
825#define __GET_KERNEL_ARG_INFO_ERR CL_HPP_ERR_STR_(clGetKernelArgInfo)
826#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
827#if CL_HPP_TARGET_OPENCL_VERSION >= 210
828#define __GET_KERNEL_SUB_GROUP_INFO_ERR CL_HPP_ERR_STR_(clGetKernelSubGroupInfo)
829#else
830#define __GET_KERNEL_SUB_GROUP_INFO_ERR CL_HPP_ERR_STR_(clGetKernelSubGroupInfoKHR)
831#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
832#define __GET_KERNEL_WORK_GROUP_INFO_ERR CL_HPP_ERR_STR_(clGetKernelWorkGroupInfo)
833#define __GET_PROGRAM_INFO_ERR CL_HPP_ERR_STR_(clGetProgramInfo)
834#define __GET_PROGRAM_BUILD_INFO_ERR CL_HPP_ERR_STR_(clGetProgramBuildInfo)
835#define __GET_COMMAND_QUEUE_INFO_ERR CL_HPP_ERR_STR_(clGetCommandQueueInfo)
836
837#define __CREATE_CONTEXT_ERR CL_HPP_ERR_STR_(clCreateContext)
838#define __CREATE_CONTEXT_FROM_TYPE_ERR CL_HPP_ERR_STR_(clCreateContextFromType)
839#define __GET_SUPPORTED_IMAGE_FORMATS_ERR CL_HPP_ERR_STR_(clGetSupportedImageFormats)
840#if CL_HPP_TARGET_OPENCL_VERSION >= 300
841#define __SET_CONTEXT_DESCTRUCTOR_CALLBACK_ERR CL_HPP_ERR_STR_(clSetContextDestructorCallback)
842#endif // CL_HPP_TARGET_OPENCL_VERSION >= 300
843
844#define __CREATE_BUFFER_ERR CL_HPP_ERR_STR_(clCreateBuffer)
845#define __COPY_ERR CL_HPP_ERR_STR_(cl::copy)
846#define __CREATE_SUBBUFFER_ERR CL_HPP_ERR_STR_(clCreateSubBuffer)
847#define __CREATE_GL_BUFFER_ERR CL_HPP_ERR_STR_(clCreateFromGLBuffer)
848#define __CREATE_GL_RENDER_BUFFER_ERR CL_HPP_ERR_STR_(clCreateFromGLBuffer)
849#define __GET_GL_OBJECT_INFO_ERR CL_HPP_ERR_STR_(clGetGLObjectInfo)
850#if CL_HPP_TARGET_OPENCL_VERSION >= 120
851#define __CREATE_IMAGE_ERR CL_HPP_ERR_STR_(clCreateImage)
852#define __CREATE_GL_TEXTURE_ERR CL_HPP_ERR_STR_(clCreateFromGLTexture)
853#define __IMAGE_DIMENSION_ERR CL_HPP_ERR_STR_(Incorrect image dimensions)
854#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
855#define __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR CL_HPP_ERR_STR_(clSetMemObjectDestructorCallback)
856
857#define __CREATE_USER_EVENT_ERR CL_HPP_ERR_STR_(clCreateUserEvent)
858#define __SET_USER_EVENT_STATUS_ERR CL_HPP_ERR_STR_(clSetUserEventStatus)
859#define __SET_EVENT_CALLBACK_ERR CL_HPP_ERR_STR_(clSetEventCallback)
860#define __WAIT_FOR_EVENTS_ERR CL_HPP_ERR_STR_(clWaitForEvents)
861
862#define __CREATE_KERNEL_ERR CL_HPP_ERR_STR_(clCreateKernel)
863#define __SET_KERNEL_ARGS_ERR CL_HPP_ERR_STR_(clSetKernelArg)
864#define __CREATE_PROGRAM_WITH_SOURCE_ERR CL_HPP_ERR_STR_(clCreateProgramWithSource)
865#define __CREATE_PROGRAM_WITH_BINARY_ERR CL_HPP_ERR_STR_(clCreateProgramWithBinary)
866#if CL_HPP_TARGET_OPENCL_VERSION >= 210
867#define __CREATE_PROGRAM_WITH_IL_ERR CL_HPP_ERR_STR_(clCreateProgramWithIL)
868#else
869#define __CREATE_PROGRAM_WITH_IL_ERR CL_HPP_ERR_STR_(clCreateProgramWithILKHR)
870#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
871#if CL_HPP_TARGET_OPENCL_VERSION >= 120
872#define __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR CL_HPP_ERR_STR_(clCreateProgramWithBuiltInKernels)
873#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
874#define __BUILD_PROGRAM_ERR CL_HPP_ERR_STR_(clBuildProgram)
875#if CL_HPP_TARGET_OPENCL_VERSION >= 120
876#define __COMPILE_PROGRAM_ERR CL_HPP_ERR_STR_(clCompileProgram)
877#define __LINK_PROGRAM_ERR CL_HPP_ERR_STR_(clLinkProgram)
878#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
879#define __CREATE_KERNELS_IN_PROGRAM_ERR CL_HPP_ERR_STR_(clCreateKernelsInProgram)
880
881#if CL_HPP_TARGET_OPENCL_VERSION >= 200
882#define __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR CL_HPP_ERR_STR_(clCreateCommandQueueWithProperties)
883#define __CREATE_SAMPLER_WITH_PROPERTIES_ERR CL_HPP_ERR_STR_(clCreateSamplerWithProperties)
884#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
885#define __SET_COMMAND_QUEUE_PROPERTY_ERR CL_HPP_ERR_STR_(clSetCommandQueueProperty)
886#define __ENQUEUE_READ_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueReadBuffer)
887#define __ENQUEUE_READ_BUFFER_RECT_ERR CL_HPP_ERR_STR_(clEnqueueReadBufferRect)
888#define __ENQUEUE_WRITE_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueWriteBuffer)
889#define __ENQUEUE_WRITE_BUFFER_RECT_ERR CL_HPP_ERR_STR_(clEnqueueWriteBufferRect)
890#define __ENQEUE_COPY_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueCopyBuffer)
891#define __ENQEUE_COPY_BUFFER_RECT_ERR CL_HPP_ERR_STR_(clEnqueueCopyBufferRect)
892#define __ENQUEUE_FILL_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueFillBuffer)
893#define __ENQUEUE_READ_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueReadImage)
894#define __ENQUEUE_WRITE_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueWriteImage)
895#define __ENQUEUE_COPY_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueCopyImage)
896#define __ENQUEUE_FILL_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueFillImage)
897#define __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueCopyImageToBuffer)
898#define __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueCopyBufferToImage)
899#define __ENQUEUE_MAP_BUFFER_ERR CL_HPP_ERR_STR_(clEnqueueMapBuffer)
900#define __ENQUEUE_MAP_SVM_ERR CL_HPP_ERR_STR_(clEnqueueSVMMap)
901#define __ENQUEUE_FILL_SVM_ERR CL_HPP_ERR_STR_(clEnqueueSVMMemFill)
902#define __ENQUEUE_COPY_SVM_ERR CL_HPP_ERR_STR_(clEnqueueSVMMemcpy)
903#define __ENQUEUE_UNMAP_SVM_ERR CL_HPP_ERR_STR_(clEnqueueSVMUnmap)
904#define __ENQUEUE_MAP_IMAGE_ERR CL_HPP_ERR_STR_(clEnqueueMapImage)
905#define __ENQUEUE_UNMAP_MEM_OBJECT_ERR CL_HPP_ERR_STR_(clEnqueueUnMapMemObject)
906#define __ENQUEUE_NDRANGE_KERNEL_ERR CL_HPP_ERR_STR_(clEnqueueNDRangeKernel)
907#define __ENQUEUE_NATIVE_KERNEL CL_HPP_ERR_STR_(clEnqueueNativeKernel)
908#if CL_HPP_TARGET_OPENCL_VERSION >= 120
909#define __ENQUEUE_MIGRATE_MEM_OBJECTS_ERR CL_HPP_ERR_STR_(clEnqueueMigrateMemObjects)
910#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
911#if CL_HPP_TARGET_OPENCL_VERSION >= 210
912#define __ENQUEUE_MIGRATE_SVM_ERR CL_HPP_ERR_STR_(clEnqueueSVMMigrateMem)
913#define __SET_DEFAULT_DEVICE_COMMAND_QUEUE_ERR CL_HPP_ERR_STR_(clSetDefaultDeviceCommandQueue)
914#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
915
916
917#define __ENQUEUE_ACQUIRE_GL_ERR CL_HPP_ERR_STR_(clEnqueueAcquireGLObjects)
918#define __ENQUEUE_RELEASE_GL_ERR CL_HPP_ERR_STR_(clEnqueueReleaseGLObjects)
919
920#define __CREATE_PIPE_ERR CL_HPP_ERR_STR_(clCreatePipe)
921#define __GET_PIPE_INFO_ERR CL_HPP_ERR_STR_(clGetPipeInfo)
922
923#define __RETAIN_ERR CL_HPP_ERR_STR_(Retain Object)
924#define __RELEASE_ERR CL_HPP_ERR_STR_(Release Object)
925#define __FLUSH_ERR CL_HPP_ERR_STR_(clFlush)
926#define __FINISH_ERR CL_HPP_ERR_STR_(clFinish)
927#define __VECTOR_CAPACITY_ERR CL_HPP_ERR_STR_(Vector capacity error)
928
929#if CL_HPP_TARGET_OPENCL_VERSION >= 210
930#define __GET_HOST_TIMER_ERR CL_HPP_ERR_STR_(clGetHostTimer)
931#define __GET_DEVICE_AND_HOST_TIMER_ERR CL_HPP_ERR_STR_(clGetDeviceAndHostTimer)
932#endif
933#if CL_HPP_TARGET_OPENCL_VERSION >= 220
934#define __SET_PROGRAM_RELEASE_CALLBACK_ERR CL_HPP_ERR_STR_(clSetProgramReleaseCallback)
935#define __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR CL_HPP_ERR_STR_(clSetProgramSpecializationConstant)
936#endif
937
938#ifdef cl_khr_external_memory
939#define __ENQUEUE_ACQUIRE_EXTERNAL_MEMORY_ERR CL_HPP_ERR_STR_(clEnqueueAcquireExternalMemObjectsKHR)
940#define __ENQUEUE_RELEASE_EXTERNAL_MEMORY_ERR CL_HPP_ERR_STR_(clEnqueueReleaseExternalMemObjectsKHR)
941#endif
942
943#ifdef cl_khr_semaphore
944#define __GET_SEMAPHORE_KHR_INFO_ERR CL_HPP_ERR_STR_(clGetSemaphoreInfoKHR)
945#define __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR CL_HPP_ERR_STR_(clCreateSemaphoreWithPropertiesKHR)
946#define __ENQUEUE_WAIT_SEMAPHORE_KHR_ERR CL_HPP_ERR_STR_(clEnqueueWaitSemaphoresKHR)
947#define __ENQUEUE_SIGNAL_SEMAPHORE_KHR_ERR CL_HPP_ERR_STR_(clEnqueueSignalSemaphoresKHR)
948#define __RETAIN_SEMAPHORE_KHR_ERR CL_HPP_ERR_STR_(clRetainSemaphoreKHR)
949#define __RELEASE_SEMAPHORE_KHR_ERR CL_HPP_ERR_STR_(clReleaseSemaphoreKHR)
950#endif
951
952#ifdef cl_khr_external_semaphore
953#define __GET_SEMAPHORE_HANDLE_FOR_TYPE_KHR_ERR CL_HPP_ERR_STR_(clGetSemaphoreHandleForTypeKHR)
954#endif // cl_khr_external_semaphore
955
956#if defined(cl_khr_command_buffer)
957#define __CREATE_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clCreateCommandBufferKHR)
958#define __GET_COMMAND_BUFFER_INFO_KHR_ERR CL_HPP_ERR_STR_(clGetCommandBufferInfoKHR)
959#define __FINALIZE_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clFinalizeCommandBufferKHR)
960#define __ENQUEUE_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clEnqueueCommandBufferKHR)
961#define __COMMAND_BARRIER_WITH_WAIT_LIST_KHR_ERR CL_HPP_ERR_STR_(clCommandBarrierWithWaitListKHR)
962#define __COMMAND_COPY_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyBufferKHR)
963#define __COMMAND_COPY_BUFFER_RECT_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyBufferRectKHR)
964#define __COMMAND_COPY_BUFFER_TO_IMAGE_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyBufferToImageKHR)
965#define __COMMAND_COPY_IMAGE_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyImageKHR)
966#define __COMMAND_COPY_IMAGE_TO_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clCommandCopyImageToBufferKHR)
967#define __COMMAND_FILL_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clCommandFillBufferKHR)
968#define __COMMAND_FILL_IMAGE_KHR_ERR CL_HPP_ERR_STR_(clCommandFillImageKHR)
969#define __COMMAND_NDRANGE_KERNEL_KHR_ERR CL_HPP_ERR_STR_(clCommandNDRangeKernelKHR)
970#define __UPDATE_MUTABLE_COMMANDS_KHR_ERR CL_HPP_ERR_STR_(clUpdateMutableCommandsKHR)
971#define __GET_MUTABLE_COMMAND_INFO_KHR_ERR CL_HPP_ERR_STR_(clGetMutableCommandInfoKHR)
972#define __RETAIN_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clRetainCommandBufferKHR)
973#define __RELEASE_COMMAND_BUFFER_KHR_ERR CL_HPP_ERR_STR_(clReleaseCommandBufferKHR)
974#endif // cl_khr_command_buffer
975
976#if defined(cl_ext_image_requirements_info)
977#define __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR CL_HPP_ERR_STR_(clGetImageRequirementsInfoEXT)
978#endif //cl_ext_image_requirements_info
979
983#if CL_HPP_TARGET_OPENCL_VERSION >= 120
984#define __CREATE_SUB_DEVICES_ERR CL_HPP_ERR_STR_(clCreateSubDevices)
985#else
986#define __CREATE_SUB_DEVICES_ERR CL_HPP_ERR_STR_(clCreateSubDevicesEXT)
987#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
988
992#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
993#define __ENQUEUE_MARKER_ERR CL_HPP_ERR_STR_(clEnqueueMarker)
994#define __ENQUEUE_WAIT_FOR_EVENTS_ERR CL_HPP_ERR_STR_(clEnqueueWaitForEvents)
995#define __ENQUEUE_BARRIER_ERR CL_HPP_ERR_STR_(clEnqueueBarrier)
996#define __UNLOAD_COMPILER_ERR CL_HPP_ERR_STR_(clUnloadCompiler)
997#define __CREATE_GL_TEXTURE_2D_ERR CL_HPP_ERR_STR_(clCreateFromGLTexture2D)
998#define __CREATE_GL_TEXTURE_3D_ERR CL_HPP_ERR_STR_(clCreateFromGLTexture3D)
999#define __CREATE_IMAGE2D_ERR CL_HPP_ERR_STR_(clCreateImage2D)
1000#define __CREATE_IMAGE3D_ERR CL_HPP_ERR_STR_(clCreateImage3D)
1001#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
1002
1006#if defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
1007#define __CREATE_COMMAND_QUEUE_ERR CL_HPP_ERR_STR_(clCreateCommandQueue)
1008#define __ENQUEUE_TASK_ERR CL_HPP_ERR_STR_(clEnqueueTask)
1009#define __CREATE_SAMPLER_ERR CL_HPP_ERR_STR_(clCreateSampler)
1010#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
1011
1015#if CL_HPP_TARGET_OPENCL_VERSION >= 120
1016#define __ENQUEUE_MARKER_WAIT_LIST_ERR CL_HPP_ERR_STR_(clEnqueueMarkerWithWaitList)
1017#define __ENQUEUE_BARRIER_WAIT_LIST_ERR CL_HPP_ERR_STR_(clEnqueueBarrierWithWaitList)
1018#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
1019
1020#if CL_HPP_TARGET_OPENCL_VERSION >= 210
1021#define __CLONE_KERNEL_ERR CL_HPP_ERR_STR_(clCloneKernel)
1022#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
1023
1024#endif // CL_HPP_USER_OVERRIDE_ERROR_STRINGS
1026
1027#ifdef cl_khr_external_memory
1028CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueAcquireExternalMemObjectsKHR);
1029CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueReleaseExternalMemObjectsKHR);
1030
1031CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueAcquireExternalMemObjectsKHR pfn_clEnqueueAcquireExternalMemObjectsKHR = nullptr;
1032CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueReleaseExternalMemObjectsKHR pfn_clEnqueueReleaseExternalMemObjectsKHR = nullptr;
1033#endif // cl_khr_external_memory
1034
1035#ifdef cl_khr_semaphore
1036CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateSemaphoreWithPropertiesKHR);
1037CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clReleaseSemaphoreKHR);
1038CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clRetainSemaphoreKHR);
1039CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueWaitSemaphoresKHR);
1040CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueSignalSemaphoresKHR);
1041CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetSemaphoreInfoKHR);
1042
1043CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateSemaphoreWithPropertiesKHR pfn_clCreateSemaphoreWithPropertiesKHR = nullptr;
1044CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clReleaseSemaphoreKHR pfn_clReleaseSemaphoreKHR = nullptr;
1045CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clRetainSemaphoreKHR pfn_clRetainSemaphoreKHR = nullptr;
1046CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueWaitSemaphoresKHR pfn_clEnqueueWaitSemaphoresKHR = nullptr;
1047CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueSignalSemaphoresKHR pfn_clEnqueueSignalSemaphoresKHR = nullptr;
1048CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetSemaphoreInfoKHR pfn_clGetSemaphoreInfoKHR = nullptr;
1049#endif // cl_khr_semaphore
1050
1051#ifdef cl_khr_external_semaphore
1052CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetSemaphoreHandleForTypeKHR);
1053CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetSemaphoreHandleForTypeKHR pfn_clGetSemaphoreHandleForTypeKHR = nullptr;
1054#endif // cl_khr_external_semaphore
1055
1056#if defined(cl_khr_command_buffer)
1057CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateCommandBufferKHR);
1058CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clFinalizeCommandBufferKHR);
1059CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clRetainCommandBufferKHR);
1060CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clReleaseCommandBufferKHR);
1061CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetCommandBufferInfoKHR);
1062CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueCommandBufferKHR);
1063CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandBarrierWithWaitListKHR);
1064CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferKHR);
1065CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferRectKHR);
1066CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferToImageKHR);
1067CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyImageKHR);
1068CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyImageToBufferKHR);
1069CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandFillBufferKHR);
1070CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandFillImageKHR);
1071CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandNDRangeKernelKHR);
1072
1073CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateCommandBufferKHR pfn_clCreateCommandBufferKHR = nullptr;
1074CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clFinalizeCommandBufferKHR pfn_clFinalizeCommandBufferKHR = nullptr;
1075CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clRetainCommandBufferKHR pfn_clRetainCommandBufferKHR = nullptr;
1076CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clReleaseCommandBufferKHR pfn_clReleaseCommandBufferKHR = nullptr;
1077CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetCommandBufferInfoKHR pfn_clGetCommandBufferInfoKHR = nullptr;
1078CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueCommandBufferKHR pfn_clEnqueueCommandBufferKHR = nullptr;
1079CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandBarrierWithWaitListKHR pfn_clCommandBarrierWithWaitListKHR = nullptr;
1080CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferKHR pfn_clCommandCopyBufferKHR = nullptr;
1081CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferRectKHR pfn_clCommandCopyBufferRectKHR = nullptr;
1082CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferToImageKHR pfn_clCommandCopyBufferToImageKHR = nullptr;
1083CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyImageKHR pfn_clCommandCopyImageKHR = nullptr;
1084CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyImageToBufferKHR pfn_clCommandCopyImageToBufferKHR = nullptr;
1085CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandFillBufferKHR pfn_clCommandFillBufferKHR = nullptr;
1086CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandFillImageKHR pfn_clCommandFillImageKHR = nullptr;
1087CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandNDRangeKernelKHR pfn_clCommandNDRangeKernelKHR = nullptr;
1088#endif /* cl_khr_command_buffer */
1089
1090#if defined(cl_khr_command_buffer_mutable_dispatch)
1091CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clUpdateMutableCommandsKHR);
1092CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetMutableCommandInfoKHR);
1093
1094CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clUpdateMutableCommandsKHR pfn_clUpdateMutableCommandsKHR = nullptr;
1095CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetMutableCommandInfoKHR pfn_clGetMutableCommandInfoKHR = nullptr;
1096#endif /* cl_khr_command_buffer_mutable_dispatch */
1097
1098#if defined(cl_ext_image_requirements_info)
1099CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetImageRequirementsInfoEXT);
1100CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetImageRequirementsInfoEXT pfn_clGetImageRequirementsInfoEXT = nullptr;
1101#endif
1102
1103#if defined(cl_ext_device_fission)
1104CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateSubDevicesEXT);
1105CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateSubDevicesEXT
1106 pfn_clCreateSubDevicesEXT = nullptr;
1107#endif
1108
1109namespace detail {
1110
1111// Generic getInfoHelper. The final parameter is used to guide overload
1112// resolution: the actual parameter passed is an int, which makes this
1113// a worse conversion sequence than a specialization that declares the
1114// parameter as an int.
1115template<typename Functor, typename T>
1116inline cl_int getInfoHelper(Functor f, cl_uint name, T* param, long)
1117{
1118 return f(name, sizeof(T), param, nullptr);
1119}
1120
1121// Specialized for getInfo<CL_PROGRAM_BINARIES>
1122// Assumes that the output vector was correctly resized on the way in
1123template <typename Func>
1124inline cl_int getInfoHelper(Func f, cl_uint name, vector<vector<unsigned char>>* param, int)
1125{
1126 if (name != CL_PROGRAM_BINARIES) {
1127 return CL_INVALID_VALUE;
1128 }
1129 if (param) {
1130 // Create array of pointers, calculate total size and pass pointer array in
1131 size_type numBinaries = param->size();
1132 vector<unsigned char*> binariesPointers(numBinaries);
1133
1134 for (size_type i = 0; i < numBinaries; ++i)
1135 {
1136 binariesPointers[i] = (*param)[i].data();
1137 }
1138
1139 cl_int err = f(name, numBinaries * sizeof(unsigned char*), binariesPointers.data(), nullptr);
1140
1141 if (err != CL_SUCCESS) {
1142 return err;
1143 }
1144 }
1145
1146 return CL_SUCCESS;
1147}
1148
1149// Specialized getInfoHelper for vector params
1150template <typename Func, typename T>
1151inline cl_int getInfoHelper(Func f, cl_uint name, vector<T>* param, long)
1152{
1153 size_type required;
1154 cl_int err = f(name, 0, nullptr, &required);
1155 if (err != CL_SUCCESS) {
1156 return err;
1157 }
1158 const size_type elements = required / sizeof(T);
1159
1160 // Temporary to avoid changing param on an error
1161 vector<T> localData(elements);
1162 err = f(name, required, localData.data(), nullptr);
1163 if (err != CL_SUCCESS) {
1164 return err;
1165 }
1166 if (param) {
1167 *param = std::move(localData);
1168 }
1169
1170 return CL_SUCCESS;
1171}
1172
1173/* Specialization for reference-counted types. This depends on the
1174 * existence of Wrapper<T>::cl_type, and none of the other types having the
1175 * cl_type member. Note that simplify specifying the parameter as Wrapper<T>
1176 * does not work, because when using a derived type (e.g. Context) the generic
1177 * template will provide a better match.
1178 */
1179template <typename Func, typename T>
1180inline cl_int getInfoHelper(
1181 Func f, cl_uint name, vector<T>* param, int, typename T::cl_type = 0)
1182{
1183 size_type required;
1184 cl_int err = f(name, 0, nullptr, &required);
1185 if (err != CL_SUCCESS) {
1186 return err;
1187 }
1188
1189 const size_type elements = required / sizeof(typename T::cl_type);
1190
1191 vector<typename T::cl_type> value(elements);
1192 err = f(name, required, value.data(), nullptr);
1193 if (err != CL_SUCCESS) {
1194 return err;
1195 }
1196
1197 if (param) {
1198 // Assign to convert CL type to T for each element
1199 param->resize(elements);
1200
1201 // Assign to param, constructing with retain behaviour
1202 // to correctly capture each underlying CL object
1203 for (size_type i = 0; i < elements; i++) {
1204 (*param)[i] = T(value[i], true);
1205 }
1206 }
1207 return CL_SUCCESS;
1208}
1209
1210// Specialized GetInfoHelper for string params
1211template <typename Func>
1212inline cl_int getInfoHelper(Func f, cl_uint name, string* param, long)
1213{
1214 size_type required;
1215 cl_int err = f(name, 0, nullptr, &required);
1216 if (err != CL_SUCCESS) {
1217 return err;
1218 }
1219
1220 // std::string has a constant data member
1221 // a char vector does not
1222 if (required > 0) {
1223 vector<char> value(required);
1224 err = f(name, required, value.data(), nullptr);
1225 if (err != CL_SUCCESS) {
1226 return err;
1227 }
1228 if (param) {
1229 param->assign(value.begin(), value.end() - 1);
1230 }
1231 }
1232 else if (param) {
1233 param->assign("");
1234 }
1235 return CL_SUCCESS;
1236}
1237
1238// Specialized GetInfoHelper for clsize_t params
1239template <typename Func, size_type N>
1240inline cl_int getInfoHelper(Func f, cl_uint name, array<size_type, N>* param, long)
1241{
1242 size_type required;
1243 cl_int err = f(name, 0, nullptr, &required);
1244 if (err != CL_SUCCESS) {
1245 return err;
1246 }
1247
1248 size_type elements = required / sizeof(size_type);
1249 vector<size_type> value(elements, 0);
1250
1251 err = f(name, required, value.data(), nullptr);
1252 if (err != CL_SUCCESS) {
1253 return err;
1254 }
1255
1256 // Bound the copy with N to prevent overruns
1257 // if passed N > than the amount copied
1258 if (elements > N) {
1259 elements = N;
1260 }
1261 for (size_type i = 0; i < elements; ++i) {
1262 (*param)[i] = value[i];
1263 }
1264
1265 return CL_SUCCESS;
1266}
1267
1268template<typename T> struct ReferenceHandler;
1269
1270/* Specialization for reference-counted types. This depends on the
1271 * existence of Wrapper<T>::cl_type, and none of the other types having the
1272 * cl_type member. Note that simplify specifying the parameter as Wrapper<T>
1273 * does not work, because when using a derived type (e.g. Context) the generic
1274 * template will provide a better match.
1275 */
1276template<typename Func, typename T>
1277inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_type = 0)
1278{
1279 typename T::cl_type value;
1280 cl_int err = f(name, sizeof(value), &value, nullptr);
1281 if (err != CL_SUCCESS) {
1282 return err;
1283 }
1284 *param = value;
1285 if (value != nullptr)
1286 {
1287 err = param->retain();
1288 if (err != CL_SUCCESS) {
1289 return err;
1290 }
1291 }
1292 return CL_SUCCESS;
1293}
1294
1295#define CL_HPP_PARAM_NAME_INFO_1_0_(F) \
1296 F(cl_platform_info, CL_PLATFORM_PROFILE, string) \
1297 F(cl_platform_info, CL_PLATFORM_VERSION, string) \
1298 F(cl_platform_info, CL_PLATFORM_NAME, string) \
1299 F(cl_platform_info, CL_PLATFORM_VENDOR, string) \
1300 F(cl_platform_info, CL_PLATFORM_EXTENSIONS, string) \
1301 \
1302 F(cl_device_info, CL_DEVICE_TYPE, cl_device_type) \
1303 F(cl_device_info, CL_DEVICE_VENDOR_ID, cl_uint) \
1304 F(cl_device_info, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint) \
1305 F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint) \
1306 F(cl_device_info, CL_DEVICE_MAX_WORK_GROUP_SIZE, size_type) \
1307 F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_SIZES, cl::vector<size_type>) \
1308 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, cl_uint) \
1309 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, cl_uint) \
1310 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, cl_uint) \
1311 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, cl_uint) \
1312 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, cl_uint) \
1313 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, cl_uint) \
1314 F(cl_device_info, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint) \
1315 F(cl_device_info, CL_DEVICE_ADDRESS_BITS, cl_uint) \
1316 F(cl_device_info, CL_DEVICE_MAX_READ_IMAGE_ARGS, cl_uint) \
1317 F(cl_device_info, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, cl_uint) \
1318 F(cl_device_info, CL_DEVICE_MAX_MEM_ALLOC_SIZE, cl_ulong) \
1319 F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_WIDTH, size_type) \
1320 F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_HEIGHT, size_type) \
1321 F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_WIDTH, size_type) \
1322 F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_HEIGHT, size_type) \
1323 F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_DEPTH, size_type) \
1324 F(cl_device_info, CL_DEVICE_IMAGE_SUPPORT, cl_bool) \
1325 F(cl_device_info, CL_DEVICE_MAX_PARAMETER_SIZE, size_type) \
1326 F(cl_device_info, CL_DEVICE_MAX_SAMPLERS, cl_uint) \
1327 F(cl_device_info, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint) \
1328 F(cl_device_info, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, cl_uint) \
1329 F(cl_device_info, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config) \
1330 F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \
1331 F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \
1332 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, cl_device_mem_cache_type) \
1333 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint)\
1334 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong) \
1335 F(cl_device_info, CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong) \
1336 F(cl_device_info, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, cl_ulong) \
1337 F(cl_device_info, CL_DEVICE_MAX_CONSTANT_ARGS, cl_uint) \
1338 F(cl_device_info, CL_DEVICE_LOCAL_MEM_TYPE, cl_device_local_mem_type) \
1339 F(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong) \
1340 F(cl_device_info, CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_bool) \
1341 F(cl_device_info, CL_DEVICE_PROFILING_TIMER_RESOLUTION, size_type) \
1342 F(cl_device_info, CL_DEVICE_ENDIAN_LITTLE, cl_bool) \
1343 F(cl_device_info, CL_DEVICE_AVAILABLE, cl_bool) \
1344 F(cl_device_info, CL_DEVICE_COMPILER_AVAILABLE, cl_bool) \
1345 F(cl_device_info, CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities) \
1346 F(cl_device_info, CL_DEVICE_PLATFORM, cl::Platform) \
1347 F(cl_device_info, CL_DEVICE_NAME, string) \
1348 F(cl_device_info, CL_DEVICE_VENDOR, string) \
1349 F(cl_device_info, CL_DRIVER_VERSION, string) \
1350 F(cl_device_info, CL_DEVICE_PROFILE, string) \
1351 F(cl_device_info, CL_DEVICE_VERSION, string) \
1352 F(cl_device_info, CL_DEVICE_EXTENSIONS, string) \
1353 \
1354 F(cl_context_info, CL_CONTEXT_REFERENCE_COUNT, cl_uint) \
1355 F(cl_context_info, CL_CONTEXT_DEVICES, cl::vector<Device>) \
1356 F(cl_context_info, CL_CONTEXT_PROPERTIES, cl::vector<cl_context_properties>) \
1357 \
1358 F(cl_event_info, CL_EVENT_COMMAND_QUEUE, cl::CommandQueue) \
1359 F(cl_event_info, CL_EVENT_COMMAND_TYPE, cl_command_type) \
1360 F(cl_event_info, CL_EVENT_REFERENCE_COUNT, cl_uint) \
1361 F(cl_event_info, CL_EVENT_COMMAND_EXECUTION_STATUS, cl_int) \
1362 \
1363 F(cl_profiling_info, CL_PROFILING_COMMAND_QUEUED, cl_ulong) \
1364 F(cl_profiling_info, CL_PROFILING_COMMAND_SUBMIT, cl_ulong) \
1365 F(cl_profiling_info, CL_PROFILING_COMMAND_START, cl_ulong) \
1366 F(cl_profiling_info, CL_PROFILING_COMMAND_END, cl_ulong) \
1367 \
1368 F(cl_mem_info, CL_MEM_TYPE, cl_mem_object_type) \
1369 F(cl_mem_info, CL_MEM_FLAGS, cl_mem_flags) \
1370 F(cl_mem_info, CL_MEM_SIZE, size_type) \
1371 F(cl_mem_info, CL_MEM_HOST_PTR, void*) \
1372 F(cl_mem_info, CL_MEM_MAP_COUNT, cl_uint) \
1373 F(cl_mem_info, CL_MEM_REFERENCE_COUNT, cl_uint) \
1374 F(cl_mem_info, CL_MEM_CONTEXT, cl::Context) \
1375 \
1376 F(cl_image_info, CL_IMAGE_FORMAT, cl_image_format) \
1377 F(cl_image_info, CL_IMAGE_ELEMENT_SIZE, size_type) \
1378 F(cl_image_info, CL_IMAGE_ROW_PITCH, size_type) \
1379 F(cl_image_info, CL_IMAGE_SLICE_PITCH, size_type) \
1380 F(cl_image_info, CL_IMAGE_WIDTH, size_type) \
1381 F(cl_image_info, CL_IMAGE_HEIGHT, size_type) \
1382 F(cl_image_info, CL_IMAGE_DEPTH, size_type) \
1383 \
1384 F(cl_sampler_info, CL_SAMPLER_REFERENCE_COUNT, cl_uint) \
1385 F(cl_sampler_info, CL_SAMPLER_CONTEXT, cl::Context) \
1386 F(cl_sampler_info, CL_SAMPLER_NORMALIZED_COORDS, cl_bool) \
1387 F(cl_sampler_info, CL_SAMPLER_ADDRESSING_MODE, cl_addressing_mode) \
1388 F(cl_sampler_info, CL_SAMPLER_FILTER_MODE, cl_filter_mode) \
1389 \
1390 F(cl_program_info, CL_PROGRAM_REFERENCE_COUNT, cl_uint) \
1391 F(cl_program_info, CL_PROGRAM_CONTEXT, cl::Context) \
1392 F(cl_program_info, CL_PROGRAM_NUM_DEVICES, cl_uint) \
1393 F(cl_program_info, CL_PROGRAM_DEVICES, cl::vector<Device>) \
1394 F(cl_program_info, CL_PROGRAM_SOURCE, string) \
1395 F(cl_program_info, CL_PROGRAM_BINARY_SIZES, cl::vector<size_type>) \
1396 F(cl_program_info, CL_PROGRAM_BINARIES, cl::vector<cl::vector<unsigned char>>) \
1397 \
1398 F(cl_program_build_info, CL_PROGRAM_BUILD_STATUS, cl_build_status) \
1399 F(cl_program_build_info, CL_PROGRAM_BUILD_OPTIONS, string) \
1400 F(cl_program_build_info, CL_PROGRAM_BUILD_LOG, string) \
1401 \
1402 F(cl_kernel_info, CL_KERNEL_FUNCTION_NAME, string) \
1403 F(cl_kernel_info, CL_KERNEL_NUM_ARGS, cl_uint) \
1404 F(cl_kernel_info, CL_KERNEL_REFERENCE_COUNT, cl_uint) \
1405 F(cl_kernel_info, CL_KERNEL_CONTEXT, cl::Context) \
1406 F(cl_kernel_info, CL_KERNEL_PROGRAM, cl::Program) \
1407 \
1408 F(cl_kernel_work_group_info, CL_KERNEL_WORK_GROUP_SIZE, size_type) \
1409 F(cl_kernel_work_group_info, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, cl::detail::size_t_array) \
1410 F(cl_kernel_work_group_info, CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong) \
1411 \
1412 F(cl_command_queue_info, CL_QUEUE_CONTEXT, cl::Context) \
1413 F(cl_command_queue_info, CL_QUEUE_DEVICE, cl::Device) \
1414 F(cl_command_queue_info, CL_QUEUE_REFERENCE_COUNT, cl_uint) \
1415 F(cl_command_queue_info, CL_QUEUE_PROPERTIES, cl_command_queue_properties)
1416
1417
1418#define CL_HPP_PARAM_NAME_INFO_1_1_(F) \
1419 F(cl_context_info, CL_CONTEXT_NUM_DEVICES, cl_uint)\
1420 F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, cl_uint) \
1421 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, cl_uint) \
1422 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, cl_uint) \
1423 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, cl_uint) \
1424 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, cl_uint) \
1425 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint) \
1426 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint) \
1427 F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint) \
1428 F(cl_device_info, CL_DEVICE_OPENCL_C_VERSION, string) \
1429 \
1430 F(cl_mem_info, CL_MEM_ASSOCIATED_MEMOBJECT, cl::Memory) \
1431 F(cl_mem_info, CL_MEM_OFFSET, size_type) \
1432 \
1433 F(cl_kernel_work_group_info, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, size_type) \
1434 F(cl_kernel_work_group_info, CL_KERNEL_PRIVATE_MEM_SIZE, cl_ulong) \
1435 \
1436 F(cl_event_info, CL_EVENT_CONTEXT, cl::Context)
1437
1438#define CL_HPP_PARAM_NAME_INFO_1_2_(F) \
1439 F(cl_program_info, CL_PROGRAM_NUM_KERNELS, size_type) \
1440 F(cl_program_info, CL_PROGRAM_KERNEL_NAMES, string) \
1441 \
1442 F(cl_program_build_info, CL_PROGRAM_BINARY_TYPE, cl_program_binary_type) \
1443 \
1444 F(cl_kernel_info, CL_KERNEL_ATTRIBUTES, string) \
1445 \
1446 F(cl_kernel_arg_info, CL_KERNEL_ARG_ADDRESS_QUALIFIER, cl_kernel_arg_address_qualifier) \
1447 F(cl_kernel_arg_info, CL_KERNEL_ARG_ACCESS_QUALIFIER, cl_kernel_arg_access_qualifier) \
1448 F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_NAME, string) \
1449 F(cl_kernel_arg_info, CL_KERNEL_ARG_NAME, string) \
1450 F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_QUALIFIER, cl_kernel_arg_type_qualifier) \
1451 \
1452 F(cl_kernel_work_group_info, CL_KERNEL_GLOBAL_WORK_SIZE, cl::detail::size_t_array) \
1453 \
1454 F(cl_device_info, CL_DEVICE_LINKER_AVAILABLE, cl_bool) \
1455 F(cl_device_info, CL_DEVICE_IMAGE_MAX_BUFFER_SIZE, size_type) \
1456 F(cl_device_info, CL_DEVICE_IMAGE_MAX_ARRAY_SIZE, size_type) \
1457 F(cl_device_info, CL_DEVICE_PARENT_DEVICE, cl::Device) \
1458 F(cl_device_info, CL_DEVICE_PARTITION_MAX_SUB_DEVICES, cl_uint) \
1459 F(cl_device_info, CL_DEVICE_PARTITION_PROPERTIES, cl::vector<cl_device_partition_property>) \
1460 F(cl_device_info, CL_DEVICE_PARTITION_TYPE, cl::vector<cl_device_partition_property>) \
1461 F(cl_device_info, CL_DEVICE_REFERENCE_COUNT, cl_uint) \
1462 F(cl_device_info, CL_DEVICE_PREFERRED_INTEROP_USER_SYNC, cl_bool) \
1463 F(cl_device_info, CL_DEVICE_PARTITION_AFFINITY_DOMAIN, cl_device_affinity_domain) \
1464 F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS, string) \
1465 F(cl_device_info, CL_DEVICE_PRINTF_BUFFER_SIZE, size_type) \
1466 \
1467 F(cl_image_info, CL_IMAGE_ARRAY_SIZE, size_type) \
1468 F(cl_image_info, CL_IMAGE_NUM_MIP_LEVELS, cl_uint) \
1469 F(cl_image_info, CL_IMAGE_NUM_SAMPLES, cl_uint)
1470
1471#define CL_HPP_PARAM_NAME_INFO_2_0_(F) \
1472 F(cl_device_info, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES, cl_command_queue_properties) \
1473 F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES, cl_command_queue_properties) \
1474 F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE, cl_uint) \
1475 F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE, cl_uint) \
1476 F(cl_device_info, CL_DEVICE_MAX_ON_DEVICE_QUEUES, cl_uint) \
1477 F(cl_device_info, CL_DEVICE_MAX_ON_DEVICE_EVENTS, cl_uint) \
1478 F(cl_device_info, CL_DEVICE_MAX_PIPE_ARGS, cl_uint) \
1479 F(cl_device_info, CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS, cl_uint) \
1480 F(cl_device_info, CL_DEVICE_PIPE_MAX_PACKET_SIZE, cl_uint) \
1481 F(cl_device_info, CL_DEVICE_SVM_CAPABILITIES, cl_device_svm_capabilities) \
1482 F(cl_device_info, CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT, cl_uint) \
1483 F(cl_device_info, CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT, cl_uint) \
1484 F(cl_device_info, CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT, cl_uint) \
1485 F(cl_device_info, CL_DEVICE_IMAGE_PITCH_ALIGNMENT, cl_uint) \
1486 F(cl_device_info, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT, cl_uint) \
1487 F(cl_device_info, CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS, cl_uint ) \
1488 F(cl_device_info, CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE, size_type ) \
1489 F(cl_device_info, CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE, size_type ) \
1490 F(cl_profiling_info, CL_PROFILING_COMMAND_COMPLETE, cl_ulong) \
1491 F(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM, cl_bool) \
1492 F(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_SVM_PTRS, void**) \
1493 F(cl_command_queue_info, CL_QUEUE_SIZE, cl_uint) \
1494 F(cl_mem_info, CL_MEM_USES_SVM_POINTER, cl_bool) \
1495 F(cl_program_build_info, CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE, size_type) \
1496 F(cl_pipe_info, CL_PIPE_PACKET_SIZE, cl_uint) \
1497 F(cl_pipe_info, CL_PIPE_MAX_PACKETS, cl_uint)
1498
1499#define CL_HPP_PARAM_NAME_INFO_SUBGROUP_KHR_(F) \
1500 F(cl_kernel_sub_group_info, CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE_KHR, size_type) \
1501 F(cl_kernel_sub_group_info, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR, size_type)
1502
1503#define CL_HPP_PARAM_NAME_INFO_IL_KHR_(F) \
1504 F(cl_device_info, CL_DEVICE_IL_VERSION_KHR, string) \
1505 F(cl_program_info, CL_PROGRAM_IL_KHR, cl::vector<unsigned char>)
1506
1507#define CL_HPP_PARAM_NAME_INFO_2_1_(F) \
1508 F(cl_platform_info, CL_PLATFORM_HOST_TIMER_RESOLUTION, cl_ulong) \
1509 F(cl_program_info, CL_PROGRAM_IL, cl::vector<unsigned char>) \
1510 F(cl_device_info, CL_DEVICE_MAX_NUM_SUB_GROUPS, cl_uint) \
1511 F(cl_device_info, CL_DEVICE_IL_VERSION, string) \
1512 F(cl_device_info, CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS, cl_bool) \
1513 F(cl_command_queue_info, CL_QUEUE_DEVICE_DEFAULT, cl::DeviceCommandQueue) \
1514 F(cl_kernel_sub_group_info, CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE, size_type) \
1515 F(cl_kernel_sub_group_info, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE, size_type) \
1516 F(cl_kernel_sub_group_info, CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT, cl::detail::size_t_array) \
1517 F(cl_kernel_sub_group_info, CL_KERNEL_MAX_NUM_SUB_GROUPS, size_type) \
1518 F(cl_kernel_sub_group_info, CL_KERNEL_COMPILE_NUM_SUB_GROUPS, size_type)
1519
1520#define CL_HPP_PARAM_NAME_INFO_2_2_(F) \
1521 F(cl_program_info, CL_PROGRAM_SCOPE_GLOBAL_CTORS_PRESENT, cl_bool) \
1522 F(cl_program_info, CL_PROGRAM_SCOPE_GLOBAL_DTORS_PRESENT, cl_bool)
1523
1524#define CL_HPP_PARAM_NAME_DEVICE_FISSION_EXT_(F) \
1525 F(cl_device_info, CL_DEVICE_PARENT_DEVICE_EXT, cl::Device) \
1526 F(cl_device_info, CL_DEVICE_PARTITION_TYPES_EXT, cl::vector<cl_device_partition_property_ext>) \
1527 F(cl_device_info, CL_DEVICE_AFFINITY_DOMAINS_EXT, cl::vector<cl_device_partition_property_ext>) \
1528 F(cl_device_info, CL_DEVICE_REFERENCE_COUNT_EXT , cl_uint) \
1529 F(cl_device_info, CL_DEVICE_PARTITION_STYLE_EXT, cl::vector<cl_device_partition_property_ext>)
1530
1531#define CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_CL3_SHARED_(F) \
1532 F(cl_platform_info, CL_PLATFORM_NUMERIC_VERSION_KHR, cl_version_khr) \
1533 F(cl_platform_info, CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>) \
1534 \
1535 F(cl_device_info, CL_DEVICE_NUMERIC_VERSION_KHR, cl_version_khr) \
1536 F(cl_device_info, CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>) \
1537 F(cl_device_info, CL_DEVICE_ILS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>) \
1538 F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>)
1539
1540#define CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_KHRONLY_(F) \
1541 F(cl_device_info, CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR, cl_version_khr)
1542
1543// Note: the query for CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR is handled specially!
1544#define CL_HPP_PARAM_NAME_CL_KHR_SEMAPHORE_(F) \
1545 F(cl_semaphore_info_khr, CL_SEMAPHORE_CONTEXT_KHR, cl::Context) \
1546 F(cl_semaphore_info_khr, CL_SEMAPHORE_REFERENCE_COUNT_KHR, cl_uint) \
1547 F(cl_semaphore_info_khr, CL_SEMAPHORE_PROPERTIES_KHR, cl::vector<cl_semaphore_properties_khr>) \
1548 F(cl_semaphore_info_khr, CL_SEMAPHORE_TYPE_KHR, cl_semaphore_type_khr) \
1549 F(cl_semaphore_info_khr, CL_SEMAPHORE_PAYLOAD_KHR, cl_semaphore_payload_khr) \
1550 F(cl_platform_info, CL_PLATFORM_SEMAPHORE_TYPES_KHR, cl::vector<cl_semaphore_type_khr>) \
1551 F(cl_device_info, CL_DEVICE_SEMAPHORE_TYPES_KHR, cl::vector<cl_semaphore_type_khr>) \
1552
1553#define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_MEMORY_(F) \
1554 F(cl_device_info, CL_DEVICE_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl::ExternalMemoryType>) \
1555 F(cl_platform_info, CL_PLATFORM_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl::ExternalMemoryType>)
1556
1557#define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_(F) \
1558 F(cl_platform_info, CL_PLATFORM_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl_external_semaphore_handle_type_khr>) \
1559 F(cl_platform_info, CL_PLATFORM_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR, cl::vector<cl_external_semaphore_handle_type_khr>) \
1560 F(cl_device_info, CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl_external_semaphore_handle_type_khr>) \
1561 F(cl_device_info, CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR, cl::vector<cl_external_semaphore_handle_type_khr>) \
1562 F(cl_semaphore_info_khr, CL_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR, cl::vector<cl_external_semaphore_handle_type_khr>) \
1563
1564#define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_OPAQUE_FD_EXT(F) \
1565 F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR, int) \
1566
1567#define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_SYNC_FD_EXT(F) \
1568 F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_SYNC_FD_KHR, int) \
1569
1570#define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_WIN32_EXT(F) \
1571 F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR, void*) \
1572 F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR, void*) \
1573
1574#define CL_HPP_PARAM_NAME_INFO_3_0_(F) \
1575 F(cl_platform_info, CL_PLATFORM_NUMERIC_VERSION, cl_version) \
1576 F(cl_platform_info, CL_PLATFORM_EXTENSIONS_WITH_VERSION, cl::vector<cl_name_version>) \
1577 \
1578 F(cl_device_info, CL_DEVICE_NUMERIC_VERSION, cl_version) \
1579 F(cl_device_info, CL_DEVICE_EXTENSIONS_WITH_VERSION, cl::vector<cl_name_version>) \
1580 F(cl_device_info, CL_DEVICE_ILS_WITH_VERSION, cl::vector<cl_name_version>) \
1581 F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION, cl::vector<cl_name_version>) \
1582 F(cl_device_info, CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES, cl_device_atomic_capabilities) \
1583 F(cl_device_info, CL_DEVICE_ATOMIC_FENCE_CAPABILITIES, cl_device_atomic_capabilities) \
1584 F(cl_device_info, CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT, cl_bool) \
1585 F(cl_device_info, CL_DEVICE_OPENCL_C_ALL_VERSIONS, cl::vector<cl_name_version>) \
1586 F(cl_device_info, CL_DEVICE_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, size_type) \
1587 F(cl_device_info, CL_DEVICE_WORK_GROUP_COLLECTIVE_FUNCTIONS_SUPPORT, cl_bool) \
1588 F(cl_device_info, CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT, cl_bool) \
1589 F(cl_device_info, CL_DEVICE_OPENCL_C_FEATURES, cl::vector<cl_name_version>) \
1590 F(cl_device_info, CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES, cl_device_device_enqueue_capabilities) \
1591 F(cl_device_info, CL_DEVICE_PIPE_SUPPORT, cl_bool) \
1592 F(cl_device_info, CL_DEVICE_LATEST_CONFORMANCE_VERSION_PASSED, string) \
1593 \
1594 F(cl_command_queue_info, CL_QUEUE_PROPERTIES_ARRAY, cl::vector<cl_queue_properties>) \
1595 F(cl_mem_info, CL_MEM_PROPERTIES, cl::vector<cl_mem_properties>) \
1596 F(cl_pipe_info, CL_PIPE_PROPERTIES, cl::vector<cl_pipe_properties>) \
1597 F(cl_sampler_info, CL_SAMPLER_PROPERTIES, cl::vector<cl_sampler_properties>) \
1598
1599#define CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_EXT(F) \
1600 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_ROW_PITCH_ALIGNMENT_EXT, size_type) \
1601 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_BASE_ADDRESS_ALIGNMENT_EXT, size_type) \
1602 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_SIZE_EXT, size_type) \
1603 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_WIDTH_EXT, cl_uint) \
1604 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_HEIGHT_EXT, cl_uint) \
1605 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_DEPTH_EXT, cl_uint) \
1606 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_ARRAY_SIZE_EXT, cl_uint) \
1607
1608#define CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT(F) \
1609 F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT, size_type) \
1610
1611#define CL_HPP_PARAM_NAME_CL_INTEL_COMMAND_QUEUE_FAMILIES_(F) \
1612 F(cl_device_info, CL_DEVICE_QUEUE_FAMILY_PROPERTIES_INTEL, cl::vector<cl_queue_family_properties_intel>) \
1613 \
1614 F(cl_command_queue_info, CL_QUEUE_FAMILY_INTEL, cl_uint) \
1615 F(cl_command_queue_info, CL_QUEUE_INDEX_INTEL, cl_uint)
1616
1617#define CL_HPP_PARAM_NAME_CL_INTEL_UNIFIED_SHARED_MEMORY_(F) \
1618 F(cl_device_info, CL_DEVICE_HOST_MEM_CAPABILITIES_INTEL, cl_device_unified_shared_memory_capabilities_intel ) \
1619 F(cl_device_info, CL_DEVICE_DEVICE_MEM_CAPABILITIES_INTEL, cl_device_unified_shared_memory_capabilities_intel ) \
1620 F(cl_device_info, CL_DEVICE_SINGLE_DEVICE_SHARED_MEM_CAPABILITIES_INTEL, cl_device_unified_shared_memory_capabilities_intel ) \
1621 F(cl_device_info, CL_DEVICE_CROSS_DEVICE_SHARED_MEM_CAPABILITIES_INTEL, cl_device_unified_shared_memory_capabilities_intel ) \
1622 F(cl_device_info, CL_DEVICE_SHARED_SYSTEM_MEM_CAPABILITIES_INTEL, cl_device_unified_shared_memory_capabilities_intel )
1623
1624template <typename enum_type, cl_int Name>
1626
1627#define CL_HPP_DECLARE_PARAM_TRAITS_(token, param_name, T) \
1628struct token; \
1629template<> \
1630struct param_traits<detail:: token,param_name> \
1631{ \
1632 enum { value = param_name }; \
1633 typedef T param_type; \
1634};
1635
1636CL_HPP_PARAM_NAME_INFO_1_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1637#if CL_HPP_TARGET_OPENCL_VERSION >= 110
1638CL_HPP_PARAM_NAME_INFO_1_1_(CL_HPP_DECLARE_PARAM_TRAITS_)
1639#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
1640#if CL_HPP_TARGET_OPENCL_VERSION >= 120
1641CL_HPP_PARAM_NAME_INFO_1_2_(CL_HPP_DECLARE_PARAM_TRAITS_)
1642#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
1643#if CL_HPP_TARGET_OPENCL_VERSION >= 200
1644CL_HPP_PARAM_NAME_INFO_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1645#endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
1646#if CL_HPP_TARGET_OPENCL_VERSION >= 210
1647CL_HPP_PARAM_NAME_INFO_2_1_(CL_HPP_DECLARE_PARAM_TRAITS_)
1648#endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
1649#if CL_HPP_TARGET_OPENCL_VERSION >= 220
1650CL_HPP_PARAM_NAME_INFO_2_2_(CL_HPP_DECLARE_PARAM_TRAITS_)
1651#endif // CL_HPP_TARGET_OPENCL_VERSION >= 220
1652#if CL_HPP_TARGET_OPENCL_VERSION >= 300
1653CL_HPP_PARAM_NAME_INFO_3_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1654#endif // CL_HPP_TARGET_OPENCL_VERSION >= 300
1655
1656#if defined(cl_khr_subgroups) && CL_HPP_TARGET_OPENCL_VERSION < 210
1657CL_HPP_PARAM_NAME_INFO_SUBGROUP_KHR_(CL_HPP_DECLARE_PARAM_TRAITS_)
1658#endif // #if defined(cl_khr_subgroups) && CL_HPP_TARGET_OPENCL_VERSION < 210
1659
1660#if defined(cl_khr_il_program) && CL_HPP_TARGET_OPENCL_VERSION < 210
1661CL_HPP_PARAM_NAME_INFO_IL_KHR_(CL_HPP_DECLARE_PARAM_TRAITS_)
1662#endif // #if defined(cl_khr_il_program) && CL_HPP_TARGET_OPENCL_VERSION < 210
1663
1664
1665// Flags deprecated in OpenCL 2.0
1666#define CL_HPP_PARAM_NAME_INFO_1_0_DEPRECATED_IN_2_0_(F) \
1667 F(cl_device_info, CL_DEVICE_QUEUE_PROPERTIES, cl_command_queue_properties)
1668
1669#define CL_HPP_PARAM_NAME_INFO_1_1_DEPRECATED_IN_2_0_(F) \
1670 F(cl_device_info, CL_DEVICE_HOST_UNIFIED_MEMORY, cl_bool)
1671
1672#define CL_HPP_PARAM_NAME_INFO_1_2_DEPRECATED_IN_2_0_(F) \
1673 F(cl_image_info, CL_IMAGE_BUFFER, cl::Buffer)
1674
1675// Include deprecated query flags based on versions
1676// Only include deprecated 1.0 flags if 2.0 not active as there is an enum clash
1677#if CL_HPP_TARGET_OPENCL_VERSION > 100 && CL_HPP_MINIMUM_OPENCL_VERSION < 200 && CL_HPP_TARGET_OPENCL_VERSION < 200
1678CL_HPP_PARAM_NAME_INFO_1_0_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1679#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 110
1680#if CL_HPP_TARGET_OPENCL_VERSION > 110 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
1681CL_HPP_PARAM_NAME_INFO_1_1_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1682#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
1683#if CL_HPP_TARGET_OPENCL_VERSION > 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
1684CL_HPP_PARAM_NAME_INFO_1_2_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1685#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
1686
1687#if defined(cl_ext_device_fission)
1688CL_HPP_PARAM_NAME_DEVICE_FISSION_EXT_(CL_HPP_DECLARE_PARAM_TRAITS_)
1689#endif // cl_ext_device_fission
1690
1691#if defined(cl_khr_extended_versioning)
1692#if CL_HPP_TARGET_OPENCL_VERSION < 300
1693CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_CL3_SHARED_(CL_HPP_DECLARE_PARAM_TRAITS_)
1694#endif // CL_HPP_TARGET_OPENCL_VERSION < 300
1695CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_KHRONLY_(CL_HPP_DECLARE_PARAM_TRAITS_)
1696#endif // cl_khr_extended_versioning
1697
1698#if defined(cl_khr_semaphore)
1699CL_HPP_PARAM_NAME_CL_KHR_SEMAPHORE_(CL_HPP_DECLARE_PARAM_TRAITS_)
1700#if defined(CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR)
1701CL_HPP_DECLARE_PARAM_TRAITS_(cl_semaphore_info_khr, CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR, cl::vector<cl::Device>)
1702#endif // defined(CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR)
1703#endif // defined(cl_khr_semaphore)
1704
1705#ifdef cl_khr_external_memory
1706CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_MEMORY_(CL_HPP_DECLARE_PARAM_TRAITS_)
1707#endif // cl_khr_external_memory
1708
1709#if defined(cl_khr_external_semaphore)
1710CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_(CL_HPP_DECLARE_PARAM_TRAITS_)
1711#endif // cl_khr_external_semaphore
1712
1713#if defined(cl_khr_external_semaphore_opaque_fd)
1714CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_OPAQUE_FD_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1715#endif // cl_khr_external_semaphore_opaque_fd
1716#if defined(cl_khr_external_semaphore_sync_fd)
1717CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_SYNC_FD_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1718#endif // cl_khr_external_semaphore_sync_fd
1719#if defined(cl_khr_external_semaphore_win32)
1720CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_WIN32_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1721#endif // cl_khr_external_semaphore_win32
1722
1723#if defined(cl_khr_device_uuid)
1724using uuid_array = array<cl_uchar, CL_UUID_SIZE_KHR>;
1725using luid_array = array<cl_uchar, CL_LUID_SIZE_KHR>;
1726CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_UUID_KHR, uuid_array)
1727CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DRIVER_UUID_KHR, uuid_array)
1728CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LUID_VALID_KHR, cl_bool)
1729CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LUID_KHR, luid_array)
1730CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_NODE_MASK_KHR, cl_uint)
1731#endif
1732
1733#if defined(cl_khr_pci_bus_info)
1734CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_PCI_BUS_INFO_KHR, cl_device_pci_bus_info_khr)
1735#endif
1736
1737// Note: some headers do not define cl_khr_image2d_from_buffer
1738#if CL_HPP_TARGET_OPENCL_VERSION < 200
1739#if defined(CL_DEVICE_IMAGE_PITCH_ALIGNMENT_KHR)
1740CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_IMAGE_PITCH_ALIGNMENT_KHR, cl_uint)
1741#endif
1742#if defined(CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT_KHR)
1743CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT_KHR, cl_uint)
1744#endif
1745#endif // CL_HPP_TARGET_OPENCL_VERSION < 200
1746
1747#if defined(cl_khr_integer_dot_product)
1748CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGER_DOT_PRODUCT_CAPABILITIES_KHR, cl_device_integer_dot_product_capabilities_khr)
1749#if defined(CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR)
1750CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR, cl_device_integer_dot_product_acceleration_properties_khr)
1751CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_4x8BIT_PACKED_KHR, cl_device_integer_dot_product_acceleration_properties_khr)
1752#endif // defined(CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR)
1753#endif // defined(cl_khr_integer_dot_product)
1754
1755#if defined(cl_ext_image_requirements_info)
1756CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1757#endif // cl_ext_image_requirements_info
1758
1759#if defined(cl_ext_image_from_buffer)
1760CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1761#endif // cl_ext_image_from_buffer
1762
1763#ifdef CL_PLATFORM_ICD_SUFFIX_KHR
1764CL_HPP_DECLARE_PARAM_TRAITS_(cl_platform_info, CL_PLATFORM_ICD_SUFFIX_KHR, string)
1765#endif
1766
1767#ifdef CL_DEVICE_PROFILING_TIMER_OFFSET_AMD
1768CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_PROFILING_TIMER_OFFSET_AMD, cl_ulong)
1769#endif
1770#ifdef CL_DEVICE_GLOBAL_FREE_MEMORY_AMD
1771CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_FREE_MEMORY_AMD, vector<size_type>)
1772#endif
1773#ifdef CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD
1774CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD, cl_uint)
1775#endif
1776#ifdef CL_DEVICE_SIMD_WIDTH_AMD
1777CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_WIDTH_AMD, cl_uint)
1778#endif
1779#ifdef CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD
1780CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD, cl_uint)
1781#endif
1782#ifdef CL_DEVICE_WAVEFRONT_WIDTH_AMD
1783CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_WAVEFRONT_WIDTH_AMD, cl_uint)
1784#endif
1785#ifdef CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD
1786CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD, cl_uint)
1787#endif
1788#ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD
1789CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD, cl_uint)
1790#endif
1791#ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD
1792CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD, cl_uint)
1793#endif
1794#ifdef CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD
1795CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD, cl_uint)
1796#endif
1797#ifdef CL_DEVICE_LOCAL_MEM_BANKS_AMD
1798CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LOCAL_MEM_BANKS_AMD, cl_uint)
1799#endif
1800#ifdef CL_DEVICE_BOARD_NAME_AMD
1801CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_BOARD_NAME_AMD, string)
1802#endif
1803
1804#ifdef CL_DEVICE_COMPUTE_UNITS_BITFIELD_ARM
1805CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_UNITS_BITFIELD_ARM, cl_ulong)
1806#endif
1807#ifdef CL_DEVICE_JOB_SLOTS_ARM
1808CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_JOB_SLOTS_ARM, cl_uint)
1809#endif
1810#ifdef CL_DEVICE_SCHEDULING_CONTROLS_CAPABILITIES_ARM
1811CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SCHEDULING_CONTROLS_CAPABILITIES_ARM, cl_bitfield)
1812#endif
1813#ifdef CL_DEVICE_SUPPORTED_REGISTER_ALLOCATIONS_ARM
1814CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SUPPORTED_REGISTER_ALLOCATIONS_ARM, vector<cl_uint>)
1815#endif
1816#ifdef CL_DEVICE_MAX_WARP_COUNT_ARM
1817CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_MAX_WARP_COUNT_ARM, cl_uint)
1818#endif
1819#ifdef CL_KERNEL_MAX_WARP_COUNT_ARM
1820CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_info, CL_KERNEL_MAX_WARP_COUNT_ARM, cl_uint)
1821#endif
1822#ifdef CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_ARM
1823CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_ARM, cl_uint)
1824#endif
1825#ifdef CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_MODIFIER_ARM
1826CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_MODIFIER_ARM, cl_int)
1827#endif
1828#ifdef CL_KERNEL_EXEC_INFO_WARP_COUNT_LIMIT_ARM
1829CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_WARP_COUNT_LIMIT_ARM, cl_uint)
1830#endif
1831#ifdef CL_KERNEL_EXEC_INFO_COMPUTE_UNIT_MAX_QUEUED_BATCHES_ARM
1832CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_COMPUTE_UNIT_MAX_QUEUED_BATCHES_ARM, cl_uint)
1833#endif
1834
1835#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
1836CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, cl_uint)
1837#endif
1838#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV
1839CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV, cl_uint)
1840#endif
1841#ifdef CL_DEVICE_REGISTERS_PER_BLOCK_NV
1842CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_REGISTERS_PER_BLOCK_NV, cl_uint)
1843#endif
1844#ifdef CL_DEVICE_WARP_SIZE_NV
1845CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_WARP_SIZE_NV, cl_uint)
1846#endif
1847#ifdef CL_DEVICE_GPU_OVERLAP_NV
1848CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GPU_OVERLAP_NV, cl_bool)
1849#endif
1850#ifdef CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV
1851CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV, cl_bool)
1852#endif
1853#ifdef CL_DEVICE_INTEGRATED_MEMORY_NV
1854CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGRATED_MEMORY_NV, cl_bool)
1855#endif
1856
1857#if defined(cl_khr_command_buffer)
1858CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMMAND_BUFFER_CAPABILITIES_KHR, cl_device_command_buffer_capabilities_khr)
1859CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR, cl_command_queue_properties)
1860CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_QUEUES_KHR, cl::vector<CommandQueue>)
1861CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_NUM_QUEUES_KHR, cl_uint)
1862CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR, cl_uint)
1863CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_STATE_KHR, cl_command_buffer_state_khr)
1864CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_PROPERTIES_ARRAY_KHR, cl::vector<cl_command_buffer_properties_khr>)
1865#endif /* cl_khr_command_buffer */
1866
1867#if defined(cl_khr_command_buffer_mutable_dispatch)
1868CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_QUEUE_KHR, CommandQueue)
1869CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_BUFFER_KHR, CommandBufferKhr)
1870CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_TYPE_KHR, cl_command_type)
1871
1872#if CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_EXTENSION_VERSION > CL_MAKE_VERSION(0, 9, 2)
1873CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_PROPERTIES_ARRAY_KHR, cl::vector<cl_command_properties_khr>)
1874#else
1875CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_PROPERTIES_ARRAY_KHR, cl::vector<cl_ndrange_kernel_command_properties_khr>)
1876#endif
1877CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_KERNEL_KHR, cl_kernel)
1878CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_DIMENSIONS_KHR, cl_uint)
1879CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_GLOBAL_WORK_OFFSET_KHR, cl::vector<size_type>)
1880CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_GLOBAL_WORK_SIZE_KHR, cl::vector<size_type>)
1881CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_LOCAL_WORK_SIZE_KHR, cl::vector<size_type>)
1882#endif /* cl_khr_command_buffer_mutable_dispatch */
1883
1884#if defined(cl_khr_kernel_clock)
1885CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_KERNEL_CLOCK_CAPABILITIES_KHR, cl_device_kernel_clock_capabilities_khr)
1886#endif /* cl_khr_kernel_clock */
1887
1888#if defined(cl_ext_float_atomics)
1889CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SINGLE_FP_ATOMIC_CAPABILITIES_EXT, cl_device_fp_atomic_capabilities_ext)
1890CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_DOUBLE_FP_ATOMIC_CAPABILITIES_EXT, cl_device_fp_atomic_capabilities_ext)
1891CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_HALF_FP_ATOMIC_CAPABILITIES_EXT, cl_device_fp_atomic_capabilities_ext)
1892#endif /* cl_ext_float_atomics */
1893
1894#if defined(cl_intel_command_queue_families)
1895CL_HPP_PARAM_NAME_CL_INTEL_COMMAND_QUEUE_FAMILIES_(CL_HPP_DECLARE_PARAM_TRAITS_)
1896#endif // cl_intel_command_queue_families
1897
1898#if defined(cl_intel_device_attribute_query)
1899CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_IP_VERSION_INTEL, cl_uint)
1900CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_ID_INTEL, cl_uint)
1901CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_NUM_SLICES_INTEL, cl_uint)
1902CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_NUM_SUB_SLICES_PER_SLICE_INTEL, cl_uint)
1903CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_NUM_EUS_PER_SUB_SLICE_INTEL, cl_uint)
1904CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_NUM_THREADS_PER_EU_INTEL, cl_uint)
1905CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_FEATURE_CAPABILITIES_INTEL, cl_device_feature_capabilities_intel)
1906#endif // cl_intel_device_attribute_query
1907
1908#if defined(cl_intel_required_subgroup_size)
1909CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SUB_GROUP_SIZES_INTEL, cl::vector<size_type>)
1910CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_work_group_info, CL_KERNEL_SPILL_MEM_SIZE_INTEL, cl_ulong)
1911#endif // cl_intel_required_subgroup_size
1912
1913#if defined(cl_intel_unified_shared_memory)
1914CL_HPP_PARAM_NAME_CL_INTEL_UNIFIED_SHARED_MEMORY_(CL_HPP_DECLARE_PARAM_TRAITS_)
1915#endif // cl_intel_unified_shared_memory
1916
1917// Convenience functions
1918
1919template <typename Func, typename T>
1920inline cl_int
1921getInfo(Func f, cl_uint name, T* param)
1922{
1923 return getInfoHelper(f, name, param, 0);
1924}
1925
1926template <typename Func, typename Arg0>
1928{
1929 Func f_; const Arg0& arg0_;
1930 cl_int operator ()(
1931 cl_uint param, size_type size, void* value, size_type* size_ret)
1932 { return f_(arg0_, param, size, value, size_ret); }
1933};
1934
1935template <typename Func, typename Arg0, typename Arg1>
1937{
1938 Func f_; const Arg0& arg0_; const Arg1& arg1_;
1939 cl_int operator ()(
1940 cl_uint param, size_type size, void* value, size_type* size_ret)
1941 { return f_(arg0_, arg1_, param, size, value, size_ret); }
1942};
1943
1944template <typename Func, typename Arg0, typename T>
1945inline cl_int
1946getInfo(Func f, const Arg0& arg0, cl_uint name, T* param)
1947{
1948 GetInfoFunctor0<Func, Arg0> f0 = { f, arg0 };
1949 return getInfoHelper(f0, name, param, 0);
1950}
1951
1952template <typename Func, typename Arg0, typename Arg1, typename T>
1953inline cl_int
1954getInfo(Func f, const Arg0& arg0, const Arg1& arg1, cl_uint name, T* param)
1955{
1956 GetInfoFunctor1<Func, Arg0, Arg1> f0 = { f, arg0, arg1 };
1957 return getInfoHelper(f0, name, param, 0);
1958}
1959
1960
1961template<typename T>
1963{ };
1964
1965#if CL_HPP_TARGET_OPENCL_VERSION >= 120
1969template <>
1970struct ReferenceHandler<cl_device_id>
1971{
1981 static cl_int retain(cl_device_id device)
1982 { return ::clRetainDevice(device); }
1992 static cl_int release(cl_device_id device)
1993 { return ::clReleaseDevice(device); }
1994};
1995#else // CL_HPP_TARGET_OPENCL_VERSION >= 120
1999template <>
2000struct ReferenceHandler<cl_device_id>
2001{
2002 // cl_device_id does not have retain().
2003 static cl_int retain(cl_device_id)
2004 { return CL_SUCCESS; }
2005 // cl_device_id does not have release().
2006 static cl_int release(cl_device_id)
2007 { return CL_SUCCESS; }
2008};
2009#endif // ! (CL_HPP_TARGET_OPENCL_VERSION >= 120)
2010
2011template <>
2012struct ReferenceHandler<cl_platform_id>
2013{
2014 // cl_platform_id does not have retain().
2015 static cl_int retain(cl_platform_id)
2016 { return CL_SUCCESS; }
2017 // cl_platform_id does not have release().
2018 static cl_int release(cl_platform_id)
2019 { return CL_SUCCESS; }
2020};
2021
2022template <>
2023struct ReferenceHandler<cl_context>
2024{
2025 static cl_int retain(cl_context context)
2026 { return ::clRetainContext(context); }
2027 static cl_int release(cl_context context)
2028 { return ::clReleaseContext(context); }
2029};
2030
2031template <>
2032struct ReferenceHandler<cl_command_queue>
2033{
2034 static cl_int retain(cl_command_queue queue)
2035 { return ::clRetainCommandQueue(queue); }
2036 static cl_int release(cl_command_queue queue)
2037 { return ::clReleaseCommandQueue(queue); }
2038};
2039
2040template <>
2041struct ReferenceHandler<cl_mem>
2042{
2043 static cl_int retain(cl_mem memory)
2044 { return ::clRetainMemObject(memory); }
2045 static cl_int release(cl_mem memory)
2046 { return ::clReleaseMemObject(memory); }
2047};
2048
2049template <>
2050struct ReferenceHandler<cl_sampler>
2051{
2052 static cl_int retain(cl_sampler sampler)
2053 { return ::clRetainSampler(sampler); }
2054 static cl_int release(cl_sampler sampler)
2055 { return ::clReleaseSampler(sampler); }
2056};
2057
2058template <>
2059struct ReferenceHandler<cl_program>
2060{
2061 static cl_int retain(cl_program program)
2062 { return ::clRetainProgram(program); }
2063 static cl_int release(cl_program program)
2064 { return ::clReleaseProgram(program); }
2065};
2066
2067template <>
2068struct ReferenceHandler<cl_kernel>
2069{
2070 static cl_int retain(cl_kernel kernel)
2071 { return ::clRetainKernel(kernel); }
2072 static cl_int release(cl_kernel kernel)
2073 { return ::clReleaseKernel(kernel); }
2074};
2075
2076template <>
2077struct ReferenceHandler<cl_event>
2078{
2079 static cl_int retain(cl_event event)
2080 { return ::clRetainEvent(event); }
2081 static cl_int release(cl_event event)
2082 { return ::clReleaseEvent(event); }
2083};
2084
2085#ifdef cl_khr_semaphore
2086template <>
2087struct ReferenceHandler<cl_semaphore_khr>
2088{
2089 static cl_int retain(cl_semaphore_khr semaphore)
2090 {
2091 if (pfn_clRetainSemaphoreKHR != nullptr) {
2092 return pfn_clRetainSemaphoreKHR(semaphore);
2093 }
2094
2095 return CL_INVALID_OPERATION;
2096 }
2097
2098 static cl_int release(cl_semaphore_khr semaphore)
2099 {
2100 if (pfn_clReleaseSemaphoreKHR != nullptr) {
2101 return pfn_clReleaseSemaphoreKHR(semaphore);
2102 }
2103
2104 return CL_INVALID_OPERATION;
2105 }
2106};
2107#endif // cl_khr_semaphore
2108#if defined(cl_khr_command_buffer)
2109template <>
2110struct ReferenceHandler<cl_command_buffer_khr>
2111{
2112 static cl_int retain(cl_command_buffer_khr cmdBufferKhr)
2113 {
2114 if (pfn_clRetainCommandBufferKHR == nullptr) {
2115 return detail::errHandler(CL_INVALID_OPERATION, __RETAIN_COMMAND_BUFFER_KHR_ERR);
2116 }
2117 return pfn_clRetainCommandBufferKHR(cmdBufferKhr);
2118 }
2119
2120 static cl_int release(cl_command_buffer_khr cmdBufferKhr)
2121 {
2122 if (pfn_clReleaseCommandBufferKHR == nullptr) {
2123 return detail::errHandler(CL_INVALID_OPERATION, __RELEASE_COMMAND_BUFFER_KHR_ERR);
2124 }
2125 return pfn_clReleaseCommandBufferKHR(cmdBufferKhr);
2126 }
2127};
2128
2129template <>
2130struct ReferenceHandler<cl_mutable_command_khr>
2131{
2132 // cl_mutable_command_khr does not have retain().
2133 static cl_int retain(cl_mutable_command_khr)
2134 { return CL_SUCCESS; }
2135 // cl_mutable_command_khr does not have release().
2136 static cl_int release(cl_mutable_command_khr)
2137 { return CL_SUCCESS; }
2138};
2139#endif // cl_khr_command_buffer
2140
2141
2142#if (CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120) || \
2143 (CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200)
2144// Extracts version number with major in the upper 16 bits, minor in the lower 16
2145static cl_uint getVersion(const vector<char> &versionInfo)
2146{
2147 int highVersion = 0;
2148 int lowVersion = 0;
2149 int index = 7;
2150 while(versionInfo[index] != '.' ) {
2151 highVersion *= 10;
2152 highVersion += versionInfo[index]-'0';
2153 ++index;
2154 }
2155 ++index;
2156 while(versionInfo[index] != ' ' && versionInfo[index] != '\0') {
2157 lowVersion *= 10;
2158 lowVersion += versionInfo[index]-'0';
2159 ++index;
2160 }
2161 return (highVersion << 16) | lowVersion;
2162}
2163
2164static cl_uint getPlatformVersion(cl_platform_id platform)
2165{
2166 size_type size = 0;
2167 clGetPlatformInfo(platform, CL_PLATFORM_VERSION, 0, nullptr, &size);
2168
2169 vector<char> versionInfo(size);
2170 clGetPlatformInfo(platform, CL_PLATFORM_VERSION, size, versionInfo.data(), &size);
2171 return getVersion(versionInfo);
2172}
2173
2174static cl_uint getDevicePlatformVersion(cl_device_id device)
2175{
2176 cl_platform_id platform;
2177 clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(platform), &platform, nullptr);
2178 return getPlatformVersion(platform);
2179}
2180
2181static cl_uint getContextPlatformVersion(cl_context context)
2182{
2183 // The platform cannot be queried directly, so we first have to grab a
2184 // device and obtain its context
2185 size_type size = 0;
2186 clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, nullptr, &size);
2187 if (size == 0)
2188 return 0;
2189 vector<cl_device_id> devices(size/sizeof(cl_device_id));
2190 clGetContextInfo(context, CL_CONTEXT_DEVICES, size, devices.data(), nullptr);
2191 return getDevicePlatformVersion(devices[0]);
2192}
2193#endif // CL_HPP_TARGET_OPENCL_VERSION && CL_HPP_MINIMUM_OPENCL_VERSION
2194
2195template <typename T>
2197{
2198public:
2199 typedef T cl_type;
2200
2201protected:
2202 cl_type object_;
2203
2204public:
2205 Wrapper() : object_(nullptr) { }
2206
2207 Wrapper(const cl_type &obj, bool retainObject) : object_(obj)
2208 {
2209 if (retainObject) {
2210 detail::errHandler(retain(), __RETAIN_ERR);
2211 }
2212 }
2213
2214 ~Wrapper()
2215 {
2216 if (object_ != nullptr) { release(); }
2217 }
2218
2219 Wrapper(const Wrapper<cl_type>& rhs)
2220 {
2221 object_ = rhs.object_;
2222 detail::errHandler(retain(), __RETAIN_ERR);
2223 }
2224
2225 Wrapper(Wrapper<cl_type>&& rhs) noexcept
2226 {
2227 object_ = rhs.object_;
2228 rhs.object_ = nullptr;
2229 }
2230
2231 Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
2232 {
2233 if (this != &rhs) {
2234 detail::errHandler(release(), __RELEASE_ERR);
2235 object_ = rhs.object_;
2236 detail::errHandler(retain(), __RETAIN_ERR);
2237 }
2238 return *this;
2239 }
2240
2241 Wrapper<cl_type>& operator = (Wrapper<cl_type>&& rhs)
2242 {
2243 if (this != &rhs) {
2244 detail::errHandler(release(), __RELEASE_ERR);
2245 object_ = rhs.object_;
2246 rhs.object_ = nullptr;
2247 }
2248 return *this;
2249 }
2250
2251 Wrapper<cl_type>& operator = (const cl_type &rhs)
2252 {
2253 detail::errHandler(release(), __RELEASE_ERR);
2254 object_ = rhs;
2255 return *this;
2256 }
2257
2258 const cl_type& operator ()() const { return object_; }
2259
2260 cl_type& operator ()() { return object_; }
2261
2262 cl_type get() const { return object_; }
2263
2264protected:
2265 template<typename Func, typename U>
2266 friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type);
2267
2268 cl_int retain() const
2269 {
2270 if (object_ != nullptr) {
2271 return ReferenceHandler<cl_type>::retain(object_);
2272 }
2273 else {
2274 return CL_SUCCESS;
2275 }
2276 }
2277
2278 cl_int release() const
2279 {
2280 if (object_ != nullptr) {
2281 return ReferenceHandler<cl_type>::release(object_);
2282 }
2283 else {
2284 return CL_SUCCESS;
2285 }
2286 }
2287};
2288
2289template <>
2290class Wrapper<cl_device_id>
2291{
2292public:
2293 typedef cl_device_id cl_type;
2294
2295protected:
2296 cl_type object_;
2297 bool referenceCountable_;
2298
2299 static bool isReferenceCountable(cl_device_id device)
2300 {
2301 bool retVal = false;
2302#if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
2303 if (device != nullptr) {
2304 int version = getDevicePlatformVersion(device);
2305 if(version > ((1 << 16) + 1)) {
2306 retVal = true;
2307 }
2308 }
2309#elif CL_HPP_TARGET_OPENCL_VERSION >= 120
2310 retVal = true;
2311#endif // CL_HPP_TARGET_OPENCL_VERSION
2312 (void)device;
2313 return retVal;
2314 }
2315
2316public:
2317 Wrapper() : object_(nullptr), referenceCountable_(false)
2318 {
2319 }
2320
2321 Wrapper(const cl_type &obj, bool retainObject) :
2322 object_(obj),
2323 referenceCountable_(false)
2324 {
2325 referenceCountable_ = isReferenceCountable(obj);
2326
2327 if (retainObject) {
2328 detail::errHandler(retain(), __RETAIN_ERR);
2329 }
2330 }
2331
2332 ~Wrapper()
2333 {
2334 release();
2335 }
2336
2337 Wrapper(const Wrapper<cl_type>& rhs)
2338 {
2339 object_ = rhs.object_;
2340 referenceCountable_ = isReferenceCountable(object_);
2341 detail::errHandler(retain(), __RETAIN_ERR);
2342 }
2343
2344 Wrapper(Wrapper<cl_type>&& rhs) noexcept
2345 {
2346 object_ = rhs.object_;
2347 referenceCountable_ = rhs.referenceCountable_;
2348 rhs.object_ = nullptr;
2349 rhs.referenceCountable_ = false;
2350 }
2351
2352 Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
2353 {
2354 if (this != &rhs) {
2355 detail::errHandler(release(), __RELEASE_ERR);
2356 object_ = rhs.object_;
2357 referenceCountable_ = rhs.referenceCountable_;
2358 detail::errHandler(retain(), __RETAIN_ERR);
2359 }
2360 return *this;
2361 }
2362
2363 Wrapper<cl_type>& operator = (Wrapper<cl_type>&& rhs)
2364 {
2365 if (this != &rhs) {
2366 detail::errHandler(release(), __RELEASE_ERR);
2367 object_ = rhs.object_;
2368 referenceCountable_ = rhs.referenceCountable_;
2369 rhs.object_ = nullptr;
2370 rhs.referenceCountable_ = false;
2371 }
2372 return *this;
2373 }
2374
2375 Wrapper<cl_type>& operator = (const cl_type &rhs)
2376 {
2377 detail::errHandler(release(), __RELEASE_ERR);
2378 object_ = rhs;
2379 referenceCountable_ = isReferenceCountable(object_);
2380 return *this;
2381 }
2382
2383 const cl_type& operator ()() const { return object_; }
2384
2385 cl_type& operator ()() { return object_; }
2386
2387 cl_type get() const { return object_; }
2388
2389protected:
2390 template<typename Func, typename U>
2391 friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type);
2392
2393 template<typename Func, typename U>
2394 friend inline cl_int getInfoHelper(Func, cl_uint, vector<U>*, int, typename U::cl_type);
2395
2396 cl_int retain() const
2397 {
2398 if( object_ != nullptr && referenceCountable_ ) {
2399 return ReferenceHandler<cl_type>::retain(object_);
2400 }
2401 else {
2402 return CL_SUCCESS;
2403 }
2404 }
2405
2406 cl_int release() const
2407 {
2408 if (object_ != nullptr && referenceCountable_) {
2409 return ReferenceHandler<cl_type>::release(object_);
2410 }
2411 else {
2412 return CL_SUCCESS;
2413 }
2414 }
2415};
2416
2417template <typename T>
2418inline bool operator==(const Wrapper<T> &lhs, const Wrapper<T> &rhs)
2419{
2420 return lhs() == rhs();
2421}
2422
2423template <typename T>
2424inline bool operator!=(const Wrapper<T> &lhs, const Wrapper<T> &rhs)
2425{
2426 return !operator==(lhs, rhs);
2427}
2428
2429} // namespace detail
2431
2432
2433
2434
2435
2441struct ImageFormat : public cl_image_format
2442{
2445
2447 ImageFormat(cl_channel_order order, cl_channel_type type)
2448 {
2449 image_channel_order = order;
2450 image_channel_data_type = type;
2451 }
2452
2454 ImageFormat(const ImageFormat &other) { *this = other; }
2455
2458 {
2459 if (this != &rhs) {
2460 this->image_channel_data_type = rhs.image_channel_data_type;
2461 this->image_channel_order = rhs.image_channel_order;
2462 }
2463 return *this;
2464 }
2465};
2466
2474class Device : public detail::Wrapper<cl_device_id>
2475{
2476private:
2477 static std::once_flag default_initialized_;
2478 static Device default_;
2479 static cl_int default_error_;
2480
2486 static void makeDefault();
2487
2493 static void makeDefaultProvided(const Device &p) {
2494 default_ = p;
2495 }
2496
2497public:
2498#ifdef CL_HPP_UNIT_TEST_ENABLE
2505 static void unitTestClearDefault() {
2506 default_ = Device();
2507 }
2508#endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
2509
2511 Device() : detail::Wrapper<cl_type>() { }
2512
2517 explicit Device(const cl_device_id &device, bool retainObject = false) :
2518 detail::Wrapper<cl_type>(device, retainObject) { }
2519
2525 cl_int *errResult = nullptr)
2526 {
2527 std::call_once(default_initialized_, makeDefault);
2528 detail::errHandler(default_error_);
2529 if (errResult != nullptr) {
2530 *errResult = default_error_;
2531 }
2532 return default_;
2533 }
2534
2542 static Device setDefault(const Device &default_device)
2543 {
2544 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_device));
2545 detail::errHandler(default_error_);
2546 return default_;
2547 }
2548
2553 Device& operator = (const cl_device_id& rhs)
2554 {
2556 return *this;
2557 }
2558
2559
2561 template <typename T>
2562 cl_int getInfo(cl_device_info name, T* param) const
2563 {
2564 return detail::errHandler(
2565 detail::getInfo(&::clGetDeviceInfo, object_, name, param),
2566 __GET_DEVICE_INFO_ERR);
2567 }
2568
2570 template <cl_device_info name> typename
2572 getInfo(cl_int* err = nullptr) const
2573 {
2574 typename detail::param_traits<
2575 detail::cl_device_info, name>::param_type param;
2576 cl_int result = getInfo(name, &param);
2577 if (err != nullptr) {
2578 *err = result;
2579 }
2580 return param;
2581 }
2582
2583#if CL_HPP_TARGET_OPENCL_VERSION >= 210
2590 cl_ulong getHostTimer(cl_int *error = nullptr)
2591 {
2592 cl_ulong retVal = 0;
2593 cl_int err =
2594 clGetHostTimer(this->get(), &retVal);
2595 detail::errHandler(
2596 err,
2597 __GET_HOST_TIMER_ERR);
2598 if (error) {
2599 *error = err;
2600 }
2601 return retVal;
2602 }
2603
2614 std::pair<cl_ulong, cl_ulong> getDeviceAndHostTimer(cl_int *error = nullptr)
2615 {
2616 std::pair<cl_ulong, cl_ulong> retVal;
2617 cl_int err =
2618 clGetDeviceAndHostTimer(this->get(), &(retVal.first), &(retVal.second));
2619 detail::errHandler(
2620 err,
2621 __GET_DEVICE_AND_HOST_TIMER_ERR);
2622 if (error) {
2623 *error = err;
2624 }
2625 return retVal;
2626 }
2627#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
2628
2629#if CL_HPP_TARGET_OPENCL_VERSION >= 120
2631 cl_int createSubDevices(const cl_device_partition_property* properties,
2632 vector<Device>* devices);
2633#endif // defined (CL_HPP_TARGET_OPENCL_VERSION >= 120)
2634
2635#if defined(cl_ext_device_fission)
2637 cl_int createSubDevices(const cl_device_partition_property_ext* properties,
2638 vector<Device>* devices);
2639#endif // defined(cl_ext_device_fission)
2640};
2641
2642using BuildLogType = vector<std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, CL_PROGRAM_BUILD_LOG>::param_type>>;
2643#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2647class BuildError : public Error
2648{
2649private:
2650 BuildLogType buildLogs;
2651public:
2652 BuildError(cl_int err, const char * errStr, const BuildLogType &vec) : Error(err, errStr), buildLogs(vec)
2653 {
2654 }
2655
2656 BuildLogType getBuildLog() const
2657 {
2658 return buildLogs;
2659 }
2660};
2661namespace detail {
2662 static inline cl_int buildErrHandler(
2663 cl_int err,
2664 const char * errStr,
2665 const BuildLogType &buildLogs)
2666 {
2667 if (err != CL_SUCCESS) {
2668 throw BuildError(err, errStr, buildLogs);
2669 }
2670 return err;
2671 }
2672} // namespace detail
2673
2674#else
2675namespace detail {
2676 static inline cl_int buildErrHandler(
2677 cl_int err,
2678 const char * errStr,
2679 const BuildLogType &buildLogs)
2680 {
2681 (void)buildLogs; // suppress unused variable warning
2682 (void)errStr;
2683 return err;
2684 }
2685} // namespace detail
2686#endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
2687
2688CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Device::default_initialized_;
2689CL_HPP_DEFINE_STATIC_MEMBER_ Device Device::default_;
2690CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Device::default_error_ = CL_SUCCESS;
2691
2699class Platform : public detail::Wrapper<cl_platform_id>
2700{
2701private:
2702 static std::once_flag default_initialized_;
2703 static Platform default_;
2704 static cl_int default_error_;
2705
2711 static void makeDefault() {
2712 /* Throwing an exception from a call_once invocation does not do
2713 * what we wish, so we catch it and save the error.
2714 */
2715#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2716 try
2717#endif
2718 {
2719 // If default wasn't passed ,generate one
2720 // Otherwise set it
2721 cl_uint n = 0;
2722
2723 cl_int err = ::clGetPlatformIDs(0, nullptr, &n);
2724 if (err != CL_SUCCESS) {
2725 default_error_ = err;
2726 return;
2727 }
2728 if (n == 0) {
2729 default_error_ = CL_INVALID_PLATFORM;
2730 return;
2731 }
2732
2733 vector<cl_platform_id> ids(n);
2734 err = ::clGetPlatformIDs(n, ids.data(), nullptr);
2735 if (err != CL_SUCCESS) {
2736 default_error_ = err;
2737 return;
2738 }
2739
2740 default_ = Platform(ids[0]);
2741 }
2742#if defined(CL_HPP_ENABLE_EXCEPTIONS)
2743 catch (cl::Error &e) {
2744 default_error_ = e.err();
2745 }
2746#endif
2747 }
2748
2754 static void makeDefaultProvided(const Platform &p) {
2755 default_ = p;
2756 }
2757
2758public:
2759#ifdef CL_HPP_UNIT_TEST_ENABLE
2766 static void unitTestClearDefault() {
2767 default_ = Platform();
2768 }
2769#endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
2770
2772 Platform() : detail::Wrapper<cl_type>() { }
2773
2781 explicit Platform(const cl_platform_id &platform, bool retainObject = false) :
2782 detail::Wrapper<cl_type>(platform, retainObject) { }
2783
2788 Platform& operator = (const cl_platform_id& rhs)
2789 {
2791 return *this;
2792 }
2793
2794 static Platform getDefault(
2795 cl_int *errResult = nullptr)
2796 {
2797 std::call_once(default_initialized_, makeDefault);
2798 detail::errHandler(default_error_);
2799 if (errResult != nullptr) {
2800 *errResult = default_error_;
2801 }
2802 return default_;
2803 }
2804
2812 static Platform setDefault(const Platform &default_platform)
2813 {
2814 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_platform));
2815 detail::errHandler(default_error_);
2816 return default_;
2817 }
2818
2820 template <typename T>
2821 cl_int getInfo(cl_platform_info name, T* param) const
2822 {
2823 return detail::errHandler(
2824 detail::getInfo(&::clGetPlatformInfo, object_, name, param),
2825 __GET_PLATFORM_INFO_ERR);
2826 }
2827
2829 template <cl_platform_info name> typename
2831 getInfo(cl_int* err = nullptr) const
2832 {
2833 typename detail::param_traits<
2834 detail::cl_platform_info, name>::param_type param;
2835 cl_int result = getInfo(name, &param);
2836 if (err != nullptr) {
2837 *err = result;
2838 }
2839 return param;
2840 }
2841
2847 cl_device_type type,
2848 vector<Device>* devices) const
2849 {
2850 cl_uint n = 0;
2851 if( devices == nullptr ) {
2852 return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR);
2853 }
2854 cl_int err = ::clGetDeviceIDs(object_, type, 0, nullptr, &n);
2855 if (err != CL_SUCCESS && err != CL_DEVICE_NOT_FOUND) {
2856 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2857 }
2858
2859 vector<cl_device_id> ids(n);
2860 if (n>0) {
2861 err = ::clGetDeviceIDs(object_, type, n, ids.data(), nullptr);
2862 if (err != CL_SUCCESS) {
2863 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2864 }
2865 }
2866
2867 // Cannot trivially assign because we need to capture intermediates
2868 // with safe construction
2869 // We must retain things we obtain from the API to avoid releasing
2870 // API-owned objects.
2871 if (devices) {
2872 devices->resize(ids.size());
2873
2874 // Assign to param, constructing with retain behaviour
2875 // to correctly capture each underlying CL object
2876 for (size_type i = 0; i < ids.size(); i++) {
2877 (*devices)[i] = Device(ids[i], true);
2878 }
2879 }
2880 return CL_SUCCESS;
2881 }
2882
2883#if defined(CL_HPP_USE_DX_INTEROP)
2907 cl_int getDevices(
2908 cl_d3d10_device_source_khr d3d_device_source,
2909 void * d3d_object,
2910 cl_d3d10_device_set_khr d3d_device_set,
2911 vector<Device>* devices) const
2912 {
2913 typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clGetDeviceIDsFromD3D10KHR)(
2914 cl_platform_id platform,
2915 cl_d3d10_device_source_khr d3d_device_source,
2916 void * d3d_object,
2917 cl_d3d10_device_set_khr d3d_device_set,
2918 cl_uint num_entries,
2919 cl_device_id * devices,
2920 cl_uint* num_devices);
2921
2922 if( devices == nullptr ) {
2923 return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR);
2924 }
2925
2926 static PFN_clGetDeviceIDsFromD3D10KHR pfn_clGetDeviceIDsFromD3D10KHR = nullptr;
2927#if CL_HPP_TARGET_OPENCL_VERSION >= 120
2928 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(object_, clGetDeviceIDsFromD3D10KHR);
2929#endif
2930#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
2931 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetDeviceIDsFromD3D10KHR);
2932#endif
2933
2934 cl_uint n = 0;
2935 cl_int err = pfn_clGetDeviceIDsFromD3D10KHR(
2936 object_,
2937 d3d_device_source,
2938 d3d_object,
2939 d3d_device_set,
2940 0,
2941 nullptr,
2942 &n);
2943 if (err != CL_SUCCESS) {
2944 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2945 }
2946
2947 vector<cl_device_id> ids(n);
2948 err = pfn_clGetDeviceIDsFromD3D10KHR(
2949 object_,
2950 d3d_device_source,
2951 d3d_object,
2952 d3d_device_set,
2953 n,
2954 ids.data(),
2955 nullptr);
2956 if (err != CL_SUCCESS) {
2957 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2958 }
2959
2960 // Cannot trivially assign because we need to capture intermediates
2961 // with safe construction
2962 // We must retain things we obtain from the API to avoid releasing
2963 // API-owned objects.
2964 if (devices) {
2965 devices->resize(ids.size());
2966
2967 // Assign to param, constructing with retain behaviour
2968 // to correctly capture each underlying CL object
2969 for (size_type i = 0; i < ids.size(); i++) {
2970 (*devices)[i] = Device(ids[i], true);
2971 }
2972 }
2973 return CL_SUCCESS;
2974 }
2975#endif
2976
2981 static cl_int get(
2982 vector<Platform>* platforms)
2983 {
2984 cl_uint n = 0;
2985
2986 if( platforms == nullptr ) {
2987 return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_PLATFORM_IDS_ERR);
2988 }
2989
2990 cl_int err = ::clGetPlatformIDs(0, nullptr, &n);
2991 if (err != CL_SUCCESS) {
2992 return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2993 }
2994
2995 vector<cl_platform_id> ids(n);
2996 err = ::clGetPlatformIDs(n, ids.data(), nullptr);
2997 if (err != CL_SUCCESS) {
2998 return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2999 }
3000
3001 if (platforms) {
3002 platforms->resize(ids.size());
3003
3004 // Platforms don't reference count
3005 for (size_type i = 0; i < ids.size(); i++) {
3006 (*platforms)[i] = Platform(ids[i]);
3007 }
3008 }
3009 return CL_SUCCESS;
3010 }
3011
3016 static cl_int get(
3017 Platform * platform)
3018 {
3019 cl_int err;
3020 Platform default_platform = Platform::getDefault(&err);
3021 if (platform) {
3022 *platform = default_platform;
3023 }
3024 return err;
3025 }
3026
3036 cl_int * errResult = nullptr)
3037 {
3038 cl_int err;
3039 Platform default_platform = Platform::getDefault(&err);
3040 if (errResult) {
3041 *errResult = err;
3042 }
3043 return default_platform;
3044 }
3045
3046#if CL_HPP_TARGET_OPENCL_VERSION >= 120
3048 cl_int
3050 {
3051 return ::clUnloadPlatformCompiler(object_);
3052 }
3053#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
3054}; // class Platform
3055
3056#if CL_HPP_TARGET_OPENCL_VERSION >= 120
3058inline cl_int Device::createSubDevices(const cl_device_partition_property* properties,
3059 vector<Device>* devices)
3060{
3061 cl_uint n = 0;
3062 cl_int err = clCreateSubDevices(object_, properties, 0, nullptr, &n);
3063 if (err != CL_SUCCESS)
3064 {
3065 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
3066 }
3067
3068 vector<cl_device_id> ids(n);
3069 err = clCreateSubDevices(object_, properties, n, ids.data(), nullptr);
3070 if (err != CL_SUCCESS)
3071 {
3072 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
3073 }
3074
3075 // Cannot trivially assign because we need to capture intermediates
3076 // with safe construction
3077 if (devices)
3078 {
3079 devices->resize(ids.size());
3080
3081 // Assign to param, constructing with retain behaviour
3082 // to correctly capture each underlying CL object
3083 for (size_type i = 0; i < ids.size(); i++)
3084 {
3085 // We do not need to retain because this device is being created
3086 // by the runtime
3087 (*devices)[i] = Device(ids[i], false);
3088 }
3089 }
3090
3091 return CL_SUCCESS;
3092}
3093#endif // defined (CL_HPP_TARGET_OPENCL_VERSION >= 120)
3094
3095#if defined(cl_ext_device_fission)
3097inline cl_int Device::createSubDevices(const cl_device_partition_property_ext* properties,
3098 vector<Device>* devices)
3099{
3100#if CL_HPP_TARGET_OPENCL_VERSION >= 120
3101 cl::Device device(object_);
3102 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
3103 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateSubDevicesEXT);
3104#endif
3105#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
3106 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateSubDevicesEXT);
3107#endif
3108
3109 cl_uint n = 0;
3110 cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, nullptr, &n);
3111 if (err != CL_SUCCESS)
3112 {
3113 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
3114 }
3115
3116 vector<cl_device_id> ids(n);
3117 err =
3118 pfn_clCreateSubDevicesEXT(object_, properties, n, ids.data(), nullptr);
3119 if (err != CL_SUCCESS)
3120 {
3121 return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
3122 }
3123 // Cannot trivially assign because we need to capture intermediates
3124 // with safe construction
3125 if (devices)
3126 {
3127 devices->resize(ids.size());
3128
3129 // Assign to param, constructing with retain behaviour
3130 // to correctly capture each underlying CL object
3131 for (size_type i = 0; i < ids.size(); i++)
3132 {
3133 // We do not need to retain because this device is being created
3134 // by the runtime
3135 (*devices)[i] = Device(ids[i], false);
3136 }
3137 }
3138
3139 return CL_SUCCESS;
3140}
3141#endif // defined(cl_ext_device_fission)
3142
3143CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Platform::default_initialized_;
3144CL_HPP_DEFINE_STATIC_MEMBER_ Platform Platform::default_;
3145CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Platform::default_error_ = CL_SUCCESS;
3146
3147
3151#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
3156inline CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_int
3157UnloadCompiler() CL_API_SUFFIX__VERSION_1_1_DEPRECATED;
3158inline cl_int
3160{
3161 return ::clUnloadCompiler();
3162}
3163#endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
3164
3165
3166#if defined(cl_ext_image_requirements_info)
3167enum ImageRequirementsInfoExt : cl_image_requirements_info_ext
3168{
3169 RowPitchAlign = CL_IMAGE_REQUIREMENTS_ROW_PITCH_ALIGNMENT_EXT,
3170 BaseAddAlign = CL_IMAGE_REQUIREMENTS_BASE_ADDRESS_ALIGNMENT_EXT,
3171 Size = CL_IMAGE_REQUIREMENTS_SIZE_EXT,
3172 MaxWidth = CL_IMAGE_REQUIREMENTS_MAX_WIDTH_EXT,
3173 MaxHeight = CL_IMAGE_REQUIREMENTS_MAX_HEIGHT_EXT,
3174 MaxDepth = CL_IMAGE_REQUIREMENTS_MAX_DEPTH_EXT,
3175 MaxArraySize = CL_IMAGE_REQUIREMENTS_MAX_ARRAY_SIZE_EXT,
3176#if defined(cl_ext_image_from_buffer)
3177 SlicePitchAlign = CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT,
3178#endif
3179};
3180
3181#endif // cl_ext_image_requirements_info
3182
3183
3193 : public detail::Wrapper<cl_context>
3194{
3195private:
3196 static std::once_flag default_initialized_;
3197 static Context default_;
3198 static cl_int default_error_;
3199
3205 static void makeDefault() {
3206 /* Throwing an exception from a call_once invocation does not do
3207 * what we wish, so we catch it and save the error.
3208 */
3209#if defined(CL_HPP_ENABLE_EXCEPTIONS)
3210 try
3211#endif
3212 {
3213#if !defined(__APPLE__) && !defined(__MACOS)
3214 const Platform &p = Platform::getDefault();
3215 cl_platform_id defaultPlatform = p();
3216 cl_context_properties properties[3] = {
3217 CL_CONTEXT_PLATFORM, (cl_context_properties)defaultPlatform, 0
3218 };
3219#else // #if !defined(__APPLE__) && !defined(__MACOS)
3220 cl_context_properties *properties = nullptr;
3221#endif // #if !defined(__APPLE__) && !defined(__MACOS)
3222
3223 default_ = Context(
3224 CL_DEVICE_TYPE_DEFAULT,
3225 properties,
3226 nullptr,
3227 nullptr,
3228 &default_error_);
3229 }
3230#if defined(CL_HPP_ENABLE_EXCEPTIONS)
3231 catch (cl::Error &e) {
3232 default_error_ = e.err();
3233 }
3234#endif
3235 }
3236
3237
3243 static void makeDefaultProvided(const Context &c) {
3244 default_ = c;
3245 }
3246
3247#if defined(cl_ext_image_requirements_info)
3248 struct ImageRequirementsInfo {
3249
3250 ImageRequirementsInfo(cl_mem_flags f, const cl_mem_properties* mem_properties, const ImageFormat* format, const cl_image_desc* desc)
3251 {
3252 flags = f;
3253 properties = mem_properties;
3254 image_format = format;
3255 image_desc = desc;
3256 }
3257
3258 cl_mem_flags flags = 0;
3259 const cl_mem_properties* properties;
3260 const ImageFormat* image_format;
3261 const cl_image_desc* image_desc;
3262 };
3263
3264 static cl_int getImageRequirementsInfoExtHelper(const Context &context,
3265 const ImageRequirementsInfo &info,
3266 cl_image_requirements_info_ext param_name,
3267 size_type param_value_size,
3268 void* param_value,
3269 size_type* param_value_size_ret)
3270 {
3271
3272#if CL_HPP_TARGET_OPENCL_VERSION >= 120
3273 Device device = context.getInfo<CL_CONTEXT_DEVICES>().at(0);
3274 cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
3275 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetImageRequirementsInfoEXT);
3276#else
3277 CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetImageRequirementsInfoEXT);
3278#endif
3279
3280 if (pfn_clGetImageRequirementsInfoEXT == nullptr) {
3281 return detail::errHandler(CL_INVALID_OPERATION, __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR);
3282 }
3283
3284 return detail::errHandler(
3285 pfn_clGetImageRequirementsInfoEXT(context(), info.properties,
3286 info.flags, info.image_format, info.image_desc, param_name,
3287 param_value_size, param_value, param_value_size_ret),
3288 __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR);
3289 }
3290#endif // cl_ext_image_requirements_info
3291
3292public:
3293#ifdef CL_HPP_UNIT_TEST_ENABLE
3300 static void unitTestClearDefault() {
3301 default_ = Context();
3302 }
3303#endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
3304
3310 const vector<Device>& devices,
3311 const cl_context_properties* properties = nullptr,
3312 void (CL_CALLBACK * notifyFptr)(
3313 const char *,
3314 const void *,
3315 size_type,
3316 void *) = nullptr,
3317 void* data = nullptr,
3318 cl_int* err = nullptr)
3319 {
3320 cl_int error;
3321
3322 size_type numDevices = devices.size();
3323 vector<cl_device_id> deviceIDs(numDevices);
3324
3325 for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
3326 deviceIDs[deviceIndex] = (devices[deviceIndex])();
3327 }
3328
3329 object_ = ::clCreateContext(
3330 properties, (cl_uint) numDevices,
3331 deviceIDs.data(),
3332 notifyFptr, data, &error);
3333
3334 detail::errHandler(error, __CREATE_CONTEXT_ERR);
3335 if (err != nullptr) {
3336 *err = error;
3337 }
3338 }
3339
3345 const Device& device,
3346 const cl_context_properties* properties = nullptr,
3347 void (CL_CALLBACK * notifyFptr)(
3348 const char *,
3349 const void *,
3350 size_type,
3351 void *) = nullptr,
3352 void* data = nullptr,
3353 cl_int* err = nullptr)
3354 {
3355 cl_int error;
3356
3357 cl_device_id deviceID = device();
3358
3359 object_ = ::clCreateContext(
3360 properties, 1,
3361 &deviceID,
3362 notifyFptr, data, &error);
3363
3364 detail::errHandler(error, __CREATE_CONTEXT_ERR);
3365 if (err != nullptr) {
3366 *err = error;
3367 }
3368 }
3369
3375 cl_device_type type,
3376 const cl_context_properties* properties = nullptr,
3377 void (CL_CALLBACK * notifyFptr)(
3378 const char *,
3379 const void *,
3380 size_type,
3381 void *) = nullptr,
3382 void* data = nullptr,
3383 cl_int* err = nullptr)
3384 {
3385 cl_int error;
3386
3387#if !defined(__APPLE__) && !defined(__MACOS)
3388 cl_context_properties prop[4] = {CL_CONTEXT_PLATFORM, 0, 0, 0 };
3389
3390 if (properties == nullptr) {
3391 // Get a valid platform ID as we cannot send in a blank one
3392 vector<Platform> platforms;
3393 error = Platform::get(&platforms);
3394 if (error != CL_SUCCESS) {
3395 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
3396 if (err != nullptr) {
3397 *err = error;
3398 }
3399 return;
3400 }
3401
3402 // Check the platforms we found for a device of our specified type
3403 cl_context_properties platform_id = 0;
3404 for (unsigned int i = 0; i < platforms.size(); i++) {
3405
3406 vector<Device> devices;
3407
3408#if defined(CL_HPP_ENABLE_EXCEPTIONS)
3409 try {
3410#endif
3411
3412 error = platforms[i].getDevices(type, &devices);
3413
3414#if defined(CL_HPP_ENABLE_EXCEPTIONS)
3415 } catch (cl::Error& e) {
3416 error = e.err();
3417 }
3418 // Catch if exceptions are enabled as we don't want to exit if first platform has no devices of type
3419 // We do error checking next anyway, and can throw there if needed
3420#endif
3421
3422 // Only squash CL_SUCCESS and CL_DEVICE_NOT_FOUND
3423 if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND) {
3424 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
3425 if (err != nullptr) {
3426 *err = error;
3427 }
3428 }
3429
3430 if (devices.size() > 0) {
3431 platform_id = (cl_context_properties)platforms[i]();
3432 break;
3433 }
3434 }
3435
3436 if (platform_id == 0) {
3437 detail::errHandler(CL_DEVICE_NOT_FOUND, __CREATE_CONTEXT_FROM_TYPE_ERR);
3438 if (err != nullptr) {
3439 *err = CL_DEVICE_NOT_FOUND;
3440 }
3441 return;
3442 }
3443
3444 prop[1] = platform_id;
3445 properties = &prop[0];
3446 }
3447#endif
3448 object_ = ::clCreateContextFromType(
3449 properties, type, notifyFptr, data, &error);
3450
3451 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
3452 if (err != nullptr) {
3453 *err = error;
3454 }
3455 }
3456
3457
3462 static Context getDefault(cl_int * err = nullptr)
3463 {
3464 std::call_once(default_initialized_, makeDefault);
3465 detail::errHandler(default_error_);
3466 if (err != nullptr) {
3467 *err = default_error_;
3468 }
3469 return default_;
3470 }
3471
3479 static Context setDefault(const Context &default_context)
3480 {
3481 std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_context));
3482 detail::errHandler(default_error_);
3483 return default_;
3484 }
3485
3487 Context() : detail::Wrapper<cl_type>() { }
3488
3494 explicit Context(const cl_context& context, bool retainObject = false) :
3495 detail::Wrapper<cl_type>(context, retainObject) { }
3496
3502 Context& operator = (const cl_context& rhs)
3503 {
3505 return *this;
3506 }
3507
3509 template <typename T>
3510 cl_int getInfo(cl_context_info name, T* param) const
3511 {
3512 return detail::errHandler(
3513 detail::getInfo(&::clGetContextInfo, object_, name, param),
3514 __GET_CONTEXT_INFO_ERR);
3515 }
3516
3518 template <cl_context_info name> typename
3520 getInfo(cl_int* err = nullptr) const
3521 {
3522 typename detail::param_traits<
3523 detail::cl_context_info, name>::param_type param;
3524 cl_int result = getInfo(name, &param);
3525 if (err != nullptr) {
3526 *err = result;
3527 }
3528 return param;
3529 }
3530
3536 cl_mem_flags flags,
3537 cl_mem_object_type type,
3538 vector<ImageFormat>* formats) const
3539 {
3540 cl_uint numEntries;
3541
3542 if (!formats) {
3543 return CL_SUCCESS;
3544 }
3545
3546 cl_int err = ::clGetSupportedImageFormats(
3547 object_,
3548 flags,
3549 type,
3550 0,
3551 nullptr,
3552 &numEntries);
3553 if (err != CL_SUCCESS) {
3554 return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
3555 }
3556
3557 if (numEntries > 0) {
3558 vector<ImageFormat> value(numEntries);
3559 err = ::clGetSupportedImageFormats(
3560 object_,
3561 flags,
3562 type,
3563 numEntries,
3564 (cl_image_format*)value.data(),
3565 nullptr);
3566 if (err != CL_SUCCESS) {
3567 return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
3568 }
3569
3570 formats->assign(value.begin(), value.end());
3571 }
3572 else {
3573 // If no values are being returned, ensure an empty vector comes back
3574 formats->clear();
3575 }
3576
3577 return CL_SUCCESS;
3578 }
3579
3580#if defined(cl_ext_image_requirements_info)
3581 template <typename T>
3582 cl_int getImageRequirementsInfoExt(cl_image_requirements_info_ext name,
3583 T* param,
3584 cl_mem_flags flags = 0,
3585 const cl_mem_properties* properties = nullptr,
3586 const ImageFormat* image_format = nullptr,
3587 const cl_image_desc* image_desc = nullptr) const
3588 {
3589 ImageRequirementsInfo imageInfo = {flags, properties, image_format, image_desc};
3590
3591 return detail::errHandler(
3592 detail::getInfo(
3593 Context::getImageRequirementsInfoExtHelper, *this, imageInfo, name, param),
3594 __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR);
3595 }
3596
3597 template <cl_image_requirements_info_ext type> typename
3598 detail::param_traits<detail::cl_image_requirements_info_ext, type>::param_type
3599 getImageRequirementsInfoExt(cl_mem_flags flags = 0,
3600 const cl_mem_properties* properties = nullptr,
3601 const ImageFormat* image_format = nullptr,
3602 const cl_image_desc* image_desc = nullptr,
3603 cl_int* err = nullptr) const
3604 {
3605 typename detail::param_traits<
3606 detail::cl_image_requirements_info_ext, type>::param_type param;
3607 cl_int result = getImageRequirementsInfoExt(type, &param, flags, properties, image_format, image_desc);
3608 if (err != nullptr) {
3609 *err = result;
3610 }
3611 return param;
3612 }
3613#endif // cl_ext_image_requirements_info
3614
3615#if CL_HPP_TARGET_OPENCL_VERSION >= 300
3627 void (CL_CALLBACK * pfn_notify)(cl_context, void *),
3628 void * user_data = nullptr)
3629 {
3630 return detail::errHandler(
3631 ::clSetContextDestructorCallback(
3632 object_,
3633 pfn_notify,
3634 user_data),
3635 __SET_CONTEXT_DESCTRUCTOR_CALLBACK_ERR);
3636 }
3637#endif // CL_HPP_TARGET_OPENCL_VERSION >= 300
3638};
3639
3640inline void Device::makeDefault()
3641{
3642 /* Throwing an exception from a call_once invocation does not do
3643 * what we wish, so we catch it and save the error.
3644 */
3645#if defined(CL_HPP_ENABLE_EXCEPTIONS)
3646 try
3647#endif
3648 {
3649 cl_int error = 0;
3650
3651 Context context = Context::getDefault(&error);
3652 detail::errHandler(error, __CREATE_CONTEXT_ERR);
3653
3654 if (error != CL_SUCCESS) {
3655 default_error_ = error;
3656 }
3657 else {
3658 default_ = context.getInfo<CL_CONTEXT_DEVICES>()[0];
3659 default_error_ = CL_SUCCESS;
3660 }
3661 }
3662#if defined(CL_HPP_ENABLE_EXCEPTIONS)
3663 catch (cl::Error &e) {
3664 default_error_ = e.err();
3665 }
3666#endif
3667}
3668
3669CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Context::default_initialized_;
3670CL_HPP_DEFINE_STATIC_MEMBER_ Context Context::default_;
3671CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Context::default_error_ = CL_SUCCESS;
3672
3681class Event : public detail::Wrapper<cl_event>
3682{
3683public:
3685 Event() : detail::Wrapper<cl_type>() { }
3686
3695 explicit Event(const cl_event& event, bool retainObject = false) :
3696 detail::Wrapper<cl_type>(event, retainObject) { }
3697
3703 Event& operator = (const cl_event& rhs)
3704 {
3706 return *this;
3707 }
3708
3710 template <typename T>
3711 cl_int getInfo(cl_event_info name, T* param) const
3712 {
3713 return detail::errHandler(
3714 detail::getInfo(&::clGetEventInfo, object_, name, param),
3715 __GET_EVENT_INFO_ERR);
3716 }
3717
3719 template <cl_event_info name> typename
3721 getInfo(cl_int* err = nullptr) const
3722 {
3723 typename detail::param_traits<
3724 detail::cl_event_info, name>::param_type param;
3725 cl_int result = getInfo(name, &param);
3726 if (err != nullptr) {
3727 *err = result;
3728 }
3729 return param;
3730 }
3731
3733 template <typename T>
3734 cl_int getProfilingInfo(cl_profiling_info name, T* param) const
3735 {
3736 return detail::errHandler(detail::getInfo(
3737 &::clGetEventProfilingInfo, object_, name, param),
3738 __GET_EVENT_PROFILE_INFO_ERR);
3739 }
3740
3742 template <cl_profiling_info name> typename
3744 getProfilingInfo(cl_int* err = nullptr) const
3745 {
3746 typename detail::param_traits<
3747 detail::cl_profiling_info, name>::param_type param;
3748 cl_int result = getProfilingInfo(name, &param);
3749 if (err != nullptr) {
3750 *err = result;
3751 }
3752 return param;
3753 }
3754
3759 cl_int wait() const
3760 {
3761 return detail::errHandler(
3762 ::clWaitForEvents(1, &object_),
3763 __WAIT_FOR_EVENTS_ERR);
3764 }
3765
3766#if CL_HPP_TARGET_OPENCL_VERSION >= 110
3772 cl_int type,
3773 void (CL_CALLBACK * pfn_notify)(cl_event, cl_int, void *),
3774 void * user_data = nullptr)
3775 {
3776 return detail::errHandler(
3777 ::clSetEventCallback(
3778 object_,
3779 type,
3780 pfn_notify,
3781 user_data),
3782 __SET_EVENT_CALLBACK_ERR);
3783 }
3784#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3785
3790 static cl_int
3791 waitForEvents(const vector<Event>& events)
3792 {
3793 static_assert(sizeof(cl::Event) == sizeof(cl_event),
3794 "Size of cl::Event must be equal to size of cl_event");
3795
3796 return detail::errHandler(
3797 ::clWaitForEvents(
3798 (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : nullptr),
3799 __WAIT_FOR_EVENTS_ERR);
3800 }
3801};
3802
3803#if CL_HPP_TARGET_OPENCL_VERSION >= 110
3808class UserEvent : public Event
3809{
3810public:
3816 const Context& context,
3817 cl_int * err = nullptr)
3818 {
3819 cl_int error;
3820 object_ = ::clCreateUserEvent(
3821 context(),
3822 &error);
3823
3824 detail::errHandler(error, __CREATE_USER_EVENT_ERR);
3825 if (err != nullptr) {
3826 *err = error;
3827 }
3828 }
3829
3832
3837 cl_int setStatus(cl_int status)
3838 {
3839 return detail::errHandler(
3840 ::clSetUserEventStatus(object_,status),
3841 __SET_USER_EVENT_STATUS_ERR);
3842 }
3843};
3844#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3845
3850inline static cl_int
3851WaitForEvents(const vector<Event>& events)
3852{
3853 return detail::errHandler(
3854 ::clWaitForEvents(
3855 (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : nullptr),
3856 __WAIT_FOR_EVENTS_ERR);
3857}
3858
3867class Memory : public detail::Wrapper<cl_mem>
3868{
3869public:
3871 Memory() : detail::Wrapper<cl_type>() { }
3872
3884 explicit Memory(const cl_mem& memory, bool retainObject) :
3885 detail::Wrapper<cl_type>(memory, retainObject) { }
3886
3892 Memory& operator = (const cl_mem& rhs)
3893 {
3895 return *this;
3896 }
3897
3899 template <typename T>
3900 cl_int getInfo(cl_mem_info name, T* param) const
3901 {
3902 return detail::errHandler(
3903 detail::getInfo(&::clGetMemObjectInfo, object_, name, param),
3904 __GET_MEM_OBJECT_INFO_ERR);
3905 }
3906
3908 template <cl_mem_info name> typename
3910 getInfo(cl_int* err = nullptr) const
3911 {
3912 typename detail::param_traits<
3913 detail::cl_mem_info, name>::param_type param;
3914 cl_int result = getInfo(name, &param);
3915 if (err != nullptr) {
3916 *err = result;
3917 }
3918 return param;
3919 }
3920
3921#if CL_HPP_TARGET_OPENCL_VERSION >= 110
3936 void (CL_CALLBACK * pfn_notify)(cl_mem, void *),
3937 void * user_data = nullptr)
3938 {
3939 return detail::errHandler(
3940 ::clSetMemObjectDestructorCallback(
3941 object_,
3942 pfn_notify,
3943 user_data),
3944 __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR);
3945 }
3946#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3947
3948};
3949
3950// Pre-declare copy functions
3951class Buffer;
3952template< typename IteratorType >
3953cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
3954template< typename IteratorType >
3955cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator );
3956template< typename IteratorType >
3957cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
3958template< typename IteratorType >
3959cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator );
3960
3961
3962#if CL_HPP_TARGET_OPENCL_VERSION >= 200
3963namespace detail
3964{
3966 {
3967 public:
3968 static cl_svm_mem_flags getSVMMemFlags()
3969 {
3970 return 0;
3971 }
3972 };
3973} // namespace detail
3974
3975template<class Trait = detail::SVMTraitNull>
3977{
3978public:
3979 static cl_svm_mem_flags getSVMMemFlags()
3980 {
3981 return CL_MEM_READ_WRITE |
3982 Trait::getSVMMemFlags();
3983 }
3984};
3985
3986template<class Trait = detail::SVMTraitNull>
3988{
3989public:
3990 static cl_svm_mem_flags getSVMMemFlags()
3991 {
3992 return CL_MEM_READ_ONLY |
3993 Trait::getSVMMemFlags();
3994 }
3995};
3996
3997template<class Trait = detail::SVMTraitNull>
3999{
4000public:
4001 static cl_svm_mem_flags getSVMMemFlags()
4002 {
4003 return CL_MEM_WRITE_ONLY |
4004 Trait::getSVMMemFlags();
4005 }
4006};
4007
4008template<class Trait = SVMTraitReadWrite<>>
4010{
4011public:
4012 static cl_svm_mem_flags getSVMMemFlags()
4013 {
4014 return Trait::getSVMMemFlags();
4015 }
4016};
4017
4018template<class Trait = SVMTraitReadWrite<>>
4020{
4021public:
4022 static cl_svm_mem_flags getSVMMemFlags()
4023 {
4024 return CL_MEM_SVM_FINE_GRAIN_BUFFER |
4025 Trait::getSVMMemFlags();
4026 }
4027};
4028
4029template<class Trait = SVMTraitReadWrite<>>
4031{
4032public:
4033 static cl_svm_mem_flags getSVMMemFlags()
4034 {
4035 return
4036 CL_MEM_SVM_FINE_GRAIN_BUFFER |
4037 CL_MEM_SVM_ATOMICS |
4038 Trait::getSVMMemFlags();
4039 }
4040};
4041
4042// Pre-declare SVM map function
4043template<typename T>
4044inline cl_int enqueueMapSVM(
4045 T* ptr,
4046 cl_bool blocking,
4047 cl_map_flags flags,
4048 size_type size,
4049 const vector<Event>* events = nullptr,
4050 Event* event = nullptr);
4051
4063template<typename T, class SVMTrait>
4065private:
4066 Context context_;
4067
4068public:
4069 typedef T value_type;
4070 typedef value_type* pointer;
4071 typedef const value_type* const_pointer;
4072 typedef value_type& reference;
4073 typedef const value_type& const_reference;
4074 typedef std::size_t size_type;
4075 typedef std::ptrdiff_t difference_type;
4076
4077 template<typename U>
4078 struct rebind
4079 {
4080 typedef SVMAllocator<U, SVMTrait> other;
4081 };
4082
4083 template<typename U, typename V>
4084 friend class SVMAllocator;
4085
4086 SVMAllocator() :
4087 context_(Context::getDefault())
4088 {
4089 }
4090
4091 explicit SVMAllocator(cl::Context context) :
4092 context_(context)
4093 {
4094 }
4095
4096
4097 SVMAllocator(const SVMAllocator &other) :
4098 context_(other.context_)
4099 {
4100 }
4101
4102 template<typename U>
4103 SVMAllocator(const SVMAllocator<U, SVMTrait> &other) :
4104 context_(other.context_)
4105 {
4106 }
4107
4108 ~SVMAllocator()
4109 {
4110 }
4111
4112 pointer address(reference r) noexcept
4113 {
4114 return std::addressof(r);
4115 }
4116
4117 const_pointer address(const_reference r) noexcept
4118 {
4119 return std::addressof(r);
4120 }
4121
4128 pointer allocate(
4129 size_type size,
4130 typename cl::SVMAllocator<void, SVMTrait>::const_pointer = 0,
4131 bool map = true)
4132 {
4133 // Allocate memory with default alignment matching the size of the type
4134 void* voidPointer =
4135 clSVMAlloc(
4136 context_(),
4137 SVMTrait::getSVMMemFlags(),
4138 size*sizeof(T),
4139 0);
4140 pointer retValue = reinterpret_cast<pointer>(
4141 voidPointer);
4142#if defined(CL_HPP_ENABLE_EXCEPTIONS)
4143 if (!retValue) {
4144 std::bad_alloc excep;
4145 throw excep;
4146 }
4147#endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
4148
4149 // If allocation was coarse-grained then map it
4150 if (map && !(SVMTrait::getSVMMemFlags() & CL_MEM_SVM_FINE_GRAIN_BUFFER)) {
4151 cl_int err = enqueueMapSVM(retValue, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, size*sizeof(T));
4152 if (err != CL_SUCCESS) {
4153 clSVMFree(context_(), retValue);
4154 retValue = nullptr;
4155#if defined(CL_HPP_ENABLE_EXCEPTIONS)
4156 std::bad_alloc excep;
4157 throw excep;
4158#endif
4159 }
4160 }
4161
4162 // If exceptions disabled, return null pointer from allocator
4163 return retValue;
4164 }
4165
4166 void deallocate(pointer p, size_type)
4167 {
4168 clSVMFree(context_(), p);
4169 }
4170
4175 size_type max_size() const noexcept
4176 {
4177 size_type maxSize = std::numeric_limits<size_type>::max() / sizeof(T);
4178
4179 for (const Device &d : context_.getInfo<CL_CONTEXT_DEVICES>()) {
4180 maxSize = std::min(
4181 maxSize,
4182 static_cast<size_type>(d.getInfo<CL_DEVICE_MAX_MEM_ALLOC_SIZE>()));
4183 }
4184
4185 return maxSize;
4186 }
4187
4188 template< class U, class... Args >
4189 void construct(U* p, Args&&... args)
4190 {
4191 new(p)T(args...);
4192 }
4193
4194 template< class U >
4195 void destroy(U* p)
4196 {
4197 p->~U();
4198 }
4199
4203 inline bool operator==(SVMAllocator const& rhs)
4204 {
4205 return (context_==rhs.context_);
4206 }
4207
4208 inline bool operator!=(SVMAllocator const& a)
4209 {
4210 return !operator==(a);
4211 }
4212}; // class SVMAllocator return cl::pointer<T>(tmp, detail::Deleter<T, Alloc>{alloc, copies});
4213
4214
4215template<class SVMTrait>
4216class SVMAllocator<void, SVMTrait> {
4217public:
4218 typedef void value_type;
4219 typedef value_type* pointer;
4220 typedef const value_type* const_pointer;
4221
4222 template<typename U>
4223 struct rebind
4224 {
4225 typedef SVMAllocator<U, SVMTrait> other;
4226 };
4227
4228 template<typename U, typename V>
4229 friend class SVMAllocator;
4230};
4231
4232#if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
4233namespace detail
4234{
4235 template<class Alloc>
4236 class Deleter {
4237 private:
4238 Alloc alloc_;
4239 size_type copies_;
4240
4241 public:
4242 typedef typename std::allocator_traits<Alloc>::pointer pointer;
4243
4244 Deleter(const Alloc &alloc, size_type copies) : alloc_{ alloc }, copies_{ copies }
4245 {
4246 }
4247
4248 void operator()(pointer ptr) const {
4249 Alloc tmpAlloc{ alloc_ };
4250 std::allocator_traits<Alloc>::destroy(tmpAlloc, std::addressof(*ptr));
4251 std::allocator_traits<Alloc>::deallocate(tmpAlloc, ptr, copies_);
4252 }
4253 };
4254} // namespace detail
4255
4262template <class T, class Alloc, class... Args>
4263cl::pointer<T, detail::Deleter<Alloc>> allocate_pointer(const Alloc &alloc_, Args&&... args)
4264{
4265 Alloc alloc(alloc_);
4266 static const size_type copies = 1;
4267
4268 // Ensure that creation of the management block and the
4269 // object are dealt with separately such that we only provide a deleter
4270
4271 T* tmp = std::allocator_traits<Alloc>::allocate(alloc, copies);
4272 if (!tmp) {
4273#if defined(CL_HPP_ENABLE_EXCEPTIONS)
4274 std::bad_alloc excep;
4275 throw excep;
4276#else
4277 return nullptr;
4278#endif
4279 }
4280
4281#if defined(CL_HPP_ENABLE_EXCEPTIONS)
4282 try
4283#endif
4284 {
4285 std::allocator_traits<Alloc>::construct(
4286 alloc,
4287 std::addressof(*tmp),
4288 std::forward<Args>(args)...);
4289
4290 return cl::pointer<T, detail::Deleter<Alloc>>(tmp, detail::Deleter<Alloc>{alloc, copies});
4291 }
4292#if defined(CL_HPP_ENABLE_EXCEPTIONS)
4293 catch (std::bad_alloc&)
4294 {
4295 std::allocator_traits<Alloc>::deallocate(alloc, tmp, copies);
4296 throw;
4297 }
4298#endif
4299}
4300
4301template< class T, class SVMTrait, class... Args >
4302cl::pointer<T, detail::Deleter<SVMAllocator<T, SVMTrait>>> allocate_svm(Args... args)
4303{
4304 SVMAllocator<T, SVMTrait> alloc;
4305 return cl::allocate_pointer<T>(alloc, args...);
4306}
4307
4308template< class T, class SVMTrait, class... Args >
4309cl::pointer<T, detail::Deleter<SVMAllocator<T, SVMTrait>>> allocate_svm(const cl::Context &c, Args... args)
4310{
4311 SVMAllocator<T, SVMTrait> alloc(c);
4312 return cl::allocate_pointer<T>(alloc, args...);
4313}
4314#endif // #if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
4315
4319template < class T >
4320using coarse_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitCoarse<>>>;
4321
4325template < class T >
4326using fine_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitFine<>>>;
4327
4331template < class T >
4332using atomic_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitAtomic<>>>;
4333
4334#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
4335
4336
4343class Buffer : public Memory
4344{
4345public:
4346
4355 const Context& context,
4356 cl_mem_flags flags,
4357 size_type size,
4358 void* host_ptr = nullptr,
4359 cl_int* err = nullptr)
4360 {
4361 cl_int error;
4362 object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error);
4363
4364 detail::errHandler(error, __CREATE_BUFFER_ERR);
4365 if (err != nullptr) {
4366 *err = error;
4367 }
4368 }
4369
4370#if CL_HPP_TARGET_OPENCL_VERSION >= 300
4382 const Context& context,
4383 const vector<cl_mem_properties>& properties,
4384 cl_mem_flags flags,
4385 size_type size,
4386 void* host_ptr = nullptr,
4387 cl_int* err = nullptr)
4388 {
4389 cl_int error;
4390
4391 if (properties.empty()) {
4392 object_ = ::clCreateBufferWithProperties(context(), nullptr, flags,
4393 size, host_ptr, &error);
4394 }
4395 else {
4396 object_ = ::clCreateBufferWithProperties(
4397 context(), properties.data(), flags, size, host_ptr, &error);
4398 }
4399
4400 detail::errHandler(error, __CREATE_BUFFER_ERR);
4401 if (err != nullptr) {
4402 *err = error;
4403 }
4404 }
4405#endif
4406
4417 cl_mem_flags flags,
4418 size_type size,
4419 void* host_ptr = nullptr,
4420 cl_int* err = nullptr) : Buffer(Context::getDefault(err), flags, size, host_ptr, err) { }
4421
4422#if CL_HPP_TARGET_OPENCL_VERSION >= 300
4436 const vector<cl_mem_properties>& properties,
4437 cl_mem_flags flags,
4438 size_type size,
4439 void* host_ptr = nullptr,
4440 cl_int* err = nullptr) : Buffer(Context::getDefault(err), properties, flags, size, host_ptr, err) { }
4441#endif
4442
4448 template< typename IteratorType >
4450 IteratorType startIterator,
4451 IteratorType endIterator,
4452 bool readOnly,
4453 bool useHostPtr = false,
4454 cl_int* err = nullptr)
4455 {
4456 typedef typename std::iterator_traits<IteratorType>::value_type DataType;
4457 cl_int error;
4458
4459 cl_mem_flags flags = 0;
4460 if( readOnly ) {
4461 flags |= CL_MEM_READ_ONLY;
4462 }
4463 else {
4464 flags |= CL_MEM_READ_WRITE;
4465 }
4466 if( useHostPtr ) {
4467 flags |= CL_MEM_USE_HOST_PTR;
4468 }
4469
4470 size_type size = sizeof(DataType)*(endIterator - startIterator);
4471
4472 Context context = Context::getDefault(err);
4473
4474 if( useHostPtr ) {
4475 object_ = ::clCreateBuffer(context(), flags, size, const_cast<DataType*>(&*startIterator), &error);
4476 } else {
4477 object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
4478 }
4479
4480 detail::errHandler(error, __CREATE_BUFFER_ERR);
4481 if (err != nullptr) {
4482 *err = error;
4483 }
4484
4485 if( !useHostPtr ) {
4486 error = cl::copy(startIterator, endIterator, *this);
4487 detail::errHandler(error, __CREATE_BUFFER_ERR);
4488 if (err != nullptr) {
4489 *err = error;
4490 }
4491 }
4492 }
4493
4499 template< typename IteratorType >
4500 Buffer(const Context &context, IteratorType startIterator, IteratorType endIterator,
4501 bool readOnly, bool useHostPtr = false, cl_int* err = nullptr);
4502
4507 template< typename IteratorType >
4508 Buffer(const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator,
4509 bool readOnly, bool useHostPtr = false, cl_int* err = nullptr);
4510
4512 Buffer() : Memory() { }
4513
4521 explicit Buffer(const cl_mem& buffer, bool retainObject = false) :
4522 Memory(buffer, retainObject) { }
4523
4528 Buffer& operator = (const cl_mem& rhs)
4529 {
4530 Memory::operator=(rhs);
4531 return *this;
4532 }
4533
4534
4535#if CL_HPP_TARGET_OPENCL_VERSION >= 110
4541 cl_mem_flags flags,
4542 cl_buffer_create_type buffer_create_type,
4543 const void * buffer_create_info,
4544 cl_int * err = nullptr)
4545 {
4546 Buffer result;
4547 cl_int error;
4548 result.object_ = ::clCreateSubBuffer(
4549 object_,
4550 flags,
4551 buffer_create_type,
4552 buffer_create_info,
4553 &error);
4554
4555 detail::errHandler(error, __CREATE_SUBBUFFER_ERR);
4556 if (err != nullptr) {
4557 *err = error;
4558 }
4559
4560 return result;
4561 }
4562#endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
4563};
4564
4565#if defined (CL_HPP_USE_DX_INTEROP)
4574class BufferD3D10 : public Buffer
4575{
4576public:
4577
4578
4584 BufferD3D10(
4585 const Context& context,
4586 cl_mem_flags flags,
4587 ID3D10Buffer* bufobj,
4588 cl_int * err = nullptr) : pfn_clCreateFromD3D10BufferKHR(nullptr)
4589 {
4590 typedef CL_API_ENTRY cl_mem (CL_API_CALL *PFN_clCreateFromD3D10BufferKHR)(
4591 cl_context context, cl_mem_flags flags, ID3D10Buffer* buffer,
4592 cl_int* errcode_ret);
4593 PFN_clCreateFromD3D10BufferKHR pfn_clCreateFromD3D10BufferKHR;
4594#if CL_HPP_TARGET_OPENCL_VERSION >= 120
4595 vector<cl_context_properties> props = context.getInfo<CL_CONTEXT_PROPERTIES>();
4596 cl_platform platform = nullptr;
4597 for( int i = 0; i < props.size(); ++i ) {
4598 if( props[i] == CL_CONTEXT_PLATFORM ) {
4599 platform = props[i+1];
4600 }
4601 }
4602 CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateFromD3D10BufferKHR);
4603#endif
4604#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
4605 CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateFromD3D10BufferKHR);
4606#endif
4607
4608 cl_int error;
4609 object_ = pfn_clCreateFromD3D10BufferKHR(
4610 context(),
4611 flags,
4612 bufobj,
4613 &error);
4614
4615 // TODO: This should really have a D3D10 rerror code!
4616 detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
4617 if (err != nullptr) {
4618 *err = error;
4619 }
4620 }
4621
4623 BufferD3D10() : Buffer() { }
4624
4632 explicit BufferD3D10(const cl_mem& buffer, bool retainObject = false) :
4633 Buffer(buffer, retainObject) { }
4634
4639 BufferD3D10& operator = (const cl_mem& rhs)
4640 {
4641 Buffer::operator=(rhs);
4642 return *this;
4643 }
4644};
4645#endif
4646
4655class BufferGL : public Buffer
4656{
4657public:
4664 const Context& context,
4665 cl_mem_flags flags,
4666 cl_GLuint bufobj,
4667 cl_int * err = nullptr)
4668 {
4669 cl_int error;
4670 object_ = ::clCreateFromGLBuffer(
4671 context(),
4672 flags,
4673 bufobj,
4674 &error);
4675
4676 detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
4677 if (err != nullptr) {
4678 *err = error;
4679 }
4680 }
4681
4684
4692 explicit BufferGL(const cl_mem& buffer, bool retainObject = false) :
4693 Buffer(buffer, retainObject) { }
4694
4699 BufferGL& operator = (const cl_mem& rhs)
4700 {
4701 Buffer::operator=(rhs);
4702 return *this;
4703 }
4704
4705
4708 cl_gl_object_type *type,
4709 cl_GLuint * gl_object_name)
4710 {
4711 return detail::errHandler(
4712 ::clGetGLObjectInfo(object_,type,gl_object_name),
4713 __GET_GL_OBJECT_INFO_ERR);
4714 }
4715};
4716
4726{
4727public:
4734 const Context& context,
4735 cl_mem_flags flags,
4736 cl_GLuint bufobj,
4737 cl_int * err = nullptr)
4738 {
4739 cl_int error;
4740 object_ = ::clCreateFromGLRenderbuffer(
4741 context(),
4742 flags,
4743 bufobj,
4744 &error);
4745
4746 detail::errHandler(error, __CREATE_GL_RENDER_BUFFER_ERR);
4747 if (err != nullptr) {
4748 *err = error;
4749 }
4750 }
4751
4754
4762 explicit BufferRenderGL(const cl_mem& buffer, bool retainObject = false) :
4763 Buffer(buffer, retainObject) { }
4764
4769 BufferRenderGL& operator = (const cl_mem& rhs)
4770 {
4771 Buffer::operator=(rhs);
4772 return *this;
4773 }
4774
4775
4778 cl_gl_object_type *type,
4779 cl_GLuint * gl_object_name)
4780 {
4781 return detail::errHandler(
4782 ::clGetGLObjectInfo(object_,type,gl_object_name),
4783 __GET_GL_OBJECT_INFO_ERR);
4784 }
4785};
4786
4793class Image : public Memory
4794{
4795protected:
4797 Image() : Memory() { }
4798
4806 explicit Image(const cl_mem& image, bool retainObject = false) :
4807 Memory(image, retainObject) { }
4808
4813 Image& operator = (const cl_mem& rhs)
4814 {
4815 Memory::operator=(rhs);
4816 return *this;
4817 }
4818
4819
4820public:
4822 template <typename T>
4823 cl_int getImageInfo(cl_image_info name, T* param) const
4824 {
4825 return detail::errHandler(
4826 detail::getInfo(&::clGetImageInfo, object_, name, param),
4827 __GET_IMAGE_INFO_ERR);
4828 }
4829
4831 template <cl_image_info name> typename
4833 getImageInfo(cl_int* err = nullptr) const
4834 {
4835 typename detail::param_traits<
4836 detail::cl_image_info, name>::param_type param;
4837 cl_int result = getImageInfo(name, &param);
4838 if (err != nullptr) {
4839 *err = result;
4840 }
4841 return param;
4842 }
4843};
4844
4845#if CL_HPP_TARGET_OPENCL_VERSION >= 120
4852class Image1D : public Image
4853{
4854public:
4860 const Context& context,
4861 cl_mem_flags flags,
4862 ImageFormat format,
4863 size_type width,
4864 void* host_ptr = nullptr,
4865 cl_int* err = nullptr)
4866 {
4867 cl_int error;
4868
4869 cl_image_desc desc = {};
4870 desc.image_type = CL_MEM_OBJECT_IMAGE1D;
4871 desc.image_width = width;
4872
4873 object_ = ::clCreateImage(
4874 context(),
4875 flags,
4876 &format,
4877 &desc,
4878 host_ptr,
4879 &error);
4880
4881 detail::errHandler(error, __CREATE_IMAGE_ERR);
4882 if (err != nullptr) {
4883 *err = error;
4884 }
4885 }
4886
4889
4890#if CL_HPP_TARGET_OPENCL_VERSION >= 300
4901 Image1D(const Context &context, const vector<cl_mem_properties> &properties,
4902 cl_mem_flags flags, ImageFormat format, size_type width,
4903 void *host_ptr = nullptr, cl_int *err = nullptr) {
4904 cl_int error;
4905
4906 cl_image_desc desc = {};
4907 desc.image_type = CL_MEM_OBJECT_IMAGE1D;
4908 desc.image_width = width;
4909
4910 if (properties.empty()) {
4911 object_ = ::clCreateImageWithProperties(
4912 context(), nullptr, flags, &format, &desc, host_ptr, &error);
4913 } else {
4914 object_ =
4915 ::clCreateImageWithProperties(context(), properties.data(), flags,
4916 &format, &desc, host_ptr, &error);
4917 }
4918
4919 detail::errHandler(error, __CREATE_IMAGE_ERR);
4920 if (err != nullptr) {
4921 *err = error;
4922 }
4923 }
4924#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 300
4925
4933 explicit Image1D(const cl_mem& image1D, bool retainObject = false) :
4934 Image(image1D, retainObject) { }
4935
4940 Image1D& operator = (const cl_mem& rhs)
4941 {
4942 Image::operator=(rhs);
4943 return *this;
4944 }
4945
4946
4947};
4948
4952class Image1DBuffer : public Image
4953{
4954public:
4956 const Context& context,
4957 cl_mem_flags flags,
4958 ImageFormat format,
4959 size_type width,
4960 const Buffer &buffer,
4961 cl_int* err = nullptr)
4962 {
4963 cl_int error;
4964
4965 cl_image_desc desc = {};
4966 desc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
4967 desc.image_width = width;
4968 desc.buffer = buffer();
4969
4970 object_ = ::clCreateImage(
4971 context(),
4972 flags,
4973 &format,
4974 &desc,
4975 nullptr,
4976 &error);
4977
4978 detail::errHandler(error, __CREATE_IMAGE_ERR);
4979 if (err != nullptr) {
4980 *err = error;
4981 }
4982 }
4983
4984 Image1DBuffer() { }
4985
4986#if CL_HPP_TARGET_OPENCL_VERSION >= 300
4996 Image1DBuffer(const Context &context,
4997 const vector<cl_mem_properties> &properties,
4998 cl_mem_flags flags, ImageFormat format, size_type width,
4999 const Buffer &buffer, cl_int *err = nullptr) {
5000 cl_int error;
5001
5002 cl_image_desc desc = {};
5003 desc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
5004 desc.image_width = width;
5005 desc.buffer = buffer();
5006
5007 if (properties.empty()) {
5008 object_ = ::clCreateImageWithProperties(
5009 context(), nullptr, flags, &format, &desc, nullptr, &error);
5010 } else {
5011 object_ =
5012 ::clCreateImageWithProperties(context(), properties.data(), flags,
5013 &format, &desc, nullptr, &error);
5014 }
5015
5016 detail::errHandler(error, __CREATE_IMAGE_ERR);
5017 if (err != nullptr) {
5018 *err = error;
5019 }
5020 }
5021#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 300
5022
5030 explicit Image1DBuffer(const cl_mem& image1D, bool retainObject = false) :
5031 Image(image1D, retainObject) { }
5032
5033 Image1DBuffer& operator = (const cl_mem& rhs)
5034 {
5035 Image::operator=(rhs);
5036 return *this;
5037 }
5038};
5039
5043class Image1DArray : public Image
5044{
5045public:
5047 const Context& context,
5048 cl_mem_flags flags,
5049 ImageFormat format,
5050 size_type arraySize,
5051 size_type width,
5052 size_type rowPitch,
5053 void* host_ptr = nullptr,
5054 cl_int* err = nullptr)
5055 {
5056 cl_int error;
5057
5058 cl_image_desc desc = {};
5059 desc.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
5060 desc.image_width = width;
5061 desc.image_array_size = arraySize;
5062 desc.image_row_pitch = rowPitch;
5063
5064 object_ = ::clCreateImage(
5065 context(),
5066 flags,
5067 &format,
5068 &desc,
5069 host_ptr,
5070 &error);
5071
5072 detail::errHandler(error, __CREATE_IMAGE_ERR);
5073 if (err != nullptr) {
5074 *err = error;
5075 }
5076 }
5077
5078 Image1DArray() { }
5079
5080#if CL_HPP_TARGET_OPENCL_VERSION >= 300
5091 Image1DArray(const Context &context,
5092 const vector<cl_mem_properties> &properties,
5093 cl_mem_flags flags, ImageFormat format, size_type arraySize,
5094 size_type width, size_type rowPitch = 0,
5095 void *host_ptr = nullptr, cl_int *err = nullptr) {
5096 cl_int error;
5097
5098 cl_image_desc desc = {};
5099 desc.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
5100 desc.image_width = width;
5101 desc.image_array_size = arraySize;
5102 desc.image_row_pitch = rowPitch;
5103
5104 if (properties.empty()) {
5105 object_ = ::clCreateImageWithProperties(
5106 context(), nullptr, flags, &format, &desc, host_ptr, &error);
5107 } else {
5108 object_ =
5109 ::clCreateImageWithProperties(context(), properties.data(), flags,
5110 &format, &desc, host_ptr, &error);
5111 }
5112
5113 detail::errHandler(error, __CREATE_IMAGE_ERR);
5114 if (err != nullptr) {
5115 *err = error;
5116 }
5117 }
5118#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 300
5119
5127 explicit Image1DArray(const cl_mem& imageArray, bool retainObject = false) :
5128 Image(imageArray, retainObject) { }
5129
5130
5131 Image1DArray& operator = (const cl_mem& rhs)
5132 {
5133 Image::operator=(rhs);
5134 return *this;
5135 }
5136
5137
5138};
5139#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5140
5141
5148class Image2D : public Image
5149{
5150public:
5156 const Context& context,
5157 cl_mem_flags flags,
5158 ImageFormat format,
5159 size_type width,
5160 size_type height,
5161 size_type row_pitch = 0,
5162 void* host_ptr = nullptr,
5163 cl_int* err = nullptr)
5164 {
5165 cl_int error;
5166 bool useCreateImage;
5167
5168#if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
5169 // Run-time decision based on the actual platform
5170 {
5171 cl_uint version = detail::getContextPlatformVersion(context());
5172 useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above
5173 }
5174#elif CL_HPP_TARGET_OPENCL_VERSION >= 120
5175 useCreateImage = true;
5176#else
5177 useCreateImage = false;
5178#endif
5179
5180#if CL_HPP_TARGET_OPENCL_VERSION >= 120
5181 if (useCreateImage)
5182 {
5183 cl_image_desc desc = {};
5184 desc.image_type = CL_MEM_OBJECT_IMAGE2D;
5185 desc.image_width = width;
5186 desc.image_height = height;
5187 desc.image_row_pitch = row_pitch;
5188
5189 object_ = ::clCreateImage(
5190 context(),
5191 flags,
5192 &format,
5193 &desc,
5194 host_ptr,
5195 &error);
5196
5197 detail::errHandler(error, __CREATE_IMAGE_ERR);
5198 if (err != nullptr) {
5199 *err = error;
5200 }
5201 }
5202#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5203#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
5204 if (!useCreateImage)
5205 {
5206 object_ = ::clCreateImage2D(
5207 context(), flags,&format, width, height, row_pitch, host_ptr, &error);
5208
5209 detail::errHandler(error, __CREATE_IMAGE2D_ERR);
5210 if (err != nullptr) {
5211 *err = error;
5212 }
5213 }
5214#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
5215 }
5216
5217#if CL_HPP_TARGET_OPENCL_VERSION >= 120
5227 const Context& context,
5228 ImageFormat format,
5229 const Buffer &sourceBuffer,
5230 size_type width,
5231 size_type height,
5232 size_type row_pitch = 0,
5233 cl_int* err = nullptr)
5234 {
5235 cl_int error;
5236
5237 cl_image_desc desc = {};
5238 desc.image_type = CL_MEM_OBJECT_IMAGE2D;
5239 desc.image_width = width;
5240 desc.image_height = height;
5241 desc.image_row_pitch = row_pitch;
5242 desc.buffer = sourceBuffer();
5243
5244 object_ = ::clCreateImage(
5245 context(),
5246 0, // flags inherited from buffer
5247 &format,
5248 &desc,
5249 nullptr,
5250 &error);
5251
5252 detail::errHandler(error, __CREATE_IMAGE_ERR);
5253 if (err != nullptr) {
5254 *err = error;
5255 }
5256 }
5257#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5258
5259#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5273 const Context& context,
5274 cl_channel_order order,
5275 const Image &sourceImage,
5276 cl_int* err = nullptr)
5277 {
5278 cl_int error;
5279
5280 // Descriptor fields have to match source image
5281 size_type sourceWidth =
5282 sourceImage.getImageInfo<CL_IMAGE_WIDTH>();
5283 size_type sourceHeight =
5284 sourceImage.getImageInfo<CL_IMAGE_HEIGHT>();
5285 size_type sourceRowPitch =
5286 sourceImage.getImageInfo<CL_IMAGE_ROW_PITCH>();
5287 cl_uint sourceNumMIPLevels =
5288 sourceImage.getImageInfo<CL_IMAGE_NUM_MIP_LEVELS>();
5289 cl_uint sourceNumSamples =
5290 sourceImage.getImageInfo<CL_IMAGE_NUM_SAMPLES>();
5291 cl_image_format sourceFormat =
5292 sourceImage.getImageInfo<CL_IMAGE_FORMAT>();
5293
5294 // Update only the channel order.
5295 // Channel format inherited from source.
5296 sourceFormat.image_channel_order = order;
5297
5298 cl_image_desc desc = {};
5299 desc.image_type = CL_MEM_OBJECT_IMAGE2D;
5300 desc.image_width = sourceWidth;
5301 desc.image_height = sourceHeight;
5302 desc.image_row_pitch = sourceRowPitch;
5303 desc.num_mip_levels = sourceNumMIPLevels;
5304 desc.num_samples = sourceNumSamples;
5305 desc.buffer = sourceImage();
5306
5307 object_ = ::clCreateImage(
5308 context(),
5309 0, // flags should be inherited from mem_object
5310 &sourceFormat,
5311 &desc,
5312 nullptr,
5313 &error);
5314
5315 detail::errHandler(error, __CREATE_IMAGE_ERR);
5316 if (err != nullptr) {
5317 *err = error;
5318 }
5319 }
5320#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5321
5322#if CL_HPP_TARGET_OPENCL_VERSION >= 300
5333 Image2D(const Context &context, const vector<cl_mem_properties> &properties,
5334 cl_mem_flags flags, ImageFormat format, size_type width,
5335 size_type height, size_type row_pitch = 0, void *host_ptr = nullptr,
5336 cl_int *err = nullptr) {
5337 cl_int error;
5338
5339 cl_image_desc desc = {};
5340 desc.image_type = CL_MEM_OBJECT_IMAGE2D;
5341 desc.image_width = width;
5342 desc.image_height = height;
5343 desc.image_row_pitch = row_pitch;
5344
5345 if (properties.empty()) {
5346 object_ = ::clCreateImageWithProperties(
5347 context(), nullptr, flags, &format, &desc, host_ptr, &error);
5348 } else {
5349 object_ =
5350 ::clCreateImageWithProperties(context(), properties.data(), flags,
5351 &format, &desc, host_ptr, &error);
5352 }
5353
5354 detail::errHandler(error, __CREATE_IMAGE_ERR);
5355 if (err != nullptr) {
5356 *err = error;
5357 }
5358 }
5359
5369 Image2D(const Context &context, const vector<cl_mem_properties> &properties,
5370 cl_mem_flags flags, ImageFormat format, const Buffer &buffer,
5371 size_type width, size_type height, size_type row_pitch = 0,
5372 cl_int *err = nullptr) {
5373 cl_int error;
5374
5375 cl_image_desc desc = {};
5376 desc.image_type = CL_MEM_OBJECT_IMAGE2D;
5377 desc.image_width = width;
5378 desc.image_height = height;
5379 desc.image_row_pitch = row_pitch;
5380 desc.buffer = buffer();
5381
5382 if (properties.empty()) {
5383 object_ = ::clCreateImageWithProperties(
5384 context(), nullptr, flags, &format, &desc, nullptr, &error);
5385 } else {
5386 object_ =
5387 ::clCreateImageWithProperties(context(), properties.data(), flags,
5388 &format, &desc, nullptr, &error);
5389 }
5390
5391 detail::errHandler(error, __CREATE_IMAGE_ERR);
5392 if (err != nullptr) {
5393 *err = error;
5394 }
5395 }
5396
5397#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 300
5398
5401
5409 explicit Image2D(const cl_mem& image2D, bool retainObject = false) :
5410 Image(image2D, retainObject) { }
5411
5416 Image2D& operator = (const cl_mem& rhs)
5417 {
5418 Image::operator=(rhs);
5419 return *this;
5420 }
5421};
5422
5423
5424#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
5434class CL_API_PREFIX__VERSION_1_1_DEPRECATED Image2DGL : public Image2D
5435{
5436public:
5443 const Context& context,
5444 cl_mem_flags flags,
5445 cl_GLenum target,
5446 cl_GLint miplevel,
5447 cl_GLuint texobj,
5448 cl_int * err = nullptr)
5449 {
5450 cl_int error;
5451 object_ = ::clCreateFromGLTexture2D(
5452 context(),
5453 flags,
5454 target,
5455 miplevel,
5456 texobj,
5457 &error);
5458
5459 detail::errHandler(error, __CREATE_GL_TEXTURE_2D_ERR);
5460 if (err != nullptr) {
5461 *err = error;
5462 }
5463
5464 }
5465
5468
5476 explicit Image2DGL(const cl_mem& image, bool retainObject = false) :
5477 Image2D(image, retainObject) { }
5478
5483 Image2DGL& operator = (const cl_mem& rhs)
5484 {
5485 Image2D::operator=(rhs);
5486 return *this;
5487 }
5488
5489
5490
5491} CL_API_SUFFIX__VERSION_1_1_DEPRECATED;
5492#endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
5493
5494#if CL_HPP_TARGET_OPENCL_VERSION >= 120
5498class Image2DArray : public Image
5499{
5500public:
5502 const Context& context,
5503 cl_mem_flags flags,
5504 ImageFormat format,
5505 size_type arraySize,
5506 size_type width,
5507 size_type height,
5508 size_type rowPitch,
5509 size_type slicePitch,
5510 void* host_ptr = nullptr,
5511 cl_int* err = nullptr)
5512 {
5513 cl_int error;
5514
5515 cl_image_desc desc = {};
5516 desc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
5517 desc.image_width = width;
5518 desc.image_height = height;
5519 desc.image_array_size = arraySize;
5520 desc.image_row_pitch = rowPitch;
5521 desc.image_slice_pitch = slicePitch;
5522
5523 object_ = ::clCreateImage(
5524 context(),
5525 flags,
5526 &format,
5527 &desc,
5528 host_ptr,
5529 &error);
5530
5531 detail::errHandler(error, __CREATE_IMAGE_ERR);
5532 if (err != nullptr) {
5533 *err = error;
5534 }
5535 }
5536
5537#if CL_HPP_TARGET_OPENCL_VERSION >= 300
5548 Image2DArray(const Context &context,
5549 const vector<cl_mem_properties> &properties,
5550 cl_mem_flags flags, ImageFormat format, size_type arraySize,
5551 size_type width, size_type height, size_type rowPitch = 0,
5552 size_type slicePitch = 0, void *host_ptr = nullptr,
5553 cl_int *err = nullptr) {
5554 cl_int error;
5555
5556 cl_image_desc desc = {};
5557 desc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
5558 desc.image_width = width;
5559 desc.image_height = height;
5560 desc.image_array_size = arraySize;
5561 desc.image_row_pitch = rowPitch;
5562 desc.image_slice_pitch = slicePitch;
5563
5564 if (properties.empty()) {
5565 object_ = ::clCreateImageWithProperties(
5566 context(), nullptr, flags, &format, &desc, host_ptr, &error);
5567 } else {
5568 object_ =
5569 ::clCreateImageWithProperties(context(), properties.data(), flags,
5570 &format, &desc, host_ptr, &error);
5571 }
5572
5573 detail::errHandler(error, __CREATE_IMAGE_ERR);
5574 if (err != nullptr) {
5575 *err = error;
5576 }
5577 }
5578#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 300
5579
5580 Image2DArray() { }
5581
5589 explicit Image2DArray(const cl_mem& imageArray, bool retainObject = false) : Image(imageArray, retainObject) { }
5590
5591 Image2DArray& operator = (const cl_mem& rhs)
5592 {
5593 Image::operator=(rhs);
5594 return *this;
5595 }
5596
5597};
5598#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5599
5606class Image3D : public Image
5607{
5608public:
5614 const Context& context,
5615 cl_mem_flags flags,
5616 ImageFormat format,
5617 size_type width,
5618 size_type height,
5619 size_type depth,
5620 size_type row_pitch = 0,
5621 size_type slice_pitch = 0,
5622 void* host_ptr = nullptr,
5623 cl_int* err = nullptr)
5624 {
5625 cl_int error;
5626 bool useCreateImage;
5627
5628#if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
5629 // Run-time decision based on the actual platform
5630 {
5631 cl_uint version = detail::getContextPlatformVersion(context());
5632 useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above
5633 }
5634#elif CL_HPP_TARGET_OPENCL_VERSION >= 120
5635 useCreateImage = true;
5636#else
5637 useCreateImage = false;
5638#endif
5639
5640#if CL_HPP_TARGET_OPENCL_VERSION >= 120
5641 if (useCreateImage)
5642 {
5643 cl_image_desc desc = {};
5644 desc.image_type = CL_MEM_OBJECT_IMAGE3D;
5645 desc.image_width = width;
5646 desc.image_height = height;
5647 desc.image_depth = depth;
5648 desc.image_row_pitch = row_pitch;
5649 desc.image_slice_pitch = slice_pitch;
5650
5651 object_ = ::clCreateImage(
5652 context(),
5653 flags,
5654 &format,
5655 &desc,
5656 host_ptr,
5657 &error);
5658
5659 detail::errHandler(error, __CREATE_IMAGE_ERR);
5660 if (err != nullptr) {
5661 *err = error;
5662 }
5663 }
5664#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5665#if CL_HPP_MINIMUM_OPENCL_VERSION < 120
5666 if (!useCreateImage)
5667 {
5668 object_ = ::clCreateImage3D(
5669 context(), flags, &format, width, height, depth, row_pitch,
5670 slice_pitch, host_ptr, &error);
5671
5672 detail::errHandler(error, __CREATE_IMAGE3D_ERR);
5673 if (err != nullptr) {
5674 *err = error;
5675 }
5676 }
5677#endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
5678 }
5679
5680#if CL_HPP_TARGET_OPENCL_VERSION >= 300
5691 Image3D(const Context &context, const vector<cl_mem_properties> &properties,
5692 cl_mem_flags flags, ImageFormat format, size_type width,
5693 size_type height, size_type depth, size_type row_pitch = 0,
5694 size_type slice_pitch = 0, void *host_ptr = nullptr,
5695 cl_int *err = nullptr) {
5696 cl_int error;
5697
5698 cl_image_desc desc = {};
5699 desc.image_type = CL_MEM_OBJECT_IMAGE3D;
5700 desc.image_width = width;
5701 desc.image_height = height;
5702 desc.image_depth = depth;
5703 desc.image_row_pitch = row_pitch;
5704 desc.image_slice_pitch = slice_pitch;
5705
5706 if (properties.empty()) {
5707 object_ = ::clCreateImageWithProperties(
5708 context(), nullptr, flags, &format, &desc, host_ptr, &error);
5709 } else {
5710 object_ =
5711 ::clCreateImageWithProperties(context(), properties.data(), flags,
5712 &format, &desc, host_ptr, &error);
5713 }
5714
5715 detail::errHandler(error, __CREATE_IMAGE_ERR);
5716 if (err != nullptr) {
5717 *err = error;
5718 }
5719 }
5720#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 300
5721
5723 Image3D() : Image() { }
5724
5732 explicit Image3D(const cl_mem& image3D, bool retainObject = false) :
5733 Image(image3D, retainObject) { }
5734
5739 Image3D& operator = (const cl_mem& rhs)
5740 {
5741 Image::operator=(rhs);
5742 return *this;
5743 }
5744
5745};
5746
5747#if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
5756class Image3DGL : public Image3D
5757{
5758public:
5765 const Context& context,
5766 cl_mem_flags flags,
5767 cl_GLenum target,
5768 cl_GLint miplevel,
5769 cl_GLuint texobj,
5770 cl_int * err = nullptr)
5771 {
5772 cl_int error;
5773 object_ = ::clCreateFromGLTexture3D(
5774 context(),
5775 flags,
5776 target,
5777 miplevel,
5778 texobj,
5779 &error);
5780
5781 detail::errHandler(error, __CREATE_GL_TEXTURE_3D_ERR);
5782 if (err != nullptr) {
5783 *err = error;
5784 }
5785 }
5786
5789
5797 explicit Image3DGL(const cl_mem& image, bool retainObject = false) :
5798 Image3D(image, retainObject) { }
5799
5804 Image3DGL& operator = (const cl_mem& rhs)
5805 {
5806 Image3D::operator=(rhs);
5807 return *this;
5808 }
5809
5810};
5811#endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
5812
5813#if CL_HPP_TARGET_OPENCL_VERSION >= 120
5820class ImageGL : public Image
5821{
5822public:
5823 ImageGL(
5824 const Context& context,
5825 cl_mem_flags flags,
5826 cl_GLenum target,
5827 cl_GLint miplevel,
5828 cl_GLuint texobj,
5829 cl_int * err = nullptr)
5830 {
5831 cl_int error;
5832 object_ = ::clCreateFromGLTexture(
5833 context(),
5834 flags,
5835 target,
5836 miplevel,
5837 texobj,
5838 &error);
5839
5840 detail::errHandler(error, __CREATE_GL_TEXTURE_ERR);
5841 if (err != nullptr) {
5842 *err = error;
5843 }
5844 }
5845
5846 ImageGL() : Image() { }
5847
5855 explicit ImageGL(const cl_mem& image, bool retainObject = false) :
5856 Image(image, retainObject) { }
5857
5858 ImageGL& operator = (const cl_mem& rhs)
5859 {
5860 Image::operator=(rhs);
5861 return *this;
5862 }
5863
5864};
5865#endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5866
5867
5868
5869#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5876class Pipe : public Memory
5877{
5878public:
5879
5890 const Context& context,
5891 cl_uint packet_size,
5892 cl_uint max_packets,
5893 cl_int* err = nullptr)
5894 {
5895 cl_int error;
5896
5897 cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
5898 object_ = ::clCreatePipe(context(), flags, packet_size, max_packets, nullptr, &error);
5899
5900 detail::errHandler(error, __CREATE_PIPE_ERR);
5901 if (err != nullptr) {
5902 *err = error;
5903 }
5904 }
5905
5915 cl_uint packet_size,
5916 cl_uint max_packets,
5917 cl_int* err = nullptr)
5918 {
5919 cl_int error;
5920
5921 Context context = Context::getDefault(err);
5922
5923 cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
5924 object_ = ::clCreatePipe(context(), flags, packet_size, max_packets, nullptr, &error);
5925
5926 detail::errHandler(error, __CREATE_PIPE_ERR);
5927 if (err != nullptr) {
5928 *err = error;
5929 }
5930 }
5931
5933 Pipe() : Memory() { }
5934
5942 explicit Pipe(const cl_mem& pipe, bool retainObject = false) :
5943 Memory(pipe, retainObject) {