Embedded OpenCL inside Kotlin
GitHub: https://github.com/dickensas/kotlin-gradle-templates/tree/master/embed-opencl
OpenCL code which runs from kotlin
#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
__constant char hw[] = "Hello World";
__kernel void hello(__global char * A) {
size_t tid = get_global_id(0);
A[tid] = hw[tid];
}
Kotlin code which runs OpenCL
package plot
import kotlinx.cinterop.*
import opencl.*
import platform.posix.intptr_t
import platform.posix.size_tVar
var code =
"""
#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
__constant char hw[] = "Hello World";
__kernel void hello(__global char * A) {
size_t tid = get_global_id(0);
A[tid] = hw[tid];
}
"""
fun main() {
println ("code which will call opencl");
memScoped {
var platform = alloc<cl_platform_idVar>()
var device = alloc<cl_device_idVar>()
var props = allocArray<cl_context_propertiesVar>(3)
props[0] = CL_CONTEXT_PLATFORM.toLong()
props[1] = 0.toLong()
props[2] = 0.toLong()
clGetPlatformIDs( 1, platform.ptr, null )
var err = clGetDeviceIDs( platform.value, CL_DEVICE_TYPE_GPU, 1, device.ptr, null )
if (err != CL_SUCCESS) { throw Error("Unable to enumerate device IDs") }
props[1] = platform.value.toLong()
var errCtx = memScoped { alloc<cl_intVar>() }
var ctx = clCreateContext( props, 1, device.ptr, null, null, errCtx.ptr )
if (ctx == null || errCtx.value != 0) { throw Error("Unable to create context") }
var queue = clCreateCommandQueue( ctx, device.value, 0, errCtx.ptr )
if (queue == null || errCtx.value != 0) { throw Error("Unable to create queue") }
var program = clCreateProgramWithSource( ctx, 1, arrayOf(code).toCStringArray(memScope), null, errCtx.ptr)
if (program == null || errCtx.value != 0) { throw Error("Unable to create program") }
err = clBuildProgram( program, 0, null, null, null, null)
if (err != CL_SUCCESS) { throw Error("Unable to build program") }
var kernel = clCreateKernel( program, "hello", errCtx.ptr)
if (kernel == null || errCtx.value != 0) { throw Error("Unable to create kernel") }
var N = alloc<size_tVar>()
N.value = 12.toULong()
var B = allocArray<ByteVar>((N.value.toInt()+1 * sizeOf<ByteVar>()).toInt() )
var output = alloc<cl_memVar>()
output.value = clCreateBuffer( ctx, CL_MEM_WRITE_ONLY.toULong(), (N.value.toInt()+1 * sizeOf<ByteVar>()).toULong(), null, errCtx.ptr)
if (errCtx.value != 0) { throw Error("Unable to create buffer") }
err = clSetKernelArg(kernel, 0, (sizeOf<cl_memVar>()).toULong(), output.ptr)
if (err != CL_SUCCESS) { throw Error("Unable to set arguments") }
clEnqueueNDRangeKernel( queue, kernel, 1, null, N.ptr, N.ptr, 0, null, null)
clFinish(queue)
clEnqueueReadBuffer( queue, output.value, CL_TRUE, 0, (N.value.toInt()+1 * sizeOf<ByteVar>()).toULong(), B, 0, null, null );
clFinish(queue);
println(B.toKString())
clReleaseMemObject( output.value )
clReleaseCommandQueue ( queue )
clReleaseContext ( ctx )
}
}
You need to install MSYS2 and opencl using below command
pacman -S mingw-w64-x86_64-opencl-headers mingw-w64-x86_64-opencl-icd-git
If segment fault occurs or buffer allocation fails, try to execute few more times
For Python use is code embed python in kolin
For Ruby use this code embed ruby in kotlin
For Lua use this code embed lua in kotlin
For R use this code embed R in kotlin