JOCL v2.6.0-rc-20250722
JOCL, OpenCL® API Binding for Java™ (public API).
CLProgram.java
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.opencl;
30
31import com.jogamp.common.nio.AbstractBuffer;
32import com.jogamp.common.nio.CachedBufferFactory;
33import com.jogamp.opencl.util.CLProgramConfiguration;
34import com.jogamp.opencl.util.CLUtil;
35import com.jogamp.common.os.Platform;
36import com.jogamp.common.util.UnsafeUtil;
37import com.jogamp.common.nio.PointerBuffer;
38import com.jogamp.opencl.llb.CL;
39import com.jogamp.opencl.llb.impl.BuildProgramCallback;
40import com.jogamp.opencl.util.CLBuildListener;
41import java.nio.ByteBuffer;
42import java.nio.IntBuffer;
43import java.util.Collections;
44import java.util.HashMap;
45import java.util.HashSet;
46import java.util.LinkedHashMap;
47import java.util.Map.Entry;
48import java.util.Set;
49import java.util.Map;
50import java.util.concurrent.Semaphore;
51
52import static com.jogamp.opencl.CLException.*;
53import static com.jogamp.opencl.llb.CL.*;
54import static com.jogamp.common.nio.Buffers.*;
55
56/**
57 * Represents a OpenCL program executed on one or more {@link CLDevice}s.
58 * A CLProgram must be build using one of the build methods before creating {@link CLKernel}s.
59 * @see CLContext#createProgram(java.io.InputStream)
60 * @see CLContext#createProgram(java.lang.String)
61 * @see CLContext#createProgram(java.util.Map)
62 * @author Michael Bien, et al.
63 */
64public class CLProgram extends CLObjectResource {
65
66 // must use a semaphore instead of a reentrant lock because the CL implementation can call
67 // our notifier function from a different thread than the one that calls clBuildProgram
68 private final static Semaphore buildLock = new Semaphore(1, true);
69 private final CL binding;
70
71 private final Set<CLKernel> kernels;
72 private Map<CLDevice, Status> buildStatusMap;
73
74 private boolean executable;
75 private boolean released;
76 /** Set if program created from binary, or else getting source can crash the driver on Macs. */
77 private boolean noSource;
78
79 private CLProgram(final CLContext context, final long id) {
80 super(context, id);
81 this.kernels = new HashSet<CLKernel>();
82 this.binding = context.getPlatform().getCLBinding();
83 }
84
85 static CLProgram create(final CLContext context, final String src) {
86
87 final IntBuffer status = newDirectIntBuffer(1);
88
89 final PointerBuffer length = PointerBuffer.allocateDirect(1).put(0, src.length());
90 final String[] srcArray = new String[] {src};
91
92 // Create the program
93 final CL binding = context.getPlatform().getCLBinding();
94 final long id = binding.clCreateProgramWithSource(context.ID, 1, srcArray, length, status);
95
96 final int err = status.get();
97 if(err != CL_SUCCESS) {
98 throw newException(err, "can not create program with source on "+context);
99 }
100
101 return new CLProgram(context, id);
102 }
103
104 static CLProgram create(final CLContext context, final Map<CLDevice, byte[]> binaries) {
105
106 final Set<Entry<CLDevice, byte[]>> entries = binaries.entrySet();
107
108 // calculate buffer size
109 int binarySize = 0;
110 for (final Map.Entry<CLDevice, byte[]> entry : entries) {
111 binarySize += entry.getValue().length;
112 }
113
114 final int pbSize = AbstractBuffer.POINTER_SIZE;
115 final int deviceCount = binaries.size();
116
117 final CachedBufferFactory bf = CachedBufferFactory.create(binarySize + pbSize*deviceCount*3 + 4, true);
118 final PointerBuffer devices = PointerBuffer.wrap(bf.newDirectByteBuffer(deviceCount*pbSize));
119 final PointerBuffer codeBuffers = PointerBuffer.wrap(bf.newDirectByteBuffer(deviceCount*pbSize));
120 final PointerBuffer lengths = PointerBuffer.wrap(bf.newDirectByteBuffer(deviceCount*pbSize));
121
122 int i = 0;
123 for (final Map.Entry<CLDevice, byte[]> entry : entries) {
124
125 final byte[] bytes = entry.getValue();
126 final CLDevice device = entry.getKey();
127
128 devices.put(device.ID);
129 lengths.put(bytes.length);
130
131 codeBuffers.referenceBuffer(i, bf.newDirectByteBuffer(bytes));
132 i++;
133 }
134 devices.rewind();
135 lengths.rewind();
136
137 final IntBuffer errBuffer = bf.newDirectIntBuffer(1);
138// IntBuffer status = newDirectByteBuffer(binaries.size()*4).asIntBuffer();
139 final CL binding = context.getPlatform().getCLBinding();
140 final long id = binding.clCreateProgramWithBinary(context.ID, devices.capacity(), devices, lengths, codeBuffers, /*status*/null, errBuffer);
141
142// while(status.remaining() != 0) {
143// checkForError(status.get(), "unable to load binaries on all devices");
144// }
145
146 final int err = errBuffer.get();
147 if(err != CL_SUCCESS) {
148 throw newException(err, "can not create program on "+context +" with binaries "+binaries);
149 }
150
151 return new CLProgram(context, id);
152 }
153
154 private void initBuildStatus() {
155
156 if(buildStatusMap == null) {
157 final Map<CLDevice, Status> map = new HashMap<CLDevice, Status>();
158 final CLDevice[] devices = getCLDevices();
159 for (final CLDevice device : devices) {
160 final Status status = getBuildStatus(device);
161 if(status == Status.BUILD_SUCCESS) {
162 executable = true;
163 }
164 map.put(device, status);
165 }
166 this.buildStatusMap = Collections.unmodifiableMap(map);
167 }
168 }
169
170 private String getBuildInfoString(final CLDevice device, final int flag) {
171
172 if(released) {
173 return "";
174 }
175
176 final PointerBuffer size = PointerBuffer.allocateDirect(1);
177
178 int ret = binding.clGetProgramBuildInfo(ID, device.ID, flag, 0, null, size);
179 if(ret != CL_SUCCESS) {
180 throw newException(ret, "on clGetProgramBuildInfo with "+device);
181 }
182
183 final ByteBuffer buffer = newDirectByteBuffer((int)size.get(0));
184
185 ret = binding.clGetProgramBuildInfo(ID, device.ID, flag, buffer.capacity(), buffer, null);
186 if(ret != CL_SUCCESS) {
187 throw newException(ret, "on clGetProgramBuildInfo with "+device);
188 }
189
190 return CLUtil.clString2JavaString(buffer, (int)size.get(0));
191 }
192
193 private String getProgramInfoString(final int flag) {
194
195 if(released) {
196 return "";
197 }
198
199 final PointerBuffer size = PointerBuffer.allocateDirect(1);
200
201 int ret = binding.clGetProgramInfo(ID, flag, 0, null, size);
202 checkForError(ret, "on clGetProgramInfo");
203
204 final ByteBuffer buffer = newDirectByteBuffer((int)size.get(0));
205
206 ret = binding.clGetProgramInfo(ID, flag, buffer.capacity(), buffer, null);
207 checkForError(ret, "on clGetProgramInfo");
208
209 return CLUtil.clString2JavaString(buffer, (int)size.get(0));
210 }
211
212 private int getBuildInfoInt(final CLDevice device, final int flag) {
213
214 final ByteBuffer buffer = newDirectByteBuffer(4);
215
216 final int ret = binding.clGetProgramBuildInfo(ID, device.ID, flag, buffer.capacity(), buffer, null);
217 checkForError(ret, "error on clGetProgramBuildInfo");
218
219 return buffer.getInt();
220 }
221
222 /**
223 * Builds this program for all devices associated with the context.
224 * @return this
225 */
226 public CLProgram build() {
227 build(null, (String)null, (CLDevice[]) null);
228 return this;
229 }
230
231 /**
232 * Builds this program for all devices associated with the context.
233 * @see CLBuildListener
234 * @param listener A listener who is notified when the program was built.
235 * @return this
236 */
237 public CLProgram build(final CLBuildListener listener) {
238 build(listener, null, (CLDevice[])null);
239 return this;
240 }
241
242 /**
243 * Builds this program for the given devices.
244 * @param devices A list of devices this program should be build on or null for all devices of its context.
245 * @return this
246 */
247 public CLProgram build(final CLDevice... devices) {
248 build(null, (String) null, devices);
249 return this;
250 }
251
252 /**
253 * Builds this program for the given devices.
254 * @see CLBuildListener
255 * @param listener A listener who is notified when the program was built.
256 * @param devices A list of devices this program should be build on or null for all devices of its context.
257 * @return this
258 */
259 public CLProgram build(final CLBuildListener listener, final CLDevice... devices) {
260 build(listener,null, devices);
261 return this;
262 }
263
264 /**
265 * Builds this program for all devices associated with the context using the specified build options.
266 * @see CompilerOptions
267 * @return this
268 */
269 public CLProgram build(final String options) {
270 build(null, options, (CLDevice[])null);
271 return this;
272 }
273
274 /**
275 * Builds this program for all devices associated with the context using the specified build options.
276 * @see CompilerOptions
277 * @see CLBuildListener
278 * @param listener A listener who is notified when the program was built.
279 * @return this
280 */
281 public CLProgram build(final CLBuildListener listener, final String options) {
282 build(listener, options, (CLDevice[])null);
283 return this;
284 }
285
286 /**
287 * Builds this program for all devices associated with the context using the specified build options.
288 * @see CompilerOptions
289 */
290 public CLProgram build(final String... options) {
291 build(null, optionsOf(options), (CLDevice[])null);
292 return this;
293 }
294
295 /**
296 * Builds this program for all devices associated with the context using the specified build options.
297 * @see CompilerOptions
298 * @see CLBuildListener
299 * @param listener A listener who is notified when the program was built.
300 */
301 public CLProgram build(final CLBuildListener listener, final String... options) {
302 build(listener, optionsOf(options), (CLDevice[])null);
303 return this;
304 }
305
306 /**
307 * Builds this program for the given devices and with the specified build options. In case this program was
308 * already built and there are kernels associated with this program they will be released first before rebuild.
309 * @see CompilerOptions
310 * @param devices A list of devices this program should be build on or null for all devices of its context.
311 * @return this
312 */
313 public CLProgram build(final String options, final CLDevice... devices) {
314 build(null, options, devices);
315 return this;
316 }
317
318 /**
319 * Builds this program for the given devices and with the specified build options. In case this program was
320 * already built and there are kernels associated with this program they will be released first before rebuild.
321 * @see CompilerOptions
322 * @see CLBuildListener
323 * @return this
324 * @param devices A list of devices this program should be build on or null for all devices of its context.
325 * @param listener A listener who is notified when the program was built.
326 */
327 public CLProgram build(final CLBuildListener listener, String options, final CLDevice... devices) {
328
329 if(released) {
330 throw new CLException("can not build a released program");
331 }
332
333 if(!kernels.isEmpty()) {
334 //No changes to the program executable are allowed while there are
335 //kernel objects associated with a program object.
336 releaseKernels();
337 }
338
339 PointerBuffer deviceIDs = null;
340 int count = 0;
341 if(devices != null && devices.length != 0) {
342 deviceIDs = PointerBuffer.allocateDirect(devices.length);
343 for (int i = 0; i < devices.length; i++) {
344 deviceIDs.put(i, devices[i].ID);
345 }
346 deviceIDs.rewind();
347 count = devices.length;
348 }
349
350 // nvidia driver doesn't like empty strings
351 if(options != null && options.trim().isEmpty()) {
352 options = null;
353 }
354
355 // invalidate build status
356 buildStatusMap = null;
357 executable = false;
358
359 BuildProgramCallback callback = null;
360 if(listener != null) {
361 callback = new BuildProgramCallback() {
362 @Override
363 public void buildFinished(final long cl_program) {
364 buildLock.release();
365 listener.buildFinished(CLProgram.this);
366 }
367 };
368 }
369
370 // Build the program
371 int ret = 0;
372
373 // spec: building programs is not threadsafe, we are locking the API call to
374 // make sure only one thread calls it at a time until it completes (asynchronous or synchronously).
375 {
376 try {
377 buildLock.acquire();
378 } catch(final InterruptedException e) {
379 throw newException(ret, "\nInterrupted while waiting to get build lock");
380 }
381
382 boolean exception = true;
383 try{
384 ret = binding.clBuildProgram(ID, count, deviceIDs, options, callback);
385 exception = false;
386 }finally{
387 if(callback == null || exception) {
388 buildLock.release();
389 }
390 }
391 }
392
393 if(ret != CL_SUCCESS) {
394 throw newException(ret, "\n"+getBuildLog());
395 }
396
397 return this;
398 }
399
400 /**
401 * Prepares the build for this program by returning a new {@link CLProgramConfiguration}.
402 */
405 }
406
407 /**
408 * Creates a kernel with the specified kernel name.
409 */
410 public CLKernel createCLKernel(final String kernelName) {
411
412 if(released) {
413 return null;
414 }
415
416 final int[] err = new int[1];
417 final long id = binding.clCreateKernel(ID, kernelName, err, 0);
418 if(err[0] != CL_SUCCESS) {
419 throw newException(err[0], "unable to create Kernel with name: "+kernelName);
420 }
421
422 final CLKernel kernel = new CLKernel(this, kernelName, id);
423 kernels.add(kernel);
424 return kernel;
425 }
426
427 /**
428 * Creates all kernels of this program and stores them a Map with the kernel name as key.
429 */
431
432 if(released) {
433 return Collections.emptyMap();
434 }
435
436 final HashMap<String, CLKernel> newKernels = new HashMap<String, CLKernel>();
437
438 final IntBuffer numKernels = newDirectByteBuffer(4).asIntBuffer();
439 int ret = binding.clCreateKernelsInProgram(ID, 0, null, numKernels);
440 if(ret != CL_SUCCESS) {
441 throw newException(ret, "can not create kernels for "+this);
442 }
443
444 if(numKernels.get(0) > 0) {
445
446 final PointerBuffer kernelIDs = PointerBuffer.allocateDirect(numKernels.get(0));
447 ret = binding.clCreateKernelsInProgram(ID, kernelIDs.capacity(), kernelIDs, null);
448 if(ret != CL_SUCCESS) {
449 throw newException(ret, "can not create "+kernelIDs.capacity()+" kernels for "+this);
450 }
451
452 for (int i = 0; i < kernelIDs.capacity(); i++) {
453 final CLKernel kernel = new CLKernel(this, kernelIDs.get(i));
454 kernels.add(kernel);
455 newKernels.put(kernel.name, kernel);
456 }
457 }else{
458 initBuildStatus();
459 if(!isExecutable()) {
460 // It is illegal to create kernels from a not executable program.
461 // For consistency between AMD and NVIDIA drivers throw an exception at this point.
462 throw newException(CL_INVALID_PROGRAM_EXECUTABLE,
463 "can not initialize kernels, program is not executable. status: "+buildStatusMap);
464 }
465 }
466
467 return newKernels;
468 }
469
470 void onKernelReleased(final CLKernel kernel) {
471 this.kernels.remove(kernel);
472 }
473
474 /**
475 * Releases this program with its kernels.
476 */
477 @Override
478 public void release() {
479
480 super.release();
481 releaseKernels();
482
483 executable = false;
484 released = true;
485 buildStatusMap = null;
486
487 final int ret = binding.clReleaseProgram(ID);
488 context.onProgramReleased(this);
489 if(ret != CL_SUCCESS) {
490 throw newException(ret, "can not release "+this);
491 }
492 }
493
494 private void releaseKernels() {
495 if(!kernels.isEmpty()) {
496 // copy to array to prevent concurrent modification exception
497 final CLKernel[] array = kernels.toArray(new CLKernel[kernels.size()]);
498 for (final CLKernel kernel : array) {
499 kernel.release();
500 }
501 }
502 }
503
504 /**
505 * Returns all devices associated with this program.
506 */
508 if(released) {
509 return new CLDevice[0];
510 }
511
512 final PointerBuffer size = PointerBuffer.allocateDirect(1);
513 int ret = binding.clGetProgramInfo(ID, CL_PROGRAM_DEVICES, 0, null, size);
514 if(ret != CL_SUCCESS) {
515 throw newException(ret, "on clGetProgramInfo of "+this);
516 }
517
518 final ByteBuffer bb = newDirectByteBuffer((int) size.get(0));
519 ret = binding.clGetProgramInfo(ID, CL_PROGRAM_DEVICES, bb.capacity(), bb, null);
520 if(ret != CL_SUCCESS) {
521 throw newException(ret, "on clGetProgramInfo of "+this);
522 }
523
524 final int count = bb.capacity() / (Platform.is32Bit()?4:8);
525 final CLDevice[] devices = new CLDevice[count];
526 for (int i = 0; i < count; i++) {
527 devices[i] = context.getDevice(Platform.is32Bit()?bb.getInt():bb.getLong());
528 }
529
530 return devices;
531
532 }
533
534 /**
535 * Returns the build log of this program on all devices. The contents of the log are
536 * implementation dependent.
537 */
538 public String getBuildLog() {
539 if(released) {
540 return "";
541 }
542 final StringBuilder sb = new StringBuilder(200);
543 final CLDevice[] devices = getCLDevices();
544 for (int i = 0; i < devices.length; i++) {
545 final CLDevice device = devices[i];
546 sb.append(device).append(" build log:\n");
547 final String log = getBuildLog(device).trim();
548 sb.append(log.isEmpty()?" <empty>":log);
549 if(i != devices.length-1)
550 sb.append("\n");
551 }
552 return sb.toString();
553 }
554
555 /**
556 * Returns the build status enum of this program for each device as Map.
557 */
559 if(released) {
560 return Collections.emptyMap();
561 }
562 initBuildStatus();
563 return buildStatusMap;
564 }
565
566 /**
567 * Returns true if the build status 'BUILD_SUCCESS' for at least one device
568 * of this program exists.
569 */
570 public boolean isExecutable() {
571 if(released) {
572 return false;
573 }
574 initBuildStatus();
575 return executable;
576 }
577
578 /**
579 * Returns the build log for this program on the specified device. The contents
580 * of the log are implementation dependent log can be an empty String.
581 */
582 public String getBuildLog(final CLDevice device) {
583 return getBuildInfoString(device, CL_PROGRAM_BUILD_LOG);
584 }
585
586 /**
587 * Returns the build status enum for this program on the specified device.
588 */
589 public Status getBuildStatus(final CLDevice device) {
590 if(released) {
591 return Status.BUILD_NONE;
592 }
593 final int clStatus = getBuildInfoInt(device, CL_PROGRAM_BUILD_STATUS);
594 return Status.valueOf(clStatus);
595 }
596
597 /**
598 * Must set this if the program is created from binary so we know not to call getSource(),
599 * which can SIGSEGV on Macs if there is no source.
600 */
601 public void setNoSource() {
602 noSource = true;
603 }
604
605 /**
606 * Returns the source code of this program. Note: sources are not cached,
607 * each call of this method calls into Open
608 */
609 public String getSource() {
610 if(noSource)
611 return "";
612 // some drivers return IVE codes if the program haven't been built from source.
613 try{
614 return getProgramInfoString(CL_PROGRAM_SOURCE);
615 }catch(final CLException.CLInvalidValueException ingore) {
616 return "";
617 }
618 }
619
620 /**
621 * Returns the binaries for this program in an ordered Map containing the device as key
622 * and the program binaries as value.
623 */
625
626 if(!isExecutable()) {
627 return Collections.emptyMap();
628 }
629
630 final CLDevice[] devices = getCLDevices();
631
632 final PointerBuffer sizes = PointerBuffer.allocateDirect(devices.length);
633 int ret = binding.clGetProgramInfo(ID, CL_PROGRAM_BINARY_SIZES, sizes.capacity()*sizes.elementSize(), sizes.getBuffer(), null);
634 if(ret != CL_SUCCESS) {
635 throw newException(ret, "on clGetProgramInfo(CL_PROGRAM_BINARY_SIZES) of "+this);
636 }
637
638 int binariesSize = 0;
639 while(sizes.remaining() != 0) {
640 final int size = (int) sizes.get();
641 binariesSize += size;
642 }
643 final ByteBuffer binaries = newDirectByteBuffer(binariesSize);
644
645
646 long address = UnsafeUtil.getDirectBufferAddress(binaries);
647 final PointerBuffer addresses = PointerBuffer.allocateDirect(sizes.capacity());
648 sizes.rewind();
649 while(sizes.remaining() != 0) {
650 addresses.put(address);
651 address += sizes.get();
652 }
653 addresses.rewind();
654
655 ret = binding.clGetProgramInfo(ID, CL_PROGRAM_BINARIES, addresses.capacity()*addresses.elementSize(), addresses.getBuffer(), null);
656 if(ret != CL_SUCCESS) {
657 throw newException(ret, "on clGetProgramInfo(CL_PROGRAM_BINARIES) of "+this);
658 }
659
660 final Map<CLDevice, byte[]> map = new LinkedHashMap<CLDevice, byte[]>();
661 sizes.rewind();
662 for (int i = 0; i < devices.length; i++) {
663 final byte[] bytes = new byte[(int)sizes.get()];
664 binaries.get(bytes);
665 map.put(devices[i], bytes);
666 }
667
668 return map;
669 }
670
671 /**
672 * Utility method which builds a properly seperated option string.
673 */
674 public static String optionsOf(final String... options) {
675 final StringBuilder sb = new StringBuilder(options.length * 24);
676 for (int i = 0; i < options.length; i++) {
677 sb.append(options[i]);
678 if(i!= options.length-1)
679 sb.append(" ");
680 }
681 return sb.toString();
682 }
683
684 /**
685 * Utility method for defining macros as build options (Returns "-D name").
686 */
687 public static String define(final String name) {
688 return "-D "+name;
689 }
690
691 /**
692 * Utility method for defining macros as build options (Returns "-D name=value").
693 */
694 public static String define(final String name, final Object value) {
695 return "-D "+name+"="+value;
696 }
697
698 @Override
699 public String toString() {
700 return "CLProgram [id: " + ID
701 + " status: "+getBuildStatus()+"]";
702 }
703
704 @Override
705 public boolean equals(final Object obj) {
706 if (obj == null) {
707 return false;
708 }
709 if (getClass() != obj.getClass()) {
710 return false;
711 }
712 final CLProgram other = (CLProgram) obj;
713 if (this.ID != other.ID) {
714 return false;
715 }
716 if (!this.context.equals(other.context)) {
717 return false;
718 }
719 return true;
720 }
721
722 @Override
723 public int hashCode() {
724 int hash = 7;
725 hash = 37 * hash + (this.context != null ? this.context.hashCode() : 0);
726 hash = 37 * hash + (int) (this.ID ^ (this.ID >>> 32));
727 return hash;
728 }
729
730 public enum Status {
731
732 BUILD_SUCCESS(CL_BUILD_SUCCESS),
733 BUILD_NONE(CL_BUILD_NONE),
734 BUILD_IN_PROGRESS(CL_BUILD_IN_PROGRESS),
735 BUILD_ERROR(CL_BUILD_ERROR);
736
737 /**
738 * Value of wrapped OpenCL device type.
739 */
740 public final int STATUS;
741
742 private Status(final int status) {
743 this.STATUS = status;
744 }
745
746 public static Status valueOf(final int clBuildStatus) {
747 switch(clBuildStatus) {
748 case(CL_BUILD_SUCCESS):
749 return BUILD_SUCCESS;
750 case(CL_BUILD_NONE):
751 return BUILD_NONE;
752 case(CL_BUILD_IN_PROGRESS):
753 return BUILD_IN_PROGRESS;
754 case(CL_BUILD_ERROR):
755 return BUILD_ERROR;
756// is this a standard state?
757// case (CL_BUILD_PROGRAM_FAILURE):
758// return BUILD_PROGRAM_FAILURE;
759 }
760 return null;
761 }
762 }
763
764 /**
765 * Common compiler options for the OpenCL compiler.
766 */
767 public interface CompilerOptions {
768
769 /**
770 * Treat double precision floating-point constant as single precision constant.
771 */
772 public final static String SINGLE_PRECISION_CONSTANTS = "-cl-single-precision-constant";
773
774 /**
775 * This option controls how single precision and double precision denormalized numbers are handled.
776 * If specified as a build option, the single precision denormalized numbers may be flushed to zero
777 * and if the optional extension for double precision is supported, double precision denormalized numbers
778 * may also be flushed to zero. This is intended to be a performance hint and the OpenCL compiler can choose
779 * not to flush denorms to zero if the device supports single precision (or double precision) denormalized numbers.<br>
780 * This option is ignored for single precision numbers if the device does not support single precision denormalized
781 * numbers i.e. {@link CLDevice.FPConfig#DENORM} is not present in the set returned by {@link CLDevice#getSingleFPConfig()}<br>
782 * This option is ignored for double precision numbers if the device does not support double precision or if it does support
783 * double precision but {@link CLDevice.FPConfig#DENORM} is not present in the set returned by {@link CLDevice#getDoubleFPConfig()}.<br>
784 * This flag only applies for scalar and vector single precision floating-point variables and computations on
785 * these floating-point variables inside a program. It does not apply to reading from or writing to image objects.
786 */
787 public final static String DENORMS_ARE_ZERO = "-cl-denorms-are-zero";
788
789 /**
790 * This option disables all optimizations. The default is optimizations are enabled.
791 */
792 public final static String DISABLE_OPT = "-cl-opt-disable";
793
794 /**
795 * This option allows the compiler to assume the strictest aliasing rules.
796 */
797 public final static String STRICT_ALIASING = "-cl-strict-aliasing";
798
799 /**
800 * Allow a * b + c to be replaced by a mad. The mad computes a * b + c with reduced accuracy.
801 * For example, some OpenCL devices implement mad as truncate the result of a * b before adding it to c.
802 */
803 public final static String ENABLE_MAD = "-cl-mad-enable";
804
805 /**
806 * Allow optimizations for floating-point arithmetic that ignore the signedness of zero.
807 * IEEE 754 arithmetic specifies the behavior of distinct +0.0 and -0.0 values, which then prohibits
808 * simplification of expressions such as x+0.0 or 0.0*x (even with -cl-finite-math-only ({@link #FINITE_MATH_ONLY})).
809 * This option implies that the sign of a zero result isn't significant.
810 */
811 public final static String NO_SIGNED_ZEROS = "-cl-no-signed-zeros";
812
813 /**
814 * Allow optimizations for floating-point arithmetic that<br>
815 * (a) assume that arguments and results are valid,<br>
816 * (b) may violate IEEE 754 standard and<br>
817 * (c) may violate the OpenCL numerical compliance requirements as defined in section
818 * 7.4 for single-precision floating-point, section 9.3.9 for double-precision floating-point,
819 * and edge case behavior in section 7.5.
820 * This option includes the -cl-no-signed-zeros ({@link #NO_SIGNED_ZEROS})
821 * and -cl-mad-enable ({@link #ENABLE_MAD}) options.
822 */
823 public final static String UNSAFE_MATH = "-cl-unsafe-math-optimizations";
824
825 /**
826 * Allow optimizations for floating-point arithmetic that assume that arguments and results are not NaNs or plus/minus infinity.
827 * This option may violate the OpenCL numerical compliance requirements defined in in section 7.4 for
828 * single-precision floating-point, section 9.3.9 for double-precision floating-point, and edge case behavior in section 7.5.
829 */
830 public final static String FINITE_MATH_ONLY = "-cl-finite-math-only";
831
832 /**
833 * Sets the optimization options -cl-finite-math-only ({@link #FINITE_MATH_ONLY}) and -cl-unsafe-math-optimizations ({@link #UNSAFE_MATH}).
834 * This allows optimizations for floating-point arithmetic that may violate the IEEE 754
835 * standard and the OpenCL numerical compliance requirements defined in the specification
836 * in section 7.4 for single-precision floating-point, section 9.3.9 for double-precision
837 * floating-point, and edge case behavior in section 7.5. This option causes the preprocessor
838 * macro __FAST_RELAXED_MATH__ to be defined in the OpenCL program.
839 */
840 public final static String FAST_RELAXED_MATH = "-cl-fast-relaxed-math";
841
842 /**
843 * Inhibit all warning messages.
844 */
845 public final static String DISABLE_WARNINGS = "-w";
846
847 /**
848 * Make all warnings into errors.
849 */
850 public final static String WARNINGS_ARE_ERRORS = "-Werror";
851
852 }
853
854}
CLContext is responsible for managing objects such as command-queues, memory, program and kernel obje...
Definition: CLContext.java:79
boolean equals(final Object obj)
Definition: CLContext.java:683
CLPlatform getPlatform()
Returns the CLPlatform this context is running on.
Definition: CLContext.java:569
This object represents an OpenCL device.
Definition: CLDevice.java:53
CLException thrown on CL.CL_INVALID_VALUE errors.
Main Exception type for runtime OpenCL errors and failed function calls (e.g.
High level abstraction for an OpenCL Kernel.
Definition: CLKernel.java:53
void release()
Releases all resources of this kernel from its context.
Definition: CLKernel.java:386
final long ID
The OpenCL object handle.
Definition: CLObject.java:41
CLProgramBuilder is a helper for building programs with more complex configurations or building multi...
static CLBuildConfiguration createConfiguration()
Creates a new CLBuildConfiguration.
Represents a OpenCL program executed on one or more CLDevices.
Definition: CLProgram.java:64
String getBuildLog()
Returns the build log of this program on all devices.
Definition: CLProgram.java:538
CLProgram build(final String options)
Builds this program for all devices associated with the context using the specified build options.
Definition: CLProgram.java:269
static String define(final String name)
Utility method for defining macros as build options (Returns "-D name").
Definition: CLProgram.java:687
boolean isExecutable()
Returns true if the build status 'BUILD_SUCCESS' for at least one device of this program exists.
Definition: CLProgram.java:570
CLProgram build(final String... options)
Builds this program for all devices associated with the context using the specified build options.
Definition: CLProgram.java:290
CLProgramConfiguration prepare()
Prepares the build for this program by returning a new CLProgramConfiguration.
Definition: CLProgram.java:403
Map< CLDevice, byte[]> getBinaries()
Returns the binaries for this program in an ordered Map containing the device as key and the program ...
Definition: CLProgram.java:624
String getBuildLog(final CLDevice device)
Returns the build log for this program on the specified device.
Definition: CLProgram.java:582
boolean equals(final Object obj)
Definition: CLProgram.java:705
CLProgram build(final CLBuildListener listener, final String options)
Builds this program for all devices associated with the context using the specified build options.
Definition: CLProgram.java:281
String getSource()
Returns the source code of this program.
Definition: CLProgram.java:609
CLProgram build()
Builds this program for all devices associated with the context.
Definition: CLProgram.java:226
CLProgram build(final CLDevice... devices)
Builds this program for the given devices.
Definition: CLProgram.java:247
CLDevice[] getCLDevices()
Returns all devices associated with this program.
Definition: CLProgram.java:507
CLProgram build(final CLBuildListener listener)
Builds this program for all devices associated with the context.
Definition: CLProgram.java:237
CLProgram build(final CLBuildListener listener, final String... options)
Builds this program for all devices associated with the context using the specified build options.
Definition: CLProgram.java:301
CLProgram build(final CLBuildListener listener, String options, final CLDevice... devices)
Builds this program for the given devices and with the specified build options.
Definition: CLProgram.java:327
Map< CLDevice, Status > getBuildStatus()
Returns the build status enum of this program for each device as Map.
Definition: CLProgram.java:558
CLProgram build(final String options, final CLDevice... devices)
Builds this program for the given devices and with the specified build options.
Definition: CLProgram.java:313
Status getBuildStatus(final CLDevice device)
Returns the build status enum for this program on the specified device.
Definition: CLProgram.java:589
Map< String, CLKernel > createCLKernels()
Creates all kernels of this program and stores them a Map with the kernel name as key.
Definition: CLProgram.java:430
CLProgram build(final CLBuildListener listener, final CLDevice... devices)
Builds this program for the given devices.
Definition: CLProgram.java:259
void release()
Releases this program with its kernels.
Definition: CLProgram.java:478
CLKernel createCLKernel(final String kernelName)
Creates a kernel with the specified kernel name.
Definition: CLProgram.java:410
void setNoSource()
Must set this if the program is created from binary so we know not to call getSource(),...
Definition: CLProgram.java:601
static String define(final String name, final Object value)
Utility method for defining macros as build options (Returns "-D name=value").
Definition: CLProgram.java:694
static String optionsOf(final String... options)
Utility method which builds a properly seperated option string.
Definition: CLProgram.java:674
static String clString2JavaString(final byte[] chars, int clLength)
Definition: CLUtil.java:51
Configures the mapping process.
Definition: CLMemory.java:402
static Status valueOf(final int clBuildStatus)
Definition: CLProgram.java:746
final int STATUS
Value of wrapped OpenCL device type.
Definition: CLProgram.java:740
Common compiler options for the OpenCL compiler.
Definition: CLProgram.java:767
static final String FINITE_MATH_ONLY
Allow optimizations for floating-point arithmetic that assume that arguments and results are not NaNs...
Definition: CLProgram.java:830
static final String ENABLE_MAD
Allow a * b + c to be replaced by a mad.
Definition: CLProgram.java:803
static final String SINGLE_PRECISION_CONSTANTS
Treat double precision floating-point constant as single precision constant.
Definition: CLProgram.java:772
static final String DISABLE_OPT
This option disables all optimizations.
Definition: CLProgram.java:792
static final String UNSAFE_MATH
Allow optimizations for floating-point arithmetic that (a) assume that arguments and results are val...
Definition: CLProgram.java:823
static final String DENORMS_ARE_ZERO
This option controls how single precision and double precision denormalized numbers are handled.
Definition: CLProgram.java:787
static final String WARNINGS_ARE_ERRORS
Make all warnings into errors.
Definition: CLProgram.java:850
static final String FAST_RELAXED_MATH
Sets the optimization options -cl-finite-math-only (FINITE_MATH_ONLY) and -cl-unsafe-math-optimizatio...
Definition: CLProgram.java:840
static final String DISABLE_WARNINGS
Inhibit all warning messages.
Definition: CLProgram.java:845
static final String STRICT_ALIASING
This option allows the compiler to assume the strictest aliasing rules.
Definition: CLProgram.java:797
static final String NO_SIGNED_ZEROS
Allow optimizations for floating-point arithmetic that ignore the signedness of zero.
Definition: CLProgram.java:811
Java bindings to OpenCL, the Open Computing Language.
Definition: CL.java:26
long clCreateProgramWithBinary(long context, int num_devices, PointerBuffer device_list, PointerBuffer lengths, PointerBuffer binaries, IntBuffer binary_status, IntBuffer errcode_ret)
Interface to C language function: cl_program {@native clCreateProgramWithBinary}(cl_context context...
long clCreateKernel(long program, String kernel_name, IntBuffer errcode_ret)
Interface to C language function: cl_kernel {@native clCreateKernel}(cl_program program,...
int clBuildProgram(long program, int deviceCount, PointerBuffer devices, String options, BuildProgramCallback cb)
Interface to C language function: int32_t {@native clBuildProgram}(cl_program, uint32_t,...
int clGetProgramInfo(long program, int param_name, long param_value_size, Buffer param_value, PointerBuffer param_value_size_ret)
Interface to C language function: cl_int {@native clGetProgramInfo}(cl_program program,...
int clCreateKernelsInProgram(long program, int num_kernels, PointerBuffer kernels, IntBuffer num_kernels_ret)
Interface to C language function: cl_int {@native clCreateKernelsInProgram}(cl_program program,...
int clGetProgramBuildInfo(long program, long device, int param_name, long param_value_size, Buffer param_value, PointerBuffer param_value_size_ret)
Interface to C language function: cl_int {@native clGetProgramBuildInfo}(cl_program program,...
int clReleaseProgram(long program)
Interface to C language function: cl_int {@native clReleaseProgram}(cl_program program)
long clCreateProgramWithSource(long context, int count, String[] strings, PointerBuffer lengths, IntBuffer errcode_ret)
Interface to C language function: cl_program {@native clCreateProgramWithSource}(cl_context context...
A callback an application can register to be called when the program executable has been built (succe...
A callback an application can register to be called when the program executable has been built (succe...
void buildFinished(CLProgram program)
Called when the program executable has been built (successfully or unsuccessfully).
Configuration representing everything needed to build an OpenCL program (program included).