diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..eabb052 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,21 @@ +name: C/C++ CI + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y build-essential libsdl2-dev libsdl2-image-dev g++ + - name: make check + run: make check \ No newline at end of file diff --git a/Makefile b/Makefile index a767e3d..a60b9db 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ all:$(BUILD_DIR) $(BUILD_DIR): mkdir -p $(BUILD_DIR) -TESTS = $(wildcard unit_tests*.cpp) +TESTS = $(wildcard tests*.cpp) TESTS_TARGETS = $(TESTS:.cpp=) unit: $(BUILD_DIR) $(TESTS_TARGETS) @@ -18,4 +18,21 @@ unit: $(BUILD_DIR) $(TESTS_TARGETS) g++ -g -Iheaders -o $(BUILD_DIR)/$@ $< clean: - rm -rf $(BUILD_DIR) \ No newline at end of file + rm -rf $(BUILD_DIR) + +check:$(BUILD_DIR) + g++ -O3 -std=c++17 `sdl2-config --libs` -lSDL2_image -o $(BUILD_DIR)/basic_identity tests/basic_identity.cpp + ./build/basic_identity + g++ -O3 -std=c++17 -fopenmp -DNUM_THREADS=2 `sdl2-config --libs` -lSDL2_image -o $(BUILD_DIR)/basic_identity tests/basic_identity.cpp + ./build/basic_identity + g++ -O3 -std=c++17 `sdl2-config --libs` -lSDL2_image -o $(BUILD_DIR)/basic_no_restrictions tests/basic_no_restrictions.cpp + ./build/basic_no_restrictions + g++ -O3 -std=c++17 -fopenmp -DNUM_THREADS=2 `sdl2-config --libs` -lSDL2_image -o $(BUILD_DIR)/basic_no_restrictions tests/basic_no_restrictions.cpp + ./build/basic_no_restrictions +# removed from loop because it is unpredictable +# g++ -O3 -std=c++17 -fopenmp -DNUM_THREADS=2 `sdl2-config --libs` -lSDL2_image -o $(BUILD_DIR)/basic_random_adjacency tests/basic_random_adjacency.cpp +# ./build/basic_random_adjacency + g++ -O3 -std=c++17 `sdl2-config --libs` -lSDL2_image -o $(BUILD_DIR)/basic_smooth_noise tests/basic_smooth_noise.cpp + ./build/basic_smooth_noise + g++ -O3 -std=c++17 -fopenmp -DNUM_THREADS=2 `sdl2-config --libs` -lSDL2_image -o $(BUILD_DIR)/basic_smooth_noise tests/basic_smooth_noise.cpp + ./build/basic_smooth_noise \ No newline at end of file diff --git a/main.cpp b/main.cpp index 9683e05..85e0518 100644 --- a/main.cpp +++ b/main.cpp @@ -1,17 +1,13 @@ -#include #include -#include using namespace std; -#include "src/common.h" -#include "src/structures.h" #include "src/solver.h" #include "src/argument_parser.h" #include "src/timer.h" -#include "src/examples/patterns.h" #include "src/examples/pipes.h" #include "src/examples/pipes_colored.h" +#include "src/examples/patterns.h" int main( int argc, char* argv[]){ ArgumentParser parser(argc, argv); diff --git a/src/common.h b/src/common.h index f2cb6c7..63f256b 100644 --- a/src/common.h +++ b/src/common.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include using namespace std; @@ -12,7 +13,7 @@ class Matrix3D{ int size; type* values; public: - Matrix3D(int sx, int sy, int sz): sx(sx), sy(sy), sz(sz),size(sx*sy*sz), values(static_cast(std::aligned_alloc(64, size * sizeof(type)))) {} + Matrix3D(int sx, int sy, int sz): sx(sx), sy(sy), sz(sz),size(sx*sy*sz), values(static_cast(aligned_alloc(64, size * sizeof(type)))) {} int get_size(){return size;} int get_sx(){return sx;} diff --git a/src/solver.h b/src/solver.h index 69b4056..de4c3d1 100644 --- a/src/solver.h +++ b/src/solver.h @@ -26,7 +26,7 @@ class WFCSolver{ // Solver settings bool log_progress = false; - bool log_result = true; + bool log_result = false; bool sucessful = false; bool periodic = false; int propagation_method = 0; @@ -200,12 +200,19 @@ class WFCSolver{ int num_of_steps = 0; int progress = 0; sucessful = true; - + int last_progress = -1; // Main solver loop while(collapse_path_length < total_size && !terminate){ num_of_steps++; + if(log_progress){ + int progress = (100 * (collapse_path_length)) / total_size; + if(progress % 1 == 0 && progress != last_progress) { + last_progress = progress; + std::cout << "\rProgress: " << progress << "% (" << collapse_path_length << "/" << total_size << ")" << " setbacks: " << num_of_steps-collapse_path_length << std::flush; + } + } // try to collapse another entropy = data.least_entropy(next_x, next_y); //cout << next_x << " " << next_y << " " << entropy << " " << collapse_path_length << endl; @@ -263,6 +270,10 @@ class WFCSolver{ need_to_be_updated = data.need_to_be_updated(); } } + if(log_progress){ + std::cout << "\rProgress: " << "100% (" << collapse_path_length << "/" << total_size << ")" << " setbacks: " << num_of_steps-collapse_path_length << std::flush; + cout << "\n" << endl; + } if(log_result){ cout << collapse_path_length << endl; cout << data.total_updates << endl; diff --git a/unit_tests/basic_identity.cpp b/tests/basic_identity.cpp similarity index 64% rename from unit_tests/basic_identity.cpp rename to tests/basic_identity.cpp index 86b708d..15776b9 100644 --- a/unit_tests/basic_identity.cpp +++ b/tests/basic_identity.cpp @@ -1,13 +1,4 @@ -#include -#include -#include -#include -using namespace std; -#include "common.h" -#include "structures.h" -//#include "headers/converter.h" -#include "solver.h" -#include "visualizer.h" +#include "../src/solver.h" int main( int argc, char* argv[]){ int sx = 10, sy = 10; @@ -23,20 +14,21 @@ int main( int argc, char* argv[]){ WFCDataStructure data = WFCDataStructure(sx,sy,options,adjacency_rules); WFCSolver solver = WFCSolver(); + #ifdef _OPENMP Matrix2D result = solver.solve(data); - adjacency_matrix_x.print(); - result.print(); + #else + Matrix2D result = solver.solve_sequential(data); + #endif + //adjacency_matrix_x.print(); + //result.print(); // Unit test result check int first_value = result.get(0); for (int i = 0; i -#include -#include -#include -using namespace std; -#include "common.h" -#include "structures.h" -//#include "headers/converter.h" -#include "solver.h" -#include "visualizer.h" +#include "../src/solver.h" + int main( int argc, char* argv[]){ int sx = 10, sy = 10; @@ -29,19 +21,17 @@ int main( int argc, char* argv[]){ WFCDataStructure data = WFCDataStructure(sx,sy,options,adjacency_rules); WFCSolver solver = WFCSolver(); + #ifdef _OPENMP Matrix2D result = solver.solve(data); - //adjacency_matrix_x.print(); - //adjacency_matrix_y.print(); - //result.print(); + #else + Matrix2D result = solver.solve_sequential(data); + #endif // Unit test result check - if(solver.sucessful){ - cout << "Unit test sucessful:" << endl; - }else{ - cout << "Unit test unsucessful:" << endl; + if(!solver.sucessful){ + return 1; } - return 0; } diff --git a/unit_tests/basic_random_adjacency.cpp b/tests/basic_random_adjacency.cpp similarity index 72% rename from unit_tests/basic_random_adjacency.cpp rename to tests/basic_random_adjacency.cpp index 55a23bd..5d57c77 100644 --- a/unit_tests/basic_random_adjacency.cpp +++ b/tests/basic_random_adjacency.cpp @@ -1,13 +1,4 @@ -#include -#include -#include -#include -using namespace std; -#include "common.h" -#include "structures.h" -//#include "headers/converter.h" -#include "solver.h" -#include "visualizer.h" +#include "../src/solver.h" int main( int argc, char* argv[]){ int sx = 10, sy = 10; @@ -34,13 +25,12 @@ int main( int argc, char* argv[]){ WFCDataStructure data = WFCDataStructure(sx,sy,options,adjacency_rules); WFCSolver solver = WFCSolver(); + #ifdef _OPENMP Matrix2D result = solver.solve(data); - adjacency_matrix_x.print(); - adjacency_matrix_y.print(); - result.print(); - - cout << "^ check unit test result manually" << endl; - + #else + Matrix2D result = solver.solve_sequential(data); + #endif + // Random adjacency => code is correct if this finishes return 0; } diff --git a/unit_tests/basic_smooth_noise.cpp b/tests/basic_smooth_noise.cpp similarity index 54% rename from unit_tests/basic_smooth_noise.cpp rename to tests/basic_smooth_noise.cpp index cf6913f..32e2724 100644 --- a/unit_tests/basic_smooth_noise.cpp +++ b/tests/basic_smooth_noise.cpp @@ -1,13 +1,4 @@ -#include -#include -#include -#include -using namespace std; -#include "common.h" -#include "structures.h" -//#include "headers/converter.h" -#include "solver.h" -#include "visualizer.h" +#include "../src/solver.h" int main( int argc, char* argv[]){ int sx = 10, sy = 10; @@ -29,27 +20,24 @@ int main( int argc, char* argv[]){ WFCDataStructure data = WFCDataStructure(sx,sy,options,adjacency_rules); WFCSolver solver = WFCSolver(); + #ifdef _OPENMP Matrix2D result = solver.solve(data); - adjacency_matrix_x.print(); - result.print(); + #else + Matrix2D result = solver.solve_sequential(data); + #endif // Unit test result check // all differences must be exactly one for (int x = 0; x < sx - 1; x++) { - for (int y = 0; y < sy - 1; y++) { - if(abs(result.get(x,y) - result.get(x+1,y)) != 1){ - cout << "Unit test unsucessful:" << endl; - cout << "difference too big on " << x << " " << y << endl; - break; + for (int y = 0; y < sy - 1; y++) { + if(abs(result.get(x,y) - result.get(x+1,y)) != 1){ + return 1; + } + if(abs(result.get(x,y) - result.get(x,y+1)) != 1){ + return 1; + } } - if(abs(result.get(x,y) - result.get(x,y+1)) != 1){ - cout << "Unit test unsucessful:" << endl; - cout << "difference too big on " << x << " " << y << endl; - break; - } - } } - cout << "Unit test sucessful" << endl; return 0; }