From bc1e43ea95b9455cdccee442db77bc5fafd3dcc6 Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Tue, 26 May 2020 22:11:32 +0200 Subject: tests for kvx --- test/kvx/sort/.gitignore | 9 +++++ test/kvx/sort/Makefile | 91 ++++++++++++++++++++++++++++++++++++++++++++++ test/kvx/sort/README.md | 17 +++++++++ test/kvx/sort/insertion.c | 59 ++++++++++++++++++++++++++++++ test/kvx/sort/insertion.h | 6 ++++ test/kvx/sort/main.c | 34 ++++++++++++++++++ test/kvx/sort/merge.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++ test/kvx/sort/merge.h | 7 ++++ test/kvx/sort/selection.c | 62 ++++++++++++++++++++++++++++++++ test/kvx/sort/selection.h | 6 ++++ test/kvx/sort/test.h | 6 ++++ 11 files changed, 389 insertions(+) create mode 100644 test/kvx/sort/.gitignore create mode 100644 test/kvx/sort/Makefile create mode 100644 test/kvx/sort/README.md create mode 100644 test/kvx/sort/insertion.c create mode 100644 test/kvx/sort/insertion.h create mode 100644 test/kvx/sort/main.c create mode 100644 test/kvx/sort/merge.c create mode 100644 test/kvx/sort/merge.h create mode 100644 test/kvx/sort/selection.c create mode 100644 test/kvx/sort/selection.h create mode 100644 test/kvx/sort/test.h (limited to 'test/kvx/sort') diff --git a/test/kvx/sort/.gitignore b/test/kvx/sort/.gitignore new file mode 100644 index 00000000..070b87c4 --- /dev/null +++ b/test/kvx/sort/.gitignore @@ -0,0 +1,9 @@ +main-test-ccomp-kvx +main-test-gcc-kvx +main-test-gcc-x86 +merge-test-gcc-kvx +merge-test-gcc-x86 +selection-test-gcc-kvx +selection-test-gcc-x86 +insertion-test-gcc-kvx +insertion-test-gcc-x86 diff --git a/test/kvx/sort/Makefile b/test/kvx/sort/Makefile new file mode 100644 index 00000000..c4090352 --- /dev/null +++ b/test/kvx/sort/Makefile @@ -0,0 +1,91 @@ +KVXC ?= k1-cos-gcc +CC ?= gcc +CCOMP ?= ccomp +CFLAGS ?= -O2 +SIMU ?= k1-mppa +TIMEOUT ?= 10s + +KVXCPATH=$(shell which $(KVXC)) +CCPATH=$(shell which $(CC)) +CCOMPPATH=$(shell which $(CCOMP)) +SIMUPATH=$(shell which $(SIMU)) + +PRNG=../prng/prng.c + +CFILES=insertion.c merge.c selection.c main.c + +ALL= insertion-gcc-x86 insertion-gcc-kvx insertion-ccomp-kvx\ + selection-gcc-x86 selection-gcc-kvx selection-ccomp-kvx\ + merge-gcc-x86 merge-gcc-kvx merge-ccomp-kvx\ + main-gcc-x86 main-gcc-kvx main-ccomp-kvx + +CCOMP_OUT= insertion-ccomp-kvx.out selection-ccomp-kvx.out merge-ccomp-kvx.out\ + main-ccomp-kvx.out +GCC_OUT= insertion-gcc-kvx.out selection-gcc-kvx.out merge-gcc-kvx.out\ + main-gcc-kvx.out +X86_GCC_OUT= insertion-gcc-x86.out selection-gcc-x86.out merge-gcc-x86.out\ + main-gcc-x86.out +STUB_OUT= .zero + +all: $(ALL) + +main-gcc-x86: $(CFILES) $(PRNG) $(CCPATH) + $(CC) $(CFLAGS) $(filter-out $(CCPATH),$^) -o $@ + +%-gcc-x86: %.c $(PRNG) $(CCPATH) + $(CC) -D__UNIT_TEST_$$(echo $(basename $<) | tr a-z A-Z)__ $(CFLAGS) $(filter-out $(CCPATH),$^) -o $@ + +main-gcc-kvx: $(CFILES) $(PRNG) $(CCPATH) + $(KVXC) $(CFLAGS) $(filter-out $(CCPATH),$^) -o $@ + +%-gcc-kvx: %.c $(PRNG) $(KVXCPATH) + $(KVXC) -D__UNIT_TEST_$$(echo $(basename $<) | tr a-z A-Z)__ $(CFLAGS) $(filter-out $(KVXCPATH),$^) -o $@ + +main-ccomp-kvx: $(CFILES) $(PRNG) $(CCOMPPATH) + $(CCOMP) $(CFLAGS) $(filter-out $(CCOMPPATH),$^) -o $@ + +%-ccomp-kvx: %.c $(PRNG) $(CCOMPPATH) + $(CCOMP) -D__UNIT_TEST_$$(echo $(basename $<) | tr a-z A-Z)__ $(CFLAGS) $(filter-out $(CCOMPPATH),$^) -o $@ + +.SECONDARY: +%x86.out: %x86 + ret=0; timeout $(TIMEOUT) ./$< > $@ || { ret=$$?; }; echo $$ret >> $@ + +%kvx.out: %kvx $(SIMUPATH) + ret=0; timeout $(TIMEOUT) $(SIMU) -- $< > $@ || { ret=$$?; }; echo $$ret >> $@ + +.zero: + @echo "0" > $@ + +.PHONY: +test-x86: $(STUB_OUT) $(X86_GCC_OUT) + @for test in $(wordlist 2,100,$^); do\ + if ! diff $$test $(STUB_OUT); then\ + >&2 echo "ERROR x86: $$test failed";\ + else\ + echo "GOOD x86: $$test succeeded";\ + fi;\ + done + +.PHONY: +test-kvx: $(STUB_OUT) $(GCC_OUT) + @for test in $(wordlist 2,100,$^); do\ + if ! diff $$test $(STUB_OUT); then\ + >&2 echo "ERROR kvx: $$test failed";\ + else\ + echo "GOOD kvx: $$test succeeded";\ + fi;\ + done + +.PHONY: +test: test-x86 test-kvx + +.PHONY: +check: $(STUB_OUT) $(CCOMP_OUT) + @for test in $(wordlist 2,100,$^); do\ + if ! diff $$test $(STUB_OUT); then\ + >&2 echo "ERROR kvx: $$test failed";\ + else\ + echo "GOOD kvx: $$test succeeded";\ + fi;\ + done diff --git a/test/kvx/sort/README.md b/test/kvx/sort/README.md new file mode 100644 index 00000000..98ed539d --- /dev/null +++ b/test/kvx/sort/README.md @@ -0,0 +1,17 @@ +PRNG +==== + +This is a simple Pseudo Random Number Generator. + +`prng.c` contains a simple unitary test that compares the sum of the "bytewise sum" +of 1000 generated numbers to a hardcoded result, that is the one obtained with +`gcc -O2` on a x86 processor, and returns 0 if the result is correct. + +The following commands can be run inside that folder: + +- `make`: produces the unitary test binaries + - `prng-test-gcc-x86` : binary from gcc on x86 + - `prng-test-kvx-x86` : binary from gcc on kvx + - `prng-test-ccomp-x86` : binary from ccomp on kvx +- `make test`: tests the return value of the binaries produced by gcc. +- `make check`: tests the return value of the binary produced by CompCert. diff --git a/test/kvx/sort/insertion.c b/test/kvx/sort/insertion.c new file mode 100644 index 00000000..bca09599 --- /dev/null +++ b/test/kvx/sort/insertion.c @@ -0,0 +1,59 @@ +#include "../prng/prng.h" +#include "../prng/types.h" + +#ifdef __UNIT_TEST_INSERTION__ +#define SIZE 100 +#else +#include "test.h" +#endif + +void swap_ins(uint64_t *a, uint64_t *b){ + uint64_t tmp = *a; + *a = *b; + *b = tmp; +} + +int insert_sort(uint64_t *res, const uint64_t *T){ + int i, j; + + if (SIZE <= 0) + return -1; + + for (i = 0 ; i < SIZE ; i++) + res[i] = T[i]; + + for (i = 0 ; i < SIZE-1 ; i++){ + if (res[i] > res[i+1]){ + swap_ins(&res[i], &res[i+1]); + for (j = i ; j > 0 ; j--) + if (res[j-1] > res[j]) + swap_ins(&res[j-1], &res[j]); + } + } + + return 0; +} + +#ifdef __UNIT_TEST_INSERTION__ +int main(void){ + uint64_t T[SIZE]; + uint64_t res[SIZE]; + int i; + srand(42); + + for (i = 0 ; i < SIZE ; i++) + T[i] = randlong(); + + /* Sorting the table */ + if (insert_sort(res, T) < 0) return -1; + + /* Computing max(T) */ + uint64_t max = T[0]; + for (i = 1 ; i < SIZE ; i++) + if (T[i] > max) + max = T[i]; + + /* We should have: max(T) == res[SIZE] */ + return !(max == res[SIZE-1]); +} +#endif // __UNIT_TEST_INSERTION__ diff --git a/test/kvx/sort/insertion.h b/test/kvx/sort/insertion.h new file mode 100644 index 00000000..6e37c5fe --- /dev/null +++ b/test/kvx/sort/insertion.h @@ -0,0 +1,6 @@ +#ifndef __INSERTION_H__ +#define __INSERTION_H__ + +int insert_sort(uint64_t *res, const uint64_t *T); + +#endif // __INSERTION_H__ diff --git a/test/kvx/sort/main.c b/test/kvx/sort/main.c new file mode 100644 index 00000000..aef419aa --- /dev/null +++ b/test/kvx/sort/main.c @@ -0,0 +1,34 @@ +#include "../prng/prng.h" +#include "../prng/types.h" + +#include "test.h" +#include "insertion.h" +#include "selection.h" +#include "merge.h" + +int main(void){ + uint64_t T[SIZE]; + uint64_t res1[SIZE], res2[SIZE], res3[SIZE]; + int i; + srand(42); + + for (i = 0 ; i < SIZE ; i++) + T[i] = randlong(); + + /* insertion sort */ + if (insert_sort(res1, T) < 0) return -1; + + /* selection sort */ + if (select_sort(res2, T) < 0) return -2; + + /* merge sort */ + if (merge_sort(res3, T) < 0) return -3; + + /* We should have: res1[i] == res2[i] == res3[i] */ + for (i = 0 ; i < SIZE ; i++){ + if (!(res1[i] == res2[i] && res2[i] == res3[i])) + return -4; + } + + return 0; +} diff --git a/test/kvx/sort/merge.c b/test/kvx/sort/merge.c new file mode 100644 index 00000000..99f8ba85 --- /dev/null +++ b/test/kvx/sort/merge.c @@ -0,0 +1,92 @@ +#include "../prng/prng.h" +#include "../prng/types.h" + +//https://en.wikipedia.org/wiki/Merge_sort + +#ifdef __UNIT_TEST_MERGE__ +#define SIZE 100 +#else +#include "test.h" +#endif + +int min(int a, int b){ + return (a < b)?a:b; +} + +void BottomUpMerge(const uint64_t *A, int iLeft, int iRight, int iEnd, uint64_t *B) +{ + int i = iLeft, j = iRight, k; + for (k = iLeft; k < iEnd; k++) { + if (i < iRight && (j >= iEnd || A[i] <= A[j])) { + B[k] = A[i]; + i = i + 1; + } else { + B[k] = A[j]; + j = j + 1; + } + } +} + +void CopyArray(uint64_t *to, const uint64_t *from) +{ + const int n = SIZE; + int i; + + for(i = 0; i < n; i++) + to[i] = from[i]; +} + +void BottomUpMergeSort(uint64_t *A, uint64_t *B) +{ + const int n = SIZE; + int width, i; + + for (width = 1; width < n; width = 2 * width) + { + for (i = 0; i < n; i = i + 2 * width) + { + BottomUpMerge(A, i, min(i+width, n), min(i+2*width, n), B); + } + CopyArray(A, B); + } +} + +int merge_sort(uint64_t *res, const uint64_t *T){ + int i; + + if (SIZE <= 0) + return -1; + + uint64_t B[SIZE]; + uint64_t *A = res; + for (i = 0 ; i < SIZE ; i++) + A[i] = T[i]; + + BottomUpMergeSort(A, B); + + return 0; +} + +#ifdef __UNIT_TEST_MERGE__ +int main(void){ + uint64_t T[SIZE]; + uint64_t res[SIZE]; + int i; + srand(42); + + for (i = 0 ; i < SIZE ; i++) + T[i] = randlong(); + + /* Sorting the table */ + if (merge_sort(res, T) < 0) return -1; + + /* Computing max(T) */ + uint64_t max = T[0]; + for (i = 1 ; i < SIZE ; i++) + if (T[i] > max) + max = T[i]; + + /* We should have: max(T) == res[SIZE] */ + return !(max == res[SIZE-1]); +} +#endif // __UNIT_TEST_MERGE__ diff --git a/test/kvx/sort/merge.h b/test/kvx/sort/merge.h new file mode 100644 index 00000000..439ce64a --- /dev/null +++ b/test/kvx/sort/merge.h @@ -0,0 +1,7 @@ +#ifndef __MERGE_H__ +#define __MERGE_H__ + +int merge_sort(uint64_t *res, const uint64_t *T); + +#endif // __MERGE_H__ + diff --git a/test/kvx/sort/selection.c b/test/kvx/sort/selection.c new file mode 100644 index 00000000..df4be04f --- /dev/null +++ b/test/kvx/sort/selection.c @@ -0,0 +1,62 @@ +#include "../prng/prng.h" +#include "../prng/types.h" + +#ifdef __UNIT_TEST_SELECTION__ +#define SIZE 100 +#else +#include "test.h" +#endif + +void swap_sel(uint64_t *a, uint64_t *b){ + uint64_t tmp = *a; + *a = *b; + *b = tmp; +} + +int select_sort(uint64_t *res, const uint64_t *T){ + int i, j, iMin; + + if (SIZE <= 0) + return -1; + + for (i = 0 ; i < SIZE ; i++) + res[i] = T[i]; + + for (j = 0 ; j < SIZE ; j++){ + iMin = j; + for (i = j+1 ; i < SIZE ; i++) + if (res[i] < res[iMin]) + iMin = i; + + if (iMin != j) + swap_sel (&res[j], &res[iMin]); + } + + return 0; +} + +#ifdef __UNIT_TEST_SELECTION__ +int main(void){ + uint64_t T[SIZE]; + uint64_t res[SIZE]; + uint64_t max; + int i; + srand(42); + + for (i = 0 ; i < SIZE ; i++) + T[i] = randlong(); + + /* Sorting the table */ + if (select_sort(res, T) < 0) return -1; + + /* Computing max(T) */ + max = T[0]; + for (i = 1 ; i < SIZE ; i++) + if (T[i] > max) + max = T[i]; + + /* We should have: max(T) == res[SIZE] */ + return !(max == res[SIZE-1]); +} +#endif // __UNIT_TEST_SELECTION__ + diff --git a/test/kvx/sort/selection.h b/test/kvx/sort/selection.h new file mode 100644 index 00000000..92a6b461 --- /dev/null +++ b/test/kvx/sort/selection.h @@ -0,0 +1,6 @@ +#ifndef __SELECTION_H__ +#define __SELECTION_H__ + +int select_sort(uint64_t *res, const uint64_t *T); + +#endif // __SELECTION_H__ diff --git a/test/kvx/sort/test.h b/test/kvx/sort/test.h new file mode 100644 index 00000000..4501ee38 --- /dev/null +++ b/test/kvx/sort/test.h @@ -0,0 +1,6 @@ +#ifndef __TEST_H__ +#define __TEST_H__ + +#define SIZE 100 + +#endif -- cgit