/*******************************************************************************1* Copyright (c) 2013, 2017 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* 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-exception20*******************************************************************************/2122#include "CudaCommon.hpp"23#include "java/com_ibm_cuda_CudaBuffer.h"2425#ifdef OMR_OPT_CUDA2627namespace28{2930/**31* A macro that expands the argument macro for each primitive type.32*/33#define SPECIALIZE_ALL(SPECIALIZATION) \34SPECIALIZATION(jbyte, Byte) \35SPECIALIZATION(jchar, Char) \36SPECIALIZATION(jfloat, Float) \37SPECIALIZATION(jdouble, Double) \38SPECIALIZATION(jint, Int) \39SPECIALIZATION(jlong, Long) \40SPECIALIZATION(jshort, Short)4142/**43* A template function (specialized for each primitive array type) that44* answers the size in bytes of an array of the specified length.45*46* @param[in] array the array reference47* @param[in] length the length of the array48* @return the size of the array49*/50template<typename ArrayType> size_t51arraySize(ArrayType array, jint length);5253/**54* A macro that expands to one specialization of the arraySize template.55*56* @param[in] Type the array element type57* @param[in] Name the name of the element type58*/59#define SPECIALIZE_ARRAY_SIZE(Type, Name) \60template<> inline size_t \61arraySize<Type##Array>(Type##Array array, jint length) \62{ return sizeof(Type) * (size_t)length; }6364/**65* Template specializations of arraySize for all primitive array types.66*/67SPECIALIZE_ALL(SPECIALIZE_ARRAY_SIZE)6869/**70* A template function (specialized for each primitive array type) that71* copies a region of the array into the specified buffer.72*73* @param[in] env the JNI interface pointer74* @param[in] array the array reference75* @param[in] start the source starting index (inclusive)76* @param[in] length the number of elements to be copied77* @param[in] buffer the destination buffer78*/79template<typename ArrayType> void80getArrayRegion(JNIEnv * env, ArrayType array, jint start, jint length, void * buffer);8182/**83* A macro that expands to one specialization of the getArrayRegion template.84*85* @param[in] Type the array element type86* @param[in] Name the name of the element type87*/88#define SPECIALIZE_GET_ARRAY_REGION(Type, Name) \89template<> inline void \90getArrayRegion<Type##Array>(JNIEnv * env, Type##Array array, jint start, jint length, void * buffer) \91{ env->Get##Name##ArrayRegion(array, start, length, (Type *)buffer); }9293/**94* Template specializations of getArrayRegion for all primitive array types.95*/96SPECIALIZE_ALL(SPECIALIZE_GET_ARRAY_REGION)9798/**99* A template function (specialized for each primitive array type) that100* sets a region of the array from the specified buffer.101*102* @param[in] env the JNI interface pointer103* @param[in] array the array reference104* @param[in] start the source starting index (inclusive)105* @param[in] length the number of elements to be copied106* @param[in] buffer the source buffer107*/108template<typename ArrayType> void109setArrayRegion(JNIEnv * env, ArrayType array, jint start, jint length, void * buffer);110111/**112* A macro that expands to one specialization of the setArrayRegion template.113*114* @param[in] Type the array element type115* @param[in] Name the name of the element type116*/117#define SPECIALIZE_SET_ARRAY_REGION(Type, Name) \118template<> inline void \119setArrayRegion<Type##Array>(JNIEnv * env, Type##Array array, jint start, jint length, void * buffer) \120{ env->Set##Name##ArrayRegion(array, start, length, (Type *)buffer); }121122/**123* Template specializations of setArrayRegion for all primitive array types.124*/125SPECIALIZE_ALL(SPECIALIZE_SET_ARRAY_REGION)126127/**128* Copy data from a Java primitive array to a region of device memory.129* The ArrayType template parameter identifies the type of the Java array.130* The data are copied to temporary host storage before the final transfer131* to device memory. The transfer to temporary host storage is required132* because j9cuda_memcpyHostToDevice may block, in violation of the contract133* for using GetPrimitiveArrayCritical (were it used instead).134*135* @param[in] env the JNI interface pointer136* @param[in] deviceId the device identifier137* @param[in] devicePtr the device pointer138* @param[in] array the source array139* @param[in] fromIndex the source starting index (inclusive)140* @param[in] toIndex the source ending index (exclusive)141*/142template<typename ArrayType> void143copyFromHost(144JNIEnv * env,145jint deviceId,146jlong devicePtr,147ArrayType array,148jint fromIndex,149jint toIndex)150{151jint length = toIndex - fromIndex;152size_t byteCount = arraySize(array, length);153154PORT_ACCESS_FROM_ENV(env);155156void * buffer = J9CUDA_ALLOCATE_MEMORY(byteCount);157int32_t error = J9CUDA_ERROR_MEMORY_ALLOCATION;158159if (NULL != buffer) {160getArrayRegion(env, array, fromIndex, length, buffer);161162error = j9cuda_memcpyHostToDevice(163(uint32_t)deviceId,164(void *)(uintptr_t)devicePtr,165buffer,166byteCount);167168J9CUDA_FREE_MEMORY(buffer);169}170171if (0 != error) {172throwCudaException(env, error);173}174}175176/**177* Copy data to a Java primitive array from a region of device memory.178* The ArrayType template parameter identifies the type of the Java array.179* The data are copied to temporary host storage before the final transfer180* to the array. The transfer to temporary host storage is required because181* j9cuda_memcpyDeviceToHost may block, in violation of the contract for182* using GetPrimitiveArrayCritical (were it used instead).183*184* @param[in] env the JNI interface pointer185* @param[in] deviceId the device identifier186* @param[in] devicePtr the device pointer187* @param[in] array the target array188* @param[in] fromIndex the target starting index (inclusive)189* @param[in] toIndex the target ending index (exclusive)190*/191template<typename ArrayType> void192copyToHost(JNIEnv * env, jint deviceId, jlong devicePtr, ArrayType array, jint fromIndex, jint toIndex)193{194jint length = toIndex - fromIndex;195size_t byteCount = arraySize(array, length);196197PORT_ACCESS_FROM_ENV(env);198199void * buffer = J9CUDA_ALLOCATE_MEMORY(byteCount);200int32_t error = J9CUDA_ERROR_MEMORY_ALLOCATION;201202if (NULL != buffer) {203error = j9cuda_memcpyDeviceToHost(204(uint32_t)deviceId,205buffer,206(void *)(uintptr_t)devicePtr,207byteCount);208209if (0 == error) {210setArrayRegion(env, array, fromIndex, length, buffer);211}212213J9CUDA_FREE_MEMORY(buffer);214}215216if (0 != error) {217throwCudaException(env, error);218}219}220221} // namespace222223#endif /* OMR_OPT_CUDA */224225/**226* Allocate a block of memory on the specified device.227*228* Class: com.ibm.cuda.CudaBuffer229* Method: allocate230* Signature: (IJ)J231*232* @param[in] env the JNI interface pointer233* @param[in] (unused) the class pointer234* @param[in] deviceId the device identifier235* @param[in] byteCount the number of bytes requested236* @return a pointer to the block of storage237*/238jlong JNICALL239Java_com_ibm_cuda_CudaBuffer_allocate240(JNIEnv * env, jclass, jint deviceId, jlong byteCount)241{242J9VMThread * thread = (J9VMThread *)env;243244Trc_cuda_bufferAllocate_entry(thread, deviceId, byteCount);245246void * devicePtr = NULL;247int32_t error = J9CUDA_ERROR_NO_DEVICE;248#ifdef OMR_OPT_CUDA249PORT_ACCESS_FROM_ENV(env);250error = j9cuda_deviceAlloc(deviceId, (uintptr_t)byteCount, &devicePtr);251#endif /* OMR_OPT_CUDA */252253if (0 != error) {254throwCudaException(env, error);255}256257Trc_cuda_bufferAllocate_exit(thread, devicePtr);258259return (jlong)devicePtr;260}261262#ifdef OMR_OPT_CUDA263264/**265* Allocate a direct NIO byte buffer of the specified capacity.266* The resulting buffer is used only internally within CudaBuffer for transfers267* involving NIO buffers that are neither direct nor backed by an array.268*269* Class: com.ibm.cuda.CudaBuffer270* Method: allocateDirectBuffer271* Signature: (J)Ljava/nio/ByteBuffer;272*273* @param[in] env the JNI interface pointer274* @param[in] (unused) the class pointer275* @param[in] capacity the requested buffer capacity in bytes276* @return a pointer to the byte buffer277*/278jobject JNICALL279Java_com_ibm_cuda_CudaBuffer_allocateDirectBuffer280(JNIEnv * env, jclass, jlong capacity)281{282J9VMThread * thread = (J9VMThread *)env;283284Trc_cuda_bufferAllocateDirectBuffer_entry(thread, capacity);285286PORT_ACCESS_FROM_ENV(env);287288void * buffer = J9CUDA_ALLOCATE_MEMORY((size_t)capacity);289jobject result = NULL;290291if (NULL == buffer) {292Trc_cuda_bufferAllocateDirectBuffer_allocFail(thread);293throwCudaException(env, J9CUDA_ERROR_MEMORY_ALLOCATION);294} else {295result = env->NewDirectByteBuffer(buffer, capacity);296297if ((NULL == result) || env->ExceptionCheck()) {298Trc_cuda_bufferAllocateDirectBuffer_newFail(thread);299J9CUDA_FREE_MEMORY(buffer);300buffer = NULL;301result = NULL;302}303}304305Trc_cuda_bufferAllocateDirectBuffer_exit(thread, result, buffer);306307return result;308}309310/**311* Copy data to device memory from device memory; the source may be on the same312* or a different device.313*314* Class: com.ibm.cuda.CudaBuffer315* Method: copyFromDevice316* Signature: (IJIJJ)V317*318* @param[in] env the JNI interface pointer319* @param[in] (unused) the class pointer320* @param[in] targetDeviceId the target device identifier321* @param[in] targetAddress the target device pointer322* @param[in] sourceDeviceId the source device identifier323* @param[in] sourceAddress the source device pointer324* @param[in] byteCount the number of bytes to be copied325*/326void JNICALL327Java_com_ibm_cuda_CudaBuffer_copyFromDevice328(JNIEnv * env, jclass, jint targetDeviceId, jlong targetAddress, jint sourceDeviceId, jlong sourceAddress, jlong byteCount)329{330J9VMThread * thread = (J9VMThread *)env;331332Trc_cuda_bufferCopyFromDevice_entry(333thread,334targetDeviceId, (uintptr_t)targetAddress,335sourceDeviceId, (uintptr_t)sourceAddress, byteCount);336337PORT_ACCESS_FROM_ENV(env);338339int32_t error = 0;340341if (targetDeviceId == sourceDeviceId) {342error = j9cuda_memcpyDeviceToDevice(343(uint32_t)targetDeviceId,344(void *)(uintptr_t)targetAddress,345(const void *)(uintptr_t)sourceAddress,346(uintptr_t)byteCount);347} else {348error = j9cuda_memcpyPeer(349(uint32_t)targetDeviceId,350(void *)(uintptr_t)targetAddress,351(uint32_t)sourceDeviceId,352(const void *)(uintptr_t)sourceAddress,353(uintptr_t)byteCount);354}355356if (0 != error) {357Trc_cuda_bufferCopyFromDevice_fail(thread, error);358throwCudaException(env, error);359}360361Trc_cuda_bufferCopyFromDevice_exit(thread);362}363364/**365* Copy data to device memory from a Java byte array.366*367* Class: com.ibm.cuda.CudaBuffer368* Method: copyFromHostByte369* Signature: (IJ[BII)V370*371* @param[in] env the JNI interface pointer372* @param[in] (unused) the class pointer373* @param[in] deviceId the device identifier374* @param[in] devicePtr the device pointer375* @param[in] array the source array376* @param[in] fromIndex the source starting index (inclusive)377* @param[in] toIndex the source ending index (exclusive)378*/379void JNICALL380Java_com_ibm_cuda_CudaBuffer_copyFromHostByte381(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jbyteArray array, jint fromIndex, jint toIndex)382{383J9VMThread * thread = (J9VMThread *)env;384385Trc_cuda_bufferCopyFromHostByte_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);386387copyFromHost(env, deviceId, devicePtr, array, fromIndex, toIndex);388389Trc_cuda_bufferCopyFromHostByte_exit(thread);390}391392/**393* Copy data to device memory from a Java char array.394*395* Class: com.ibm.cuda.CudaBuffer396* Method: copyFromHostChar397* Signature: (IJ[CII)V398*399* @param[in] env the JNI interface pointer400* @param[in] (unused) the class pointer401* @param[in] deviceId the device identifier402* @param[in] devicePtr the device pointer403* @param[in] array the source array404* @param[in] fromIndex the source starting index (inclusive)405* @param[in] toIndex the source ending index (exclusive)406*/407void JNICALL408Java_com_ibm_cuda_CudaBuffer_copyFromHostChar409(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jcharArray array, jint fromIndex, jint toIndex)410{411J9VMThread * thread = (J9VMThread *)env;412413Trc_cuda_bufferCopyFromHostChar_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);414415copyFromHost(env, deviceId, devicePtr, array, fromIndex, toIndex);416417Trc_cuda_bufferCopyFromHostChar_exit(thread);418}419420/**421* Copy data to device memory from a direct NIO buffer.422*423* Class: com.ibm.cuda.CudaBuffer424* Method: copyFromHostDirect425* Signature: (IJLjava/nio/Buffer;JJ)V426*427* @param[in] env the JNI interface pointer428* @param[in] (unused) the class pointer429* @param[in] deviceId the device identifier430* @param[in] devicePtr the device pointer431* @param[in] source the source buffer432* @param[in] fromOffset the source starting byte offset (inclusive)433* @param[in] toOffset the source ending byte offset (exclusive)434*/435void JNICALL436Java_com_ibm_cuda_CudaBuffer_copyFromHostDirect437(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jobject source, jlong fromOffset, jlong toOffset)438{439J9VMThread * thread = (J9VMThread *)env;440441Trc_cuda_bufferCopyFromHostDirect_entry(thread, deviceId, (uintptr_t)devicePtr, source, fromOffset, toOffset);442443jbyte const * buffer = (jbyte const *)env->GetDirectBufferAddress(source);444int32_t error = J9CUDA_ERROR_OPERATING_SYSTEM;445446if (NULL != buffer) {447PORT_ACCESS_FROM_ENV(env);448449error = j9cuda_memcpyHostToDevice(450(uint32_t)deviceId,451(void *)(uintptr_t)devicePtr,452&buffer[fromOffset],453(size_t)(toOffset - fromOffset));454}455456if (0 != error) {457throwCudaException(env, error);458}459460Trc_cuda_bufferCopyFromHostDirect_exit(thread);461}462463/**464* Copy data to device memory from a Java double array.465*466* Class: com.ibm.cuda.CudaBuffer467* Method: copyFromHostDouble468* Signature: (IJ[DII)V469*470* @param[in] env the JNI interface pointer471* @param[in] (unused) the class pointer472* @param[in] deviceId the device identifier473* @param[in] devicePtr the device pointer474* @param[in] array the source array475* @param[in] fromIndex the source starting index (inclusive)476* @param[in] toIndex the source ending index (exclusive)477*/478void JNICALL479Java_com_ibm_cuda_CudaBuffer_copyFromHostDouble480(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jdoubleArray array, jint fromIndex, jint toIndex)481{482J9VMThread * thread = (J9VMThread *)env;483484Trc_cuda_bufferCopyFromHostDouble_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);485486copyFromHost(env, deviceId, devicePtr, array, fromIndex, toIndex);487488Trc_cuda_bufferCopyFromHostDouble_exit(thread);489}490491/**492* Copy data to device memory from a Java float array.493*494* Class: com.ibm.cuda.CudaBuffer495* Method: copyFromHostFloat496* Signature: (IJ[FII)V497*498* @param[in] env the JNI interface pointer499* @param[in] (unused) the class pointer500* @param[in] deviceId the device identifier501* @param[in] devicePtr the device pointer502* @param[in] array the source array503* @param[in] fromIndex the source starting index (inclusive)504* @param[in] toIndex the source ending index (exclusive)505*/506void JNICALL507Java_com_ibm_cuda_CudaBuffer_copyFromHostFloat508(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jfloatArray array, jint fromIndex, jint toIndex)509{510J9VMThread * thread = (J9VMThread *)env;511512Trc_cuda_bufferCopyFromHostFloat_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);513514copyFromHost(env, deviceId, devicePtr, array, fromIndex, toIndex);515516Trc_cuda_bufferCopyFromHostFloat_exit(thread);517}518519/**520* Copy data to device memory from a Java int array.521*522* Class: com.ibm.cuda.CudaBuffer523* Method: copyFromHostInt524* Signature: (IJ[III)V525*526* @param[in] env the JNI interface pointer527* @param[in] (unused) the class pointer528* @param[in] deviceId the device identifier529* @param[in] devicePtr the device pointer530* @param[in] array the source array531* @param[in] fromIndex the source starting index (inclusive)532* @param[in] toIndex the source ending index (exclusive)533*/534void JNICALL535Java_com_ibm_cuda_CudaBuffer_copyFromHostInt536(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jintArray array, jint fromIndex, jint toIndex)537{538J9VMThread * thread = (J9VMThread *)env;539540Trc_cuda_bufferCopyFromHostInt_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);541542copyFromHost(env, deviceId, devicePtr, array, fromIndex, toIndex);543544Trc_cuda_bufferCopyFromHostInt_exit(thread);545}546547/**548* Copy data to device memory from a Java long array.549*550* Class: com.ibm.cuda.CudaBuffer551* Method: copyFromHostLong552* Signature: (IJ[JII)V553*554* @param[in] env the JNI interface pointer555* @param[in] (unused) the class pointer556* @param[in] deviceId the device identifier557* @param[in] devicePtr the device pointer558* @param[in] array the source array559* @param[in] fromIndex the source starting index (inclusive)560* @param[in] toIndex the source ending index (exclusive)561*/562void JNICALL563Java_com_ibm_cuda_CudaBuffer_copyFromHostLong564(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jlongArray array, jint fromIndex, jint toIndex)565{566J9VMThread * thread = (J9VMThread *)env;567568Trc_cuda_bufferCopyFromHostLong_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);569570copyFromHost(env, deviceId, devicePtr, array, fromIndex, toIndex);571572Trc_cuda_bufferCopyFromHostLong_exit(thread);573}574575/**576* Copy data to device memory from a Java short array.577*578* Class: com.ibm.cuda.CudaBuffer579* Method: copyFromHostShort580* Signature: (IJ[SII)V581*582* @param[in] env the JNI interface pointer583* @param[in] (unused) the class pointer584* @param[in] deviceId the device identifier585* @param[in] devicePtr the device pointer586* @param[in] array the source array587* @param[in] fromIndex the source starting index (inclusive)588* @param[in] toIndex the source ending index (exclusive)589*/590void JNICALL591Java_com_ibm_cuda_CudaBuffer_copyFromHostShort592(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jshortArray array, jint fromIndex, jint toIndex)593{594J9VMThread * thread = (J9VMThread *)env;595596Trc_cuda_bufferCopyFromHostShort_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);597598copyFromHost(env, deviceId, devicePtr, array, fromIndex, toIndex);599600Trc_cuda_bufferCopyFromHostShort_exit(thread);601}602603/**604* Copy data from device memory to a Java byte array.605*606* Class: com.ibm.cuda.CudaBuffer607* Method: copyToHostByte608* Signature: (IJ[BII)V609*610* @param[in] env the JNI interface pointer611* @param[in] (unused) the class pointer612* @param[in] deviceId the device identifier613* @param[in] devicePtr the device pointer614* @param[in] array the target array615* @param[in] fromIndex the target starting index (inclusive)616* @param[in] toIndex the target ending index (exclusive)617*/618void JNICALL619Java_com_ibm_cuda_CudaBuffer_copyToHostByte620(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jbyteArray array, jint fromIndex, jint toIndex)621{622J9VMThread * thread = (J9VMThread *)env;623624Trc_cuda_bufferCopyToHostByte_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);625626copyToHost(env, deviceId, devicePtr, array, fromIndex, toIndex);627628Trc_cuda_bufferCopyToHostByte_exit(thread);629}630631/**632* Copy data from device memory to a Java char array.633*634* Class: com.ibm.cuda.CudaBuffer635* Method: copyToHostChar636* Signature: (IJ[CII)V637*638* @param[in] env the JNI interface pointer639* @param[in] (unused) the class pointer640* @param[in] deviceId the device identifier641* @param[in] devicePtr the device pointer642* @param[in] array the target array643* @param[in] fromIndex the target starting index (inclusive)644* @param[in] toIndex the target ending index (exclusive)645*/646void JNICALL647Java_com_ibm_cuda_CudaBuffer_copyToHostChar648(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jcharArray array, jint fromIndex, jint toIndex)649{650J9VMThread * thread = (J9VMThread *)env;651652Trc_cuda_bufferCopyToHostChar_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);653654copyToHost(env, deviceId, devicePtr, array, fromIndex, toIndex);655656Trc_cuda_bufferCopyToHostChar_exit(thread);657}658659/**660* Copy data from device memory to a direct NIO buffer.661*662* Class: com.ibm.cuda.CudaBuffer663* Method: copyToHostDirect664* Signature: (IJLjava/nio/Buffer;JJ)V665*666* @param[in] env the JNI interface pointer667* @param[in] (unused) the class pointer668* @param[in] deviceId the device identifier669* @param[in] devicePtr the device pointer670* @param[in] target the target buffer671* @param[in] fromOffset the target starting byte offset (inclusive)672* @param[in] toOffset the target ending byte offset (exclusive)673*/674void JNICALL675Java_com_ibm_cuda_CudaBuffer_copyToHostDirect676(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jobject target, jlong fromOffset, jlong toOffset)677{678J9VMThread * thread = (J9VMThread *)env;679680Trc_cuda_bufferCopyToHostDirect_entry(thread, deviceId, (uintptr_t)devicePtr, target, fromOffset, toOffset);681682jbyte * buffer = (jbyte *)env->GetDirectBufferAddress(target);683int32_t error = J9CUDA_ERROR_OPERATING_SYSTEM;684685if (NULL != buffer) {686PORT_ACCESS_FROM_ENV(env);687688error = j9cuda_memcpyDeviceToHost(689(uint32_t)deviceId,690&buffer[fromOffset],691(void *)(uintptr_t)devicePtr,692(size_t)(toOffset - fromOffset));693}694695if (0 != error) {696throwCudaException(env, error);697}698699Trc_cuda_bufferCopyToHostDirect_exit(thread);700}701702/**703* Copy data from device memory to a Java double array.704*705* Class: com.ibm.cuda.CudaBuffer706* Method: copyToHostDouble707* Signature: (IJ[DII)V708*709* @param[in] env the JNI interface pointer710* @param[in] (unused) the class pointer711* @param[in] deviceId the device identifier712* @param[in] devicePtr the device pointer713* @param[in] array the target array714* @param[in] fromIndex the target starting index (inclusive)715* @param[in] toIndex the target ending index (exclusive)716*/717void JNICALL718Java_com_ibm_cuda_CudaBuffer_copyToHostDouble719(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jdoubleArray array, jint fromIndex, jint toIndex)720{721J9VMThread * thread = (J9VMThread *)env;722723Trc_cuda_bufferCopyToHostDouble_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);724725copyToHost(env, deviceId, devicePtr, array, fromIndex, toIndex);726727Trc_cuda_bufferCopyToHostDouble_exit(thread);728}729730/**731* Copy data from device memory to a Java float array.732*733* Class: com.ibm.cuda.CudaBuffer734* Method: copyToHostFloat735* Signature: (IJ[FII)V736*737* @param[in] env the JNI interface pointer738* @param[in] (unused) the class pointer739* @param[in] deviceId the device identifier740* @param[in] devicePtr the device pointer741* @param[in] array the target array742* @param[in] fromIndex the target starting index (inclusive)743* @param[in] toIndex the target ending index (exclusive)744*/745void JNICALL746Java_com_ibm_cuda_CudaBuffer_copyToHostFloat747(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jfloatArray array, jint fromIndex, jint toIndex)748{749J9VMThread * thread = (J9VMThread *)env;750751Trc_cuda_bufferCopyToHostFloat_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);752753copyToHost(env, deviceId, devicePtr, array, fromIndex, toIndex);754755Trc_cuda_bufferCopyToHostFloat_exit(thread);756}757758/**759* Copy data from device memory to a Java int array.760*761* Class: com.ibm.cuda.CudaBuffer762* Method: copyToHostInt763* Signature: (IJ[III)V764*765* @param[in] env the JNI interface pointer766* @param[in] (unused) the class pointer767* @param[in] deviceId the device identifier768* @param[in] devicePtr the device pointer769* @param[in] array the target array770* @param[in] fromIndex the target starting index (inclusive)771* @param[in] toIndex the target ending index (exclusive)772*/773void JNICALL774Java_com_ibm_cuda_CudaBuffer_copyToHostInt775(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jintArray array, jint fromIndex, jint toIndex)776{777J9VMThread * thread = (J9VMThread *)env;778779Trc_cuda_bufferCopyToHostInt_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);780781copyToHost(env, deviceId, devicePtr, array, fromIndex, toIndex);782783Trc_cuda_bufferCopyToHostInt_exit(thread);784}785786/**787* Copy data from device memory to a Java long array.788*789* Class: com.ibm.cuda.CudaBuffer790* Method: copyToHostLong791* Signature: (IJ[JII)V792*793* @param[in] env the JNI interface pointer794* @param[in] (unused) the class pointer795* @param[in] deviceId the device identifier796* @param[in] devicePtr the device pointer797* @param[in] array the target array798* @param[in] fromIndex the target starting index (inclusive)799* @param[in] toIndex the target ending index (exclusive)800*/801void JNICALL802Java_com_ibm_cuda_CudaBuffer_copyToHostLong803(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jlongArray array, jint fromIndex, jint toIndex)804{805J9VMThread * thread = (J9VMThread *)env;806807Trc_cuda_bufferCopyToHostLong_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);808809copyToHost(env, deviceId, devicePtr, array, fromIndex, toIndex);810811Trc_cuda_bufferCopyToHostLong_exit(thread);812}813814/**815* Copy data from device memory to a Java short array.816*817* Class: com.ibm.cuda.CudaBuffer818* Method: copyToHostShort819* Signature: (IJ[SII)V820*821* @param[in] env the JNI interface pointer822* @param[in] (unused) the class pointer823* @param[in] deviceId the device identifier824* @param[in] devicePtr the device pointer825* @param[in] array the target array826* @param[in] fromIndex the target starting index (inclusive)827* @param[in] toIndex the target ending index (exclusive)828*/829void JNICALL830Java_com_ibm_cuda_CudaBuffer_copyToHostShort831(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jshortArray array, jint fromIndex, jint toIndex)832{833J9VMThread * thread = (J9VMThread *)env;834835Trc_cuda_bufferCopyToHostShort_entry(thread, deviceId, (uintptr_t)devicePtr, array, fromIndex, toIndex);836837copyToHost(env, deviceId, devicePtr, array, fromIndex, toIndex);838839Trc_cuda_bufferCopyToHostShort_exit(thread);840}841842/**843* Fill device memory with a repeating value.844*845* Class: com.ibm.cuda.CudaBuffer846* Method: fill847* Signature: (IJIIJ)V848*849* @param[in] env the JNI interface pointer850* @param[in] (unused) the class pointer851* @param[in] deviceId the device identifier852* @param[in] devicePtr the device pointer853* @param[in] elemSize the value size in bytes854* @param[in] value the value to be repeated855* @param[in] count the number of copies requested856*/857void JNICALL858Java_com_ibm_cuda_CudaBuffer_fill859(JNIEnv * env, jclass, jint deviceId, jlong devicePtr, jint elemSize, jint value, jlong count)860{861J9VMThread * thread = (J9VMThread *)env;862863Trc_cuda_bufferFill_entry(thread, deviceId, (uintptr_t)devicePtr, elemSize, value, count);864865PORT_ACCESS_FROM_ENV(env);866867int32_t error = J9CUDA_ERROR_INVALID_VALUE;868869switch (elemSize) {870case 1:871error = j9cuda_memset8 ((uint32_t)deviceId, (void *)(uintptr_t)devicePtr, (uint8_t) value, (uintptr_t)count);872break;873case 2:874error = j9cuda_memset16((uint32_t)deviceId, (void *)(uintptr_t)devicePtr, (uint16_t)value, (uintptr_t)count);875break;876case 4:877error = j9cuda_memset32((uint32_t)deviceId, (void *)(uintptr_t)devicePtr, (uint32_t)value, (uintptr_t)count);878break;879default:880break;881}882883if (0 != error) {884throwCudaException(env, error);885}886887Trc_cuda_bufferFill_exit(thread);888}889890/**891* Release a direct NIO byte buffer allocated by allocateDirectBuffer.892*893* Class: com.ibm.cuda.CudaBuffer894* Method: allocateDirectBuffer895* Signature: (J)Ljava/nio/ByteBuffer;896*897* @param[in] env the JNI interface pointer898* @param[in] (unused) the class pointer899* @param[in] byteBuffer the byte buffer900901* Class: com.ibm.cuda.CudaBuffer902* Method: freeDirectBuffer903* Signature: (Ljava/nio/Buffer;)V904*/905void JNICALL906Java_com_ibm_cuda_CudaBuffer_freeDirectBuffer907(JNIEnv * env, jclass, jobject byteBuffer)908{909J9VMThread * thread = (J9VMThread *)env;910911Trc_cuda_bufferFreeDirectBuffer_entry(thread, byteBuffer);912913void * buffer = env->GetDirectBufferAddress(byteBuffer);914915if (NULL != buffer) {916PORT_ACCESS_FROM_ENV(env);917918J9CUDA_FREE_MEMORY(buffer);919}920921Trc_cuda_bufferFreeDirectBuffer_exit(thread);922}923924/**925* Release a block of memory on the specified device.926*927* Class: com.ibm.cuda.CudaBuffer928* Method: release929* Signature: (IJ)V930*931* @param[in] env the JNI interface pointer932* @param[in] (unused) the class pointer933* @param[in] deviceId the device identifier934* @param[in] devicePtr the device pointer935*/936void JNICALL937Java_com_ibm_cuda_CudaBuffer_release938(JNIEnv * env, jclass, jint deviceId, jlong devicePtr)939{940J9VMThread * thread = (J9VMThread *)env;941942Trc_cuda_bufferRelease_entry(thread, deviceId, (uintptr_t)devicePtr);943944PORT_ACCESS_FROM_ENV(env);945946int32_t error = j9cuda_deviceFree(deviceId, (void *)(uintptr_t)devicePtr);947948if (0 != error) {949throwCudaException(env, error);950}951952Trc_cuda_bufferRelease_exit(thread);953}954955#endif /* OMR_OPT_CUDA */956957958