From 7dfa2ae2e6f8ccaaf133318265a7ab00de546e82 Mon Sep 17 00:00:00 2001 From: aamir Date: Sun, 27 May 2018 14:18:53 -0700 Subject: added wmma parsing but execution getting aborted --- cuda-kernels/tensor_core.cu | 250 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 cuda-kernels/tensor_core.cu (limited to 'cuda-kernels/tensor_core.cu') diff --git a/cuda-kernels/tensor_core.cu b/cuda-kernels/tensor_core.cu new file mode 100644 index 0000000..483a42b --- /dev/null +++ b/cuda-kernels/tensor_core.cu @@ -0,0 +1,250 @@ +/* Copyright (c) 1993-2017, NVIDIA CORPORATION. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of NVIDIA CORPORATION nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +// Define some error checking macros. +#define cudaErrCheck(stat) { cudaErrCheck_((stat), __FILE__, __LINE__); } +void cudaErrCheck_(cudaError_t stat, const char *file, int line) { + if (stat != cudaSuccess) { + fprintf(stderr, "CUDA Error: %s %s %d\n", cudaGetErrorString(stat), file, line); + } +} + + + + +#include +using namespace nvcuda; + +// Must be multiples of 16 for wmma code to work +#define MATRIX_M (16) +#define MATRIX_N (16) +#define MATRIX_K (16) + + + +// The only dimensions currently supported by WMMA +const int WMMA_M = 16; +const int WMMA_N = 16; +const int WMMA_K = 16; + + +// Performs an MxNxK GEMM (C=alpha*A*B + beta*C) assuming: +// 1) Matrices are packed in memory. +// 2) M, N and K are multiples of 16. +// 3) Neither A nor B are transposed. +// Note: This is NOT a high performance example but is for demonstration purposes only +// For a high performance code please use the GEMM provided in cuBLAS. +__global__ void wmma_example(half *a, half *b, float *c, int M, int N, int K, float alpha, float beta) { + unsigned int start_time=0,end_time=0; + // Leading dimensions. Packed with no transpositions. + start_time=clock(); + int lda = M; + int ldb = K; + int ldc = M; + + // Tile using a 2D grid/ + int warpM = (blockIdx.x * blockDim.x + threadIdx.x) / warpSize; + int warpN = (blockIdx.y * blockDim.y + threadIdx.y); + + // Declare the fragments + wmma::fragment a_frag; + wmma::fragment b_frag; + wmma::fragment acc_frag; + wmma::fragment c_frag; + + wmma::fill_fragment(c_frag, 0.0f); + + int i=0; + int aRow = warpM * WMMA_M; + int bCol = warpN * WMMA_N; + int aCol = i; + int bRow = i; + + + // Bounds checking + if (aRow < M && aCol < K && bRow < K && bCol < N) { + wmma::load_matrix_sync(a_frag, a+aRow+aCol*lda, lda); + wmma::load_matrix_sync(b_frag, b+bRow*ldb+bCol, ldb); + wmma::mma_sync(c_frag, a_frag, b_frag, c_frag); + //wmma::mma_sync(acc_frag, a_frag, b_frag, acc_frag); + } + int cRow = warpM * WMMA_M; + int cCol = warpN * WMMA_N; + wmma::store_matrix_sync(c + cRow + cCol * ldc, c_frag, ldc, wmma::mem_col_major); + end_time=clock(); + printf("clock=%d",end_time-start_time); +} + +__global__ void convertFp32ToFp16 (half *out, float *in, int n) { + int idx = blockDim.x * blockIdx.x + threadIdx.x; + if (idx < n) { + out[idx] = in[idx]; + } +} + +int main(int argc, char* argv[]) { + float *a_fp32; + float *b_fp32; + half *a_fp16; + half *b_fp16; + + float *c; + float *c_cublas; + float *c_wmma; + + float *c_host_cublas; + float *c_host_wmma; + float *a_host_wmma; + float *b_host_wmma; + float *c_init_host_wmma; + + + cudaEvent_t startWMMA; + cudaEvent_t stopWMMA; + + + cudaErrCheck(cudaEventCreate(&startWMMA)); + cudaErrCheck(cudaEventCreate(&stopWMMA)); + + + + + // Use tensor cores + + + cudaErrCheck(cudaMalloc((void**)&a_fp32, MATRIX_M * MATRIX_K * sizeof(float))); + cudaErrCheck(cudaMalloc((void**)&b_fp32, MATRIX_K * MATRIX_N * sizeof(float))); + cudaErrCheck(cudaMalloc((void**)&a_fp16, MATRIX_M * MATRIX_K * sizeof(half))); + cudaErrCheck(cudaMalloc((void**)&b_fp16, MATRIX_K * MATRIX_N * sizeof(half))); + + cudaErrCheck(cudaMalloc((void**)&c, MATRIX_M * MATRIX_N * sizeof(float))); + cudaErrCheck(cudaMalloc((void**)&c_wmma, MATRIX_M * MATRIX_N * sizeof(float))); + + c_host_wmma = (float*)malloc(MATRIX_M * MATRIX_N * sizeof(float)); + c_init_host_wmma = (float*)malloc(MATRIX_M * MATRIX_N * sizeof(float)); + a_host_wmma = (float*)malloc(MATRIX_M * MATRIX_K * sizeof(float)); + b_host_wmma = (float*)malloc(MATRIX_K * MATRIX_N * sizeof(float)); + + + +// printf("a_fp32\n"); + for(int m=0;m>> (a_fp16, a_fp32, MATRIX_M * MATRIX_K); + convertFp32ToFp16 <<< (MATRIX_K * MATRIX_N + 255) / 256, 256 >>> (b_fp16, b_fp32, MATRIX_K * MATRIX_N); + + for(int m=0;m>> (a_fp16, b_fp16, c_wmma, MATRIX_M, MATRIX_N, MATRIX_K, alpha, beta); + // wmma_example <<< gridDim, blockDim >>> (a_fp16, b_fp16, c_wmma, MATRIX_M, MATRIX_N, MATRIX_K, alpha, beta); + cudaErrCheck(cudaEventRecord(stopWMMA)); + + + + + // Error checking + printf("\nChecking results...\n"); + cudaErrCheck(cudaMemcpy(c_host_wmma, c_wmma, MATRIX_M * MATRIX_N * sizeof(float), cudaMemcpyDeviceToHost)); + // printf("c_host\n"); + // for(int m=0;m