text: /**
   * This version is stamped on May 10, 2016
   *
   * Contact:
   *   Louis-Noel Pouchet <pouchet.ohio-state.edu>
   *   Tomofumi Yuki <tomofumi.yuki.fr>
   *
   * Web address: http://polybench.sourceforge.net
   */
  /* gemm.c: this file is part of PolyBench/C */
  
  
  /*
  
  /home/lchelini/scratch/polygeist/build/mlir-clang/mlir-clang /home/lchelini/scratch/OpenBLAS/benchmark/polybench-c-4.2.1-beta/linear-algebra/blas/blas_gemm/gemm.c -I ../../ -I /home/lchelini/scratch/polygeist/llvm-project/llvm/../clang/lib/Headers -I /home/lchelini/scratch/polygeist/mlir-clang/Test/polybench/utilities/
  
  */
  
  #include <stdio.h>
  #include <unistd.h>
  #include <string.h>
  #include <math.h>
  #include <cblas.h>
  
  /* Include polybench common header. */
  #include <polybench.h>
  
  /* Include benchmark-specific header. */
  #include "gemm.h"
  
  
  /* Array initialization. */
  static
  void init_array(int ni, int nj, int nk,
  		DATA_TYPE *alpha,
  		DATA_TYPE *beta,
  		DATA_TYPE POLYBENCH_2D(C,NI,NJ,ni,nj),
  		DATA_TYPE POLYBENCH_2D(A,NI,NK,ni,nk),
  		DATA_TYPE POLYBENCH_2D(B,NK,NJ,nk,nj))
  {
    int i, j;
  
    *alpha = 1.5;
    *beta = 1.2;
    for (i = 0; i < ni; i++)
      for (j = 0; j < nj; j++)
        C[i][j] = (DATA_TYPE) ((i*j+1) % ni) / ni;
    for (i = 0; i < ni; i++)
      for (j = 0; j < nk; j++)
        A[i][j] = (DATA_TYPE) (i*(j+1) % nk) / nk;
    for (i = 0; i < nk; i++)
      for (j = 0; j < nj; j++)
        B[i][j] = (DATA_TYPE) (i*(j+2) % nj) / nj;
  }
  
  
  /* DCE code. Must scan the entire live-out data.
     Can be used also to check the correctness of the output. */
  static
  void print_array(int ni, int nj,
  		 DATA_TYPE POLYBENCH_2D(C,NI,NJ,ni,nj))
  {
    int i, j;
  
    POLYBENCH_DUMP_START;
    POLYBENCH_DUMP_BEGIN("C");
    for (i = 0; i < ni; i++)
      for (j = 0; j < nj; j++) {
  	if ((i * ni + j) % 20 == 0) fprintf (POLYBENCH_DUMP_TARGET, "\n");
  	fprintf (POLYBENCH_DUMP_TARGET, DATA_PRINTF_MODIFIER, C[i][j]);
      }
    POLYBENCH_DUMP_END("C");
    POLYBENCH_DUMP_FINISH;
  }
  
  
  /* Main computational kernel. The whole function will be timed,
     including the call and return. */
  static
  void kernel_gemm(int ni, int nj, int nk,
  		 DATA_TYPE alpha,
  		 DATA_TYPE beta,
  		 DATA_TYPE POLYBENCH_2D(C,NI,NJ,ni,nj),
  		 DATA_TYPE POLYBENCH_2D(A,NI,NK,ni,nk),
  		 DATA_TYPE POLYBENCH_2D(B,NK,NJ,nk,nj))
  {
  //BLAS PARAMS
  //TRANSA = 'N'
  //TRANSB = 'N'
  // => Form C := alpha*A*B + beta*C,
  //A is NIxNK
  //B is NKxNJ
  //C is NIxNJ
  
  cblas_dgemm(
    CblasRowMajor, CblasNoTrans, CblasNoTrans, NI, NJ, NK, alpha, &A[0][0], NK, &B[0][0], NJ, beta, &C[0][0], NJ);
  
  }
  
  
  int main(int argc, char** argv)
  {
    /* Retrieve problem size. */
    int ni = NI;
    int nj = NJ;
    int nk = NK;
  
    /* Variable declaration/allocation. */
    DATA_TYPE alpha;
    DATA_TYPE beta;
    POLYBENCH_2D_ARRAY_DECL(C,DATA_TYPE,NI,NJ,ni,nj);
    POLYBENCH_2D_ARRAY_DECL(A,DATA_TYPE,NI,NK,ni,nk);
    POLYBENCH_2D_ARRAY_DECL(B,DATA_TYPE,NK,NJ,nk,nj);
  
    /* Initialize array(s). */
    init_array (ni, nj, nk, &alpha, &beta,
  	      POLYBENCH_ARRAY(C),
  	      POLYBENCH_ARRAY(A),
  	      POLYBENCH_ARRAY(B));
  
    /* Start timer. */
    polybench_start_instruments;
  
    /* Run kernel. */
    kernel_gemm (ni, nj, nk,
  	       alpha, beta,
  	       POLYBENCH_ARRAY(C),
  	       POLYBENCH_ARRAY(A),
  	       POLYBENCH_ARRAY(B));
  
    /* Stop and print timer. */
    polybench_stop_instruments;
    polybench_print_instruments;
  
    /* Prevent dead-code elimination. All live-out data must be printed
       by the function call in argument. */
    polybench_prevent_dce(print_array(ni, nj,  POLYBENCH_ARRAY(C)));
  
    /* Be clean. */
    POLYBENCH_FREE_ARRAY(C);
    POLYBENCH_FREE_ARRAY(A);
    POLYBENCH_FREE_ARRAY(B);
  
    return 0;
  }
  