From 34647d23b1eebc3ea04b80eb1f7cb5450dbfb192 Mon Sep 17 00:00:00 2001 From: MarekOnd Date: Tue, 16 Sep 2025 14:22:18 +0200 Subject: [PATCH 1/6] updated unit test --- {unit_tests => tests}/basic_identity.cpp | 13 +++---- .../basic_no_restrictions.cpp | 21 ++++------- .../basic_random_adjacency.cpp | 20 +++-------- {unit_tests => tests}/basic_smooth_noise.cpp | 35 ++++++------------- 4 files changed, 27 insertions(+), 62 deletions(-) rename {unit_tests => tests}/basic_identity.cpp (72%) rename {unit_tests => tests}/basic_no_restrictions.cpp (68%) rename {unit_tests => tests}/basic_random_adjacency.cpp (71%) rename {unit_tests => tests}/basic_smooth_noise.cpp (52%) diff --git a/unit_tests/basic_identity.cpp b/tests/basic_identity.cpp similarity index 72% rename from unit_tests/basic_identity.cpp rename to tests/basic_identity.cpp index 86b708d..182208f 100644 --- a/unit_tests/basic_identity.cpp +++ b/tests/basic_identity.cpp @@ -3,11 +3,9 @@ #include #include using namespace std; -#include "common.h" -#include "structures.h" -//#include "headers/converter.h" -#include "solver.h" -#include "visualizer.h" +#include "../src/common.h" +#include "../src/structures.h" +#include "../src/solver.h" int main( int argc, char* argv[]){ int sx = 10, sy = 10; @@ -23,7 +21,7 @@ int main( int argc, char* argv[]){ WFCDataStructure data = WFCDataStructure(sx,sy,options,adjacency_rules); WFCSolver solver = WFCSolver(); - Matrix2D result = solver.solve(data); + Matrix2D result = solver.solve_sequential(data); adjacency_matrix_x.print(); result.print(); @@ -31,12 +29,9 @@ int main( int argc, char* argv[]){ int first_value = result.get(0); for (int i = 0; i #include using namespace std; -#include "common.h" -#include "structures.h" -//#include "headers/converter.h" -#include "solver.h" -#include "visualizer.h" +#include "../src/common.h" +#include "../src/structures.h" +#include "../src/solver.h" + int main( int argc, char* argv[]){ int sx = 10, sy = 10; @@ -29,19 +28,13 @@ int main( int argc, char* argv[]){ WFCDataStructure data = WFCDataStructure(sx,sy,options,adjacency_rules); WFCSolver solver = WFCSolver(); - Matrix2D result = solver.solve(data); - //adjacency_matrix_x.print(); - //adjacency_matrix_y.print(); - //result.print(); + Matrix2D result = solver.solve_sequential(data); // 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 71% rename from unit_tests/basic_random_adjacency.cpp rename to tests/basic_random_adjacency.cpp index 55a23bd..e38369b 100644 --- a/unit_tests/basic_random_adjacency.cpp +++ b/tests/basic_random_adjacency.cpp @@ -1,13 +1,8 @@ -#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/common.h" +#include "../src/structures.h" +#include "../src/solver.h" int main( int argc, char* argv[]){ int sx = 10, sy = 10; @@ -34,13 +29,8 @@ int main( int argc, char* argv[]){ WFCDataStructure data = WFCDataStructure(sx,sy,options,adjacency_rules); WFCSolver solver = WFCSolver(); - Matrix2D result = solver.solve(data); - adjacency_matrix_x.print(); - adjacency_matrix_y.print(); - result.print(); - - cout << "^ check unit test result manually" << endl; - + Matrix2D result = solver.solve_sequential(data); + // 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 52% rename from unit_tests/basic_smooth_noise.cpp rename to tests/basic_smooth_noise.cpp index cf6913f..abd645b 100644 --- a/unit_tests/basic_smooth_noise.cpp +++ b/tests/basic_smooth_noise.cpp @@ -1,13 +1,7 @@ -#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/common.h" +#include "../src/structures.h" +#include "../src/solver.h" int main( int argc, char* argv[]){ int sx = 10, sy = 10; @@ -29,27 +23,20 @@ int main( int argc, char* argv[]){ WFCDataStructure data = WFCDataStructure(sx,sy,options,adjacency_rules); WFCSolver solver = WFCSolver(); - Matrix2D result = solver.solve(data); - adjacency_matrix_x.print(); - result.print(); + Matrix2D result = solver.solve_sequential(data); // 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; } From 51b40f2ce8fc9ec1808fb98ec86254b24c4e7d85 Mon Sep 17 00:00:00 2001 From: MarekOnd Date: Tue, 16 Sep 2025 14:47:19 +0200 Subject: [PATCH 2/6] updated solver output to work with tests --- src/solver.h | 15 +++++++++++++-- tests/basic_identity.cpp | 4 ++-- 2 files changed, 15 insertions(+), 4 deletions(-) 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/tests/basic_identity.cpp b/tests/basic_identity.cpp index 182208f..d8b8548 100644 --- a/tests/basic_identity.cpp +++ b/tests/basic_identity.cpp @@ -22,8 +22,8 @@ int main( int argc, char* argv[]){ WFCDataStructure data = WFCDataStructure(sx,sy,options,adjacency_rules); WFCSolver solver = WFCSolver(); Matrix2D result = solver.solve_sequential(data); - adjacency_matrix_x.print(); - result.print(); + //adjacency_matrix_x.print(); + //result.print(); // Unit test result check int first_value = result.get(0); From 8add65ade065a5f3f04ecb608d0fdaf848cc7eb9 Mon Sep 17 00:00:00 2001 From: MarekOnd Date: Tue, 16 Sep 2025 15:03:15 +0200 Subject: [PATCH 3/6] simplified included headers and libraries --- main.cpp | 6 +----- src/common.h | 3 ++- tests/basic_identity.cpp | 7 ------- tests/basic_no_restrictions.cpp | 7 ------- tests/basic_random_adjacency.cpp | 4 ---- tests/basic_smooth_noise.cpp | 3 --- 6 files changed, 3 insertions(+), 27 deletions(-) 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/tests/basic_identity.cpp b/tests/basic_identity.cpp index d8b8548..7cd3c69 100644 --- a/tests/basic_identity.cpp +++ b/tests/basic_identity.cpp @@ -1,10 +1,3 @@ -#include -#include -#include -#include -using namespace std; -#include "../src/common.h" -#include "../src/structures.h" #include "../src/solver.h" int main( int argc, char* argv[]){ diff --git a/tests/basic_no_restrictions.cpp b/tests/basic_no_restrictions.cpp index 3d49055..0b8d881 100644 --- a/tests/basic_no_restrictions.cpp +++ b/tests/basic_no_restrictions.cpp @@ -1,10 +1,3 @@ -#include -#include -#include -#include -using namespace std; -#include "../src/common.h" -#include "../src/structures.h" #include "../src/solver.h" diff --git a/tests/basic_random_adjacency.cpp b/tests/basic_random_adjacency.cpp index e38369b..a372e3f 100644 --- a/tests/basic_random_adjacency.cpp +++ b/tests/basic_random_adjacency.cpp @@ -1,7 +1,3 @@ -#include -using namespace std; -#include "../src/common.h" -#include "../src/structures.h" #include "../src/solver.h" int main( int argc, char* argv[]){ diff --git a/tests/basic_smooth_noise.cpp b/tests/basic_smooth_noise.cpp index abd645b..04a2d5d 100644 --- a/tests/basic_smooth_noise.cpp +++ b/tests/basic_smooth_noise.cpp @@ -1,6 +1,3 @@ -using namespace std; -#include "../src/common.h" -#include "../src/structures.h" #include "../src/solver.h" int main( int argc, char* argv[]){ From f6965fa42b37dc5dd49684fa536870f3c3551be3 Mon Sep 17 00:00:00 2001 From: MarekOnd Date: Tue, 16 Sep 2025 15:04:14 +0200 Subject: [PATCH 4/6] added github workflow for tests --- .github/workflows/tests.yml | 20 ++++++++++++++++++++ Makefile | 16 ++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..74010ae --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,20 @@ +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 + 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..2bf2577 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,16 @@ 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 `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_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_random_adjacency tests/basic_random_adjacency.cpp + ./build/basic_random_adjacency + 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 From a111ec1a3c8bea91b58dde06fef3a4006a12e231 Mon Sep 17 00:00:00 2001 From: MarekOnd Date: Tue, 16 Sep 2025 15:09:41 +0200 Subject: [PATCH 5/6] fixed install dependencies --- .github/workflows/tests.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 74010ae..eabb052 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,8 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install dependencies - run: sudo apt-get update - apt-get install -y build-essential libsdl2-dev libsdl2-image-dev g++ + 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 From a3e5a3c4f8c29ad5fccaa77e41781a32c3c52f25 Mon Sep 17 00:00:00 2001 From: MarekOnd Date: Tue, 16 Sep 2025 15:19:17 +0200 Subject: [PATCH 6/6] added CI test with and without OpenMP, removed random adjacency test --- Makefile | 11 ++++++++--- tests/basic_identity.cpp | 4 ++++ tests/basic_no_restrictions.cpp | 4 ++++ tests/basic_random_adjacency.cpp | 4 ++++ tests/basic_smooth_noise.cpp | 4 ++++ 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 2bf2577..a60b9db 100644 --- a/Makefile +++ b/Makefile @@ -23,11 +23,16 @@ clean: 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 `sdl2-config --libs` -lSDL2_image -o $(BUILD_DIR)/basic_identity tests/basic_identity.cpp + 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 - 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 +# 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/tests/basic_identity.cpp b/tests/basic_identity.cpp index 7cd3c69..15776b9 100644 --- a/tests/basic_identity.cpp +++ b/tests/basic_identity.cpp @@ -14,7 +14,11 @@ int main( int argc, char* argv[]){ WFCDataStructure data = WFCDataStructure(sx,sy,options,adjacency_rules); WFCSolver solver = WFCSolver(); + #ifdef _OPENMP + Matrix2D result = solver.solve(data); + #else Matrix2D result = solver.solve_sequential(data); + #endif //adjacency_matrix_x.print(); //result.print(); diff --git a/tests/basic_no_restrictions.cpp b/tests/basic_no_restrictions.cpp index 0b8d881..b2729dd 100644 --- a/tests/basic_no_restrictions.cpp +++ b/tests/basic_no_restrictions.cpp @@ -21,7 +21,11 @@ int main( int argc, char* argv[]){ WFCDataStructure data = WFCDataStructure(sx,sy,options,adjacency_rules); WFCSolver solver = WFCSolver(); + #ifdef _OPENMP + Matrix2D result = solver.solve(data); + #else Matrix2D result = solver.solve_sequential(data); + #endif // Unit test result check diff --git a/tests/basic_random_adjacency.cpp b/tests/basic_random_adjacency.cpp index a372e3f..5d57c77 100644 --- a/tests/basic_random_adjacency.cpp +++ b/tests/basic_random_adjacency.cpp @@ -25,7 +25,11 @@ int main( int argc, char* argv[]){ WFCDataStructure data = WFCDataStructure(sx,sy,options,adjacency_rules); WFCSolver solver = WFCSolver(); + #ifdef _OPENMP + Matrix2D result = solver.solve(data); + #else Matrix2D result = solver.solve_sequential(data); + #endif // Random adjacency => code is correct if this finishes return 0; } diff --git a/tests/basic_smooth_noise.cpp b/tests/basic_smooth_noise.cpp index 04a2d5d..32e2724 100644 --- a/tests/basic_smooth_noise.cpp +++ b/tests/basic_smooth_noise.cpp @@ -20,7 +20,11 @@ int main( int argc, char* argv[]){ WFCDataStructure data = WFCDataStructure(sx,sy,options,adjacency_rules); WFCSolver solver = WFCSolver(); + #ifdef _OPENMP + Matrix2D result = solver.solve(data); + #else Matrix2D result = solver.solve_sequential(data); + #endif // Unit test result check // all differences must be exactly one