Last active
December 17, 2015 02:58
-
-
Save rjeschke/5539416 to your computer and use it in GitHub Desktop.
OpenCL bindings for Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.nio.FloatBuffer; | |
import com.github.rjeschke.neetutils.collections.Colls; | |
import com.github.rjeschke.njocl.Buffers; | |
import com.github.rjeschke.njocl.CL; | |
import com.github.rjeschke.njocl.CLException; | |
import com.github.rjeschke.njocl.CommandQueue; | |
import com.github.rjeschke.njocl.Context; | |
import com.github.rjeschke.njocl.Device; | |
import com.github.rjeschke.njocl.Kernel; | |
import com.github.rjeschke.njocl.MemObject; | |
import com.github.rjeschke.njocl.Platform; | |
import com.github.rjeschke.njocl.Program; | |
import com.github.rjeschke.njocl.SizeOf; | |
/** | |
* The OpenCL 'Hello world' using NJOCL. | |
* | |
* Ported from: http://www.jocl.org/samples/JOCLSample.java | |
* | |
* @author rjeschke | |
*/ | |
public class NJOCLSample | |
{ | |
private static String PROGRAM_SOURCE = | |
"__kernel void " + | |
"sampleKernel(__global const float *a," + | |
" __global const float *b," + | |
" __global float *c)" + "{" + | |
" int gid = get_global_id(0);" + | |
" c[gid] = a[gid] * b[gid];" + | |
"}"; | |
public static void main(final String[] args) throws CLException | |
{ | |
final int N = 16777216; | |
final FloatBuffer srcArrayA = Buffers.newFloats(N); | |
final FloatBuffer srcArrayB = Buffers.newFloats(N); | |
final FloatBuffer outArray = Buffers.newFloats(N); | |
// Fill input array (buffer) | |
for (int i = 0; i < N; i++) | |
{ | |
srcArrayA.put(i, i); | |
srcArrayB.put(i, i); | |
} | |
// Get a (the first) platform | |
final Platform platform = CL.getPlatform(); | |
// Get the first CPU device, create Context, CommandQueue and Program | |
try (final Device device = platform.getDevice(CL.DEVICE_TYPE_CPU); | |
final Context context = device.createContext(); | |
final CommandQueue cmdQueue = context.createCommandQueue(device, 0); | |
final Program program = context.createProgramWithSource(PROGRAM_SOURCE)) | |
{ | |
// build the program | |
program.buildProgram(null); | |
// Create the Kernel and allocate MemObjects | |
try (final Kernel kernel = program.createKernel("sampleKernel"); | |
final MemObject srcMemA = context.createBuffer(CL.MEM_READ_ONLY | CL.MEM_USE_HOST_PTR, srcArrayA); | |
final MemObject srcMemB = context.createBuffer(CL.MEM_READ_ONLY | CL.MEM_USE_HOST_PTR, srcArrayB); | |
final MemObject outMem = context.createBuffer(CL.MEM_WRITE_ONLY | CL.MEM_ALLOC_HOST_PTR, N * SizeOf.FLOAT)) | |
{ | |
// Set Kernel arguments | |
kernel.setArg(0, srcMemA); | |
kernel.setArg(1, srcMemB); | |
kernel.setArg(2, outMem); | |
// Enqueue the Kernel | |
cmdQueue.enqueueNDRangeKernel(kernel, 1, null, Colls.array((long)N), Colls.array(device.getMaxWorkGroupSize())); | |
// Read back the results (blocking) | |
cmdQueue.enqueueReadBuffer(outMem, outArray); | |
} | |
} | |
// Check if computation succeeded | |
boolean passed = true; | |
final float epsilon = 1e-7f; | |
for (int i = 0; i < N; i++) | |
{ | |
final float x = outArray.get(i); | |
final float y = srcArrayA.get(i) * srcArrayB.get(i); | |
final boolean epsilonEqual = Math.abs(x - y) <= epsilon * Math.abs(x); | |
if (!epsilonEqual) | |
{ | |
passed = false; | |
break; | |
} | |
} | |
System.out.println("Test " + (passed ? "PASSED" : "FAILED")); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment