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/CudaLinker.java
12927 views
1
/*[INCLUDE-IF Sidecar18-SE]*/
2
/*******************************************************************************
3
* Copyright (c) 2013, 2018 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.concurrent.atomic.AtomicLong;
28
29
import com.ibm.cuda.internal.CudaUtil;
30
31
/**
32
* The {@code CudaLinker} class supports combining one or more code fragments
33
* to form a module that can be then loaded on a CUDA-capable device.
34
* <p>
35
* When no longer required, a linker must be destroyed (see {@link #destroy()}).
36
*/
37
public final class CudaLinker {
38
39
private static native void add(int deviceId, long linkStateHandle,
40
int inputType, byte[] data, String name, long optionsHandle)
41
throws CudaException;
42
43
private static native byte[] complete(int deviceId, long linkStateHandle)
44
throws CudaException;
45
46
private static native long create(int deviceId, long optionsHandle)
47
throws CudaException;
48
49
private static native void destroy(int deviceId, long linkStateHandle)
50
throws CudaException;
51
52
private final CudaJitOptions createOptions;
53
54
private final int deviceId;
55
56
private final AtomicLong nativeHandle;
57
58
/**
59
* Creates a new linker for the specified {@code device}
60
* using default options.
61
*
62
* @param device
63
* the device on which the resulting module is to be loaded
64
* @throws CudaException
65
* if a CUDA exception occurs
66
*/
67
public CudaLinker(CudaDevice device) throws CudaException {
68
this(device, null);
69
}
70
71
/**
72
* Creates a new linker for the specified {@code device}
73
* using the specified {@code options}.
74
*
75
* @param device
76
* the device on which the resulting module is to be loaded
77
* @param options
78
* the desired options, or null for the default options
79
* @throws CudaException
80
* if a CUDA exception occurs
81
*/
82
public CudaLinker(CudaDevice device, CudaJitOptions options)
83
throws CudaException {
84
super();
85
this.createOptions = options;
86
this.deviceId = device.getDeviceId();
87
this.nativeHandle = new AtomicLong( // <br/>
88
create(deviceId, options == null ? 0 : options.getHandle()));
89
}
90
91
/**
92
* Adds a new code fragment to be linked into the module under construction
93
* using the default options.
94
*
95
* @param type
96
* the type of input data
97
* @param data
98
* the content of the new code fragment
99
* @param name
100
* the name to be used in log messages in reference to this code fragment
101
* @return
102
* this linker object
103
* @throws CudaException
104
* if a CUDA exception occurs
105
* @throws IllegalStateException
106
* if this linker has been destroyed (see {@link #destroy()})
107
*/
108
public CudaLinker add(CudaJitInputType type, byte[] data, String name)
109
throws CudaException {
110
return add(type, data, name, null);
111
}
112
113
/**
114
* Adds a new code fragment to be linked into the module under construction
115
* using the specified options.
116
*
117
* @param type
118
* the type of input data
119
* @param data
120
* the content of the new code fragment
121
* @param name
122
* the name to be used in log messages in reference to this code fragment
123
* @param options
124
* the desired options
125
* @return
126
* this linker object
127
* @throws CudaException
128
* if a CUDA exception occurs
129
* @throws IllegalStateException
130
* if this linker has been destroyed (see {@link #destroy()})
131
*/
132
public CudaLinker add(CudaJitInputType type, byte[] data, String name,
133
CudaJitOptions options) throws CudaException {
134
if (type == null) {
135
throw new NullPointerException();
136
}
137
138
if (data == null) {
139
throw new NullPointerException();
140
}
141
142
long handle = getHandle();
143
144
if (options == null) {
145
add(deviceId, handle, type.nativeValue, data, name, 0);
146
} else {
147
try {
148
add(deviceId, handle, type.nativeValue, data, name, options.getHandle());
149
} finally {
150
options.releaseHandle(true);
151
}
152
}
153
154
if (createOptions != null) {
155
createOptions.update();
156
}
157
158
return this;
159
}
160
161
/**
162
* Adds a new code fragment to be linked into the module under construction
163
* using the default options.
164
*
165
* @param type
166
* the type of input data
167
* @param input
168
* the content of the new code fragment
169
* @param name
170
* the name to be used in log messages in reference to this code fragment
171
* @return
172
* this linker object
173
* @throws CudaException
174
* if a CUDA exception occurs
175
* @throws IllegalStateException
176
* if this linker has been destroyed (see {@link #destroy()})
177
* @throws IOException
178
* if an I/O error occurs reading {@code input}
179
*/
180
public CudaLinker add(CudaJitInputType type, InputStream input, String name)
181
throws CudaException, IOException {
182
return add(type, input, name, null);
183
}
184
185
/**
186
* Adds a new code fragment to be linked into the module under construction
187
* using the default options.
188
*
189
* @param type
190
* the type of input data
191
* @param input
192
* the content of the new code fragment
193
* @param name
194
* the name to be used in log messages in reference to this code fragment
195
* @param options
196
* the desired options
197
* @return
198
* this linker object
199
* @throws CudaException
200
* if a CUDA exception occurs
201
* @throws IllegalStateException
202
* if this linker has been destroyed (see {@link #destroy()})
203
* @throws IOException
204
* if an I/O error occurs reading {@code input}
205
*/
206
public CudaLinker add(CudaJitInputType type, InputStream input,
207
String name, CudaJitOptions options) throws CudaException,
208
IOException {
209
return add(type, CudaUtil.read(input, true), name, options);
210
}
211
212
/**
213
* Completes the module under construction and return an image suitable
214
* for loading.
215
*
216
* @return
217
* the image suitable for loading
218
* @throws CudaException
219
* if a CUDA exception occurs
220
* @throws IllegalStateException
221
* if this linker has been destroyed (see {@link #destroy()})
222
*/
223
public byte[] complete() throws CudaException {
224
return complete(deviceId, getHandle());
225
}
226
227
/**
228
* Destroys this linker, releasing associated resources.
229
*
230
* @throws CudaException
231
* if a CUDA exception occurs
232
*/
233
public void destroy() throws CudaException {
234
long handle = nativeHandle.getAndSet(0);
235
236
if (handle != 0) {
237
destroy(deviceId, handle);
238
}
239
240
if (createOptions != null) {
241
createOptions.releaseHandle(false);
242
}
243
}
244
245
/**
246
* Returns the contents of the error log.
247
* <p>
248
* The result will be empty unless this linker was created with options
249
* which specified a positive error log buffer size
250
* (see {@link CudaJitOptions#setErrorLogBufferSize(int)})
251
* and errors were reported.
252
*
253
* @return
254
* the contents of the error log
255
*/
256
public String getErrorLogBuffer() {
257
if (createOptions == null) {
258
return ""; //$NON-NLS-1$
259
} else {
260
return createOptions.getErrorLogBuffer();
261
}
262
}
263
264
private long getHandle() {
265
long handle = nativeHandle.get();
266
267
if (handle == 0) {
268
throw new IllegalStateException();
269
}
270
271
return handle;
272
}
273
274
/**
275
* Returns the contents of the information log.
276
* <p>
277
* The result will be empty unless this linker was created with options
278
* which specified a positive information log buffer size
279
* (see {@link CudaJitOptions#setInfoLogBufferSize(int)})
280
* and informational messages were reported.
281
*
282
* @return
283
* the contents of the information log
284
*/
285
public String getInfoLogBuffer() {
286
if (createOptions == null) {
287
return ""; //$NON-NLS-1$
288
} else {
289
return createOptions.getInfoLogBuffer();
290
}
291
}
292
293
/**
294
* Answers the total elapsed time, in milliseconds,
295
* spent in the compiler and linker.
296
* <p>
297
* Applies to: compiler and linker.
298
*
299
* @return
300
* the total elapsed time, in milliseconds, spent in the compiler and linker
301
*/
302
public float getWallTime() {
303
if (createOptions == null) {
304
return 0.0f;
305
} else {
306
return createOptions.getWallTime();
307
}
308
}
309
}
310
311