diff options
author | Determinant <[email protected]> | 2016-02-17 20:14:06 +0800 |
---|---|---|
committer | Determinant <[email protected]> | 2016-02-17 20:14:06 +0800 |
commit | 0ee43c21af4fcd3aed070b1f5ad1eb9feb2ad159 (patch) | |
tree | ceb1d38328767fb657bc0d37ec6e513b08a86277 /nerv/lib | |
parent | 490a10c2130773bd022f05513fa2905b6a6c6e91 (diff) |
try to merge manually
Diffstat (limited to 'nerv/lib')
-rw-r--r-- | nerv/lib/matrix/cumatrix.c | 8 | ||||
-rw-r--r-- | nerv/lib/matrix/generic/cukernel.cu | 48 | ||||
-rw-r--r-- | nerv/lib/matrix/generic/cumatrix.c | 8 | ||||
-rw-r--r-- | nerv/lib/matrix/generic/cumatrix.h | 1 |
4 files changed, 65 insertions, 0 deletions
diff --git a/nerv/lib/matrix/cumatrix.c b/nerv/lib/matrix/cumatrix.c index 04205e4..58bdfe7 100644 --- a/nerv/lib/matrix/cumatrix.c +++ b/nerv/lib/matrix/cumatrix.c @@ -9,6 +9,14 @@ 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() { size_t i; fprintf(stderr, "*** [nerv cumatrix profile] **\n"); diff --git a/nerv/lib/matrix/generic/cukernel.cu b/nerv/lib/matrix/generic/cukernel.cu index 8fbe05d..51e3b6a 100644 --- a/nerv/lib/matrix/generic/cukernel.cu +++ b/nerv/lib/matrix/generic/cukernel.cu @@ -383,6 +383,20 @@ __global__ void cudak_(copy_rows_by_colidx)(const MATRIX_ELEM *a, MATRIX_ELEM *b b[j + i * stride] = a[j + k * stride]; } +__global__ void cudak_(prefixsum_row_reduce)(const MATRIX_ELEM *a, MATRIX_ELEM *b, + int nrow, int ncol, int stride_a, int stride_b, int offset) { + int j = blockIdx.x * blockDim.x + threadIdx.x; + int i = blockIdx.y * blockDim.y + threadIdx.y; + long idx_a, idx_b; + if (i >= nrow || j >= ncol) return; + idx_b = j + i * stride_b; + idx_a = j + i * stride_a; + //b[idx] = 1.0 / (1.0 + exp(-a[idx])); + if (j >= offset) + b[idx_b] = a[idx_a] + a[idx_a - offset]; + else + b[idx_b] = a[idx_a]; +} extern "C" { #include "../cukernel.h" @@ -745,6 +759,40 @@ extern "C" { cudaStreamSynchronize(0); } + void cudak_(cuda_prefixsum_row)(const Matrix *a, Matrix *b) { + dim3 threadsPerBlock(CUDA_THREADS_N, CUDA_THREADS_N); + dim3 numBlocks(CEIL_DIV(b->ncol, threadsPerBlock.x), + CEIL_DIV(b->nrow, threadsPerBlock.y)); + + MATRIX_ELEM *tmp[2]; + size_t tmp_stride[2]; + cudaMallocPitch(tmp, tmp_stride + 0, a->ncol * sizeof(MATRIX_ELEM), a->nrow); + cudaMallocPitch(tmp + 1, tmp_stride + 1, a->ncol * sizeof(MATRIX_ELEM), a->nrow); + + int offset = 1; + cudak_(prefixsum_row_reduce)<<<numBlocks, threadsPerBlock>>> \ + (MATRIX_ELEM_PTR(a), tmp[0], b->nrow, b->ncol, + a->stride / sizeof(MATRIX_ELEM), tmp_stride[0] / sizeof(MATRIX_ELEM), offset); + int pin = 0, pout = 1; + + for (offset = 2;offset <= a->ncol / 2;offset *= 2) { + cudak_(prefixsum_row_reduce)<<<numBlocks, threadsPerBlock>>> \ + (tmp[pin], tmp[pout], b->nrow, b->ncol, + tmp_stride[pin] / sizeof(MATRIX_ELEM), tmp_stride[pout] / sizeof(MATRIX_ELEM), offset); + pin = 1 - pin; + pout = 1 - pout; + } + + cudak_(prefixsum_row_reduce)<<<numBlocks, threadsPerBlock>>> \ + (tmp[pin], MATRIX_ELEM_PTR(b), b->nrow, b->ncol, + tmp_stride[pin] / sizeof(MATRIX_ELEM), b->stride / sizeof(MATRIX_ELEM), offset); + + cudaFree(tmp[0]); + cudaFree(tmp[1]); + + cudaStreamSynchronize(0); + } + void cudak_(cuda_decompress)(const Matrix *a, Matrix *b) { dim3 threadsPerBlock(1, CUDA_THREADS_NN); dim3 numBlocks(1, CEIL_DIV(a->nrow, threadsPerBlock.y)); diff --git a/nerv/lib/matrix/generic/cumatrix.c b/nerv/lib/matrix/generic/cumatrix.c index bf93b77..7b70607 100644 --- a/nerv/lib/matrix/generic/cumatrix.c +++ b/nerv/lib/matrix/generic/cumatrix.c @@ -486,6 +486,14 @@ void nerv_matrix_(scale_rows_by_row)(Matrix *a, const Matrix *b, NERV_SET_STATUS(status, NERV_NORMAL, 0); } +void nerv_matrix_(prefixsum_row)(Matrix *a, const Matrix *b, Status *status) { + CHECK_SAME_DIMENSION(a, b, status); + PROFILE_START + cudak_(cuda_prefixsum_row)(b, a); + PROFILE_STOP + NERV_SET_STATUS(status, NERV_NORMAL, 0); +} + static void cuda_matrix_(free)(MATRIX_ELEM *ptr, Status *status) { CUDA_SAFE_SYNC_CALL(cudaFree(ptr), status); NERV_SET_STATUS(status, NERV_NORMAL, 0); diff --git a/nerv/lib/matrix/generic/cumatrix.h b/nerv/lib/matrix/generic/cumatrix.h index 4f66a2c..5b8076f 100644 --- a/nerv/lib/matrix/generic/cumatrix.h +++ b/nerv/lib/matrix/generic/cumatrix.h @@ -61,6 +61,7 @@ void nerv_matrix_(scale_rows_by_col)(Matrix *a, const Matrix *b, Status *status); void nerv_matrix_(scale_rows_by_row)(Matrix *a, const Matrix *b, Status *status); +void nerv_matrix_(prefixsum_row)(Matrix *a, const Matrix *b, Status *status); void nerv_matrix_(thres_mask)(Matrix *a, Matrix *b, double thres, double low, double high, Status *status); |