diff --git a/.github/workflows/linux-conda.yml b/.github/workflows/linux-conda.yml index 0e2ca8699..249aef805 100644 --- a/.github/workflows/linux-conda.yml +++ b/.github/workflows/linux-conda.yml @@ -3,7 +3,7 @@ name: Linux Conda package on: push: branches-ignore: - - "gh590" + - "ghxyz" paths: - "conanfile.py" - ".github/workflows/linux-conda.yml" diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 8e15db2e5..0ae557302 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -3,7 +3,7 @@ name: Linux CI on: push: branches-ignore: - - "gh590" + - "ghxyz" paths: - ".github/actions/**" - ".github/workflows/linux.yml" diff --git a/.github/workflows/macos-conda.yml b/.github/workflows/macos-conda.yml index 417df0553..66ab8c972 100644 --- a/.github/workflows/macos-conda.yml +++ b/.github/workflows/macos-conda.yml @@ -3,7 +3,7 @@ name: macOS Conda package on: push: branches-ignore: - - "gh590" + - "ghxyz" paths: - "conanfile.py" - ".github/workflows/macos-conda.yml" diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index df1199c35..aba1678f4 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -3,7 +3,7 @@ name: macOS CI on: push: branches-ignore: - - "gh590" + - "ghxyz" paths: - ".github/actions/**" - ".github/workflows/macos.yml" diff --git a/.github/workflows/windows-conda.yml b/.github/workflows/windows-conda.yml index cc8efc622..3e5ce6db4 100644 --- a/.github/workflows/windows-conda.yml +++ b/.github/workflows/windows-conda.yml @@ -3,7 +3,7 @@ name: Windows Conda package on: push: branches-ignore: - - "gh590" + - "ghxyz" paths: - "conanfile.py" - ".github/workflows/windows-conda.yml" diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index aa1dcdf37..d625a41bf 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -3,7 +3,7 @@ name: Windows CI on: push: branches-ignore: - - "gh590" + - "ghxyz" paths: - ".github/actions/**" - ".github/workflows/windows.yml" diff --git a/CMakeLists.txt b/CMakeLists.txt index 25cdb17dc..a443af421 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,34 @@ if(NOT WIN32 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() endif() + +get_property(LUE_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + +# if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) +# if(LUE_GENERATOR_IS_MULTI_CONFIG) +# if(NOT "Profile" IN_LIST CMAKE_CONFIGURATION_TYPES) +# LIST(APPEND CMAKE_CONFIGURATION_TYPES Profile) +# endif() +# else() +# set(LUE_ALLOWED_BUILD_TYPES Debug Release RelWithDebInfo Profile) +# set_property(CACHE CMAKE_BUILD_TYPE +# PROPERTY +# STRING "${LUE_ALLOWED_BUILD_TYPES}" +# ) +# if(NOT_CMAKE_BUILD_TYPE) +# set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE) +# elseif +# message(FATAL_ERROR "Unknown build type: ${CMAKE_BUILD_TYPE}") +# endif() +# endif() +# set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -pg") +# set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -pg") +# set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} -pg") +# set(CMAKE_STATIC_LINKER_FLAGS_PROFILE "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO}") +# set(CMAKE_MODULE_LINKER_FLAGS_PROFILE "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} -pg") +# endif() + + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/environment/cmake") find_package(Git REQUIRED) diff --git a/environment/cmake/Lue.cmake b/environment/cmake/Lue.cmake index a1c0d25f6..cedfe3051 100644 --- a/environment/cmake/Lue.cmake +++ b/environment/cmake/Lue.cmake @@ -37,8 +37,6 @@ if(LUE_BUILD_QA AND LUE_QA_WITH_TESTS) enable_testing() endif() -get_property(LUE_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if(APPLE) set(LUE_ORIGIN @loader_path) else() diff --git a/source/framework/algorithm/include/lue/framework/algorithm/definition/decreasing_order.hpp b/source/framework/algorithm/include/lue/framework/algorithm/definition/decreasing_order.hpp index 567600933..bd28ee0b8 100644 --- a/source/framework/algorithm/include/lue/framework/algorithm/definition/decreasing_order.hpp +++ b/source/framework/algorithm/include/lue/framework/algorithm/definition/decreasing_order.hpp @@ -11,6 +11,22 @@ // #include +// Record a route +// Alternative strategy: +// - Just record a route, recursively. The last one knows when the route is finished. This +// happens when the maxima collection is empty. +// - In fact any component can mark itself as ready when the maxima collection for all routes +// become empty. Components can hand out a future that will be set once the component has +// done its thing. Hand out this future at the start (component_ready). Once ready, the caller +// can obtain a route partition. + + +// TODO / NOTE / WARNING +// We *have* to do things in some other way. recording a route is the main bottleneck. Try to +// turn its logic into something more fire and forget. +// As it is now, it will not work for us. + + namespace lue { namespace detail { @@ -48,6 +64,8 @@ namespace lue { using RouteFragment = typename RoutePartition::RouteFragment; + using CellIdxs = typename RouteFragment::CellIdxs; + DecreasingOrderZone(Offset const& offset, Shape const& shape): @@ -194,12 +212,15 @@ namespace lue { result[zone] = std::get<0>(values.front()); } - // As a side-effect, partitions that don't contain valid cells are - // created immidiately so they can participate already in other operations - if (result.empty()) - { - create_partition(); - } + // TODO This currently does not work well, given that below we iterate + // over *all* components to create partitions. If we need this, + // we need to change either create_partition, or the call site. + // // As a side-effect, partitions that don't contain valid cells are + // // created immidiately so they can participate already in other operations + // if (result.empty()) + // { + // create_partition(); + // } return result; } @@ -210,6 +231,7 @@ namespace lue { std::vector> maxima, Count current_length, Count const max_length) + // hpx::promise&& route_ready_p) { // Gather route fragments in current partition and return the location // information @@ -269,8 +291,6 @@ namespace lue { lue_hpx_assert(remote_id != this->get_id()); } - using CellIdxs = typename RouteFragment::CellIdxs; - // Collection for storing idxs of cells in the current partition // containing values that are all higher than or equal to the highest // value in another partition @@ -294,11 +314,13 @@ namespace lue { } } + // TODO Relative slow pop from front of vector values_by_zone.erase(values_by_zone.begin(), values_by_zone.begin() + idx); } if (values_by_zone.empty()) { + // TODO Relative slow pop from front of vector maxima.erase(maxima.begin()); } else @@ -312,6 +334,7 @@ namespace lue { // Grab new maximum. This is the first one in our colleciton. Value const new_maximum = std::get<0>(values_by_zone[0]); + // TODO Relative slow pop from front of vector // Pop current record from the front of the maxima collection that is moved around auto maximum_and_component_id = maxima[0]; maxima.erase(maxima.begin()); @@ -343,7 +366,10 @@ namespace lue { detail::DecreasingOrderZone component{remote_id}; auto downstream_route_fragment_location_f = component.record_route( - route_id, std::move(maxima), current_length, max_length); + route_id, + std::move(maxima), + current_length, + max_length); // , std::move(route_ready_p)); // End the current fragment by storing the location information of // the partition containing the downstream fragment. Wait for this @@ -352,6 +378,13 @@ namespace lue { route_fragment.end(downstream_route_fragment_location_f.get()); } + else + { + // TODO Done recording the route with the ID passed in. We can use this to: + // - Let the caller know the route is done + // - Only know create the partition + // route_ready_p.set_value(); + } _route_fragments[route_id].push_back(route_fragment); @@ -395,6 +428,8 @@ namespace lue { /// hpx::shared_future _partition_future; + hpx::promise _component_ready_p; + RoutePartition _route_partition; std::map>> _values_by_zone; @@ -526,13 +561,20 @@ namespace lue { std::vector>&& maxima, Count current_length, Count const max_length) const + // hpx::promise&& route_ready_p) const { lue_hpx_assert(this->is_ready()); lue_hpx_assert(this->get_id()); typename Server::RecordRouteAction action; - return hpx::async(action, this->get_id(), route_id, maxima, current_length, max_length); + return hpx::async( + action, + this->get_id(), + route_id, + std::move(maxima), + current_length, + max_length); // , std::move(route_ready_p)); } }; @@ -754,7 +796,11 @@ namespace lue { { return std::get<0>(lhs) > std::get<0>(rhs); }); } - // Per zone / route, record the route + // // Per zone / route, record the route + // // Pass in a promise that will become ready once the route has + // // been recorded. We keep the futures so we can attach a continuation. + // std::vector> routes_ready_f(max_values_by_zone.size()); + std::vector zones(max_values_by_zone.size()); std::vector> starts_f( max_values_by_zone.size()); @@ -766,10 +812,15 @@ namespace lue { lue_hpx_assert(!values.empty()); Component component{std::get<1>(values.front())}; + // hpx::promise route_ready_p{}; + // routes_ready_f[idx] = route_ready_p.get_future(); zones[idx] = zone; - starts_f[idx] = - component.record_route(zone, std::move(values), Count{0}, max_length); + starts_f[idx] = component.record_route( + zone, + std::move(values), + Count{0}, + max_length); // , std::move(route_ready_p)); ++idx; } diff --git a/source/framework/algorithm/test/decreasing_order_test.cpp b/source/framework/algorithm/test/decreasing_order_test.cpp index 81e28bfa4..6f14e37a3 100644 --- a/source/framework/algorithm/test/decreasing_order_test.cpp +++ b/source/framework/algorithm/test/decreasing_order_test.cpp @@ -1,9 +1,13 @@ #define BOOST_TEST_MODULE lue framework algorithm decreasing_order #include "lue/framework/algorithm/create_partitioned_array.hpp" #include "lue/framework/algorithm/value_policies/decreasing_order.hpp" +#include "lue/framework/algorithm/value_policies/greater_than.hpp" +#include "lue/framework/algorithm/value_policies/uniform.hpp" +#include "lue/framework/algorithm/value_policies/where.hpp" #include "lue/framework/test/array.hpp" #include "lue/framework/test/hpx_unit_test.hpp" #include "lue/stream.hpp" +#include namespace { @@ -968,10 +972,72 @@ BOOST_AUTO_TEST_CASE(use_case_01) BOOST_AUTO_TEST_CASE(random_input) { - // Create random input and test whether decreasing_order finishes at all. Random aspects: - // - Array shape - // - Partition shape - // - Value array elements - // - Zone array elements - // - Maximum route length + lue::Rank const rank{2}; + + using ZoneElement = std::uint64_t; + using ValueElement = float; + using Shape = lue::Shape; + using ValueArray = lue::PartitionedArray; + using ZoneArray = lue::PartitionedArray; + + ValueElement const x1{lue::policy::no_data_value}; + ZoneElement const x2{lue::policy::no_data_value}; + + std::random_device random_device{}; + std::default_random_engine random_number_engine(random_device()); + + Shape const array_shape = [&]() + { + lue::Count const min{100}; + lue::Count const max{500}; + std::uniform_int_distribution distribution(min, max); + + return Shape{ + distribution(random_number_engine), + distribution(random_number_engine), + }; + }(); + Shape const partition_shape = [&]() + { + lue::Count const min{10}; + lue::Count const max{100}; + std::uniform_int_distribution distribution(min, max); + + return Shape{ + distribution(random_number_engine), + distribution(random_number_engine), + }; + }(); + lue::Count const nr_zones = [&]() + { + lue::Count const min{1}; + lue::Count const max{10}; + std::uniform_int_distribution distribution(min, max); + + return distribution(random_number_engine); + }(); + + lue::Count const max_route_length = [&]() + { + lue::Count const min{0}; + lue::Count const max{lue::nr_elements(array_shape)}; + std::uniform_int_distribution distribution(min, max); + + return distribution(random_number_engine); + }(); + + using namespace lue::value_policies; + + ValueArray value_array{lue::value_policies::uniform(array_shape, partition_shape, 0, 100)}; + + value_array = lue::value_policies::where(value_array > ValueElement{10.0}, value_array); + + ZoneArray const zone_array{ + lue::value_policies::uniform(array_shape, partition_shape, 1, nr_zones)}; + + Route const route_we_got = lue::value_policies::decreasing_order(zone_array, value_array); + + route_we_got.wait(); + + BOOST_CHECK_EQUAL(route_we_got.nr_routes(), nr_zones); }