Path: blob/master/jcl/src/openj9.cuda/share/classes/com/ibm/cuda/CudaBuffer.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.nio.Buffer;25import java.nio.ByteBuffer;26import java.nio.ByteOrder;27import java.nio.CharBuffer;28import java.nio.DoubleBuffer;29import java.nio.FloatBuffer;30import java.nio.IntBuffer;31import java.nio.LongBuffer;32import java.nio.ShortBuffer;33import java.util.concurrent.atomic.AtomicLong;3435/**36* The {@code CudaBuffer} class represents a region of memory on a specific37* device.38* <p>39* Data may be transferred between the device and the Java host via the40* various {@code copyTo} or {@code copyFrom} methods. A buffer may be filled41* with a specific pattern through use of one of the {@code fillXxx} methods.42* <p>43* When no longer required, a buffer must be {@code close}d.44*/45public final class CudaBuffer implements AutoCloseable {4647private static final ByteOrder DeviceOrder = ByteOrder.LITTLE_ENDIAN;4849private static native long allocate(int deviceId, long byteCount)50throws CudaException;5152private static native ByteBuffer allocateDirectBuffer(long capacity);5354private static int chunkBytes(long size) {55return size <= Integer.MAX_VALUE ? (int) size : Integer.MAX_VALUE & ~7;56}5758private static native void copyFromDevice(int deviceId, long devicePtr,59int sourceDeviceId, long sourceAddress, long byteCount)60throws CudaException;6162private static native void copyFromHostByte(int deviceId, long devicePtr,63byte[] array, int fromIndex, int toIndex) throws CudaException;6465private static native void copyFromHostChar(int deviceId, long devicePtr,66char[] array, int fromIndex, int toIndex) throws CudaException;6768private static native void copyFromHostDirect(int deviceId, long devicePtr,69Buffer source, long fromOffset, long toOffset) throws CudaException;7071private static native void copyFromHostDouble(int deviceId, long devicePtr,72double[] array, int fromIndex, int toIndex) throws CudaException;7374private static native void copyFromHostFloat(int deviceId, long devicePtr,75float[] array, int fromIndex, int toIndex) throws CudaException;7677private static native void copyFromHostInt(int deviceId, long devicePtr,78int[] array, int fromIndex, int toIndex) throws CudaException;7980private static native void copyFromHostLong(int deviceId, long devicePtr,81long[] array, int fromIndex, int toIndex) throws CudaException;8283private static native void copyFromHostShort(int deviceId, long devicePtr,84short[] array, int fromIndex, int toIndex) throws CudaException;8586private static native void copyToHostByte(int deviceId, long devicePtr,87byte[] array, int fromIndex, int toIndex) throws CudaException;8889private static native void copyToHostChar(int deviceId, long devicePtr,90char[] array, int fromIndex, int toIndex) throws CudaException;9192private static native void copyToHostDirect(int deviceId, long devicePtr,93Buffer target, long fromOffset, long toOffset) throws CudaException;9495private static native void copyToHostDouble(int deviceId, long devicePtr,96double[] array, int fromIndex, int toIndex) throws CudaException;9798private static native void copyToHostFloat(int deviceId, long devicePtr,99float[] array, int fromIndex, int toIndex) throws CudaException;100101private static native void copyToHostInt(int deviceId, long devicePtr,102int[] array, int fromIndex, int toIndex) throws CudaException;103104private static native void copyToHostLong(int deviceId, long devicePtr,105long[] array, int fromIndex, int toIndex) throws CudaException;106107private static native void copyToHostShort(int deviceId, long devicePtr,108short[] array, int fromIndex, int toIndex) throws CudaException;109110private static native void fill(int deviceId, long devicePtr,111int elementSize, int value, long count) throws CudaException;112113private static native void freeDirectBuffer(Buffer buffer);114115private static void rangeCheck(long length, long fromIndex, long toIndex) {116if (fromIndex > toIndex) {117throw new IllegalArgumentException(118"fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ')'); //$NON-NLS-1$ //$NON-NLS-2$119}120121if (fromIndex < 0) {122throw new IndexOutOfBoundsException(String.valueOf(fromIndex));123}124125if (toIndex > length) {126throw new IndexOutOfBoundsException(String.valueOf(toIndex));127}128}129130private static native void release(int deviceId, long devicePtr)131throws CudaException;132133private final int deviceId;134135private final AtomicLong devicePtr;136137private final long length;138139private final CudaBuffer parent;140141private CudaBuffer(CudaBuffer parent, int deviceId, long devicePtr,142long length) {143super();144this.deviceId = deviceId;145this.devicePtr = new AtomicLong(devicePtr);146this.length = length;147this.parent = parent;148}149150/**151* Allocates a new region on the specified {@code device} of size {@code byteCount} bytes.152*153* @param device154* the device on which the region is to be allocated155* @param byteCount156* the allocation size in bytes157* @throws CudaException158* if a CUDA exception occurs159*/160public CudaBuffer(CudaDevice device, long byteCount) throws CudaException {161super();162this.deviceId = device.getDeviceId();163this.devicePtr = new AtomicLong(allocate(this.deviceId, byteCount));164this.length = byteCount;165this.parent = null;166}167168/**169* Returns a sub-region of this buffer. The new buffer begins at the170* specified offset and extends to the end of this buffer.171*172* @param fromOffset173* the byte offset of the sub-region within this buffer174* @return175* the specified sub-region176* @throws IllegalStateException177* if this buffer has been closed (see {@link #close()})178* @throws IndexOutOfBoundsException179* if the specified offset is negative or larger than the180* length of this buffer181*/182public CudaBuffer atOffset(long fromOffset) {183return slice(fromOffset, length);184}185186/**187* Releases the region of device memory backing this buffer.188* <p>189* Closing a buffer created via {@link #atOffset(long)} with a190* non-zero offset has no effect: the memory is still accessible via191* the parent buffer which must be closed separately.192*193* @throws CudaException194* if a CUDA exception occurs195*/196@Override197public void close() throws CudaException {198long address = devicePtr.getAndSet(0);199200if (address != 0 && parent == null) {201release(deviceId, address);202}203}204205/**206* Copies all data from the specified {@code array} (on the Java host) to207* this buffer (on the device). Equivalent to208* <pre>209* copyFrom(array, 0, array.length);210* </pre>211*212* @param array213* the source array214* @throws CudaException215* if a CUDA exception occurs216* @throws IllegalStateException217* if this buffer has been closed (see {@link #close()})218* @throws IndexOutOfBoundsException219* if the number of source bytes is larger than the length220* of this buffer221*/222public void copyFrom(byte[] array) throws CudaException {223copyFrom(array, 0, array.length);224}225226/**227* Copies data from the specified {@code array} (on the Java host) to this228* buffer (on the device). Elements are read from {@code array} beginning229* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}230* storing them in the same order in this buffer.231* <p>232* A sub-buffer may be created (see {@link #atOffset(long)}) when the data233* are to be copied somewhere other than the beginning of this buffer.234*235* @param array236* the source array237* @param fromIndex238* the source starting offset (inclusive)239* @param toIndex240* the source ending offset (exclusive)241* @throws CudaException242* if a CUDA exception occurs243* @throws IllegalArgumentException244* if {@code fromIndex > toIndex}245* @throws IllegalStateException246* if this buffer has been closed (see {@link #close()})247* @throws IndexOutOfBoundsException248* if {@code fromIndex} is negative, {@code toIndex > array.length},249* or the number of source bytes is larger than the length250* of this buffer251*/252public void copyFrom(byte[] array, int fromIndex, int toIndex)253throws CudaException {254rangeCheck(array.length, fromIndex, toIndex);255lengthCheck(toIndex - fromIndex, 0);256copyFromHostByte(deviceId, getAddress(), // <br/>257array, fromIndex, toIndex);258}259260/**261* Copies data from the specified {@code source} buffer (on the Java host)262* to this buffer (on the device). Elements are read from {@code source}263* beginning at {@code position()} continuing up to, but excluding,264* {@code limit()} storing them in the same order in this buffer.265* The {@code source} buffer position is set to {@code limit()}.266* <p>267* A sub-buffer may be created (see {@link #atOffset(long)}) when the data268* are to be copied somewhere other than the beginning of this buffer.269*270* @param source271* the source buffer272* @throws CudaException273* if a CUDA exception occurs274* @throws IllegalStateException275* if this buffer has been closed (see {@link #close()})276* @throws IndexOutOfBoundsException277* if the number of source bytes is larger than the length278* of this buffer279*/280public void copyFrom(ByteBuffer source) throws CudaException {281final int fromIndex = source.position();282final int toIndex = source.limit();283final int byteCount = toIndex - fromIndex;284285lengthCheck(byteCount, 0);286287if (source.isDirect()) {288copyFromHostDirect(deviceId, getAddress(), // <br/>289source, fromIndex, toIndex);290} else if (source.hasArray()) {291final int offset = source.arrayOffset();292293copyFrom(source.array(), fromIndex + offset, toIndex + offset);294} else {295ByteBuffer tmp = allocateDirectBuffer(byteCount).order(DeviceOrder);296297try {298tmp.put(source);299copyFromHostDirect(deviceId, getAddress(), // <br/>300tmp, 0, byteCount);301} finally {302freeDirectBuffer(tmp);303}304}305306source.position(toIndex);307}308309/**310* Copies all data from the specified {@code array} (on the Java host) to311* this buffer (on the device). Equivalent to312* <pre>313* copyFrom(array, 0, array.length);314* </pre>315*316* @param array317* the source array318* @throws CudaException319* if a CUDA exception occurs320* @throws IllegalStateException321* if this buffer has been closed (see {@link #close()})322* @throws IndexOutOfBoundsException323* if the number of source bytes is larger than the length324* of this buffer325*/326public void copyFrom(char[] array) throws CudaException {327copyFrom(array, 0, array.length);328}329330/**331* Copies data from the specified {@code array} (on the Java host) to this332* buffer (on the device). Elements are read from {@code array} beginning333* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}334* storing them in the same order in this buffer.335* <p>336* A sub-buffer may be created (see {@link #atOffset(long)}) when the data337* are to be copied somewhere other than the beginning of this buffer.338*339* @param array340* the source array341* @param fromIndex342* the source starting offset (inclusive)343* @param toIndex344* the source ending offset (exclusive)345* @throws CudaException346* if a CUDA exception occurs347* @throws IllegalArgumentException348* if {@code fromIndex > toIndex}349* @throws IllegalStateException350* if this buffer has been closed (see {@link #close()})351* @throws IndexOutOfBoundsException352* if {@code fromIndex} is negative, {@code toIndex > array.length},353* or the number of source bytes is larger than the length354* of this buffer355*/356public void copyFrom(char[] array, int fromIndex, int toIndex)357throws CudaException {358rangeCheck(array.length, fromIndex, toIndex);359lengthCheck(toIndex - fromIndex, 1);360copyFromHostChar(deviceId, getAddress(), // <br/>361array, fromIndex, toIndex);362}363364/**365* Copies data from the specified {@code source} buffer (on the Java host)366* to this buffer (on the device). Elements are read from {@code source}367* beginning at {@code position()} continuing up to, but excluding,368* {@code limit()} storing them in the same order in this buffer.369* The {@code source} buffer position is set to {@code limit()}.370* <p>371* A sub-buffer may be created (see {@link #atOffset(long)}) when the data372* are to be copied somewhere other than the beginning of this buffer.373*374* @param source375* the source buffer376* @throws CudaException377* if a CUDA exception occurs378* @throws IllegalStateException379* if this buffer has been closed (see {@link #close()})380* @throws IndexOutOfBoundsException381* if the number of source bytes is larger than the length382* of this buffer383*/384public void copyFrom(CharBuffer source) throws CudaException {385final int fromIndex = source.position();386final int toIndex = source.limit();387388lengthCheck(toIndex - fromIndex, 1);389390if (source.isDirect()) {391copyFromHostDirect(deviceId, getAddress(), // <br/>392source, (long) fromIndex << 1, (long) toIndex << 1);393} else if (source.hasArray()) {394final int offset = source.arrayOffset();395396copyFrom(source.array(), fromIndex + offset, toIndex + offset);397} else {398final long byteCount = (long) (toIndex - fromIndex) << 1;399final int chunkSize = chunkBytes(byteCount);400final CharBuffer slice = source.slice();401final CharBuffer tmp = allocateDirectBuffer(chunkSize) // <br/>402.order(DeviceOrder).asCharBuffer();403404try {405for (long start = 0; start < byteCount; start += chunkSize) {406final long end = Math.min(start + chunkSize, byteCount);407408slice.limit((int) (end >> 1));409tmp.clear();410tmp.put(slice);411copyFromHostDirect(deviceId, getAddress() + start, // <br/>412tmp, 0, end - start);413}414} finally {415freeDirectBuffer(tmp);416}417}418419source.position(toIndex);420}421422/**423* Copies data from the specified {@code source} buffer (on a device)424* to this buffer (on the device). Elements are read from {@code source}425* beginning at {@code position()} continuing up to, but excluding,426* {@code limit()} storing them in the same order in this buffer.427* <p>428* A sub-buffer may be created (see {@link #atOffset(long)}) when the data429* are to be copied somewhere other than the beginning of this buffer.430*431* @param source432* the source buffer433* @param fromOffset434* the source starting offset (inclusive)435* @param toOffset436* the source ending offset (exclusive)437* @throws CudaException438* if a CUDA exception occurs439* @throws IllegalStateException440* if this buffer has been closed (see {@link #close()})441* @throws IndexOutOfBoundsException442* if either {@code fromOffset} or {@code toOffset} is not a legal443* offset within the source buffer or the number of source bytes444* is larger than the length of this buffer445*/446public void copyFrom(CudaBuffer source, long fromOffset, long toOffset)447throws CudaException {448final long byteCount = toOffset - fromOffset;449450rangeCheck(source.length, fromOffset, toOffset);451lengthCheck(byteCount, 0);452453copyFromDevice(deviceId, getAddress(), // <br/>454source.deviceId, source.getAddress() + fromOffset, // <br/>455byteCount);456}457458/**459* Copies all data from the specified {@code array} (on the Java host) to460* this buffer (on the device). Equivalent to461* <pre>462* copyFrom(array, 0, array.length);463* </pre>464*465* @param array466* the source array467* @throws CudaException468* if a CUDA exception occurs469* @throws IllegalStateException470* if this buffer has been closed (see {@link #close()})471* @throws IndexOutOfBoundsException472* if the number of source bytes is larger than the length473* of this buffer474*/475public void copyFrom(double[] array) throws CudaException {476copyFrom(array, 0, array.length);477}478479/**480* Copies data from the specified {@code array} (on the Java host) to this481* buffer (on the device). Elements are read from {@code array} beginning482* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}483* storing them in the same order in this buffer.484* <p>485* A sub-buffer may be created (see {@link #atOffset(long)}) when the data486* are to be copied somewhere other than the beginning of this buffer.487*488* @param array489* the source array490* @param fromIndex491* the source starting offset (inclusive)492* @param toIndex493* the source ending offset (exclusive)494* @throws CudaException495* if a CUDA exception occurs496* @throws IllegalArgumentException497* if {@code fromIndex > toIndex}498* @throws IllegalStateException499* if this buffer has been closed (see {@link #close()})500* @throws IndexOutOfBoundsException501* if {@code fromIndex} is negative, {@code toIndex > array.length},502* or the number of source bytes is larger than the length503* of this buffer504*/505public void copyFrom(double[] array, int fromIndex, int toIndex)506throws CudaException {507rangeCheck(array.length, fromIndex, toIndex);508lengthCheck(toIndex - fromIndex, 3);509copyFromHostDouble(deviceId, getAddress(), // <br/>510array, fromIndex, toIndex);511}512513/**514* Copies data from the specified {@code source} buffer (on the Java host)515* to this buffer (on the device). Elements are read from {@code source}516* beginning at {@code position()} continuing up to, but excluding,517* {@code limit()} storing them in the same order in this buffer.518* The {@code source} buffer position is set to {@code limit()}.519* <p>520* A sub-buffer may be created (see {@link #atOffset(long)}) when the data521* are to be copied somewhere other than the beginning of this buffer.522*523* @param source524* the source buffer525* @throws CudaException526* if a CUDA exception occurs527* @throws IllegalStateException528* if this buffer has been closed (see {@link #close()})529* @throws IndexOutOfBoundsException530* if the number of source bytes is larger than the length531* of this buffer532*/533public void copyFrom(DoubleBuffer source) throws CudaException {534final int fromIndex = source.position();535final int toIndex = source.limit();536537lengthCheck(toIndex - fromIndex, 3);538539if (source.isDirect()) {540copyFromHostDirect(deviceId, getAddress(), // <br/>541source, (long) fromIndex << 3, (long) toIndex << 3);542} else if (source.hasArray()) {543final int offset = source.arrayOffset();544545copyFrom(source.array(), fromIndex + offset, toIndex + offset);546} else {547final long byteCount = (long) (toIndex - fromIndex) << 3;548final int chunkSize = chunkBytes(byteCount);549final DoubleBuffer slice = source.slice();550final DoubleBuffer tmp = allocateDirectBuffer(chunkSize) // <br/>551.order(DeviceOrder).asDoubleBuffer();552553try {554for (long start = 0; start < byteCount; start += chunkSize) {555final long end = Math.min(start + chunkSize, byteCount);556557slice.limit((int) (end >> 3));558tmp.clear();559tmp.put(slice);560copyFromHostDirect(deviceId, getAddress() + start, // <br/>561tmp, 0, end - start);562}563} finally {564freeDirectBuffer(tmp);565}566}567568source.position(toIndex);569}570571/**572* Copies all data from the specified {@code array} (on the Java host) to573* this buffer (on the device). Equivalent to574* <pre>575* copyFrom(array, 0, array.length);576* </pre>577*578* @param array579* the source array580* @throws CudaException581* if a CUDA exception occurs582* @throws IllegalStateException583* if this buffer has been closed (see {@link #close()})584* @throws IndexOutOfBoundsException585* if the number of source bytes is larger than the length586* of this buffer587*/588public void copyFrom(float[] array) throws CudaException {589copyFrom(array, 0, array.length);590}591592/**593* Copies data from the specified {@code array} (on the Java host) to this594* buffer (on the device). Elements are read from {@code array} beginning595* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}596* storing them in the same order in this buffer.597* <p>598* A sub-buffer may be created (see {@link #atOffset(long)}) when the data599* are to be copied somewhere other than the beginning of this buffer.600*601* @param array602* the source array603* @param fromIndex604* the source starting offset (inclusive)605* @param toIndex606* the source ending offset (exclusive)607* @throws CudaException608* if a CUDA exception occurs609* @throws IllegalArgumentException610* if {@code fromIndex > toIndex}611* @throws IllegalStateException612* if this buffer has been closed (see {@link #close()})613* @throws IndexOutOfBoundsException614* if {@code fromIndex} is negative, {@code toIndex > array.length},615* or the number of source bytes is larger than the length616* of this buffer617*/618public void copyFrom(float[] array, int fromIndex, int toIndex)619throws CudaException {620rangeCheck(array.length, fromIndex, toIndex);621lengthCheck(toIndex - fromIndex, 2);622copyFromHostFloat(deviceId, getAddress(), // <br/>623array, fromIndex, toIndex);624}625626/**627* Copies data from the specified {@code source} buffer (on the Java host)628* to this buffer (on the device). Elements are read from {@code source}629* beginning at {@code position()} continuing up to, but excluding,630* {@code limit()} storing them in the same order in this buffer.631* The {@code source} buffer position is set to {@code limit()}.632* <p>633* A sub-buffer may be created (see {@link #atOffset(long)}) when the data634* are to be copied somewhere other than the beginning of this buffer.635*636* @param source637* the source buffer638* @throws CudaException639* if a CUDA exception occurs640* @throws IllegalStateException641* if this buffer has been closed (see {@link #close()})642* @throws IndexOutOfBoundsException643* if the number of source bytes is larger than the length644* of this buffer645*/646public void copyFrom(FloatBuffer source) throws CudaException {647final int fromIndex = source.position();648final int toIndex = source.limit();649650lengthCheck(toIndex - fromIndex, 2);651652if (source.isDirect()) {653copyFromHostDirect(deviceId, getAddress(), // <br/>654source, (long) fromIndex << 2, (long) toIndex << 2);655} else if (source.hasArray()) {656final int offset = source.arrayOffset();657658copyFrom(source.array(), fromIndex + offset, toIndex + offset);659} else {660final long byteCount = (long) (toIndex - fromIndex) << 2;661final int chunkSize = chunkBytes(byteCount);662final FloatBuffer slice = source.slice();663final FloatBuffer tmp = allocateDirectBuffer(chunkSize) // <br/>664.order(DeviceOrder).asFloatBuffer();665666try {667for (long start = 0; start < byteCount; start += chunkSize) {668final long end = Math.min(start + chunkSize, byteCount);669670slice.limit((int) (end >> 2));671tmp.clear();672tmp.put(slice);673copyFromHostDirect(deviceId, getAddress() + start, // <br/>674tmp, 0, end - start);675}676} finally {677freeDirectBuffer(tmp);678}679}680681source.position(toIndex);682}683684/**685* Copies all data from the specified {@code array} (on the Java host) to686* this buffer (on the device). Equivalent to687* <pre>688* copyFrom(array, 0, array.length);689* </pre>690*691* @param array692* the source array693* @throws CudaException694* if a CUDA exception occurs695* @throws IllegalStateException696* if this buffer has been closed (see {@link #close()})697* @throws IndexOutOfBoundsException698* if the number of source bytes is larger than the length699* of this buffer700*/701public void copyFrom(int[] array) throws CudaException {702copyFrom(array, 0, array.length);703}704705/**706* Copies data from the specified {@code array} (on the Java host) to this707* buffer (on the device). Elements are read from {@code array} beginning708* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}709* storing them in the same order in this buffer.710* <p>711* A sub-buffer may be created (see {@link #atOffset(long)}) when the data712* are to be copied somewhere other than the beginning of this buffer.713*714* @param array715* the source array716* @param fromIndex717* the source starting offset (inclusive)718* @param toIndex719* the source ending offset (exclusive)720* @throws CudaException721* if a CUDA exception occurs722* @throws IllegalArgumentException723* if {@code fromIndex > toIndex}724* @throws IllegalStateException725* if this buffer has been closed (see {@link #close()})726* @throws IndexOutOfBoundsException727* if {@code fromIndex} is negative, {@code toIndex > array.length},728* or the number of source bytes is larger than the length729* of this buffer730*/731public void copyFrom(int[] array, int fromIndex, int toIndex)732throws CudaException {733rangeCheck(array.length, fromIndex, toIndex);734lengthCheck(toIndex - fromIndex, 2);735copyFromHostInt(deviceId, getAddress(), // <br/>736array, fromIndex, toIndex);737}738739/**740* Copies data from the specified {@code source} buffer (on the Java host)741* to this buffer (on the device). Elements are read from {@code source}742* beginning at {@code position()} continuing up to, but excluding,743* {@code limit()} storing them in the same order in this buffer.744* The {@code source} buffer position is set to {@code limit()}.745* <p>746* A sub-buffer may be created (see {@link #atOffset(long)}) when the data747* are to be copied somewhere other than the beginning of this buffer.748*749* @param source750* the source buffer751* @throws CudaException752* if a CUDA exception occurs753* @throws IllegalStateException754* if this buffer has been closed (see {@link #close()})755* @throws IndexOutOfBoundsException756* if the number of source bytes is larger than the length757* of this buffer758*/759public void copyFrom(IntBuffer source) throws CudaException {760final int fromIndex = source.position();761final int toIndex = source.limit();762763lengthCheck(toIndex - fromIndex, 2);764765if (source.isDirect()) {766copyFromHostDirect(deviceId, getAddress(), // <br/>767source, (long) fromIndex << 2, (long) toIndex << 2);768} else if (source.hasArray()) {769final int offset = source.arrayOffset();770771copyFrom(source.array(), fromIndex + offset, toIndex + offset);772} else {773final long byteCount = (long) (toIndex - fromIndex) << 2;774final int chunkSize = chunkBytes(byteCount);775final IntBuffer slice = source.slice();776final IntBuffer tmp = allocateDirectBuffer(chunkSize) // <br/>777.order(DeviceOrder).asIntBuffer();778779try {780for (long start = 0; start < byteCount; start += chunkSize) {781final long end = Math.min(start + chunkSize, byteCount);782783slice.limit((int) (end >> 2));784tmp.clear();785tmp.put(slice);786copyFromHostDirect(deviceId, getAddress() + start, // <br/>787tmp, 0, end - start);788}789} finally {790freeDirectBuffer(tmp);791}792}793794source.position(toIndex);795}796797/**798* Copies all data from the specified {@code array} (on the Java host) to799* this buffer (on the device). Equivalent to800* <pre>801* copyFrom(array, 0, array.length);802* </pre>803*804* @param array805* the source array806* @throws CudaException807* if a CUDA exception occurs808* @throws IllegalStateException809* if this buffer has been closed (see {@link #close()})810* @throws IndexOutOfBoundsException811* if the number of source bytes is larger than the length812* of this buffer813*/814public void copyFrom(long[] array) throws CudaException {815copyFrom(array, 0, array.length);816}817818/**819* Copies data from the specified {@code array} (on the Java host) to this820* buffer (on the device). Elements are read from {@code array} beginning821* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}822* storing them in the same order in this buffer.823* <p>824* A sub-buffer may be created (see {@link #atOffset(long)}) when the data825* are to be copied somewhere other than the beginning of this buffer.826*827* @param array828* the source array829* @param fromIndex830* the source starting offset (inclusive)831* @param toIndex832* the source ending offset (exclusive)833* @throws CudaException834* if a CUDA exception occurs835* @throws IllegalArgumentException836* if {@code fromIndex > toIndex}837* @throws IllegalStateException838* if this buffer has been closed (see {@link #close()})839* @throws IndexOutOfBoundsException840* if {@code fromIndex} is negative, {@code toIndex > array.length},841* or the number of source bytes is larger than the length842* of this buffer843*/844public void copyFrom(long[] array, int fromIndex, int toIndex)845throws CudaException {846rangeCheck(array.length, fromIndex, toIndex);847lengthCheck(toIndex - fromIndex, 3);848copyFromHostLong(deviceId, getAddress(), // <br/>849array, fromIndex, toIndex);850}851852/**853* Copies data from the specified {@code source} buffer (on the Java host)854* to this buffer (on the device). Elements are read from {@code source}855* beginning at {@code position()} continuing up to, but excluding,856* {@code limit()} storing them in the same order in this buffer.857* The {@code source} buffer position is set to {@code limit()}.858* <p>859* A sub-buffer may be created (see {@link #atOffset(long)}) when the data860* are to be copied somewhere other than the beginning of this buffer.861*862* @param source863* the source buffer864* @throws CudaException865* if a CUDA exception occurs866* @throws IllegalStateException867* if this buffer has been closed (see {@link #close()})868* @throws IndexOutOfBoundsException869* if the number of source bytes is larger than the length870* of this buffer871*/872public void copyFrom(LongBuffer source) throws CudaException {873final int fromIndex = source.position();874final int toIndex = source.limit();875876lengthCheck(toIndex - fromIndex, 3);877878if (source.isDirect()) {879copyFromHostDirect(deviceId, getAddress(), // <br/>880source, (long) fromIndex << 3, (long) toIndex << 3);881} else if (source.hasArray()) {882final int offset = source.arrayOffset();883884copyFrom(source.array(), fromIndex + offset, toIndex + offset);885} else {886final long byteCount = (long) (toIndex - fromIndex) << 3;887final int chunkSize = chunkBytes(byteCount);888final LongBuffer slice = source.slice();889final LongBuffer tmp = allocateDirectBuffer(chunkSize) // <br/>890.order(DeviceOrder).asLongBuffer();891892try {893for (long start = 0; start < byteCount; start += chunkSize) {894final long end = Math.min(start + chunkSize, byteCount);895896slice.limit((int) (end >> 3));897tmp.clear();898tmp.put(slice);899copyFromHostDirect(deviceId, getAddress() + start, // <br/>900tmp, 0, end - start);901}902} finally {903freeDirectBuffer(tmp);904}905}906907source.position(toIndex);908}909910/**911* Copies all data from the specified {@code array} (on the Java host) to912* this buffer (on the device). Equivalent to913* <pre>914* copyFrom(array, 0, array.length);915* </pre>916*917* @param array918* the source array919* @throws CudaException920* if a CUDA exception occurs921* @throws IllegalStateException922* if this buffer has been closed (see {@link #close()})923* @throws IndexOutOfBoundsException924* if the number of source bytes is larger than the length925* of this buffer926*/927public void copyFrom(short[] array) throws CudaException {928copyFrom(array, 0, array.length);929}930931/**932* Copies data from the specified {@code array} (on the Java host) to this933* buffer (on the device). Elements are read from {@code array} beginning934* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}935* storing them in the same order in this buffer.936* <p>937* A sub-buffer may be created (see {@link #atOffset(long)}) when the data938* are to be copied somewhere other than the beginning of this buffer.939*940* @param array941* the source array942* @param fromIndex943* the source starting offset (inclusive)944* @param toIndex945* the source ending offset (exclusive)946* @throws CudaException947* if a CUDA exception occurs948* @throws IllegalArgumentException949* if {@code fromIndex > toIndex}950* @throws IllegalStateException951* if this buffer has been closed (see {@link #close()})952* @throws IndexOutOfBoundsException953* if {@code fromIndex} is negative, {@code toIndex > array.length},954* or the number of source bytes is larger than the length955* of this buffer956*/957public void copyFrom(short[] array, int fromIndex, int toIndex)958throws CudaException {959rangeCheck(array.length, fromIndex, toIndex);960lengthCheck(toIndex - fromIndex, 1);961copyFromHostShort(deviceId, getAddress(), // <br/>962array, fromIndex, toIndex);963}964965/**966* Copies data from the specified {@code source} buffer (on the Java host)967* to this buffer (on the device). Elements are read from {@code source}968* beginning at {@code position()} continuing up to, but excluding,969* {@code limit()} storing them in the same order in this buffer.970* The {@code source} buffer position is set to {@code limit()}.971* <p>972* A sub-buffer may be created (see {@link #atOffset(long)}) when the data973* are to be copied somewhere other than the beginning of this buffer.974*975* @param source976* the source buffer977* @throws CudaException978* if a CUDA exception occurs979* @throws IllegalStateException980* if this buffer has been closed (see {@link #close()})981* @throws IndexOutOfBoundsException982* if the number of source bytes is larger than the length983* of this buffer984*/985public void copyFrom(ShortBuffer source) throws CudaException {986final int fromIndex = source.position();987final int toIndex = source.limit();988989lengthCheck(toIndex - fromIndex, 1);990991if (source.isDirect()) {992copyFromHostDirect(deviceId, getAddress(), // <br/>993source, (long) fromIndex << 1, (long) toIndex << 1);994} else if (source.hasArray()) {995final int offset = source.arrayOffset();996997copyFrom(source.array(), fromIndex + offset, toIndex + offset);998} else {999final long byteCount = (long) (toIndex - fromIndex) << 1;1000final int chunkSize = chunkBytes(byteCount);1001final ShortBuffer slice = source.slice();1002final ShortBuffer tmp = allocateDirectBuffer(chunkSize) // <br/>1003.order(DeviceOrder).asShortBuffer();10041005try {1006for (long start = 0; start < byteCount; start += chunkSize) {1007final long end = Math.min(start + chunkSize, byteCount);10081009slice.limit((int) (end >> 1));1010tmp.clear();1011tmp.put(slice);1012copyFromHostDirect(deviceId, getAddress() + start, // <br/>1013tmp, 0, end - start);1014}1015} finally {1016freeDirectBuffer(tmp);1017}1018}10191020source.position(toIndex);1021}10221023/**1024* Copies data from this buffer (on the device) to the specified1025* {@code array} (on the Java host). Equivalent to1026* <pre>1027* copyTo(array, 0, array.length);1028* </pre>1029*1030* @param array1031* the destination array1032* @throws CudaException1033* if a CUDA exception occurs1034* @throws IllegalStateException1035* if this buffer has been closed (see {@link #close()})1036* @throws IndexOutOfBoundsException1037* if the number of required source bytes is larger than the length1038* of this buffer1039*/1040public void copyTo(byte[] array) throws CudaException {1041copyTo(array, 0, array.length);1042}10431044/**1045* Copies data from this buffer (on the device) to the specified1046* {@code array} (on the Java host). Elements are read starting at the1047* beginning of this buffer and stored in {@code array} beginning1048* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}.1049* <p>1050* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1051* data are not located at the beginning of this buffer.1052*1053* @param array1054* the destination array1055* @param fromIndex1056* the destination starting offset (inclusive)1057* @param toIndex1058* the destination ending offset (exclusive)1059* @throws CudaException1060* if a CUDA exception occurs1061* @throws IllegalArgumentException1062* if {@code fromIndex > toIndex}1063* @throws IllegalStateException1064* if this buffer has been closed (see {@link #close()})1065* @throws IndexOutOfBoundsException1066* if {@code fromIndex} is negative, {@code toIndex > array.length},1067* or the number of required source bytes is larger than the length1068* of this buffer1069*/1070public void copyTo(byte[] array, int fromIndex, int toIndex)1071throws CudaException {1072rangeCheck(array.length, fromIndex, toIndex);1073lengthCheck(toIndex - fromIndex, 0);1074copyToHostByte(deviceId, getAddress(), // <br/>1075array, fromIndex, toIndex);1076}10771078/**1079* Copies data from this buffer (on the device) to the specified1080* {@code target} buffer (on the Java host). Elements are read starting at1081* the beginning of this buffer and stored in {@code target} beginning1082* at {@code position()} continuing up to, but excluding, {@code limit()}.1083* The {@code target} buffer position is set to {@code limit()}.1084* <p>1085* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1086* data are not located at the beginning of this buffer.1087*1088* @param target1089* the destination buffer1090* @throws CudaException1091* if a CUDA exception occurs1092* @throws IllegalStateException1093* if this buffer has been closed (see {@link #close()})1094* @throws IndexOutOfBoundsException1095* if the number of required source bytes is larger than the length1096* of this buffer1097*/1098public void copyTo(ByteBuffer target) throws CudaException {1099final int fromIndex = target.position();1100final int toIndex = target.limit();1101final int byteCount = toIndex - fromIndex;11021103lengthCheck(byteCount, 0);11041105if (target.isDirect()) {1106copyToHostDirect(deviceId, getAddress(), // <br/>1107target, fromIndex, toIndex);1108} else if (target.hasArray()) {1109final int offset = target.arrayOffset();11101111copyTo(target.array(), fromIndex + offset, toIndex + offset);1112} else {1113ByteBuffer tmp = allocateDirectBuffer(byteCount).order(DeviceOrder);11141115try {1116copyToHostDirect(deviceId, getAddress(), // <br/>1117tmp, 0, byteCount);1118target.put(tmp);1119} finally {1120freeDirectBuffer(tmp);1121}1122}11231124target.position(toIndex);1125}11261127/**1128* Copies data from this buffer (on the device) to the specified1129* {@code array} (on the Java host). Equivalent to1130* <pre>1131* copyTo(array, 0, array.length);1132* </pre>1133*1134* @param array1135* the destination array1136* @throws CudaException1137* if a CUDA exception occurs1138* @throws IllegalStateException1139* if this buffer has been closed (see {@link #close()})1140* @throws IndexOutOfBoundsException1141* if the number of required source bytes is larger than the length1142* of this buffer1143*/1144public void copyTo(char[] array) throws CudaException {1145copyTo(array, 0, array.length);1146}11471148/**1149* Copies data from this buffer (on the device) to the specified1150* {@code array} (on the Java host). Elements are read starting at the1151* beginning of this buffer and stored in {@code array} beginning1152* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}.1153* <p>1154* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1155* data are not located at the beginning of this buffer.1156*1157* @param array1158* the destination array1159* @param fromIndex1160* the destination starting offset (inclusive)1161* @param toIndex1162* the destination ending offset (exclusive)1163* @throws CudaException1164* if a CUDA exception occurs1165* @throws IllegalArgumentException1166* if {@code fromIndex > toIndex}1167* @throws IllegalStateException1168* if this buffer has been closed (see {@link #close()})1169* @throws IndexOutOfBoundsException1170* if {@code fromIndex} is negative, {@code toIndex > array.length},1171* or the number of required source bytes is larger than the length1172* of this buffer1173*/1174public void copyTo(char[] array, int fromIndex, int toIndex)1175throws CudaException {1176rangeCheck(array.length, fromIndex, toIndex);1177lengthCheck(toIndex - fromIndex, 1);1178copyToHostChar(deviceId, getAddress(), // <br/>1179array, fromIndex, toIndex);1180}11811182/**1183* Copies data from this buffer (on the device) to the specified1184* {@code target} buffer (on the Java host). Elements are read starting at1185* the beginning of this buffer and stored in {@code target} beginning1186* at {@code position()} continuing up to, but excluding, {@code limit()}.1187* The {@code target} buffer position is set to {@code limit()}.1188* <p>1189* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1190* data are not located at the beginning of this buffer.1191*1192* @param target1193* the destination buffer1194* @throws CudaException1195* if a CUDA exception occurs1196* @throws IllegalStateException1197* if this buffer has been closed (see {@link #close()})1198* @throws IndexOutOfBoundsException1199* if the number of required source bytes is larger than the length1200* of this buffer1201*/1202public void copyTo(CharBuffer target) throws CudaException {1203final int fromIndex = target.position();1204final int toIndex = target.limit();12051206lengthCheck(toIndex - fromIndex, 1);12071208if (target.isDirect()) {1209copyToHostDirect(deviceId, getAddress(), // <br/>1210target, (long) fromIndex << 1, (long) toIndex << 1);1211} else if (target.hasArray()) {1212final int offset = target.arrayOffset();12131214copyTo(target.array(), fromIndex + offset, toIndex + offset);1215} else {1216final long byteCount = (long) (toIndex - fromIndex) << 1;1217final int chunkSize = chunkBytes(byteCount);1218final CharBuffer tmp = allocateDirectBuffer(chunkSize) // <br/>1219.order(DeviceOrder).asCharBuffer();12201221try {1222for (long start = 0; start < byteCount; start += chunkSize) {1223final int chunk = (int) Math.min(byteCount - start,1224chunkSize);12251226tmp.position(0).limit(chunk >> 1);1227copyToHostDirect(deviceId, getAddress() + start, // <br/>1228tmp, 0, chunk);1229target.put(tmp);1230}1231} finally {1232freeDirectBuffer(tmp);1233}1234}12351236target.position(toIndex);1237}12381239/**1240* Copies data from this buffer (on the device) to the specified1241* {@code array} (on the Java host). Equivalent to1242* <pre>1243* copyTo(array, 0, array.length);1244* </pre>1245*1246* @param array1247* the destination array1248* @throws CudaException1249* if a CUDA exception occurs1250* @throws IllegalStateException1251* if this buffer has been closed (see {@link #close()})1252* @throws IndexOutOfBoundsException1253* if the number of required source bytes is larger than the length1254* of this buffer1255*/1256public void copyTo(double[] array) throws CudaException {1257copyTo(array, 0, array.length);1258}12591260/**1261* Copies data from this buffer (on the device) to the specified1262* {@code array} (on the Java host). Elements are read starting at the1263* beginning of this buffer and stored in {@code array} beginning1264* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}.1265* <p>1266* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1267* data are not located at the beginning of this buffer.1268*1269* @param array1270* the destination array1271* @param fromIndex1272* the destination starting offset (inclusive)1273* @param toIndex1274* the destination ending offset (exclusive)1275* @throws CudaException1276* if a CUDA exception occurs1277* @throws IllegalArgumentException1278* if {@code fromIndex > toIndex}1279* @throws IllegalStateException1280* if this buffer has been closed (see {@link #close()})1281* @throws IndexOutOfBoundsException1282* if {@code fromIndex} is negative, {@code toIndex > array.length},1283* or the number of required source bytes is larger than the length1284* of this buffer1285*/1286public void copyTo(double[] array, int fromIndex, int toIndex)1287throws CudaException {1288rangeCheck(array.length, fromIndex, toIndex);1289lengthCheck(toIndex - fromIndex, 3);1290copyToHostDouble(deviceId, getAddress(), // <br/>1291array, fromIndex, toIndex);1292}12931294/**1295* Copies data from this buffer (on the device) to the specified1296* {@code target} buffer (on the Java host). Elements are read starting at1297* the beginning of this buffer and stored in {@code target} beginning1298* at {@code position()} continuing up to, but excluding, {@code limit()}.1299* The {@code target} buffer position is set to {@code limit()}.1300* <p>1301* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1302* data are not located at the beginning of this buffer.1303*1304* @param target1305* the destination buffer1306* @throws CudaException1307* if a CUDA exception occurs1308* @throws IllegalStateException1309* if this buffer has been closed (see {@link #close()})1310* @throws IndexOutOfBoundsException1311* if the number of required source bytes is larger than the length1312* of this buffer1313*/1314public void copyTo(DoubleBuffer target) throws CudaException {1315final int fromIndex = target.position();1316final int toIndex = target.limit();13171318lengthCheck(toIndex - fromIndex, 3);13191320if (target.isDirect()) {1321copyToHostDirect(deviceId, getAddress(), // <br/>1322target, (long) fromIndex << 3, (long) toIndex << 3);1323} else if (target.hasArray()) {1324final int offset = target.arrayOffset();13251326copyTo(target.array(), fromIndex + offset, toIndex + offset);1327} else {1328final long byteCount = (long) (toIndex - fromIndex) << 3;1329final int chunkSize = chunkBytes(byteCount);1330final DoubleBuffer tmp = allocateDirectBuffer(chunkSize) // <br/>1331.order(DeviceOrder).asDoubleBuffer();13321333try {1334for (long start = 0; start < byteCount; start += chunkSize) {1335final int chunk = (int) Math.min(byteCount - start,1336chunkSize);13371338tmp.position(0).limit(chunk >> 3);1339copyToHostDirect(deviceId, getAddress() + start, // <br/>1340tmp, 0, chunk);1341target.put(tmp);1342}1343} finally {1344freeDirectBuffer(tmp);1345}1346}13471348target.position(toIndex);1349}13501351/**1352* Copies data from this buffer (on the device) to the specified1353* {@code array} (on the Java host). Equivalent to1354* <pre>1355* copyTo(array, 0, array.length);1356* </pre>1357*1358* @param array1359* the destination array1360* @throws CudaException1361* if a CUDA exception occurs1362* @throws IllegalStateException1363* if this buffer has been closed (see {@link #close()})1364* @throws IndexOutOfBoundsException1365* if the number of required source bytes is larger than the length1366* of this buffer1367*/1368public void copyTo(float[] array) throws CudaException {1369copyTo(array, 0, array.length);1370}13711372/**1373* Copies data from this buffer (on the device) to the specified1374* {@code array} (on the Java host). Elements are read starting at the1375* beginning of this buffer and stored in {@code array} beginning1376* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}.1377* <p>1378* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1379* data are not located at the beginning of this buffer.1380*1381* @param array1382* the destination array1383* @param fromIndex1384* the destination starting offset (inclusive)1385* @param toIndex1386* the destination ending offset (exclusive)1387* @throws CudaException1388* if a CUDA exception occurs1389* @throws IllegalArgumentException1390* if {@code fromIndex > toIndex}1391* @throws IllegalStateException1392* if this buffer has been closed (see {@link #close()})1393* @throws IndexOutOfBoundsException1394* if {@code fromIndex} is negative, {@code toIndex > array.length},1395* or the number of required source bytes is larger than the length1396* of this buffer1397*/1398public void copyTo(float[] array, int fromIndex, int toIndex)1399throws CudaException {1400rangeCheck(array.length, fromIndex, toIndex);1401lengthCheck(toIndex - fromIndex, 2);1402copyToHostFloat(deviceId, getAddress(), // <br/>1403array, fromIndex, toIndex);1404}14051406/**1407* Copies data from this buffer (on the device) to the specified1408* {@code target} buffer (on the Java host). Elements are read starting at1409* the beginning of this buffer and stored in {@code target} beginning1410* at {@code position()} continuing up to, but excluding, {@code limit()}.1411* The {@code target} buffer position is set to {@code limit()}.1412* <p>1413* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1414* data are not located at the beginning of this buffer.1415*1416* @param target1417* the destination buffer1418* @throws CudaException1419* if a CUDA exception occurs1420* @throws IllegalStateException1421* if this buffer has been closed (see {@link #close()})1422* @throws IndexOutOfBoundsException1423* if the number of required source bytes is larger than the length1424* of this buffer1425*/1426public void copyTo(FloatBuffer target) throws CudaException {1427final int fromIndex = target.position();1428final int toIndex = target.limit();14291430lengthCheck(toIndex - fromIndex, 2);14311432if (target.isDirect()) {1433copyToHostDirect(deviceId, getAddress(), // <br/>1434target, (long) fromIndex << 2, (long) toIndex << 2);1435} else if (target.hasArray()) {1436final int offset = target.arrayOffset();14371438copyTo(target.array(), fromIndex + offset, toIndex + offset);1439} else {1440final long byteCount = (long) (toIndex - fromIndex) << 2;1441final int chunkSize = chunkBytes(byteCount);1442final FloatBuffer tmp = allocateDirectBuffer(chunkSize) // <br/>1443.order(DeviceOrder).asFloatBuffer();14441445try {1446for (long start = 0; start < byteCount; start += chunkSize) {1447final int chunk = (int) Math.min(byteCount - start,1448chunkSize);14491450tmp.position(0).limit(chunk >> 2);1451copyToHostDirect(deviceId, getAddress() + start, // <br/>1452tmp, 0, chunk);1453target.put(tmp);1454}1455} finally {1456freeDirectBuffer(tmp);1457}1458}14591460target.position(toIndex);1461}14621463/**1464* Copies data from this buffer (on the device) to the specified1465* {@code array} (on the Java host). Equivalent to1466* <pre>1467* copyTo(array, 0, array.length);1468* </pre>1469*1470* @param array1471* the destination array1472* @throws CudaException1473* if a CUDA exception occurs1474* @throws IllegalStateException1475* if this buffer has been closed (see {@link #close()})1476* @throws IndexOutOfBoundsException1477* if the number of required source bytes is larger than the length1478* of this buffer1479*/1480public void copyTo(int[] array) throws CudaException {1481copyTo(array, 0, array.length);1482}14831484/**1485* Copies data from this buffer (on the device) to the specified1486* {@code array} (on the Java host). Elements are read starting at the1487* beginning of this buffer and stored in {@code array} beginning1488* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}.1489* <p>1490* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1491* data are not located at the beginning of this buffer.1492*1493* @param array1494* the destination array1495* @param fromIndex1496* the destination starting offset (inclusive)1497* @param toIndex1498* the destination ending offset (exclusive)1499* @throws CudaException1500* if a CUDA exception occurs1501* @throws IllegalArgumentException1502* if {@code fromIndex > toIndex}1503* @throws IllegalStateException1504* if this buffer has been closed (see {@link #close()})1505* @throws IndexOutOfBoundsException1506* if {@code fromIndex} is negative, {@code toIndex > array.length},1507* or the number of required source bytes is larger than the length1508* of this buffer1509*/1510public void copyTo(int[] array, int fromIndex, int toIndex)1511throws CudaException {1512rangeCheck(array.length, fromIndex, toIndex);1513lengthCheck(toIndex - fromIndex, 2);1514copyToHostInt(deviceId, getAddress(), // <br/>1515array, fromIndex, toIndex);1516}15171518/**1519* Copies data from this buffer (on the device) to the specified1520* {@code target} buffer (on the Java host). Elements are read starting at1521* the beginning of this buffer and stored in {@code target} beginning1522* at {@code position()} continuing up to, but excluding, {@code limit()}.1523* The {@code target} buffer position is set to {@code limit()}.1524* <p>1525* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1526* data are not located at the beginning of this buffer.1527*1528* @param target1529* the destination buffer1530* @throws CudaException1531* if a CUDA exception occurs1532* @throws IllegalStateException1533* if this buffer has been closed (see {@link #close()})1534* @throws IndexOutOfBoundsException1535* if the number of required source bytes is larger than the length1536* of this buffer1537*/1538public void copyTo(IntBuffer target) throws CudaException {1539final int fromIndex = target.position();1540final int toIndex = target.limit();15411542lengthCheck(toIndex - fromIndex, 2);15431544if (target.isDirect()) {1545copyToHostDirect(deviceId, getAddress(), // <br/>1546target, (long) fromIndex << 2, (long) toIndex << 2);1547} else if (target.hasArray()) {1548final int offset = target.arrayOffset();15491550copyTo(target.array(), fromIndex + offset, toIndex + offset);1551} else {1552final long byteCount = (long) (toIndex - fromIndex) << 2;1553final int chunkSize = chunkBytes(byteCount);1554final IntBuffer tmp = allocateDirectBuffer(chunkSize) // <br/>1555.order(DeviceOrder).asIntBuffer();15561557try {1558for (long start = 0; start < byteCount; start += chunkSize) {1559final int chunk = (int) Math.min(byteCount - start,1560chunkSize);15611562tmp.position(0).limit(chunk >> 2);1563copyToHostDirect(deviceId, getAddress() + start, // <br/>1564tmp, 0, chunk);1565target.put(tmp);1566}1567} finally {1568freeDirectBuffer(tmp);1569}1570}15711572target.position(toIndex);1573}15741575/**1576* Copies data from this buffer (on the device) to the specified1577* {@code array} (on the Java host). Equivalent to1578* <pre>1579* copyTo(array, 0, array.length);1580* </pre>1581*1582* @param array1583* the destination array1584* @throws CudaException1585* if a CUDA exception occurs1586* @throws IllegalStateException1587* if this buffer has been closed (see {@link #close()})1588* @throws IndexOutOfBoundsException1589* if the number of required source bytes is larger than the length1590* of this buffer1591*/1592public void copyTo(long[] array) throws CudaException {1593copyTo(array, 0, array.length);1594}15951596/**1597* Copies data from this buffer (on the device) to the specified1598* {@code array} (on the Java host). Elements are read starting at the1599* beginning of this buffer and stored in {@code array} beginning1600* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}.1601* <p>1602* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1603* data are not located at the beginning of this buffer.1604*1605* @param array1606* the destination array1607* @param fromIndex1608* the destination starting offset (inclusive)1609* @param toIndex1610* the destination ending offset (exclusive)1611* @throws CudaException1612* if a CUDA exception occurs1613* @throws IllegalArgumentException1614* if {@code fromIndex > toIndex}1615* @throws IllegalStateException1616* if this buffer has been closed (see {@link #close()})1617* @throws IndexOutOfBoundsException1618* if {@code fromIndex} is negative, {@code toIndex > array.length},1619* or the number of required source bytes is larger than the length1620* of this buffer1621*/1622public void copyTo(long[] array, int fromIndex, int toIndex)1623throws CudaException {1624rangeCheck(array.length, fromIndex, toIndex);1625lengthCheck(toIndex - fromIndex, 3);1626copyToHostLong(deviceId, getAddress(), // <br/>1627array, fromIndex, toIndex);1628}16291630/**1631* Copies data from this buffer (on the device) to the specified1632* {@code target} buffer (on the Java host). Elements are read starting at1633* the beginning of this buffer and stored in {@code target} beginning1634* at {@code position()} continuing up to, but excluding, {@code limit()}.1635* The {@code target} buffer position is set to {@code limit()}.1636* <p>1637* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1638* data are not located at the beginning of this buffer.1639*1640* @param target1641* the destination buffer1642* @throws CudaException1643* if a CUDA exception occurs1644* @throws IllegalStateException1645* if this buffer has been closed (see {@link #close()})1646* @throws IndexOutOfBoundsException1647* if the number of required source bytes is larger than the length1648* of this buffer1649*/1650public void copyTo(LongBuffer target) throws CudaException {1651final int fromIndex = target.position();1652final int toIndex = target.limit();16531654lengthCheck(toIndex - fromIndex, 3);16551656if (target.isDirect()) {1657copyToHostDirect(deviceId, getAddress(), // <br/>1658target, (long) fromIndex << 3, (long) toIndex << 3);1659} else if (target.hasArray()) {1660final int offset = target.arrayOffset();16611662copyTo(target.array(), fromIndex + offset, toIndex + offset);1663} else {1664final long byteCount = (long) (toIndex - fromIndex) << 3;1665final int chunkSize = chunkBytes(byteCount);1666final LongBuffer tmp = allocateDirectBuffer(chunkSize) // <br/>1667.order(DeviceOrder).asLongBuffer();16681669try {1670for (long start = 0; start < byteCount; start += chunkSize) {1671final int chunk = (int) Math.min(byteCount - start,1672chunkSize);16731674tmp.position(0).limit(chunk >> 3);1675copyToHostDirect(deviceId, getAddress() + start, // <br/>1676tmp, 0, chunk);1677target.put(tmp);1678}1679} finally {1680freeDirectBuffer(tmp);1681}1682}16831684target.position(toIndex);1685}16861687/**1688* Copies data from this buffer (on the device) to the specified1689* {@code array} (on the Java host). Equivalent to1690* <pre>1691* copyTo(array, 0, array.length);1692* </pre>1693*1694* @param array1695* the destination array1696* @throws CudaException1697* if a CUDA exception occurs1698* @throws IllegalStateException1699* if this buffer has been closed (see {@link #close()})1700* @throws IndexOutOfBoundsException1701* if the number of required source bytes is larger than the length1702* of this buffer1703*/1704public void copyTo(short[] array) throws CudaException {1705copyTo(array, 0, array.length);1706}17071708/**1709* Copies data from this buffer (on the device) to the specified1710* {@code array} (on the Java host). Elements are read starting at the1711* beginning of this buffer and stored in {@code array} beginning1712* at {@code fromIndex} continuing up to, but excluding, {@code toIndex}.1713* <p>1714* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1715* data are not located at the beginning of this buffer.1716*1717* @param array1718* the destination array1719* @param fromIndex1720* the destination starting offset (inclusive)1721* @param toIndex1722* the destination ending offset (exclusive)1723* @throws CudaException1724* if a CUDA exception occurs1725* @throws IllegalArgumentException1726* if {@code fromIndex > toIndex}1727* @throws IllegalStateException1728* if this buffer has been closed (see {@link #close()})1729* @throws IndexOutOfBoundsException1730* if {@code fromIndex} is negative, {@code toIndex > array.length},1731* or the number of required source bytes is larger than the length1732* of this buffer1733*/1734public void copyTo(short[] array, int fromIndex, int toIndex)1735throws CudaException {1736rangeCheck(array.length, fromIndex, toIndex);1737lengthCheck(toIndex - fromIndex, 1);1738copyToHostShort(deviceId, getAddress(), // <br/>1739array, fromIndex, toIndex);1740}17411742/**1743* Copies data from this buffer (on the device) to the specified1744* {@code target} buffer (on the Java host). Elements are read starting at1745* the beginning of this buffer and stored in {@code target} beginning1746* at {@code position()} continuing up to, but excluding, {@code limit()}.1747* The {@code target} buffer position is set to {@code limit()}.1748* <p>1749* A sub-buffer may be created (see {@link #atOffset(long)}) when the source1750* data are not located at the beginning of this buffer.1751*1752* @param target1753* the destination buffer1754* @throws CudaException1755* if a CUDA exception occurs1756* @throws IllegalStateException1757* if this buffer has been closed (see {@link #close()})1758* @throws IndexOutOfBoundsException1759* if the number of required source bytes is larger than the length1760* of this buffer1761*/1762public void copyTo(ShortBuffer target) throws CudaException {1763final int fromIndex = target.position();1764final int toIndex = target.limit();17651766lengthCheck(toIndex - fromIndex, 1);17671768if (target.isDirect()) {1769copyToHostDirect(deviceId, getAddress(), // <br/>1770target, (long) fromIndex << 1, (long) toIndex << 1);1771} else if (target.hasArray()) {1772final int offset = target.arrayOffset();17731774copyTo(target.array(), fromIndex + offset, toIndex + offset);1775} else {1776final long byteCount = (long) (toIndex - fromIndex) << 1;1777final int chunkSize = chunkBytes(byteCount);1778final ShortBuffer tmp = allocateDirectBuffer(chunkSize) // <br/>1779.order(DeviceOrder).asShortBuffer();17801781try {1782for (long start = 0; start < byteCount; start += chunkSize) {1783final int chunk = (int) Math.min(byteCount - start,1784chunkSize);17851786tmp.position(0).limit(chunk >> 1);1787copyToHostDirect(deviceId, getAddress() + start, // <br/>1788tmp, 0, chunk);1789target.put(tmp);1790}1791} finally {1792freeDirectBuffer(tmp);1793}1794}17951796target.position(toIndex);1797}17981799/**1800* Stores {@code count} copies of {@code value} in this buffer.1801* <p>1802* A sub-buffer may be created (see {@link #atOffset(long)}) when the values1803* are to be stored somewhere other than the beginning of this buffer.1804*1805* @param value1806* the destination array1807* @param count1808* the destination array1809* @throws CudaException1810* if a CUDA exception occurs1811* @throws IllegalStateException1812* if this buffer has been closed (see {@link #close()})1813* @throws IndexOutOfBoundsException1814* if the space required is larger than the length of this buffer1815*/1816public void fillByte(byte value, long count) throws CudaException {1817lengthCheck(count, 0);1818fill(deviceId, getAddress(), Byte.SIZE / 8, value, count);1819}18201821/**1822* Stores {@code count} copies of {@code value} in this buffer.1823* <p>1824* A sub-buffer may be created (see {@link #atOffset(long)}) when the values1825* are to be stored somewhere other than the beginning of this buffer.1826*1827* @param value1828* the destination array1829* @param count1830* the destination array1831* @throws CudaException1832* if a CUDA exception occurs1833* @throws IllegalStateException1834* if this buffer has been closed (see {@link #close()})1835* @throws IndexOutOfBoundsException1836* if the space required is larger than the length of this buffer1837*/1838public void fillChar(char value, long count) throws CudaException {1839lengthCheck(count, 1);1840fill(deviceId, getAddress(), Character.SIZE / 8, value, count);1841}18421843/**1844* Stores {@code count} copies of {@code value} in this buffer.1845* <p>1846* A sub-buffer may be created (see {@link #atOffset(long)}) when the values1847* are to be stored somewhere other than the beginning of this buffer.1848*1849* @param value1850* the destination array1851* @param count1852* the destination array1853* @throws CudaException1854* if a CUDA exception occurs1855* @throws IllegalStateException1856* if this buffer has been closed (see {@link #close()})1857* @throws IndexOutOfBoundsException1858* if the space required is larger than the length of this buffer1859*/1860public void fillFloat(float value, long count) throws CudaException {1861fillInt(Float.floatToRawIntBits(value), count);1862}18631864/**1865* Stores {@code count} copies of {@code value} in this buffer.1866* <p>1867* A sub-buffer may be created (see {@link #atOffset(long)}) when the values1868* are to be stored somewhere other than the beginning of this buffer.1869*1870* @param value1871* the destination array1872* @param count1873* the destination array1874* @throws CudaException1875* if a CUDA exception occurs1876* @throws IllegalStateException1877* if this buffer has been closed (see {@link #close()})1878* @throws IndexOutOfBoundsException1879* if the space required is larger than the length of this buffer1880*/1881public void fillInt(int value, long count) throws CudaException {1882lengthCheck(count, 2);1883fill(deviceId, getAddress(), Integer.SIZE / 8, value, count);1884}18851886/**1887* Stores {@code count} copies of {@code value} in this buffer.1888* <p>1889* A sub-buffer may be created (see {@link #atOffset(long)}) when the values1890* are to be stored somewhere other than the beginning of this buffer.1891*1892* @param value1893* the destination array1894* @param count1895* the destination array1896* @throws CudaException1897* if a CUDA exception occurs1898* @throws IllegalStateException1899* if this buffer has been closed (see {@link #close()})1900* @throws IndexOutOfBoundsException1901* if the space required is larger than the length of this buffer1902*/1903public void fillShort(short value, long count) throws CudaException {1904lengthCheck(count, 1);1905fill(deviceId, getAddress(), Short.SIZE / 8, value, count);1906}19071908long getAddress() {1909long address = devicePtr.get();19101911if (address != 0) {1912if (parent == null || parent.devicePtr.get() != 0) {1913return address;1914}19151916// the parent buffer has been closed making this buffer invalid1917devicePtr.set(0);1918}19191920throw new IllegalStateException();1921}19221923/**1924* Returns the length in bytes of this buffer.1925*1926* @return1927* the length in bytes of this buffer1928*/1929public long getLength() {1930return length;1931}19321933private void lengthCheck(long elementCount, int logUnitSize) {1934if (!(0 <= elementCount && elementCount <= (length >> logUnitSize))) {1935throw new IndexOutOfBoundsException(String.valueOf(elementCount));1936}1937}19381939/**1940* Returns a sub-region of this buffer. The new buffer begins at the1941* specified fromOffset and extends to the specified toOffset (exclusive).1942*1943* @param fromOffset1944* the byte offset of the start of the sub-region within this buffer1945* @param toOffset1946* the byte offset of the end of the sub-region within this buffer1947* @return1948* the specified sub-region1949* @throws IllegalArgumentException1950* if {@code fromOffset > toOffset}1951* @throws IllegalStateException1952* if this buffer has been closed (see {@link #close()})1953* @throws IndexOutOfBoundsException1954* if {@code fromOffset} is negative, {@code toOffset > length},1955* or the number of source bytes is larger than the length1956* of this buffer1957*/1958public CudaBuffer slice(long fromOffset, long toOffset) {1959if (fromOffset == 0 && toOffset == length) {1960return this;1961} else {1962rangeCheck(length, fromOffset, toOffset);19631964return new CudaBuffer( // <br/>1965parent != null ? parent : this, // <br/>1966deviceId, // <br/>1967getAddress() + fromOffset, // <br/>1968toOffset - fromOffset);1969}1970}1971}197219731974