From e91fc2ddaa74dd2c46ce93c9e92020d66c037c8e Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 24 Feb 2016 16:58:32 +0800 Subject: add CuContext/MContext --- nerv/lib/matrix/cumatrix.c | 88 +++++++++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 29 deletions(-) (limited to 'nerv/lib/matrix/cumatrix.c') diff --git a/nerv/lib/matrix/cumatrix.c b/nerv/lib/matrix/cumatrix.c index d998871..2fbe7d8 100644 --- a/nerv/lib/matrix/cumatrix.c +++ b/nerv/lib/matrix/cumatrix.c @@ -1,23 +1,12 @@ #define NERV_GENERIC_CUMATRIX +#define MATRIX_CONTEXT CuContext #include "cumatrix.h" #include "cuda_helper.h" #include #include -#define PROFILE_HASHMAP_SIZE 123457 -static cublasHandle_t cublas_handle; -static cudaEvent_t profile_start, profile_stop; -curandGenerator_t curand_gen; -static HashMap *profile; -void nerv_cumatrix_select_gpu(int dev, Status *status) { - fprintf(stderr, "** selecting GPU %d\n", dev); - NERV_SET_STATUS(status, NERV_NORMAL, 0); - CUDA_SAFE_SYNC_CALL(cudaSetDevice(dev), status); - CUDA_SAFE_SYNC_CALL(cublasDestroy(cublas_handle), status); - CUDA_SAFE_SYNC_CALL(cublasCreate(&cublas_handle), status); -} - -void nerv_cumatrix_print_profile() { +void nerv_cuda_context_print_profile(CuContext *context) { + HashMap *profile = context->profile; size_t i; fprintf(stderr, "*** [nerv cumatrix profile] **\n"); for (i = 0; i < profile->size; i++) @@ -30,28 +19,72 @@ void nerv_cumatrix_print_profile() { } } -void nerv_cumatrix_clear_profile() { - hashmap_clear(profile); +void nerv_cuda_context_clear_profile(CuContext *context) { + nerv_hashmap_clear(context->profile); } -void accu_profile(const char *name, float delta) { - float *val = hashmap_getval(profile, name); +void nerv_cuda_context_accu_profile(CuContext *context, + const char *name, float delta) { + HashMap *profile = context->profile; + float *val = nerv_hashmap_getval(profile, name); if (!val) { val = malloc(sizeof(float)); *val = 0; - hashmap_setval(profile, name, val); + nerv_hashmap_setval(profile, name, val); } *val += delta; } -void nerv_cumatrix_init() { - cublasCreate(&cublas_handle); - curandCreateGenerator(&curand_gen, CURAND_RNG_PSEUDO_DEFAULT); - curandSetPseudoRandomGeneratorSeed(curand_gen, time(NULL)); - cudaEventCreate(&profile_start); - cudaEventCreate(&profile_stop); - profile = hashmap_create(PROFILE_HASHMAP_SIZE, bkdr_hash, strcmp); +static void new_cuda_handles(CuContext *context, Status *status) { + CUBLAS_SAFE_SYNC_CALL(cublasCreate(&(context->cublas_handle)), status); + CURAND_SAFE_SYNC_CALL(curandCreateGenerator(&(context->curand_gen), + CURAND_RNG_PSEUDO_DEFAULT), status); + CURAND_SAFE_SYNC_CALL( + curandSetPseudoRandomGeneratorSeed(context->curand_gen, time(NULL)), + status); + CUDA_SAFE_SYNC_CALL(cudaEventCreate(&(context->profile_start)), status); + CUDA_SAFE_SYNC_CALL(cudaEventCreate(&(context->profile_stop)), status); + NERV_SET_STATUS(status, NERV_NORMAL, 0); +} + +static void free_cuda_handles(CuContext *context, Status *status) { + CUBLAS_SAFE_SYNC_CALL(cublasDestroy(context->cublas_handle), status); + CURAND_SAFE_SYNC_CALL(curandDestroyGenerator(context->curand_gen), status); + CUDA_SAFE_SYNC_CALL(cudaEventDestroy(context->profile_start), status); + CUDA_SAFE_SYNC_CALL(cudaEventDestroy(context->profile_stop), status); + NERV_SET_STATUS(status, NERV_NORMAL, 0); +} + +CuContext *nerv_cuda_context_create(Status *status) { + CuContext *context = (CuContext *)malloc(sizeof(CuContext)); + new_cuda_handles(context, status); + if (status->err_code != NERV_NORMAL) + return NULL; + context->profile = nerv_hashmap_create(PROFILE_HASHMAP_SIZE, bkdr_hash, strcmp); + NERV_SET_STATUS(status, NERV_NORMAL, 0); + return context; +} + +void nerv_cuda_context_destroy(CuContext *context, Status *status) { + free_cuda_handles(context, status); + if (status->err_code != NERV_NORMAL) + return; + nerv_hashmap_destroy(context->profile); + free(context); + NERV_SET_STATUS(status, NERV_NORMAL, 0); +} + +void nerv_cuda_context_select_gpu(CuContext *context, + int dev, Status *status) { + free_cuda_handles(context, status); + if (status->err_code != NERV_NORMAL) + return; + CUDA_SAFE_SYNC_CALL(cudaSetDevice(dev), status); + new_cuda_handles(context, status); + if (status->err_code != NERV_NORMAL) + return; + NERV_SET_STATUS(status, NERV_NORMAL, 0); } #define MATRIX_USE_FLOAT @@ -59,7 +92,6 @@ void nerv_cumatrix_init() { #define nerv_matrix_(NAME) nerv_matrix_cuda_float_##NAME #define cudak_(NAME) cudak_float_ ## NAME #define NERV_CUBLAS_(NAME) cublasS##NAME -#define MATRIX_CUMATRIX_HOST_TNAME nerv_matrix_host_float_tname #include "generic/cumatrix.c" #undef NERV_CUBLAS_ @@ -72,12 +104,10 @@ void nerv_cumatrix_init() { #undef MATRIX_ELEM_PTR_BASE #undef MATRIX_ELEM_FMT #undef MATRIX_ELEM_WRITE_FMT -#undef MATRIX_CUMATRIX_HOST_TNAME #define MATRIX_USE_DOUBLE #define cuda_matrix_(NAME) cuda_matrix_double_##NAME #define nerv_matrix_(NAME) nerv_matrix_cuda_double_##NAME #define cudak_(NAME) cudak_double_ ## NAME #define NERV_CUBLAS_(NAME) cublasD##NAME -#define MATRIX_CUMATRIX_HOST_TNAME nerv_matrix_host_double_tname #include "generic/cumatrix.c" -- cgit v1.2.3