Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/jcl/src/openj9.cuda/share/classes/com/ibm/cuda/Cuda.java
12885 views
1
/*[INCLUDE-IF Sidecar18-SE]*/
2
/*******************************************************************************
3
* Copyright (c) 2013, 2021 IBM Corp. and others
4
*
5
* This program and the accompanying materials are made available under
6
* the terms of the Eclipse Public License 2.0 which accompanies this
7
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
8
* or the Apache License, Version 2.0 which accompanies this distribution and
9
* is available at https://www.apache.org/licenses/LICENSE-2.0.
10
*
11
* This Source Code may also be made available under the following
12
* Secondary Licenses when the conditions for such availability set
13
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
14
* General Public License, version 2 with the GNU Classpath
15
* Exception [1] and GNU General Public License, version 2 with the
16
* OpenJDK Assembly Exception [2].
17
*
18
* [1] https://www.gnu.org/software/classpath/license.html
19
* [2] http://openjdk.java.net/legal/assembly-exception.html
20
*
21
* 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-exception
22
*******************************************************************************/
23
package com.ibm.cuda;
24
25
import com.ibm.oti.vm.VM;
26
import java.lang.ref.ReferenceQueue;
27
import java.lang.ref.WeakReference;
28
import java.lang.reflect.Method;
29
import java.nio.ByteBuffer;
30
import java.nio.ByteOrder;
31
import java.security.AccessController;
32
import java.security.PrivilegedAction;
33
import java.util.Map;
34
import java.util.concurrent.ConcurrentHashMap;
35
36
/**
37
* The {@code Cuda} class provides general CUDA utilities.
38
*/
39
/*[IF JAVA_SPEC_VERSION >= 17]*/
40
@SuppressWarnings("removal")
41
/*[ENDIF] JAVA_SPEC_VERSION >= 17 */
42
public final class Cuda {
43
44
private static final class Cleaner implements Runnable {
45
46
static final Cleaner instance;
47
48
/**
49
* Counts the number of pinned buffers released by the cleaner thread
50
* (for use in junit tests).
51
*/
52
private static long releaseCount;
53
54
static {
55
instance = new Cleaner();
56
57
PrivilegedAction<Thread> createThread = () -> VM.getVMLangAccess().createThread(instance,
58
"CUDA pinned buffer cleaner", true, false, true, null); //$NON-NLS-1$
59
60
// we assert privilege to create the Thread
61
Thread daemon = AccessController.doPrivileged(createThread);
62
63
daemon.start();
64
}
65
66
private static native void releasePinnedBuffer(long address)
67
throws CudaException;
68
69
private final Map<Object, Long> inuse;
70
71
private final ReferenceQueue<Object> queue;
72
73
private Cleaner() {
74
super();
75
inuse = new ConcurrentHashMap<>();
76
queue = new ReferenceQueue<>();
77
}
78
79
ByteBuffer insert(ByteBuffer buffer, long address) {
80
inuse.put(new WeakReference<>(buffer, queue), Long.valueOf(address));
81
82
return buffer;
83
}
84
85
@Override
86
public void run() {
87
for (;;) {
88
try {
89
Long address = inuse.remove(queue.remove());
90
91
if (address != null) {
92
releasePinnedBuffer(address.longValue());
93
releaseCount = releaseCount + 1;
94
}
95
} catch (CudaException | InterruptedException e) {
96
// ignore
97
}
98
}
99
}
100
}
101
102
static {
103
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
104
System.loadLibrary("cuda4j29"); //$NON-NLS-1$
105
return null;
106
});
107
108
Method runMethod;
109
110
try {
111
runMethod = Runnable.class.getMethod("run"); //$NON-NLS-1$
112
} catch (NoSuchMethodException | SecurityException e) {
113
throw new RuntimeException(e);
114
}
115
116
int status = initialize(CudaException.class, runMethod);
117
118
if (status != CudaError.Success) {
119
throw new RuntimeException(getErrorMessage(status));
120
}
121
}
122
123
private static native long allocatePinnedBuffer(long byteCount)
124
throws CudaException;
125
126
/**
127
* Allocates a new direct byte buffer, backed by page-locked host memory;
128
* enabling optimal performance of transfers to and from device memory.
129
* <p>
130
* The position of the returned buffer will be zero; its limit and
131
* capacity will be {@code capacity}; its order will be
132
* {@link ByteOrder#LITTLE_ENDIAN LITTLE_ENDIAN}.
133
* <p>
134
* Notes:
135
* <ul>
136
* <li>The capacity of a ByteBuffer is in general limited to {@link Integer#MAX_VALUE}
137
* - that limit also applies and is enforced here.</li>
138
* <li>Even though the result is backed by host memory, a {@code CudaException}
139
* will be thrown if the driver is not installed because registration of that
140
* host memory with the driver is integral to the behavior of this method.</li>
141
* </ul>
142
*
143
* @param capacity
144
* the desired capacity, in bytes, of the buffer
145
* @return
146
* the new buffer
147
* @throws CudaException
148
* if a CUDA exception occurs
149
* @throws IllegalArgumentException
150
* if {@code capacity} is negative or larger than {@code Integer.MAX_VALUE}
151
*/
152
public static ByteBuffer allocatePinnedHostBuffer(long capacity)
153
throws CudaException {
154
if (0 <= capacity && capacity <= Integer.MAX_VALUE) {
155
long address = allocatePinnedBuffer(capacity);
156
ByteBuffer buffer = wrapDirectBuffer(address, capacity);
157
158
return Cleaner.instance // <br/>
159
.insert(buffer, address) // <br/>
160
.order(ByteOrder.LITTLE_ENDIAN);
161
}
162
163
throw new IllegalArgumentException(String.valueOf(capacity));
164
}
165
166
/**
167
* Returns the number of CUDA-capable devices available to the Java host.
168
*
169
* @return the number of available CUDA-capable devices
170
* @throws CudaException
171
* if a CUDA exception occurs
172
*/
173
public static native int getDeviceCount() throws CudaException;
174
175
/**
176
* Returns a number identifying the driver version.
177
* A {@code CudaException} will be thrown if the CUDA driver is not installed.
178
*
179
* @return
180
* the driver version number
181
* @throws CudaException
182
* if a CUDA exception occurs
183
*/
184
public static native int getDriverVersion() throws CudaException;
185
186
static native String getErrorMessage(int code);
187
188
/**
189
* Returns a number identifying the runtime version.
190
* A {@code CudaException} will be thrown if the CUDA driver is not installed.
191
*
192
* @return
193
* the runtime version number
194
* @throws CudaException
195
* if a CUDA exception occurs
196
*/
197
public static native int getRuntimeVersion() throws CudaException;
198
199
private static native int initialize(Class<CudaException> exceptionClass, Method runMethod);
200
201
static void loadNatives() {
202
return;
203
}
204
205
private static native ByteBuffer wrapDirectBuffer(long address, long capacity);
206
207
private Cuda() {
208
super();
209
}
210
211
}
212
213