Path: blob/master/jcl/src/openj9.cuda/share/classes/com/ibm/cuda/Cuda.java
12885 views
/*[INCLUDE-IF Sidecar18-SE]*/1/*******************************************************************************2* Copyright (c) 2013, 2021 IBM Corp. and others3*4* This program and the accompanying materials are made available under5* the terms of the Eclipse Public License 2.0 which accompanies this6* distribution and is available at https://www.eclipse.org/legal/epl-2.0/7* or the Apache License, Version 2.0 which accompanies this distribution and8* is available at https://www.apache.org/licenses/LICENSE-2.0.9*10* This Source Code may also be made available under the following11* Secondary Licenses when the conditions for such availability set12* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU13* General Public License, version 2 with the GNU Classpath14* Exception [1] and GNU General Public License, version 2 with the15* OpenJDK Assembly Exception [2].16*17* [1] https://www.gnu.org/software/classpath/license.html18* [2] http://openjdk.java.net/legal/assembly-exception.html19*20* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception21*******************************************************************************/22package com.ibm.cuda;2324import com.ibm.oti.vm.VM;25import java.lang.ref.ReferenceQueue;26import java.lang.ref.WeakReference;27import java.lang.reflect.Method;28import java.nio.ByteBuffer;29import java.nio.ByteOrder;30import java.security.AccessController;31import java.security.PrivilegedAction;32import java.util.Map;33import java.util.concurrent.ConcurrentHashMap;3435/**36* The {@code Cuda} class provides general CUDA utilities.37*/38/*[IF JAVA_SPEC_VERSION >= 17]*/39@SuppressWarnings("removal")40/*[ENDIF] JAVA_SPEC_VERSION >= 17 */41public final class Cuda {4243private static final class Cleaner implements Runnable {4445static final Cleaner instance;4647/**48* Counts the number of pinned buffers released by the cleaner thread49* (for use in junit tests).50*/51private static long releaseCount;5253static {54instance = new Cleaner();5556PrivilegedAction<Thread> createThread = () -> VM.getVMLangAccess().createThread(instance,57"CUDA pinned buffer cleaner", true, false, true, null); //$NON-NLS-1$5859// we assert privilege to create the Thread60Thread daemon = AccessController.doPrivileged(createThread);6162daemon.start();63}6465private static native void releasePinnedBuffer(long address)66throws CudaException;6768private final Map<Object, Long> inuse;6970private final ReferenceQueue<Object> queue;7172private Cleaner() {73super();74inuse = new ConcurrentHashMap<>();75queue = new ReferenceQueue<>();76}7778ByteBuffer insert(ByteBuffer buffer, long address) {79inuse.put(new WeakReference<>(buffer, queue), Long.valueOf(address));8081return buffer;82}8384@Override85public void run() {86for (;;) {87try {88Long address = inuse.remove(queue.remove());8990if (address != null) {91releasePinnedBuffer(address.longValue());92releaseCount = releaseCount + 1;93}94} catch (CudaException | InterruptedException e) {95// ignore96}97}98}99}100101static {102AccessController.doPrivileged((PrivilegedAction<Void>) () -> {103System.loadLibrary("cuda4j29"); //$NON-NLS-1$104return null;105});106107Method runMethod;108109try {110runMethod = Runnable.class.getMethod("run"); //$NON-NLS-1$111} catch (NoSuchMethodException | SecurityException e) {112throw new RuntimeException(e);113}114115int status = initialize(CudaException.class, runMethod);116117if (status != CudaError.Success) {118throw new RuntimeException(getErrorMessage(status));119}120}121122private static native long allocatePinnedBuffer(long byteCount)123throws CudaException;124125/**126* Allocates a new direct byte buffer, backed by page-locked host memory;127* enabling optimal performance of transfers to and from device memory.128* <p>129* The position of the returned buffer will be zero; its limit and130* capacity will be {@code capacity}; its order will be131* {@link ByteOrder#LITTLE_ENDIAN LITTLE_ENDIAN}.132* <p>133* Notes:134* <ul>135* <li>The capacity of a ByteBuffer is in general limited to {@link Integer#MAX_VALUE}136* - that limit also applies and is enforced here.</li>137* <li>Even though the result is backed by host memory, a {@code CudaException}138* will be thrown if the driver is not installed because registration of that139* host memory with the driver is integral to the behavior of this method.</li>140* </ul>141*142* @param capacity143* the desired capacity, in bytes, of the buffer144* @return145* the new buffer146* @throws CudaException147* if a CUDA exception occurs148* @throws IllegalArgumentException149* if {@code capacity} is negative or larger than {@code Integer.MAX_VALUE}150*/151public static ByteBuffer allocatePinnedHostBuffer(long capacity)152throws CudaException {153if (0 <= capacity && capacity <= Integer.MAX_VALUE) {154long address = allocatePinnedBuffer(capacity);155ByteBuffer buffer = wrapDirectBuffer(address, capacity);156157return Cleaner.instance // <br/>158.insert(buffer, address) // <br/>159.order(ByteOrder.LITTLE_ENDIAN);160}161162throw new IllegalArgumentException(String.valueOf(capacity));163}164165/**166* Returns the number of CUDA-capable devices available to the Java host.167*168* @return the number of available CUDA-capable devices169* @throws CudaException170* if a CUDA exception occurs171*/172public static native int getDeviceCount() throws CudaException;173174/**175* Returns a number identifying the driver version.176* A {@code CudaException} will be thrown if the CUDA driver is not installed.177*178* @return179* the driver version number180* @throws CudaException181* if a CUDA exception occurs182*/183public static native int getDriverVersion() throws CudaException;184185static native String getErrorMessage(int code);186187/**188* Returns a number identifying the runtime version.189* A {@code CudaException} will be thrown if the CUDA driver is not installed.190*191* @return192* the runtime version number193* @throws CudaException194* if a CUDA exception occurs195*/196public static native int getRuntimeVersion() throws CudaException;197198private static native int initialize(Class<CudaException> exceptionClass, Method runMethod);199200static void loadNatives() {201return;202}203204private static native ByteBuffer wrapDirectBuffer(long address, long capacity);205206private Cuda() {207super();208}209210}211212213