shithub: opus

Download patch

ref: 74b98437bad697c863fb3e764820ec730a89d957
parent: 03dcb8195ffea2a214fc176e807d30b8cfd34105
author: David Rowe <david@rowetel.com>
date: Mon Dec 10 20:41:27 EST 2018

Vectorization testing code

Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>

--- /dev/null
+++ b/dnn/test_vec.c
@@ -1,0 +1,130 @@
+#include <stdio.h>
+#include <math.h>
+#include "opus_types.h"
+#include "arch.h"
+#include "common.h"
+#include "tansig_table.h"
+
+#define LPCNET_TEST
+
+// we need to call two versions of each functions that have the same
+// name, so use #defines to temp rename them
+
+#define celt_exp2 celt_exp2_fast
+#define tansig_approx tansig_approx_fast
+#define sigmoid_approx sigmoid_approx_fast
+#define softmax softmax_fast
+#define vec_tanh vec_tanh_fast
+#define vec_sigmoid vec_sigmoid_fast
+#define sgemv_accum16 sgemv_accum16_fast
+#define sparse_sgemv_accum16 sparse_sgemv_accum16_fast
+
+#ifdef __AVX__
+#include "vec_avx.h"
+#ifdef __AVX2__
+const char simd[]="AVX2";
+#else
+const char simd[]="AVX";
+#endif
+#elif __ARM_NEON__
+#include "vec_neon.h"
+const char simd[]="NEON";
+#else
+const char simd[]="none";
+
+#endif
+
+#undef celt_exp2
+#undef tansig_approx
+#undef sigmoid_approx
+#undef softmax
+#undef vec_tanh
+#undef vec_sigmoid
+#undef sgemv_accum16
+#undef sparse_sgemv_accum16
+#include "vec.h"
+
+#define ROW_STEP 16
+#define ROWS     ROW_STEP*10
+#define COLS     2
+#define ENTRIES  2
+
+int test_sgemv_accum16() {
+    float weights[ROWS*COLS];
+    float x[COLS];
+    float out[ROWS], out_fast[ROWS];
+    int i;
+
+    printf("sgemv_accum16.....................: ");
+    for(i=0; i<ROWS*COLS; i++) {
+	weights[i] = i;
+    }
+    for(i=0; i<ROWS; i++) {
+	out[i] = 0;
+	out_fast[i] = 0;
+    }
+  
+    for(i=0; i<COLS; i++) {
+	x[i] = i+1;
+    }
+
+    sgemv_accum16(out, weights, ROWS, COLS, 1, x);
+    sgemv_accum16_fast(out_fast, weights, ROWS, COLS, 1, x);
+
+    for(i=0; i<ROWS; i++) {
+	if (out[i] != out_fast[i]) {
+	    printf("fail\n");
+	    for(i=0; i<ROWS; i++) {
+		printf("%d %f %f\n", i, out[i], out_fast[i]);
+		if (out[i] != out_fast[i])
+		    return 1;
+	    }
+	}
+    }
+
+    printf("pass\n");
+    return 0;
+}
+
+
+int test_sparse_sgemv_accum16() {
+    int rows = ROW_STEP*ENTRIES;
+    int indx[] = {1,0,2,0,1};
+    float w[ROW_STEP*(1+2)];
+    float x[ENTRIES] = {1,2};
+    float out[ROW_STEP*(1+2)], out_fast[ROW_STEP*(1+2)];
+    int i;
+
+    printf("sparse_sgemv_accum16..............: ");
+    for(i=0; i<ROW_STEP*(1+2); i++) {
+	w[i] = i;
+	out[i] = 0;
+	out_fast[i] = 0;
+    }
+  
+    sparse_sgemv_accum16(out, w, rows, indx, x);
+    sparse_sgemv_accum16_fast(out_fast, w, rows, indx, x);
+
+    for(i=0; i<ROW_STEP*ENTRIES; i++) {
+	if (out[i] != out_fast[i]) {
+	    printf("fail\n");
+	    for(i=0; i<ROW_STEP*ENTRIES; i++) {
+		printf("%d %f %f\n", i, out[i], out_fast[i]);
+		if (out[i] != out_fast[i])
+		    return 1;
+	    }
+	}
+    }
+
+    printf("pass\n");
+    return 0;
+}
+
+int main() {
+    printf("testing vector routines on SIMD: %s\n", simd);
+    int test1 = test_sgemv_accum16();
+    int test2 = test_sparse_sgemv_accum16();
+    return test1 || test2;
+}
+
+  
--