Path: blob/master/jcl/src/openj9.cuda/share/classes/com/ibm/cuda/CudaStream.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.util.Objects;25import java.util.concurrent.atomic.AtomicLong;2627/**28* The {@code CudaStream} class represents an independent queue of work for a29* specific {@link CudaDevice}.30* <p>31* When no longer required, a stream must be {@code close}d.32*/33public final class CudaStream implements AutoCloseable {3435/**36* Default stream creation flag.37*/38public static final int FLAG_DEFAULT = 0;3940/**41* Stream creation flag requesting no implicit synchronization with the42* default stream.43*/44public static final int FLAG_NON_BLOCKING = 1;4546private static native long create(int deviceId) throws CudaException;4748private static native long createWithPriority(int deviceId, int flags,49int priority) throws CudaException;5051private static native void destroy(int deviceId, long streamHandle)52throws CudaException;5354private static native int getFlags(int deviceId, long streamHandle)55throws CudaException;5657private static native int getPriority(int deviceId, long streamHandle)58throws CudaException;5960private static native int query(int deviceId, long streamHandle);6162private static native void synchronize(int deviceId, long streamHandle)63throws CudaException;6465private static native void waitFor(int deviceId, long streamHandle,66long eventHandle) throws CudaException;6768final int deviceId;6970private final AtomicLong nativeHandle;7172/**73* Creates a new stream on the specified device, with the default flags74* and the default priority.75*76* @param device77* the specified device78* @throws CudaException79* if a CUDA exception occurs80*/81public CudaStream(CudaDevice device) throws CudaException {82super();83this.deviceId = device.getDeviceId();84this.nativeHandle = new AtomicLong(create(this.deviceId));85}8687/**88* Creates a new stream on the specified device, with the specified flags89* and priority.90*91* @param device92* the specified device93* @param flags94* the desired flags95* @param priority96* the desired priority97* @throws CudaException98* if a CUDA exception occurs99*/100public CudaStream(CudaDevice device, int flags, int priority)101throws CudaException {102super();103this.deviceId = device.getDeviceId();104this.nativeHandle = new AtomicLong( // <br/>105createWithPriority(this.deviceId, flags, priority));106}107108/**109* Enqueues a callback to be run after all previous work on this stream110* has been completed.111* <p>112* Note that the callback will occur on a distinct thread. Further, any113* attempts to interact with CUDA devices will fail with a CudaException114* with code {@link CudaError#NotPermitted}.115*116* @param callback117* the runnable to be run118* @throws CudaException119* if a CUDA exception occurs120*/121public void addCallback(Runnable callback) throws CudaException {122Objects.requireNonNull(callback);123CudaDevice.addCallback(deviceId, getHandle(), callback);124}125126/**127* Closes this stream.128* Any work queued on this stream will be allowed to complete: this method129* does not wait for that work (if any) to complete.130* @throws CudaException131* if a CUDA exception occurs132*/133@Override134public void close() throws CudaException {135long handle = nativeHandle.getAndSet(0);136137if (handle != 0) {138destroy(deviceId, handle);139}140}141142/**143* Returns the flags of this stream.144* @return145* the flags of this stream146* @throws CudaException147* if a CUDA exception occurs148* @throws IllegalStateException149* if this stream has been closed (see {@link #close()})150*/151public int getFlags() throws CudaException {152return getFlags(deviceId, getHandle());153}154155long getHandle() {156long handle = nativeHandle.get();157158if (handle == 0) {159throw new IllegalStateException();160}161162return handle;163}164165/**166* Returns the priority of this stream.167* @return168* the priority of this stream169* @throws CudaException170* if a CUDA exception occurs171* @throws IllegalStateException172* if this stream has been closed (see {@link #close()})173*/174public int getPriority() throws CudaException {175return getPriority(deviceId, getHandle());176}177178/**179* Queries the state of this stream.180* The common normally occurring states are:181* <ul>182* <li>CudaError.Success - stream has no pending work</li>183* <li>CudaError.NotReady - stream has pending work</li>184* </ul>185*186* @return187* the state of this stream188* @throws IllegalStateException189* if this stream has been closed (see {@link #close()})190*/191public int query() {192return query(deviceId, getHandle());193}194195/**196* Synchronizes with this stream.197* This method blocks until all work queued on this stream has completed.198*199* @throws CudaException200* if a CUDA exception occurs201* @throws IllegalStateException202* if this stream has been closed (see {@link #close()})203*/204public void synchronize() throws CudaException {205synchronize(deviceId, getHandle());206}207208/**209* Makes all future work submitted to this stream wait for the specified210* event to occur.211*212* @param event213* the specified event214* @throws CudaException215* if a CUDA exception occurs216* @throws IllegalStateException217* if this stream has been closed (see {@link #close()}),218* or the event has been closed (see {@link CudaEvent#close()})219*/220public void waitFor(CudaEvent event) throws CudaException {221waitFor(deviceId, getHandle(), event.getHandle());222}223}224225226