From b0e23628f95845591f8ce697784beda13e3cf640 Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Fri, 15 Feb 2019 21:50:45 +0100 Subject: double matrix multiplication --- test/monniaux/float_mat/Makefile | 21 ++++ test/monniaux/float_mat/float_mat.c | 182 ++++++++++++++++++++++++++++++++ test/monniaux/float_mat/float_mat.h | 50 +++++++++ test/monniaux/float_mat/float_mat_run.c | 118 +++++++++++++++++++++ 4 files changed, 371 insertions(+) create mode 100644 test/monniaux/float_mat/Makefile create mode 100644 test/monniaux/float_mat/float_mat.c create mode 100644 test/monniaux/float_mat/float_mat.h create mode 100644 test/monniaux/float_mat/float_mat_run.c (limited to 'test/monniaux/float_mat') diff --git a/test/monniaux/float_mat/Makefile b/test/monniaux/float_mat/Makefile new file mode 100644 index 00000000..0b66010a --- /dev/null +++ b/test/monniaux/float_mat/Makefile @@ -0,0 +1,21 @@ +include ../rules.mk + +PRODUCTS=float_mat.host float_mat.gcc.k1c.out float_mat.ccomp.k1c.out float_mat.ccomp.k1c.s float_mat.gcc.k1c.s float_mat.gcc.k1c float_mat.ccomp.k1c + +all: $(PRODUCTS) + +float_mat.host: float_mat.c float_mat_run.c float_mat.h + $(CC) $(CFLAGS) float_mat.c float_mat_run.c -o $@ + +float_mat.gcc.k1c.s float_mat.ccomp.k1c.s float_mat_run.gcc.k1c.s: float_mat.h + +float_mat.gcc.k1c: float_mat.gcc.k1c.o float_mat_run.gcc.k1c.o + $(K1C_CC) $(K1C_CFLAGS) $+ -o $@ + +float_mat.ccomp.k1c: float_mat.ccomp.k1c.o float_mat_run.gcc.k1c.o + $(K1C_CCOMP) $(K1C_CCOMPFLAGS) $+ -o $@ + +clean: + $(RM) -f $(PRODUCTS) float_mat.gcc.k1c.o float_mat.ccomp.k1c.o float_mat_run.gcc.k1c.o + +.PHONY: clean diff --git a/test/monniaux/float_mat/float_mat.c b/test/monniaux/float_mat/float_mat.c new file mode 100644 index 00000000..818dbded --- /dev/null +++ b/test/monniaux/float_mat/float_mat.c @@ -0,0 +1,182 @@ +#include "float_mat.h" + +#define ADD += +#define MUL * + +void REAL_mat_mul1(unsigned m, unsigned n, unsigned p, + REAL * restrict c, unsigned stride_c, + const REAL *a, unsigned stride_a, + const REAL *b, unsigned stride_b) { + for(unsigned i=0; i 0) { + do { + CHUNK + CHUNK + j2++; + } while (j2 < n2); + } + if (n%2) { + total ADD (*pa_i_j MUL *pb_j_k); + } + pc_i[k] = total; + } + pa_i += stride_a; + pc_i += stride_c; + } +} + +#define UNROLL 4 +void REAL_mat_mul7(unsigned m, unsigned n, unsigned p, + REAL * c, unsigned stride_c, + const REAL *a, unsigned stride_a, + const REAL *b, unsigned stride_b) { + const REAL *pa_i = a; + REAL * pc_i = c; + for(unsigned i=0; i 0) { + do { + CHUNK + CHUNK + CHUNK + CHUNK + j4++; + } while (j4 < n4); + } + } + { + unsigned j4=0, n4=n%UNROLL; + if (n4 > 0) { + do { + CHUNK + j4++; + } while (j4 < n4); + } + } + pc_i[k] = total; + } + pa_i += stride_a; + pc_i += stride_c; + } +} diff --git a/test/monniaux/float_mat/float_mat.h b/test/monniaux/float_mat/float_mat.h new file mode 100644 index 00000000..d0f48951 --- /dev/null +++ b/test/monniaux/float_mat/float_mat.h @@ -0,0 +1,50 @@ +#include +#include + +typedef double REAL; + +void REAL_mat_mul1(unsigned m, unsigned n, unsigned p, + REAL * restrict c, unsigned stride_c, + const REAL *a, unsigned stride_a, + const REAL *b, unsigned stride_b); + +void REAL_mat_mul2(unsigned m, unsigned n, unsigned p, + REAL * restrict c, unsigned stride_c, + const REAL *a, unsigned stride_a, + const REAL *b, unsigned stride_b); + +void REAL_mat_mul3(unsigned m, unsigned n, unsigned p, + REAL * restrict c, unsigned stride_c, + const REAL *a, unsigned stride_a, + const REAL *b, unsigned stride_b); + +void REAL_mat_mul4(unsigned m, unsigned n, unsigned p, + REAL * restrict c, unsigned stride_c, + const REAL *a, unsigned stride_a, + const REAL *b, unsigned stride_b); + +void REAL_mat_mul5(unsigned m, unsigned n, unsigned p, + REAL * restrict c, unsigned stride_c, + const REAL *a, unsigned stride_a, + const REAL *b, unsigned stride_b); + +void REAL_mat_mul6(unsigned m, unsigned n, unsigned p, + REAL * restrict c, unsigned stride_c, + const REAL *a, unsigned stride_a, + const REAL *b, unsigned stride_b); + +void REAL_mat_mul7(unsigned m, unsigned n, unsigned p, + REAL * restrict c, unsigned stride_c, + const REAL *a, unsigned stride_a, + const REAL *b, unsigned stride_b); + +REAL REAL_random(void); + +void REAL_mat_random(unsigned m, + unsigned n, + REAL *a, unsigned stride_a); + +bool REAL_mat_equal(unsigned m, + unsigned n, + const REAL *a, unsigned stride_a, + const REAL *b, unsigned stride_b); diff --git a/test/monniaux/float_mat/float_mat_run.c b/test/monniaux/float_mat/float_mat_run.c new file mode 100644 index 00000000..cb5e2110 --- /dev/null +++ b/test/monniaux/float_mat/float_mat_run.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include "float_mat.h" +#include "../cycles.h" + +/* FIXME DMonniaux should be in the other but branches and float_of_int not implemented */ +bool REAL_mat_equal(unsigned m, + unsigned n, + const REAL *a, unsigned stride_a, + const REAL *b, unsigned stride_b) { + for(unsigned i=0; i Date: Mon, 18 Feb 2019 11:41:24 +0100 Subject: forgot to deallocate block -g changes performance --- test/monniaux/float_mat/Makefile | 2 +- test/monniaux/float_mat/float_mat.h | 2 +- test/monniaux/float_mat/float_mat_run.c | 7 ++++++- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'test/monniaux/float_mat') diff --git a/test/monniaux/float_mat/Makefile b/test/monniaux/float_mat/Makefile index 0b66010a..60bde6aa 100644 --- a/test/monniaux/float_mat/Makefile +++ b/test/monniaux/float_mat/Makefile @@ -16,6 +16,6 @@ float_mat.ccomp.k1c: float_mat.ccomp.k1c.o float_mat_run.gcc.k1c.o $(K1C_CCOMP) $(K1C_CCOMPFLAGS) $+ -o $@ clean: - $(RM) -f $(PRODUCTS) float_mat.gcc.k1c.o float_mat.ccomp.k1c.o float_mat_run.gcc.k1c.o + $(RM) -f *.k1c *.host *.o *.s .PHONY: clean diff --git a/test/monniaux/float_mat/float_mat.h b/test/monniaux/float_mat/float_mat.h index d0f48951..03a25036 100644 --- a/test/monniaux/float_mat/float_mat.h +++ b/test/monniaux/float_mat/float_mat.h @@ -1,7 +1,7 @@ #include #include -typedef double REAL; +typedef float REAL; void REAL_mat_mul1(unsigned m, unsigned n, unsigned p, REAL * restrict c, unsigned stride_c, diff --git a/test/monniaux/float_mat/float_mat_run.c b/test/monniaux/float_mat/float_mat_run.c index cb5e2110..448bb8a5 100644 --- a/test/monniaux/float_mat/float_mat_run.c +++ b/test/monniaux/float_mat/float_mat_run.c @@ -12,7 +12,11 @@ bool REAL_mat_equal(unsigned m, const REAL *b, unsigned stride_b) { for(unsigned i=0; i Date: Tue, 19 Feb 2019 12:48:00 +0100 Subject: mul8: loop-invariant code motion --- test/monniaux/float_mat/float_mat.c | 46 +++++++++++++++++++++++++++++++++ test/monniaux/float_mat/float_mat.h | 7 ++++- test/monniaux/float_mat/float_mat_run.c | 13 ++++++++-- 3 files changed, 63 insertions(+), 3 deletions(-) (limited to 'test/monniaux/float_mat') diff --git a/test/monniaux/float_mat/float_mat.c b/test/monniaux/float_mat/float_mat.c index 818dbded..45612635 100644 --- a/test/monniaux/float_mat/float_mat.c +++ b/test/monniaux/float_mat/float_mat.c @@ -1,4 +1,5 @@ #include "float_mat.h" +#include #define ADD += #define MUL * @@ -180,3 +181,48 @@ void REAL_mat_mul7(unsigned m, unsigned n, unsigned p, pc_i += stride_c; } } + +#undef CHUNK +#define CHUNK \ + total ADD (*pa_i_j MUL *pb_j_k); \ + pa_i_j ++; \ + pb_j_k = (REAL*) ((char*) pb_j_k + stride_b_scaled); + +void REAL_mat_mul8(unsigned m, unsigned n, unsigned p, + REAL * c, unsigned stride_c, + const REAL *a, unsigned stride_a, + const REAL *b, unsigned stride_b) { + const REAL *pa_i = a; + REAL * pc_i = c; + size_t stride_b_scaled = sizeof(REAL) * stride_b; + for(unsigned i=0; i 0) { + do { + CHUNK + CHUNK + CHUNK + CHUNK + j4++; + } while (j4 < n4); + } + } + { + unsigned j4=0, n4=n%UNROLL; + if (n4 > 0) { + do { + CHUNK + j4++; + } while (j4 < n4); + } + } + pc_i[k] = total; + } + pa_i += stride_a; + pc_i += stride_c; + } +} diff --git a/test/monniaux/float_mat/float_mat.h b/test/monniaux/float_mat/float_mat.h index 03a25036..3b787b1f 100644 --- a/test/monniaux/float_mat/float_mat.h +++ b/test/monniaux/float_mat/float_mat.h @@ -1,7 +1,7 @@ #include #include -typedef float REAL; +typedef double REAL; void REAL_mat_mul1(unsigned m, unsigned n, unsigned p, REAL * restrict c, unsigned stride_c, @@ -38,6 +38,11 @@ void REAL_mat_mul7(unsigned m, unsigned n, unsigned p, const REAL *a, unsigned stride_a, const REAL *b, unsigned stride_b); +void REAL_mat_mul8(unsigned m, unsigned n, unsigned p, + REAL * restrict c, unsigned stride_c, + const REAL *a, unsigned stride_a, + const REAL *b, unsigned stride_b); + REAL REAL_random(void); void REAL_mat_random(unsigned m, diff --git a/test/monniaux/float_mat/float_mat_run.c b/test/monniaux/float_mat/float_mat_run.c index 448bb8a5..f5dfa0af 100644 --- a/test/monniaux/float_mat/float_mat_run.c +++ b/test/monniaux/float_mat/float_mat_run.c @@ -81,19 +81,26 @@ int main() { REAL_mat_mul7(m, n, p, c7, p, a, n, b, p); c7_time = get_cycle()-c7_time; + REAL *c8 = malloc(sizeof(REAL) * m * p); + cycle_t c8_time = get_cycle(); + REAL_mat_mul8(m, n, p, c8, p, a, n, b, p); + c8_time = get_cycle()-c8_time; + printf("c1==c2: %s\n" "c1==c3: %s\n" "c1==c4: %s\n" "c1==c5: %s\n" "c1==c6: %s\n" "c1==c7: %s\n" + "c1==c8: %s\n" "c1_time = %" PRIu64 "\n" "c2_time = %" PRIu64 "\n" "c3_time = %" PRIu64 "\n" "c4_time = %" PRIu64 "\n" "c5_time = %" PRIu64 "\n" "c6_time = %" PRIu64 "\n" - "c7_time = %" PRIu64 "\n", + "c7_time = %" PRIu64 "\n" + "c8_time = %" PRIu64 "\n", REAL_mat_equal(m, n, c1, p, c2, p)?"true":"false", REAL_mat_equal(m, n, c1, p, c3, p)?"true":"false", @@ -101,6 +108,7 @@ int main() { REAL_mat_equal(m, n, c1, p, c5, p)?"true":"false", REAL_mat_equal(m, n, c1, p, c6, p)?"true":"false", REAL_mat_equal(m, n, c1, p, c7, p)?"true":"false", + REAL_mat_equal(m, n, c1, p, c8, p)?"true":"false", c1_time, c2_time, @@ -108,7 +116,8 @@ int main() { c4_time, c5_time, c6_time, - c7_time); + c7_time, + c8_time); free(a); free(b); -- cgit From 3dab0dce340fd6de7bd31f0edab312efa10594ff Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Tue, 12 Mar 2019 12:58:40 +0100 Subject: forgot a free() --- test/monniaux/float_mat/float_mat_run.c | 1 + 1 file changed, 1 insertion(+) (limited to 'test/monniaux/float_mat') diff --git a/test/monniaux/float_mat/float_mat_run.c b/test/monniaux/float_mat/float_mat_run.c index f5dfa0af..5d34bb70 100644 --- a/test/monniaux/float_mat/float_mat_run.c +++ b/test/monniaux/float_mat/float_mat_run.c @@ -128,5 +128,6 @@ int main() { free(c5); free(c6); free(c7); + free(c8); return 0; } -- cgit From 24e97bd87918f2c487416744ba12a78aba35a9e5 Mon Sep 17 00:00:00 2001 From: Cyril SIX Date: Fri, 26 Apr 2019 16:35:30 +0200 Subject: Changes to include a -O1 -fschedule-insns2 gcc run as well --- test/monniaux/float_mat/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'test/monniaux/float_mat') diff --git a/test/monniaux/float_mat/Makefile b/test/monniaux/float_mat/Makefile index 60bde6aa..0d3d68d6 100644 --- a/test/monniaux/float_mat/Makefile +++ b/test/monniaux/float_mat/Makefile @@ -1,6 +1,6 @@ include ../rules.mk -PRODUCTS=float_mat.host float_mat.gcc.k1c.out float_mat.ccomp.k1c.out float_mat.ccomp.k1c.s float_mat.gcc.k1c.s float_mat.gcc.k1c float_mat.ccomp.k1c +PRODUCTS=float_mat.host float_mat.gcc.o1.k1c.out float_mat.gcc.k1c.out float_mat.ccomp.k1c.out float_mat.ccomp.k1c.s float_mat.gcc.k1c.s float_mat.gcc.k1c float_mat.ccomp.k1c all: $(PRODUCTS) @@ -12,6 +12,9 @@ float_mat.gcc.k1c.s float_mat.ccomp.k1c.s float_mat_run.gcc.k1c.s: float_mat.h float_mat.gcc.k1c: float_mat.gcc.k1c.o float_mat_run.gcc.k1c.o $(K1C_CC) $(K1C_CFLAGS) $+ -o $@ +float_mat.gcc.o1.k1c: float_mat.gcc.o1.k1c.o float_mat_run.gcc.o1.k1c.o + $(K1C_CC) $(K1C_CFLAGS_O1) $+ -o $@ + float_mat.ccomp.k1c: float_mat.ccomp.k1c.o float_mat_run.gcc.k1c.o $(K1C_CCOMP) $(K1C_CCOMPFLAGS) $+ -o $@ -- cgit From 76abb605749d1b8ddcc842cecb258fa755d63ccf Mon Sep 17 00:00:00 2001 From: Cyril SIX Date: Tue, 14 May 2019 18:01:28 +0200 Subject: Avancement sur la génération de Makefile des benchmarks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/monniaux/float_mat/Makefile | 24 ------------------------ test/monniaux/float_mat/make.proto | 2 ++ 2 files changed, 2 insertions(+), 24 deletions(-) delete mode 100644 test/monniaux/float_mat/Makefile create mode 100644 test/monniaux/float_mat/make.proto (limited to 'test/monniaux/float_mat') diff --git a/test/monniaux/float_mat/Makefile b/test/monniaux/float_mat/Makefile deleted file mode 100644 index 0d3d68d6..00000000 --- a/test/monniaux/float_mat/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -include ../rules.mk - -PRODUCTS=float_mat.host float_mat.gcc.o1.k1c.out float_mat.gcc.k1c.out float_mat.ccomp.k1c.out float_mat.ccomp.k1c.s float_mat.gcc.k1c.s float_mat.gcc.k1c float_mat.ccomp.k1c - -all: $(PRODUCTS) - -float_mat.host: float_mat.c float_mat_run.c float_mat.h - $(CC) $(CFLAGS) float_mat.c float_mat_run.c -o $@ - -float_mat.gcc.k1c.s float_mat.ccomp.k1c.s float_mat_run.gcc.k1c.s: float_mat.h - -float_mat.gcc.k1c: float_mat.gcc.k1c.o float_mat_run.gcc.k1c.o - $(K1C_CC) $(K1C_CFLAGS) $+ -o $@ - -float_mat.gcc.o1.k1c: float_mat.gcc.o1.k1c.o float_mat_run.gcc.o1.k1c.o - $(K1C_CC) $(K1C_CFLAGS_O1) $+ -o $@ - -float_mat.ccomp.k1c: float_mat.ccomp.k1c.o float_mat_run.gcc.k1c.o - $(K1C_CCOMP) $(K1C_CCOMPFLAGS) $+ -o $@ - -clean: - $(RM) -f *.k1c *.host *.o *.s - -.PHONY: clean diff --git a/test/monniaux/float_mat/make.proto b/test/monniaux/float_mat/make.proto new file mode 100644 index 00000000..3628afbb --- /dev/null +++ b/test/monniaux/float_mat/make.proto @@ -0,0 +1,2 @@ +objdeps: [{name: float_mat_run, compiler: gcc}] +target: float_mat -- cgit From 4f3b7c0d75fd90ac064419d19d7af2e340d516aa Mon Sep 17 00:00:00 2001 From: Cyril SIX Date: Fri, 17 May 2019 12:03:18 +0200 Subject: Adding more measures --- test/monniaux/float_mat/float_mat_run.c | 16 ++++++++-------- test/monniaux/float_mat/make.proto | 1 + 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'test/monniaux/float_mat') diff --git a/test/monniaux/float_mat/float_mat_run.c b/test/monniaux/float_mat/float_mat_run.c index 5d34bb70..329648c2 100644 --- a/test/monniaux/float_mat/float_mat_run.c +++ b/test/monniaux/float_mat/float_mat_run.c @@ -93,14 +93,14 @@ int main() { "c1==c6: %s\n" "c1==c7: %s\n" "c1==c8: %s\n" - "c1_time = %" PRIu64 "\n" - "c2_time = %" PRIu64 "\n" - "c3_time = %" PRIu64 "\n" - "c4_time = %" PRIu64 "\n" - "c5_time = %" PRIu64 "\n" - "c6_time = %" PRIu64 "\n" - "c7_time = %" PRIu64 "\n" - "c8_time = %" PRIu64 "\n", + "c1_time : %" PRIu64 "\n" + "c2_time : %" PRIu64 "\n" + "c3_time : %" PRIu64 "\n" + "c4_time : %" PRIu64 "\n" + "c5_time : %" PRIu64 "\n" + "c6_time : %" PRIu64 "\n" + "c7_time : %" PRIu64 "\n" + "c8_time : %" PRIu64 "\n", REAL_mat_equal(m, n, c1, p, c2, p)?"true":"false", REAL_mat_equal(m, n, c1, p, c3, p)?"true":"false", diff --git a/test/monniaux/float_mat/make.proto b/test/monniaux/float_mat/make.proto index 3628afbb..ebdd8930 100644 --- a/test/monniaux/float_mat/make.proto +++ b/test/monniaux/float_mat/make.proto @@ -1,2 +1,3 @@ objdeps: [{name: float_mat_run, compiler: gcc}] target: float_mat +measures: [[c2_time, c2]] -- cgit From 1aa0d92ddba4e017f1b8f9aebc1757a8ad77c0eb Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Wed, 29 May 2019 23:24:45 +0200 Subject: take other measurements --- test/monniaux/float_mat/make.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/monniaux/float_mat') diff --git a/test/monniaux/float_mat/make.proto b/test/monniaux/float_mat/make.proto index ebdd8930..e775e9b8 100644 --- a/test/monniaux/float_mat/make.proto +++ b/test/monniaux/float_mat/make.proto @@ -1,3 +1,3 @@ objdeps: [{name: float_mat_run, compiler: gcc}] target: float_mat -measures: [[c2_time, c2]] +measures: [[c2_time, c2], [c8_time, c8]] -- cgit From c1330c1f6863d4029bfa965b4151e629d72a2217 Mon Sep 17 00:00:00 2001 From: Cyril SIX Date: Wed, 17 Jul 2019 11:52:14 +0200 Subject: Up to ntt --- test/monniaux/float_mat/Makefile | 4 ++++ test/monniaux/float_mat/make.proto | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 test/monniaux/float_mat/Makefile delete mode 100644 test/monniaux/float_mat/make.proto (limited to 'test/monniaux/float_mat') diff --git a/test/monniaux/float_mat/Makefile b/test/monniaux/float_mat/Makefile new file mode 100644 index 00000000..69621159 --- /dev/null +++ b/test/monniaux/float_mat/Makefile @@ -0,0 +1,4 @@ +TARGET=float_mat +MEASURES="c1 c2 c3 c4 c5 c6 c7 c8" + +include ../rules.mk diff --git a/test/monniaux/float_mat/make.proto b/test/monniaux/float_mat/make.proto deleted file mode 100644 index e775e9b8..00000000 --- a/test/monniaux/float_mat/make.proto +++ /dev/null @@ -1,3 +0,0 @@ -objdeps: [{name: float_mat_run, compiler: gcc}] -target: float_mat -measures: [[c2_time, c2], [c8_time, c8]] -- cgit From 1d7e934386fdb23f4e16f056e3d419be09ec0b02 Mon Sep 17 00:00:00 2001 From: Cyril SIX Date: Wed, 17 Jul 2019 14:42:40 +0200 Subject: Portage réussi et complet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/monniaux/float_mat/float_mat_run.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'test/monniaux/float_mat') diff --git a/test/monniaux/float_mat/float_mat_run.c b/test/monniaux/float_mat/float_mat_run.c index 329648c2..2f590f98 100644 --- a/test/monniaux/float_mat/float_mat_run.c +++ b/test/monniaux/float_mat/float_mat_run.c @@ -93,14 +93,14 @@ int main() { "c1==c6: %s\n" "c1==c7: %s\n" "c1==c8: %s\n" - "c1_time : %" PRIu64 "\n" - "c2_time : %" PRIu64 "\n" - "c3_time : %" PRIu64 "\n" - "c4_time : %" PRIu64 "\n" - "c5_time : %" PRIu64 "\n" - "c6_time : %" PRIu64 "\n" - "c7_time : %" PRIu64 "\n" - "c8_time : %" PRIu64 "\n", + "c1 cycles: %" PRIu64 "\n" + "c2 cycles: %" PRIu64 "\n" + "c3 cycles: %" PRIu64 "\n" + "c4 cycles: %" PRIu64 "\n" + "c5 cycles: %" PRIu64 "\n" + "c6 cycles: %" PRIu64 "\n" + "c7 cycles: %" PRIu64 "\n" + "c8 cycles: %" PRIu64 "\n", REAL_mat_equal(m, n, c1, p, c2, p)?"true":"false", REAL_mat_equal(m, n, c1, p, c3, p)?"true":"false", -- cgit