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/CudaModule.java
12917 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 java.io.IOException;
26
import java.io.InputStream;
27
import java.util.HashMap;
28
import java.util.Map;
29
import java.util.concurrent.atomic.AtomicLong;
30
31
import com.ibm.cuda.internal.CudaUtil;
32
33
/**
34
* The {@code CudaModule} class represents a module that has been loaded
35
* on a CUDA-capable device.
36
* <p>
37
* When no longer required, a module must be unloaded (see {@link #unload()}).
38
*/
39
public final class CudaModule {
40
41
/**
42
* The {@code Cache} class provides a simple mechanism to avoid reloading
43
* modules repeatedly. The set of loaded modules is specific to each device
44
* so two pieces of identification are required for each module: the device
45
* and a user-supplied key.
46
* <p>
47
* Note: Because this class is implemented with {@link HashMap}, keys
48
* must implement {@link #equals(Object)} and {@link #hashCode()}.
49
*/
50
public static final class Cache {
51
52
private final Map<Object, Map<CudaDevice, CudaModule>> store;
53
54
/**
55
* Creates a new cache.
56
*/
57
public Cache() {
58
super();
59
this.store = new HashMap<>(1);
60
}
61
62
/**
63
* Retrieves an existing module for the specified device and key.
64
*
65
* @param device
66
* the specified device
67
* @param key
68
* the specified key
69
* @return
70
* return the module associated with the given key on the
71
* specified device, or null if no such module exists
72
*/
73
public CudaModule get(CudaDevice device, Object key) {
74
Map<?, CudaModule> map = store.get(key);
75
76
return map == null ? null : map.get(device);
77
}
78
79
/**
80
* Stores a module in this cache, associating it with the given
81
* device and key.
82
*
83
* @param device
84
* the specified device
85
* @param key
86
* the specified key
87
* @param module
88
* the module to be stored
89
* @return
90
* the module previously associated with the given key on
91
* the specified device, or null if no such module exists
92
*/
93
public CudaModule put(CudaDevice device, Object key, CudaModule module) {
94
Map<CudaDevice, CudaModule> map = store.get(key);
95
96
if (map == null) {
97
store.put(key, map = new HashMap<>());
98
}
99
100
return map.put(device, module);
101
}
102
}
103
104
private static native long getFunction(int deviceId, long moduleHandle,
105
String name) throws CudaException;
106
107
private static native long getGlobal(int deviceId, long moduleHandle,
108
String name) throws CudaException;
109
110
private static native long getSurface(int deviceId, long moduleHandle,
111
String name) throws CudaException;
112
113
private static native long getTexture(int deviceId, long moduleHandle,
114
String name) throws CudaException;
115
116
private static native long load(int deviceId, byte[] image,
117
long optionsHandle) throws CudaException;
118
119
private static native void unload(int deviceId, long moduleHandle)
120
throws CudaException;
121
122
final int deviceId;
123
124
private final Map<String, CudaFunction> functions;
125
126
private final Map<String, CudaGlobal> globals;
127
128
private final AtomicLong nativeHandle;
129
130
private final Map<String, CudaSurface> surfaces;
131
132
private final Map<String, CudaTexture> textures;
133
134
/**
135
* Loads a module on the specified device, using the given image and the
136
* default options.
137
*
138
* @param device
139
* the specified device
140
* @param image
141
* the module image
142
* @throws CudaException
143
* if a CUDA exception occurs
144
* @throws SecurityException
145
* if a security manager exists and the calling thread
146
* does not have permission to load GPU modules
147
*/
148
public CudaModule(CudaDevice device, byte[] image) throws CudaException {
149
this(device, image, null);
150
}
151
152
/**
153
* Loads a module on the specified device, using the given image and the
154
* given options.
155
*
156
* @param device
157
* the specified device
158
* @param image
159
* the module image
160
* @param options
161
* the desired options
162
* @throws CudaException
163
* if a CUDA exception occurs
164
* @throws SecurityException
165
* if a security manager exists and the calling thread
166
* does not have permission to load GPU modules
167
*/
168
public CudaModule(CudaDevice device, byte[] image, CudaJitOptions options)
169
throws CudaException {
170
super();
171
172
@SuppressWarnings("removal")
173
SecurityManager security = System.getSecurityManager();
174
175
if (security != null) {
176
security.checkPermission(CudaPermission.LoadModule);
177
}
178
179
if (image == null) {
180
throw new NullPointerException();
181
}
182
183
this.deviceId = device.getDeviceId();
184
185
long optionsHandle = options == null ? 0 : options.getHandle();
186
187
try {
188
this.functions = new HashMap<>();
189
this.globals = new HashMap<>();
190
this.nativeHandle = new AtomicLong( // <br/>
191
load(this.deviceId, image, optionsHandle));
192
this.surfaces = new HashMap<>();
193
this.textures = new HashMap<>();
194
} finally {
195
if (options != null) {
196
options.releaseHandle(true);
197
}
198
}
199
}
200
201
/**
202
* Loads a module on the specified device from the given input stream using
203
* the default options.
204
*
205
* @param device
206
* the specified device
207
* @param input
208
* a stream containing the module image
209
* @throws CudaException
210
* if a CUDA exception occurs
211
* @throws IOException
212
* if an I/O error occurs reading {@code input}
213
* @throws SecurityException
214
* if a security manager exists and the calling thread
215
* does not have permission to load GPU modules
216
*/
217
public CudaModule(CudaDevice device, InputStream input)
218
throws CudaException, IOException {
219
this(device, input, null);
220
}
221
222
/**
223
* Loads a module on the specified device from the given input stream using
224
* the specified options.
225
*
226
* @param device
227
* the specified device
228
* @param input
229
* a stream containing the module image
230
* @param options
231
* the desired options
232
* @throws CudaException
233
* if a CUDA exception occurs
234
* @throws IOException
235
* if an I/O error occurs reading {@code input}
236
* @throws SecurityException
237
* if a security manager exists and the calling thread
238
* does not have permission to load GPU modules
239
*/
240
public CudaModule(CudaDevice device, InputStream input,
241
CudaJitOptions options) throws CudaException, IOException {
242
this(device, CudaUtil.read(input, true), options);
243
}
244
245
/**
246
* Returns the function of the specified name from this module.
247
*
248
* @param name
249
* the link-name of the desired function
250
* @return
251
* the function of the specified name
252
* @throws CudaException
253
* if a CUDA exception occurs
254
* @throws IllegalStateException
255
* if this module has been unloaded (see {@link #unload()})
256
*/
257
public CudaFunction getFunction(String name) throws CudaException {
258
CudaFunction function = functions.get(name);
259
260
if (function == null) {
261
long address = getFunction(deviceId, getHandle(), name);
262
263
functions.put(name, function = new CudaFunction(deviceId, address));
264
}
265
266
return function;
267
}
268
269
/**
270
* Returns the global variable of the specified name from this module.
271
*
272
* @param name
273
* the link-name of the desired global variable
274
* @return
275
* the global variable of the specified name
276
* @throws CudaException
277
* if a CUDA exception occurs
278
* @throws IllegalStateException
279
* if this module has been unloaded (see {@link #unload()})
280
*/
281
public CudaGlobal getGlobal(String name) throws CudaException {
282
CudaGlobal global = globals.get(name);
283
284
if (global == null) {
285
long address = getGlobal(deviceId, getHandle(), name);
286
287
globals.put(name, global = new CudaGlobal(address));
288
}
289
290
return global;
291
}
292
293
private long getHandle() {
294
long handle = nativeHandle.get();
295
296
if (handle == 0) {
297
throw new IllegalStateException();
298
}
299
300
return handle;
301
}
302
303
/**
304
* Returns the surface of the specified name from this module.
305
*
306
* @param name
307
* the link-name of the desired surface
308
* @return
309
* the surface of the specified name
310
* @throws CudaException
311
* if a CUDA exception occurs
312
* @throws IllegalStateException
313
* if this module has been unloaded (see {@link #unload()})
314
*/
315
public CudaSurface getSurface(String name) throws CudaException {
316
CudaSurface surface = surfaces.get(name);
317
318
if (surface == null) {
319
long address = getSurface(deviceId, getHandle(), name);
320
321
surfaces.put(name, surface = new CudaSurface(address));
322
}
323
324
return surface;
325
}
326
327
/**
328
* Returns the texture of the specified name from this module.
329
*
330
* @param name
331
* the link-name of the desired texture
332
* @return
333
* the texture of the specified name
334
* @throws CudaException
335
* if a CUDA exception occurs
336
* @throws IllegalStateException
337
* if this module has been unloaded (see {@link #unload()})
338
*/
339
public CudaTexture getTexture(String name) throws CudaException {
340
CudaTexture texture = textures.get(name);
341
342
if (texture == null) {
343
long address = getTexture(deviceId, getHandle(), name);
344
345
textures.put(name, texture = new CudaTexture(address));
346
}
347
348
return texture;
349
}
350
351
/**
352
* Unloads this module from the associated device.
353
* <p>
354
* Note that this has no effect on any {@link Cache caches}.
355
* @throws CudaException
356
* if a CUDA exception occurs
357
*/
358
public void unload() throws CudaException {
359
long handle = nativeHandle.getAndSet(0);
360
361
if (handle != 0) {
362
functions.clear();
363
globals.clear();
364
surfaces.clear();
365
textures.clear();
366
unload(deviceId, handle);
367
}
368
}
369
}
370
371