diff --git a/document/doc/CMakeLists.txt b/document/doc/CMakeLists.txt index bc325ccb5..154564c6a 100644 --- a/document/doc/CMakeLists.txt +++ b/document/doc/CMakeLists.txt @@ -19,57 +19,6 @@ doxygen_add_docs( ) set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${DOXYGEN_OUTPUT_DIRECTORY}) -# set(AUTODOC2_PACKAGE_DIR ../../${LUE_BUILD_PYTHON_PACKAGE_DIR}) - - -# set(SPHINX_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -# set(SPHINX_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/sphinx) -# set(SPHINX_INDEX_FILE ${SPHINX_BUILD_DIR}/index.html) -# -# file(GLOB_RECURSE sphinx_sources LIST_DIRECTORIES False *.rst) -# -# configure_file(conf.py.in conf.py @ONLY) -# -# add_custom_command( -# OUTPUT ${SPHINX_INDEX_FILE} -# COMMAND -# ${CMAKE_COMMAND} -# -E env "PYTHONPATH=${PROJECT_BINARY_DIR}/${LUE_INSTALL_PYTHON_PACKAGE_DIR}/..:$ENV{PYTHONPATH}" -# ${SPHINX_BUILD_EXECUTABLE} -b html -# -c ${CMAKE_CURRENT_BINARY_DIR} -# -Dbreathe_projects.LUE=${DOXYGEN_OUTPUT_DIR}/xml -# ${SPHINX_SOURCE_DIR} ${SPHINX_BUILD_DIR} -# DEPENDS -# doxygen_doc -# ${sphinx_sources} -# MAIN_DEPENDENCY -# ${CMAKE_CURRENT_BINARY_DIR}/conf.py) -# -# add_custom_target(sphinx_doc DEPENDS ${SPHINX_INDEX_FILE}) -# -# # TODO Make this depend on the generation of the docs. They must be ready to copy. -# # install( -# # DIRECTORY -# # ${SPHINX_BUILD_DIR} -# # DESTINATION ${CMAKE_INSTALL_DOCDIR} -# # COMPONENT lue_development -# # ) - - -# # https://www.sphinx-doc.org/en/master/man/sphinx-apidoc.html -# add_custom_target(python_api -# VERBATIM -# COMMAND -# ${CMAKE_COMMAND} -# -E env "SPHINX_APIDOC_OPTIONS=members,undoc-members,show-inheritance,inherited-members" -# ${SPHINX_APIDOC_EXECUTABLE} -# --force -# --separate -# --module-first -# -d 1 -# -o ${CMAKE_CURRENT_BINARY_DIR}/reference/python/api -# ${CMAKE_BINARY_DIR}/${LUE_BUILD_PYTHON_PACKAGE_DIR} -# ) configure_file( _config.yml.in @@ -78,19 +27,16 @@ configure_file( ) foreach(name IN ITEMS - about/project.md about/license.md + about/project.md about/publication.md about/related.md about/release.md - contribute/index.md contribute/documentation.md + contribute/index.md contribute/release.md example/index.md index.md - install/conda.md - install/index.md - install/source.md manual/data_model/concept.md manual/data_model/format.md manual/data_model/index.md @@ -99,32 +45,40 @@ foreach(name IN ITEMS manual/framework/index.md manual/framework/python/index.md manual/framework/scalability.md - manual/view/index.md manual/glossary.md + manual/index.md + manual/install/conda.md + manual/install/index.md + manual/install/source.md + manual/view/index.md + pcraster/index.md + pcraster/port.md + pcraster/status.md + quick_start/cpp.md + quick_start/index.md + quick_start/python.md reference/algorithm/clump.md reference/algorithm/index.md # reference/cpp/dataset.md reference/cpp/index.md - # reference/python/data_model/index.rst + reference/index.md # reference/python/data_model/hdf5/index.rst + # reference/python/data_model/index.rst # reference/python/framework/index.rst reference/python/index.md references.bib - short_description.md - pcraster/port.md - pcraster/status.md reference/utility/index.md reference/utility/lue_calculate.md reference/utility/lue_scalability.md reference/utility/lue_translate.md reference/utility/lue_validate.md reference/utility/lue_view.md + short_description.md _toc.yml ) configure_file(${name} ${name} COPYONLY) endforeach() - foreach(name IN ITEMS data_model/doc/index.md doc/index.md @@ -136,6 +90,8 @@ foreach(name IN ITEMS framework/algorithm/doc/policy/range.md framework/algorithm/doc/template.md + framework/doc/test/index.md + framework/doc/howto/index.md framework/doc/howto/add_local_operation.md @@ -148,6 +104,7 @@ foreach(name IN ITEMS framework/algorithm/doc/grouped_operation/global_operation.md framework/algorithm/doc/grouped_operation/routing_operation.md framework/algorithm/doc/grouped_operation/mathematical_operation.md + framework/algorithm/doc/grouped_operation/array_operation.md framework/algorithm/doc/grouped_operation/random_number_operation.md framework/partitioned_array/doc/index.md diff --git a/document/doc/_toc.yml b/document/doc/_toc.yml index 384bf1db9..230bec498 100644 --- a/document/doc/_toc.yml +++ b/document/doc/_toc.yml @@ -1,68 +1,63 @@ -# Table of contents -# Learn more at https://jupyterbook.org/customize/toc.html +# https://jupyterbook.org/en/stable/structure/toc.html format: jb-book root: index parts: - - caption: Manual + - caption: User chapters: - - file: install/index.md - sections: - - file: install/conda.md - - file: install/source.md - - file: manual/data_model/index.md + + - file: quick_start/index.md sections: - - file: manual/data_model/concept.md - - file: manual/data_model/format.md - - file: manual/framework/index.md + - file: quick_start/python.md + - file: quick_start/cpp.md + + - file: manual/index.md sections: - - file: manual/framework/python/index.md - - file: manual/framework/cpp/index.md - - file: manual/framework/execute.md - - file: manual/framework/scalability.md - - file: manual/view/index.md - - file: manual/glossary.md - - caption: Reference - chapters: - - file: reference/python/index.md - # sections: - # - file: reference/python/data_model/index.rst - # - file: reference/python/data_model/hdf5/index.rst - # - file: reference/python/framework/index.rst - # - file: reference/python/api/lue.rst - # - url: file:///genindex.html - # title: genindex - # - url: file:///py-modindex.html - # title: py-modindex - # - url: file:///search.html - # title: search - # - file: reference/python/apidocs/index.rst - # sections: - # - file: reference/python/data_model/hdf5/file.rst - # chapters: - # - file: genindex.html - - file: reference/cpp/index.md - # sections: - # - file: reference/cpp/dataset.md - - file: reference/utility/index.md + - file: manual/install/index.md + sections: + - file: manual/install/conda.md + - file: manual/install/source.md + - file: manual/data_model/index.md + sections: + - file: manual/data_model/concept.md + - file: manual/data_model/format.md + - file: manual/framework/index.md + sections: + - file: manual/framework/python/index.md + - file: manual/framework/cpp/index.md + - file: manual/framework/execute.md + - file: manual/framework/scalability.md + - file: manual/view/index.md + - file: manual/glossary.md + + - file: reference/index.md sections: - - file: reference/utility/lue_calculate.md - - file: reference/utility/lue_scalability.md - - file: reference/utility/lue_translate.md - - file: reference/utility/lue_validate.md - - file: reference/utility/lue_view.md - - file: reference/algorithm/index.md + - file: reference/python/index.md + - file: reference/cpp/index.md + - file: reference/utility/index.md + sections: + - file: reference/utility/lue_calculate.md + - file: reference/utility/lue_scalability.md + - file: reference/utility/lue_translate.md + - file: reference/utility/lue_validate.md + - file: reference/utility/lue_view.md + - file: reference/algorithm/index.md + sections: + - file: reference/algorithm/clump.md + + - file: pcraster/index.md sections: - - file: reference/algorithm/clump.md - - caption: PCRaster - chapters: - - file: pcraster/port.md - - file: pcraster/status.md - - caption: Development + - file: pcraster/port.md + - file: pcraster/status.md + + - caption: Developer chapters: + - file: contribute/index.md - - file: contribute/documentation.md - - file: contribute/release.md + sections: + - file: contribute/documentation.md + - file: contribute/release.md + - file: source/doc/index.md sections: - file: source/data_model/doc/index.md @@ -86,13 +81,17 @@ parts: - file: source/framework/algorithm/doc/grouped_operation/zonal_operation.md - file: source/framework/algorithm/doc/grouped_operation/global_operation.md - file: source/framework/algorithm/doc/grouped_operation/routing_operation.md + - file: source/framework/algorithm/doc/grouped_operation/array_operation.md - file: source/framework/algorithm/doc/grouped_operation/mathematical_operation.md - file: source/framework/algorithm/doc/grouped_operation/random_number_operation.md + - file: source/framework/doc/test/index.md - file: source/framework/doc/howto/index.md sections: - file: source/framework/doc/howto/add_local_operation.md + - caption: About chapters: + - file: about/project.md - file: about/release.md - file: example/index.md diff --git a/document/doc/about/project.md b/document/doc/about/project.md index 83fac4144..51c374142 100644 --- a/document/doc/about/project.md +++ b/document/doc/about/project.md @@ -1,6 +1,17 @@ (doc-about-project)= # Project +```{include} short_description.md +``` + +:::{margin} +LUE is an acronym for "Life, the Universe and Everything". It is pronounced as the French pronounce the name +Louis (`LU-EE`). +::: + +The LUE data model is described in more detail in {cite}`DeBakker:2017` and {cite}`DeJong:2019`. Details +about the LUE framework can be found in {cite}`DeJong:2021` and {cite}`DeJong:2022`. + LUE is the result of multiple research projects performed by the [Computational Geography](https://www.computationalgeography.org) group at Utrecht University in The Netherlands. One of the focus areas of this group is to improve on the concepts and design of environmental modelling frameworks, with diff --git a/document/doc/index.md b/document/doc/index.md index 6e3c82ce1..e243c579f 100644 --- a/document/doc/index.md +++ b/document/doc/index.md @@ -1,26 +1,5 @@ # LUE -:::{margin} -LUE is an acronym for "Life, the Universe and Everything". It is pronounced as the French pronounce the name -Louis (`LU-EE`). -::: - -```{include} short_description.md -``` - -The LUE data model is described in more detail in {cite}`DeBakker:2017` and {cite}`DeJong:2019`. Details -about the LUE framework can be found in {cite}`DeJong:2021` and {cite}`DeJong:2022`. - :::{warning} This documentation is work in progress. It is improved continuously, but nowhere near being complete. ::: - -The documentation is split into several parts: - -| | | -| --- | --- | -| Manual | General information about LUE. Start here if you are new to the software. | -| Reference | Details required to be able to use LUE. | -| PCRaster | Information for model developers interested in porting their PCRaster model to use LUE. | -| Development | Information for software developers interested in contributing to LUE. | -| About | Information about the project that doesn't fit in the other parts. | diff --git a/document/doc/install/conda.md b/document/doc/manual/install/conda.md similarity index 100% rename from document/doc/install/conda.md rename to document/doc/manual/install/conda.md diff --git a/document/doc/install/index.md b/document/doc/manual/install/index.md similarity index 100% rename from document/doc/install/index.md rename to document/doc/manual/install/index.md diff --git a/document/doc/install/source.md b/document/doc/manual/install/source.md similarity index 100% rename from document/doc/install/source.md rename to document/doc/manual/install/source.md diff --git a/document/doc/pcraster/index.md b/document/doc/pcraster/index.md new file mode 100644 index 000000000..503491a41 --- /dev/null +++ b/document/doc/pcraster/index.md @@ -0,0 +1 @@ +# PCRaster diff --git a/document/doc/quick_start/cpp.md b/document/doc/quick_start/cpp.md new file mode 100644 index 000000000..cc91bb079 --- /dev/null +++ b/document/doc/quick_start/cpp.md @@ -0,0 +1,15 @@ +# Game of Life in C++ + +## Install + +TODO + + +## Implement + +TODO + + +## Execute + +TODO diff --git a/document/doc/quick_start/index.md b/document/doc/quick_start/index.md new file mode 100644 index 000000000..9d79a93ba --- /dev/null +++ b/document/doc/quick_start/index.md @@ -0,0 +1,5 @@ +# Quick start + +Here, you will find just enough information to get started with using LUE. It is targetted at model +developers. We will be implementing [Conway's Game of +Life](https://en.wikipedia.org/wiki/Conway's_Game_of_Life) and execute it in parallel, using a single process. diff --git a/document/doc/quick_start/python.md b/document/doc/quick_start/python.md new file mode 100644 index 000000000..15283f9af --- /dev/null +++ b/document/doc/quick_start/python.md @@ -0,0 +1,14 @@ +# Game of Life in Python + +## Install +```bash +conda install -c conda-forge lue +``` + +See also [](#install-conda). + + +## Implement + + +## Execute diff --git a/source/doc/index.md b/source/doc/index.md index a2c6bb29d..b20a75ac5 100644 --- a/source/doc/index.md +++ b/source/doc/index.md @@ -1,5 +1,5 @@ (source-lue)= -# Source +# Source code The LUE software contains two main parts: code related to the physical [](#source-lue-data-model) and code related to the [framework](#source-lue-framework) for environmental modelling. diff --git a/source/framework/algorithm/doc/group.dox b/source/framework/algorithm/doc/group.dox index 3be2ac695..c36d0b2d0 100644 --- a/source/framework/algorithm/doc/group.dox +++ b/source/framework/algorithm/doc/group.dox @@ -25,3 +25,7 @@ /*! @defgroup random_number_operation Random number operations */ + +/*! + @defgroup array_operation Array operations +*/ diff --git a/source/framework/algorithm/doc/grouped_operation/array_operation.md b/source/framework/algorithm/doc/grouped_operation/array_operation.md new file mode 100644 index 000000000..793fe9f03 --- /dev/null +++ b/source/framework/algorithm/doc/grouped_operation/array_operation.md @@ -0,0 +1,8 @@ +(source-framework-algorithm-array)= +# Array operations + + +```{eval-rst} +.. doxygengroup:: array_operation + :content-only: +``` diff --git a/source/framework/algorithm/doc/grouped_operation/index.md b/source/framework/algorithm/doc/grouped_operation/index.md index e502e1c52..0c9a5254a 100644 --- a/source/framework/algorithm/doc/grouped_operation/index.md +++ b/source/framework/algorithm/doc/grouped_operation/index.md @@ -17,3 +17,4 @@ - [Zonal operations](#source-framework-algorithm-zonal) - [Global operations](#source-framework-algorithm-global) - [Routing operations](#source-framework-algorithm-routing) +- [Array operations](#source-framework-algorithm-array) diff --git a/source/framework/algorithm/doc/policy/domain.md b/source/framework/algorithm/doc/policy/domain.md index 6e8f386b5..369ab7277 100644 --- a/source/framework/algorithm/doc/policy/domain.md +++ b/source/framework/algorithm/doc/policy/domain.md @@ -9,19 +9,21 @@ class DomainPolicy { public: - auto within_domain(Element const... element) -> bool; + auto within_domain(Element const... value) -> bool; }; ``` The policy is used to check whether input element values are part of an algorithm's domain. For example, the -`sqrt` algorithm only support computing results for non-negative values. In case a negative value is passed +`sqrt` algorithm only supports computing results for non-negative values. In case a negative value is passed in, `within_domain` should return `false`. The {cpp:class}`lue::policy::AllValuesWithinDomain` policy is special in that it will consider all input element values to be part of an algorithm's domain. This policy can be used when it is guaranteed that this is the case. An optimizing compiler will completely remove the "check" from the code. +Algorithms that require a domain check typically use an custom, algorithm-specific domain policy. + ```{eval-rst} .. doxygenclass:: lue::policy::AllValuesWithinDomain ``` diff --git a/source/framework/algorithm/doc/policy/index.md b/source/framework/algorithm/doc/policy/index.md index f0661111e..01f07cb17 100644 --- a/source/framework/algorithm/doc/policy/index.md +++ b/source/framework/algorithm/doc/policy/index.md @@ -27,8 +27,11 @@ Currently there are several kinds of policies used by the algorithms: - Mark an output element value as no-data ::: -How the various policies perform their responsibility is up to the implementation. This way, same algorithm -can support multiple conventions, like for representing no-data values. +How the various policies perform their responsibility is up to the implementation. This way, the same +algorithm can support multiple conventions, like for representing no-data values. + +In general, the various policies are aggregated into a single {cpp:class}`lue::policy::Policies` instance, +which is passed as an argument to an algorithm. :::{margin} Please suggest a better name for the "default" and "value" policies... @@ -45,6 +48,7 @@ for all use-cases. Different policies can be created and used by 3rd-party users - Optimizer should remove all checks These policies are typically used as default policies: + - {cpp:class}`lue::policy::SkipNoData` - {cpp:class}`lue::policy::AllValuesWithinDomain` - {cpp:class}`lue::policy::AllValuesWithinRange` @@ -58,3 +62,18 @@ These policies are typically used as default policies: - Check input no-data, if relevant - Write output no-data, if relevant - Use LUE's default no-data policies + +These policies are typically used as value policies: +- {cpp:class}`lue::policy::DetectNoDataByValue` +- {cpp:class}`lue::policy::DetectNoDataByNaN` +- {cpp:class}`lue::policy::MarkNoDataByValue` +- {cpp:class}`lue::policy::MarkNoDataByNaN` + +Algorithms that require a domain check typically use an custom, algorithm-specific domain policy. + + +### Policies + +```{eval-rst} +.. doxygenclass:: lue::policy::Policies +``` diff --git a/source/framework/algorithm/doc/policy/no_data.md b/source/framework/algorithm/doc/policy/no_data.md index 4ccb0efa8..ec00b2017 100644 --- a/source/framework/algorithm/doc/policy/no_data.md +++ b/source/framework/algorithm/doc/policy/no_data.md @@ -3,6 +3,7 @@ No-data values are used to signal the absence of a valid value to use in a computation. Various conventions exist to do this. To support these conventions, algorithms can make use of input and output no-data policies. Depending on the policies used when instantiating an algorithm, it will use a specific concrete convention. +A single application can support multiple conventions. Often a special value is used to mark no-data. This special value is then dependant on the element type. In case of floating point values, `NaN` is a popular option to represent no-data. In case of signed integral @@ -24,16 +25,16 @@ class InputNoDataPolicy { public: - auto is_no_data(Element const& element) -> bool; + auto is_no_data(Element const& value) -> bool; - template - auto is_no_data(Data const& data, Index const idx...) -> bool; + template + auto is_no_data(Data const& data, Idxs const... idx) -> bool; }; ``` The policy is used to check whether input element values contain no-data. Often, algorithms will want to treat -such elements differently. For example, in case of a focal operation, no-data values can be skipped from -computing a result value. +such elements differently. For example, in case of a focal operation, no-data values within the focal window +may have to be skipped from the computation of the result value. The {cpp:class}`lue::policy::SkipNoData` policy is special in that it does not perform any check at all. This policy can be used when it is guaranteed that none of the input elements will contain a no-data value. An @@ -41,6 +42,8 @@ optimizing compiler will completely remove the "check" from the code. ```{eval-rst} .. doxygenclass:: lue::policy::SkipNoData +.. doxygenclass:: lue::policy::DetectNoDataByValue +.. doxygenclass:: lue::policy::DetectNoDataByNaN ``` @@ -55,17 +58,18 @@ class OutputNoDataPolicy { public: - void mark_no_data(Element& element) + void mark_no_data(Element& value) - template - void mark_no_data(Data& data, Index const idx...); + template + void mark_no_data(Data& data, Idxs const... idx); }; ``` The policy is used to mark a result element of an algorithm as no-data. For example, in case of the `sqrt` -algorithm, when the domain policy detected that an input element value is not within the domain of valid input -values (is negative in this case), then `mark_no_data` should mark the result element as no-data. +algorithm, when the [domain policy](#source-framework-algorithm-policy-domain) detected that an input element +value is not within the domain of valid input values (is negative in this case), then `mark_no_data` should +mark the result element as no-data. The {cpp:class}`lue::policy::DontMarkNoData` policy is special in that it does not mark any result element as no-data. This policy can be used when it is guaranteed that marking no-data is never needed. An optimizing @@ -73,4 +77,6 @@ compiler will completely remove the "marking" from the code. ```{eval-rst} .. doxygenclass:: lue::policy::DontMarkNoData +.. doxygenclass:: lue::policy::MarkNoDataByValue +.. doxygenclass:: lue::policy::MarkNoDataByNaN ``` diff --git a/source/framework/algorithm/doc/policy/range.md b/source/framework/algorithm/doc/policy/range.md index 9f46cbd90..d9187f04f 100644 --- a/source/framework/algorithm/doc/policy/range.md +++ b/source/framework/algorithm/doc/policy/range.md @@ -9,7 +9,7 @@ class RangePolicy { public: - auto within_range(InputElement const... element, OutputElement const result) -> bool; + auto within_range(InputElement const... value, OutputElement const result) -> bool; }; ``` diff --git a/source/framework/algorithm/include/lue/framework/algorithm/array_like.hpp b/source/framework/algorithm/include/lue/framework/algorithm/array_like.hpp index 364ea6ced..5a17c91d4 100644 --- a/source/framework/algorithm/include/lue/framework/algorithm/array_like.hpp +++ b/source/framework/algorithm/include/lue/framework/algorithm/array_like.hpp @@ -36,25 +36,27 @@ namespace lue { OutputData output_partition_data{shape}; - auto const& indp = std::get<0>(policies.inputs_policies()).input_no_data_policy(); - auto const& ondp = std::get<0>(policies.outputs_policies()).output_no_data_policy(); + // NOTE Can't use indp to check for no-data in the (output!) fill_value + // auto const& indp = std::get<0>(policies.inputs_policies()).input_no_data_policy(); + // auto const& ondp = + // std::get<0>(policies.outputs_policies()).output_no_data_policy(); Count const nr_elements{lue::nr_elements(output_partition_data)}; - if (indp.is_no_data(fill_value)) + // if (indp.is_no_data(fill_value)) + // { + // for (Index i = 0; i < nr_elements; ++i) + // { + // ondp.mark_no_data(output_partition_data, i); + // } + // } + // else + // { + for (Index i = 0; i < nr_elements; ++i) { - for (Index i = 0; i < nr_elements; ++i) - { - ondp.mark_no_data(output_partition_data, i); - } - } - else - { - for (Index i = 0; i < nr_elements; ++i) - { - output_partition_data[i] = fill_value; - } + output_partition_data[i] = fill_value; } + // } return OutputPartition{hpx::find_here(), offset, std::move(output_partition_data)}; } diff --git a/source/framework/algorithm/include/lue/framework/algorithm/definition/cell_index.hpp b/source/framework/algorithm/include/lue/framework/algorithm/definition/cell_index.hpp index 878d96562..12cc2247f 100644 --- a/source/framework/algorithm/include/lue/framework/algorithm/definition/cell_index.hpp +++ b/source/framework/algorithm/include/lue/framework/algorithm/definition/cell_index.hpp @@ -118,7 +118,7 @@ namespace lue { /*! @brief Return an array with for each valid true value in @a condition, the cell index along the dimension @a dimension_idx - @ingroup local_operation + @ingroup array_operation All elements with a non-valid or false value in @a condition will become non-valid in the result. diff --git a/source/framework/algorithm/include/lue/framework/algorithm/policy/all_values_within_domain.hpp b/source/framework/algorithm/include/lue/framework/algorithm/policy/all_values_within_domain.hpp index 92f705261..ce735bca7 100644 --- a/source/framework/algorithm/include/lue/framework/algorithm/policy/all_values_within_domain.hpp +++ b/source/framework/algorithm/include/lue/framework/algorithm/policy/all_values_within_domain.hpp @@ -13,11 +13,11 @@ namespace lue::policy { public: /*! - @brief Return whether all @a element values are within the domain + @brief Return whether all element @a value (s) are within the domain This function always returns `true`. */ - static constexpr auto within_domain([[maybe_unused]] Element const... element) -> bool + static constexpr auto within_domain([[maybe_unused]] Element const... value) -> bool { return true; } diff --git a/source/framework/algorithm/include/lue/framework/algorithm/policy/all_values_within_range.hpp b/source/framework/algorithm/include/lue/framework/algorithm/policy/all_values_within_range.hpp index ef912d0a0..c71e966b9 100644 --- a/source/framework/algorithm/include/lue/framework/algorithm/policy/all_values_within_range.hpp +++ b/source/framework/algorithm/include/lue/framework/algorithm/policy/all_values_within_range.hpp @@ -9,7 +9,7 @@ namespace lue::policy { @tparam OutputElement Type of the output element @tparam InputElement Types of the input elements - Use this policy if you do not want to check for out-of-rangeness in the output + Use this policy if you do not want to check for "out-of-rangeness" in the output */ template class AllValuesWithinRange @@ -17,13 +17,13 @@ namespace lue::policy { public: /*! - @brief Return whether all @a element values are within the range + @brief Return whether all element @a value (s) are within the range @param result Result value This function always returns `true`. */ static constexpr auto within_range( - [[maybe_unused]] InputElement const... element, [[maybe_unused]] OutputElement const result) + [[maybe_unused]] InputElement const... value, [[maybe_unused]] OutputElement const result) -> bool { return true; diff --git a/source/framework/algorithm/include/lue/framework/algorithm/policy/detect_no_data_by_nan.hpp b/source/framework/algorithm/include/lue/framework/algorithm/policy/detect_no_data_by_nan.hpp index 54ef33fe3..71a8df776 100644 --- a/source/framework/algorithm/include/lue/framework/algorithm/policy/detect_no_data_by_nan.hpp +++ b/source/framework/algorithm/include/lue/framework/algorithm/policy/detect_no_data_by_nan.hpp @@ -7,6 +7,12 @@ namespace lue::policy { + /*! + @brief Input no-data policy + @sa MarkNoDataByNaN, DetectNoDataByValue + + Policy to use when @a Element is a floating point type and NaN is used to represent no-data values. + */ template class DetectNoDataByNaN { @@ -15,22 +21,27 @@ namespace lue::policy { static_assert(std::is_floating_point_v); + /*! + @brief The no-data value to use in tests: std::numeric_limits::quiet_NaN() + */ static constexpr Element no_data_value{std::numeric_limits::quiet_NaN()}; - DetectNoDataByNaN() - { - } - - - bool is_no_data(Element const& element) const + /*! + @brief Return whether @a value is no-data + */ + auto is_no_data(Element const& value) const -> bool { - return std::isnan(element); + return std::isnan(value); } + /*! + @brief Return whether the element at index @a idx in @a data contains no-data + @tparam Data Collection of elements + */ template - bool is_no_data(Data const& data, Index const idx) const + auto is_no_data(Data const& data, Index const idx) const -> bool { static_assert(std::is_same_v, Element>); @@ -38,8 +49,12 @@ namespace lue::policy { } + /*! + @brief Return whether the element at index @a idx in @a data contains no-data + @tparam Data Collection of elements + */ template - bool is_no_data(Data const& data, Idxs const... idxs) const + auto is_no_data(Data const& data, Idxs const... idxs) const -> bool { static_assert(std::is_same_v, Element>); diff --git a/source/framework/algorithm/include/lue/framework/algorithm/policy/detect_no_data_by_value.hpp b/source/framework/algorithm/include/lue/framework/algorithm/policy/detect_no_data_by_value.hpp index c7d3f333b..e57c872cd 100644 --- a/source/framework/algorithm/include/lue/framework/algorithm/policy/detect_no_data_by_value.hpp +++ b/source/framework/algorithm/include/lue/framework/algorithm/policy/detect_no_data_by_value.hpp @@ -8,12 +8,32 @@ namespace lue::policy { + /*! + @brief Input no-data policy + @warning Don't use this policy when @a Element is a floating point type and when the no-data value + must be represented by a NaN + @sa MarkNoDataByValue, DetectNoDataByNaN + + Policy suitable for those cases where no-data is represented by some "special" value, like a minimum + value, maximum value, or a very small value. + */ template class DetectNoDataByValue { public: + /*! + @brief The default no-data value to use in tests + + These values are used, depending on @a Element: + + | Type | value | + | --- | --- | + | signed integral | std::numeric_limits::min() | + | unsigned integral | std::numeric_limits::max() | + | floating point | std::numeric_limits::lowest() | + */ static constexpr Element no_data_value{ []() { @@ -34,6 +54,10 @@ namespace lue::policy { }()}; + /*! + @brief Construct an instance, using the default DetectNoDataByValue::no_data_value as + the no-data value in tests + */ DetectNoDataByValue(): DetectNoDataByValue{no_data_value} @@ -42,6 +66,10 @@ namespace lue::policy { } + /*! + @brief Construct an instance, using @a value as the no-data value in tests + @warning If @a Element is a floating point type, @a value must not by NaN + */ DetectNoDataByValue(Element const value): _value{value} @@ -58,8 +86,21 @@ namespace lue::policy { } + /*! + @brief Return whether @a value is no-data + */ + auto is_no_data(Element const& value) const -> bool + { + return value == _value; + } + + + /*! + @brief Return whether the element at index @a idx in @a data contains no-data + @tparam Data Collection of elements + */ template - bool is_no_data(Data const& data, Index const idx) const + auto is_no_data(Data const& data, Index const idx) const -> bool { static_assert(std::is_same_v, Element>); @@ -67,27 +108,22 @@ namespace lue::policy { } + /*! + @brief Return whether the element at index @a idx in @a data contains no-data + @tparam Data Collection of elements + */ template - bool is_no_data(Data const& data, Idxs const... idxs) const + auto is_no_data(Data const& data, Idxs const... idxs) const -> bool { - if constexpr (sizeof...(Idxs) == 0) - { - static_assert(std::is_arithmetic_v); - - return data == _value; - } - else - { - static_assert(std::is_same_v, Element>); + static_assert(std::is_same_v, Element>); - return data(idxs...) == _value; - } + return data(idxs...) == _value; } protected: - Element value() const + auto value() const -> Element { return _value; } diff --git a/source/framework/algorithm/include/lue/framework/algorithm/policy/dont_mark_no_data.hpp b/source/framework/algorithm/include/lue/framework/algorithm/policy/dont_mark_no_data.hpp index 950b8298d..a23cf8ee7 100644 --- a/source/framework/algorithm/include/lue/framework/algorithm/policy/dont_mark_no_data.hpp +++ b/source/framework/algorithm/include/lue/framework/algorithm/policy/dont_mark_no_data.hpp @@ -2,60 +2,58 @@ #include "lue/framework/algorithm/policy/skip_no_data.hpp" -namespace lue { - namespace policy { +namespace lue::policy { - /*! - @brief Output no-data policy that does nothing + /*! + @brief Output no-data policy that does nothing + @sa SkipNoData - Use this policy if you do not want to mark no-data values in - the output. - */ - template - class DontMarkNoData: public SkipNoData - { + Use this policy if you do not want to mark no-data values in the output. + */ + template + class DontMarkNoData: public SkipNoData + { - public: + public: - /*! - @brief Mark @a element as no-data + /*! + @brief Mark @a value as no-data - This function does nothing. - */ - static constexpr void mark_no_data([[maybe_unused]] Element& element) - { - } + This function does nothing. + */ + static constexpr void mark_no_data([[maybe_unused]] Element& value) + { + } - /*! - @brief Mark the element at @a idx in @a data as no-data + /*! + @brief Mark the value at @a idx in @a data as no-data - This function does nothing. - */ - template - static constexpr void mark_no_data( - [[maybe_unused]] Data& data, [[maybe_unused]] Index const idx...) - { - } - }; + This function does nothing. + */ + template + static constexpr void mark_no_data( + [[maybe_unused]] Data& data, [[maybe_unused]] Idxs const... idx) + { + } + }; - namespace detail { + namespace detail { - template - class TypeTraits> - { + template + class TypeTraits> + { - public: + public: - using Element = E; + using Element = E; - template - using Policy = DontMarkNoData; + template + using Policy = DontMarkNoData; - using InputNoDataPolicy = SkipNoData; - }; + using InputNoDataPolicy = SkipNoData; + }; - } // namespace detail - } // namespace policy -} // namespace lue + } // namespace detail +} // namespace lue::policy diff --git a/source/framework/algorithm/include/lue/framework/algorithm/policy/mark_no_data_by_nan.hpp b/source/framework/algorithm/include/lue/framework/algorithm/policy/mark_no_data_by_nan.hpp index 7e2cd2122..dd5a8261b 100644 --- a/source/framework/algorithm/include/lue/framework/algorithm/policy/mark_no_data_by_nan.hpp +++ b/source/framework/algorithm/include/lue/framework/algorithm/policy/mark_no_data_by_nan.hpp @@ -4,6 +4,12 @@ namespace lue::policy { + /*! + @brief Output no-data policy + @sa DetectNoDataByNaN, MarkNoDataByValue + + Policy to use when @a Element is a floating point type and NaN is used to represent no-data values. + */ template class MarkNoDataByNaN: public DetectNoDataByNaN { @@ -13,20 +19,18 @@ namespace lue::policy { static_assert(std::is_floating_point_v); - MarkNoDataByNaN(): - - DetectNoDataByNaN{} - - { - } - - - void mark_no_data(Element& element) const + /*! + @brief Mark @a value as no-data + */ + void mark_no_data(Element& value) const { - element = std::numeric_limits::quiet_NaN(); + value = std::numeric_limits::quiet_NaN(); } + /*! + @brief Mark the value at @a idx in @a data as no-data + */ template void mark_no_data(Data& data, Index const idx) const { @@ -36,6 +40,9 @@ namespace lue::policy { } + /*! + @brief Mark the value at @a idx in @a data as no-data + */ template void mark_no_data(Data& data, Idxs const... idxs) const { diff --git a/source/framework/algorithm/include/lue/framework/algorithm/policy/mark_no_data_by_value.hpp b/source/framework/algorithm/include/lue/framework/algorithm/policy/mark_no_data_by_value.hpp index f7cf25186..17883ec36 100644 --- a/source/framework/algorithm/include/lue/framework/algorithm/policy/mark_no_data_by_value.hpp +++ b/source/framework/algorithm/include/lue/framework/algorithm/policy/mark_no_data_by_value.hpp @@ -4,20 +4,34 @@ namespace lue::policy { + /*! + @brief Output no-data policy + @sa DetectNoDataByValue, MarkNoDataByNaN + + Policy suitable for those cases where no-data is represented by some "special" value, like a minimum + value, maximum value, or a very small value. + */ template class MarkNoDataByValue: public DetectNoDataByValue { public: + /*! + @brief Construct an instance, using the default DetectNoDataByValue::no_data_value as + the no-data value + */ MarkNoDataByValue(): - MarkNoDataByValue(DetectNoDataByValue::no_data_value) + MarkNoDataByValue{DetectNoDataByValue::no_data_value} { } + /*! + @brief Construct an instance, using @a value as the no-data value + */ MarkNoDataByValue(Element const value): DetectNoDataByValue{value} @@ -26,12 +40,18 @@ namespace lue::policy { } - void mark_no_data(Element& element) const + /*! + @brief Mark @a value as no-data + */ + void mark_no_data(Element& value) const { - element = this->value(); + value = this->value(); } + /*! + @brief Mark the value at @a idx in @a data as no-data + */ template void mark_no_data(Data& data, Index const idx) const { @@ -41,6 +61,9 @@ namespace lue::policy { } + /*! + @brief Mark the value at @a idx in @a data as no-data + */ template void mark_no_data(Data& data, Idxs const... idxs) const { diff --git a/source/framework/algorithm/include/lue/framework/algorithm/policy/policies.hpp b/source/framework/algorithm/include/lue/framework/algorithm/policy/policies.hpp index 39ac4d872..9ac6f8366 100644 --- a/source/framework/algorithm/include/lue/framework/algorithm/policy/policies.hpp +++ b/source/framework/algorithm/include/lue/framework/algorithm/policy/policies.hpp @@ -18,6 +18,12 @@ namespace lue::policy { using Elements = detail::TypeList; + /*! + @brief Primary class template for a class aggregating all algorithm policies + @tparam DomainPolicy_ Domain policy class + @tparam OutputsPolicies_ Policies related to zero or more outputs + @tparam InputsPolicies_ Policies related to zero or more inputs + */ template class Policies { @@ -29,6 +35,21 @@ namespace lue::policy { using OutputsPolicies = OutputsPolicies_; using InputsPolicies = InputsPolicies_; + + /*! + @brief Return the domain policy + */ + auto domain_policy() const -> DomainPolicy const&; + + /*! + @brief Return the inputs policies + */ + auto inputs_policies() const -> InputsPolicies const&; + + /*! + @brief Return the outputs policies + */ + auto outputs_policies() const -> OutputsPolicies const&; }; @@ -40,6 +61,15 @@ namespace lue::policy { // - NoDataFocusElementPolicy + /*! + @brief Partial specialization of a class template for a class aggregating all algorithm policies + @tparam DomainPolicy_ Domain policy class + @tparam OutputsPolicies_ Policies related to the algorithm's output(s) + @tparam InputsPolicies_ Policies related to the algorithm's input(s) + + This specialization uses detail::TypeList to be able to separate between an unknown number of output + policies and an unknown number of input policies. + */ template class Policies, detail::TypeList> { @@ -57,8 +87,8 @@ namespace lue::policy { Policies( DomainPolicy const& domain_policy, - OutputPolicy... output_policies, - InputPolicy... input_policies): + OutputPolicy const&... output_policies, + InputPolicy const&... input_policies): _dp{domain_policy}, _op{output_policies...}, @@ -67,17 +97,17 @@ namespace lue::policy { { } - DomainPolicy const& domain_policy() const + auto domain_policy() const -> DomainPolicy const& { return _dp; } - InputsPolicies const& inputs_policies() const + auto inputs_policies() const -> InputsPolicies const& { return _ip; } - OutputsPolicies const& outputs_policies() const + auto outputs_policies() const -> OutputsPolicies const& { return _op; } diff --git a/source/framework/algorithm/include/lue/framework/algorithm/policy/skip_no_data.hpp b/source/framework/algorithm/include/lue/framework/algorithm/policy/skip_no_data.hpp index 085d49ad0..9d0dddb2a 100644 --- a/source/framework/algorithm/include/lue/framework/algorithm/policy/skip_no_data.hpp +++ b/source/framework/algorithm/include/lue/framework/algorithm/policy/skip_no_data.hpp @@ -4,72 +4,71 @@ #include -namespace lue { - namespace policy { +namespace lue::policy { - /*! - @brief Input no-data policy that does nothing + /*! + @brief Input no-data policy that does nothing + @sa DontMarkNoData - Use this policy if you do not want to check for no-data values in - the input. - */ - template - class SkipNoData - { - - public: + Use this policy if you do not want to check for no-data values in + the input. + */ + template + class SkipNoData + { - /*! - @brief Return whether @a element contains no-data + public: - This function always returns `false`. - */ - static constexpr auto is_no_data([[maybe_unused]] Element const& element) -> bool - { - return false; - } + /*! + @brief Return whether @a element contains no-data - /*! - @brief Return whether the element at index @a idx in @a data contains no-data - @tparam Data Collection of elements - - This function always returns `false`. - */ - template - static constexpr auto is_no_data( - [[maybe_unused]] Data const& data, [[maybe_unused]] Index const idx...) -> bool - { - static_assert(std::is_same_v, Element>); + This function always returns `false`. + */ + static constexpr auto is_no_data([[maybe_unused]] Element const& value) -> bool + { + return false; + } + + /*! + @brief Return whether the element at index @a idx in @a data contains no-data + @tparam Data Collection of elements + + This function always returns `false`. + */ + template + static constexpr auto is_no_data( + [[maybe_unused]] Data const& data, [[maybe_unused]] Idxs const... idx) -> bool + { + static_assert(std::is_same_v, Element>); - return false; - } + return false; + } - private: + private: - friend class hpx::serialization::access; + friend class hpx::serialization::access; - template - void serialize([[maybe_unused]] Archive& archive, [[maybe_unused]] unsigned int const version) - { - // Nothing to do - } - }; + template + void serialize([[maybe_unused]] Archive& archive, [[maybe_unused]] unsigned int const version) + { + // Nothing to do + } + }; - namespace detail { + namespace detail { - template - class TypeTraits> - { + template + class TypeTraits> + { - public: + public: - using Element = E; + using Element = E; - template - using Policy = SkipNoData; - }; + template + using Policy = SkipNoData; + }; - } // namespace detail - } // namespace policy -} // namespace lue + } // namespace detail +} // namespace lue::policy diff --git a/source/framework/doc/test/index.md b/source/framework/doc/test/index.md new file mode 100644 index 000000000..8ae056963 --- /dev/null +++ b/source/framework/doc/test/index.md @@ -0,0 +1 @@ +# Test