<commit_before>/* ************************************************************************
 * Copyright 2016 Advanced Micro Devices, Inc.
 *
 * ************************************************************************ */

#include <sys/time.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>

#include "rocblas.hpp"
#include "utility.h"
#include "cblas_interface.h"
#include "norm.h"
#include "unit.h"
#include "flops.h"
#include <typeinfo>

using namespace std;

/* ============================================================================================ */

template<typename T>
rocblas_status testing_gemm(Arguments argus)
{

    rocblas_int M = argus.M;
    rocblas_int N = argus.N;
    rocblas_int K = argus.K;

    rocblas_int lda = argus.lda;
    rocblas_int ldb = argus.ldb;
    rocblas_int ldc = argus.ldc;

    rocblas_operation transA = char2rocblas_operation(argus.transA_option);
    rocblas_operation transB = char2rocblas_operation(argus.transB_option);

    rocblas_int  A_size, B_size, C_size, A_row, A_col, B_row, B_col;
    T alpha = argus.alpha;
    T beta = argus.beta;

    double gpu_time_used, cpu_time_used;
    double rocblas_gflops, cblas_gflops;

    T rocblas_error = 0.0;
    rocblas_handle handle;
    rocblas_status status = rocblas_status_success;
    rocblas_create_handle(&handle);

    if(transA == rocblas_operation_none){
        A_row =  M; A_col = K;
    }
    else{
        A_row = K; A_col = M;
    }

    if(transB == rocblas_operation_none){
        B_row =  K; B_col = N;
    }
    else{
        B_row = N; B_col = K;
    }

    A_size = lda * A_col; B_size = ldb * B_col; C_size = ldc * N;

    //check here to prevent undefined memory allocation error
    if( M < 0 || N < 0 || K < 0 || lda < 0 || ldb < 0 || ldc < 0 ){
        return rocblas_status_invalid_size;
    }
    //Naming: dX is in GPU (device) memory. hK is in CPU (host) memory, plz follow this practice
    vector<T> hA(A_size);
    vector<T> hB(B_size);
    vector<T> hC(C_size);
    vector<T> hC_copy(C_size);

    T *dA, *dB, *dC;

    //allocate memory on device
    CHECK_HIP_ERROR(hipMalloc(&dA, A_size * sizeof(T)));
    CHECK_HIP_ERROR(hipMalloc(&dB, B_size * sizeof(T)));
    CHECK_HIP_ERROR(hipMalloc(&dC, C_size * sizeof(T)));

    //Initial Data on CPU
    srand(1);
    rocblas_init<T>(hA, A_row, A_col, lda);
    rocblas_init<T>(hB, B_row, B_col, ldb);
    rocblas_init<T>(hC, M, N, ldc);

    //copy vector is easy in STL; hz = hx: save a copy in hC_copy which will be output of CPU BLAS
    hC_copy = hC;

    //copy data from CPU to device, does not work for lda != A_row
    CHECK_HIP_ERROR(hipMemcpy(dA, hA.data(), sizeof(T)*lda*A_col,  hipMemcpyHostToDevice));
    CHECK_HIP_ERROR(hipMemcpy(dB, hB.data(), sizeof(T)*ldb*B_col,  hipMemcpyHostToDevice));
    CHECK_HIP_ERROR(hipMemcpy(dC, hC.data(), sizeof(T)*ldc*N,      hipMemcpyHostToDevice));

    /* =====================================================================
         ROCBLAS
    =================================================================== */
    if(argus.timing){
        gpu_time_used = get_time_us();// in microseconds
    }

    //library interface
    status = rocblas_gemm<T>(handle, transA, transB,
                    M, N, K,
                    &alpha, dA, lda,
                    dB, ldb,
                    &beta, dC, ldc);

 //    sleep(1);
    if(argus.timing){
        gpu_time_used = get_time_us() - gpu_time_used;
        rocblas_gflops = gemm_gflop_count<T> (M, N, K) / gpu_time_used * 1e6;
    }

    //copy output from device to CPU
    CHECK_HIP_ERROR(hipMemcpy(hC.data(), dC, sizeof(T)*ldc*N,      hipMemcpyDeviceToHost));


    if(argus.unit_check || argus.norm_check){

     /* =====================================================================
                 CPU BLAS
     =================================================================== */
        if(argus.timing){
            cpu_time_used = get_time_us();
        }


        cblas_gemm<T>(
                     transA, transB, M, N, K,
                     alpha, hA.data(), lda,
                     hB.data(), ldb,
                     beta, hC_copy.data(), ldc);

        if(argus.timing){
            cpu_time_used = get_time_us() - cpu_time_used;
            cblas_gflops = gemm_gflop_count<T>(M, N, K) / cpu_time_used * 1e6;
        }

        for(int i=0;i<min(N, 4);i++)
            for(int j=0;j<min(M,4);j++)
            {
                printf("matrix C col %d, row %d, CPU result=%f, GPU result=%f\n", i, j,  hC_copy[j+i*ldc], hC[j+i*ldc]);
            }

        //enable unit check, notice unit check is not invasive, but norm check is,
        // unit check and norm check can not be interchanged their order
        if(argus.unit_check){
            unit_check_general<T>(M, N, ldc, hC_copy.data(), hC.data());
        }

        //if enable norm check, norm check is invasive
        //any typeinfo(T) will not work here, because template deduction is matched in compilation time<commit_msg>protect cblas call when status == success<commit_after>/* ************************************************************************
 * Copyright 2016 Advanced Micro Devices, Inc.
 *
 * ************************************************************************ */

#include <sys/time.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>

#include "rocblas.hpp"
#include "utility.h"
#include "cblas_interface.h"
#include "norm.h"
#include "unit.h"
#include "flops.h"
#include <typeinfo>

using namespace std;

/* ============================================================================================ */

template<typename T>
rocblas_status testing_gemm(Arguments argus)
{

    rocblas_int M = argus.M;
    rocblas_int N = argus.N;
    rocblas_int K = argus.K;

    rocblas_int lda = argus.lda;
    rocblas_int ldb = argus.ldb;
    rocblas_int ldc = argus.ldc;

    rocblas_operation transA = char2rocblas_operation(argus.transA_option);
    rocblas_operation transB = char2rocblas_operation(argus.transB_option);

    rocblas_int  A_size, B_size, C_size, A_row, A_col, B_row, B_col;
    T alpha = argus.alpha;
    T beta = argus.beta;

    double gpu_time_used, cpu_time_used;
    double rocblas_gflops, cblas_gflops;

    T rocblas_error = 0.0;
    rocblas_handle handle;
    rocblas_status status = rocblas_status_success;
    rocblas_create_handle(&handle);

    if(transA == rocblas_operation_none){
        A_row =  M; A_col = K;
    }
    else{
        A_row = K; A_col = M;
    }

    if(transB == rocblas_operation_none){
        B_row =  K; B_col = N;
    }
    else{
        B_row = N; B_col = K;
    }

    A_size = lda * A_col; B_size = ldb * B_col; C_size = ldc * N;

    //check here to prevent undefined memory allocation error
    if( M < 0 || N < 0 || K < 0 || lda < 0 || ldb < 0 || ldc < 0 ){
        return rocblas_status_invalid_size;
    }
    //Naming: dX is in GPU (device) memory. hK is in CPU (host) memory, plz follow this practice
    vector<T> hA(A_size);
    vector<T> hB(B_size);
    vector<T> hC(C_size);
    vector<T> hC_copy(C_size);

    T *dA, *dB, *dC;

    //allocate memory on device
    CHECK_HIP_ERROR(hipMalloc(&dA, A_size * sizeof(T)));
    CHECK_HIP_ERROR(hipMalloc(&dB, B_size * sizeof(T)));
    CHECK_HIP_ERROR(hipMalloc(&dC, C_size * sizeof(T)));

    //Initial Data on CPU
    srand(1);
    rocblas_init<T>(hA, A_row, A_col, lda);
    rocblas_init<T>(hB, B_row, B_col, ldb);
    rocblas_init<T>(hC, M, N, ldc);

    //copy vector is easy in STL; hz = hx: save a copy in hC_copy which will be output of CPU BLAS
    hC_copy = hC;

    //copy data from CPU to device, does not work for lda != A_row
    CHECK_HIP_ERROR(hipMemcpy(dA, hA.data(), sizeof(T)*lda*A_col,  hipMemcpyHostToDevice));
    CHECK_HIP_ERROR(hipMemcpy(dB, hB.data(), sizeof(T)*ldb*B_col,  hipMemcpyHostToDevice));
    CHECK_HIP_ERROR(hipMemcpy(dC, hC.data(), sizeof(T)*ldc*N,      hipMemcpyHostToDevice));

    /* =====================================================================
         ROCBLAS
    =================================================================== */
    if(argus.timing){
        gpu_time_used = get_time_us();// in microseconds
    }

    //library interface
    status = rocblas_gemm<T>(handle, transA, transB,
                    M, N, K,
                    &alpha, dA, lda,
                    dB, ldb,
                    &beta, dC, ldc);

 //    sleep(1);
    if(argus.timing){
        gpu_time_used = get_time_us() - gpu_time_used;
        rocblas_gflops = gemm_gflop_count<T> (M, N, K) / gpu_time_used * 1e6;
    }

    //copy output from device to CPU
    CHECK_HIP_ERROR(hipMemcpy(hC.data(), dC, sizeof(T)*ldc*N,      hipMemcpyDeviceToHost));


    if(argus.unit_check || argus.norm_check){

     /* =====================================================================
                 CPU BLAS
     =================================================================== */
        if(argus.timing){
            cpu_time_used = get_time_us();
        }


        if(status == rocblas_status_success) {
            cblas_gemm<T>(
                         transA, transB, M, N, K,
                         alpha, hA.data(), lda,
                         hB.data(), ldb,
                         beta, hC_copy.data(), ldc);
        }

        if(argus.timing){
            cpu_time_used = get_time_us() - cpu_time_used;
            cblas_gflops = gemm_gflop_count<T>(M, N, K) / cpu_time_used * 1e6;
        }

        for(int i=0;i<min(N, 4);i++)
            for(int j=0;j<min(M,4);j++)
            {
                printf("matrix C col %d, row %d, CPU result=%f, GPU result=%f\n", i, j,  hC_copy[j+i*ldc], hC[j+i*ldc]);
            }

        //enable unit check, notice unit check is not invasive, but norm check is,
        // unit check and norm check can not be interchanged their order
        if(argus.unit_check){
            unit_check_general<T>(M, N, ldc, hC_copy.data(), hC.data());
        }

        //if enable norm check, norm check is invasive
        //any typeinfo(T) will not work here, because template deduction is matched in compilation time
{'fraction_non_alphanumeric': 0.21291654379239164, 'fraction_numerical': 0.004718372161604247, 'mean_word_length': 2.7625739644970415, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7535351', 'n_tokens_mistral': 3719, 'n_tokens_neox': 3501, 'n_words': 802}