Files
pj2/lib/edu_rit_gpu_Cuda.c
2016-04-27 01:07:35 -04:00

1070 lines
28 KiB
C

//******************************************************************************
//
// File: Cuda.c
// Package: edu.rit.gpu
// Unit: Class edu.rit.gpu.Cuda
//
// This C source file is copyright (C) 2014 by Alan Kaminsky. All rights
// reserved. For further information, contact the author, Alan Kaminsky, at
// ark@cs.rit.edu.
//
// This C source file is part of the Parallel Java 2 Library ("PJ2"). PJ2 is
// free software; you can redistribute it and/or modify it under the terms of
// the GNU General Public License as published by the Free Software Foundation;
// either version 3 of the License, or (at your option) any later version.
//
// PJ2 is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// A copy of the GNU General Public License is provided in the file gpl.txt. You
// may also obtain a copy of the GNU General Public License on the World Wide
// Web at http://www.gnu.org/licenses/gpl.html.
//
//******************************************************************************
#include <jni.h>
#include <cuda.h>
#include <builtin_types.h>
#include "edu_rit_gpu_Cuda.h"
/**
* File Cuda.c contains the C code implementations of the native methods in
* class edu.rit.gpu.Cuda.
*
* @author Alan Kaminsky
* @version 19-Feb-2014
*/
/*
* Convert a C pointer to a Java long.
*/
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
#define cptr_to_jlong(x) ((jlong)x)
#else
#define cptr_to_jlong(x) ((jlong)((jint)x))
#endif
/*
* Convert a Java long to a C pointer.
*/
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
#define jlong_to_cptr(x) ((void*)x)
#else
#define jlong_to_cptr(x) ((void*)((jint)x))
#endif
/*
* Convert a C size_t to a Java long.
*/
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
#define csize_t_to_jlong(x) ((jlong)x)
#else
#define csize_t_to_jlong(x) ((jlong)((jint)x))
#endif
/*
* Convert a Java long to a C size_t.
*/
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
#define jlong_to_csize_t(x) ((size_t)x)
#else
#define jlong_to_csize_t(x) ((size_t)((jint)x))
#endif
/*
* Convert a C CUdeviceptr to a Java long.
*/
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
#define CUdeviceptr_to_jlong(x) ((jlong)x)
#else
#define CUdeviceptr_to_jlong(x) ((jlong)((jint)x))
#endif
/*
* Convert a Java long to a C CUdeviceptr.
*/
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
#define jlong_to_CUdeviceptr(x) ((CUdeviceptr)x)
#else
#define jlong_to_CUdeviceptr(x) ((CUdeviceptr)((jint)x))
#endif
/*
* If rv is not CUDA_SUCCESS, throw the appropriate Java exception.
* Returns 1 if an exception was thrown, 0 otherwise.
*/
int throwCudaException
(JNIEnv *env,
const CUresult rv,
const char *msg)
{
char *name;
jclass cls;
if (rv == CUDA_SUCCESS) return 0;
switch (rv)
{
case CUDA_ERROR_DEINITIALIZED:
name = "edu/rit/gpu/DeinitializedCudaException";
break;
case CUDA_ERROR_FILE_NOT_FOUND:
name = "edu/rit/gpu/FileNotFoundCudaException";
break;
case CUDA_ERROR_INVALID_CONTEXT:
name = "edu/rit/gpu/InvalidContextCudaException";
break;
case CUDA_ERROR_INVALID_DEVICE:
name = "edu/rit/gpu/InvalidDeviceCudaException";
break;
case CUDA_ERROR_INVALID_HANDLE:
name = "edu/rit/gpu/InvalidHandleCudaException";
break;
case CUDA_ERROR_INVALID_IMAGE:
name = "edu/rit/gpu/InvalidImageCudaException";
break;
case CUDA_ERROR_INVALID_VALUE:
name = "edu/rit/gpu/InvalidValueCudaException";
break;
case CUDA_ERROR_LAUNCH_FAILED:
name = "edu/rit/gpu/LaunchFailedCudaException";
break;
case CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING:
name = "edu/rit/gpu/LaunchIncompatibleTexturingCudaException";
break;
case CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES:
name = "edu/rit/gpu/LaunchOutOfResourcesCudaException";
break;
case CUDA_ERROR_LAUNCH_TIMEOUT:
name = "edu/rit/gpu/LaunchTimeoutCudaException";
break;
case CUDA_ERROR_NOT_FOUND:
name = "edu/rit/gpu/NotFoundCudaException";
break;
case CUDA_ERROR_NOT_INITIALIZED:
name = "edu/rit/gpu/NotInitializedCudaException";
break;
case CUDA_ERROR_OUT_OF_MEMORY:
name = "edu/rit/gpu/OutOfMemoryCudaException";
break;
case CUDA_ERROR_SHARED_OBJECT_INIT_FAILED:
name = "edu/rit/gpu/SharedObjectInitFailedCudaException";
break;
case CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND:
name = "edu/rit/gpu/SharedObjectSymbolNotFoundCudaException";
break;
case CUDA_ERROR_UNKNOWN:
name = "edu/rit/gpu/UnknownCudaException";
break;
default:
name = "edu/rit/gpu/CudaException";
break;
}
cls = (*env)->FindClass (env, name);
if (cls != NULL)
(*env)->ThrowNew (env, cls, msg);
(*env)->DeleteLocalRef (env, cls);
return 1;
}
/*
* Class: edu_rit_gpu_Cuda
* Method: is64BitPointer
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_edu_rit_gpu_Cuda_is64BitPointer
(JNIEnv *env,
jclass cls)
{
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
return 1;
#else
return 0;
#endif
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuInit
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuInit
(JNIEnv *env,
jclass cls,
jint flags)
{
CUresult rv = cuInit (flags);
throwCudaException (env, rv, "calling cuInit()");
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuDeviceGetCount
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_edu_rit_gpu_Cuda_cuDeviceGetCount
(JNIEnv *env,
jclass cls)
{
jint count = 0;
CUresult rv = cuDeviceGetCount (&count);
throwCudaException (env, rv, "calling cuDeviceGetCount()");
return count;
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuDeviceGet
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_edu_rit_gpu_Cuda_cuDeviceGet
(JNIEnv *env,
jclass cls,
jint ordinal)
{
CUdevice device = 0;
CUresult rv = cuDeviceGet (&device, ordinal);
throwCudaException (env, rv, "calling cuDeviceGet()");
return device;
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuDeviceGetName
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_edu_rit_gpu_Cuda_cuDeviceGetName
(JNIEnv *env,
jclass cls,
jint device)
{
char name [128];
name[0] = '\0';
CUresult rv = cuDeviceGetName (name, 127, device);
throwCudaException (env, rv, "calling cuDeviceGetName()");
return (*env)->NewStringUTF (env, name);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuDeviceGetAttributeComputeCapabilityMajor
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jint JNICALL Java_edu_rit_gpu_Cuda_cuDeviceGetAttributeComputeCapabilityMajor
(JNIEnv *env,
jclass cls,
jint device)
{
jint pi = 0;
CUresult rv = cuDeviceGetAttribute
(&pi, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, device);
throwCudaException (env, rv, "calling cuDeviceGetAttribute()");
return pi;
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuDeviceGetAttributeComputeCapabilityMinor
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jint JNICALL Java_edu_rit_gpu_Cuda_cuDeviceGetAttributeComputeCapabilityMinor
(JNIEnv *env,
jclass cls,
jint device)
{
jint pi = 0;
CUresult rv = cuDeviceGetAttribute
(&pi, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, device);
throwCudaException (env, rv, "calling cuDeviceGetAttribute()");
return pi;
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuDeviceGetAttributeMultiprocessorCount
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_edu_rit_gpu_Cuda_cuDeviceGetAttributeMultiprocessorCount
(JNIEnv *env,
jclass cls,
jint device)
{
jint pi = 0;
CUresult rv = cuDeviceGetAttribute
(&pi, CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT, device);
throwCudaException (env, rv, "calling cuDeviceGetAttribute()");
return pi;
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuCtxCreate
* Signature: (II)J
*/
JNIEXPORT jlong JNICALL Java_edu_rit_gpu_Cuda_cuCtxCreate
(JNIEnv *env,
jclass cls,
jint flags,
jint device)
{
CUcontext ctx = NULL;
CUresult rv = cuCtxCreate (&ctx, flags, device);
throwCudaException (env, rv, "calling cuCtxCreate()");
return cptr_to_jlong (ctx);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuCtxDestroy
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuCtxDestroy
(JNIEnv *env,
jclass cls,
jlong ctx)
{
CUresult rv = cuCtxDestroy ((CUcontext) jlong_to_cptr (ctx));
throwCudaException (env, rv, "calling cuCtxDestroy()");
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuCtxSetCacheConfig
* Signature: (JI)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuCtxSetCacheConfig
(JNIEnv *env,
jclass cls,
jlong ctx,
jint config)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUresult rv;
int exc = 0;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuCtxSetCacheConfig (config);
exc = throwCudaException (env, rv, "calling cuCtxSetCacheConfig()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuCtxGetCacheConfig
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_edu_rit_gpu_Cuda_cuCtxGetCacheConfig
(JNIEnv *env,
jclass cls,
jlong ctx)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUfunc_cache config;
CUresult rv;
int exc = 0;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuCtxGetCacheConfig (&config);
exc = throwCudaException (env, rv, "calling cuCtxGetCacheConfig()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
return config;
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemAlloc
* Signature: (JJ)J
*/
JNIEXPORT jlong JNICALL Java_edu_rit_gpu_Cuda_cuMemAlloc
(JNIEnv *env,
jclass cls,
jlong ctx,
jlong bytesize)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
size_t N = jlong_to_csize_t (bytesize);
CUdeviceptr dptr = 0;
CUresult rv;
int exc = 0;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemAlloc (&dptr, N);
exc = throwCudaException (env, rv, "calling cuMemAlloc()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
return CUdeviceptr_to_jlong (dptr);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemFree
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuMemFree
(JNIEnv *env,
jclass cls,
jlong ctx,
jlong dptr)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUdeviceptr ptr = jlong_to_CUdeviceptr (dptr);
CUresult rv;
int exc = 0;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemFree (ptr);
exc = throwCudaException (env, rv, "calling cuMemFree()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemcpyHtoD
* Signature: (JJI[BII)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuMemcpyHtoD__JJI_3BII
(JNIEnv *env,
jclass cls,
jlong ctx,
jlong dst,
jint dstindex,
jbyteArray src,
jint srcindex,
jint nelem)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUdeviceptr dptr = jlong_to_CUdeviceptr (dst + dstindex*sizeof(jbyte));
size_t N = nelem*sizeof(jbyte);
CUresult rv;
int exc = 0;
jbyte *csrc = (*env)->GetByteArrayElements (env, src, NULL);
if (csrc == NULL) return;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemcpyHtoD (dptr, csrc + srcindex, N);
exc = throwCudaException (env, rv, "calling cuMemcpyHtoD()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseByteArrayElements (env, src, csrc, 0);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemcpyDtoH
* Signature: (J[BIJII)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuMemcpyDtoH__J_3BIJII
(JNIEnv *env,
jclass cls,
jlong ctx,
jbyteArray dst,
jint dstindex,
jlong src,
jint srcindex,
jint nelem)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUdeviceptr dptr = jlong_to_CUdeviceptr (src + srcindex*sizeof(jbyte));
size_t N = nelem*sizeof(jbyte);
CUresult rv;
int exc = 0;
jbyte *cdst = (*env)->GetByteArrayElements (env, dst, NULL);
if (cdst == NULL) return;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemcpyDtoH (cdst + dstindex, dptr, N);
exc = throwCudaException (env, rv, "calling cuMemcpyDtoH()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseByteArrayElements (env, dst, cdst, 0);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemcpyHtoD
* Signature: (JJI[SII)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuMemcpyHtoD__JJI_3SII
(JNIEnv *env,
jclass cls,
jlong ctx,
jlong dst,
jint dstindex,
jshortArray src,
jint srcindex,
jint nelem)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUdeviceptr dptr = jlong_to_CUdeviceptr (dst + dstindex*sizeof(jshort));
size_t N = nelem*sizeof(jshort);
CUresult rv;
int exc = 0;
jshort *csrc = (*env)->GetShortArrayElements (env, src, NULL);
if (csrc == NULL) return;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemcpyHtoD (dptr, csrc + srcindex, N);
exc = throwCudaException (env, rv, "calling cuMemcpyHtoD()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseShortArrayElements (env, src, csrc, 0);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemcpyDtoH
* Signature: (J[SIJII)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuMemcpyDtoH__J_3SIJII
(JNIEnv *env,
jclass cls,
jlong ctx,
jshortArray dst,
jint dstindex,
jlong src,
jint srcindex,
jint nelem)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUdeviceptr dptr = jlong_to_CUdeviceptr (src + srcindex*sizeof(jshort));
size_t N = nelem*sizeof(jshort);
CUresult rv;
int exc = 0;
jshort *cdst = (*env)->GetShortArrayElements (env, dst, NULL);
if (cdst == NULL) return;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemcpyDtoH (cdst + dstindex, dptr, N);
exc = throwCudaException (env, rv, "calling cuMemcpyDtoH()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseShortArrayElements (env, dst, cdst, 0);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemcpyHtoD
* Signature: (JJI[III)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuMemcpyHtoD__JJI_3III
(JNIEnv *env,
jclass cls,
jlong ctx,
jlong dst,
jint dstindex,
jintArray src,
jint srcindex,
jint nelem)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUdeviceptr dptr = jlong_to_CUdeviceptr (dst + dstindex*sizeof(jint));
size_t N = nelem*sizeof(jint);
CUresult rv;
int exc = 0;
jint *csrc = (*env)->GetIntArrayElements (env, src, NULL);
if (csrc == NULL) return;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemcpyHtoD (dptr, csrc + srcindex, N);
exc = throwCudaException (env, rv, "calling cuMemcpyHtoD()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseIntArrayElements (env, src, csrc, 0);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemcpyDtoH
* Signature: (J[IIJII)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuMemcpyDtoH__J_3IIJII
(JNIEnv *env,
jclass cls,
jlong ctx,
jintArray dst,
jint dstindex,
jlong src,
jint srcindex,
jint nelem)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUdeviceptr dptr = jlong_to_CUdeviceptr (src + srcindex*sizeof(jint));
size_t N = nelem*sizeof(jint);
CUresult rv;
int exc = 0;
jint *cdst = (*env)->GetIntArrayElements (env, dst, NULL);
if (cdst == NULL) return;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemcpyDtoH (cdst + dstindex, dptr, N);
exc = throwCudaException (env, rv, "calling cuMemcpyDtoH()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseIntArrayElements (env, dst, cdst, 0);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemcpyHtoD
* Signature: (JJI[JII)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuMemcpyHtoD__JJI_3JII
(JNIEnv *env,
jclass cls,
jlong ctx,
jlong dst,
jint dstindex,
jlongArray src,
jint srcindex,
jint nelem)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUdeviceptr dptr = jlong_to_CUdeviceptr (dst + dstindex*sizeof(jlong));
size_t N = nelem*sizeof(jlong);
CUresult rv;
int exc = 0;
jlong *csrc = (*env)->GetLongArrayElements (env, src, NULL);
if (csrc == NULL) return;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemcpyHtoD (dptr, csrc + srcindex, N);
exc = throwCudaException (env, rv, "calling cuMemcpyHtoD()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseLongArrayElements (env, src, csrc, 0);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemcpyDtoH
* Signature: (J[JIJII)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuMemcpyDtoH__J_3JIJII
(JNIEnv *env,
jclass cls,
jlong ctx,
jlongArray dst,
jint dstindex,
jlong src,
jint srcindex,
jint nelem)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUdeviceptr dptr = jlong_to_CUdeviceptr (src + srcindex*sizeof(jlong));
size_t N = nelem*sizeof(jlong);
CUresult rv;
int exc = 0;
jlong *cdst = (*env)->GetLongArrayElements (env, dst, NULL);
if (cdst == NULL) return;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemcpyDtoH (cdst + dstindex, dptr, N);
exc = throwCudaException (env, rv, "calling cuMemcpyDtoH()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseLongArrayElements (env, dst, cdst, 0);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemcpyHtoD
* Signature: (JJI[FII)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuMemcpyHtoD__JJI_3FII
(JNIEnv *env,
jclass cls,
jlong ctx,
jlong dst,
jint dstindex,
jfloatArray src,
jint srcindex,
jint nelem)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUdeviceptr dptr = jlong_to_CUdeviceptr (dst + dstindex*sizeof(jfloat));
size_t N = nelem*sizeof(jfloat);
CUresult rv;
int exc = 0;
jfloat *csrc = (*env)->GetFloatArrayElements (env, src, NULL);
if (csrc == NULL) return;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemcpyHtoD (dptr, csrc + srcindex, N);
exc = throwCudaException (env, rv, "calling cuMemcpyHtoD()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseFloatArrayElements (env, src, csrc, 0);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemcpyDtoH
* Signature: (J[FIJII)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuMemcpyDtoH__J_3FIJII
(JNIEnv *env,
jclass cls,
jlong ctx,
jfloatArray dst,
jint dstindex,
jlong src,
jint srcindex,
jint nelem)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUdeviceptr dptr = jlong_to_CUdeviceptr (src + srcindex*sizeof(jfloat));
size_t N = nelem*sizeof(jfloat);
CUresult rv;
int exc = 0;
jfloat *cdst = (*env)->GetFloatArrayElements (env, dst, NULL);
if (cdst == NULL) return;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemcpyDtoH (cdst + dstindex, dptr, N);
exc = throwCudaException (env, rv, "calling cuMemcpyDtoH()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseFloatArrayElements (env, dst, cdst, 0);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemcpyHtoD
* Signature: (JJI[DII)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuMemcpyHtoD__JJI_3DII
(JNIEnv *env,
jclass cls,
jlong ctx,
jlong dst,
jint dstindex,
jdoubleArray src,
jint srcindex,
jint nelem)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUdeviceptr dptr = jlong_to_CUdeviceptr (dst + dstindex*sizeof(jdouble));
size_t N = nelem*sizeof(jdouble);
CUresult rv;
int exc = 0;
jdouble *csrc = (*env)->GetDoubleArrayElements (env, src, NULL);
if (csrc == NULL) return;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemcpyHtoD (dptr, csrc + srcindex, N);
exc = throwCudaException (env, rv, "calling cuMemcpyHtoD()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseDoubleArrayElements (env, src, csrc, 0);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuMemcpyDtoH
* Signature: (J[DIJII)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuMemcpyDtoH__J_3DIJII
(JNIEnv *env,
jclass cls,
jlong ctx,
jdoubleArray dst,
jint dstindex,
jlong src,
jint srcindex,
jint nelem)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUdeviceptr dptr = jlong_to_CUdeviceptr (src + srcindex*sizeof(jdouble));
size_t N = nelem*sizeof(jdouble);
CUresult rv;
int exc = 0;
jdouble *cdst = (*env)->GetDoubleArrayElements (env, dst, NULL);
if (cdst == NULL) return;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuMemcpyDtoH (cdst + dstindex, dptr, N);
exc = throwCudaException (env, rv, "calling cuMemcpyDtoH()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseDoubleArrayElements (env, dst, cdst, 0);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuModuleLoad
* Signature: (JLjava/lang/String;)J
*/
JNIEXPORT jlong JNICALL Java_edu_rit_gpu_Cuda_cuModuleLoad
(JNIEnv *env,
jclass cls,
jlong ctx,
jstring fname)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUresult rv;
int exc = 0;
CUmodule module = NULL;
const jbyte *cfname = (*env)->GetStringUTFChars (env, fname, NULL);
if (cfname == NULL) return 0;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuModuleLoad (&module, cfname);
exc = throwCudaException (env, rv, "calling cuModuleLoad()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseStringUTFChars (env, fname, cfname);
return cptr_to_jlong (module);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuModuleUnload
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuModuleUnload
(JNIEnv * env,
jclass cls,
jlong ctx,
jlong mod)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUmodule module = (CUmodule) jlong_to_cptr (mod);
CUresult rv;
int exc = 0;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuModuleUnload (module);
exc = throwCudaException (env, rv, "calling cuModuleUnload()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuModuleGetFunction
* Signature: (JJLjava/lang/String;)J
*/
JNIEXPORT jlong JNICALL Java_edu_rit_gpu_Cuda_cuModuleGetFunction
(JNIEnv *env,
jclass cls,
jlong ctx,
jlong mod,
jstring name)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUmodule module = (CUmodule) jlong_to_cptr (mod);
CUresult rv;
int exc = 0;
CUfunction function = NULL;
const jbyte *cname = (*env)->GetStringUTFChars (env, name, NULL);
if (cname == NULL) return 0;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuModuleGetFunction (&function, module, cname);
exc = throwCudaException (env, rv, "calling cuModuleGetFunction()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseStringUTFChars (env, name, cname);
return cptr_to_jlong (function);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuModuleGetGlobal
* Signature: (JJLjava/lang/String;)J
*/
JNIEXPORT jlong JNICALL Java_edu_rit_gpu_Cuda_cuModuleGetGlobal
(JNIEnv *env,
jclass cls,
jlong ctx,
jlong mod,
jstring name)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUmodule module = (CUmodule) jlong_to_cptr (mod);
CUresult rv;
int exc = 0;
CUdeviceptr dptr = 0;
const jbyte *cname = (*env)->GetStringUTFChars (env, name, NULL);
if (cname == NULL) return 0;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuModuleGetGlobal (&dptr, NULL, module, cname);
exc = throwCudaException (env, rv, "calling cuModuleGetGlobal()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
(*env)->ReleaseStringUTFChars (env, name, cname);
return CUdeviceptr_to_jlong (dptr);
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuFuncSetCacheConfig
* Signature: (JJI)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuFuncSetCacheConfig
(JNIEnv *env,
jclass cls,
jlong ctx,
jlong func,
jint config)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUfunction function = (CUfunction) jlong_to_cptr (func);
CUresult rv;
int exc = 0;
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuFuncSetCacheConfig (function, config);
exc = throwCudaException (env, rv, "calling cuFuncSetCacheConfig()");
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
}
/*
* Class: edu_rit_gpu_Cuda
* Method: cuLaunchKernel
* Signature: (JJIIIIIIII[B[B)V
*/
JNIEXPORT void JNICALL Java_edu_rit_gpu_Cuda_cuLaunchKernel
(JNIEnv *env,
jclass cls,
jlong ctx,
jlong func,
jint gridDimX,
jint gridDimY,
jint gridDimZ,
jint blockDimX,
jint blockDimY,
jint blockDimZ,
jint sharedMemBytes,
jint argc,
jbyteArray argv,
jbyteArray argp)
{
CUcontext context = (CUcontext) jlong_to_cptr (ctx);
CUfunction function = (CUfunction) jlong_to_cptr (func);
CUresult rv;
int exc = 0;
int i;
// Set up pointers to argument values.
jbyte *cargv = (*env)->GetByteArrayElements (env, argv, NULL);
jbyte *cargp = (*env)->GetByteArrayElements (env, argp, NULL);
jbyte *src = cargv;
void **dst = (void**)cargp;
for (i = 0; i < argc; ++ i, src += 8, ++ dst)
*dst = (void*)src;
// Invoke kernel.
rv = cuCtxPushCurrent (context);
exc = throwCudaException (env, rv, "calling cuCtxPushCurrent()");
if (! exc)
{
rv = cuLaunchKernel (function, gridDimX, gridDimY, gridDimZ,
blockDimX, blockDimY, blockDimZ, sharedMemBytes,
/*hStream*/ NULL, /*kernelParams*/ (void**)cargp,
/*extra*/ NULL);
exc = throwCudaException (env, rv, "calling cuLaunchKernel()");
if (! exc)
{
rv = cuCtxSynchronize();
exc = throwCudaException (env, rv, "calling cuCtxSynchronize()");
}
rv = cuCtxPopCurrent (&context);
if (! exc)
throwCudaException (env, rv, "calling cuCtxPopCurrent()");
}
// Release storage.
(*env)->ReleaseByteArrayElements (env, argv, cargv, JNI_ABORT);
(*env)->ReleaseByteArrayElements (env, argp, cargp, JNI_ABORT);
}