diff --git a/CMakeLists.txt b/CMakeLists.txt index e0eb752..644f159 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,13 @@ cmake_minimum_required(VERSION 3.25) -project(blt-gp VERSION 0.0.93) +project(blt-gp VERSION 0.0.94) include(CTest) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) option(ENABLE_TSAN "Enable the thread data race sanitizer" OFF) -option(BUILD_EXAMPLES "Build example programs. This is a single executable" OFF) +option(BUILD_EXAMPLES "Build example programs. This will build with CTest" OFF) +option(BUILD_GP_TESTS "Build test programs." OFF) option(DEBUG_LEVEL "Enable debug features which prints extra information to the console, might slow processing down. [0, 3)" 0) set(CMAKE_CXX_STANDARD 17) @@ -46,46 +47,59 @@ if (${ENABLE_TSAN} MATCHES ON) target_link_options(blt-gp PRIVATE -fsanitize=thread) endif () +macro(blt_add_project name source type) + + project(${name}-${type}) + + add_executable(${name}-${type} ${source}) + + target_link_libraries(${name}-${type} PRIVATE BLT blt-gp Threads::Threads) + + target_compile_options(${name}-${type} PRIVATE -Wall -Wextra -Wpedantic -Wno-comment) + target_link_options(${name}-${type} PRIVATE -Wall -Wextra -Wpedantic -Wno-comment) + target_compile_definitions(${name}-${type} PRIVATE BLT_DEBUG_LEVEL=${DEBUG_LEVEL}) + + if (${ENABLE_ADDRSAN} MATCHES ON) + target_compile_options(${name}-${type} PRIVATE -fsanitize=address) + target_link_options(${name}-${type} PRIVATE -fsanitize=address) + endif () + + if (${ENABLE_UBSAN} MATCHES ON) + target_compile_options(${name}-${type} PRIVATE -fsanitize=undefined) + target_link_options(${name}-${type} PRIVATE -fsanitize=undefined) + endif () + + if (${ENABLE_TSAN} MATCHES ON) + target_compile_options(${name}-${type} PRIVATE -fsanitize=thread) + target_link_options(${name}-${type} PRIVATE -fsanitize=thread) + endif () + + add_test(NAME ${name} COMMAND ${name}-${type}) + +# set (passRegex "Pass" "Passed" "PASS" "PASSED") + set (failRegex "WARN" "FAIL" "ERROR" "FATAL") + +# set_property (TEST ${name} PROPERTY PASS_REGULAR_EXPRESSION "${passRegex}") + set_property (TEST ${name} PROPERTY FAIL_REGULAR_EXPRESSION "${failRegex}") + + project(blt-gp) +endmacro() + if (${BUILD_EXAMPLES}) - macro(blt_add_example name source) - project(${name}-example) + blt_add_project(blt-SR-playground examples/symbolic_regression.cpp example) - add_executable(${name}-example ${source}) +endif () - target_link_libraries(${name}-example PRIVATE BLT blt-gp Threads::Threads) +if (${BUILD_GP_TESTS}) - target_compile_options(${name}-example PRIVATE -Wall -Wextra -Wpedantic -Wno-comment) - target_link_options(${name}-example PRIVATE -Wall -Wextra -Wpedantic -Wno-comment) - target_compile_definitions(${name}-example PRIVATE BLT_DEBUG_LEVEL=${DEBUG_LEVEL}) - - if (${ENABLE_ADDRSAN} MATCHES ON) - target_compile_options(${name}-example PRIVATE -fsanitize=address) - target_link_options(${name}-example PRIVATE -fsanitize=address) - endif () - - if (${ENABLE_UBSAN} MATCHES ON) - target_compile_options(${name}-example PRIVATE -fsanitize=undefined) - target_link_options(${name}-example PRIVATE -fsanitize=undefined) - endif () - - if (${ENABLE_TSAN} MATCHES ON) - target_compile_options(${name}-example PRIVATE -fsanitize=thread) - target_link_options(${name}-example PRIVATE -fsanitize=thread) - endif () - - add_test(NAME ${name} COMMAND ${name}-example) - - project(blt-gp) - endmacro() - - blt_add_example(blt-gp1 examples/gp_test_1.cpp) - blt_add_example(blt-gp2 examples/gp_test_2.cpp) - blt_add_example(blt-gp3 examples/gp_test_3.cpp) - blt_add_example(blt-gp4 examples/gp_test_4.cpp) - blt_add_example(blt-gp5 examples/gp_test_5.cpp) - blt_add_example(blt-gp6 examples/gp_test_6.cpp) - blt_add_example(blt-gp7 examples/gp_test_7.cpp) - blt_add_example(blt-SR-playground examples/pg_symbolic_regression.cpp) + blt_add_project(blt-stack tests/stack_tests.cpp test) + blt_add_project(blt-gp1 tests/gp_test_1.cpp test) + blt_add_project(blt-gp2 tests/gp_test_2.cpp test) + blt_add_project(blt-gp3 tests/gp_test_3.cpp test) + blt_add_project(blt-gp4 tests/gp_test_4.cpp test) + blt_add_project(blt-gp5 tests/gp_test_5.cpp test) + blt_add_project(blt-gp6 tests/gp_test_6.cpp test) + blt_add_project(blt-gp7 tests/gp_test_7.cpp test) endif () \ No newline at end of file diff --git a/examples/pg_symbolic_regression.cpp b/examples/symbolic_regression.cpp similarity index 100% rename from examples/pg_symbolic_regression.cpp rename to examples/symbolic_regression.cpp diff --git a/include/blt/gp/stack.h b/include/blt/gp/stack.h index aa00351..2129f9d 100644 --- a/include/blt/gp/stack.h +++ b/include/blt/gp/stack.h @@ -34,109 +34,6 @@ namespace blt::gp { - class huge_allocator - { - public: - constexpr static blt::size_t HUGE_PAGE_SIZE = BLT_2MB_SIZE; - static_assert(((HUGE_PAGE_SIZE & (HUGE_PAGE_SIZE - 1)) == 0) && "Must be a power of two!"); - - void* allocate(blt::size_t bytes) - { - std::scoped_lock lock(mutex); - if (bytes > HUGE_PAGE_SIZE) - throw std::runtime_error("Unable to allocate more than 2mb of space at a time!"); - if (head == nullptr || head.load()->remaining_bytes() < bytes) - push_block(); - auto ptr = head.load()->metadata.offset; - head.load()->metadata.offset += bytes; - head.load()->metadata.allocated_objects++; - return ptr; - } - - void deallocate(void* ptr) - { - std::scoped_lock lock(mutex); - auto block = to_block(ptr); - block->metadata.allocated_objects--; - if (block->metadata.allocated_objects == 0) - delete_block(block); - } - - private: - struct block - { - struct block_metadata_t - { - blt::ptrdiff_t allocated_objects = 0; - block* next = nullptr; - block* prev = nullptr; - blt::u8* offset = nullptr; - } metadata; - blt::u8 buffer[HUGE_PAGE_SIZE - sizeof(block_metadata_t)]{}; - - block() - { - metadata.offset = buffer; - } - - void reset() - { - metadata.allocated_objects = 0; - metadata.offset = buffer; - metadata.next = nullptr; - metadata.prev = nullptr; - } - - blt::size_t remaining_bytes() - { - static constexpr blt::size_t BLOCK_REMAINDER = HUGE_PAGE_SIZE - sizeof(block_metadata_t); - return BLOCK_REMAINDER - static_cast(metadata.offset - buffer); - } - }; - - template - static inline block* to_block(T* p) - { - return reinterpret_cast(reinterpret_cast(p) & static_cast(~(HUGE_PAGE_SIZE - 1))); - } - - void delete_block(block* b) - { - if (b->metadata.prev != nullptr) - b->metadata.prev->metadata.next = b->metadata.next; - deallocated_blocks.push_back(b); - } - - void push_block() - { - block* block; - if (deallocated_blocks.empty()) - block = allocate_block(); - else - { - block = deallocated_blocks.back(); - deallocated_blocks.pop_back(); - block->reset(); - } - block->metadata.prev = head; - if (head != nullptr) - head.load()->metadata.next = block; - head = block; - } - - static block* allocate_block() - { - auto* buffer = reinterpret_cast(std::aligned_alloc(HUGE_PAGE_SIZE, HUGE_PAGE_SIZE)); - new(buffer) block{}; - return buffer; - } - - std::atomic head = nullptr; - std::mutex mutex; - std::vector deallocated_blocks; - }; - - huge_allocator& get_allocator(); class stack_allocator { diff --git a/lib/blt b/lib/blt index cd5c98d..27d1b94 160000 --- a/lib/blt +++ b/lib/blt @@ -1 +1 @@ -Subproject commit cd5c98d748be0ceb7011fd0aaf0eec8140d97cc6 +Subproject commit 27d1b94493eb80982a4a46f80dae30cbea7e14bc diff --git a/src/program.cpp b/src/program.cpp index 3e679b7..c8eb40c 100644 --- a/src/program.cpp +++ b/src/program.cpp @@ -78,10 +78,4 @@ namespace blt::gp })); } } - - huge_allocator& get_allocator() - { - static huge_allocator alloc; - return alloc; - } } \ No newline at end of file diff --git a/src/transformers.cpp b/src/transformers.cpp index 19c9a13..7306496 100644 --- a/src/transformers.cpp +++ b/src/transformers.cpp @@ -164,15 +164,8 @@ namespace blt::gp auto end_p = ops.begin() + find_endpoint(program, ops, point); stack_allocator after_stack; - - for (auto it = ops.end() - 1; it != end_p - 1; it--) - { - if (it->is_value) - { - vals.transfer_bytes(after_stack, it->type_size); - //after_ops.push_back(*it); - } - } + + transfer_backward(vals, after_stack, ops.end() - 1, end_p - 1); for (auto it = end_p - 1; it != begin_p - 1; it--) { @@ -191,20 +184,12 @@ namespace blt::gp ops.insert(++before, new_ops.begin(), new_ops.end()); - for (auto it = new_ops.end() - 1; it != new_ops.begin() - 1; it--) - { - if (it->is_value) - new_vals.transfer_bytes(vals, it->type_size); - } + transfer_backward(new_vals, vals, new_ops.end() - 1, new_ops.begin() - 1); auto new_end_point = point + new_ops.size(); auto new_end_p = ops.begin() + static_cast(new_end_point); - for (auto it = new_end_p; it != ops.end(); it++) - { - if (it->is_value) - after_stack.transfer_bytes(vals, it->type_size); - } + transfer_forward(after_stack, vals, new_end_p, ops.end()); return c; } diff --git a/examples/gp_test_1.cpp b/tests/gp_test_1.cpp similarity index 100% rename from examples/gp_test_1.cpp rename to tests/gp_test_1.cpp diff --git a/examples/gp_test_2.cpp b/tests/gp_test_2.cpp similarity index 100% rename from examples/gp_test_2.cpp rename to tests/gp_test_2.cpp diff --git a/examples/gp_test_3.cpp b/tests/gp_test_3.cpp similarity index 100% rename from examples/gp_test_3.cpp rename to tests/gp_test_3.cpp diff --git a/examples/gp_test_4.cpp b/tests/gp_test_4.cpp similarity index 100% rename from examples/gp_test_4.cpp rename to tests/gp_test_4.cpp diff --git a/examples/gp_test_5.cpp b/tests/gp_test_5.cpp similarity index 98% rename from examples/gp_test_5.cpp rename to tests/gp_test_5.cpp index 9b3a691..bf9e783 100644 --- a/examples/gp_test_5.cpp +++ b/tests/gp_test_5.cpp @@ -155,10 +155,10 @@ int main() switch (results.error()) { case blt::gp::crossover_t::error_t::NO_VALID_TYPE: - BLT_ERROR("No valid type!"); + BLT_DEBUG("No valid type!"); break; case blt::gp::crossover_t::error_t::TREE_TOO_SMALL: - BLT_ERROR("Tree is too small!"); + BLT_DEBUG("Tree is too small!"); break; } errors++; diff --git a/examples/gp_test_6.cpp b/tests/gp_test_6.cpp similarity index 100% rename from examples/gp_test_6.cpp rename to tests/gp_test_6.cpp diff --git a/examples/gp_test_7.cpp b/tests/gp_test_7.cpp similarity index 100% rename from examples/gp_test_7.cpp rename to tests/gp_test_7.cpp diff --git a/tests/stack_tests.cpp b/tests/stack_tests.cpp new file mode 100644 index 0000000..bde268b --- /dev/null +++ b/tests/stack_tests.cpp @@ -0,0 +1,62 @@ +/* + * + * Copyright (C) 2024 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include + +struct large_2048 +{ + blt::u8 data[2048]; +}; + +struct large_4096 +{ + blt::u8 data[4096]; +}; + +struct large_6123 +{ + blt::u8 data[6123]; +}; + +struct large_18290 +{ + blt::u8 data[18290]; +}; + +template +T make_data(T t) +{ + for (const auto& [index, v] : blt::enumerate(t.data)) + { + v = index % 256; + } + return t; +} + +void test_basic_types() +{ + blt::gp::stack_allocator stack; + stack.push(50.0f); + stack.push(make_data(large_2048{})); +} + +int main() +{ + test_basic_types(); +} \ No newline at end of file