@@ -784,20 +784,14 @@ object OpenCL {
784
784
extends AnyVal
785
785
with MonadicCloseable [UnitContinuation ] {
786
786
787
- private def numberOfKernels : Int = {
788
- val result = Array .ofDim[Int ](1 )
789
- checkErrorCode(clCreateKernelsInProgram(handle, null , result))
790
- result(0 )
791
- }
792
-
793
787
def deviceIds : Seq [DeviceId [Owner ]] = {
794
788
val stack = stackPush()
795
789
try {
796
790
val sizeBuffer = stack.mallocPointer(1 )
797
791
checkErrorCode(clGetProgramInfo(this .handle, CL_PROGRAM_DEVICES , null : PointerBuffer , sizeBuffer))
798
792
val numberOfDeviceIds = sizeBuffer.get(0 ).toInt / POINTER_SIZE
799
793
val programDevicesBuffer = stack.mallocPointer(numberOfDeviceIds)
800
- checkErrorCode(clGetProgramInfo(this .handle, CL_PROGRAM_DEVICES , programDevicesBuffer, sizeBuffer ))
794
+ checkErrorCode(clGetProgramInfo(this .handle, CL_PROGRAM_DEVICES , programDevicesBuffer, null : PointerBuffer ))
801
795
(0 until numberOfDeviceIds).map { i =>
802
796
DeviceId [Owner ](programDevicesBuffer.get(i))
803
797
}
@@ -806,27 +800,16 @@ object OpenCL {
806
800
}
807
801
}
808
802
809
- def createKernels (): Seq [Kernel [Owner ]] = {
810
- (0 until createKernelBuffer().capacity).map { i =>
811
- Kernel [Owner ](createKernelBuffer().get(i))
812
- }
813
- }
814
-
815
- private def createKernelBuffer (): PointerBuffer = {
816
- val kernelBuffer = BufferUtils .createPointerBuffer(numberOfKernels)
817
- checkErrorCode(clCreateKernelsInProgram(handle, kernelBuffer, null : IntBuffer ))
818
- kernelBuffer
803
+ def createKernels ()(implicit witness : Witness .Aux [Owner ]): Seq [Kernel [Owner ]] = {
804
+ witness.value.createKernels(this .asInstanceOf [witness.value.Program ]).asInstanceOf [Seq [Kernel [Owner ]]]
819
805
}
820
806
821
- def createFirstKernel (): Kernel [Owner ] = {
822
- val stack = stackPush()
823
- try {
824
- val kernelBuffer = stack.mallocPointer(1 )
825
- checkErrorCode(clCreateKernelsInProgram(handle, kernelBuffer, null : IntBuffer ))
826
- Kernel (kernelBuffer.get(0 ))
827
- } finally {
828
- stack.close()
829
- }
807
+ /** Creates single kernel from this [[Program ]].
808
+ *
809
+ * @throws InvalidValue if the this [[Program ]] has more than one kernel.
810
+ */
811
+ def createKernel ()(implicit witness : Witness .Aux [Owner ]): Kernel [Owner ] = {
812
+ witness.value.createKernel(this .asInstanceOf [witness.value.Program ]).asInstanceOf [Kernel [Owner ]]
830
813
}
831
814
832
815
private def buildLogs (deviceIds : Seq [DeviceId [Owner ]]): Map [DeviceId [Owner ], String ] = {
@@ -1044,11 +1027,58 @@ object OpenCL {
1044
1027
}
1045
1028
}
1046
1029
1030
+ /** Make the calls to [[createKernels ]] and [[createKernel ]] synchronized.
1031
+ *
1032
+ * @note If you are using Intel OpenCL SDK, you will need this plug-in as a workaround
1033
+ * @see [[https://software.intel.com/en-us/forums/opencl/topic/760981
1034
+ * Bug report: clCreateKernelsInProgram is not thread-safe]]
1035
+ */
1036
+ trait SynchronizedCreatingKernel extends OpenCL {
1037
+ override protected def createKernels (program : Program ): Seq [Kernel ] = synchronized {
1038
+ super .createKernels(program)
1039
+ }
1040
+
1041
+ override protected def createKernel (program : Program ): Kernel = synchronized {
1042
+ super .createKernel(program)
1043
+ }
1044
+ }
1045
+
1047
1046
}
1048
1047
1049
1048
trait OpenCL extends MonadicCloseable [UnitContinuation ] with ImplicitsSingleton with DefaultCloseable {
1050
1049
import OpenCL ._
1051
1050
1051
+ protected def createKernels (program : Program ): Seq [Kernel ] = {
1052
+ val stack = stackPush()
1053
+ try {
1054
+ val numberOfKernelsBuffer = stack.mallocInt(1 )
1055
+ checkErrorCode(clCreateKernelsInProgram(program.handle, null , numberOfKernelsBuffer))
1056
+ val numberOfKernels = numberOfKernelsBuffer.get(0 )
1057
+ val kernelBuffer = stack.mallocPointer(numberOfKernels)
1058
+ checkErrorCode(clCreateKernelsInProgram(program.handle, kernelBuffer, null : IntBuffer ))
1059
+ (0 until kernelBuffer.capacity).map { i =>
1060
+ new Kernel (kernelBuffer.get(i))
1061
+ }
1062
+ } finally {
1063
+ stack.close()
1064
+ }
1065
+ }
1066
+
1067
+ /** Creates single kernel from this [[Program ]].
1068
+ *
1069
+ * @throws InvalidValue if the this [[Program ]] has more than one kernel.
1070
+ */
1071
+ protected def createKernel (program : Program ): Kernel = {
1072
+ val stack = stackPush()
1073
+ try {
1074
+ val kernelBuffer = stack.mallocPointer(1 )
1075
+ checkErrorCode(clCreateKernelsInProgram(program.handle, kernelBuffer, null : IntBuffer ))
1076
+ new Kernel (kernelBuffer.get(0 ))
1077
+ } finally {
1078
+ stack.close()
1079
+ }
1080
+ }
1081
+
1052
1082
protected val logger : Logger
1053
1083
1054
1084
type Program = OpenCL .Program [this .type ]
0 commit comments