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