001/* 002 * JavaCL - Java API and utilities for OpenCL 003 * http://javacl.googlecode.com/ 004 * 005 * Copyright (c) 2009-2013, Olivier Chafik (http://ochafik.com/) 006 * All rights reserved. 007 * 008 * Redistribution and use in source and binary forms, with or without 009 * modification, are permitted provided that the following conditions are met: 010 * 011 * * Redistributions of source code must retain the above copyright 012 * notice, this list of conditions and the following disclaimer. 013 * * Redistributions in binary form must reproduce the above copyright 014 * notice, this list of conditions and the following disclaimer in the 015 * documentation and/or other materials provided with the distribution. 016 * * Neither the name of Olivier Chafik nor the 017 * names of its contributors may be used to endorse or promote products 018 * derived from this software without specific prior written permission. 019 * 020 * THIS SOFTWARE IS PROVIDED BY OLIVIER CHAFIK AND CONTRIBUTORS ``AS IS'' AND ANY 021 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 023 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 024 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 025 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 026 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 027 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 030 */ 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050package com.nativelibs4java.opencl; 051 052import com.nativelibs4java.util.EnumValue; 053import com.nativelibs4java.util.EnumValues; 054import com.nativelibs4java.opencl.library.OpenCLLibrary; 055import com.nativelibs4java.util.IOUtils; 056import com.nativelibs4java.util.NIOUtils; 057 058import static com.nativelibs4java.opencl.library.OpenCLLibrary.*; 059import static com.nativelibs4java.opencl.library.IOpenCLLibrary.*; 060import org.bridj.*; 061import static org.bridj.Pointer.*; 062 063import java.io.IOException; 064import java.nio.*; 065import static com.nativelibs4java.opencl.JavaCL.*; 066import static com.nativelibs4java.util.NIOUtils.*; 067import java.util.*; 068import static com.nativelibs4java.opencl.CLException.*; 069import com.nativelibs4java.util.ValuedEnum; 070import java.util.logging.Level; 071import java.util.logging.Logger; 072 073/** 074 * OpenCL device (CPU, GPU...).<br> 075 * Devices are retrieved from a CLPlatform through 076 * {@link CLPlatform#listDevices(CLDevice.Type, boolean) }, 077 * {@link CLPlatform#listAllDevices(boolean) }, 078 * {@link CLPlatform#listCPUDevices(boolean) }, 079 * {@link CLPlatform#listGPUDevices(boolean) } 080 */ 081@SuppressWarnings("unused") 082public class CLDevice extends CLAbstractEntity { 083 084 protected static CLInfoGetter infos = new CLInfoGetter() { 085 @Override 086 protected int getInfo(long entity, int infoTypeEnum, long size, Pointer out, Pointer<SizeT> sizeOut) { 087 return CL.clGetDeviceInfo(entity, infoTypeEnum, size, getPeer(out), getPeer(sizeOut)); 088 } 089 }; 090 091 private volatile CLPlatform platform; 092 private volatile CLDevice parent; 093 private volatile boolean fetchedParent; 094 private final boolean needsRelease; 095 096 CLDevice(CLPlatform platform, long device) { 097 this(platform, null, device, false); 098 } 099 CLDevice(CLPlatform platform, CLDevice parent, long device, boolean needsRelease) { 100 super(device); 101 this.platform = platform; 102 this.needsRelease = needsRelease; 103 this.parent = parent; 104 this.fetchedParent = parent != null; 105 } 106 107 public synchronized CLPlatform getPlatform() { 108 if (platform == null) { 109 Pointer pplat = infos.getPointer(getEntity(), CL_DEVICE_PLATFORM); 110 platform = new CLPlatform(getPeer(pplat)); 111 } 112 return platform; 113 } 114 115 @Override 116 protected void clear() { 117 if (needsRelease) 118 error(CL.clReleaseDevice(getEntity())); 119 } 120 121 public String createSignature() { 122 return getName() + "|" + getVendor() + "|" + getDriverVersion() + "|" + getProfile(); 123 } 124 public static Map<String, List<CLDevice>> getDevicesBySignature(List<CLDevice> devices) { 125 Map<String, List<CLDevice>> ret = new HashMap<String, List<CLDevice>>(); 126 for (CLDevice device : devices) { 127 String signature = device.createSignature(); 128 List<CLDevice> list = ret.get(signature); 129 if (list == null) 130 ret.put(signature, list = new ArrayList<CLDevice>()); 131 list.add(device); 132 } 133 return ret; 134 } 135 136 private volatile ByteOrder byteOrder; 137 public ByteOrder getByteOrder() { 138 if (byteOrder == null) 139 byteOrder = isEndianLittle() ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN; 140 return byteOrder; 141 } 142 143 private volatile ByteOrder kernelsDefaultByteOrder; 144 /** 145 * @deprecated Use {@link CLDevice#getByteOrder()} 146 */ 147 @Deprecated 148 public synchronized ByteOrder getKernelsDefaultByteOrder() { 149 if (kernelsDefaultByteOrder == null) { 150 kernelsDefaultByteOrder = ByteOrderHack.guessByteOrderNeededForBuffers(this); 151 } 152 return kernelsDefaultByteOrder; 153 } 154 155 /** Bit values for CL_DEVICE_EXECUTION_CAPABILITIES */ 156 public enum ExecutionCapability implements com.nativelibs4java.util.ValuedEnum { 157 158 Kernel(CL_EXEC_KERNEL), 159 NativeKernel(CL_EXEC_NATIVE_KERNEL); 160 161 ExecutionCapability(long value) { this.value = value; } 162 long value; 163 @Override 164 public long value() { return value; } 165 public static long getValue(EnumSet<ExecutionCapability> set) { 166 return EnumValues.getValue(set); 167 } 168 169 public static EnumSet<ExecutionCapability> getEnumSet(long v) { 170 return EnumValues.getEnumSet(v, ExecutionCapability.class); 171 } 172 } 173 174 /** 175 * Describes the execution capabilities of the device.<br> 176 * The mandated minimum capability is: Kernel. 177 */ 178 @InfoName("CL_DEVICE_EXECUTION_CAPABILITIES") 179 public EnumSet<ExecutionCapability> getExecutionCapabilities() { 180 return ExecutionCapability.getEnumSet(infos.getIntOrLong(getEntity(), CL_DEVICE_EXECUTION_CAPABILITIES)); 181 } 182 183 /** Bit values for CL_DEVICE_TYPE */ 184 public enum Type implements com.nativelibs4java.util.ValuedEnum { 185 186 CPU(CL_DEVICE_TYPE_CPU), 187 GPU(CL_DEVICE_TYPE_GPU), 188 Accelerator(CL_DEVICE_TYPE_ACCELERATOR), 189 Default(CL_DEVICE_TYPE_DEFAULT), 190 All(CL_DEVICE_TYPE_ALL); 191 192 Type(long value) { this.value = value; } 193 long value; 194 @Override 195 public long value() { return value; } 196 197 public static long getValue(EnumSet<Type> set) { 198 return EnumValues.getValue(set); 199 } 200 201 public static EnumSet<Type> getEnumSet(long v) { 202 return EnumValues.getEnumSet(v, Type.class); 203 } 204 } 205 206 /** 207 * The OpenCL device type. 208 */ 209 @InfoName("CL_DEVICE_TYPE") 210 public EnumSet<Type> getType() { 211 return Type.getEnumSet(infos.getIntOrLong(getEntity(), CL_DEVICE_TYPE)); 212 } 213 214 /** 215 * A unique device vendor identifier. <br> 216 * An example of a unique device identifier could be the PCIe ID. 217 */ 218 @InfoName("CL_DEVICE_VENDOR_ID") 219 public int getVendorId() { 220 return infos.getInt(getEntity(), CL_DEVICE_VENDOR_ID); 221 } 222 223 /** 224 * The number of parallel compute cores on the OpenCL device. <br> 225 * The minimum value is 1. 226 */ 227 @InfoName("CL_DEVICE_MAX_COMPUTE_UNITS") 228 public int getMaxComputeUnits() { 229 return infos.getInt(getEntity(), CL_DEVICE_MAX_COMPUTE_UNITS); 230 } 231 232 /** 233 * Maximum dimensions that specify the global and local work-item IDs used by the data parallel execution model. <br> 234 * (Refer to clEnqueueNDRangeKernel). 235 * <br>The minimum value is 3. 236 */ 237 @InfoName("CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS") 238 public int getMaxWorkItemDimensions() { 239 return infos.getInt(getEntity(), CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS); 240 } 241 242 /** 243 * Maximum number of work-items that can be specified in each dimension of the work-group to clEnqueueNDRangeKernel. 244 */ 245 @InfoName("CL_DEVICE_MAX_WORK_ITEM_SIZES") 246 public long[] getMaxWorkItemSizes() { 247 long sizes[] = infos.getNativeSizes(getEntity(), CL_DEVICE_MAX_WORK_ITEM_SIZES, getMaxWorkItemDimensions()); 248 for (int i = 0, n = sizes.length; i < n; i++) { 249 long size = sizes[i]; 250 if ((size & 0xffffffff00000000L) == 0xcccccccc00000000L) 251 sizes[i] = size & 0xffffffffL; 252 } 253 return sizes; 254 } 255 256 /** 257 * Maximum number of work-items in a work-group executing a kernel using the data parallel execution model. 258 * (Refer to clEnqueueNDRangeKernel). <br> 259 * The minimum value is 1. 260 */ 261 @InfoName("CL_DEVICE_MAX_WORK_GROUP_SIZE") 262 public long getMaxWorkGroupSize() { 263 return infos.getIntOrLong(getEntity(), CL_DEVICE_MAX_WORK_GROUP_SIZE); 264 } 265 266 /** 267 * Maximum configured clock frequency of the device in MHz. 268 */ 269 @InfoName("CL_DEVICE_MAX_CLOCK_FREQUENCY") 270 public int getMaxClockFrequency() { 271 return infos.getInt(getEntity(), CL_DEVICE_MAX_CLOCK_FREQUENCY); 272 } 273 274 /** 275 * The default compute device address space size specified as an unsigned integer value in bits. Currently supported values are 32 or 64 bits..<br> 276 * Size of size_t type in OpenCL kernels can be obtained with getAddressBits() / 8. 277 */ 278 @InfoName("CL_DEVICE_ADDRESS_BITS") 279 public int getAddressBits() { 280 return infos.getInt(getEntity(), CL_DEVICE_ADDRESS_BITS); 281 } 282 283 /** 284 * Max size of memory object allocation in bytes. The minimum value is max (1/4th of CL_DEVICE_GLOBAL_MEM_SIZE , 128*1024*1024) 285 */ 286 @InfoName("CL_DEVICE_MAX_MEM_ALLOC_SIZE") 287 public long getMaxMemAllocSize() { 288 return infos.getIntOrLong(getEntity(), CL_DEVICE_MAX_MEM_ALLOC_SIZE); 289 } 290 291 /** 292 * Is CL_TRUE if images are supported by the OpenCL device and CL_FALSE otherwise. 293 */ 294 @InfoName("CL_DEVICE_IMAGE_SUPPORT") 295 public boolean hasImageSupport() { 296 return infos.getBool(getEntity(), CL_DEVICE_IMAGE_SUPPORT); 297 } 298 299 /** 300 * Max number of simultaneous image objects that can be read by a kernel. <br> 301 * The minimum value is 128 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE (@see hasImageSupport()). 302 */ 303 @InfoName("CL_DEVICE_MAX_READ_IMAGE_ARGS") 304 public int getMaxReadImageArgs() { 305 return infos.getInt(getEntity(), CL_DEVICE_MAX_READ_IMAGE_ARGS); 306 } 307 308 /** 309 * Max number of simultaneous image objects that can be written to by a kernel. <br> 310 * The minimum value is 8 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE (@see hasImageSupport()). 311 */ 312 @InfoName("CL_DEVICE_MAX_WRITE_IMAGE_ARGS") 313 public int getMaxWriteImageArgs() { 314 return infos.getInt(getEntity(), CL_DEVICE_MAX_WRITE_IMAGE_ARGS); 315 } 316 317 @Override 318 public String toString() { 319 return getName() + " (" + getPlatform().getName() + ")"; 320 } 321 322 /** 323 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateCommandQueue.html">clCreateCommandQueue</a>.<br> 324 * Create an OpenCL execution queue on this device for the specified context. 325 * @param context context of the queue to create 326 * @return new OpenCL queue object 327 */ 328 @SuppressWarnings("deprecation") 329 public CLQueue createQueue(CLContext context, QueueProperties... queueProperties) { 330 ReusablePointers ptrs = ReusablePointers.get(); 331 Pointer<Integer> pErr = ptrs.pErr; 332 long flags = 0; 333 for (QueueProperties prop : queueProperties) 334 flags |= prop.value(); 335 long queue = CL.clCreateCommandQueue(context.getEntity(), getEntity(), flags, getPeer(pErr)); 336 error(pErr.getInt()); 337 return new CLQueue(context, queue, this); 338 } 339 340 /** 341 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateCommandQueue.html">clCreateCommandQueue</a>.<br> 342 */ 343 @Deprecated 344 public CLQueue createQueue(EnumSet<QueueProperties> queueProperties, CLContext context) { 345 ReusablePointers ptrs = ReusablePointers.get(); 346 Pointer<Integer> pErr = ptrs.pErr; 347 long queue = CL.clCreateCommandQueue(context.getEntity(), getEntity(), QueueProperties.getValue(queueProperties), getPeer(pErr)); 348 error(pErr.getInt()); 349 350 return new CLQueue(context, queue, this); 351 } 352 353 public CLQueue createOutOfOrderQueue(CLContext context) { 354 return createQueue(EnumSet.of(QueueProperties.OutOfOrderExecModeEnable), context); 355 } 356 357 public CLQueue createProfilingQueue(CLContext context) { 358 return createQueue(EnumSet.of(QueueProperties.ProfilingEnable), context); 359 } 360 361 /** 362 * Max width of 2D image in pixels. <br> 363 * The minimum value is 8192 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE. 364 */ 365 @InfoName("CL_DEVICE_IMAGE2D_MAX_WIDTH") 366 public long getImage2DMaxWidth() { 367 return infos.getIntOrLong(getEntity(), CL_DEVICE_IMAGE2D_MAX_WIDTH); 368 } 369 370 /** 371 * Max height of 2D image in pixels. <br> 372 * The minimum value is 8192 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE. 373 */ 374 @InfoName("CL_DEVICE_IMAGE2D_MAX_HEIGHT") 375 public long getImage2DMaxHeight() { 376 return infos.getIntOrLong(getEntity(), CL_DEVICE_IMAGE2D_MAX_HEIGHT); 377 } 378 379 /** 380 * Max width of 3D image in pixels. <br> 381 * The minimum value is 2048 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE. 382 */ 383 @InfoName("CL_DEVICE_IMAGE3D_MAX_WIDTH") 384 public long getImage3DMaxWidth() { 385 return infos.getIntOrLong(getEntity(), CL_DEVICE_IMAGE3D_MAX_WIDTH); 386 } 387 388 /** 389 * Max height of 3D image in pixels. <br> 390 * The minimum value is 2048 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE. 391 */ 392 @InfoName("CL_DEVICE_IMAGE3D_MAX_HEIGHT") 393 public long getImage3DMaxHeight() { 394 return infos.getIntOrLong(getEntity(), CL_DEVICE_IMAGE3D_MAX_HEIGHT); 395 } 396 397 /** 398 * Max depth of 3D image in pixels. <br> 399 * The minimum value is 2048 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE. 400 */ 401 @InfoName("CL_DEVICE_IMAGE3D_MAX_DEPTH") 402 public long getImage3DMaxDepth() { 403 return infos.getIntOrLong(getEntity(), CL_DEVICE_IMAGE3D_MAX_DEPTH); 404 } 405 406 /** 407 * Maximum number of samplers that can be used in a kernel. <br> 408 * Refer to section 6.11.8 for a detailed description on samplers. <br> 409 * The minimum value is 16 if CL_DEVICE_IMAGE_SUPPORT is CL_TRUE. 410 */ 411 @InfoName("CL_DEVICE_MAX_SAMPLERS") 412 public int getMaxSamplers() { 413 return infos.getInt(getEntity(), CL_DEVICE_MAX_SAMPLERS); 414 } 415 416 /** 417 * Max size in bytes of the arguments that can be passed to a kernel. <br> 418 * The minimum value is 256. 419 */ 420 @InfoName("CL_DEVICE_MAX_PARAMETER_SIZE") 421 public long getMaxParameterSize() { 422 return infos.getIntOrLong(getEntity(), CL_DEVICE_MAX_PARAMETER_SIZE); 423 } 424 425 /** 426 * Describes the alignment in bits of the base address of any allocated memory object. 427 */ 428 @InfoName("CL_DEVICE_MEM_BASE_ADDR_ALIGN") 429 public int getMemBaseAddrAlign() { 430 return infos.getInt(getEntity(), CL_DEVICE_MEM_BASE_ADDR_ALIGN); 431 } 432 433 /** 434 * The smallest alignment in bytes which can be used for any data type. 435 */ 436 @InfoName("CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE") 437 public int getMinDataTypeAlign() { 438 return infos.getInt(getEntity(), CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE); 439 } 440 441 /** 442 * Describes single precision floating- point capability of the device.<br> 443 * The mandated minimum floating-point capability is: RoundToNearest and InfNaN. 444 */ 445 @InfoName("CL_DEVICE_SINGLE_FP_CONFIG") 446 public EnumSet<FpConfig> getSingleFPConfig() { 447 return FpConfig.getEnumSet(infos.getIntOrLong(getEntity(), CL_DEVICE_SINGLE_FP_CONFIG)); 448 } 449 450 /** Values for CL_DEVICE_GLOBAL_MEM_CACHE_TYPE */ 451 public enum GlobalMemCacheType implements com.nativelibs4java.util.ValuedEnum { 452 453 None(CL_NONE), 454 ReadOnlyCache(CL_READ_ONLY_CACHE), 455 ReadWriteCache(CL_READ_WRITE_CACHE); 456 457 GlobalMemCacheType(long value) { this.value = value; } 458 long value; 459 @Override 460 public long value() { return value; } 461 462 public static GlobalMemCacheType getEnum(long v) { 463 return EnumValues.getEnum(v, GlobalMemCacheType.class); 464 } 465 } 466 467 /** 468 * Type of global memory cache supported. 469 */ 470 @InfoName("CL_DEVICE_GLOBAL_MEM_CACHE_TYPE") 471 public GlobalMemCacheType getGlobalMemCacheType() { 472 return GlobalMemCacheType.getEnum(infos.getInt(getEntity(), CL_DEVICE_GLOBAL_MEM_CACHE_TYPE)); 473 } 474 475 /** 476 * Size of global memory cache line in bytes. 477 */ 478 @InfoName("CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE") 479 public int getGlobalMemCachelineSize() { 480 return infos.getInt(getEntity(), CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE); 481 } 482 483 /** 484 * Size of global memory cache in bytes. 485 */ 486 @InfoName("CL_DEVICE_GLOBAL_MEM_CACHE_SIZE") 487 public long getGlobalMemCacheSize() { 488 return infos.getIntOrLong(getEntity(), CL_DEVICE_GLOBAL_MEM_CACHE_SIZE); 489 } 490 491 /** 492 * Size of global device memory in bytes. 493 */ 494 @InfoName("CL_DEVICE_GLOBAL_MEM_SIZE") 495 public long getGlobalMemSize() { 496 return infos.getIntOrLong(getEntity(), CL_DEVICE_GLOBAL_MEM_SIZE); 497 } 498 499 /** 500 * Max size in bytes of a constant buffer allocation. <br> 501 * The minimum value is 64 KB. 502 */ 503 @InfoName("CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE") 504 public long getMaxConstantBufferSize() { 505 return infos.getIntOrLong(getEntity(), CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE); 506 } 507 508 /** 509 * Max number of arguments declared with the __constant qualifier in a kernel. <br> 510 * The minimum value is 8. 511 */ 512 @InfoName("CL_DEVICE_MAX_CONSTANT_ARGS") 513 public int getMaxConstantArgs() { 514 return infos.getInt(getEntity(), CL_DEVICE_MAX_CONSTANT_ARGS); 515 } 516 517 /** Values for CL_DEVICE_LOCAL_MEM_TYPE */ 518 public enum LocalMemType implements com.nativelibs4java.util.ValuedEnum { 519 520 /** implying dedicated local memory storage such as SRAM */ 521 Local(CL_LOCAL), 522 Global(CL_GLOBAL); 523 524 LocalMemType(long value) { this.value = value; } 525 long value; 526 @Override 527 public long value() { return value; } 528 529 public static LocalMemType getEnum(long v) { 530 return EnumValues.getEnum(v, LocalMemType.class); 531 } 532 } 533 534 /** 535 * Type of local memory supported. <br> 536 */ 537 @InfoName("CL_DEVICE_LOCAL_MEM_TYPE") 538 public LocalMemType getLocalMemType() { 539 return LocalMemType.getEnum(infos.getInt(getEntity(), CL_DEVICE_LOCAL_MEM_TYPE)); 540 } 541 542 /** 543 * Size of local memory arena in bytes. <br> 544 * The minimum value is 16 KB. 545 */ 546 @InfoName("CL_DEVICE_LOCAL_MEM_SIZE") 547 public long getLocalMemSize() { 548 return infos.getIntOrLong(getEntity(), CL_DEVICE_LOCAL_MEM_SIZE); 549 } 550 551 /** 552 * Is CL_TRUE if the device implements error correction for the memories, caches, registers etc. in the device. <br> 553 * Is CL_FALSE if the device does not implement error correction. <br> 554 * This can be a requirement for certain clients of OpenCL. 555 */ 556 @InfoName("CL_DEVICE_ERROR_CORRECTION_SUPPORT") 557 public boolean hasErrorCorrectionSupport() { 558 return infos.getBool(getEntity(), CL_DEVICE_ERROR_CORRECTION_SUPPORT); 559 } 560 561 /** 562 * Maximum size of the internal buffer that holds the output of printf calls from a kernel. 563 * The minimum value for the FULL profile is 1 MB. 564 */ 565 @InfoName("CL_DEVICE_PRINTF_BUFFER_SIZE") 566 public long getPrintfBufferSize() { 567 return infos.getIntOrLong(getEntity(), CL_DEVICE_PRINTF_BUFFER_SIZE); 568 } 569 570 /** 571 * Is CL_TRUE if the device’s preference is for the user to be responsible for synchronization, when sharing memory objects between OpenCL and other APIs such as DirectX, CL_FALSE if the device / implementation has a performant path for performing synchronization of memory object shared between OpenCL and other APIs such as DirectX. 572 */ 573 @InfoName("CL_DEVICE_PREFERRED_INTEROP_USER_SYNC") 574 public boolean isPreferredInteropUserSync() { 575 return infos.getBool(getEntity(), CL_DEVICE_PREFERRED_INTEROP_USER_SYNC); 576 } 577 578 @InfoName("Out of order queues support") 579 public boolean hasOutOfOrderQueueSupport() { 580 CLContext context = getPlatform().createContext(null, this); 581 CLQueue queue = null; 582 try { 583 queue = createOutOfOrderQueue(context); 584 return true; 585 } catch (CLException ex) { 586 return false; 587 } finally { 588 if (queue != null) 589 queue.release(); 590 context.release(); 591 } 592 } 593 594 /** 595 * Describes the resolution of device timer. <br> 596 * This is measured in nanoseconds. <br> 597 * Refer to section 5.9 for details. 598 */ 599 @InfoName("CL_DEVICE_PROFILING_TIMER_RESOLUTION") 600 public long getProfilingTimerResolution() { 601 return infos.getIntOrLong(getEntity(), CL_DEVICE_PROFILING_TIMER_RESOLUTION); 602 } 603 604 /** 605 * Is CL_TRUE if the OpenCL device is a little endian device and CL_FALSE otherwise. 606 */ 607 @InfoName("CL_DEVICE_ENDIAN_LITTLE") 608 public boolean isEndianLittle() { 609 return infos.getBool(getEntity(), CL_DEVICE_ENDIAN_LITTLE); 610 } 611 612 /** 613 * Is CL_TRUE if the device is available and CL_FALSE if the device is not available. 614 */ 615 @InfoName("CL_DEVICE_AVAILABLE") 616 public boolean isAvailable() { 617 return infos.getBool(getEntity(), CL_DEVICE_AVAILABLE); 618 } 619 620 /** 621 * Is CL_FALSE if the implementation does not have a compiler available to compile the program source. <br> 622 * Is CL_TRUE if the compiler is available.<br> 623 * This can be CL_FALSE for the embededed platform profile only. 624 */ 625 @InfoName("CL_DEVICE_COMPILER_AVAILABLE") 626 public boolean isCompilerAvailable() { 627 return infos.getBool(getEntity(), CL_DEVICE_COMPILER_AVAILABLE); 628 } 629 630 /** 631 Device name string. 632 */ 633 @InfoName("CL_DEVICE_NAME") 634 public String getName() { 635 return infos.getString(getEntity(), CL_DEVICE_NAME); 636 } 637 638 /** 639 * OpenCL C version string. <br> 640 * Returns the highest OpenCL C version supported by the compiler for this device. <br> 641 * This version string has the following format:<br> 642 * OpenCL<space>C<space><major_version.minor_version><space><vendor-specific information><br> 643 * The major_version.minor_version value returned must be 1.1 if CL_DEVICE_VERSION is OpenCL 1.1.<br> 644 * The major_version.minor_version value returned can be 1.0 or 1.1 if CL_DEVICE_VERSION is OpenCL 1.0. <br> 645 * If OpenCL C 1.1 is returned, this implies that the language feature set defined in section 6 of the OpenCL 1.1 specification is supported by the OpenCL 1.0 device. 646 * @since OpenCL 1.1 647 */ 648 @InfoName("CL_DEVICE_OPENCL_C_VERSION") 649 public String getOpenCLCVersion() { 650 try { 651 return infos.getString(getEntity(), CL_DEVICE_OPENCL_C_VERSION); 652 } catch (Throwable th) { 653 // TODO throw if supposed to handle OpenCL 1.1 654 return "OpenCL C 1.0"; 655 } 656 } 657 /** 658 * @deprecated Legacy typo, use getOpenCLCVersion() instead. 659 */ 660 @Deprecated 661 public String getOpenCLVersion() { 662 return getOpenCLCVersion(); 663 } 664 665 /** 666 Vendor name string. 667 */ 668 @InfoName("CL_DEVICE_VENDOR") 669 public String getVendor() { 670 return infos.getString(getEntity(), CL_DEVICE_VENDOR); 671 } 672 673 /** 674 * Floating-point config of a device. 675 * The mandated minimum floating-point capability for devices that are not of type CL_DEVICE_TYPE_CUSTOM is: 676 * CL_FP_ROUND_TO_NEAREST | CL_FP_INF_NAN. 677 */ 678 public enum FpConfig implements com.nativelibs4java.util.ValuedEnum { 679 /** 680 * Denorms are supported. 681 */ 682 Denorm(CL_FP_DENORM), 683 /** 684 * INF and quiet NaNs are supported. 685 */ 686 InfNan(CL_FP_INF_NAN), 687 /** 688 * Round to nearest even rounding mode supported. 689 */ 690 RoundToNearest(CL_FP_ROUND_TO_NEAREST), 691 /** 692 * Round to zero rounding mode supported. 693 */ 694 RoundToZero(CL_FP_ROUND_TO_ZERO), 695 /** 696 * Round to positive and negative infinity rounding modes supported. 697 */ 698 RoundToInf(CL_FP_ROUND_TO_INF), 699 /** 700 * IEEE754-2008 fused multiply- add is supported. 701 */ 702 FMA(CL_FP_FMA), 703 /** 704 * Divide and sqrt are correctly rounded as defined by the IEEE754 specification. 705 */ 706 CorrectlyRoundedDivideSqrt(CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT), 707 /** 708 * Basic floating-point operations (such as addition, subtraction, multiplication). 709 * are implemented in software. 710 */ 711 SoftFloat(CL_FP_SOFT_FLOAT); 712 713 FpConfig(long value) { this.value = value; } 714 long value; 715 @Override 716 public long value() { return value; } 717 public static long getValue(EnumSet<FpConfig> set) { 718 return EnumValues.getValue(set); 719 } 720 721 public static EnumSet<FpConfig> getEnumSet(long v) { 722 return EnumValues.getEnumSet(v, FpConfig.class); 723 } 724 } 725 726 727 /** 728 OpenCL software driver version string in the form major_number.minor_number. 729 */ 730 @InfoName("CL_DRIVER_VERSION") 731 public String getDriverVersion() { 732 return infos.getString(getEntity(), CL_DRIVER_VERSION); 733 } 734 735 /** TODO */ 736 @InfoName("CL_DEVICE_IMAGE_MAX_ARRAY_SIZE") 737 public long getImageMaxArraySize() { 738 return infos.getIntOrLong(getEntity(), CL_DEVICE_IMAGE_MAX_ARRAY_SIZE); 739 } 740 741 /** TODO */ 742 @InfoName("CL_DEVICE_IMAGE_MAX_BUFFER_SIZE") 743 public long getImageMaxBufferSize() { 744 return infos.getIntOrLong(getEntity(), CL_DEVICE_IMAGE_MAX_BUFFER_SIZE); 745 } 746 747 /** TODO */ 748 @InfoName("CL_DEVICE_DOUBLE_FP_CONFIG") 749 public EnumSet<FpConfig> getDoubleFpConfig() { 750 return isDoubleSupported() ? FpConfig.getEnumSet(infos.getIntOrLong(getEntity(), CL_DEVICE_DOUBLE_FP_CONFIG)) : EnumSet.noneOf(FpConfig.class); 751 } 752 753 /** TODO */ 754 @InfoName("CL_DEVICE_HALF_FP_CONFIG") 755 public EnumSet<FpConfig> getHalfFpConfig() { 756 return isHalfSupported() ? FpConfig.getEnumSet(infos.getIntOrLong(getEntity(), CL_DEVICE_HALF_FP_CONFIG)) : EnumSet.noneOf(FpConfig.class); 757 } 758 759 /** TODO */ 760 @InfoName("CL_DEVICE_LINKER_AVAILABLE") 761 public boolean isLinkerAvailable() { 762 return infos.getBool(getEntity(), CL_DEVICE_LINKER_AVAILABLE); 763 } 764 765 /** TODO */ 766 @InfoName("CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF") 767 public long getNativeVectorWidthHalf() { 768 return infos.getIntOrLong(getEntity(), CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF); 769 } 770 771 /** Device partition types. */ 772 public enum PartitionType implements com.nativelibs4java.util.ValuedEnum { 773 Equally(CL_DEVICE_PARTITION_EQUALLY), 774 ByCounts(CL_DEVICE_PARTITION_BY_COUNTS), 775 ByAffinityDomain(CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN); 776 777 PartitionType(long value) { this.value = value; } 778 long value; 779 @Override 780 public long value() { return value; } 781 public static long getValue(EnumSet<PartitionType> set) { 782 return EnumValues.getValue(set); 783 } 784 785 public static EnumSet<PartitionType> getEnumSet(long v) { 786 return EnumValues.getEnumSet(v, PartitionType.class); 787 } 788 } 789 790 /** TODO */ 791 @InfoName("CL_DEVICE_PARTITION_PROPERTIES") 792 public EnumSet<PartitionType> getPartitionProperties() { 793 return PartitionType.getEnumSet(infos.getIntOrLong(getEntity(), CL_DEVICE_PARTITION_PROPERTIES)); 794 } 795 796 /** TODO */ 797 @InfoName("CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF") 798 public long getPreferredVectorWidthHalf() { 799 return infos.getIntOrLong(getEntity(), CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF); 800 } 801 802 /** TODO */ 803 @InfoName("CL_DEVICE_REFERENCE_COUNT") 804 public long getReferenceCount() { 805 return infos.getIntOrLong(getEntity(), CL_DEVICE_REFERENCE_COUNT); 806 } 807 808 /** 809 * Affinity domain specified in {@link #createSubDevicesByAffinity(AffinityDomain)}, or null if the device is not a sub-device or wasn't split by affinity. 810 * This returns part of CL_DEVICE_PARTITION_TYPE. 811 */ 812 public AffinityDomain getPartitionAffinityDomain() { 813 Pointer<?> memory = infos.getMemory(getEntity(), CL_DEVICE_PARTITION_TYPE); 814 long type = memory.getSizeT(); 815 if (type != CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN) { 816 return null; 817 } 818 AffinityDomain affinityDomain = AffinityDomain.getEnum(memory.getSizeTAtIndex(1)); 819 return affinityDomain; 820 } 821 822 823 /** 824 * Returns the cl_device_id of the parent device to which this sub-device belongs. If device is a root-level device, a NULL value is returned. 825 */ 826 public synchronized CLDevice getParent() { 827 if (!fetchedParent) { 828 Pointer ptr = infos.getPointer(getEntity(), CL_DEVICE_PARENT_DEVICE); 829 if (ptr != null) { 830 parent = new CLDevice(platform, null, getPeer(ptr), false); 831 } 832 fetchedParent = true; 833 } 834 return parent; 835 } 836 837 838 /** 839 * OpenCL profile string. <br> 840 * Returns the profile name supported by the device. <br> 841 * The profile name returned can be one of the following strings: 842 * <ul> 843 * <li>FULL_PROFILE if the device supports the OpenCL specification (functionality defined as part of the core specification and does not require any extensions to be supported).</li> 844 * <li>EMBEDDED_PROFILE if the device supports the OpenCL embedded profile.</li> 845 * </ul> 846 */ 847 @InfoName("CL_DEVICE_PROFILE") 848 public String getProfile() { 849 return infos.getString(getEntity(), CL_DEVICE_PROFILE); 850 } 851 852 /** 853 * Whether the device and the host have a unified memory subsystem. 854 * @since OpenCL 1.1 855 */ 856 @InfoName("CL_DEVICE_HOST_UNIFIED_MEMORY") 857 public boolean isHostUnifiedMemory() { 858 platform.requireMinVersionValue("CL_DEVICE_HOST_UNIFIED_MEMORY", 1.1); 859 return infos.getBool(getEntity(), CL_DEVICE_HOST_UNIFIED_MEMORY); 860 } 861 862 /** 863 * Preferred native vector width size for built-in scalar types that can be put into vectors. <br> 864 * The vector width is defined as the number of scalar elements that can be stored in the vector. <br> 865 * If the cl_khr_fp64 extension is not supported, CL_DEVICE_PREFERRED_VECTOR_WID TH_DOUBLE must return 0. 866 */ 867 @InfoName("CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR") 868 public int getPreferredVectorWidthChar() { 869 return infos.getInt(getEntity(), CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR); 870 } 871 872 /** 873 * Preferred native vector width size for built-in scalar types that can be put into vectors. <br> 874 * The vector width is defined as the number of scalar elements that can be stored in the vector. <br> 875 * If the cl_khr_fp64 extension is not supported, CL_DEVICE_PREFERRED_VECTOR_WID TH_DOUBLE must return 0. 876 */ 877 @InfoName("CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT") 878 public int getPreferredVectorWidthShort() { 879 return infos.getInt(getEntity(), CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT); 880 } 881 882 /** 883 * Preferred native vector width size for built-in scalar types that can be put into vectors. <br> 884 * The vector width is defined as the number of scalar elements that can be stored in the vector. <br> 885 * If the cl_khr_fp64 extension is not supported, CL_DEVICE_PREFERRED_VECTOR_WID TH_DOUBLE must return 0. 886 */ 887 @InfoName("CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT") 888 public int getPreferredVectorWidthInt() { 889 return infos.getInt(getEntity(), CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT); 890 } 891 892 /** 893 * Preferred native vector width size for built-in scalar types that can be put into vectors. <br> 894 * The vector width is defined as the number of scalar elements that can be stored in the vector. <br> 895 * If the cl_khr_fp64 extension is not supported, CL_DEVICE_PREFERRED_VECTOR_WID TH_DOUBLE must return 0. 896 */ 897 @InfoName("CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG") 898 public int getPreferredVectorWidthLong() { 899 return infos.getInt(getEntity(), CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG); 900 } 901 902 /** 903 * Preferred native vector width size for built-in scalar types that can be put into vectors. <br> 904 * The vector width is defined as the number of scalar elements that can be stored in the vector. <br> 905 * If the cl_khr_fp64 extension is not supported, CL_DEVICE_PREFERRED_VECTOR_WID TH_DOUBLE must return 0. 906 */ 907 @InfoName("CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT") 908 public int getPreferredVectorWidthFloat() { 909 return infos.getInt(getEntity(), CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT); 910 } 911 912 /** 913 * Preferred native vector width size for built-in scalar types that can be put into vectors. <br> 914 * The vector width is defined as the number of scalar elements that can be stored in the vector. <br> 915 * If the cl_khr_fp64 extension is not supported, CL_DEVICE_PREFERRED_VECTOR_WID TH_DOUBLE must return 0. 916 */ 917 @InfoName("CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE") 918 public int getPreferredVectorWidthDouble() { 919 return infos.getInt(getEntity(), CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE); 920 } 921 922 /** 923 * Returns the native ISA vector width. <br> 924 * The vector width is defined as the number of scalar elements that can be stored in the vector. <br> 925 * If the cl_khr_fp64 extension is not supported, CL_DEVICE_NATIVE_VECTOR_WID TH_DOUBLE must return 0. 926 */ 927 @InfoName("CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR") 928 public int getNativeVectorWidthChar() { 929 return infos.getOptionalFeatureInt(getEntity(), CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR); 930 } 931 932 /** 933 * Returns the native ISA vector width. <br> 934 * The vector width is defined as the number of scalar elements that can be stored in the vector. <br> 935 * If the cl_khr_fp64 extension is not supported, CL_DEVICE_NATIVE_VECTOR_WID TH_DOUBLE must return 0. 936 */ 937 @InfoName("CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT") 938 public int getNativeVectorWidthShort() { 939 return infos.getOptionalFeatureInt(getEntity(), CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT); 940 } 941 942 /** 943 * Returns the native ISA vector width. <br> 944 * The vector width is defined as the number of scalar elements that can be stored in the vector. <br> 945 * If the cl_khr_fp64 extension is not supported, CL_DEVICE_NATIVE_VECTOR_WID TH_DOUBLE must return 0. 946 */ 947 @InfoName("CL_DEVICE_NATIVE_VECTOR_WIDTH_INT") 948 public int getNativeVectorWidthInt() { 949 return infos.getOptionalFeatureInt(getEntity(), CL_DEVICE_NATIVE_VECTOR_WIDTH_INT); 950 } 951 952 /** 953 * Returns the native ISA vector width. <br> 954 * The vector width is defined as the number of scalar elements that can be stored in the vector. <br> 955 * If the cl_khr_fp64 extension is not supported, CL_DEVICE_NATIVE_VECTOR_WID TH_DOUBLE must return 0. 956 */ 957 @InfoName("CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG") 958 public int getNativeVectorWidthLong() { 959 return infos.getOptionalFeatureInt(getEntity(), CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG); 960 } 961 962 /** 963 * Returns the native ISA vector width. <br> 964 * The vector width is defined as the number of scalar elements that can be stored in the vector. <br> 965 * If the cl_khr_fp64 extension is not supported, CL_DEVICE_NATIVE_VECTOR_WID TH_DOUBLE must return 0. 966 */ 967 @InfoName("CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT") 968 public int getNativeVectorWidthFloat() { 969 return infos.getOptionalFeatureInt(getEntity(), CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT); 970 } 971 972 /** 973 * Returns the native ISA vector width. <br> 974 * The vector width is defined as the number of scalar elements that can be stored in the vector. <br> 975 * If the cl_khr_fp64 extension is not supported, CL_DEVICE_NATIVE_VECTOR_WID TH_DOUBLE must return 0. 976 */ 977 @InfoName("CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE") 978 public int getNativeVectorWidthDouble() { 979 return infos.getOptionalFeatureInt(getEntity(), CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE); 980 } 981 982 /** 983 * OpenCL version string. <br> 984 * Returns the OpenCL version supported by the device.<br> 985 * This version string has the following format: 986 * <code> 987 * OpenCL<space><major_version.min or_version><space><vendor-specific information> 988 * </code> 989 * The major_version.minor_version value returned will be 1.0. 990 */ 991 @InfoName("CL_DEVICE_VERSION") 992 public String getVersion() { 993 return infos.getString(getEntity(), CL_DEVICE_VERSION); 994 } 995 996 /** 997 * List of extension names supported by the device. 998 * The list of extension names returned can be vendor supported extension names and one or more of the following Khronos approved extension names: 999 * - cl_khr_int64_base_atomics 1000 * - cl_khr_int64_extended_atomics 1001 * - cl_khr_fp16 1002 * - cl_khr_gl_sharing 1003 * - cl_khr_gl_event 1004 * - cl_khr_d3d10_sharing 1005 * - cl_khr_dx9_media_sharing 1006 * - cl_khr_d3d11_sharing 1007 * 1008 * The following approved Khronos extension names must be returned by all device that support OpenCL C 1.2: 1009 * - cl_khr_global_int32_base_atomics 1010 * - cl_khr_global_int32_extended_atomics 1011 * - cl_khr_local_int32_base_atomics 1012 * - cl_khr_local_int32_extended_atomics 1013 * - cl_khr_byte_addressable_store 1014 * - cl_khr_fp64 (for backward compatibility if double precision is supported) 1015 * Please refer to the OpenCL 1.2 Extension Specification for a detailed description of these extensions. 1016 */ 1017 @InfoName("CL_DEVICE_EXTENSIONS") 1018 public String[] getExtensions() { 1019 if (extensions == null) { 1020 extensions = new LinkedHashSet<String>(Arrays.asList(infos.getString(getEntity(), CL_DEVICE_EXTENSIONS).split("\\s+"))); 1021 } 1022 return extensions.toArray(new String[extensions.size()]); 1023 } 1024 private Set<String> extensions; 1025 1026 public boolean hasExtension(String name) { 1027 getExtensions(); 1028 return extensions.contains(name.trim()); 1029 } 1030 1031 /** 1032 * List of built-in kernels supported by the device. 1033 */ 1034 @InfoName("CL_DEVICE_BUILT_IN_KERNELS") 1035 public String[] getBuiltInKernels() { 1036 if (buildInKernels == null) { 1037 buildInKernels = new LinkedHashSet<String>(Arrays.asList(infos.getString(getEntity(), CL_DEVICE_BUILT_IN_KERNELS).split(";"))); 1038 } 1039 return buildInKernels.toArray(new String[buildInKernels.size()]); 1040 } 1041 private Set<String> buildInKernels; 1042 1043 /** 1044 * Whether this device support any double-precision number extension (<a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/cl_khr_fp64.html">cl_khr_fp64</a> or <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/cl_amd_fp64.html">cl_amd_fp64</a>) 1045 */ 1046 public boolean isDoubleSupported() { 1047 return isDoubleSupportedKHR() || isDoubleSupportedAMD(); 1048 } 1049 1050 /** 1051 * Whether this device support the <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/cl_khr_fp64.html">cl_khr_fp64</a> double-precision number extension 1052 */ 1053 public boolean isDoubleSupportedKHR() { 1054 return hasExtension("cl_khr_fp64"); 1055 } 1056 1057 /** 1058 * Whether this device supports the <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/cl_amd_fp64.html">cl_amd_fp64</a> double-precision number extension 1059 */ 1060 public boolean isDoubleSupportedAMD() { 1061 return hasExtension("cl_amd_fp64"); 1062 } 1063 1064 /** 1065 * If this device supports the extension cl_amd_fp64 but not cl_khr_fp64, replace any OpenCL source code pragma of the style <code>#pragma OPENCL EXTENSION cl_khr_fp64 : enable</code> by <code>#pragma OPENCL EXTENSION cl_amd_fp64 : enable</code>.<br> 1066 * Also works the other way around (if the KHR extension is available but the source code refers to the AMD extension).<br> 1067 * This method is called automatically by CLProgram unless the javacl.adjustDoubleExtension property is set to false or the JAVACL_ADJUST_DOUBLE_EXTENSION is set to 0. 1068 */ 1069 public String replaceDoubleExtensionByExtensionActuallyAvailable(String kernelSource) { 1070 boolean hasKHR = isDoubleSupportedKHR(), hasAMD = isDoubleSupportedAMD(); 1071 if (hasAMD && !hasKHR) 1072 kernelSource = kernelSource.replaceAll("#pragma\\s+OPENCL\\s+EXTENSION\\s+cl_khr_fp64\\s*:\\s*enable", "#pragma OPENCL EXTENSION cl_amd_fp64 : enable"); 1073 else if (!hasAMD && hasKHR) 1074 kernelSource = kernelSource.replaceAll("#pragma\\s+OPENCL\\s+EXTENSION\\s+cl_amd_fp64\\s*:\\s*enable", "#pragma OPENCL EXTENSION cl_khr_fp64 : enable"); 1075 return kernelSource; 1076 } 1077 1078 /** 1079 * Whether this device supports the <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/cl_khr_fp16.html">cl_khr_fp16 extension</a>. 1080 */ 1081 public boolean isHalfSupported() { 1082 return hasExtension("cl_khr_fp16"); 1083 } 1084 1085 /** 1086 * Whether this device supports the <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/cl_khr_byte_addressable_store.html">cl_khr_byte_addressable_store extension</a>. 1087 */ 1088 public boolean isByteAddressableStoreSupported() { 1089 return hasExtension("cl_khr_byte_addressable_store"); 1090 } 1091 1092 /** 1093 * Whether this device supports any OpenGL sharing extension (<a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/cl_khr_gl_sharing.html">cl_khr_gl_sharing</a> or <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/cl_APPLE_gl_sharing.html">cl_APPLE_gl_sharing</a>) 1094 */ 1095 public boolean isGLSharingSupported() { 1096 return hasExtension("cl_khr_gl_sharing") || hasExtension("cl_APPLE_gl_sharing"); 1097 } 1098 /** 1099 * Whether this device supports the <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/cl_khr_global_int32_base_atomics.html">cl_khr_global_int32_base_atomics extension</a>. 1100 */ 1101 public boolean isGlobalInt32BaseAtomicsSupported() { 1102 return hasExtension("cl_khr_global_int32_base_atomics"); 1103 } 1104 /** 1105 * Whether this device supports the <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/cl_khr_global_int32_extended_atomics.html">cl_khr_global_int32_extended_atomics extension</a>. 1106 */ 1107 public boolean isGlobalInt32ExtendedAtomicsSupported() { 1108 return hasExtension("cl_khr_global_int32_extended_atomics"); 1109 } 1110 /** 1111 * Whether this device supports the <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/cl_khr_local_int32_base_atomics.html">cl_khr_local_int32_base_atomics extension</a>. 1112 */ 1113 public boolean isLocalInt32BaseAtomicsSupported() { 1114 return hasExtension("cl_khr_local_int32_base_atomics"); 1115 } 1116 /** 1117 * Whether this device supports the <a href="http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/cl_khr_local_int32_extended_atomics.html">cl_khr_local_int32_extended_atomics extension</a>. 1118 */ 1119 public boolean isLocalInt32ExtendedAtomicsSupported() { 1120 return hasExtension("cl_khr_local_int32_extended_atomics"); 1121 } 1122 1123 /** Bit values for CL_DEVICE_QUEUE_PROPERTIES */ 1124 public static enum QueueProperties implements com.nativelibs4java.util.ValuedEnum { 1125 1126 OutOfOrderExecModeEnable(CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE), 1127 ProfilingEnable(CL_QUEUE_PROFILING_ENABLE); 1128 1129 QueueProperties(long value) { this.value = value; } 1130 long value; 1131 @Override 1132 public long value() { return value; } 1133 1134 public static long getValue(EnumSet<QueueProperties> set) { 1135 return EnumValues.getValue(set); 1136 } 1137 1138 public static EnumSet<QueueProperties> getEnumSet(long v) { 1139 return EnumValues.getEnumSet(v, QueueProperties.class); 1140 } 1141 } 1142 1143 /** 1144 * Describes the command-queue properties supported by the device.<br> 1145 * These properties are described in table 5.1.<br> 1146 * The mandated minimum capability is: ProfilingEnable. 1147 */ 1148 @InfoName("CL_DEVICE_QUEUE_PROPERTIES") 1149 public EnumSet<QueueProperties> getQueueProperties() { 1150 return QueueProperties.getEnumSet(infos.getIntOrLong(getEntity(), CL_DEVICE_QUEUE_PROPERTIES)); 1151 } 1152 1153 /** Enums values for cl_device_affinity_domain */ 1154 public enum AffinityDomain implements com.nativelibs4java.util.ValuedEnum { 1155 /** Split the device into sub-devices comprised of compute units that share a NUMA node. */ 1156 NUMA(CL_DEVICE_AFFINITY_DOMAIN_NUMA), 1157 /** Split the device into sub-devices comprised of compute units that share a level 4 data cache. */ 1158 L4Cache(CL_DEVICE_AFFINITY_DOMAIN_L4_CACHE), 1159 /** Split the device into sub-devices comprised of compute units that share a level 3 data cache. */ 1160 L3Cache(CL_DEVICE_AFFINITY_DOMAIN_L3_CACHE), 1161 /** Split the device into sub-devices comprised of compute units that share a level 2 data cache. */ 1162 L2Cache(CL_DEVICE_AFFINITY_DOMAIN_L2_CACHE), 1163 /** Split the device into sub-devices comprised of compute units that share a level 1 data cache. */ 1164 L1Cache(CL_DEVICE_AFFINITY_DOMAIN_L1_CACHE), 1165 /** 1166 * Split the device along the next partitionable affinity domain. The implementation shall finde 1167 * first level along which the device or sub-device may be further subdivided in the order NUMA, 1168 * L4, L3, L2, L1, and partition the device into sub-devices comprised of compute units that share 1169 * memory subsystems at this level. 1170 */ 1171 NextPartitionable(CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE); 1172 1173 AffinityDomain(long value) { this.value = value; } 1174 long value; 1175 @Override 1176 public long value() { return value; } 1177 1178 public static AffinityDomain getEnum(long v) { 1179 return EnumValues.getEnum(v, AffinityDomain.class); 1180 } 1181 } 1182 1183 /** 1184 * Creates an array of sub-devices that each reference a non-intersecting set of compute units within this device. 1185 * Split the aggregate device into as many smaller aggregate devices as can be created, each containing n compute units. The value n is passed as the value accompanying this property. If n does not divide evenly into CL_DEVICE_PARTITION_MAX_COMPUTE_UNITS, then the remaining compute units are not used. 1186 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateSubDevices.html">clCreateSubDevices</a>.<br> 1187 * @param computeUnitsForEverySubDevice Count of compute units for every subdevice. 1188 */ 1189 public CLDevice[] createSubDevicesEqually(int computeUnitsForEverySubDevice) { 1190 return createSubDevices(pointerToSizeTs( 1191 CL_DEVICE_PARTITION_EQUALLY, computeUnitsForEverySubDevice, 0, 0 1192 )); 1193 } 1194 1195 /** 1196 * Creates an array of sub-devices that each reference a non-intersecting set of compute units within this device. 1197 * For each nonzero count m in the list, a sub-device is created with m compute units in it. 1198 * The number of non-zero count entries in the list may not exceed CL_DEVICE_PARTITION_MAX_SUB_DEVICES. 1199 * The total number of compute units specified may not exceed CL_DEVICE_PARTITION_MAX_COMPUTE_UNITS. 1200 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateSubDevices.html">clCreateSubDevices</a>.<br> 1201 * @param computeUnitsForEachSubDevice List of counts of compute units for each subdevice. 1202 */ 1203 public CLDevice[] createSubDevicesByCounts(long... computeUnitsForEachSubDevice) { 1204 Pointer<SizeT> pProperties = allocateSizeTs(1 + computeUnitsForEachSubDevice.length + 1 + 1); 1205 int i = 0; 1206 pProperties.setSizeTAtIndex(i++, CL_DEVICE_PARTITION_BY_COUNTS); 1207 for (long count : computeUnitsForEachSubDevice) { 1208 pProperties.setSizeTAtIndex(i++, count); 1209 } 1210 pProperties.setSizeTAtIndex(i++, CL_DEVICE_PARTITION_BY_COUNTS_LIST_END); 1211 return createSubDevices(pProperties); 1212 } 1213 1214 /** 1215 * Creates an array of sub-devices that each reference a non-intersecting set of compute units within this device. 1216 * Split the device into smaller aggregate devices containing one or more compute units that all share part of a cache hierarchy. 1217 * The user may determine what happened by calling clGetDeviceInfo (CL_DEVICE_PARTITION_TYPE) on the sub-devices. 1218 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateSubDevices.html">clCreateSubDevices</a>.<br> 1219 * @param affinityDomain Affinity domain along which devices should be split. 1220 */ 1221 public CLDevice[] createSubDevicesByAffinity(AffinityDomain affinityDomain) { 1222 return createSubDevices(pointerToSizeTs( 1223 CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN, affinityDomain.value(), 0, 0 1224 )); 1225 } 1226 1227 /** 1228 * Creates an array of sub-devices that each reference a non-intersecting set of compute units within this device. 1229 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateSubDevices.html">clCreateSubDevices</a>.<br> 1230 * @param eventsToWaitFor Events that need to complete before this particular command can be executed. Special value {@link CLEvent#FIRE_AND_FORGET} can be used to avoid returning a CLEvent. 1231 * @return Event object that identifies this command and can be used to query or queue a wait for the command to complete, or null if eventsToWaitFor contains {@link CLEvent#FIRE_AND_FORGET}. 1232 */ 1233 CLDevice[] createSubDevices(Pointer<SizeT> pProperties) { 1234 platform.requireMinVersionValue("clCreateSubDevices", 1.2); 1235 1236 ReusablePointers ptrs = ReusablePointers.get(); 1237 Pointer<Integer> pNum = ptrs.int1; 1238 error(CL.clCreateSubDevices(getEntity(), getPeer(pProperties), 0, 0, getPeer(pNum))); 1239 int num = pNum.getInt(); 1240 1241 Pointer<SizeT> pDevices = allocateSizeTs(num); 1242 error(CL.clCreateSubDevices(getEntity(), getPeer(pProperties), num, getPeer(pDevices), 0)); 1243 CLDevice[] devices = new CLDevice[(int) num]; 1244 for (int i = 0; i < num; i++) { 1245 devices[i] = new CLDevice(platform, this, pDevices.getSizeTAtIndex(i), true); 1246 } 1247 pDevices.release(); 1248 return devices; 1249 } 1250 1251 /** 1252 * Calls <a href="http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clEnqueueMigrateMemObjects.html">clEnqueueMigrateMemObjects</a>.<br> 1253 * @param queue 1254 * @param eventsToWaitFor Events that need to complete before this particular command can be executed. Special value {@link CLEvent#FIRE_AND_FORGET} can be used to avoid returning a CLEvent. 1255 * @return Event object that identifies this command and can be used to query or queue a wait for the command to complete, or null if eventsToWaitFor contains {@link CLEvent#FIRE_AND_FORGET}. 1256 */ 1257 /* 1258 public CLEvent enqueueMigrateMemObjects(CLQueue queue, CLEvent... eventsToWaitFor) { 1259 context.getPlatform().requireMinVersionValue("clEnqueueMigrateMemObjects", 1.2); 1260 ReusablePointers ptrs = ReusablePointers.get(); 1261 int[] eventsInCount = ptrs.int1Array; 1262 Pointer<cl_event> eventsIn = 1263 CLAbstractEntity.copyNonNullEntities(eventsToWaitFor, eventsInCount, ptrs.events_in); 1264 Pointer<cl_event> eventOut = 1265 eventsToWaitFor == null || CLEvent.containsFireAndForget(eventsToWaitFor) 1266 ? null 1267 : ptrs.event_out; 1268 error(CL.clEnqueueMigrateMemObjects(queue.getEntity(), getEntity(), eventsInCount[0], getPeer(eventsIn) , getPeer(eventOut) )); 1269 return CLEvent.createEventFromPointer(queue, eventOut) ; } 1270 */ 1271}