benchmarks initial commit
[riscv-tests.git] / benchmarks / spmv / spmv_main.c
diff --git a/benchmarks/spmv/spmv_main.c b/benchmarks/spmv/spmv_main.c
new file mode 100644 (file)
index 0000000..11d9540
--- /dev/null
@@ -0,0 +1,123 @@
+//**************************************************************************
+// Double-precision general matrix multiplication benchmark
+//--------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------
+// Macros
+
+// Set HOST_DEBUG to 1 if you are going to compile this for a host
+// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
+// to 0 if you are compiling with the smips-gcc toolchain.
+
+#ifndef HOST_DEBUG
+#define HOST_DEBUG 0
+#endif
+
+// Set PREALLOCATE to 1 if you want to preallocate the benchmark
+// function before starting stats. If you have instruction/data
+// caches and you don't want to count the overhead of misses, then
+// you will need to use preallocation.
+
+#ifndef PREALLOCATE
+#define PREALLOCATE 0
+#endif
+
+// Set SET_STATS to 1 if you want to carve out the piece that actually
+// does the computation.
+
+#ifndef SET_STATS
+#define SET_STATS 0
+#endif
+
+//--------------------------------------------------------------------------
+// Input/Reference Data
+
+#include "dataset1.h"
+
+//--------------------------------------------------------------------------
+// Helper functions
+
+int verify( long n, const double test[], const double correct[] )
+{
+  int i;
+  for ( i = 0; i < n; i++ ) {
+    if ( test[i] != correct[i] ) {
+      return 2;
+    }
+  }
+  return 1;
+}
+
+#if HOST_DEBUG
+#include <stdio.h>
+#include <stdlib.h>
+void printArray( char name[], long n, const double arr[] )
+{
+  int i;
+  printf( " %10s :", name );
+  for ( i = 0; i < n; i++ )
+    printf( " %8.1f ", arr[i] );
+  printf( "\n" );
+}
+#endif
+
+void finishTest( int toHostValue )
+{
+#if HOST_DEBUG
+  if ( toHostValue == 1 )
+    printf( "*** PASSED ***\n" );
+  else
+    printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
+  exit(0);
+#else
+  asm( "mtpcr %0, cr30" : : "r" (toHostValue) );
+  while ( 1 ) { }
+#endif
+}
+
+void setStats( int enable )
+{
+#if ( !HOST_DEBUG && SET_STATS )
+  asm( "mtpcr %0, cr10" : : "r" (enable) );
+#endif
+}
+
+void spmv(int r, const double* val, const int* idx, const double* x,
+          const int* ptr, double* y)
+{
+  for (int i = 0; i < r; i++)
+  {
+    int k;
+    double yi0 = 0, yi1 = 0, yi2 = 0, yi3 = 0;
+    for (k = ptr[i]; k < ptr[i+1]-3; k+=4)
+    {
+      yi0 += val[k+0]*x[idx[k+0]];
+      yi1 += val[k+1]*x[idx[k+1]];
+      yi2 += val[k+2]*x[idx[k+2]];
+      yi3 += val[k+3]*x[idx[k+3]];
+    }
+    for ( ; k < ptr[i+1]; k++)
+    {
+      yi0 += val[k]*x[idx[k]];
+    }
+    y[i] = (yi0+yi1)+(yi2+yi3);
+  }
+}
+
+//--------------------------------------------------------------------------
+// Main
+
+int main( int argc, char* argv[] )
+{
+  double y[R];
+
+#if PREALLOCATE
+  spmv(R, val, idx, x, ptr, y);
+#endif
+
+  setStats(1);
+  spmv(R, val, idx, x, ptr, y);
+  setStats(0);
+
+  finishTest(verify(R, y, verify_data));
+}