JOCL v2.6.0-rc-20250722
JOCL, OpenCL® API Binding for Java™ (public API).
CLPlatform.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.opencl.llb.CL;
32import com.jogamp.opencl.impl.CLTLAccessorFactory;
33import com.jogamp.common.nio.Buffers;
34import com.jogamp.common.JogampRuntimeException;
35import com.jogamp.common.nio.PointerBuffer;
36import com.jogamp.opencl.spi.CLPlatformInfoAccessor;
37import com.jogamp.opencl.util.CLUtil;
38import com.jogamp.opencl.llb.impl.CLImpl11;
39import com.jogamp.opencl.llb.impl.CLImpl12;
40import com.jogamp.opencl.llb.impl.CLImpl20;
41import com.jogamp.opencl.spi.CLAccessorFactory;
42import com.jogamp.opencl.spi.CLInfoAccessor;
43import com.jogamp.opencl.util.Filter;
44
45import java.nio.IntBuffer;
46import java.util.ArrayList;
47import java.util.Collections;
48import java.util.HashSet;
49import java.util.List;
50import java.util.Map;
51import java.util.Scanner;
52import java.util.Set;
53
54import static com.jogamp.opencl.CLException.*;
55import static com.jogamp.opencl.llb.CL.*;
56
57/**
58 * CLPlatfrorm representing a OpenCL implementation (e.g. graphics driver).
59 *
60 * optional eager initialization:
61 * <p><pre>
62 * if( !CLPlatform.isAvailable() ) {
63 * return; // abort
64 * }
65 * try{
66 * CLPlatform.initialize();
67 * }catch(JogampRuntimeException ex) {
68 * throw new RuntimeException("could not load Java OpenCL Binding");
69 * }
70 * </pre></p>
71 *
72 * Example initialization:
73 * <p><pre>
74 * if( !CLPlatform.isAvailable() ) {
75 * return; // abort
76 * }
77 * CLPlatform platform = CLPlatform.getDefault(type(GPU));
78 *
79 * if(platform == null) {
80 * throw new RuntimeException("please update your graphics drivers");
81 * }
82 *
83 * CLContext context = CLContext.create(platform.getMaxFlopsDevice());
84 * try {
85 * // use it
86 * }finally{
87 * context.release();
88 * }
89 * </pre></p>
90 * concurrency:<br/>
91 * CLPlatform is threadsafe.
92 *
93 * @author Michael Bien, et al.
94 * @see #isAvailable()
95 * @see #initialize()
96 * @see #getDefault()
97 * @see #listCLPlatforms()
98 */
99public class CLPlatform {
100
101 /**
102 * OpenCL platform id for this platform.
103 */
104 public final long ID;
105
106 /**
107 * Version of this OpenCL platform.
108 */
109 public final CLVersion version;
110
111 protected static CL cl;
112 private static CLAccessorFactory defaultFactory;
113 private final CLAccessorFactory factory;
114
115 private Set<String> extensions;
116
118
119 private CLPlatform(final long id) {
120 this(id, null);
121 }
122
123 protected CLPlatform(final long id, final CLAccessorFactory factory) {
124 initialize();
125 this.ID = id;
126 if(factory == null) {
127 this.factory = defaultFactory;
128 }else{
129 this.factory = factory;
130 }
131 this.info = this.factory.createPlatformInfoAccessor(cl, id);
132 this.version = new CLVersion(getInfoString(CL_PLATFORM_VERSION));
133 }
134
135 /**
136 * @returns true if OpenCL is available on this machine,
137 * i.e. all native libraries could be loaded (CL and CL/JNI).
138 */
139 public static boolean isAvailable() { return CLImpl11.isAvailable(); }
140
141 /**
142 * Eagerly initializes JOCL. Subsequent calls do nothing.
143 * @throws JogampRuntimeException if something went wrong in the initialization (e.g. OpenCL lib not found).
144 * @see #isAvailable()
145 */
146 public static void initialize() throws JogampRuntimeException {
147 initialize(null);
148 }
149
150 // keep package private until SPI is stablized
151 /**
152 * Eagerly initializes JOCL. Subsequent calls do nothing.
153 * @param factory CLAccessorFactory used for creating the bindings.
154 * @throws JogampRuntimeException if something went wrong in the initialization (e.g. OpenCL lib not found).
155 * @see #isAvailable()
156 */
157 synchronized static void initialize(final CLAccessorFactory factory) throws JogampRuntimeException {
158 if(cl != null) {
159 return;
160 }
161
162 if(defaultFactory == null) {
163 if(factory == null) {
164 defaultFactory = new CLTLAccessorFactory();
165 }else{
166 defaultFactory = factory;
167 }
168 }
169
170 if( !CLImpl11.isAvailable() ) {
171 throw new JogampRuntimeException("JOCL is not available");
172 }
173 cl = new CLImpl11();
174 }
175
176 /**
177 * Returns the default OpenCL platform or null when no platform found.
178 */
179 public static CLPlatform getDefault() {
180 initialize();
181 return latest(listCLPlatforms());
182 }
183
184 /**
185 * Returns the default OpenCL platform or null when no platform found.
186 */
187 public static CLPlatform getDefault(final Filter<CLPlatform>... filter) {
188 final CLPlatform[] platforms = listCLPlatforms(filter);
189 if(platforms.length > 0) {
190 return latest(platforms);
191 }else{
192 return null;
193 }
194 }
195
196 private static CLPlatform latest(final CLPlatform[] platforms) {
197 CLPlatform best = platforms[0];
198 for (final CLPlatform platform : platforms) {
199 if (platform.version.compareTo(best.version) > 0) {
200 best = platform;
201 }
202 }
203 return best;
204 }
205
206 /**
207 * Lists all available OpenCL implementations.
208 * @throws CLException if something went wrong initializing OpenCL
209 */
210 public static CLPlatform[] listCLPlatforms() {
211 return listCLPlatforms((Filter<CLPlatform>[])null);
212 }
213
214 /**
215 * Lists all available OpenCL implementations. The platforms returned must pass all filters.
216 * @param filter Acceptance filter for the returned platforms.
217 * @throws CLException if something went wrong initializing OpenCL
218 */
219 public static CLPlatform[] listCLPlatforms(final Filter<CLPlatform>... filter) {
220 initialize();
221
222 final IntBuffer ib = Buffers.newDirectIntBuffer(1);
223 // find all available OpenCL platforms
224 int ret = cl.clGetPlatformIDs(0, null, ib);
225 checkForError(ret, "can not enumerate platforms");
226
227 // receive platform ids
228 final PointerBuffer platformId = PointerBuffer.allocateDirect(ib.get(0));
229 ret = cl.clGetPlatformIDs(platformId.capacity(), platformId, null);
230 checkForError(ret, "can not enumerate platforms");
231
232 final List<CLPlatform> platforms = new ArrayList<CLPlatform>();
233
234 for (int i = 0; i < platformId.capacity(); i++) {
235 final CLPlatform platform = new CLPlatform(platformId.get(i));
236 addIfAccepted(platform, platforms, filter);
237 }
238
239 return platforms.toArray(new CLPlatform[platforms.size()]);
240 }
241
242 /**
243 * Returns the low level binding interface to the OpenCL APIs. This interface is always for OpenCL 1.1.
244 */
245 public static CL getLowLevelCLInterface() {
246 initialize();
247 return cl;
248 }
249
250 /**
251 * Returns the low level binding interface to the OpenCL APIs for the specified device. This interface
252 * is the newest one the device supports.
253 */
254 public static CL getLowLevelCLInterfaceForDevice(final long device) {
255 initialize();
256
257 CLInfoAccessor deviceInfo = defaultFactory.createDeviceInfoAccessor(cl, device);
258 CLVersion version = new CLVersion(deviceInfo.getString(CL_DEVICE_VERSION));
259
261 return new CLImpl12();
262
264 return new CLImpl20();
265
266 return cl;
267 }
268
269 /**
270 * Hint to allow the implementation to release the resources allocated by the OpenCL compiler.
271 * Calls to {@link CLProgram#build()} after unloadCompiler will reload the compiler if necessary.
272 */
273 public static void unloadCompiler() {
274 initialize();
275 final int ret = cl.clUnloadCompiler();
276 checkForError(ret, "error while sending unload compiler hint");
277 }
278
279 /**
280 * Lists all physical devices available on this platform.
281 * @see #listCLDevices(com.jogamp.opencl.CLDevice.Type...)
282 */
284 try{
285 return this.listCLDevices(CLDevice.Type.ALL);
286 }
287 catch(CLInvalidDeviceTypeException ignore){ //trying to list GPUs if CL_DEVICE_TYPE_ALL isn't valid. on some non-standard implementations (Android PowerVR), only CL_DEVICE_TYPE_GPU is supported and use of other types including ALL will lead to a CL_INVALID_DEVICE_TYPE
288 return this.listCLDevices(CLDevice.Type.GPU);
289 }
290 }
291
292 /**
293 * Lists all physical devices available on this platform matching the given {@link CLDevice.Type}.
294 */
295 public CLDevice[] listCLDevices(final CLDevice.Type... types) {
296 initialize();
297
298 final List<CLDevice> list = new ArrayList<CLDevice>();
299
300 for(int t = 0; t < types.length; t++) {
301 final CLDevice.Type type = types[t];
302
303 final long[] deviceIDs = info.getDeviceIDs(type.TYPE);
304
305 //add device to list
306 for (int n = 0; n < deviceIDs.length; n++) {
307 list.add(createDevice(deviceIDs[n]));
308 }
309 }
310
311 return list.toArray(new CLDevice[list.size()]);
312
313 }
314
315 /**
316 * Lists all physical devices available on this platform matching the given {@link Filter}.
317 */
318 public CLDevice[] listCLDevices(final Filter<CLDevice>... filters) {
319 initialize();
320
321 final List<CLDevice> list = new ArrayList<CLDevice>();
322
323 final long[] deviceIDs = info.getDeviceIDs(CL_DEVICE_TYPE_ALL);
324
325 //add device to list
326 for (int n = 0; n < deviceIDs.length; n++) {
327 final CLDevice device = createDevice(deviceIDs[n]);
328 addIfAccepted(device, list, filters);
329 }
330
331 return list.toArray(new CLDevice[list.size()]);
332
333 }
334
335 protected CLDevice createDevice(final long id) {
336 return new CLDevice(this, id);
337 }
338
339 private static <I> void addIfAccepted(final I item, final List<I> list, final Filter<I>[] filters) {
340 if(filters == null) {
341 list.add(item);
342 }else{
343 boolean accepted = true;
344 for (final Filter<I> filter : filters) {
345 if(!filter.accept(item)) {
346 accepted = false;
347 break;
348 }
349 }
350 if(accepted) {
351 list.add(item);
352 }
353 }
354 }
355
356 static CLDevice findMaxFlopsDevice(final CLDevice[] devices) {
357 return findMaxFlopsDevice(devices, null);
358 }
359
360 static CLDevice findMaxFlopsDevice(final CLDevice[] devices, final CLDevice.Type type) {
361 initialize();
362
363 CLDevice maxFLOPSDevice = null;
364
365 int maxflops = -1;
366
367 for (int i = 0; i < devices.length; i++) {
368
369 final CLDevice device = devices[i];
370
371 if(type == null || type.equals(device.getType())) {
372
373 final int maxComputeUnits = device.getMaxComputeUnits();
374 final int maxClockFrequency = device.getMaxClockFrequency();
375 final int flops = maxComputeUnits*maxClockFrequency;
376
377 if(flops > maxflops) {
378 maxflops = flops;
379 maxFLOPSDevice = device;
380 }
381 }
382
383 }
384
385 return maxFLOPSDevice;
386 }
387
388
389 /**
390 * Returns the device with maximal FLOPS from this platform.
391 * The device speed is estimated by calculating the product of
392 * MAX_COMPUTE_UNITS and MAX_CLOCK_FREQUENCY.
393 * @see #getMaxFlopsDevice(com.jogamp.opencl.CLDevice.Type...)
394 */
396 return findMaxFlopsDevice(listCLDevices());
397 }
398
399 /**
400 * Returns the device with maximal FLOPS and the specified type from this platform.
401 * The device speed is estimated by calculating the product of
402 * MAX_COMPUTE_UNITS and MAX_CLOCK_FREQUENCY.
403 */
404 public CLDevice getMaxFlopsDevice(final CLDevice.Type... types) {
405 return findMaxFlopsDevice(listCLDevices(types));
406 }
407
408 /**
409 * Returns the device with maximal FLOPS and the specified type from this platform.
410 * The device speed is estimated by calculating the product of
411 * MAX_COMPUTE_UNITS and MAX_CLOCK_FREQUENCY.
412 */
414 return findMaxFlopsDevice(listCLDevices(filter));
415 }
416
417 /**
418 * Returns the platform name.
419 */
420 @CLProperty("CL_PLATFORM_NAME")
421 public String getName() {
422 return getInfoString(CL_PLATFORM_NAME);
423 }
424
425 /**
426 * Returns the OpenCL version supported by this platform.
427 */
428 @CLProperty("CL_PLATFORM_VERSION")
430 return version;
431 }
432
433 /**
434 * Returns the OpenCL Specification version supported by this platform.
435 */
436 public String getSpecVersion() {
437 return version.getSpecVersion();
438 }
439
440 /**
441 * @see CLVersion#isAtLeast(com.jogamp.opencl.CLVersion)
442 */
443 public boolean isAtLeast(final CLVersion other) {
444 return version.isAtLeast(other);
445 }
446
447 /**
448 * @see CLVersion#isAtLeast(int, int)
449 */
450 public boolean isAtLeast(final int major, final int minor) {
451 return version.isAtLeast(major, minor);
452 }
453
454 /**
455 * Returns the platform profile.
456 */
457 @CLProperty("CL_PLATFORM_PROFILE")
458 public String getProfile() {
459 return getInfoString(CL_PLATFORM_PROFILE);
460 }
461
462 /**
463 * Returns the platform vendor.
464 */
465 @CLProperty("CL_PLATFORM_VENDOR")
466 public String getVendor() {
467 return getInfoString(CL_PLATFORM_VENDOR);
468 }
469
470 /**
471 * @return true if the vendor is AMD.
472 */
473 public boolean isVendorAMD() {
474 return getVendor().contains("Advanced Micro Devices");
475 }
476
477 /**
478 * @return true if the vendor is Intel.
479 */
480 public boolean isVendorIntel() {
481 return getVendor().contains("Intel");
482 }
483
484 /**
485 * Returns the ICD suffix.
486 */
487 @CLProperty("CL_PLATFORM_ICD_SUFFIX_KHR")
488 public String getICDSuffix() {
489 return getInfoString(CL_PLATFORM_ICD_SUFFIX_KHR);
490 }
491
492 /**
493 * Returns true if the extension is supported on this platform.
494 */
495 public boolean isExtensionAvailable(final String extension) {
496 return getExtensions().contains(extension);
497 }
498
499 /**
500 * Returns all platform extension names as unmodifiable Set.
501 */
502 @CLProperty("CL_PLATFORM_EXTENSIONS")
503 public synchronized Set<String> getExtensions() {
504
505 if(extensions == null) {
506 extensions = new HashSet<String>();
507 final String ext = getInfoString(CL_PLATFORM_EXTENSIONS);
508 final Scanner scanner = new Scanner(ext);
509
510 while(scanner.hasNext())
511 extensions.add(scanner.next());
512
513 scanner.close();
514 extensions = Collections.unmodifiableSet(extensions);
515 }
516
517 return extensions;
518 }
519
520 /**
521 * Returns a Map of platform properties with the enum names as keys.
522 * @see CLUtil#obtainPlatformProperties(com.jogamp.opencl.CLPlatform)
523 */
525 return CLUtil.obtainPlatformProperties(this);
526 }
527
528 /**
529 * Returns a info string in exchange for a key (CL_PLATFORM_*).
530 */
531 public final String getInfoString(final int key) {
532 return info.getString(key);
533 }
534
535 final CLAccessorFactory getAccessorFactory(){
536 return factory;
537 }
538
540 return info;
541 }
542
543 protected CL getCLBinding() {
544 return cl;
545 }
546
547 @Override
548 public String toString() {
549 return getClass().getSimpleName()+" [name: " + getName()
550 +", vendor: "+getVendor()
551 +", profile: "+getProfile()
552 +", version: "+getVersion()+"]";
553 }
554
555 @Override
556 public boolean equals(final Object obj) {
557 if (obj == null) {
558 return false;
559 }
560 if (getClass() != obj.getClass()) {
561 return false;
562 }
563 final CLPlatform other = (CLPlatform) obj;
564 if (this.ID != other.ID) {
565 return false;
566 }
567 return true;
568 }
569
570 @Override
571 public int hashCode() {
572 int hash = 7;
573 hash = 71 * hash + (int) (this.ID ^ (this.ID >>> 32));
574 return hash;
575 }
576
577}
This object represents an OpenCL device.
Definition: CLDevice.java:53
CLPlatfrorm representing a OpenCL implementation (e.g.
Definition: CLPlatform.java:99
boolean equals(final Object obj)
String getSpecVersion()
Returns the OpenCL Specification version supported by this platform.
CLDevice getMaxFlopsDevice(final CLDevice.Type... types)
Returns the device with maximal FLOPS and the specified type from this platform.
CLDevice[] listCLDevices()
Lists all physical devices available on this platform.
CLPlatform(final long id, final CLAccessorFactory factory)
String getName()
Returns the platform name.
boolean isAtLeast(final CLVersion other)
static void unloadCompiler()
Hint to allow the implementation to release the resources allocated by the OpenCL compiler.
String getICDSuffix()
Returns the ICD suffix.
boolean isAtLeast(final int major, final int minor)
final long ID
OpenCL platform id for this platform.
CLDevice[] listCLDevices(final CLDevice.Type... types)
Lists all physical devices available on this platform matching the given CLDevice....
CLDevice[] listCLDevices(final Filter< CLDevice >... filters)
Lists all physical devices available on this platform matching the given Filter.
static CLPlatform getDefault(final Filter< CLPlatform >... filter)
Returns the default OpenCL platform or null when no platform found.
boolean isExtensionAvailable(final String extension)
Returns true if the extension is supported on this platform.
CLDevice getMaxFlopsDevice(final Filter< CLDevice >... filter)
Returns the device with maximal FLOPS and the specified type from this platform.
final CLPlatformInfoAccessor getCLAccessor()
final CLPlatformInfoAccessor info
static void initialize()
Eagerly initializes JOCL.
static CL getLowLevelCLInterfaceForDevice(final long device)
Returns the low level binding interface to the OpenCL APIs for the specified device.
static boolean isAvailable()
CLVersion getVersion()
Returns the OpenCL version supported by this platform.
final String getInfoString(final int key)
Returns a info string in exchange for a key (CL_PLATFORM_*).
static CLPlatform[] listCLPlatforms()
Lists all available OpenCL implementations.
CLDevice getMaxFlopsDevice()
Returns the device with maximal FLOPS from this platform.
static CL getLowLevelCLInterface()
Returns the low level binding interface to the OpenCL APIs.
CLDevice createDevice(final long id)
static CLPlatform[] listCLPlatforms(final Filter< CLPlatform >... filter)
Lists all available OpenCL implementations.
String getProfile()
Returns the platform profile.
static CLPlatform getDefault()
Returns the default OpenCL platform or null when no platform found.
String getVendor()
Returns the platform vendor.
synchronized Set< String > getExtensions()
Returns all platform extension names as unmodifiable Set.
final CLVersion version
Version of this OpenCL platform.
Map< String, String > getProperties()
Returns a Map of platform properties with the enum names as keys.
Version of an OpenCL Implementation.
Definition: CLVersion.java:42
boolean isEqual(final CLVersion other)
Definition: CLVersion.java:109
String getSpecVersion()
Returns '"OpenCL " + major + "." + minor'.
Definition: CLVersion.java:120
static final CLVersion CL_1_2
Definition: CLVersion.java:48
static final CLVersion CL_2_0
Definition: CLVersion.java:49
boolean isAtLeast(final CLVersion other)
Definition: CLVersion.java:101
Java bindings to OpenCL, the Open Computing Language (generated).
Definition: CLImpl11.java:32
static boolean isAvailable()
Accessor.
Definition: CLImpl11.java:1843
Java bindings to OpenCL, the Open Computing Language (generated).
Definition: CLImpl12.java:33
Java bindings to OpenCL, the Open Computing Language (generated).
Definition: CLImpl20.java:33
static Map< String, String > obtainPlatformProperties(final CLPlatform platform)
Reads all platform properties and returns them as key-value map.
Definition: CLUtil.java:87
Enumeration for the type of a device.
Definition: CLDevice.java:798
Configures the mapping process.
Definition: CLMemory.java:402
Java bindings to OpenCL, the Open Computing Language.
Definition: CL.java:26
int clGetPlatformIDs(int num_entries, PointerBuffer platforms, IntBuffer num_platforms)
Interface to C language function: cl_int {@native clGetPlatformIDs}(cl_uint num_entries,...
int clUnloadCompiler()
Interface to C language function: cl_int {@native clUnloadCompiler}()
Implementations of this interface are factories responsible for creating CLAccessors.
CLInfoAccessor createDeviceInfoAccessor(CL cl, long id)
CLPlatformInfoAccessor createPlatformInfoAccessor(CL cl, long id)
Internal utility for common OpenCL clGetFooInfo calls.
String getString(int key)
Returns the String value for the given key.