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