aboutsummaryrefslogtreecommitdiff
path: root/nerv/lib/matrix/generic/cukernel.cu
diff options
context:
space:
mode:
Diffstat (limited to 'nerv/lib/matrix/generic/cukernel.cu')
-rw-r--r--nerv/lib/matrix/generic/cukernel.cu48
1 files changed, 48 insertions, 0 deletions
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));