Path: blob/master/jcl/src/openj9.cuda/share/classes/com/ibm/cuda/CudaLinker.java
12927 views
/*[INCLUDE-IF Sidecar18-SE]*/1/*******************************************************************************2* Copyright (c) 2013, 2018 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 java.io.IOException;25import java.io.InputStream;26import java.util.concurrent.atomic.AtomicLong;2728import com.ibm.cuda.internal.CudaUtil;2930/**31* The {@code CudaLinker} class supports combining one or more code fragments32* to form a module that can be then loaded on a CUDA-capable device.33* <p>34* When no longer required, a linker must be destroyed (see {@link #destroy()}).35*/36public final class CudaLinker {3738private static native void add(int deviceId, long linkStateHandle,39int inputType, byte[] data, String name, long optionsHandle)40throws CudaException;4142private static native byte[] complete(int deviceId, long linkStateHandle)43throws CudaException;4445private static native long create(int deviceId, long optionsHandle)46throws CudaException;4748private static native void destroy(int deviceId, long linkStateHandle)49throws CudaException;5051private final CudaJitOptions createOptions;5253private final int deviceId;5455private final AtomicLong nativeHandle;5657/**58* Creates a new linker for the specified {@code device}59* using default options.60*61* @param device62* the device on which the resulting module is to be loaded63* @throws CudaException64* if a CUDA exception occurs65*/66public CudaLinker(CudaDevice device) throws CudaException {67this(device, null);68}6970/**71* Creates a new linker for the specified {@code device}72* using the specified {@code options}.73*74* @param device75* the device on which the resulting module is to be loaded76* @param options77* the desired options, or null for the default options78* @throws CudaException79* if a CUDA exception occurs80*/81public CudaLinker(CudaDevice device, CudaJitOptions options)82throws CudaException {83super();84this.createOptions = options;85this.deviceId = device.getDeviceId();86this.nativeHandle = new AtomicLong( // <br/>87create(deviceId, options == null ? 0 : options.getHandle()));88}8990/**91* Adds a new code fragment to be linked into the module under construction92* using the default options.93*94* @param type95* the type of input data96* @param data97* the content of the new code fragment98* @param name99* the name to be used in log messages in reference to this code fragment100* @return101* this linker object102* @throws CudaException103* if a CUDA exception occurs104* @throws IllegalStateException105* if this linker has been destroyed (see {@link #destroy()})106*/107public CudaLinker add(CudaJitInputType type, byte[] data, String name)108throws CudaException {109return add(type, data, name, null);110}111112/**113* Adds a new code fragment to be linked into the module under construction114* using the specified options.115*116* @param type117* the type of input data118* @param data119* the content of the new code fragment120* @param name121* the name to be used in log messages in reference to this code fragment122* @param options123* the desired options124* @return125* this linker object126* @throws CudaException127* if a CUDA exception occurs128* @throws IllegalStateException129* if this linker has been destroyed (see {@link #destroy()})130*/131public CudaLinker add(CudaJitInputType type, byte[] data, String name,132CudaJitOptions options) throws CudaException {133if (type == null) {134throw new NullPointerException();135}136137if (data == null) {138throw new NullPointerException();139}140141long handle = getHandle();142143if (options == null) {144add(deviceId, handle, type.nativeValue, data, name, 0);145} else {146try {147add(deviceId, handle, type.nativeValue, data, name, options.getHandle());148} finally {149options.releaseHandle(true);150}151}152153if (createOptions != null) {154createOptions.update();155}156157return this;158}159160/**161* Adds a new code fragment to be linked into the module under construction162* using the default options.163*164* @param type165* the type of input data166* @param input167* the content of the new code fragment168* @param name169* the name to be used in log messages in reference to this code fragment170* @return171* this linker object172* @throws CudaException173* if a CUDA exception occurs174* @throws IllegalStateException175* if this linker has been destroyed (see {@link #destroy()})176* @throws IOException177* if an I/O error occurs reading {@code input}178*/179public CudaLinker add(CudaJitInputType type, InputStream input, String name)180throws CudaException, IOException {181return add(type, input, name, null);182}183184/**185* Adds a new code fragment to be linked into the module under construction186* using the default options.187*188* @param type189* the type of input data190* @param input191* the content of the new code fragment192* @param name193* the name to be used in log messages in reference to this code fragment194* @param options195* the desired options196* @return197* this linker object198* @throws CudaException199* if a CUDA exception occurs200* @throws IllegalStateException201* if this linker has been destroyed (see {@link #destroy()})202* @throws IOException203* if an I/O error occurs reading {@code input}204*/205public CudaLinker add(CudaJitInputType type, InputStream input,206String name, CudaJitOptions options) throws CudaException,207IOException {208return add(type, CudaUtil.read(input, true), name, options);209}210211/**212* Completes the module under construction and return an image suitable213* for loading.214*215* @return216* the image suitable for loading217* @throws CudaException218* if a CUDA exception occurs219* @throws IllegalStateException220* if this linker has been destroyed (see {@link #destroy()})221*/222public byte[] complete() throws CudaException {223return complete(deviceId, getHandle());224}225226/**227* Destroys this linker, releasing associated resources.228*229* @throws CudaException230* if a CUDA exception occurs231*/232public void destroy() throws CudaException {233long handle = nativeHandle.getAndSet(0);234235if (handle != 0) {236destroy(deviceId, handle);237}238239if (createOptions != null) {240createOptions.releaseHandle(false);241}242}243244/**245* Returns the contents of the error log.246* <p>247* The result will be empty unless this linker was created with options248* which specified a positive error log buffer size249* (see {@link CudaJitOptions#setErrorLogBufferSize(int)})250* and errors were reported.251*252* @return253* the contents of the error log254*/255public String getErrorLogBuffer() {256if (createOptions == null) {257return ""; //$NON-NLS-1$258} else {259return createOptions.getErrorLogBuffer();260}261}262263private long getHandle() {264long handle = nativeHandle.get();265266if (handle == 0) {267throw new IllegalStateException();268}269270return handle;271}272273/**274* Returns the contents of the information log.275* <p>276* The result will be empty unless this linker was created with options277* which specified a positive information log buffer size278* (see {@link CudaJitOptions#setInfoLogBufferSize(int)})279* and informational messages were reported.280*281* @return282* the contents of the information log283*/284public String getInfoLogBuffer() {285if (createOptions == null) {286return ""; //$NON-NLS-1$287} else {288return createOptions.getInfoLogBuffer();289}290}291292/**293* Answers the total elapsed time, in milliseconds,294* spent in the compiler and linker.295* <p>296* Applies to: compiler and linker.297*298* @return299* the total elapsed time, in milliseconds, spent in the compiler and linker300*/301public float getWallTime() {302if (createOptions == null) {303return 0.0f;304} else {305return createOptions.getWallTime();306}307}308}309310311