Skip to content

Commit 886a615

Browse files
timkalerwsmoses
authored andcommitted
add functional c tests via check-enzyme-c command (#15)
* add functional c tests via check-enzyme-c command * add functional c tests to github workflows * fix hardcoded path * test paths again * another attempt at fix * another attempt to fix clang path in ci * install clang * test loops in build system * another build test * change return type of externed builtinautodiff to fix build * think it works with build system now? * Add an expected fail test * make ifcrash.ll be expect fail * make tests use clang instead of clang++ for c * only run functional tests on llvm 7
1 parent 60b04a8 commit 886a615

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+890
-0
lines changed
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Functional Tests CI
2+
3+
on: [push]
4+
5+
jobs:
6+
build:
7+
name: Test on os ${{ matrix.os }} and llvm ${{ matrix.llvm }} mode ${{ matrix.build }}
8+
runs-on: ${{ matrix.os }}
9+
10+
strategy:
11+
fail-fast: false
12+
matrix:
13+
llvm: ["7"]
14+
build: ["Release", "Debug"] # "RelWithDebInfo"
15+
os: [ubuntu-18.04]
16+
17+
steps:
18+
- name: add llvm
19+
run: sudo apt-get install -y llvm-${{ matrix.llvm }}-dev llvm-${{ matrix.llvm }}-tools clang-${{ matrix.llvm }}
20+
- uses: actions/checkout@v1
21+
with:
22+
fetch-depth: 1
23+
- name: mkdir
24+
run: cd enzyme && mkdir build
25+
- name: cmake
26+
run: |
27+
cd enzyme/build
28+
cmake .. -DLLVM_EXTERNAL_LIT=/usr/lib/llvm-${{ matrix.llvm }}/build/utils/lit/lit.py -DCMAKE_BUILD_TYPE=${{ matrix.build }} -DLLVM_DIR=/usr/lib/llvm-${{ matrix.llvm }}/lib/cmake/llvm
29+
- name: make
30+
run: cd enzyme/build && make
31+
- name: make check-enzyme-c
32+
run: cd enzyme/build && make check-enzyme-c

enzyme/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@ message("found llvm version " ${LLVM_VERSION_MAJOR})
4848

4949
add_subdirectory(Enzyme)
5050
add_subdirectory(test)
51+
add_subdirectory(functional_tests_c)

enzyme/functional_tests_c/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/*
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
configure_lit_site_cfg(
2+
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
3+
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
4+
MAIN_CONFIG
5+
${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
6+
)
7+
8+
set(ENZYME_TEST_DEPS LLVMEnzyme-${LLVM_VERSION_MAJOR})
9+
10+
set(ENZYME_TESTSUITES)
11+
list(APPEND ${CMAKE_CURRENT_BINARY_DIR}/lit.cfg)
12+
13+
# Run regression and unit tests
14+
add_lit_testsuite(check-enzyme-c "Running enzyme regression tests"
15+
${CMAKE_CURRENT_BINARY_DIR}
16+
DEPENDS ${ENZYME_TEST_DEPS}
17+
ARGS -v
18+
)
19+
20+
set_target_properties(check-enzyme-c PROPERTIES FOLDER "Tests")
21+
22+
#add_lit_testsuites(ENZYME ${CMAKE_CURRENT_SOURCE_DIR}
23+
# DEPENDS ${ENZYME_TEST_DEPS}
24+
#)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <math.h>
4+
#include <assert.h>
5+
6+
#define __builtin_autodiff __enzyme_autodiff
7+
double __enzyme_autodiff(void*, ...);
8+
//float man_max(float* a, float* b) {
9+
// if (*a > *b) {
10+
// return *a;
11+
// } else {
12+
// return *b;
13+
// }
14+
//}
15+
16+
17+
// size of array
18+
float* unsorted_array_init(int N) {
19+
float* arr = (float*) malloc(sizeof(float) * N);
20+
for (int i = 0; i < N; i++) {
21+
arr[i] = 1.0*(i%2);
22+
}
23+
return arr;
24+
}
25+
26+
__attribute__((noinline))
27+
void insertion_sort_inner(float* array, int i) {
28+
int j = i;
29+
while (j > 0 && array[j-1] > array[j]) {
30+
float tmp = array[j];
31+
array[j] = array[j-1];
32+
array[j-1] = tmp;
33+
j -= 1;
34+
}
35+
}
36+
37+
// sums the first half of a sorted array.
38+
void insertsort_sum (float* array, int N, float* ret) {
39+
float sum = 0;
40+
//qsort(array, N, sizeof(float), cmp);
41+
42+
for (int i = 1; i < N; i++) {
43+
insertion_sort_inner(array, i);
44+
}
45+
46+
47+
for (int i = 0; i < N/2; i++) {
48+
//printf("Val: %f\n", array[i]);
49+
sum += array[i];
50+
}
51+
*ret = sum;
52+
}
53+
54+
55+
56+
57+
int main(int argc, char** argv) {
58+
59+
60+
61+
float a = 2.0;
62+
float b = 3.0;
63+
64+
65+
66+
float da = 0;//(float*) malloc(sizeof(float));
67+
float db = 0;//(float*) malloc(sizeof(float));
68+
69+
70+
float ret = 0;
71+
float dret = 1.0;
72+
73+
int N = 10;
74+
int dN = 0;
75+
float* array = unsorted_array_init(N);
76+
float* d_array = (float*) malloc(sizeof(float)*N);
77+
for (int i = 0; i < N; i++) {
78+
d_array[i] = 0.0;
79+
}
80+
81+
printf("The total sum is %f\n", ret);
82+
83+
__builtin_autodiff(insertsort_sum, array, d_array, N, &ret, &dret);
84+
85+
for (int i = 0; i < N; i++) {
86+
printf("Diffe for index %d is %f\n", i, d_array[i]);
87+
if (i%2 == 0) {
88+
assert(d_array[i] == 0.0);
89+
} else {
90+
assert(d_array[i] == 1.0);
91+
}
92+
}
93+
94+
//assert(da == 100*1.0f);
95+
//assert(db == 100*1.0f);
96+
97+
//printf("hello! %f, res2 %f, da: %f, db: %f\n", ret, ret, da,db);
98+
return 0;
99+
}

enzyme/functional_tests_c/Makefile

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
2+
.PHONY: all clean
3+
4+
OBJ := $(wildcard *.c)
5+
6+
#ENZYME_PLUGIN := ./../build/Enzyme/LLVMEnzyme-7.so
7+
#export PATH = "$(PATH):$(LLVM_DIR)"
8+
9+
#ifeq ($(CLANG_BIN_PATH),)
10+
#CLANG_BIN_PATH=${CLANG_BIN_PATH}
11+
#endif
12+
#
13+
#ifeq ($(ENZYME_PLUGIN),)
14+
#ENZYME_PLUGIN=${ENZYME_PLUGIN}
15+
#endif
16+
17+
#CLANG_BIN_PATH :=
18+
19+
all: $(patsubst %.c,build/%-enzyme0,$(OBJ)) $(patsubst %.c,build/%-enzyme1,$(OBJ)) $(patsubst %.c,build/%-enzyme2,$(OBJ)) $(patsubst %.c,build/%-enzyme3,$(OBJ))
20+
21+
POST_ENZYME_FLAGS := -mem2reg -sroa -adce -simplifycfg
22+
23+
#all: $(patsubst %.c,build/%-enzyme1,$(OBJ)) $(patsubst %.c,build/%-enzyme2,$(OBJ)) $(patsubst %.c,build/%-enzyme3,$(OBJ))
24+
#clean:
25+
# rm -f main main-* main.ll
26+
# rm -f compilercrash compilercrash-* compilercrash.ll
27+
# rm -f segfault segfault-* segfault.ll
28+
# rm -f silent_failure silent_failure-* silent_failure.ll
29+
30+
#ENZYME_PLUGIN = $(ENZYME_PLUGIN)
31+
32+
#EXTRA_FLAGS = -indvars -loop-simplify -loop-rotate
33+
34+
# NOTE(TFK): Optimization level 0 is broken right now.
35+
build/%-enzyme0: %.c
36+
@./setup.sh $(CLANG_BIN_PATH)/clang -std=c11 -O1 $(patsubst %.c,%,$<).c -S -emit-llvm -o $@.ll
37+
@./setup.sh $(CLANG_BIN_PATH)/opt $@.ll $(EXTRA_FLAGS) -load=$(ENZYME_PLUGIN) -enzyme -o $@.bc
38+
@./setup.sh $(CLANG_BIN_PATH)/clang -std=c11 $@.bc -S -emit-llvm -o $@-final.ll
39+
@./setup.sh $(CLANG_BIN_PATH)/clang -std=c11 $@.bc -o $@
40+
41+
build/%-enzyme1: %.c
42+
@./setup.sh $(CLANG_BIN_PATH)/clang -std=c11 -O1 $(patsubst %.c,%,$<).c -S -emit-llvm -o $@.ll
43+
@./setup.sh $(CLANG_BIN_PATH)/opt $@.ll $(EXTRA_FLAGS) -load=$(ENZYME_PLUGIN) -enzyme -o $@.bc
44+
@./setup.sh $(CLANG_BIN_PATH)/clang -std=c11 $@.bc -S -emit-llvm -o $@-final.ll
45+
@./setup.sh $(CLANG_BIN_PATH)/clang -std=c11 $@.bc -o $@
46+
47+
build/%-enzyme2: %.c
48+
@./setup.sh $(CLANG_BIN_PATH)/clang -std=c11 -O2 $(patsubst %.c,%,$<).c -S -emit-llvm -o $@.ll
49+
@./setup.sh $(CLANG_BIN_PATH)/opt $@.ll $(EXTRA_FLAGS) -load=$(ENZYME_PLUGIN) -enzyme -o $@.bc
50+
@./setup.sh $(CLANG_BIN_PATH)/clang -std=c11 $@.bc -S -emit-llvm -o $@-final.ll
51+
@./setup.sh $(CLANG_BIN_PATH)/clang -std=c11 $@.bc -o $@
52+
53+
build/%-enzyme3: %.c
54+
@./setup.sh $(CLANG_BIN_PATH)/clang -std=c11 -O3 $(patsubst %.c,%,$<).c -S -emit-llvm -o $@.ll
55+
@./setup.sh $(CLANG_BIN_PATH)/opt $@.ll $(EXTRA_FLAGS) -load=$(ENZYME_PLUGIN) -enzyme $(POST_ENZYME_FLAGS) -o $@.bc
56+
@./setup.sh $(CLANG_BIN_PATH)/clang -std=c11 $@.bc -S -emit-llvm -o $@-final.ll
57+
@./setup.sh $(CLANG_BIN_PATH)/clang -std=c11 $@.bc -o $@
58+
59+
60+
%-enzyme-test0: build/%-enzyme0
61+
@./$< 2> /dev/null 1> /dev/null && echo "success" || echo "FAILURE"
62+
63+
%-enzyme-test1: build/%-enzyme1
64+
@./$< 2> /dev/null 1> /dev/null && echo "success" || echo "FAILURE"
65+
66+
%-enzyme-test2: build/%-enzyme2
67+
@./$< 2> /dev/null 1> /dev/null && echo "success" || echo "FAILURE"
68+
69+
%-enzyme-test3: build/%-enzyme3
70+
@./$< 2> /dev/null 1> /dev/null && echo "success" || echo "FAILURE"
71+
72+
test: $(patsubst %.c,%-enzyme-test0,$(OBJ)) $(patsubst %.c,%-enzyme-test1,$(OBJ)) $(patsubst %.c,%-enzyme-test2,$(OBJ)) $(patsubst %.c,%-enzyme-test3,$(OBJ))
73+
#test: $(patsubst %.c,%-enzyme-test1,$(OBJ)) $(patsubst %.c,%-enzyme-test2,$(OBJ)) $(patsubst %.c,%-enzyme-test3,$(OBJ))
74+
75+
generate-testfiles:
76+
rm testfiles/*
77+
python gentests.py $(patsubst %.c,%-enzyme0,$(OBJ))
78+
python gentests.py $(patsubst %.c,%-enzyme1,$(OBJ))
79+
python gentests.py $(patsubst %.c,%-enzyme2,$(OBJ))
80+
python gentests.py $(patsubst %.c,%-enzyme3,$(OBJ))
81+
82+
clean-%:
83+
rm -f build/%*
84+
85+
clean:
86+
rm -f build/*
87+
88+

enzyme/functional_tests_c/gentests.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import sys
2+
3+
for i in range(1,len(sys.argv)):
4+
content = open('test.template').read()
5+
content = content.replace("@NAME@", sys.argv[i])
6+
if sys.argv[i].startswith('FAIL_'):
7+
content = content.replace("@EXPECTFAIL@", "; XFAIL: *")
8+
else:
9+
content = content.replace("@EXPECTFAIL@", "")
10+
open('./testfiles/'+sys.argv[i]+".test", 'w+').write(content)
+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <math.h>
4+
#include <assert.h>
5+
6+
#define __builtin_autodiff __enzyme_autodiff
7+
8+
double __enzyme_autodiff(void*, ...);
9+
10+
// size of array
11+
float* unsorted_array_init(int N) {
12+
float* arr = (float*) malloc(sizeof(float) * N);
13+
for (int i = 0; i < N; i++) {
14+
arr[i] = 1.0*(i%2);
15+
}
16+
return arr;
17+
}
18+
19+
// sums the first half of a sorted array.
20+
void insertsort_sum (float* array, int N, float* ret) {
21+
float sum = 0;
22+
//qsort(array, N, sizeof(float), cmp);
23+
24+
for (int i = 1; i < N; i++) {
25+
int j = i;
26+
while (j > 0 && array[j-1] < array[j]) {
27+
float tmp = array[j];
28+
array[j] = array[j-1];
29+
array[j-1] = tmp;
30+
j -= 1;
31+
}
32+
}
33+
34+
35+
for (int i = 0; i < N/2; i++) {
36+
printf("Val: %f\n", array[i]);
37+
sum += array[i];
38+
}
39+
*ret = sum;
40+
}
41+
42+
43+
44+
45+
int main(int argc, char** argv) {
46+
47+
48+
49+
float a = 2.0;
50+
float b = 3.0;
51+
52+
53+
54+
float da = 0;
55+
float db = 0;
56+
57+
58+
float ret = 0;
59+
float dret = 1.0;
60+
61+
int N = 10;
62+
int dN = 0;
63+
float* array = unsorted_array_init(N);
64+
float* d_array = (float*) malloc(sizeof(float)*N);
65+
for (int i = 0; i < N; i++) {
66+
d_array[i] = 0.0;
67+
}
68+
69+
printf("Array before sorting:\n");
70+
for (int i = 0; i < N; i++) {
71+
printf("%d:%f\n", i, array[i]);
72+
}
73+
74+
//insertsort_sum(array, N, &ret);
75+
76+
printf("Array after sorting:\n");
77+
for (int i = 0; i < N; i++) {
78+
printf("%d:%f\n", i, array[i]);
79+
}
80+
81+
82+
printf("The total sum is %f\n", ret);
83+
84+
__builtin_autodiff(insertsort_sum, array, d_array, N, &ret, &dret);
85+
86+
for (int i = 0; i < N; i++) {
87+
printf("Diffe for index %d is %f\n", i, d_array[i]);
88+
if (i%2 == 0) {
89+
assert(d_array[i] == 0.0);
90+
} else {
91+
assert(d_array[i] == 1.0);
92+
}
93+
}
94+
95+
//__builtin_autodiff(compute_loops, &a, &da, &b, &db, &ret, &dret);
96+
97+
98+
//assert(da == 100*1.0f);
99+
//assert(db == 100*1.0f);
100+
101+
//printf("hello! %f, res2 %f, da: %f, db: %f\n", ret, ret, da,db);
102+
return 0;
103+
}

0 commit comments

Comments
 (0)