From 1ba0a79cdada48446d14ab274064fa90b6c6a343 Mon Sep 17 00:00:00 2001 From: Etienne Ndamlabin Date: Thu, 16 Jan 2025 12:40:40 +0100 Subject: [PATCH 01/42] Damaris plugin --- CMakeLists.txt | 11 +- plugins/damaris/AUTHORS | 12 + plugins/damaris/CMakeLists.txt | 86 ++ plugins/damaris/cmake/FindDamaris.cmake | 50 + .../cmake/FindPackageHandleStandardArgs.cmake | 466 +++++++ .../damaris/cmake/FindPackageMessage.cmake | 48 + .../cmake/SelectLibraryConfigurations.cmake | 80 ++ plugins/damaris/damaris.cxx | 203 +++ plugins/damaris/damaris_api_call_handler.cxx | 454 +++++++ plugins/damaris/damaris_api_call_handler.h | 99 ++ plugins/damaris/damaris_cfg.cxx | 1117 +++++++++++++++++ plugins/damaris/damaris_cfg.h | 207 +++ plugins/damaris/damaris_wrapper.cxx | 234 ++++ plugins/damaris/damaris_wrapper.h | 398 ++++++ plugins/damaris/example/CMakeLists.txt | 3 + .../damaris/example/paraview/CMakeLists.txt | 6 + plugins/damaris/example/paraview/image.cpp | 269 ++++ plugins/damaris/example/paraview/image.py | 71 ++ plugins/damaris/example/paraview/image.xml | 47 + plugins/damaris/example/python/.Rhistory | 0 plugins/damaris/example/python/3dmesh_dask.py | 224 ++++ .../damaris/example/python/3dmesh_dask.xml | 36 + .../damaris/example/python/3dmesh_dask.yml | 105 ++ plugins/damaris/example/python/3dmesh_py.c | 306 +++++ plugins/damaris/example/python/3dmesh_py.py | 166 +++ plugins/damaris/example/python/3dmesh_py.xml | 43 + plugins/damaris/example/python/3dmesh_py.yml | 135 ++ .../example/python/3dmesh_py_domains.c | 277 ++++ plugins/damaris/example/python/CMakeLists.txt | 13 + plugins/damaris/example/python/README.md | 116 ++ plugins/damaris/example/python/dask_file.json | 10 + plugins/damaris/example/storage/2dmesh.c | 275 ++++ plugins/damaris/example/storage/2dmesh.xml | 36 + plugins/damaris/example/storage/2dmesh.yml | 170 +++ .../damaris/example/storage/CMakeLists.txt | 6 + 35 files changed, 5778 insertions(+), 1 deletion(-) create mode 100644 plugins/damaris/AUTHORS create mode 100644 plugins/damaris/CMakeLists.txt create mode 100644 plugins/damaris/cmake/FindDamaris.cmake create mode 100644 plugins/damaris/cmake/FindPackageHandleStandardArgs.cmake create mode 100644 plugins/damaris/cmake/FindPackageMessage.cmake create mode 100644 plugins/damaris/cmake/SelectLibraryConfigurations.cmake create mode 100644 plugins/damaris/damaris.cxx create mode 100644 plugins/damaris/damaris_api_call_handler.cxx create mode 100644 plugins/damaris/damaris_api_call_handler.h create mode 100644 plugins/damaris/damaris_cfg.cxx create mode 100644 plugins/damaris/damaris_cfg.h create mode 100644 plugins/damaris/damaris_wrapper.cxx create mode 100644 plugins/damaris/damaris_wrapper.h create mode 100644 plugins/damaris/example/CMakeLists.txt create mode 100644 plugins/damaris/example/paraview/CMakeLists.txt create mode 100644 plugins/damaris/example/paraview/image.cpp create mode 100644 plugins/damaris/example/paraview/image.py create mode 100644 plugins/damaris/example/paraview/image.xml create mode 100644 plugins/damaris/example/python/.Rhistory create mode 100644 plugins/damaris/example/python/3dmesh_dask.py create mode 100644 plugins/damaris/example/python/3dmesh_dask.xml create mode 100644 plugins/damaris/example/python/3dmesh_dask.yml create mode 100644 plugins/damaris/example/python/3dmesh_py.c create mode 100755 plugins/damaris/example/python/3dmesh_py.py create mode 100644 plugins/damaris/example/python/3dmesh_py.xml create mode 100644 plugins/damaris/example/python/3dmesh_py.yml create mode 100644 plugins/damaris/example/python/3dmesh_py_domains.c create mode 100644 plugins/damaris/example/python/CMakeLists.txt create mode 100644 plugins/damaris/example/python/README.md create mode 100644 plugins/damaris/example/python/dask_file.json create mode 100644 plugins/damaris/example/storage/2dmesh.c create mode 100644 plugins/damaris/example/storage/2dmesh.xml create mode 100644 plugins/damaris/example/storage/2dmesh.yml create mode 100644 plugins/damaris/example/storage/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index cc48d5adb..e18ea9f2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,7 @@ option(BUILD_TRACE_PLUGIN "Build Trace plugin" ON) option(BUILD_USER_CODE_PLUGIN "Build User-code plugin" ON) option(BUILD_JSON_PLUGIN "Build JSON plugin" OFF) option(BUILD_DEISA_PLUGIN "Build Deisa plug-in" OFF) +option(BUILD_DAMARIS_PLUGIN "Build Damaris plug-in" ON) @@ -119,6 +120,9 @@ endif() if("${BUILD_DEISA_PLUGIN}") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/deisa/cmake") endif() +if("${BUILD_DAMARIS_PLUGIN}") + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/damaris/cmake") +endif() if("${BUILD_MPI_PLUGIN}") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/mpi/cmake") endif() @@ -133,7 +137,6 @@ if("${BUILD_TESTING}") endif() - ### Sanity check if(NOT "${BUILD_SHARED_LIBS}") @@ -532,6 +535,12 @@ sbuild_add_module(DEISA_PLUGIN DEPENDS PDI ) +sbuild_add_module(DAMARIS_PLUGIN + ENABLE_BUILD_FLAG BUILD_DAMARIS_PLUGIN + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/plugins/damaris" + DEPENDS PDI #Damaris !? +) + sbuild_add_module(PDI_EXAMPLE ENABLE_BUILD_FLAG BUILD_TESTING SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/example" diff --git a/plugins/damaris/AUTHORS b/plugins/damaris/AUTHORS new file mode 100644 index 000000000..80a2da924 --- /dev/null +++ b/plugins/damaris/AUTHORS @@ -0,0 +1,12 @@ +Multiple people have contributed to PDI Damaris plugin. To show our +appreciation for their public spirit, we list here in alphabetical order a +condensed list of their contributions. + + +Josh Bowden - Inria (joshua-charles.bowden@inria.fr) +* Maintainer (Apr. 2024 - Aug. 2024) +* Design and initial implementation + +Etienne Ndamlabin - Inria (jean-etienne.ndamlabin-mboula@inria.fr) +* Maintainer (Oct. 2024 - ...) +* (Re-)Design and initial implementation diff --git a/plugins/damaris/CMakeLists.txt b/plugins/damaris/CMakeLists.txt new file mode 100644 index 000000000..1afc10c08 --- /dev/null +++ b/plugins/damaris/CMakeLists.txt @@ -0,0 +1,86 @@ +#============================================================================= +# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2024 Institut national de recherche en informatique et en automatique (Inria) +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the names of CEA, nor the names of the contributors may be used to +# endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +cmake_minimum_required(VERSION 3.16...3.29) +project(pdi_damaris_plugin LANGUAGES C CXX) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") + +# TODO: +#include(CTest) + +include(GNUInstallDirs) + +#Damaris +set(Damaris_DEPS damaris MPI::MPI_C MPI::MPI_CXX) +find_package(Damaris) +if (Damaris_FOUND) + message(STATUS "The Damaris library was found") + # Adds the libraries used - Damaris and its dependencies to the link line + # target_link_libraries(mysim PUBLIC ${Damaris_LIBRARIES}) + # This creates a definition of a pre-processor variable (PROG_HAS_DAMARIS) + # that can be used as a guard in the C/C++ code: + # target_compile_definitions(mysim PRIVATE PROG_HAS_DAMARIS) +else() + message(STATUS "The Damaris library was NOT found") +endif() +include_directories(${Damaris_INCLUDE_DIRS} ${Damaris_INCLUDE_DIRS}/damaris) +link_directories(${Damaris_LIBRARIES_PATH}) + +# MPI +find_package(MPI REQUIRED COMPONENTS CXX C) + +# PDI +find_package(PDI REQUIRED COMPONENTS plugins) + +# The plugin +add_library(pdi_damaris_plugin MODULE + damaris.cxx + damaris_cfg.cxx + damaris_wrapper.cxx + damaris_api_call_handler.cxx) +target_link_libraries(pdi_damaris_plugin PUBLIC PDI::PDI_plugins ${Damaris_DEPS}) +set_target_properties(pdi_damaris_plugin PROPERTIES CXX_VISIBILITY_PRESET hidden) + +# installation +set(INSTALL_PDIPLUGINDIR "${PDI_DEFAULT_PLUGINDIR}" CACHE PATH "PDI plugins (${PDI_DEFAULT_PLUGINDIR})") +install(TARGETS pdi_damaris_plugin + LIBRARY DESTINATION "${INSTALL_PDIPLUGINDIR}" +) + +#[===[ TODO +# Tests +if("${BUILD_TESTING}") + add_subdirectory(tests/) +endif() +]===] + +if("${DAMARIS_BUILD_EXAMPLES}") + add_subdirectory(example/) +endif() diff --git a/plugins/damaris/cmake/FindDamaris.cmake b/plugins/damaris/cmake/FindDamaris.cmake new file mode 100644 index 000000000..c7b896a79 --- /dev/null +++ b/plugins/damaris/cmake/FindDamaris.cmake @@ -0,0 +1,50 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindDamaris +-------- + +Find Damaris, a library for data managmement and visualisation that provides +asynchronous, in situ processing capabilities to MPI based simulation codes. +#]=======================================================================] + +#include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) +#include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +include(FindPackageHandleStandardArgs) + +set(Damaris_BASE_DIR /usr/lib/damaris /opt/damaris) +set(Damaris_VERSIONS 1.11.1 1.11.2) + +#Find Damaris base install dir +set(Damaris_CANDIDATES ${Damaris_ROOT}) +foreach(base_dir ${Damaris_BASE_DIR}) + list(APPEND Damaris_CANDIDATES ${base_dir}) #In case no version dir exists + foreach(version ${Damaris_VERSIONS}) + list(APPEND Damaris_CANDIDATES ${base_dir}/${version}) + endforeach() +endforeach() + +set(Damaris_INC_SUFFIXES) +set(Damaris_LIB_SUFFIXES) +foreach(version ${Damaris_VERSIONS}) + list(APPEND Damaris_INC_SUFFIXES include) + list(APPEND Damaris_LIB_SUFFIXES lib) +endforeach() + +find_path(Damaris_INCLUDE_DIRS Damaris.h + HINTS ${Damaris_CANDIDATES} + PATH_SUFFIXES ${Damaris_INC_SUFFIXES} + ENV CPLUS_INCLUDE_PATH) +find_library(Damaris_LIBRARIES damaris + HINTS ${Damaris_CANDIDATES} + PATH_SUFFIXES ${Damaris_LIB_SUFFIXES} + ENV LIBRARY_PATH LD_LIBRARY_PATH) + +find_package_handle_standard_args(Damaris DEFAULT_MSG Damaris_INCLUDE_DIRS + Damaris_LIBRARIES) +mark_as_advanced(Damaris_INCLUDE_DIRS Damaris_LIBRARIES) +if(Damaris_INCLUDE_DIRS) + set(Damaris_FOUND TRUE) + get_filename_component(Damaris_LIBRARIES_PATH ${Damaris_LIBRARIES} DIRECTORY) +endif(Damaris_INCLUDE_DIRS) \ No newline at end of file diff --git a/plugins/damaris/cmake/FindPackageHandleStandardArgs.cmake b/plugins/damaris/cmake/FindPackageHandleStandardArgs.cmake new file mode 100644 index 000000000..4fb08259a --- /dev/null +++ b/plugins/damaris/cmake/FindPackageHandleStandardArgs.cmake @@ -0,0 +1,466 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindPackageHandleStandardArgs +----------------------------- + +This module provides a function intended to be used in :ref:`Find Modules` +implementing :command:`find_package()` calls. It handles the +``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. +It also sets the ``_FOUND`` variable. The package is +considered found if all variables listed contain valid results, e.g. +valid filepaths. + +.. command:: find_package_handle_standard_args + + There are two signatures:: + + find_package_handle_standard_args( + (DEFAULT_MSG|) + ... + ) + + find_package_handle_standard_args( + [FOUND_VAR ] + [REQUIRED_VARS ...] + [VERSION_VAR ] + [HANDLE_COMPONENTS] + [CONFIG_MODE] + [NAME_MISMATCHED] + [REASON_FAILURE_MESSAGE ] + [FAIL_MESSAGE ] + ) + + The ``_FOUND`` variable will be set to ``TRUE`` if all + the variables ``...`` are valid and any optional + constraints are satisfied, and ``FALSE`` otherwise. A success or + failure message may be displayed based on the results and on + whether the ``REQUIRED`` and/or ``QUIET`` option was given to + the :command:`find_package` call. + + The options are: + + ``(DEFAULT_MSG|)`` + In the simple signature this specifies the failure message. + Use ``DEFAULT_MSG`` to ask for a default message to be computed + (recommended). Not valid in the full signature. + + ``FOUND_VAR `` + Obsolete. Specifies either ``_FOUND`` or + ``_FOUND`` as the result variable. This exists only + for compatibility with older versions of CMake and is now ignored. + Result variables of both names are always set for compatibility. + + ``REQUIRED_VARS ...`` + Specify the variables which are required for this package. + These may be named in the generated failure message asking the + user to set the missing variable values. Therefore these should + typically be cache entries such as ``FOO_LIBRARY`` and not output + variables like ``FOO_LIBRARIES``. This option is mandatory if + ``HANDLE_COMPONENTS`` is not specified. + + ``VERSION_VAR `` + Specify the name of a variable that holds the version of the package + that has been found. This version will be checked against the + (potentially) specified required version given to the + :command:`find_package` call, including its ``EXACT`` option. + The default messages include information about the required + version and the version which has been actually found, both + if the version is ok or not. + + ``HANDLE_COMPONENTS`` + Enable handling of package components. In this case, the command + will report which components have been found and which are missing, + and the ``_FOUND`` variable will be set to ``FALSE`` + if any of the required components (i.e. not the ones listed after + the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are + missing. + + ``CONFIG_MODE`` + Specify that the calling find module is a wrapper around a + call to ``find_package( NO_MODULE)``. This implies + a ``VERSION_VAR`` value of ``_VERSION``. The command + will automatically check whether the package configuration file + was found. + + ``REASON_FAILURE_MESSAGE `` + Specify a custom message of the reason for the failure which will be + appended to the default generated message. + + ``FAIL_MESSAGE `` + Specify a custom failure message instead of using the default + generated message. Not recommended. + + ``NAME_MISMATCHED`` + Indicate that the ```` does not match + ``${CMAKE_FIND_PACKAGE_NAME}``. This is usually a mistake and raises a + warning, but it may be intentional for usage of the command for components + of a larger package. + +Example for the simple signature: + +.. code-block:: cmake + + find_package_handle_standard_args(LibXml2 DEFAULT_MSG + LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) + +The ``LibXml2`` package is considered to be found if both +``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. +Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found +and ``REQUIRED`` was used, it fails with a +:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was +used or not. If it is found, success will be reported, including +the content of the first ````. On repeated CMake runs, +the same message will not be printed again. + +.. note:: + + If ```` does not match ``CMAKE_FIND_PACKAGE_NAME`` for the + calling module, a warning that there is a mismatch is given. The + ``FPHSA_NAME_MISMATCHED`` variable may be set to bypass the warning if using + the old signature and the ``NAME_MISMATCHED`` argument using the new + signature. To avoid forcing the caller to require newer versions of CMake for + usage, the variable's value will be used if defined when the + ``NAME_MISMATCHED`` argument is not passed for the new signature (but using + both is an error).. + +Example for the full signature: + +.. code-block:: cmake + + find_package_handle_standard_args(LibArchive + REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR + VERSION_VAR LibArchive_VERSION) + +In this case, the ``LibArchive`` package is considered to be found if +both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. +Also the version of ``LibArchive`` will be checked by using the version +contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, +the default messages will be printed. + +Another example for the full signature: + +.. code-block:: cmake + + find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) + find_package_handle_standard_args(Automoc4 CONFIG_MODE) + +In this case, a ``FindAutmoc4.cmake`` module wraps a call to +``find_package(Automoc4 NO_MODULE)`` and adds an additional search +directory for ``automoc4``. Then the call to +``find_package_handle_standard_args`` produces a proper success/failure +message. +#]=======================================================================] + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) + +# internal helper macro +macro(_FPHSA_FAILURE_MESSAGE _msg) + set (__msg "${_msg}") + if (FPHSA_REASON_FAILURE_MESSAGE) + string(APPEND __msg "\n Reason given by package: ${FPHSA_REASON_FAILURE_MESSAGE}\n") + endif() + if (${_NAME}_FIND_REQUIRED) + message(FATAL_ERROR "${__msg}") + else () + if (NOT ${_NAME}_FIND_QUIETLY) + message(STATUS "${__msg}") + endif () + endif () +endmacro() + + +# internal helper macro to generate the failure message when used in CONFIG_MODE: +macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) + # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: + if(${_NAME}_CONFIG) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") + else() + # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. + # List them all in the error message: + if(${_NAME}_CONSIDERED_CONFIGS) + set(configsText "") + list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) + math(EXPR configsCount "${configsCount} - 1") + foreach(currentConfigIndex RANGE ${configsCount}) + list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) + list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) + string(APPEND configsText "\n ${filename} (version ${version})") + endforeach() + if (${_NAME}_NOT_FOUND_MESSAGE) + if (FPHSA_REASON_FAILURE_MESSAGE) + string(PREPEND FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}\n ") + else() + set(FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}") + endif() + else() + string(APPEND configsText "\n") + endif() + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:${configsText}") + + else() + # Simple case: No Config-file was found at all: + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") + endif() + endif() +endmacro() + + +function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) + + # Set up the arguments for `cmake_parse_arguments`. + set(options CONFIG_MODE HANDLE_COMPONENTS NAME_MISMATCHED) + set(oneValueArgs FAIL_MESSAGE REASON_FAILURE_MESSAGE VERSION_VAR FOUND_VAR) + set(multiValueArgs REQUIRED_VARS) + + # Check whether we are in 'simple' or 'extended' mode: + set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) + list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) + + unset(FPHSA_NAME_MISMATCHED_override) + if (DEFINED FPHSA_NAME_MISMATCHED) + # If the variable NAME_MISMATCHED variable is set, error if it is passed as + # an argument. The former is for old signatures, the latter is for new + # signatures. + list(FIND ARGN "NAME_MISMATCHED" name_mismatched_idx) + if (NOT name_mismatched_idx EQUAL "-1") + message(FATAL_ERROR + "The `NAME_MISMATCHED` argument may only be specified by the argument or " + "the variable, not both.") + endif () + + # But use the variable if it is not an argument to avoid forcing minimum + # CMake version bumps for calling modules. + set(FPHSA_NAME_MISMATCHED_override "${FPHSA_NAME_MISMATCHED}") + endif () + + if(${INDEX} EQUAL -1) + set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) + set(FPHSA_REQUIRED_VARS ${ARGN}) + set(FPHSA_VERSION_VAR) + else() + cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) + + if(FPHSA_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") + endif() + + if(NOT FPHSA_FAIL_MESSAGE) + set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") + endif() + + # In config-mode, we rely on the variable _CONFIG, which is set by find_package() + # when it successfully found the config-file, including version checking: + if(FPHSA_CONFIG_MODE) + list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) + list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) + set(FPHSA_VERSION_VAR ${_NAME}_VERSION) + endif() + + if(NOT FPHSA_REQUIRED_VARS AND NOT FPHSA_HANDLE_COMPONENTS) + message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") + endif() + endif() + + if (DEFINED FPHSA_NAME_MISMATCHED_override) + set(FPHSA_NAME_MISMATCHED "${FPHSA_NAME_MISMATCHED_override}") + endif () + + if (DEFINED CMAKE_FIND_PACKAGE_NAME + AND NOT FPHSA_NAME_MISMATCHED + AND NOT _NAME STREQUAL CMAKE_FIND_PACKAGE_NAME) + message(AUTHOR_WARNING + "The package name passed to `find_package_handle_standard_args` " + "(${_NAME}) does not match the name of the calling package " + "(${CMAKE_FIND_PACKAGE_NAME}). This can lead to problems in calling " + "code that expects `find_package` result variables (e.g., `_FOUND`) " + "to follow a certain pattern.") + endif () + +# now that we collected all arguments, process them + + if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") + set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") + endif() + + if (FPHSA_REQUIRED_VARS) + list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) + endif() + + string(TOUPPER ${_NAME} _NAME_UPPER) + string(TOLOWER ${_NAME} _NAME_LOWER) + + if(FPHSA_FOUND_VAR) + set(_FOUND_VAR_UPPER ${_NAME_UPPER}_FOUND) + set(_FOUND_VAR_MIXED ${_NAME}_FOUND) + if(FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_MIXED OR FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_UPPER) + set(_FOUND_VAR ${FPHSA_FOUND_VAR}) + else() + message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_FOUND_VAR_MIXED}\" and \"${_FOUND_VAR_UPPER}\" are valid names.") + endif() + else() + set(_FOUND_VAR ${_NAME_UPPER}_FOUND) + endif() + + # collect all variables which were not found, so they can be printed, so the + # user knows better what went wrong (#6375) + set(MISSING_VARS "") + set(DETAILS "") + # check if all passed variables are valid + set(FPHSA_FOUND_${_NAME} TRUE) + foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) + if(NOT ${_CURRENT_VAR}) + set(FPHSA_FOUND_${_NAME} FALSE) + string(APPEND MISSING_VARS " ${_CURRENT_VAR}") + else() + string(APPEND DETAILS "[${${_CURRENT_VAR}}]") + endif() + endforeach() + if(FPHSA_FOUND_${_NAME}) + set(${_NAME}_FOUND TRUE) + set(${_NAME_UPPER}_FOUND TRUE) + else() + set(${_NAME}_FOUND FALSE) + set(${_NAME_UPPER}_FOUND FALSE) + endif() + + # component handling + unset(FOUND_COMPONENTS_MSG) + unset(MISSING_COMPONENTS_MSG) + + if(FPHSA_HANDLE_COMPONENTS) + foreach(comp ${${_NAME}_FIND_COMPONENTS}) + if(${_NAME}_${comp}_FOUND) + + if(NOT DEFINED FOUND_COMPONENTS_MSG) + set(FOUND_COMPONENTS_MSG "found components:") + endif() + string(APPEND FOUND_COMPONENTS_MSG " ${comp}") + + else() + + if(NOT DEFINED MISSING_COMPONENTS_MSG) + set(MISSING_COMPONENTS_MSG "missing components:") + endif() + string(APPEND MISSING_COMPONENTS_MSG " ${comp}") + + if(${_NAME}_FIND_REQUIRED_${comp}) + set(${_NAME}_FOUND FALSE) + string(APPEND MISSING_VARS " ${comp}") + endif() + + endif() + endforeach() + set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") + string(APPEND DETAILS "[c${COMPONENT_MSG}]") + endif() + + # version handling: + set(VERSION_MSG "") + set(VERSION_OK TRUE) + + # check with DEFINED here as the requested or found version may be "0" + if (DEFINED ${_NAME}_FIND_VERSION) + if(DEFINED ${FPHSA_VERSION_VAR}) + set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) + + if(${_NAME}_FIND_VERSION_EXACT) # exact version required + # count the dots in the version string + string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}") + # add one dot because there is one dot more than there are components + string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) + if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) + # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT + # is at most 4 here. Therefore a simple lookup table is used. + if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) + set(_VERSION_REGEX "[^.]*") + elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) + set(_VERSION_REGEX "[^.]*\\.[^.]*") + elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) + set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") + else () + set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") + endif () + string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}") + unset(_VERSION_REGEX) + if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) + set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") + set(VERSION_OK FALSE) + else () + set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") + endif () + unset(_VERSION_HEAD) + else () + if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION) + set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") + set(VERSION_OK FALSE) + else () + set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") + endif () + endif () + unset(_VERSION_DOTS) + + else() # minimum version specified: + if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION) + set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") + set(VERSION_OK FALSE) + else () + set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") + endif () + endif() + + else() + + # if the package was not found, but a version was given, add that to the output: + if(${_NAME}_FIND_VERSION_EXACT) + set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") + else() + set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") + endif() + + endif() + else () + # Check with DEFINED as the found version may be 0. + if(DEFINED ${FPHSA_VERSION_VAR}) + set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") + endif() + endif () + + if(VERSION_OK) + string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") + else() + set(${_NAME}_FOUND FALSE) + endif() + + + # print the result: + if (${_NAME}_FOUND) + FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") + else () + + if(FPHSA_CONFIG_MODE) + _FPHSA_HANDLE_FAILURE_CONFIG_MODE() + else() + if(NOT VERSION_OK) + set(RESULT_MSG) + if (_FIRST_REQUIRED_VAR) + string (APPEND RESULT_MSG "found ${${_FIRST_REQUIRED_VAR}}") + endif() + if (COMPONENT_MSG) + if (RESULT_MSG) + string (APPEND RESULT_MSG ", ") + endif() + string (APPEND RESULT_MSG "${FOUND_COMPONENTS_MSG}") + endif() + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (${RESULT_MSG})") + else() + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") + endif() + endif() + + endif () + + set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) + set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) +endfunction() diff --git a/plugins/damaris/cmake/FindPackageMessage.cmake b/plugins/damaris/cmake/FindPackageMessage.cmake new file mode 100644 index 000000000..0628b9816 --- /dev/null +++ b/plugins/damaris/cmake/FindPackageMessage.cmake @@ -0,0 +1,48 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindPackageMessage +------------------ + +.. code-block:: cmake + + find_package_message( "message for user" "find result details") + +This function is intended to be used in FindXXX.cmake modules files. +It will print a message once for each unique find result. This is +useful for telling the user where a package was found. The first +argument specifies the name (XXX) of the package. The second argument +specifies the message to display. The third argument lists details +about the find result so that if they change the message will be +displayed again. The macro also obeys the QUIET argument to the +find_package command. + +Example: + +.. code-block:: cmake + + if(X11_FOUND) + find_package_message(X11 "Found X11: ${X11_X11_LIB}" + "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") + else() + ... + endif() +#]=======================================================================] + +function(find_package_message pkg msg details) + # Avoid printing a message repeatedly for the same find result. + if(NOT ${pkg}_FIND_QUIETLY) + string(REPLACE "\n" "" details "${details}") + set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) + if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") + # The message has not yet been printed. + message(STATUS "${msg}") + + # Save the find details in the cache to avoid printing the same + # message again. + set("${DETAILS_VAR}" "${details}" + CACHE INTERNAL "Details about finding ${pkg}") + endif() + endif() +endfunction() diff --git a/plugins/damaris/cmake/SelectLibraryConfigurations.cmake b/plugins/damaris/cmake/SelectLibraryConfigurations.cmake new file mode 100644 index 000000000..4c0e9a8c0 --- /dev/null +++ b/plugins/damaris/cmake/SelectLibraryConfigurations.cmake @@ -0,0 +1,80 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +SelectLibraryConfigurations +--------------------------- + +.. code-block:: cmake + + select_library_configurations(basename) + +This macro takes a library base name as an argument, and will choose +good values for the variables + +:: + + basename_LIBRARY + basename_LIBRARIES + basename_LIBRARY_DEBUG + basename_LIBRARY_RELEASE + +depending on what has been found and set. + +If only ``basename_LIBRARY_RELEASE`` is defined, ``basename_LIBRARY`` will +be set to the release value, and ``basename_LIBRARY_DEBUG`` will be set +to ``basename_LIBRARY_DEBUG-NOTFOUND``. If only ``basename_LIBRARY_DEBUG`` +is defined, then ``basename_LIBRARY`` will take the debug value, and +``basename_LIBRARY_RELEASE`` will be set to ``basename_LIBRARY_RELEASE-NOTFOUND``. + +If the generator supports configuration types, then ``basename_LIBRARY`` +and ``basename_LIBRARIES`` will be set with debug and optimized flags +specifying the library to be used for the given configuration. If no +build type has been set or the generator in use does not support +configuration types, then ``basename_LIBRARY`` and ``basename_LIBRARIES`` +will take only the release value, or the debug value if the release one +is not set. +#]=======================================================================] + +# This macro was adapted from the FindQt4 CMake module and is maintained by Will +# Dicharry . + +macro(select_library_configurations basename) + if(NOT ${basename}_LIBRARY_RELEASE) + set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.") + endif() + if(NOT ${basename}_LIBRARY_DEBUG) + set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.") + endif() + + get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND + NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND + ( _isMultiConfig OR CMAKE_BUILD_TYPE ) ) + # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for + # single-config generators, set optimized and debug libraries + set( ${basename}_LIBRARY "" ) + foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE ) + list( APPEND ${basename}_LIBRARY optimized "${_libname}" ) + endforeach() + foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG ) + list( APPEND ${basename}_LIBRARY debug "${_libname}" ) + endforeach() + elseif( ${basename}_LIBRARY_RELEASE ) + set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) + elseif( ${basename}_LIBRARY_DEBUG ) + set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} ) + else() + set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND") + endif() + + set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" ) + + if( ${basename}_LIBRARY ) + set( ${basename}_FOUND TRUE ) + endif() + + mark_as_advanced( ${basename}_LIBRARY_RELEASE + ${basename}_LIBRARY_DEBUG + ) +endmacro() diff --git a/plugins/damaris/damaris.cxx b/plugins/damaris/damaris.cxx new file mode 100644 index 000000000..4222d9c5c --- /dev/null +++ b/plugins/damaris/damaris.cxx @@ -0,0 +1,203 @@ +/******************************************************************************* + * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2024 National Institute for Research in Digital Science and Technology (Inria) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "damaris_cfg.h" +#include "damaris_wrapper.h" +#include "damaris_api_call_handler.h" + +namespace { + +using PDI::Datatype_sptr; +using PDI::Context; +using PDI::Error; +using PDI::Plugin; +using PDI::Ref; +using PDI::Ref_w; +using PDI::Ref_r; +using PDI::to_string; + +using std::get; +using std::pair; +using std::list; +using std::string; +using std::unique_ptr; +using std::unordered_map; +using std::unordered_set; + +using namespace PDI; +using namespace damaris_pdi; + +class damaris_plugin: public Plugin { + + Damaris_cfg m_config; + Damaris_api_call_handler m_event_handler; + + unique_ptr m_damaris; + + static pair, unordered_set> dependencies() + { + return {{"mpi"}, {"mpi"}}; + } + + list multi_expose_transaction_dataname; + //list multi_expose_transaction_dataref; + +public: + + damaris_plugin(Context& ctx, PC_tree_t config) + : Plugin{ctx} + , m_config{ctx, config} + , m_event_handler{m_config.xml_config_object(), m_config.communicator()} + { + multi_expose_transaction_dataname.clear(); + //multi_expose_transaction_dataref.clear(); + + ctx.callbacks().add_data_callback([this](const std::string& name, Ref ref) { this->data(name, ref); }); + ctx.callbacks().add_event_callback([this](const std::string& name) { this->event(name); }); + + ctx.logger().info("Plugin loaded successfully"); + /* + TODO: issue to handle + if (!m_config.init_on_event() && m_config.communicator()) { + MPI_Comm comm = *(static_cast(Ref_r{m_config.communicator().to_ref(context())}.get())); + //context().logger().info("communicator `{}'", m_config.communicator().to_string(context())); + + m_damaris.reset(new Damaris_wrapper{context(), m_config.xml_config_object().c_str(), comm}); + context().logger().info("Plugin initialized successfully"); + }*/ + } + + void data(const std::string& name, Ref ref) + { + context().logger().info("data `{}' has been exposed", name); + + //Update damaris parameters + if(m_config.is_needed_metadata(name)){ + std::unordered_map> updatable_parameters = m_config.get_updatable_parameters(context()); + + std::string int_numbers_types[] = {"short", "int", "integer"}; + std::string real_numbers_types[] = {"float", "real", "double"}; + + std::string prm_name_concat = ""; + for(auto prm_update_info : updatable_parameters) { + auto prm_name = prm_update_info.first; + auto update_info = prm_update_info.second; + { + std::string prm_value = update_info.first; + std::string prm_type = update_info.second; + + void* prm_value_buffer; + size_t prm_buffer_size; + if(std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prm_type)) { + int prm_long_value = std::atoi(prm_value.c_str()); + prm_value_buffer = &prm_long_value; + prm_buffer_size = sizeof(int); + + int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), prm_value_buffer, prm_buffer_size); + } + else if(std::find(std::begin(real_numbers_types), std::end(real_numbers_types), prm_type)) { + double prm_dbl_value = std::atof(prm_value.c_str()); + prm_value_buffer = &prm_dbl_value; + prm_buffer_size = sizeof(double); + + int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), prm_value_buffer, prm_buffer_size); + } + else { + std::string prm_string_value = prm_value; + prm_value_buffer = &prm_string_value; + prm_buffer_size = sizeof(std::string); + + int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), prm_value_buffer, prm_buffer_size); + } + } + + prm_name_concat.append(prm_name + ", "); + m_config.reset_parameter_depends_on(prm_name); + } + prm_name_concat.pop_back(); + prm_name_concat.pop_back(); + context().logger().info("data `{}' Is a needed metadata for the evaluation of parameters {}", name, prm_name_concat); + } + else {//Handle other situations... + multi_expose_transaction_dataname.emplace_back(name); + //multi_expose_transaction_dataref.emplace_back(ref); + } + + //In Situ + } + + void event(const std::string& event_name) + { + context().logger().info("event `{}' has been triggered", event_name); + + if(m_event_handler.is_damaris_api_call_event(event_name)){ + + context().logger().info("is_damaris_api_call_event ( `{}' ) = TRUE", event_name); + m_event_handler.damaris_api_call_event(context(), m_damaris, event_name, multi_expose_transaction_dataname); + } + else {//Non Damaris call event + + } + } + + ~damaris_plugin() + { + multi_expose_transaction_dataname.clear(); + //multi_expose_transaction_dataref.clear(); + context().logger().info("Closing plugin"); + } + + + /** Pretty name for the plugin that will be shown in the logger + * + * \return pretty name of the plugin + */ + static std::string pretty_name() { return "Damaris"; } + +}; // class damaris_plugin + +} // namespace + +PDI_PLUGIN(damaris) \ No newline at end of file diff --git a/plugins/damaris/damaris_api_call_handler.cxx b/plugins/damaris/damaris_api_call_handler.cxx new file mode 100644 index 000000000..5560ef352 --- /dev/null +++ b/plugins/damaris/damaris_api_call_handler.cxx @@ -0,0 +1,454 @@ +/******************************************************************************* + * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2024 National Institute for Research in Digital Science and Technology (Inria) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include +#include "damaris_api_call_handler.h" + +using PDI::Context; +using PDI::Ref; +using PDI::Ref_w; +using PDI::Ref_r; +using std::unordered_map; +using std::map; +using std::unordered_set; +using std::list; +using std::string; +using std::unique_ptr; + + +namespace damaris_pdi { + +Damaris_api_call_handler::Damaris_api_call_handler(std::string cfg_object) +{ + xml_config_object = cfg_object; +} + +Damaris_api_call_handler::Damaris_api_call_handler(std::string cfg_object, PDI::Expression comm) +{ + xml_config_object = cfg_object; + m_communicator = comm; +} + +bool Damaris_api_call_handler::is_damaris_api_call_event(std::string event_name) +{ + for(auto event : event_names) { + if(event_name == event.second) + return true; + } + return false; +} + + +void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptr &m_damaris, std::string event_name, list expose_dataname) +{ + //************************************************************ */ + //Events : Damaris Initialize and Damaris Start + //************************************************************ */ + if(event_name == event_names.at(Event_type::DAMARIS_INITIALIZE) + || event_name == event_names.at(Event_type::DAMARIS_INITIALIZE_ALIAS)) { + damaris_pdi_init(ctx, m_damaris, xml_config_object.c_str()); + } + else if(event_name == event_names.at(Event_type::DAMARIS_START)) { + // DAMARIS_START + // The following call starts the servers. Servers will run inside this + // function until they are asked to stop by clients. On clients, + // is_client will be set to 1 (0 on servers). + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_start() before plugin initialization (`{}')", event_name); + return; + } + std::string arg1_name; + int is_client; + int err = m_damaris->damaris_pdi_start(&is_client); + m_damaris->set_is_client(is_client); + ctx.logger().info("------------------- CALLED damaris_pdi_start Return IS_CLIENT = '{}')", is_client); + + int arg_pos = 0; + int nb_awaited_args = 1; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1 && strcmp("is_client", it->c_str()) == 0) + { + ctx.logger().info("------------------- CALLED damaris_pdi_start {} = '{}')", arg1_name, is_client); + + int *inout_is_client; + PDI_access(it->c_str(), (void**)&inout_is_client, PDI_INOUT); + *inout_is_client = is_client; + arg1_name = it->c_str(); + } + else + //if(nb_awaited_args <= arg_pos) + break; + } + } + + //************************************************************ */ + //Events that rely on Multi expose + //************************************************************ */ + // DAMARIS_PARAMETER_GET + else if(event_name == event_names.at(Event_type::DAMARIS_PARAMETER_GET)) { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_parameter_get() before plugin initialization (`{}')", event_name); + return; + } + + //Retrive parameters! sent via Multi expose, the two last sent data + char* var_name; std::string arg1_name; + void* buffer; std::string arg2_name; + unsigned int* size; std::string arg3_name; + int arg_pos = 0; + int nb_awaited_args = 3; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) + { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } + else if (arg_pos == 2){ + PDI_access(it->c_str(), (void**)&buffer, PDI_INOUT); + arg2_name = it->c_str(); + } + else if (arg_pos == 3){ + PDI_access(it->c_str(), (void**)&size, PDI_IN); + arg3_name = it->c_str(); + } + else + //if(nb_awaited_args <= arg_pos) + break; + } + + ctx.logger().info("------------------- CALLING damaris_pdi_parameter_get arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, *(int *)buffer, arg3_name, *(int*)size); + int err = m_damaris->damaris_pdi_parameter_get((const char*)var_name, (void *) buffer, *(int*)size); + } + // DAMARIS_PARAMETER_SET + else if(event_name == event_names.at(Event_type::DAMARIS_PARAMETER_SET)) { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_parameter_set() before plugin initialization (`{}')", event_name); + return; + } + + //Retrive parameters! sent via Multi expose, the three last sent data + char* var_name; std::string arg1_name; + void* buffer; std::string arg2_name; + unsigned int* size; std::string arg3_name; + int arg_pos = 0; + int nb_awaited_args = 3; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) + { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } + else if (arg_pos == 2){ + PDI_access(it->c_str(), (void**)&buffer, PDI_IN); + arg2_name = it->c_str(); + } + else if (arg_pos == 3){ + PDI_access(it->c_str(), (void**)&size, PDI_IN); + arg3_name = it->c_str(); + } + else + //if(nb_awaited_args <= arg_pos) + break; + } + + ctx.logger().info("------------------- CALLING damaris_pdi_parameter_set arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, *(int *)buffer, arg3_name, *(int*)size); + int err = m_damaris->damaris_pdi_parameter_set((const char*)var_name, (const void *) buffer, *(int*)size); + } + // DAMARIS_CLIENT_COMM_GET + else if(event_name == event_names.at(Event_type::DAMARIS_CLIENT_COMM_GET)) { + + MPI_Comm client_comm; std::string arg1_name; + + int err = m_damaris->damaris_pdi_client_comm_get(&client_comm); + + int arg_pos = 0; + int nb_awaited_args = 1; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) + { + static MPI_Comm* comm; + PDI_access(it->c_str(), (void**)&comm, PDI_INOUT); + *comm = client_comm;//Update the value + arg1_name = it->c_str(); + } + else + //if(nb_awaited_args <= arg_pos) + break; + } + //ctx.logger().info("------------------- CALLING damaris_pdi_client_comm_get arg_pos({}==='{}')", arg1_name, client_comm); + } + // DAMARIS_SET_POSITION + else if(event_name == event_names.at(Event_type::DAMARIS_SET_POSITION)) { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_set_position() before plugin initialization (`{}')", event_name); + return; + } + + //Retrive parameters! sent via Multi expose, the two last sent data + char* var_name; std::string arg1_name; + int64_t* position; std::string arg2_name; + int arg_pos = 0; + int nb_awaited_args = 2; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) + { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } + else if (arg_pos == 2){ + PDI_access(it->c_str(), (void**)&position, PDI_IN); + arg2_name = it->c_str(); + } + else + //if(nb_awaited_args <= arg_pos) + break; + } + + ctx.logger().info("------------------- CALLING damaris_pdi_set_position arg_pos({}==='{}', {}==={})", arg1_name, var_name, arg2_name, *(int64_t*)position); + int err = m_damaris->damaris_pdi_set_position((const char*)var_name, (const int64_t*)position); + } + // DAMARIS_WRITE + else if(event_name == event_names.at(Event_type::DAMARIS_WRITE)) { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_write() before plugin initialization (`{}')", event_name); + return; + } + + //Retrive parameters! sent via Multi expose, the two last sent data + char* var_name; std::string arg1_name; + void* data; std::string arg2_name; + int arg_pos = 0; + int nb_awaited_args = 2; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) + { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } + else if (arg_pos == 2){ + PDI_access(it->c_str(), (void**)&data, PDI_IN); + arg2_name = it->c_str(); + } + else + //if(nb_awaited_args <= arg_pos) + break; + } + + ctx.logger().info("------------------- CALLING damaris_pdi_write arg_pos({}==='{}', {}==={})", arg1_name, var_name, arg2_name, *(int*)data); + int err = m_damaris->damaris_pdi_write((const char*)var_name, (void*)data); + } + // DAMARIS_SET_BLOCK_POSITION + else if(event_name == event_names.at(Event_type::DAMARIS_SET_BLOCK_POSITION)) { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_set_position() before plugin initialization (`{}')", event_name); + return; + } + + //Retrive parameters! sent via Multi expose, the three last sent data + char* var_name; std::string arg1_name; + int32_t* block; std::string arg2_name; + int64_t* position; std::string arg3_name; + int arg_pos = 0; + int nb_awaited_args = 3; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) + { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } + else if (arg_pos == 2){ + PDI_access(it->c_str(), (void**)&block, PDI_IN); + arg2_name = it->c_str(); + } + else if (arg_pos == 3){ + PDI_access(it->c_str(), (void**)&position, PDI_IN); + arg3_name = it->c_str(); + } + else + //if(nb_awaited_args <= arg_pos) + break; + } + + ctx.logger().info("------------------- CALLING damaris_pdi_set_block_position arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, (int32_t) *block, arg3_name, *(int64_t*)position); + int err = m_damaris->damaris_pdi_set_block_position((const char*)var_name, (int32_t) *block, (const int64_t*)position); + } + // DAMARIS_WRITE_BLOCK + else if(event_name == event_names.at(Event_type::DAMARIS_WRITE_BLOCK)) { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_write() before plugin initialization (`{}')", event_name); + return; + } + + //Retrive parameters! sent via Multi expose, the three last sent data + char* var_name; std::string arg1_name; + int32_t* block; std::string arg2_name; + void* data; std::string arg3_name; + int arg_pos = 0; + int nb_awaited_args = 3; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) + { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } + else if (arg_pos == 2){ + PDI_access(it->c_str(), (void**)&block, PDI_IN); + arg2_name = it->c_str(); + } + else if (arg_pos == 3){ + PDI_access(it->c_str(), (void**)&data, PDI_IN); + arg3_name = it->c_str(); + } + else + //if(nb_awaited_args <= arg_pos) + break; + } + + ctx.logger().info("------------------- CALLING damaris_pdi_write_block arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, (int32_t) *block, arg3_name, *(int*)data); + int err = m_damaris->damaris_pdi_write_block((const char*)var_name, (int32_t) *block, (void*)data); + } + + //************************************************************ */ + //Events : End Iteration / Damaris Stop and Damaris Finalize + //************************************************************ */ + else if (event_name == event_names.at(Event_type::DAMARIS_END_ITERATION)) { + if (m_damaris) { + + ctx.logger().info("Plugin called damaris_end_iteration()"); + int err = m_damaris->damaris_pdi_end_iteration() ; + //iteration++; + + ctx.logger().info("Plugin sent damaris_end_iteration() to Damaris"); + } else { + ctx.logger().warn("Trying to call damaris_end_iteration() before plugin initialization (`{}')", event_name); + } + } + else if(event_name == event_names.at(Event_type::DAMARIS_STOP)) { + // DAMARIS_STOP is called and the Daamris server processes will return from the damaris_start() call + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_strop() before plugin initialization (`{}')", event_name); + return; + } + + int err = m_damaris->damaris_pdi_stop(); + } + else if(event_name == event_names.at(Event_type::DAMARIS_FINALIZE)) { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_strop() before plugin initialization (`{}')", event_name); + return; + } + + int err = m_damaris->damaris_pdi_finalize(); + } + else { + assert(false && "Unexpected damaris event type"); + } +} + + +void Damaris_api_call_handler::damaris_pdi_init(Context& ctx, unique_ptr &m_damaris, const char* damaris_xml_object) +{ + if (!m_damaris) { + MPI_Comm comm = MPI_COMM_WORLD; + if (m_communicator) { + //comm = static_cast(m_communicator.to_string(ctx)); + //comm = *(static_cast(Ref_r{m_communicator.to_ref(ctx)}.get())); + } + + // This creator method calls damaris_initialize(), passin in an XML file, so if we want to + // pre-fill our xml file, we need to do this somehow before: + // PDI_expose("mpi_comm", &main_comm, PDI_INOUT); + + m_damaris.reset(new Damaris_wrapper{ctx, damaris_xml_object, comm}); + + ctx.logger().info("Plugin initialized successfully"); + } +} + +} // namespace damaris_pdi diff --git a/plugins/damaris/damaris_api_call_handler.h b/plugins/damaris/damaris_api_call_handler.h new file mode 100644 index 000000000..24c6604d2 --- /dev/null +++ b/plugins/damaris/damaris_api_call_handler.h @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2024 National Institute for Research in Digital Science and Technology (Inria) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#ifndef DAMARIS_API_CALL_HANDLER_H_ +#define DAMARIS_API_CALL_HANDLER_H_ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "damaris_wrapper.h" + +using PDI::Context; +using std::list; +using std::string; +using std::unique_ptr; + +namespace damaris_pdi { + +enum class Event_type { + DAMARIS_INITIALIZE = 0 + , DAMARIS_INITIALIZE_ALIAS = 1 + , DAMARIS_START = 2 + , DAMARIS_SET_POSITION = 3 + , DAMARIS_SET_BLOCK_POSITION = 4 + , DAMARIS_WRITE = 5 + , DAMARIS_WRITE_BLOCK = 6 + , DAMARIS_CLIENT_COMM_GET = 7 + , DAMARIS_PARAMETER_SET = 8 + , DAMARIS_PARAMETER_GET = 9 + , DAMARIS_END_ITERATION = 10 + , DAMARIS_STOP = 11 + , DAMARIS_FINALIZE = 12 +}; + +const std::unordered_map event_names = { + {Event_type::DAMARIS_INITIALIZE, "initialize"} + ,{Event_type::DAMARIS_INITIALIZE_ALIAS, "init"} + ,{Event_type::DAMARIS_START, "damaris_start"} + ,{Event_type::DAMARIS_END_ITERATION, "damaris_end_iteration"} + ,{Event_type::DAMARIS_SET_POSITION, "damaris_set_position"} + ,{Event_type::DAMARIS_SET_BLOCK_POSITION, "damaris_set_block_position"} + ,{Event_type::DAMARIS_WRITE, "damaris_write"} + ,{Event_type::DAMARIS_WRITE_BLOCK, "damaris_write_block"} + ,{Event_type::DAMARIS_CLIENT_COMM_GET, "damaris_client_comm_get"} + ,{Event_type::DAMARIS_PARAMETER_SET, "damaris_parameter_set"} + ,{Event_type::DAMARIS_PARAMETER_GET, "damaris_parameter_get"} + ,{Event_type::DAMARIS_STOP, "damaris_stop"} + ,{Event_type::DAMARIS_FINALIZE, "finalize"} +}; + +class Damaris_api_call_handler +{ + + std::string xml_config_object; + PDI::Expression m_communicator; +public: + Damaris_api_call_handler(std::string cfg_object, PDI::Expression comm); + Damaris_api_call_handler(std::string cfg_object); + + bool is_damaris_api_call_event(std::string event_name); + + void damaris_api_call_event(Context& ctx, unique_ptr &m_damaris, std::string event_name, list expose_dataname); + +private: + void damaris_pdi_init(Context& ctx, unique_ptr &m_damaris, const char* damaris_xml_object) ; +}; // class Damaris_api_call_handler + +} // namespace damaris_pdi + +#endif // DAMARIS_API_CALL_HANDLER_H_ \ No newline at end of file diff --git a/plugins/damaris/damaris_cfg.cxx b/plugins/damaris/damaris_cfg.cxx new file mode 100644 index 000000000..ef288fab4 --- /dev/null +++ b/plugins/damaris/damaris_cfg.cxx @@ -0,0 +1,1117 @@ +/******************************************************************************* + * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2024 National Institute for Research in Digital Science and Technology (Inria) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "damaris_cfg.h" + +using PDI::Context; +using PDI::each; +using PDI::opt_each; +using PDI::Config_error; +using PDI::Value_error; +using PDI::Expression; +using PDI::Impl_error; +using PDI::Ref; +using PDI::Ref_w; +using PDI::Ref_r; +using PDI::len; +using PDI::to_long; +using PDI::to_double; +using PDI::to_string; +using std::function; +using std::list; +using std::map; +using std::string; +using std::unique_ptr; +using std::unordered_map; + + + +namespace damaris_pdi { + + /** + * This variable contains Damaris xml config nested groups, with dataset elements to display in the XML config + * It is possible to have nested groups, but in most of the cases, + * we just have root groups containing directly the dataset elements + */ + std::vector root_groups_xml; + + // Array to store the nested groups names + const unsigned max_nested_groups = 5; + std::string nested_groups_names[max_nested_groups]; + char ds_elt_full_name_delimiter = '/'; + + void retrive_nested_groups(std::string& dataset_elt_full_name, char delimiter, std::string nested_groups_names[], unsigned& index); + template + void insert_dataset_elts_to_group(DS_TYPE varxml, std::string nested_groups_names[], unsigned index); + //void insert_dataset_elts_to_group(damaris::model::DamarisVarXML varxml, std::string nested_groups_names[], unsigned index); + + +// This constructor is called on the construction of the damaris_plugin struct/object +// This code is a mapping of the Damaris src/model/Model.xsd schema to PDI YAML +// The mapping should allow us to recreate a Damaris XML object from what is present +// in the YML file +Damaris_cfg::Damaris_cfg(Context& ctx, PC_tree_t tree) + :m_communicator{"MPI_COMM_WORLD"} +{ + init_xml_config_object(); + + each(tree, [&](PC_tree_t key_tree, PC_tree_t value) { + string key = to_string(key_tree); + if (key == "architecture") { + //default_when = to_string(value); + parse_architecture_tree(ctx, value); + } + else if (key == "communicator") { + + m_communicator = to_string(value); + if (!m_communicator) { + throw Config_error{key_tree, "no MPI communicator set", key}; + } + } + else if (key == "init_on_event") { + m_init_on_event = to_long(value);// Default = true + } + else if (key == "parameters") { + parse_parameters_tree(ctx, value); + } + else if (key == "datasets") { + parse_datasets_tree(ctx, value); + } + else if (key == "layouts") { + parse_layouts_tree(ctx, value); + } + else if (key == "meshes") { + parse_meshes_tree(ctx, value); + } + else if (key == "storages") { + parse_storages_tree(ctx, value); + } + else if (key == "paraview") { + parse_paraview_tree(ctx, value); + } + else if (key == "pyscript") { + parse_pyscript_tree(ctx, value); + } + /*else { + throw Config_error{key_tree, "Unknown key in Damaris configuration: `{}'", key}; + }*/ + }); + + parse_log_tree(ctx, tree); + + //Insert grouped dataset elements + for (int root_group_id = 0; root_group_id < root_groups_xml.size(); root_group_id++) { + damaris::model::DamarisGroupXML root_gp_xml = root_groups_xml[root_group_id]; + + m_groups.emplace(root_gp_xml.get_name() , root_gp_xml) ; + std::map find_replace_map = + { + {"_DATASET_ELEMENT_REGEX_", root_gp_xml.ReturnXMLForGroup() + "\n_DATASET_ELEMENT_REGEX_"} + }; + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } + + //CleanUp XML OBJECT + std::map find_replace_map = + { + {"_DATASET_ELEMENT_REGEX_", ""} + ,{"_STORAGE_ELEMENT_REGEX_", ""} + ,{"_PLUGINS_REGEX_", ""} + ,{"_SCRIPTS_REGEX_", ""} + }; + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + + m_xml_config_object = damarisXMLModifyModel.GetConfigString(); + + printf("-------------------------------------------------------XML OBJECT MODIFIED----------------------------------------------\n%s", damarisXMLModifyModel.GetConfigString().c_str()); +} + +void Damaris_cfg::parse_architecture_tree(Context& ctx, PC_tree_t arch_tree){ + + std::map find_replace_map = {}; + + //simulation name & Buffer + std::string sim_name = "damaris_pdi_simu"; + PC_tree_t sim_name_tree = PC_get(arch_tree, ".sim_name"); + if(!PC_status(sim_name_tree)) + { + sim_name = to_string(sim_name_tree); + } + //Buffer + std::string buffer_name = sim_name + "_buffer"; + long buffer_size = 67108864; + PC_tree_t buffer_size_tree = PC_get(arch_tree, ".buffer_size"); + if(!PC_status(buffer_size_tree)) + { + buffer_size = to_long(buffer_size_tree); + } + find_replace_map.insert({ + {"_SIM_NAME_",sim_name} + ,{"_SHMEM_BUFFER_BYTES_REGEX_", std::to_string(buffer_size)} + ,{"_SHMEM_NAME_", buffer_name} + }); + + //domains + int m_arch_domains = 1; + PC_tree_t domains_tree = PC_get(arch_tree, ".domains"); + if(!PC_status(domains_tree)) + { + m_arch_domains = to_long(domains_tree); + } + find_replace_map.insert({"_DOMAINS_REGEX_", std::to_string(m_arch_domains)}); + + //dedicated + int m_dc_cores_pernode = 0; + int m_dc_nodes = 0; + PC_tree_t arch_dedicated_tree = PC_get(arch_tree, ".dedicated"); + if(!PC_status(arch_dedicated_tree)) + { + int nb_subkey_dc = len(arch_dedicated_tree); + + for (int subkey_dc_id = 0; subkey_dc_id < nb_subkey_dc; subkey_dc_id++) { + string key_str = to_string(PC_get(arch_dedicated_tree, "{%d}", subkey_dc_id)); + + if (key_str == "core") { + m_dc_cores_pernode = to_long(PC_get(arch_dedicated_tree, ".core")); + } else if (key_str == "node") { + m_dc_nodes = to_long(PC_get(arch_dedicated_tree, ".node")); + } + } + } + find_replace_map.insert( + { + {"_DC_REGEX_", std::to_string(m_dc_cores_pernode)} + ,{"_DN_REGEX_", std::to_string(m_dc_nodes)} + } + ); + + //placement not yet used + PC_tree_t arch_placement_tree = PC_get(arch_tree, ".placement"); + if(!PC_status(arch_placement_tree)) + { + int nb_subkey_dc = len(arch_placement_tree); + + for (int subkey_pl_id = 0; subkey_pl_id < nb_subkey_dc; subkey_pl_id++) { + string key_str = to_string(PC_get(arch_placement_tree, "{%d}", subkey_pl_id)); + + if (key_str == "start") { + m_placement_start = to_long(PC_get(arch_placement_tree, ".start")); + } + else if (key_str == "stride") { + m_placement_stride = to_long(PC_get(arch_placement_tree, ".stride")); + } + else if (key_str == "blocksize") { + m_placement_blocksize = to_long(PC_get(arch_placement_tree, ".blocksize")); + } + else if (key_str == "mask") { + m_placement_mask_str = to_string(PC_get(arch_placement_tree, ".mask")); + } + } + //TODO: find_replace_map.insert( ); + } + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); +} + +void Damaris_cfg::parse_parameters_tree(Context& ctx, PC_tree_t parameters_tree_list) +{ + opt_each(parameters_tree_list, [&](PC_tree_t parameters_tree) {//each parameters (list of parameter) + each(parameters_tree, [&](PC_tree_t prm_tree_key, PC_tree_t parameter_tree) {//each parameter + + damaris::model::DamarisParameterXML prmxml{} ; + std::map find_replace_map = {}; + std::unordered_map depends_on_metadata; + bool is_dependent = false; + + each(parameter_tree, [&](PC_tree_t prm_key, PC_tree_t value) {//parameter info + std::string key = to_string(prm_key); + + if (key == "name") { + prmxml.param_name_ = to_string(value); + } + else if (key == "type") { + prmxml.param_datatype_ = to_string(value); + } + else if (key == "value") { + prmxml.param_value_ = to_string(value); + m_parameter_expression.emplace(prmxml.param_name_, to_string(value)); + } + else if (key == "depends_on") { + is_dependent = true; + if (!PC_status(PC_get(value, "[0]"))) {//Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter + //int idx = 0; + each(value, [&](PC_tree_t metadata_name_tree) { + std::string metadata_name = to_string(metadata_name_tree); + + depends_on_metadata.insert( + {metadata_name, false} + ); + }); + } + else {//d1 + std::string metadata_name = to_string(value); + //depends_on_metadata[metadata_name] = false; + depends_on_metadata.insert( + {metadata_name, false} + ); + ctx.logger().info("--------------------------------------------------------------------------------PARAMETER {} depends on {}", prmxml.param_name_, metadata_name); + } + + + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized parameter map string: " << key << std::endl ; + } + }); + //m_parameter_expression.emplace(prmxml.param_name_, prmxml.param_value_); + m_parameter_depends_on.emplace(prmxml.param_name_, depends_on_metadata); + //set default value if depend on metadata + std::string numbers_types[] = {"short", "int", "integer", "float", "real", "double"}; + if(is_dependent && std::find(std::begin(numbers_types), std::end(numbers_types), prmxml.param_datatype_)) { + prmxml.param_value_ = "1"; //"0" + } + else { + ///??? + } + + m_parameters.emplace(prmxml.param_name_ , prmxml) ; + find_replace_map.insert( + {"_DATASET_ELEMENT_REGEX_", prmxml.ReturnXMLForParameter() + "\n_DATASET_ELEMENT_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + }); + }); +} + +void Damaris_cfg::parse_datasets_tree(Context& ctx, PC_tree_t datasets_tree_list) +{ + opt_each(datasets_tree_list, [&](PC_tree_t datasets_tree) {//each datasets (list of dataset) + each(datasets_tree, [&](PC_tree_t ds_tree_key, PC_tree_t dataset_tree) {//each dataset + + damaris::model::DamarisVarXML vxml{} ; + std::map find_replace_map = {}; + unsigned name_index = 0; + std::string dataset_elt_full_name; + + each(dataset_tree, [&](PC_tree_t ds_key, PC_tree_t value) {//dataset info + std::string key = to_string(ds_key); + + int tf; // 0 is false, anything else is true + if (key == "name") { + dataset_elt_full_name = to_string(value); + retrive_nested_groups(dataset_elt_full_name + , ds_elt_full_name_delimiter + , nested_groups_names + , name_index); + + vxml.var_name_ = nested_groups_names[name_index-1]; //to_string(value); + } + else if (key == "layout") { + vxml.layout_name_ = to_string(value); + } + else if (key == "mesh") { + vxml.mesh_ = to_string(value); + } + else if (key == "centering") { + std::string t_centering = to_string(value); + vxml.set_centering(t_centering) ; + } + else if (key == "storage") { + vxml.store_ = to_string(value); + } + else if (key == "script") { + vxml.script_ = to_string(value); + } + else if (key == "unit") { + vxml.unit_ = to_string(value); + } + else if (key == "select_mem") { + vxml.select_mem_ = to_string(value); + } + else if (key == "select_file") { + vxml.select_file_ = to_string(value); + } + else if (key == "select_subset") { + vxml.select_subset_ = to_string(value); + } + else if (key == "ref") { + vxml.ref_ = to_string(value); + } + else if (key == "type") { + std::string in_type = to_string(value); + vxml.set_type( in_type ); + } + else if (key == "comment") { + vxml.comment_ = to_string(value); + } + else if (key == "visualizable") { + PC_bool(value, &tf); + vxml.visualizable_ = (tf == 0) ? false : true ; + } + else if (key == "time_varying") { + PC_bool(value, &tf); + vxml.time_varying_ = (tf == 0) ? false : true ; + } + else if (key == "enabled") { + PC_bool(value, &tf); + vxml.enabled_ = (tf == 0) ? false : true ; + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized variable map string: " << key << std::endl ; + } + }); + + if(dataset_elt_full_name.empty()) + throw Value_error{"ERROR: damaris_cfg variable name must not be empty"}; + + //m_datasets.emplace(vxml.var_name_ , vxml) ; + m_datasets.emplace(dataset_elt_full_name , vxml) ; + ctx.logger().info("------------------- Parsing damaris Variable '{}' , name_index = {} ", dataset_elt_full_name, name_index); + + if(name_index == 1) { + find_replace_map.insert( + {"_DATASET_ELEMENT_REGEX_", vxml.ReturnXMLForVariable() + "\n_DATASET_ELEMENT_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } + else {//In nested groups + insert_dataset_elts_to_group(vxml, nested_groups_names, name_index); + } + }); + }); +} + +void Damaris_cfg::parse_layouts_tree(Context& ctx, PC_tree_t layouts_tree_list) +{ + opt_each(layouts_tree_list, [&](PC_tree_t layouts_tree) {//each layouts (list of layout) + each(layouts_tree, [&](PC_tree_t lts_key, PC_tree_t layout_tree) {//each layout + + damaris::model::DamarisLayoutXML layoutxml{} ; + std::map find_replace_map = {}; + unsigned name_index = 0; + std::string dataset_elt_full_name; + + each(layout_tree, [&](PC_tree_t lt_key, PC_tree_t value) {//layout info + std::string key = to_string(lt_key); + + int intb; // 0 is false, anything else is true + if (key == "name") { + dataset_elt_full_name = to_string(value); + retrive_nested_groups(dataset_elt_full_name + , ds_elt_full_name_delimiter + , nested_groups_names + , name_index); + + layoutxml.layout_name_ = nested_groups_names[name_index-1]; //to_string(value); + } + else if (key == "type") { + std::string in_datatype = to_string(value); + layoutxml.set_datatype( in_datatype ); + } + else if (key == "dimensions") { + + //Is there a way to determine if an expression is ready to be evaluated? ei, all the conponent have a value + if (!PC_status(PC_get(value, "[0]"))) {//Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter + int nb_layout_dims2; PC_len(value, &nb_layout_dims2); + std::cout << "INFO: damaris_cfg nb_layout_dims has dims2: " << nb_layout_dims2 << std::endl ; + + std::string dims_list = ""; + each(value, [&](PC_tree_t dim) { + dims_list += to_string(dim) + ","; + }); + dims_list.pop_back(); + layoutxml.layout_dimensions_ = dims_list; + } + else {//"d1,d2,d3" for instance, each di an expreession of of Damaris Parameter + layoutxml.layout_dimensions_ = to_string(value); + } + + } + else if (key == "global") { + layoutxml.layout_dims_global_ = to_string(value); + } + else if (key == "ghosts") { + layoutxml.layout_ghosts_ = to_string(value); + } + else if (key == "language") { + std::string in_language = to_string(value); + layoutxml.set_language( in_language ); + } + else if (key == "visualizable") { + PC_bool(value, &intb); + bool in_visualizable = (intb == 0) ? false : true ; + layoutxml.layout_visualizable_ = in_visualizable; + } + else if (key == "comment") { + layoutxml.layout_comment_ = to_string(value); + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized layout map string: " << key << std::endl ; + } + }); + + if(dataset_elt_full_name.empty()) + throw Value_error{"ERROR: damaris_cfg layout name must not be empty"}; + + //m_layouts.emplace(layoutxml.layout_name_ , layoutxml) ; + m_layouts.emplace(dataset_elt_full_name , layoutxml) ; + ctx.logger().info("------------------- Parsing damaris Layout '{}' , name_index = {} ", dataset_elt_full_name, name_index); + + if(name_index == 1) { + find_replace_map.insert( + {"_DATASET_ELEMENT_REGEX_", layoutxml.ReturnXMLForLayout() + "\n_DATASET_ELEMENT_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } + else {//In nested groups + insert_dataset_elts_to_group(layoutxml, nested_groups_names, name_index); + } + }); + }); +} + +void Damaris_cfg::parse_meshes_tree(Context& ctx, PC_tree_t meshes_tree_list) +{ + opt_each(meshes_tree_list, [&](PC_tree_t meshes_tree) {//each meshes (list of mesh) + each(meshes_tree, [&](PC_tree_t meshes_tree_key, PC_tree_t mesh_tree) {//each mesh + + damaris::model::DamarisMeshXML meshxml{} ; + std::map find_replace_map = {}; + unsigned name_index = 0; + std::string dataset_elt_full_name; + + each(mesh_tree, [&](PC_tree_t mesh_tree_key, PC_tree_t value) {//mesh info + std::string key = to_string(mesh_tree_key); + + int tf; // 0 is false, anything else is true + if (key == "name") { + dataset_elt_full_name = to_string(value); + retrive_nested_groups(dataset_elt_full_name + , ds_elt_full_name_delimiter + , nested_groups_names + , name_index); + + //meshxml.set_name(to_string(value)); + meshxml.set_name(nested_groups_names[name_index-1]); + } + else if (key == "type") { + meshxml.set_type(to_string(value)); + } + else if (key == "topology") { + meshxml.set_topology(to_long(value)); + } + else if (key == "coordinates") {//Liste of coordinates + opt_each(value, [&](PC_tree_t coords_tree) {//each meshes (list of mesh) + each(coords_tree, [&](PC_tree_t coord_key, PC_tree_t coord_tree) {//each mesh + std::string coord_name, coord_unit = "", coord_label = "", coord_comment = ""; + + each(coord_tree, [&](PC_tree_t ct_tree_key, PC_tree_t value) {//mesh info + std::string coord_info_key = to_string(ct_tree_key); + + int tf; // 0 is false, anything else is true + if (coord_info_key == "name") { + coord_name = to_string(value); + } else if (coord_info_key == "unit") { + coord_unit = to_string(value); + } else if (coord_info_key == "label") { + coord_label = to_string(value); + } else if (coord_info_key == "comment") { + coord_comment = to_string(value); + } else { + std::cerr << "ERROR: damaris_cfg unrecogognized coord map string: " << key << std::endl ; + } + }); + meshxml.add_coord(coord_name, coord_unit, coord_label, coord_comment); + }); + }); + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized storage map string: " << key << std::endl ; + } + }); + + if(dataset_elt_full_name.empty()) + throw Value_error{"ERROR: damaris_cfg mesh name must not be empty} groups"}; + + //m_meshes.emplace(meshxml.get_name() , meshxml) ; + m_meshes.emplace(meshxml.get_name() , meshxml) ; + ctx.logger().info("------------------- Parsing damaris Mesh '{}' , name_index = {} ", dataset_elt_full_name, name_index); + + if(name_index == 1) { + find_replace_map.insert( + {"_DATASET_ELEMENT_REGEX_", meshxml.ReturnXMLForMesh() + "\n_DATASET_ELEMENT_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } + else {//In nested groups + insert_dataset_elts_to_group(meshxml, nested_groups_names, name_index); + } + }); + }); +} + +void Damaris_cfg::parse_storages_tree(Context& ctx, PC_tree_t storages_tree_list) +{ + opt_each(storages_tree_list, [&](PC_tree_t storages_tree) {//each storages (list of storage) + each(storages_tree, [&](PC_tree_t storagest_key, PC_tree_t storage_tree) {//each storage + + damaris::model::DamarisStoreXML store{} ; + std::map find_replace_map = {}; + + each(storage_tree, [&](PC_tree_t st_key, PC_tree_t value) {//storage info + std::string key = to_string(st_key); + + int tf; // 0 is false, anything else is true + if (key == "name") { + store.store_name_ = to_string(value); + } + else if (key == "type") { + store.store_type_ = to_string(value); + } + else if (key == "file_mode") { + store.store_opt_FileMode_ = to_string(value); + } + else if (key == "files_path") { + store.store_opt_FilesPath_ = to_string(value); + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized storage map string: " << key << std::endl ; + } + }); + m_storages.emplace(store.store_name_ , store) ; + + find_replace_map.insert( + {"_STORAGE_ELEMENT_REGEX_", store.ReturnXMLForStore() + "\n_STORAGE_ELEMENT_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + }); + }); +} + +void Damaris_cfg::parse_paraview_tree(Context& ctx, PC_tree_t paraview_tree) +{ + damaris::model::DamarisParaviewXML paraviewxml{} ; + std::map find_replace_map = {}; + + each(paraview_tree, [&](PC_tree_t lt_key, PC_tree_t value) {//layout info + std::string key = to_string(lt_key); + + int intb; // 0 is false, anything else is true + if (key == "update_frequency") { + int in_update_frequency = to_long(value); + paraviewxml.set_update_frequency( in_update_frequency ); + } + else if (key == "realtime_timestep") { + float in_realtime_timestep = (float) to_double(value); + paraviewxml.set_realtime_timestep( in_realtime_timestep ); + } + else if (key == "end_iteration") { + int in_end_iteration = to_long(value); + paraviewxml.set_end_iteration( in_end_iteration ); + } + else if (key == "write_vtk") { + int in_write_vtk = to_long(value); + paraviewxml.set_write_vtk( in_write_vtk ); + } + else if (key == "write_vtk_binary") { + PC_bool(value, &intb); + bool in_write_vtk_binary = (intb == 0) ? false : true ; + paraviewxml.set_write_vtk_binary( in_write_vtk_binary ); + } + else if (key == "comment") { + std::string in_comment = to_string(value); + paraviewxml.set_comment( in_comment ); + } + else if (key == "scripts" || key == "script") { + + if (!PC_status(PC_get(value, "[0]"))) {//Array //[script1, script2, script3] + int nb_paraview_scripts; PC_len(value, &nb_paraview_scripts); + std::cout << "INFO: damaris_cfg nb paraview scripts: " << nb_paraview_scripts << std::endl ; + + each(value, [&](PC_tree_t script) { + paraviewxml.add_script(to_string(script)); + }); + } + else { + paraviewxml.add_script(to_string(value)); + } + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized paraview map string: " << key << std::endl ; + } + }); + + m_paraview = ¶viewxml ; + + find_replace_map.insert( + {"_PLUGINS_REGEX_", paraviewxml.ReturnXMLForParaview() + "\n_PLUGINS_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); +} + +void Damaris_cfg::parse_pyscript_tree(Context& ctx, PC_tree_t pyscript_tree) +{ + damaris::model::DamarisPyScriptXML pyscriptxml{} ; + std::map find_replace_map = {}; + + each(pyscript_tree, [&](PC_tree_t py_key, PC_tree_t value) {//layout info + std::string key = to_string(py_key); + + int intb; // 0 is false, anything else is true + if (key == "name") { + pyscriptxml.pyscript_name_ = to_string(value); + } + else if (key == "file") { + pyscriptxml.pyscript_file_ = to_string(value); + } + else if (key == "scheduler_file") { + pyscriptxml.scheduler_file_ = to_string(value); + } + else if (key == "execution") { + pyscriptxml.execution_ = to_string(value); + } + else if (key == "language") { + pyscriptxml.language_ = to_string(value); + } + else if (key == "scope") { + pyscriptxml.scope_ = to_string(value); + } + else if (key == "external") { + PC_bool(value, &intb); + bool in_external = (intb == 0) ? false : true ; + pyscriptxml.external_ = in_external; + } + else if (key == "frequency") { + pyscriptxml.frequency_ = to_long(value); + } + else if (key == "nthreads") { + pyscriptxml.nthreads_ = to_long(value); + } + else if (key == "timeout") { + pyscriptxml.timeout_ = to_long(value); + } + else if (key == "keep_workers_") { + pyscriptxml.keep_workers_ = to_string(value);//yes/no + } + else if (key == "comment") { + pyscriptxml.comment_ = to_string(value); + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized pyscript map string: " << key << std::endl ; + } + }); + + m_pyscript = &pyscriptxml ; + + find_replace_map.insert( + {"_SCRIPTS_REGEX_", pyscriptxml.ReturnXMLForPyScript() + "\n_SCRIPTS_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); +} + + +void Damaris_cfg::parse_log_tree(Context& ctx, PC_tree_t config) +{ + std::map find_replace_map = {}; + + //Log File Name + std::string log_file_name = "damaris_pdi_simu"; + PC_tree_t log_file_name_tree = PC_get(config, ".log.file_name"); + if(!PC_status(log_file_name_tree)) + { + log_file_name = to_string(log_file_name_tree); + } + else { + PC_tree_t sim_name_tree = PC_get(config, ".architecture.sim_name"); + if(!PC_status(sim_name_tree)) + { + log_file_name = to_string(sim_name_tree); + } + } + + std::string log_rotation_size = "5"; + PC_tree_t log_rotation_size_tree = PC_get(config, ".log.rotation_size"); + if(!PC_status(log_rotation_size_tree)) + { + log_rotation_size = to_string(log_rotation_size_tree); + } + + std::string log_level = "info"; + PC_tree_t log_level_tree = PC_get(config, ".log.log_level"); + if(!PC_status(log_level_tree)) + { + log_level = to_string(log_level_tree); + } + + std::string log_flush = "true"; + PC_tree_t log_flush_tree = PC_get(config, ".log.flush"); + if(!PC_status(log_flush_tree)) + { + log_flush = to_string(log_flush_tree); + } + + find_replace_map.insert({ + {"_SIM_LOG_NAME_",log_file_name} + ,{"_LOG_ROTATION_SIZE_", log_rotation_size} + ,{"_LOG_FLUSH_", log_flush} + ,{"_LOG_LEVEL_", log_level} + }); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); +} + + + bool Damaris_cfg::is_needed_metadata(std::string data_name) + { + bool is_needed_metadata = false; + for(auto &prm_depends_on : m_parameter_depends_on) { + auto &prm_name = prm_depends_on.first; + auto &prm_depends_on_data = prm_depends_on.second; + for(auto &depends_on_data : prm_depends_on_data) { + //auto &depends_on_data_name = depends_on_data.first; + //auto &depends_on_data_state = depends_on_data.second; + + if(data_name == depends_on_data.first && depends_on_data.second == false) + { + depends_on_data.second = true; + is_needed_metadata = true; + } + } + } + + return is_needed_metadata; + } + + + //std::vector + //std::unordered_map> Damaris_cfg::get_updatable_parameters() + std::unordered_map> Damaris_cfg::get_updatable_parameters(Context& ctx) + { + std::unordered_map> updatable_parameters; + for(auto prm_depends_on : m_parameter_depends_on) { + auto prm_name = prm_depends_on.first; + auto prm_depends_on_data = prm_depends_on.second; + bool to_be_updated = (prm_depends_on_data.size() > 0);//true; + for(auto depends_on_data : prm_depends_on_data) { + auto depends_on_data_name = depends_on_data.first; + auto depends_on_data_state = depends_on_data.second; + + if(!depends_on_data_state) + { + to_be_updated = false; + break; + } + } + if(to_be_updated) {//Update the parameter + PDI::Expression prm_value = m_parameter_expression.at(prm_name); + damaris::model::DamarisParameterXML prmxml = m_parameters.at(prm_name); + prmxml.param_value_ = prm_value.to_string(ctx); + //ctx.logger().info("------------------------------------------------------------------------------------In get_updatable_parameters `{}' prmxml.param_value_ = '{}'", prm_name, prmxml.param_value_); + std::pair update_info; + update_info.first = prm_value.to_string(ctx); + update_info.second = prmxml.param_datatype_; + + updatable_parameters.emplace(prm_name, update_info); + } + } + + return updatable_parameters; + } + + + void Damaris_cfg::reset_parameter_depends_on(std::string prm_name) { + if (m_parameter_depends_on.find(prm_name) == m_parameter_depends_on.end()) { + // not found + // handle the error + } else { + std::unordered_map prm_depends_on_data = m_parameter_depends_on.at(prm_name); + for(auto depends_on_data : prm_depends_on_data) { + depends_on_data.second = false; + } + } + } + + void Damaris_cfg::reset_parameter_depends_on(std::vector prm_list) { + for (auto prm_name : prm_list) { + reset_parameter_depends_on(prm_name); + } + } + + void Damaris_cfg::reset_all_parameters_depends_on() { + for(auto prm_depends_on : m_parameter_depends_on) { + auto prm_name = prm_depends_on.first; + auto prm_depends_on_data = prm_depends_on.second; + + for(auto depends_on_data : prm_depends_on_data) { + depends_on_data.second = false; + } + } + } + + + // Retrive nested groups names from a dataset_elt_full_name (gp1/gp2/.../dataset_elt_name) + void retrive_nested_groups(std::string& dataset_elt_full_name, char delimiter, std::string nested_groups_names[], unsigned& index) + { + // Creating an input string stream from the dataset_elt_full_name + std::istringstream namestream(dataset_elt_full_name); + + // Tmp string + string gp_name; + + // Retrive names from the string stream separated by the delimiter + while (getline(namestream, gp_name, delimiter)) { + if(index == max_nested_groups) { + throw Value_error{"Damaris variable/layout/mesh can be nested in more than {} groups", max_nested_groups}; + } + // Add the gp_name to the array + nested_groups_names[index++] = gp_name; + } + //If index==1, there is no group, ie: nested_groups_names[index-1] = dataset_elt_full_name + } + + + template + void insert_dataset_elts_to_group(DS_TYPE ds_elt_xml, std::string nested_groups_names[], unsigned index) + { + std::string nearest_group_name = nested_groups_names[index -2]; + bool root_group_exists = false; + damaris::model::DamarisGroupXML *nearest_parent_group = NULL; + for (int root_group_id = 0; root_group_id < root_groups_xml.size(); root_group_id++) { + damaris::model::DamarisGroupXML *root_gp_xml = &root_groups_xml[root_group_id]; + + if(nested_groups_names[0] == root_gp_xml->get_name()) + { + if(nearest_group_name == root_gp_xml->get_name()) + { + //printf("-------------------------------------------------------------------------------------In root_gp_xml.get_name() = %s, FOR Variable %s, nearest_group_name == root_gp_xml.get_name() = %d\n", root_gp_xml->get_name().c_str(), nested_groups_names[index -1].c_str(), (nearest_group_name == root_gp_xml->get_name())); + //root_gp_xml->add_variable(ds_elt_xml); + root_gp_xml->add_ds_element(ds_elt_xml); + + //free(root_gp_xml); + return; + } + nearest_parent_group = root_gp_xml; + root_group_exists = true; + break; + } + + //free(root_gp_xml); + } + + //Insertion in an existing nested group + bool insertion_group_found = false; + int group_id = 1; + if(root_group_exists) + { + while (group_id <= (index - 2) && !insertion_group_found) { + std::string group_name = nested_groups_names[group_id]; + + insertion_group_found = true; + std::vector sub_groups = nearest_parent_group->get_sub_groups(); + for (int group_id = 0; group_id < sub_groups.size(); group_id++) { + if(group_name == sub_groups[group_id].get_name()) + { + if(nearest_group_name == sub_groups[group_id].get_name()) + { + //(&sub_groups[group_id])->add_variable(ds_elt_xml); + (&sub_groups[group_id])->add_ds_element(ds_elt_xml); + + return; + } + insertion_group_found = false; + nearest_parent_group = &sub_groups[group_id++]; + break; + } + } + } + } + //The nested groups has to be created + else { + damaris::model::DamarisGroupXML root_gp_xml{nested_groups_names[0]}; + + if(nearest_group_name == root_gp_xml.get_name()) + { + //root_gp_xml.add_variable(ds_elt_xml); + root_gp_xml.add_ds_element(ds_elt_xml); + root_groups_xml.emplace_back(root_gp_xml); + + return; + } + + root_groups_xml.emplace_back(root_gp_xml); + + nearest_parent_group = &root_gp_xml; + insertion_group_found = true; + } + + //Insertion point found + if(insertion_group_found){ + damaris::model::DamarisGroupXML linked_parent_group{nearest_group_name}; + for (unsigned insertion_group_id = (index - 2); insertion_group_id >= group_id; insertion_group_id--) + { + std::string group_name = nested_groups_names[insertion_group_id]; + damaris::model::DamarisGroupXML sub_gp_xml{group_name}; + if(nearest_group_name == sub_gp_xml.get_name()) + { + //sub_gp_xml.add_variable(ds_elt_xml); + sub_gp_xml.add_ds_element(ds_elt_xml); + } + else { + sub_gp_xml.add_sub_group(linked_parent_group); + } + linked_parent_group = sub_gp_xml; + } + nearest_parent_group->add_sub_group(linked_parent_group); + } + + //free(nearest_parent_group); + } + + /* + void insert_dataset_elts_to_group(damaris::model::DamarisVarXML varxml, std::string nested_groups_names[], unsigned index) + { + std::string nearest_group_name = nested_groups_names[index -2]; + bool group_exists = false; + for (int root_group_id = 0; root_group_id < root_groups_xml.size(); root_group_id++) { + damaris::model::DamarisGroupXML *root_gp_xml = &root_groups_xml[root_group_id]; + + if(nearest_group_name == root_gp_xml->get_name()) + { + //printf("-------------------------------------------------------------------------------------In root_gp_xml.get_name() = %s, FOR Variable %s, nearest_group_name == root_gp_xml.get_name() = %d\n", root_gp_xml->get_name().c_str(), nested_groups_names[index -1].c_str(), (nearest_group_name == root_gp_xml->get_name())); + root_gp_xml->add_variable(varxml); + group_exists = true; + break; + } + + std::vector sub_groups = root_gp_xml->get_sub_groups(); + for (int group_id = 0; group_id < sub_groups.size(); group_id++) { + if(nearest_group_name == sub_groups[group_id].get_name()) + { + (&sub_groups[group_id])->add_variable(varxml); + group_exists = true; + break; + } + } + } + + if(!group_exists) + { + damaris::model::DamarisGroupXML root_gp_xml{nested_groups_names[0]}; + int group_id = 1; + while (group_id <= index - 2) { + std::string group_name = nested_groups_names[group_id]; + damaris::model::DamarisGroupXML sub_gp_xml{group_name}; + if(nearest_group_name == sub_gp_xml.get_name()) + { + sub_gp_xml.add_variable(varxml); + } + root_gp_xml.add_sub_group(sub_gp_xml); + group_id++; + } + + if(group_id == 1) { + root_gp_xml.add_variable(varxml); + } + + root_groups_xml.emplace_back(root_gp_xml); + } + } + */ + +const string& Damaris_cfg::xml_config_object( void ) +{ + m_xml_config_object = damarisXMLModifyModel.GetConfigString(); + return m_xml_config_object; +} + +//const PDI::Expression& Damaris_cfg::communicator() const +PDI::Expression Damaris_cfg::communicator() const +{ + return m_communicator; +} + +const unordered_map& Damaris_cfg::datasets() const +{ + return m_datasets; +} +const unordered_map& Damaris_cfg::layouts() const +{ + return m_layouts; +} + +const unordered_map& Damaris_cfg::parameters() const +{ + return m_parameters; +} + +const std::unordered_map& Damaris_cfg::storages() const +{ + return m_storages; +} + +const std::unordered_map& Damaris_cfg::meshes() const +{ + return m_meshes; +} + +const std::unordered_map& Damaris_cfg::groups() const +{ + return m_groups; +} + + +bool Damaris_cfg::init_on_event() const +{ + return m_init_on_event; +} + +} // namespace damaris_pdi \ No newline at end of file diff --git a/plugins/damaris/damaris_cfg.h b/plugins/damaris/damaris_cfg.h new file mode 100644 index 000000000..f2905f485 --- /dev/null +++ b/plugins/damaris/damaris_cfg.h @@ -0,0 +1,207 @@ +/******************************************************************************* + * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2024 National Institute for Research in Digital Science and Technology (Inria) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#ifndef DAMARIS_CFG_H_ +#define DAMARIS_CFG_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// Definitions of the Damaris XML tag generators +#include +#include +#include + +#include "damaris_wrapper.h" + +using PDI::Context; +using std::unique_ptr; + +namespace damaris_pdi { + +typedef struct placement { + int start ; + int stride ; + int blocksize ; + std::vector mask {} ; +} placement ; + +typedef struct dedicated { + int core ; + int node ; +} dedicated ; + +struct Architecture_type { + int domain ; + placement arch_placement ; + dedicated arch_cores_or_nodes ; +}; + +enum class Desc_type { + MPI_COMM, + STATUS, + DATA_SIZE, + HEAD, + STAGE_DIR, + STAGE_STATUS +}; + + +struct DamarisXMLGenerators { + damaris::model::DamarisParameterXML params_ ; // Layouts are typically descrived using parameters. Parameters can be shared between layouts. + damaris::model::DamarisVarXML variable_ ; // A variable + damaris::model::DamarisLayoutXML layout_ ; // each variable has one layout (layouts can be sahred) + damaris::model::DamarisMeshXML mesh_ ; // Contains extra elements that need to be part of a Damaris for visualization + damaris::model::DamarisStoreXML store_ ; // Contains the extra elements that need to be part of a Damaris (for HDF5 file w/r) +}; + +class Damaris_cfg +{ + std::string m_xml_config_object; + damaris::model::ModifyModel damarisXMLModifyModel; + + bool m_init_on_event = true; + + int m_arch_domains ; + int m_dc_cores_pernode ; + int m_dc_nodes ; + + + int m_placement_start ; + int m_placement_stride ; + int m_placement_blocksize ; + std::string m_placement_mask_str ; + + PDI::Expression m_communicator; + + std::unordered_map m_datasets; + std::unordered_map m_layouts; + std::unordered_map m_parameters; + std::unordered_map m_storages; + std::unordered_map m_meshes; + std::unordered_map m_groups; + damaris::model::DamarisParaviewXML *m_paraview = NULL; + damaris::model::DamarisPyScriptXML *m_pyscript = NULL; + + + //In damaris parameter play similar role than metadata in PDI, in that other variable can be expressed by them + // Here we express parameter in terms of PDI metadata, and when metadata are expose, + // we need to be awards in order to update parameter value for Damaris + // This variable is intended for that + std::unordered_map> m_parameter_depends_on; + std::unordered_map m_parameter_expression; + + +const std::string XML_CONFIG_TEMPLATE = R"V0G0N( + + + + + + + + + + + _DATASET_ELEMENT_REGEX_ + + + + _STORAGE_ELEMENT_REGEX_ + + + _PLUGINS_REGEX_ + + + + + + _SCRIPTS_REGEX_ + + + + +)V0G0N"; + + +protected: +void parse_architecture_tree(Context& ctx, PC_tree_t arch_tree); +void parse_parameters_tree(Context& ctx, PC_tree_t parameters_tree_list); +void parse_datasets_tree(Context& ctx, PC_tree_t datasets_tree_list); +void parse_layouts_tree(Context& ctx, PC_tree_t layouts_tree_list); +void parse_storages_tree(Context& ctx, PC_tree_t storages_tree_list); +void parse_meshes_tree(Context& ctx, PC_tree_t meshes_tree_list); +void parse_paraview_tree(Context& ctx, PC_tree_t paraview_tree); +void parse_pyscript_tree(Context& ctx, PC_tree_t pyscript_tree); +void parse_log_tree(Context& ctx, PC_tree_t config); + +void init_xml_config_object(){ + m_xml_config_object = XML_CONFIG_TEMPLATE; + damarisXMLModifyModel = damaris::model::ModifyModel(m_xml_config_object); +} + + +public: + Damaris_cfg(PDI::Context& ctx, PC_tree_t tree); + + const std::string& xml_config_object( void ); + + PDI::Expression communicator() const; + + const std::unordered_map& datasets() const; + const std::unordered_map& layouts() const; + const std::unordered_map& parameters() const; + const std::unordered_map& storages() const; + const std::unordered_map& meshes() const; + const std::unordered_map& groups() const; + + bool init_on_event() const; + + const std::unordered_map>& recover_var() const; + + const std::unordered_map>>& send_file() const; + + + bool is_needed_metadata(std::string data_name); + + std::unordered_map> get_updatable_parameters(Context& ctx); + + void reset_parameter_depends_on(std::string prm_name); + void reset_parameter_depends_on(std::vector prm_list); + + void reset_all_parameters_depends_on(); +}; // class Damaris_cfg + +} // namespace damaris_pdi + +#endif // DAMARIS_CFG_H_ \ No newline at end of file diff --git a/plugins/damaris/damaris_wrapper.cxx b/plugins/damaris/damaris_wrapper.cxx new file mode 100644 index 000000000..00caf901c --- /dev/null +++ b/plugins/damaris/damaris_wrapper.cxx @@ -0,0 +1,234 @@ +/******************************************************************************* + * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2024 National Institute for Research in Digital Science and Technology (Inria) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + + +#include +#include +#include +#include +#include +#include + +#include + +#include "damaris_wrapper.h" + +using PDI::Context; +using PDI::Context_proxy; +using PDI::Data_descriptor; +using PDI::Datatype_sptr; +using PDI::Impl_error; +using PDI::Plugin_error; +using PDI::Scalar_datatype; +using PDI::Scalar_kind; +using PDI::to_string; + +using std::string; + +namespace { + +void add_predefined(Context& ctx, const std::string& name, void* data, Datatype_sptr type) +{ + Data_descriptor& predef_desc = ctx.desc(name); + if (!predef_desc.empty()) { + throw Impl_error{"Predefined descriptor already defined `%s'", name.c_str()}; + } + + predef_desc.metadata(true); + // share a RO reference on comm_self with no memory destruction function (local variable) + predef_desc.share({data, nullptr, move(type), true, false}, true, false); + predef_desc.reclaim(); // reclaim the reference and let PDI keep a copy (metadata) +} + +} // namespace + +namespace damaris_pdi { + +// Constructer calls damaris_init() +Damaris_wrapper::Damaris_wrapper(Context& ctx, const char* xmlConfigObject, MPI_Comm comm) +{ + ctx.logger().info("Damaris lib initialization starts..."); + int status = damaris_pdi_initialize(xmlConfigObject, comm); + if (status != DAMARIS_OK) { + throw Plugin_error{"Cannot initialize Damaris library"}; + } + else + ctx.logger().info("Damaris lib initialization Done!"); +} + +int Damaris_wrapper::damaris_pdi_initialize(const char* configfile, MPI_Comm comm) +{ + return damaris_initialize(configfile, comm); +} + +int Damaris_wrapper::damaris_pdi_finalize( void ) +{ + return damaris_finalize(); +} + +int Damaris_wrapper::damaris_pdi_start(int* is_client) +{ + return damaris_start(is_client); +} + +int Damaris_wrapper::damaris_pdi_stop( void ) +{ + return damaris_stop(); +} + +int Damaris_wrapper::damaris_pdi_write(const char* varname, const void* data) +{ + return damaris_pdi_write_block(varname, 0, data); +} +int Damaris_wrapper::damaris_pdi_write(std::string varname, const void* data) +{ + return damaris_pdi_write_block(varname, 0, data); +} + +bool Damaris_wrapper::damaris_pdi_write_block(const char* varname, int32_t block, const void* data) +{ + return damaris_write_block(varname,block, data); +} + +bool Damaris_wrapper::damaris_pdi_write_block(std::string varname, int32_t block, const void* data) +{ + return damaris_write_block(varname.c_str(),block, data); +} + +int Damaris_wrapper::damaris_pdi_get_type(const char* variable_name, DAMARIS_TYPE_STR *vartype) +{ + return damaris_get_type(variable_name, vartype); +} + +int Damaris_wrapper::damaris_pdi_has_plugin(DAMARIS_PLUGIN_TYPE plugin) +{ + return damaris_has_plugin( plugin); +} + + +int Damaris_wrapper::damaris_pdi_alloc(const char* varname, void** ptr) +{ + return damaris_alloc(varname, ptr); +} + + +int Damaris_wrapper::damaris_pdi_alloc_block(const char* varname, int32_t block, void** ptr) +{ + return damaris_alloc_block(varname, block, ptr); +} + +int Damaris_wrapper::damaris_pdi_commit(const char* varname) +{ + return damaris_commit(varname); +} + +int Damaris_wrapper::damaris_pdi_commit_iteration(const char* varname, int32_t iteration) +{ + return damaris_commit_iteration(varname, iteration); +} + +int Damaris_wrapper::damaris_pdi_commit_block_iteration(const char* varname, + int32_t block, int32_t iteration) +{ + return damaris_commit_block_iteration( varname, block, iteration); +} + +int Damaris_wrapper::damaris_pdi_clear(const char* varname) +{ + return damaris_clear(varname); +} + +int Damaris_wrapper::damaris_pdi_clear_block(const char* varname, int32_t block) +{ + return damaris_clear_block(varname, block); +} + +int Damaris_wrapper::damaris_pdi_clear_iteration(const char* varname, int32_t iteration) +{ + return damaris_clear_iteration(varname, iteration); +} + +int Damaris_wrapper::damaris_pdi_clear_block_iteration(const char* varname, + int32_t block, int32_t iteration) +{ + return damaris_clear_block_iteration(varname, block, iteration); +} + +int Damaris_wrapper::damaris_pdi_signal(const char* signal_name) +{ + return damaris_signal(signal_name); +} + +int Damaris_wrapper::damaris_pdi_bind(const char* signal_name, signal_t sig) +{ + return damaris_bind(signal_name, sig); +} + +int Damaris_wrapper::damaris_pdi_parameter_get(const char* param_name, + void* buffer, unsigned int size) +{ + return damaris_parameter_get(param_name, buffer, size); +} + +int Damaris_wrapper::damaris_pdi_parameter_set(const char* param_name, + const void* buffer, unsigned int size) +{ + return damaris_parameter_set(param_name, buffer, size); +} + +int Damaris_wrapper::damaris_pdi_set_position(const char* var_name, const int64_t* position) +{ + return damaris_set_position(var_name, position); +} + +int Damaris_wrapper::damaris_pdi_set_block_position(const char* var_name, + int32_t block, const int64_t* position) +{ + return damaris_set_block_position(var_name, block, position); +} + +int Damaris_wrapper::damaris_pdi_client_comm_get(MPI_Comm* comm) +{ + return damaris_client_comm_get(comm); +} + +int Damaris_wrapper::damaris_pdi_end_iteration( void ) +{ + return damaris_end_iteration( ); +} + +int Damaris_wrapper::damaris_pdi_get_iteration(int* iteration) +{ + return damaris_get_iteration(iteration); +} + + +Damaris_wrapper::~Damaris_wrapper() +{ + // Call before MPI_Finalize() + damaris_finalize(); +} + +} // namespace damaris_pdi \ No newline at end of file diff --git a/plugins/damaris/damaris_wrapper.h b/plugins/damaris/damaris_wrapper.h new file mode 100644 index 000000000..8fc58be7a --- /dev/null +++ b/plugins/damaris/damaris_wrapper.h @@ -0,0 +1,398 @@ +/******************************************************************************* + * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2024 National Institute for Research in Digital Science and Technology (Inria) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + + +#ifndef DAMARIS_WRAPPER_H_ +#define DAMARIS_WRAPPER_H_ + +#include +#include + +#include + +//#include "damaris_cfg.h" + +namespace damaris_pdi { + +class Damaris_wrapper +{ + + Damaris_wrapper(const Damaris_wrapper&) = delete; + + Damaris_wrapper& operator=(const Damaris_wrapper&) = delete; + + int m_is_client ; // if != 0 (In this case == 1) then the process is a Damaris client (i.e. a simulation rank) + +public: + Damaris_wrapper(PDI::Context& ctx, const char* xmlConfigObject, MPI_Comm comm); + // Damaris_wrapper(PDI::Context& ctx, const Damaris_cfg& config, MPI_Comm comm, PC_tree_t logging_tree); + //Damaris_wrapper(PDI::Context& ctx, Damaris_cfg::Damaris_cfg& config, MPI_Comm comm); + +// void set_is_client(int is_client) ; +// int get_is_client( void ) ; + + + void set_is_client(int is_client) + { + m_is_client = is_client ; + } + + int get_is_client( void ) + { + return m_is_client ; + } + +private: + /** + * Initializes Damaris, should be called after MPI_Init. + * + * \param[in] configfile : name of the XML configuration file. + * \param[in] comm : MPI communicator gathering all the nodes. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_initialize(const char* configfile, MPI_Comm comm); + +public: + /** + * Finalize Damaris. Should be called before MPI_Finalize. If Damaris was + * started (damaris_start()), it should be stopped (using damaris_stop()) before this call. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_finalize( void ); + + /** + * Starts the server(s). Sets is_client to 1 if this core is a client. + * Otherwise, this function starts the server and blocks until clients call + * damaris_stop, and is_client is set to 0. + * + * \param[out] is_client : indicates if this core is a client. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_start(int* is_client); + + /** + * Stops the server. This function should only be called by client processes + * and these processes must have called damaris_start to start the servers + * before. When all client processes have called damaris_stop, server processes + * blocked on damaris_start will return (with is_client set to 0). + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_stop( void ); + + + /** + * Writes a variable (similar to damaris_write_block(varnale,0,data)). + * + * \param[in] varname : name of the variable to write. + * \param[in] data : pointer to the data to write. + * + * \return DAMARIS_OK on success, other error codes on failures. + */ + int damaris_pdi_write(const char* varname, const void* data); + /** + * Writes a variable (similar to damaris_write_block(varnale,0,data)). + * + * \param[in] varname : name of the variable to write. + * \param[in] data : pointer to the data to write. + * + * \return DAMARIS_OK on success, other error codes on failures. + */ + int damaris_pdi_write(std::string varname, const void* data); + + + /** + * Writes a block of a variable. The variable name should be the full name + * of a variable defined in the configuration file. The block id should be + * between 0 and the number of domains per client - 1, as defined in the + * configuration file. + * + * \param[in] varname : name of the variable to write. + * \param[in] block : id of the block to write. + * \param[in] data : pointer to the data to write. + * + * \return DAMARIS_OK on success, other error codes on failures. + */ + bool damaris_pdi_write_block(const char* varname, int32_t block, const void* data); + /** + * Writes a block of a variable. The variable name should be the full name + * of a variable defined in the configuration file. The block id should be + * between 0 and the number of domains per client - 1, as defined in the + * configuration file. + * + * \param[in] varname : name of the variable to write. + * \param[in] block : id of the block to write. + * \param[in] data : pointer to the data to write. + * + * \return DAMARIS_OK on success, other error codes on failures. + */ + bool damaris_pdi_write_block(std::string varname, int32_t block, const void* data); + + /** + * Checks what a variables layout type is and returns an enumerated constant + * indicating the type + * + * \param[in] varname : name of the variable to check the type of. + * \param[out] vartype : enumerated constant indicating what data type the + * Variable data is defined with. + * + * \return DAMARIS_OK on success, other error codes on failures. + */ + int damaris_pdi_get_type(const char* variable_name, DAMARIS_TYPE_STR *vartype); + + + /** + * Checks if a particular Damaris plugin is available. + * + * \param[out] vartype : enumerated constant indicating what data type the + * Variable data is defined with. + * + * \return 1 on plugin being available, 0 otherwise + */ + int damaris_pdi_has_plugin(DAMARIS_PLUGIN_TYPE plugin); + + /** + * Allocates the data required for a variable to be entirely written in memory. + * Similar to damaris_alloc_block(varname,0,ptr). + * + * \param[in] varname : name of the variable to write. + * \param[out] ptr : pointer to a pointer to the allocated memory. + * + * \return DAMARIS_OK on success, other error codes on failure. + */ + int damaris_pdi_alloc(const char* varname, void** ptr); + + /** + * Allocates the data required for a block of a variable to be written + * in memory. + * + * \param[in] varname : name of the variable to write. + * \param[in] block : block id for which to allocate memory. + * \param[out] ptr : pointer to a pointer to the allocated memory. + */ + int damaris_pdi_alloc_block(const char* varname, int32_t block, void** ptr); + + /** + * Commits data associated to the variable on current iteration. This function + * is equivalent to calling damaris_commit_block(varname,0). + * + * \param[in] varname : name of the variable to commit. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_commit(const char* varname); + + /** + * Commits variable from the given iteration. This call is equivalent to + * damaris_commit_block_iteration(varname,0,iteration). + * + * \param[in] varname : name of the variable to commit. + * \param[in] iteration : iteration to commit. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_commit_iteration(const char* varname, int32_t iteration); + + /** + * Commits a specific block of variable from the given iteration. The variable + * should be defined in the configuration file and the block id should be + * within the range defined by the number of domains per client. + * + * \param[in] varname : name of the variable to commit. + * \param[in] block : block id. + * \param[in] iteration : iteration to commit. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_commit_block_iteration(const char* varname, + int32_t block, int32_t iteration); + + /** + * Clears the specified variable. This call is equivalent to + * damaris_clear_block(varname,0). Will transfer the responsibility of the data + * to the dedicated cores. + * + * \param[in] varname : name of the variable to clear. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_clear(const char* varname); + + /** + * Clears the block for the specified variable. + * + * \param[in] varname : name of the variable to clear. + * \param[in] block : block id. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_clear_block(const char* varname, int32_t block); + + /** + * Clears the specified variable at a specified iteration. + * + * \param[in] varname : name of the variable to clear. + * \param[in] iteration : iteration to clear. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_clear_iteration(const char* varname, int32_t iteration); + + /** + * Clears the block for the specified variable at a specified iteration. + * + * \param[in] varname : name of the variable to clear. + * \param[in] iteration : iteration number. + * \param[in] block : block id. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_clear_block_iteration(const char* varname, + int32_t block, int32_t iteration); + + /** + * Sends a signal to the closest dedicated core. + * + * \param[in] signal_name : name of the signal to send, must correspond to an + * event or a script in the configuration file. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_signal(const char* signal_name); + + /** + * Associates a signal name to a function from the executable. + * + * \param[in] signal_name : name of the signal. + * \param[in] sig : function to bind. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_bind(const char* signal_name, signal_t sig); + + /** + * Get the current value of a parameter. + * + * \param[in] param_name : name of the parameter to read. + * \param[out] buffer : buffer in which to put the value. + * \param[in] size : maximum size (in bytes) in the buffer. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_parameter_get(const char* param_name, + void* buffer, unsigned int size); + + /** + * Set the value of a parameter. + * + * \param[in] param_name : name of the parameter. + * \param[in] buffer : buffer from which to take the value. + * \param[in] size : size of the buffer. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_parameter_set(const char* param_name, + const void* buffer, unsigned int size); + + /** + * Changes the position of the variable. Sets the meta-data that represents + * the start of position within the variable of which the block stores the data + * of. + * Equivalent to a call to + * damaris_set_block_position(var_name,0,position). + * + * \param[in] var_name : name of the variable to move. + * \param[in] position : array of new coordinates. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_set_position(const char* var_name, const int64_t* position); + + /** + * Changes the position of a block of the variable. + * + * \param[in] var_name : name of the variable to move. + * \param[in] block : block id. + * \param[in] position : array of new coordinates. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_set_block_position(const char* var_name, + int32_t block, const int64_t* position); + + /** + * Gets the communicator that the clients must use. + * + * \param[out] comm : communicator gathering clients. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_client_comm_get(MPI_Comm* comm); + + /** + * Ends the current iteration. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_end_iteration( void ); + + /** + * Gets the current iteration number. + * + * \param[out] iteration : current iteration number. + * + * \return DAMARIS_OK on success, other error codes on failures. + * + */ + int damaris_pdi_get_iteration(int* iteration); + + + ~Damaris_wrapper() ; +}; // class Damaris_wrapper + +} // namespace damaris_pdi +#endif // DAMARIS_WRAPPER_H_ \ No newline at end of file diff --git a/plugins/damaris/example/CMakeLists.txt b/plugins/damaris/example/CMakeLists.txt new file mode 100644 index 000000000..19c2192f8 --- /dev/null +++ b/plugins/damaris/example/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory (storage) +add_subdirectory (paraview) +add_subdirectory (python) \ No newline at end of file diff --git a/plugins/damaris/example/paraview/CMakeLists.txt b/plugins/damaris/example/paraview/CMakeLists.txt new file mode 100644 index 000000000..1c011b1e0 --- /dev/null +++ b/plugins/damaris/example/paraview/CMakeLists.txt @@ -0,0 +1,6 @@ +add_definitions(-DPARALLEL) + +add_executable (image image.cpp) +target_link_libraries (image PDI::PDI_C MPI::MPI_CXX) +set_target_properties (image PROPERTIES LINK_FLAGS "-Wl,-export-dynamic") +#INSTALL(TARGETS image RUNTIME DESTINATION bin) \ No newline at end of file diff --git a/plugins/damaris/example/paraview/image.cpp b/plugins/damaris/example/paraview/image.cpp new file mode 100644 index 000000000..a6c575ec8 --- /dev/null +++ b/plugins/damaris/example/paraview/image.cpp @@ -0,0 +1,269 @@ +#include +#include + +//#include "mpi.h" +#include +//#include "Damaris.h" +#include +#include + +#include "pdi.h" + +#include +using std::string; + +int Steps = 1000; + + +struct simdata { + double* zonal_cube; + double* nodal_cube; + int step; + int rank; + int size; + + int zonal_x; + int zonal_y; + int zonal_z; + + int nodal_x; + int nodal_y; + int nodal_z; +}; + + +template +void setZonalValue(simdata& sim , T value, int i , int j , int k=0) { + if ((i == sim.zonal_x) || (j == sim.zonal_y) || (k == sim.zonal_z)) + return; + + sim.zonal_cube[i + j * sim.zonal_x + k * sim.zonal_y * sim.zonal_x] = value; // row major +} + +template +void setNodalValue(simdata& sim , T value, int i , int j , int k=0) { + sim.nodal_cube[i + j * sim.nodal_x + k * sim.nodal_y * sim.nodal_x] = value; // row major +} + +double GetFillValue(simdata& sim, int i , int j , int k) +{ + if ((sim.step % 100) == i) + return -100; + + int a = (int)k/10; + int b = (int)i/10; + + return ((a+b)*10+(sim.rank*100)); +} + +void InitSimData(simdata &sim , MPI_Comm comm) +{ + int X,Y,Z; + MPI_Comm_size(comm , &sim.size); + MPI_Comm_rank(comm , &sim.rank); + + int int_size = sizeof(int); + // Pass the specific size parameter back to Damaris + // damaris_parameter_set("size",&sim.size,sizeof(int)); + char * prm_name = "size"; + PDI_multi_expose("damaris_parameter_set" + ,"prm_name", prm_name, PDI_OUT + ,"prm_buffer", &sim.size, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + + //damaris_parameter_get("WIDTH",&X,sizeof(int)); + //damaris_parameter_get("HEIGHT",&Y,sizeof(int)); + //damaris_parameter_get("DEPTH",&Z,sizeof(int)); + prm_name = "WIDTH"; + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", prm_name, PDI_OUT + ,"prm_buffer", &X, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + prm_name = "HEIGHT"; + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", prm_name, PDI_OUT + ,"prm_buffer", &Y, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + prm_name = "DEPTH"; + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", prm_name, PDI_OUT + ,"prm_buffer", &Z, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + + // Split the cube over the Z direction + int local_z = Z/sim.size; + + sim.zonal_x = X; + sim.zonal_y = Y; + sim.zonal_z = local_z; + sim.zonal_cube = new double[sim.zonal_x*sim.zonal_y*sim.zonal_z]; + + sim.nodal_x = sim.zonal_x + 1; + sim.nodal_y = sim.zonal_y + 1; + sim.nodal_z = sim.zonal_z + 1; + sim.nodal_cube = new double[sim.nodal_x*sim.nodal_y*sim.nodal_z]; +} + +void FreeSimData(simdata& sim) +{ + delete [] sim.zonal_cube; + delete [] sim.nodal_cube; + + sim.zonal_cube = nullptr; + sim.nodal_cube = nullptr; +} + +void WriteCoordinates(simdata sim) +{ + float* XCoord = new float[sim.nodal_x]; + float* YCoord = new float[sim.nodal_y]; + float* ZCoord = new float[sim.nodal_z]; + + for(int i=0; i\n", argv[0]); + exit(0); + } + + MPI_Init(&argc, &argv); + PC_tree_t conf = PC_parse_path(argv[1]); + + PDI_init(PC_get(conf, ".pdi")); + //damaris_initialize(argv[1],MPI_COMM_WORLD); + PDI_event("initialize"); // or init + //PDI_event("init"); + + + int is_client = -1; + //int err = damaris_start(&is_client); + + PDI_multi_expose("damaris_start" + ,"is_client", &is_client, PDI_INOUT + , NULL); + + // if((err == DAMARIS_OK || err == DAMARIS_NO_SERVER) && is_client) { + if(is_client) { + simdata sim; + MPI_Comm comm; + + //damaris_client_comm_get(&comm); + PDI_multi_expose("damaris_client_comm_get" + ,"client_comm", &comm, PDI_INOUT + , NULL); + + + InitSimData(sim , comm); + WriteCoordinates(sim); + + for(int s=0; s < Steps ; s++) { + sim.step = s; + SimMainLoop(sim); + } + + FreeSimData(sim); + //damaris_stop(); + PDI_event("damaris_stop"); + } + + //damaris_finalize(); + PDI_event("finalize"); + PDI_finalize(); + MPI_Finalize(); + + return 0; +} diff --git a/plugins/damaris/example/paraview/image.py b/plugins/damaris/example/paraview/image.py new file mode 100644 index 000000000..3b17c0cec --- /dev/null +++ b/plugins/damaris/example/paraview/image.py @@ -0,0 +1,71 @@ +from paraview.simple import * +from paraview import coprocessing + +#-------------------------------------------------------------- +# Code generated from cpstate.py to create the CoProcessor. + +# ----------------------- CoProcessor definition ----------------------- + +def CreateCoProcessor(): + def _CreatePipeline(coprocessor, datadescription): + class Pipeline: + filename_2_pvti = coprocessor.CreateProducer( datadescription, "input" ) + + return Pipeline() + + class CoProcessor(coprocessing.CoProcessor): + def CreatePipeline(self, datadescription): + self.Pipeline = _CreatePipeline(self, datadescription) + + coprocessor = CoProcessor() + freqs = {'input': [10, 100]} + coprocessor.SetUpdateFrequencies(freqs) + return coprocessor + +#-------------------------------------------------------------- +# Global variables that will hold the pipeline for each timestep +# Creating the CoProcessor object, doesn't actually create the ParaView pipeline. +# It will be automatically setup when coprocessor.UpdateProducers() is called the +# first time. +coprocessor = CreateCoProcessor() + +#-------------------------------------------------------------- +# Enable Live-Visualizaton with ParaView +coprocessor.EnableLiveVisualization(True) + + +# ---------------------- Data Selection method ---------------------- + +def RequestDataDescription(datadescription): + "Callback to populate the request for current timestep" + global coprocessor + if datadescription.GetForceOutput() == True: + # We are just going to request all fields and meshes from the simulation + # code/adaptor. + for i in range(datadescription.GetNumberOfInputDescriptions()): + datadescription.GetInputDescription(i).AllFieldsOn() + datadescription.GetInputDescription(i).GenerateMeshOn() + return + + # setup requests for all inputs based on the requirements of the + # pipeline. + coprocessor.LoadRequestedData(datadescription) + +# ------------------------ Processing method ------------------------ + +def DoCoProcessing(datadescription): + "Callback to do co-processing for current timestep" + global coprocessor + + # Update the coprocessor by providing it the newly generated simulation data. + # If the pipeline hasn't been setup yet, this will setup the pipeline. + coprocessor.UpdateProducers(datadescription) + + # Write output data, if appropriate. + #coprocessor.WriteData(datadescription); + + # Write image capture (Last arg: rescale lookup table), if appropriate. + #coprocessor.WriteImages(datadescription, rescale_lookuptable=False) + + # Live Visualization, if enabled. + coprocessor.DoLiveVisualization(datadescription, "localhost", 22222) diff --git a/plugins/damaris/example/paraview/image.xml b/plugins/damaris/example/paraview/image.xml new file mode 100644 index 000000000..b5933c568 --- /dev/null +++ b/plugins/damaris/example/paraview/image.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/damaris/example/python/.Rhistory b/plugins/damaris/example/python/.Rhistory new file mode 100644 index 000000000..e69de29bb diff --git a/plugins/damaris/example/python/3dmesh_dask.py b/plugins/damaris/example/python/3dmesh_dask.py new file mode 100644 index 000000000..765b33626 --- /dev/null +++ b/plugins/damaris/example/python/3dmesh_dask.py @@ -0,0 +1,224 @@ +# Python code: 3dmesh_dask.py.template +# Author: Josh Bowden, Inria +# Description: Template file for running tests on Grid5000 +# Part of the Damaris examples of using Python integration with Dask distributed +# To run this example, a Dask scheduler needs to be spun up: +# +# dask-scheduler --scheduler-file "/home/user/dask_file.json" & +# +# The --scheduler-file argument must match what is int the Damaris XML file +# tag +# +# Then run the simulation: (assumes 4 Damaris clients and 2 Damaris server cores as per the xml file) +# +# mpirun --oversubscribe --host ubu20-hvvm-c -np 6 ./3dmesh_py 3dmesh_dask.xml -i 3 -v 2 -r +# +# This will create the Dask workers (one per Damaris server core) and have them connect to +# the Dask scheduler. The simulation code will remove the workers at the end of the execution, +# unless keep-workers="yes" is specified in 3dmesh_dask.xml tag +# + +import numpy as np +np.set_printoptions(threshold=np.inf) + + +# N.B. This file is read by each Damaris server process on each iteration that is +# specified by the frequency="" in the XML sttribute. +# +# DD (AKA Damaris Data) is a dictionary that has been filled by the +# Damaris server process with NumPy arrays that point to the Damaris data variables +# that are exposed in the simulation. The Damaris class that implements +# this is PyAction, found in the src/scripts/ and include/damaris/scripts +# directories. Damaris must be exposed to the Python +# XML element by including its name i.e. "MyPyAction"" in the following example: +# +# +# +# +# +# +# N.B. Setting nthreads="openmp" will set the dask worker threads +# to the value obtained from opm_get_num_threads() +# +# +# The Damaris server processes also present three dictionaries, damaris_env, dask_env and iteration_data +# containing various data about the simulation as well as the variable data itself, packaged as Numpy arrays. +# DD['damaris_env'].keys() - The global Damaris environment data +# (['is_dedicated_node', # +# 'is_dedicated_core', # +# 'servers_per_node', # Number of Damaris server ranks per node +# 'clients_per_node', # Number of Damaris client ranks per node +# 'ranks_per_node', # Total number of ranks per node +# 'cores_per_node', # Total number of ranks per node (yes, the same as above) +# 'number_of_nodes', # The total number of nodes used in the simulation +# 'simulation_name', # The name of the simulation (specified in Damaris XML file) +# 'simulation_magic_number' # Unique number for a simulation run (used in constructing name of Dask workers.) +# ]) +# +# DD['dask_env'].keys() - The Dask environment data, +# (['dask_scheduler_file', # if an empty string then no Dask scheduler was found +# 'dask_workers_name', # Each simulation has a uniquely named set of workers +# 'dask_nworkers', # The total number of dask workers (== 'servers_per_node' x 'number_of_nodes') +# 'dask_threads_per_worker' # Dask workers can have their own threads. Specify as nthreads="1" in Damris XML file +# ]) +# +# DD['iteration_data'].keys() - A single simulation iteration. +# Contains the iteration number and a list of sub-dictionaries, +# one for each *Damaris variable* that has been exposed to the Python +# interface. i.e. specified with the script="MyAction" as in the example above +# (['iteration', # The iteration number as an integer. +# 'cube_i', # A Damaris variable dictionary - the name relates to the variable name used in the Damaris XML file +# '...', # A Damaris variable dictionary +# '...' # A Damaris variable dictionary +# ]) +# +# A Damaris variable dictionary has the following structure +# DD['iteration_data']['cube_i'].keys() +# (['numpy_data', +# 'sort_data', +# 'type_string' # possibly to be removed as this information can be obtained from the NumPy array itself +# ]) +# +# DD['iteration_data']['cube_i']['sort_data'] +# sort_data is a list, that can be sorted on (possibly required to be transformed to tuple) which +# when sorted, the list values can be used to reconstruct the whole array using Dask: +# ['string', 'string', [ ]] +# A specific example: +# ['S0_I1_', 'P0_B0', [ 0, 9, 12 ]] +# The string 'S0_I1_' indicates 'S' for server and 'I' for iteration. +# The magic number is needed as the data is published to a Dask server +# The string 'P0_B0' indciates the dictionary key of Numpy data (see next description for explanation of 'P' and 'B') +# The list [ 0, 9, 12 ] indicates the offestes into the global array from where the NumPy data is mapped +# (The size of the NumPy array inicates the block size of the data) +# +# +# And, finally, the NumPy data is present in blocks, given by keys constructed as described below +# DD['iteration_data']['cube_i']['numpy_data'].keys() +# (['P0_B0', +# 'P1_B0' +# ]) + +# Damaris NumPy data keys: 'P' + damaris client number + '_B' + domain number +# The client number is the source of the data (i.e. it is the Damaris client number that wrote the data) +# The domain number is the result of multiple calls to damaris_write_block() +# or 0 if only damaris_write() API is used or a single block only was written. +# +# N.B. Only the data for the current iteration is available - and it is Read Only. +# If it is needed later it needs to be saved somehow and re-read on the +# next iteration. When connected to a Dask scheduler then the data can be saved on +# the distributed workers. + + + +def main(DD): + import numpy as np + import time + from os import path + from dask.distributed import Client, TimeoutError, Lock, Variable + from damaris4py.server import getservercomm + from damaris4py.server import listknownclients + from damaris4py.dask import damaris_dask + + + + # Using to sum up elements in each block + # see: https://stackoverflow.com/questions/40092808/compute-sum-of-the-elements-in-a-chunk-of-a-dask-array + def compute_block_sum(block): + return np.array([np.sum(block)])[:, None, None] + + try: + # pass + damaris_comm = getservercomm() + rank = damaris_comm.Get_rank() + size = damaris_comm.Get_size() + + # This is the iteration value the from Damaris perspective + # i.e. It is the number of times damaris_end_iteration() has been called + iter_dict = DD['iteration_data'] + iteration = iter_dict['iteration'] + iteration_dam = damaris_dask.return_iteration(DD) + assert iteration == iteration_dam + + damaris_comm.Barrier() + + # The value passed through by Damaris clients as array_sum is to be compared with the + # value computed by Dask. It is an array of a single value, which changes each iteration + # and is the sum of all values in the whole cube_i dataset in distributed memory. + # The sum is only available on client rank 0 + # Uses defaults for: client_rank=0, block_number=0 + sum_from_sim = damaris_dask.return_scalar_from_position(DD, 'array_sum', pos=(0)) + print('Info from Python: Iteration ', iteration, ' Data found: iter_dict[array_sum][numpy_data][P0_B0] = ', sum_from_sim ) + + + # lists the known clients of the current Damaris server rank + client_list = listknownclients() + last_iter_numpy = damaris_dask.return_numpy_array(DD, 'last_iter', client_rank=client_list[0] ) + if (iteration == 0): + if (last_iter_numpy is not None): + print('Python iteration ', iteration, ' Data found: last_iter = ', last_iter_numpy[0] ) + else: + print('Python iteration ', iteration, ' Data not found: last_iter ') + + # Do some Dask stuff + # If this scheduler_file exists (is not an empty string) then a Dask scheduler was + # found (Access has been tested on the Damaris server C++ Python). + # scheduler_file = dask_dict['dask_scheduler_file'] + scheduler_file = damaris_dask.return_scheduler_filename(DD) + if iteration == 0: + print('Python INFO: Scheduler file '+ scheduler_file) + if (scheduler_file != ""): + + try: + client = Client(scheduler_file=scheduler_file, timeout='2s') + # We now create the Dask dask.array + x = damaris_dask.return_dask_array(DD, client, 'cube_i', damaris_comm, print_array_component=False ) + # Only rank 0 returns a dask.array, the others return None + if (x is not None): + array_sum_dask = x.sum().compute() + print('Python iteration ', iteration,' dask x.sum() := ', array_sum_dask) + + # if iteration == 2 : + # y = x.map_blocks(compute_block_sum, chunks=(1, 1, 1)).compute() + # print('Python iteration ', iteration, 'The sum of values within the dask.array blocks is:') + # print(y) + + if sum_from_sim == array_sum_dask: + print('PASS') # I should push this to the Dask memory to compare at end of iterations? + else: + print('FAIL') + print('') + # Use .persist() to not bring datasets back to the curent client + # Use .compute() with small datasets (summaries / reductions) to use in displaying results + + damaris_comm.Barrier() + + # close the client only: + client.close() + + except TimeoutError as err: + print('Python ERROR: TimeoutError!: ', err) + except OSError as err: + print('Python ERROR: OSError!: ', err) + else: + print('Python INFO: Scheduler file not found:', scheduler_file) + except KeyError as err: + print('Python ERROR: KeyError: No damaris data of name: ', err) + except PermissionError as err: + print('Python ERROR: PermissionError!: ', err) + except ValueError as err: + print('Python ERROR: Damaris Data problem!: ', err) + except UnboundLocalError as err: + print('Python ERROR: Damaris data not assigned!: ', err) + except NameError as err: + print('Python ERROR: NameError: ', err) + # finally: is always called. + finally: + pass + + + +if __name__ == '__main__': + main(DamarisData) diff --git a/plugins/damaris/example/python/3dmesh_dask.xml b/plugins/damaris/example/python/3dmesh_dask.xml new file mode 100644 index 000000000..ae1eac44a --- /dev/null +++ b/plugins/damaris/example/python/3dmesh_dask.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/damaris/example/python/3dmesh_dask.yml b/plugins/damaris/example/python/3dmesh_dask.yml new file mode 100644 index 000000000..0a861ebea --- /dev/null +++ b/plugins/damaris/example/python/3dmesh_dask.yml @@ -0,0 +1,105 @@ +# only the following config is passed to PDI +pdi: + metadata: # type of small values for which PDI keeps a copy + size: int + data: # type of values for which PDI does not keep a copy + is_client: int # equivalent to fti_head + plugins: + #mpi: + damaris: + #init_on_event: 1 + communicator: MPI_COMM_WORLD + architecture: + sim_name: 3dmesh_wf + domains: 8 + buffer_size: 536870912 + placement: + start: + stride: + blocksize: + mask: + dedicated: + core: 2 + node: 0 + parameters: + - parameter: + name: WIDTH + type: int + value: 16 + - parameter: + name: HEIGHT + type: int + value: 8 + - parameter: + name: DEPTH + type: int + value: 16 + - parameter: + name: size + type: int + value: 4 + - parameter: + name: blocks + type: int + value: 4 + datasets: + - dataset: + name: cube_i + type: scalar + layout: cells_whd_wf + time_varying: true + mesh: mesh + centering: nodal + script: MyPyAction + - dataset: + name: last_iter + type: scalar + layout: one_int + time_varying: true + mesh: mesh + script: MyPyAction + - dataset: + name: array_sum + type: scalar + layout: one_double + time_varying: true + mesh: mesh + script: MyPyAction + layouts: + - layout: + name: cells_whd_wf + type: int + dimensions: 'WIDTH/size,HEIGHT,DEPTH/blocks' + global: 'WIDTH,HEIGHT,DEPTH' + #ghosts: '0:0,0:0,0:0' + - layout: + name: one_int + type: int + dimensions: '1' + global: '1' + - layout: + name: one_double + type: double + dimensions: '1' + global: '1' + pyscript: + name: MyPyAction + file: 3dmesh_dask.py # can be absolute or relative path + scheduler_file: dask_file.json + #execution: 1 + language: python + #scope: core + #external: false + frequency: 1 + #nthreads: 1 + #timeout: 2 + #keep_workers: no + #comment: "" + log: + #file_name: 2dmesh # default = $sim_name + rotation_size: 5 + log_level: info + flush: true + + + diff --git a/plugins/damaris/example/python/3dmesh_py.c b/plugins/damaris/example/python/3dmesh_py.c new file mode 100644 index 000000000..7ee35ea7b --- /dev/null +++ b/plugins/damaris/example/python/3dmesh_py.c @@ -0,0 +1,306 @@ +#include +#include +#include +#include +#include + +#include +//#include "Damaris.h" +#include +#include + +#include "pdi.h" + + +/** C code: 3dmesh_py + Damaris example of obtaining data from a simulation via Python + + mpirun --oversubscribe -np 5 ./3dmesh_py 3dmesh_py.xml -i 3 -v 2 -r + +*/ +void print_usage(char* exename) { + + fprintf(stderr,"Usage: %s <3dmesh_py.xml> [-v] [-r] [-s X]\n",exename); + fprintf(stderr,"-v X = 0 default, do not print arrays\n"); + fprintf(stderr," X = 1 Verbose mode, prints arrays\n"); + fprintf(stderr," X = 2 Verbose mode, prints summation of arrays\n"); + fprintf(stderr,"-r Array values set as rank of process\n"); + fprintf(stderr,"-s Y is integer time to sleep in sconds between iterations\n"); + fprintf(stderr,"-i I is the number of iterations of simulation to run\n"); +} + +int WIDTH; +int HEIGHT; +int DEPTH; +int MAX_CYCLES ; + + +int main(int argc, char** argv) +{ + if(argc < 2) + { + print_usage(argv[0]) ; + exit(0); + } + + MPI_Init(&argc, &argv); + PC_tree_t conf = PC_parse_path(argv[1]); + PDI_init(PC_get(conf, ".pdi")); + + //damaris_initialize(argv[1],MPI_COMM_WORLD); + PDI_event("initialize"); // or init + //PDI_event("init"); + + int verbose = 0; + int rank_only = 0; + int current_arg = 2 ; + int time = 1 ; + MAX_CYCLES = 5; // default number of iterations to run + while (current_arg < argc ) + { + if (strcmp(argv[current_arg],"-v") == 0) { + current_arg++; + verbose = atoi(argv[current_arg]); + } + else if (strcmp(argv[current_arg],"-r") == 0) + rank_only = 1 ; + else if (strcmp(argv[current_arg],"-s") == 0) { + current_arg++; + time = atoi(argv[current_arg]); + } else if (strcmp(argv[current_arg],"-i") == 0) { + current_arg++; + MAX_CYCLES = atoi(argv[current_arg]); + } else if (strcmp(argv[current_arg],"-h") == 0) { + print_usage(argv[0]) ; + exit(0); + } + + current_arg++; + } + + + + int size_client, rank_client, whd_layout; + + + int is_client = -1; + //int err = damaris_start(&is_client); + + PDI_multi_expose("damaris_start" + ,"is_client", &is_client, PDI_INOUT + , NULL); + + printf("-------------------------------------------------------------------------------------D: :) ;) is_client = %d\n", is_client); + + + // if((err == DAMARIS_OK || err == DAMARIS_NO_SERVER) && is_client) { + //if(err == DAMARIS_OK && is_client) { + if(is_client) { + + MPI_Comm comm; + //damaris_client_comm_get(&comm); + PDI_multi_expose("damaris_client_comm_get" + ,"client_comm", &comm, PDI_INOUT + , NULL); + + //damaris_parameter_get("WIDTH" , &WIDTH , sizeof(int)); + //damaris_parameter_get("HEIGHT", &HEIGHT, sizeof(int)); + //damaris_parameter_get("DEPTH" , &DEPTH , sizeof(int)); + //damaris_parameter_get("whd_layout" , &whd_layout , sizeof(int)); + + int int_size = sizeof(int); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "WIDTH", PDI_OUT + ,"prm_buffer", &WIDTH, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "HEIGHT", PDI_OUT + ,"prm_buffer", &HEIGHT, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "DEPTH", PDI_OUT + ,"prm_buffer", &DEPTH, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "whd_layout", PDI_OUT + ,"prm_buffer", &whd_layout, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + + MPI_Comm_rank(comm , &rank_client); + MPI_Comm_size(comm , &size_client); + + if (verbose > 0 ) + fprintf(stdout,"C++ Input paramaters found: v=%d r=%d (0 is not found)\n",verbose, rank_only); + + // Dynamically update the size used in the Damaris layout configuration + //damaris_parameter_set("size" , &size_client , sizeof(int)); + PDI_multi_expose("damaris_parameter_set" + ,"prm_name", "size", PDI_OUT + ,"prm_buffer", &size_client, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + + int64_t position_cube[3]; + int local_width, local_height, local_depth ; + int rank_start = 0 ; + + + if (size_client > DEPTH) { + printf("ERROR: MPI process count (size=%2d) is greater than the blocked index (DEPTH=%2d)\t", size_client, DEPTH ); + exit(-1); + } + // used with: + local_width = WIDTH ; // WIDTH/size; + local_height = HEIGHT; + local_depth = DEPTH/size_client; + + position_cube[0] = rank_client*local_depth; + position_cube[1] = 0; + position_cube[2] = 0; + + rank_start = rank_client * local_width * local_height ; + + // allocate the local data array + int cube[local_depth][local_height][local_width]; + float cube_f[local_depth][local_height][local_width]; + + // set the appropriate position for the current rank + //damaris_set_position("cube_i",position_cube); + //damaris_set_position("cube_f",position_cube); + PDI_multi_expose("damaris_set_position" + ,"pos_var_name", "cube_i", PDI_OUT + ,"position_cube", position_cube, PDI_OUT + , NULL); + PDI_multi_expose("damaris_set_position" + ,"pos_var_name", "cube_f", PDI_OUT + ,"position_cube", position_cube, PDI_OUT + , NULL); + + // do not do this here as we will not get an updated value (if time-varying="true" ) + // damaris_write("last_iter" , &MAX_CYCLES); + + sleep(time); + + int i, d, h, w ; + for( i=0; i < MAX_CYCLES; i++) { + double t1 = MPI_Wtime(); + int sequence ; + sequence = i ; // this is the start of the sequence for this iteration + if (verbose == 0) { // default - do not print values to screen + + for ( d = 0; d < local_depth; d++){ + for ( h = 0; h < local_height; h++){ + for ( w = 0; w < local_width; w++) { + + cube[d][h][w] = (int) sequence + rank_start; + cube_f[d][h][w] = (float) sequence + rank_start +0.5f; + if (rank_only==0) sequence++; + } + } + } + } else if (verbose == 1) { // print values to screen + int current_rank = 0 ; + int sending_rank = 0 ; + // serialize the print statements + while ( current_rank < size_client) + { + printf("\n"); + if (rank_client == current_rank) { // start of serialized section + + for ( d = 0; d < local_depth; d++){ + for ( h = 0; h < local_height; h++){ + for ( w = 0; w < local_width; w++) { + cube[d][h][w] = (int) sequence + rank_start; + cube_f[d][h][w] = (float) sequence + rank_start +0.5f; + printf("%2d\t", cube[d][h][w] ); + if (rank_only==0) sequence++; + } + printf("\n"); + } + printf("\n"); + } + fflush(stdin); + sending_rank = current_rank ; + current_rank++ ; + } // end of serialized section + MPI_Bcast(¤t_rank,1, MPI_INT,sending_rank, comm); + sending_rank = current_rank ; + } // end of in-order loop over ranks + } else if (verbose == 2) { // print sumation values to screen + + long int sumdata = 0 ; + for ( d = 0; d < local_depth; d++){ + for ( h = 0; h < local_height; h++){ + for ( w = 0; w < local_width; w++) { + cube[d][h][w] = (int) sequence + rank_start ; + cube_f[d][h][w] = (float) sequence + rank_start +0.5f; + sumdata += cube[d][h][w] ; + if (rank_only==0) sequence++; + } + } + } + + // Each MPI process sends its rank to reduction, root MPI process collects the result + long int reduction_result = 0; + MPI_Reduce(&sumdata, &reduction_result, 1, MPI_LONG, MPI_SUM, 0, comm); + + + if (rank_client == 0) + printf("C++ iteration %d , Sum () = %ld\n", i, reduction_result ); + + double array_sum = (double) reduction_result ; + //damaris_write("array_sum" , &array_sum); // Used to confirm the summation value found in Dask + PDI_multi_expose("damaris_write" + ,"w_var_name", "array_sum", PDI_OUT + ,"array_sum", &array_sum, PDI_OUT + , NULL); + } + + //damaris_write("cube_i" , cube); + //damaris_write("cube_f" , cube_f); + PDI_multi_expose("damaris_write" + ,"w_var_name", "cube_i", PDI_OUT + ,"cube", cube, PDI_OUT + , NULL); + PDI_multi_expose("damaris_write" + ,"w_var_name", "cube_f", PDI_OUT + ,"cube_f", cube_f, PDI_OUT + , NULL); + + //damaris_write("last_iter" , &MAX_CYCLES); // The Damaris XML variable has time-varing=true so we must give an updated value at each iteration + PDI_multi_expose("damaris_write" + ,"w_var_name", "last_iter", PDI_OUT + ,"MAX_CYCLES", &MAX_CYCLES, PDI_OUT + , NULL); + sleep(time); + + //damaris_end_iteration(); + PDI_event("damaris_end_iteration"); + MPI_Barrier(comm); + + // sleep(time); + + double t2 = MPI_Wtime(); + + if(rank_client == 0) { + if (verbose > 0 ) + printf("C++ iteration %d done in %f seconds\n",i,(t2-t1)); + } + fflush(stdin); + } // end of for loop over MAX_CYCLES + + //damaris_stop(); + PDI_event("damaris_stop"); + } + + //damaris_finalize(); + PDI_event("finalize"); + PDI_finalize(); + MPI_Finalize(); + + return 0; +} diff --git a/plugins/damaris/example/python/3dmesh_py.py b/plugins/damaris/example/python/3dmesh_py.py new file mode 100755 index 000000000..bc5538da1 --- /dev/null +++ b/plugins/damaris/example/python/3dmesh_py.py @@ -0,0 +1,166 @@ +# Python code: 3dmesh_py.py +# Damaris example of obtaining data from a simulation via Python +# +# mpirun --oversubscribe --host ubu20-hvvm-c -np 5 ./3dmesh_py 3dmesh_py.xml -i 3 -v 2 -r +# +# Example output: +# ScriptManager has found a script which has a file field named: 3dmesh_py.py +# Input paramaters found: v=2 r=1 (0 is not found) +# Input paramaters found: v=2 r=1 (0 is not found) +# Input paramaters found: v=2 r=1 (0 is not found) +# Input paramaters found: v=2 r=1 (0 is not found) +# Iteration 0 Rank 0 Sum = 0 +# Iteration 0 Rank 1 Sum = 16384 +# Iteration 0 Rank 2 Sum = 32768 +# Iteration 0 Rank 3 Sum = 49152 +# Iteration 0 done in 1.001990 seconds +# cube_i +# cube_f +# Info from Python: Iteration 0 Data found: cube_i[ P3_B0 ].sum() = 49152 +# Info from Python: Iteration 0 Data found: cube_i[ P1_B0 ].sum() = 16384 +# Info from Python: Iteration 0 Data found: cube_i[ P0_B0 ].sum() = 0 +# Info from Python: Iteration 0 Data found: cube_i[ P2_B0 ].sum() = 32768 +# for variable cube_i the number of domains (== clients x blocks_per_client) for variable last_iter: 4 +# for variable cube_i block sources list: [3, 1, 0, 2] + +import numpy as np +np.set_printoptions(threshold=np.inf) + + +# DD (AKA Damaris Data) is a dictionary that has been filled by the +# Damaris server process with NumPy arraysthat point to the data variables +# that is exposed in the simulation. The Damaris source file that implements +# thisis PyAction, found in the src/scripts/ and include/damaris/scripts +# directories. Damaris must be exposed to the Python +# XML element by including its name i.e. MyPyAction in the following example: +# +# +# +# +# +# +# +# The Damaris server processes also present three dictionaries, damaris_env, dask_env and iteration_data +# containing various data about the simulation as well as the variable data itself, packaged as Numpy arrays. +# DD['damaris_env'].keys() - The global Damaris environment data +# (['is_dedicated_node', # +# 'is_dedicated_core', # +# 'servers_per_node', # Number of Damaris server ranks per node +# 'clients_per_node', # Number of Damaris client ranks per node +# 'ranks_per_node', # Total number of ranks per node +# 'cores_per_node', # Total number of ranks per node (yes, the same as above) +# 'number_of_nodes', # The total number of nodes used in the simulation +# 'simulation_name', # The name of the simulation (specified in Damaris XML file) +# 'simulation_magic_number' # Unique number for a simulation run (used in constructing name of Dask workers.) +# ]) +# +# DD['dask_env'].keys() - The Dask environment data, +# (['dask_scheduler_file', # if an empty string then no Dask scheduler was found +# 'dask_workers_name', # Each simulation has a uniquely named set of workers +# 'dask_nworkers', # The total number of dask workers (== 'servers_per_node' x 'number_of_nodes') +# 'dask_threads_per_worker' # Dask workers can have their own threads. Specify as nthreads="1" in Damris XML file +# ]) +# +# DD['iteration_data'].keys() - A single simulation iteration. +# Contains the iteration number and a list of sub-dictionaries, +# one for each *Damaris variable* that has been exposed to the Python +# interface. i.e. specified with the script="MyAction" as in the example above +# (['iteration', # The iteration number as an integer. +# 'cube_i', # A Damaris variable dictionary - the name relates to the variable name used in the Damaris XML file +# '...', # A Damaris variable dictionary +# '...' # A Damaris variable dictionary +# ]) +# +# A Damaris variable dictionary has the following structure +# DD['iteration_data']['cube_i'].keys() +# (['numpy_data', +# 'sort_data', +# 'type_string' # possibly to be removed as this information can be obtained from the NumPy array itself +# ]) +# +# DD['iteration_data']['cube_i']['sort_data'] +# sort_data is a list, that can be sorted on (possibly required to be transformed to tuple) which +# when sorted, the list values can be used to reconstruct the whole array using Dask: +# ['string', 'string', [ ]] +# A specific example: +# ['S0_I1_', 'P0_B0', [ 0, 9, 12 ]] +# The string 'S0_I1_' indicates 'S' for server and 'I' for iteration. +# The magic number is needed as the data is published to a Dask server +# The string 'P0_B0' indciates the dictionary key of Numpy data (see next description for explanation of 'P' and 'B') +# The list [ 0, 9, 12 ] indicates the offestes into the global array from where the NumPy data is mapped +# (The size of the NumPy array inicates the block size of the data) +# +# +# And, finally, the NumPy data is present in blocks, given by keys constructed as described below +# DD['iteration_data']['cube_i']['numpy_data'].keys() +# (['P0_B0', +# 'P1_B0' +# ]) + +# Damaris NumPy data keys: 'P' + damaris client number + '_B' + domain number +# The client number is the source of the data (i.e. it is the Damaris client number that wrote the data) +# The domain number is the result of multiple calls to damaris_write_block() +# or 0 if only damaris_write() API is used or a single block only was written. +# +# N.B. Only the data for the current iteration is available - and it is Read Only. +# If it is needed later it needs to be saved somehow and re-read on the +# next iteration. When connected to a Dask scheduler then the data can be saved on +# the distributed workers. + + + +def main(DD): + try: + # These two dictionaries are set up in the PyAction constructor + # and are static. + damaris_dict = DD['damaris_env'] + dask_dict = DD['dask_env'] + # This third dictionary is set up in PyAction::PassDataToPython() and is + # typically different each iteration. + iter_dict = DD['iteration_data'] + # This is the iteration value the from Damaris perspective + # i.e. It is the number of times damaris_end_iteration() has been called + it = iter_dict['iteration'] + + if it == 0: + print('The DamarisData dictionaries are:') + keys = list(DD.keys()) + print(keys) + + # These are the variables that have been published to Python by the Damaris server process: + print('The DamarisData variables available are :') + keys = list(iter_dict.keys()) + for data_key in keys : + if (data_key != 'iteration'): + print(data_key) + + # We know the variable names as they match what is in the Damaris XML file + cube_i = iter_dict['cube_i'] + # There will be one key and corresponding NumPy array for each block of the variable + total_sum = 0 + for key in cube_i['numpy_data'].keys() : + cube_i_numpy = cube_i['numpy_data'][key] # This is our NumPy array + print('Python iteration ', it, ', Data found: cube_i[',key,'].sum() = ', cube_i_numpy.sum() ) + total_sum += cube_i_numpy.sum() + + print('Python iteration ', it, ', Sum() = ', total_sum ) + + + + except KeyError as err: + print('KeyError: No damaris data of name: ', err) + except PermissionError as err: + print('PermissionError!: ', err) + except ValueError as err: + print('Damaris Data is read only!: ', err) + except UnboundLocalError as err: + print('Damaris data not assigned!: ', err) + finally: + pass + + +if __name__ == '__main__': + main(DamarisData) diff --git a/plugins/damaris/example/python/3dmesh_py.xml b/plugins/damaris/example/python/3dmesh_py.xml new file mode 100644 index 000000000..a4572cb94 --- /dev/null +++ b/plugins/damaris/example/python/3dmesh_py.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/damaris/example/python/3dmesh_py.yml b/plugins/damaris/example/python/3dmesh_py.yml new file mode 100644 index 000000000..7533f957b --- /dev/null +++ b/plugins/damaris/example/python/3dmesh_py.yml @@ -0,0 +1,135 @@ +# only the following config is passed to PDI +pdi: + metadata: # type of small values for which PDI keeps a copy + size: int + data: # type of values for which PDI does not keep a copy + is_client: int # equivalent to fti_head + plugins: + #mpi: + damaris: + #init_on_event: 1 + communicator: MPI_COMM_WORLD + architecture: + sim_name: 3dmesh_col_wf + domains: 1 + buffer_size: 536870912 + placement: + start: + stride: + blocksize: + mask: + dedicated: + core: 1 + node: 0 + parameters: + - parameter: + name: WIDTH + type: int + value: 16 + - parameter: + name: HEIGHT + type: int + value: 8 + - parameter: + name: DEPTH + type: int + value: 4 + - parameter: + name: size + type: int + value: 4 + - parameter: + name: whd_layout + type: int + value: 2 + datasets: + - dataset: + name: cube_i + type: scalar + layout: cells_whd_wf + mesh: mesh + centering: nodal + script: MyPyAction + - dataset: + name: cube_f + type: scalar + layout: cells_whd_wf_float + mesh: mesh + centering: nodal + script: MyPyAction + - dataset: + name: last_iter + type: scalar + layout: one_int + time_varying: true + mesh: mesh + script: MyPyAction + - dataset: + name: array_sum + type: scalar + layout: one_double + time_varying: true + mesh: mesh + script: MyPyAction + layouts: + - layout: + name: cells_whd_dl + type: int + dimensions: 'WIDTH,HEIGHT,DEPTH/size' + global: 'WIDTH,HEIGHT,DEPTH' + ghosts: '0:0,0:0,0:0' + - layout: + name: cells_whd_hm + type: int + dimensions: 'WIDTH,HEIGHT/size,DEPTH' + global: 'WIDTH,HEIGHT,DEPTH' + ghosts: '0:0,0:0,0:0' + - layout: + name: cells_whd_wf_original + type: int + dimensions: 'WIDTH/size,HEIGHT,DEPTH' + global: 'WIDTH,HEIGHT,DEPTH' + ghosts: '0:0,0:0,0:0' + - layout: + name: cells_whd_wf + type: int + dimensions: 'WIDTH/size,HEIGHT,DEPTH' + global: 'WIDTH,HEIGHT,DEPTH' + ghosts: '0:0,0:0,0:0' + - layout: + name: cells_whd_wf_float + type: float + dimensions: 'WIDTH/size,HEIGHT,DEPTH' + global: 'WIDTH,HEIGHT,DEPTH' + ghosts: '0:0,0:0,0:0' + - layout: + name: one_int + type: int + dimensions: '1' + global: '1' + - layout: + name: one_double + type: double + dimensions: '1' + global: '1' + pyscript: + name: MyPyAction + file: 3dmesh_py.py # can be absolute or relative path + scheduler_file: dask_file.json + #execution: 1 + language: python + #scope: core + #external: false + frequency: 1 + #nthreads: 1 + #timeout: 2 + #keep_workers: no + #comment: "" + log: + #file_name: 2dmesh # default = $sim_name + rotation_size: 5 + log_level: info + flush: true + + + diff --git a/plugins/damaris/example/python/3dmesh_py_domains.c b/plugins/damaris/example/python/3dmesh_py_domains.c new file mode 100644 index 000000000..b830d3c66 --- /dev/null +++ b/plugins/damaris/example/python/3dmesh_py_domains.c @@ -0,0 +1,277 @@ +#include +#include +#include +#include +#include + +#include +//#include "Damaris.h" +#include +#include + +#include "pdi.h" + +/** + A Damaris example of using Python integration with Dask distributed. This version sets up a dataset + which has multiple domains (or blocks) written per iteration, and the sum of the data in the blocks is + compared between this simulation code and the Python code (3dmesh_dask.py) that is passed data via Damaris. + + To run this example, a Dask scheduler needs to be spun up: + + dask-scheduler --scheduler-file "/home/user/dask_file.json" & + + The --scheduler-file argument must match what is in the Damaris XML file tag. + + Then run the simulation: (assumes 4 Damaris clients and 2 Damaris server cores as per the xml file) + + mpirun --oversubscribe --host ubu20-hvvm-c -np 6 ./3dmesh_py_domains 3dmesh_dask.xml -i 10 -r -d 4 + + N.B. Set the global mesh size values WIDTH, HEIGHT and DEPTH using the XML input file. + Set the name of the Python script to run in the tag + + The simulation code (via Damaris pyscript class) will create the Dask workers (one per Damaris server core) + and have them connect to the Dask scheduler. The simulation code will remove the workers at the end of the execution, + unless keep-workers="yes" is specified in 3dmesh_dask.xml tag +*/ + +void print_usage(char* exename) { + fprintf(stderr,"Usage: %s <3dmesh_dask.xml> [-i I] [-d D] [-r] [-s S]\n",exename); + fprintf(stderr,"-i I I is the number of iterations of simulation to run\n"); + fprintf(stderr,"-r Array values set as rank of process\n"); + fprintf(stderr,"-d D D is the number of domains to split data into (must divide into Width perfectly)\n"); + fprintf(stderr,"-s S S is integer time to sleep in seconds between iterations\n"); +} + +int WIDTH; +int HEIGHT; +int DEPTH; +int MAX_CYCLES ; + + +int main(int argc, char** argv) +{ + if(argc < 2) + { + print_usage(argv[0]) ; + exit(0); + } + + MPI_Init(&argc, &argv); + PC_tree_t conf = PC_parse_path(argv[1]); + PDI_init(PC_get(conf, ".pdi")); + + //damaris_initialize(argv[1],MPI_COMM_WORLD); + PDI_event("initialize"); // or init + //PDI_event("init"); + + int verbose = 0; + int rank_only = 0; + int current_arg = 2 ; + int time = 1 ; + int domains = 1 ; + MAX_CYCLES = 5; // default number of iterations to run + while (current_arg < argc ) + { + if (strcmp(argv[current_arg],"-v") == 0) { + current_arg++; + verbose = atoi(argv[current_arg]); + } + else if (strcmp(argv[current_arg],"-r") == 0) + rank_only = 1 ; + else if (strcmp(argv[current_arg],"-i") == 0) { + current_arg++; + MAX_CYCLES = atoi(argv[current_arg]); + } else if (strcmp(argv[current_arg],"-d") == 0) { + current_arg++; + domains = atoi(argv[current_arg]); + } else if (strcmp(argv[current_arg],"-h") == 0) { + print_usage(argv[0]) ; + exit(0); + } + + current_arg++; + } + + int size_client, rank_client, whd_layout; + int is_client = -1; + //int err = damaris_start(&is_client); + + PDI_multi_expose("damaris_start" + ,"is_client", &is_client, PDI_INOUT + , NULL); + + + //if(err == DAMARIS_OK && is_client) { + if(is_client) { + + MPI_Comm comm; + //damaris_client_comm_get(&comm); + PDI_multi_expose("damaris_client_comm_get" + ,"client_comm", &comm, PDI_INOUT + , NULL); + + // We get the dimensions from the XML input file. + // We could have, conversely, got the values from the command line (or somewhere else) + // And then used damaris_paramater_set() to tell Damaris how big the arrays will be. + //damaris_parameter_get("WIDTH" , &WIDTH , sizeof(int)); + //damaris_parameter_get("HEIGHT", &HEIGHT, sizeof(int)); + //damaris_parameter_get("DEPTH" , &DEPTH , sizeof(int)); + + int int_size = sizeof(int); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "WIDTH", PDI_OUT + ,"prm_buffer", &WIDTH, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "HEIGHT", PDI_OUT + ,"prm_buffer", &HEIGHT, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "DEPTH", PDI_OUT + ,"prm_buffer", &DEPTH, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + + // This is only be available on the first iteration if time-varing=false + // damaris_write("last_iter" , &MAX_CYCLES); // we could set it now and publish it in Dask to keep it around as needed. + + MPI_Comm_rank(comm , &rank_client); + MPI_Comm_size(comm , &size_client); + + fprintf(stdout,"Input paramaters found: v=%d r=%d (0 is not found)\n",verbose, rank_only) ; + + // Dynamically update the size used in the Damaris layout configuration + //damaris_parameter_set("size" , &size_client , sizeof(int)) ; + PDI_multi_expose("damaris_parameter_set" + ,"prm_name", "size", PDI_OUT + ,"prm_buffer", &size_client, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + + + // Dynamically update the number of domains being used in the Damaris layout configuration + //damaris_parameter_set("blocks" , &domains , sizeof(int)) ; + PDI_multi_expose("damaris_parameter_set" + ,"prm_name", "blocks", PDI_OUT + ,"prm_buffer", &domains, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + + + + int64_t position_cube[3]; + int local_width, local_height, local_depth ; + // rank_start is the value a ranks data will start at and then be incremented + // at each position onward (if -r not present) + int rank_start = 0 ; + + + if (size_client > DEPTH) { + printf("ERROR: MPI process count (size=%2d) is greater than the blocked index (DEPTH=%2d)\t", size_client, DEPTH ); + exit(-1); + } + if (WIDTH % domains != 0) { + int temp_int =WIDTH % domains ; + printf("ERROR: WIDTH mod domains must divide perfectly %d mod %d = %d\t", WIDTH, domains, temp_int ); + exit(-1); + } + + // used with: + // These sizes do not change + local_width = WIDTH / domains ; + local_height = HEIGHT ; + local_depth = DEPTH / size_client ; + int i, d, h, w ; + for( i=0; i < MAX_CYCLES; i++) + { + double array_sum = 0.0 ; + long int reduction_result = 0 ; + double t1 = MPI_Wtime() ; + + //damaris_write("last_iter" , &MAX_CYCLES) ; // The Damaris XML variable has time-varing=true + PDI_multi_expose("damaris_write" + ,"w_var_name", "last_iter", PDI_OUT + ,"MAX_CYCLES", &MAX_CYCLES, PDI_OUT + , NULL); + + // We are writing multiple blocks of data per Damaris client rank. + // This requires that we use damaris_set_block_position() and damaris_write_block() API calls + // instead of damaris_set_position() and damaris_write() + for (int block = 0 ; block < domains ; block++) + { + position_cube[0] = rank_client*local_depth ; + position_cube[1] = 0 ; + position_cube[2] = block * local_width ; + + rank_start = rank_client * local_width * local_height ; + + // allocate the local data array + int cube[local_depth][local_height][local_width] ; + + // set the appropriate position for the current rank + //damaris_set_block_position("cube_i", block, position_cube) ; + PDI_multi_expose("damaris_set_block_position" + ,"bpos_var_name", "cube_i", PDI_OUT + ,"block", &block, PDI_OUT + ,"position_cube", position_cube, PDI_OUT + , NULL); + + int sequence ; + sequence = i ; // this is the start of the sequence for this iteration + + // print sumation values to screen + long int sumdata = 0 ; + for ( d = 0; d < local_depth; d++){ + for ( h = 0; h < local_height; h++){ + for ( w = 0 ; w < local_width; w++) { + cube[d][h][w] = (int) sequence + rank_start ; + sumdata += cube[d][h][w] ; + if (rank_only==0) sequence++; + } + } + } + + // Each MPI process sends its rank to reduction, root MPI process collects the result + MPI_Reduce(&sumdata, &reduction_result, 1, MPI_LONG, MPI_SUM, 0, comm) ; + array_sum += reduction_result ; + + //damaris_write_block("cube_i" , block, cube) ; + PDI_multi_expose("damaris_write_block" + ,"wb_var_name", "cube_i", PDI_OUT + ,"block", &block, PDI_OUT + ,"cube", cube, PDI_OUT + , NULL); + + } // end of loop over blocks + sleep(time) ; + MPI_Barrier(comm) ; + double t2 = MPI_Wtime() ; + if(rank_client == 0) { + printf("C++ iteration %d done in %f seconds\n",i,(t2-t1)) ; + fflush(stdin); + } + if (rank_client == 0) + printf("C++ iteration %d Sum = %f\n", i, array_sum ) ; + //damaris_write("array_sum" , &array_sum) ; // Used to confirm the summation value found in Dask + PDI_multi_expose("damaris_write" + ,"w_var_name", "array_sum", PDI_OUT + ,"array_sum", &array_sum, PDI_OUT + , NULL); + + //damaris_end_iteration(); + PDI_event("damaris_end_iteration"); + } // end of for loop over MAX_CYCLES + + //damaris_stop(); + PDI_event("damaris_stop"); + } + + //damaris_finalize(); + PDI_event("finalize"); + PDI_finalize(); + MPI_Finalize() ; + return 0; +} diff --git a/plugins/damaris/example/python/CMakeLists.txt b/plugins/damaris/example/python/CMakeLists.txt new file mode 100644 index 000000000..1abf779cb --- /dev/null +++ b/plugins/damaris/example/python/CMakeLists.txt @@ -0,0 +1,13 @@ +add_definitions(-DPARALLEL) + +add_executable (3dmesh_py 3dmesh_py.c) +set_property(TARGET 3dmesh_py PROPERTY C_STANDARD 99) +target_link_libraries (3dmesh_py PDI::PDI_C MPI::MPI_CXX) +set_target_properties (3dmesh_py PROPERTIES LINK_FLAGS "-Wl,-export-dynamic") +#INSTALL(TARGETS 3dmesh_py RUNTIME DESTINATION bin) + +add_executable (3dmesh_py_domains 3dmesh_py_domains.c) +set_property(TARGET 3dmesh_py_domains PROPERTY C_STANDARD 99) +target_link_libraries (3dmesh_py_domains PDI::PDI_C MPI::MPI_CXX) +set_target_properties (3dmesh_py_domains PROPERTIES LINK_FLAGS "-Wl,-export-dynamic") +#INSTALL(TARGETS 3dmesh_py_domains RUNTIME DESTINATION bin) diff --git a/plugins/damaris/example/python/README.md b/plugins/damaris/example/python/README.md new file mode 100644 index 000000000..856f3d863 --- /dev/null +++ b/plugins/damaris/example/python/README.md @@ -0,0 +1,116 @@ +# Damaris with Python and Dask Support + +## Running the Examples +There are 2 examples in the example/python directory that can be useful to understand what is happening. + +Please note: The examples are only installed if CMake was configured with -DDAMARIS_BUILD_EXAMPLES=ON. + And, if they are installed in a read-only system directory, you will need to copy them + to your local directory area. They do not write a lot of data. + +### Example 1 +A very basic example that only uses Python functionality (no Dask). +From directory : /example/python +Executable : 3dmesh_py +YML config : 3dmesh_py.yml +Python script : 3dmesh_py.py + +``` +Usage: 3dmesh_py <3dmesh_py.yml> [-v] [-r] [-s X] +-v X = 0 default, do not print arrays + X = 1 Verbose mode, prints arrays + X = 2 Verbose mode, prints summation of arrays +-r Array values set as rank of process\n"); +-s Y is integer time to sleep in seconds between iterations +-i I is the number of iterations of simulation to run\ + + mpirun --oversubscribe -np 5 ./3dmesh_py 3dmesh_py.yml -i 3 -v 2 -r +``` + +Expected result: +For the same iteration, the sum output from C++ printed to screen should match the value computed by the 3dmesh_py.py script + +N.B. This example will fail if run over multiple nodes, or with multiple Damaris server cores, as the Python script only has access to NumPy data of the clients that are working with the server core. + +To see this in action, change to in file 3dmesh_py.yml and run: +``` + # Note the extra rank requested: -np 6, to account for the extra Damaris server core. + mpirun --oversubscribe -np 6 ./3dmesh_py 3dmesh_py.yml -i 3 -v 2 -r +``` + +You will notice 2 outputs from the Python script on each iteration, one output for each Damaris server, showing a sum, and still only a single output of the sum from C++. You will notice that the sum of the 2 Python outputs will be equal to the C++ total. +``` +C++ iteration 0 , Sum () = 98304 +... +Python iteration 0 , Sum() = 16384 +Python iteration 0 , Sum() = 81920 + +``` +This shows that distributed nature of the data, with each Damaris server looking after data from particular Damaris server ranks (2 clients per server in this case). + +### Example 2 +From directory : /example/python +Executable : 3dmesh_py_domains +YML config : 3dmesh_dask.yml +Python script : 3dmesh_dask.py + +An example of using Python integration with Dask distributed. This version sets deals with the distributed data on the Python side by creating a dask.array, so it can sum of the data in the blocks over multiple Damaris server cores and even over distributed nodes. + +To run this example, a Dask scheduler needs to be spun up: +``` + # N.B. best to run this in a separate xterm session as it is quite verbose + dask-scheduler --scheduler-file "path/to/dask_file.json" & +``` + +The --scheduler-file argument must match what is specified in the Damaris YML file + +```yaml +pdi: + ... + plugins: + ... + damaris: + ... + pyscript: + name: MyPyAction + file: path/to/3dmesh_dask.py # can be absolute or relative path + scheduler_file: path/to/dask_file.json + ... +``` + +To run the simulation: +Assumes 4 Damaris clients and 2 Damaris server cores as per the xml file +i.e. the YML input file (3dmesh_dask.yml) ] contains + +```yaml +pdi: + ... + plugins: + ... + damaris: + ... + architecture: + ... + dedicated: + core: 2 + node: 0 + ... +``` + +Usage: 3dmesh_py_domains <3dmesh_dask.yml> [-i I] [-d D] [-r] [-s S]; +-i I I is the number of iterations of simulation to run +-r Array values set as rank of process +-d D D is the number of domains to split data into (must divide into WIDTH value in XML file perfectly) +-s S S is integer time to sleep in seconds between iterations + +mpirun --oversubscribe -np 6 ./3dmesh_py_domains 3dmesh_dask.yml -i 10 -r -d 4 +``` + +The simulation code (via Damaris pyscript class) will create the Dask workers (one per Damaris server core) and have them connect to the Dask scheduler. The simulation code will remove the workers at the end of the execution, unless we have ```keep_workers: yes``` specified in 3dmesh_dask.yml. + +To stop the scheduler: +``` +DASK_SCHEDULER_FILE=$HOME/dask_file.json # must match what you are using above +DASK_SCHED_STR=\'$DASK_SCHEDULER_FILE\' +python3 -c "from dask.distributed import Client; client= Client(scheduler_file=$DASK_SCHED_STR, timeout='2s'); client.shutdown()" +``` + diff --git a/plugins/damaris/example/python/dask_file.json b/plugins/damaris/example/python/dask_file.json new file mode 100644 index 000000000..76d7a03fe --- /dev/null +++ b/plugins/damaris/example/python/dask_file.json @@ -0,0 +1,10 @@ +{ + "type": "Scheduler", + "id": "Scheduler-1f6e29d5-90d0-48f5-b2f8-6ca6446909a9", + "address": "tcp://131.254.16.79:8786", + "services": { + "dashboard": 8787 + }, + "started": 1736863766.0072548, + "workers": {} +} \ No newline at end of file diff --git a/plugins/damaris/example/storage/2dmesh.c b/plugins/damaris/example/storage/2dmesh.c new file mode 100644 index 000000000..5f36a8af2 --- /dev/null +++ b/plugins/damaris/example/storage/2dmesh.c @@ -0,0 +1,275 @@ +#include +#include +#include +#include +#include +//#include "Damaris.h" +#include +#include + +#include "pdi.h" + +#define MAX_CYCLES 3 + + +int WIDTH; +int HEIGHT; +int domains; // change the number of domains from .xml file (both from the tag and domains parameter) +int size; +int rank; +int local_width; +int local_height; +int GX0; // **************************************************** +int GX1; // * The ghost zones for each process will be something like: +int GY0; // * ghost="GX0:GX1,GY0:GY1". Do not forget to update the related parameters as well. +int GY1; // **************************************************** +int total_width; +int total_height; +int ghost_value = 42; + + +void normalWrite(int iteration , int* array) { + + int (*parray)[total_height] = (int (*)[total_height]) array; + int x,y; + + int offset_width = rank*local_width; + int offset_height = 0; + + int64_t position_space[2]; + + position_space[0] = offset_width; + position_space[1] = offset_height; + + for(x = 0; x < total_width; x++) + for(y = 0; y < total_height; y++){ + + if ((x < GX0) || (y < GY0)) + parray[x][y] = ghost_value; + else if ((x >= total_width - GX1) || (y >= total_height - GY1)) + parray[x][y] = ghost_value; + else + parray[x][y] = rank + iteration; + } + + //damaris_set_position("space",position_space); + PDI_multi_expose("damaris_set_position" + ,"pos_var_name", "space", PDI_OUT + ,"position_space", position_space, PDI_OUT + , NULL); + + //damaris_write("space",parray); + PDI_multi_expose("damaris_write" + ,"w_var_name", "space", PDI_OUT + ,"parray", parray, PDI_OUT + , NULL); + + //damaris_end_iteration(); + PDI_event("damaris_end_iteration"); +} + +void blockWrite(int iteration , int* array){ + + int (*parray)[total_height] = (int (*)[total_height]) array; + int dom; + + for(dom=0; dom= total_width - GX1) || (y >= total_height - GY1)) + parray[x][y] = ghost_value; + else + parray[x][y] = rank*10 +dom + iteration; + } + } + + //damaris_set_block_position("space", dom, position_space); + PDI_multi_expose("damaris_set_block_position" + ,"bpos_var_name", "space", PDI_OUT + ,"dom", &dom, PDI_OUT + ,"position_space", position_space, PDI_OUT + , NULL); + + //damaris_write_block("space", dom, array); + PDI_multi_expose("damaris_write_block" + ,"wb_var_name", "space", PDI_OUT + ,"dom", &dom, PDI_OUT + ,"array", array, PDI_OUT + , NULL); + } + + //damaris_end_iteration(); + PDI_event("damaris_end_iteration"); +} + +int main(int argc, char** argv) +{ + if ( argc != 2 ) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(0); + } + + MPI_Init(&argc, &argv); + PC_tree_t conf = PC_parse_path(argv[1]); + + PDI_init(PC_get(conf, ".pdi")); + + //PDI_event("initialize"); // or init + PDI_event("init"); + //damaris_initialize(argv[1],MPI_COMM_WORLD); + //MPI_Comm comm = MPI_COMM_WORLD; + //MPI_Comm_rank(MPI_COMM_WORLD , &rank); + //MPI_Comm_size(MPI_COMM_WORLD , &size); + + + int is_client = -1; + + PDI_multi_expose("damaris_start" + ,"is_client", &is_client, PDI_INOUT + , NULL); + + printf("-------------------------------------------------------------------------------------D: :) ;) is_client = %d\n", is_client); + + //if((err == DAMARIS_OK || err == DAMARIS_NO_SERVER) && is_client) { + if(is_client) { + + + //Evaluation of metadate, etc... + + int dsize[2]; + dsize[0] = 32; + dsize[1] = 16; + PDI_expose("dsize", dsize, PDI_OUT); + + MPI_Comm client_comm; + //damaris_client_comm_get(&comm); + PDI_multi_expose("damaris_client_comm_get" + ,"client_comm", &client_comm, PDI_INOUT + , NULL); + + + /* + damaris_parameter_get("WIDTH" , &WIDTH , sizeof(int)); + damaris_parameter_get("HEIGHT" , &HEIGHT , sizeof(int)); + damaris_parameter_get("domains", &domains , sizeof(int)); + damaris_parameter_get("GX0" , &GX0 , sizeof(int)); + damaris_parameter_get("GY0" , &GY0 , sizeof(int)); + damaris_parameter_get("GX1" , &GX1 , sizeof(int)); + damaris_parameter_get("GY1" , &GY1 , sizeof(int)); + */ + int int_size = sizeof(int); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "HEIGHT", PDI_OUT + ,"prm_buffer", &HEIGHT, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "WIDTH", PDI_OUT + ,"prm_buffer", &WIDTH, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "domains", PDI_OUT + ,"prm_buffer", &domains, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "GX0", PDI_OUT + ,"prm_buffer", &GX0, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "GX1", PDI_OUT + ,"prm_buffer", &GX1, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "GY0", PDI_OUT + ,"prm_buffer", &GY0, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + PDI_multi_expose("damaris_parameter_get" + ,"prm_name", "GY1", PDI_OUT + ,"prm_buffer", &GY1, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + + + MPI_Comm_rank(client_comm , &rank); + MPI_Comm_size(client_comm , &size); + + assert(size < WIDTH) ; + + //damaris_parameter_set("size" , &size, sizeof(int)) ; + //PDI_expose("size", &size, PDI_OUT); /*If the parameter size depends on size, this can work*/ + PDI_multi_expose("damaris_parameter_set" + ,"prm_name", "size", PDI_OUT + ,"prm_buffer", &size, PDI_INOUT + ,"prm_size", &int_size, PDI_OUT + , NULL); + + local_width = WIDTH/size; + local_height = HEIGHT/domains; + + total_width = local_width + GX0 + GX1; // GX:GX + total_height = local_height + GY0 + GY1; // GY:GY + + int (*space)[total_height] = malloc((total_height)*(total_width)*sizeof(int)); + int i,j; + + for(i=0; i < MAX_CYCLES; i++) { + double t1 = MPI_Wtime(); + + if (domains == 1) + normalWrite(i , (int*)space); + else + blockWrite(i , (int*)space); + + MPI_Barrier(client_comm); + + double t2 = MPI_Wtime(); + + if(rank == 0) { + printf("2dmesh: Iteration %d done in %f seconds\n",i,(t2-t1)); + } + } + + + /*if (rank == 0) + { + printf("\nTotal array for rank 0 is: \n"); + for (i = 0; i < total_width; i++) { + for (j = 0; j < total_height; j++) + printf("%3d ", space[i][j]); + + printf("\n"); + } + }*/ + + //damaris_stop(); + PDI_event("damaris_stop"); + + free(space); + } + + //damaris_finalize(); + PDI_event("finalize"); + + PDI_finalize(); + PC_tree_destroy(&conf); + + MPI_Finalize(); + return 0; +} + diff --git a/plugins/damaris/example/storage/2dmesh.xml b/plugins/damaris/example/storage/2dmesh.xml new file mode 100644 index 000000000..fc099e043 --- /dev/null +++ b/plugins/damaris/example/storage/2dmesh.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/damaris/example/storage/2dmesh.yml b/plugins/damaris/example/storage/2dmesh.yml new file mode 100644 index 000000000..76efe990e --- /dev/null +++ b/plugins/damaris/example/storage/2dmesh.yml @@ -0,0 +1,170 @@ +# only the following config is passed to PDI +pdi: + metadata: # type of small values for which PDI keeps a copy + size: int + data: # type of values for which PDI does not keep a copy + is_client: int # equivalent to fti_head + plugins: + #mpi: + damaris: + #init_on_event: 1 + communicator: MPI_COMM_WORLD + architecture: + sim_name: 2dmesh + domains: 2 + placement: + start: + stride: + blocksize: + mask: + dedicated: + core: 1 + node: 0 + parameters: + - parameter: + name: WIDTH + type: int + value: 16 + - parameter: + name: HEIGHT + type: int + value: 16 + - parameter: + name: size + type: int + value: '$size' + depends_on: size + - parameter: + name: domains + type: int + value: 2 + - parameter: + name: GX0 + type: int + value: 2 + - parameter: + name: GY0 + type: int + value: 3 + - parameter: + name: GX1 + type: int + value: 1 + - parameter: + name: GY1 + type: int + value: 4 + datasets: + - dataset: + name: space + type: scalar + layout: cells + mesh: mesh2d + centering: nodal + storage: MyStore + - dataset: + name: coord/candy_x + type: scalar + layout: cells + mesh: mesh2d + centering: nodal + storage: MyStore + - dataset: + name: coord/sub_coord/candy_xyz + type: scalar + layout: cells + mesh: mesh2d + centering: nodal + storage: MyStore + - dataset: + name: coord/candy_y + type: scalar + layout: cells + mesh: mesh2d + centering: nodal + storage: MyStore + - dataset: + name: coord/candy_z + type: scalar + layout: cells + mesh: mesh2d + centering: nodal + storage: MyStore + - dataset: + name: coordinate/candy_x + type: scalar + layout: cells + mesh: mesh2d + centering: nodal + storage: MyStore + - dataset: + name: coordinate/candy_y + type: scalar + layout: cells + mesh: mesh2d + centering: nodal + storage: MyStore + - dataset: + name: coordinate/sub_coord1/sub_coord2/candy_xyz + type: scalar + layout: cells + mesh: mesh2d + centering: nodal + storage: MyStore + - dataset: + name: coordinate/candy_z + type: scalar + layout: cells + mesh: mesh2d + centering: nodal + storage: MyStore + layouts: + - layout: + name: cells + type: int + dimensions: [ '(WIDTH/size)+(GX0+GX1)' , '(HEIGHT/domains)+(GY0+GY1)' ] # '(WIDTH/size)+(GX0+GX1),(HEIGHT/domains)+(GY0+GY1)' # + global: 'WIDTH,HEIGHT' + ghosts: 'GX0:GX1,GY0:GY1' + - layout: + name: coord/cells2 + type: int + dimensions: [ '(WIDTH/size)+(GX0+GX1)' , '(HEIGHT/domains)+(GY0+GY1)' ] # '(WIDTH/size)+(GX0+GX1),(HEIGHT/domains)+(GY0+GY1)' # + global: 'WIDTH,HEIGHT' + ghosts: 'GX0:GX1,GY0:GY1' + storages: + - storage: + name: MyStore + type: HDF5 + file_mode: FilePerCore # Or + files_path: ./HDF_files/ # Where to save files + #frequency: 1 + paraview: + script: path/to/script.py # can be absolute or relative path + #scripts: [ 'path/to/script1.py' , 'path/to/script2.py' ] + update_frequency: 1 + realtime_timestep: 0.1 + end_iteration: 0 + write_vtk: 0 + write_vtk_binary: true + #comment: "" + #pyscript: + #name: MyPyAction + #file: path/to/script.py # can be absolute or relative path + #scheduler_file: path/to/dask_scheduler.json + #execution: 1 + #language: python + #scope: core + #external: false + #frequency: 1 + #nthreads: 1 + #timeout: 2 + #keep_workers: no + #comment: "" + log: + file_name: 2dmesh # default = $sim_name + rotation_size: 5 + log_level: info + flush: true + + + diff --git a/plugins/damaris/example/storage/CMakeLists.txt b/plugins/damaris/example/storage/CMakeLists.txt new file mode 100644 index 000000000..9978a7b93 --- /dev/null +++ b/plugins/damaris/example/storage/CMakeLists.txt @@ -0,0 +1,6 @@ +add_definitions(-DPARALLEL) + +add_executable (2dmesh 2dmesh.c) +target_link_libraries (2dmesh PDI::PDI_C MPI::MPI_CXX) +set_target_properties (2dmesh PROPERTIES LINK_FLAGS "-Wl,-export-dynamic") +#INSTALL(TARGETS 2dmesh RUNTIME DESTINATION bin) \ No newline at end of file From 857f16dee86f4041933cd16c6b7869c016944100 Mon Sep 17 00:00:00 2001 From: Etienne Ndamlabin Date: Tue, 11 Feb 2025 16:08:15 +0100 Subject: [PATCH 02/42] Removing specific event calls, and adding event handling on data expose or on other configs options. --- .vscode/settings.json | 90 ++++++ plugins/damaris/cmake/FindDamaris.cmake | 2 +- plugins/damaris/damaris.cxx | 80 +++++- plugins/damaris/damaris_api_call_handler.cxx | 184 +++++++----- plugins/damaris/damaris_api_call_handler.h | 27 +- plugins/damaris/damaris_cfg.cxx | 177 +++++++++++- plugins/damaris/damaris_cfg.h | 46 ++- plugins/damaris/example/CMakeLists.txt | 6 +- plugins/damaris/example/example.c | 280 +++++++++++++++++++ plugins/damaris/example/example.yml | 108 +++++++ 10 files changed, 906 insertions(+), 94 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 plugins/damaris/example/example.c create mode 100644 plugins/damaris/example/example.yml diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..e7427eab5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,90 @@ +{ + "files.associations": { + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "csetjmp": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "any": "cpp", + "array": "cpp", + "atomic": "cpp", + "barrier": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cfenv": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "cinttypes": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "coroutine": "cpp", + "cstdint": "cpp", + "cuchar": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "source_location": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "latch": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "ranges": "cpp", + "scoped_allocator": "cpp", + "semaphore": "cpp", + "shared_mutex": "cpp", + "span": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "syncstream": "cpp", + "thread": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "valarray": "cpp", + "variant": "cpp" + } +} \ No newline at end of file diff --git a/plugins/damaris/cmake/FindDamaris.cmake b/plugins/damaris/cmake/FindDamaris.cmake index c7b896a79..050ad1ff5 100644 --- a/plugins/damaris/cmake/FindDamaris.cmake +++ b/plugins/damaris/cmake/FindDamaris.cmake @@ -14,7 +14,7 @@ asynchronous, in situ processing capabilities to MPI based simulation codes. include(FindPackageHandleStandardArgs) set(Damaris_BASE_DIR /usr/lib/damaris /opt/damaris) -set(Damaris_VERSIONS 1.11.1 1.11.2) +set(Damaris_VERSIONS 1.11.1 1.12.0) #Find Damaris base install dir set(Damaris_CANDIDATES ${Damaris_ROOT}) diff --git a/plugins/damaris/damaris.cxx b/plugins/damaris/damaris.cxx index 4222d9c5c..563ec7290 100644 --- a/plugins/damaris/damaris.cxx +++ b/plugins/damaris/damaris.cxx @@ -89,29 +89,37 @@ class damaris_plugin: public Plugin { damaris_plugin(Context& ctx, PC_tree_t config) : Plugin{ctx} , m_config{ctx, config} - , m_event_handler{m_config.xml_config_object(), m_config.communicator()} + , m_event_handler{m_config.xml_config_object(), m_config.communicator(), m_config.init_on_event() + , m_config.start_on_event(), m_config.stop_on_event()} { - multi_expose_transaction_dataname.clear(); - //multi_expose_transaction_dataref.clear(); + for (auto&& desc: m_config.descs()) {//add data callback only for awaited data + ctx.callbacks().add_data_callback([this](const std::string& name, Ref ref) { this->data(name, ref); }, + desc.first); + } + //Trigger other data callback for multi_expose_transaction_dataname OR remove totally !!!? - ctx.callbacks().add_data_callback([this](const std::string& name, Ref ref) { this->data(name, ref); }); ctx.callbacks().add_event_callback([this](const std::string& name) { this->event(name); }); ctx.logger().info("Plugin loaded successfully"); - /* - TODO: issue to handle + if (!m_config.init_on_event() && m_config.communicator()) { + //TODO: issue communicator to handle + /* MPI_Comm comm = *(static_cast(Ref_r{m_config.communicator().to_ref(context())}.get())); //context().logger().info("communicator `{}'", m_config.communicator().to_string(context())); m_damaris.reset(new Damaris_wrapper{context(), m_config.xml_config_object().c_str(), comm}); context().logger().info("Plugin initialized successfully"); - }*/ + */ + + std::string init_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_INITIALIZE); + PDI_status_t status = PDI_event(init_event_name.c_str()); + } } void data(const std::string& name, Ref ref) { - context().logger().info("data `{}' has been exposed", name); + //context().logger().info("data `{}' has been exposed", name); //Update damaris parameters if(m_config.is_needed_metadata(name)){ @@ -160,6 +168,54 @@ class damaris_plugin: public Plugin { prm_name_concat.pop_back(); context().logger().info("data `{}' Is a needed metadata for the evaluation of parameters {}", name, prm_name_concat); } + else if(m_config.is_dataset_to_write(name)){ + context().logger().info("is_dataset_to_write(`{}') = '{}'", name, m_config.is_dataset_to_write(name)); + if (Ref_r rref = ref) { + Dataset_Write_Info ds_write_info = m_config.get_dataset_write_info(name); + + //Only write when autorized! + if(ds_write_info.when.to_long(context())) { + context().logger().info("data `{}' will be written when = '{}'", name, ds_write_info.when.to_long(context())); + + int32_t block = ds_write_info.block.to_long(context()); + context().logger().info("data `{}' will be written in block = '{}'", name, block); + int64_t position[3] = { + ds_write_info.position[0].to_long(context()) + ,ds_write_info.position[1].to_long(context()) + ,ds_write_info.position[2].to_long(context()) + }; + context().logger().info("data `{}' will be written at: block '{}' and position '{}:{}:{}', when = '{}'", name, block, position[0], position[1], position[2], ds_write_info.when.to_long(context())); + + const void* data = static_cast(rref.get()); + + std::string set_block_pos_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_SET_BLOCK_POSITION); + m_event_handler.damaris_api_call_event(context(), m_damaris, set_block_pos_event_name, multi_expose_transaction_dataname, name, block, position); + + std::string write_block_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_WRITE_BLOCK); + m_event_handler.damaris_api_call_event(context(), m_damaris, write_block_event_name, multi_expose_transaction_dataname, name, block, data); + + if(m_config.is_there_after_write_events()) { + list after_write_events = m_config.get_after_write_events(); + for (auto it = after_write_events.begin(); it != after_write_events.end(); it++) { + std::string aw_event = it->c_str(); + if(m_event_handler.is_damaris_api_call_event(aw_event)){ + context().logger().info("event `{}' has been triggered", aw_event); + + context().logger().info("is_damaris_api_call_event ( `{}' ) = TRUE", aw_event); + m_event_handler.damaris_api_call_event(context(), m_damaris, aw_event, {}); + //m_event_handler.damaris_api_call_event(context(), m_damaris, aw_event, list expose_dataname = {}); + } + else {//Non Damaris call event + + } + } + } + } + } + else{ + context().logger().error("The Damaris need write access over the data (`{}')", name); + } + } else {//Handle other situations... multi_expose_transaction_dataname.emplace_back(name); //multi_expose_transaction_dataref.emplace_back(ref); @@ -170,12 +226,14 @@ class damaris_plugin: public Plugin { void event(const std::string& event_name) { - context().logger().info("event `{}' has been triggered", event_name); - if(m_event_handler.is_damaris_api_call_event(event_name)){ + context().logger().info("event `{}' has been triggered", event_name); context().logger().info("is_damaris_api_call_event ( `{}' ) = TRUE", event_name); m_event_handler.damaris_api_call_event(context(), m_damaris, event_name, multi_expose_transaction_dataname); + + multi_expose_transaction_dataname.clear(); + //multi_expose_transaction_dataref.clear(); } else {//Non Damaris call event @@ -184,8 +242,6 @@ class damaris_plugin: public Plugin { ~damaris_plugin() { - multi_expose_transaction_dataname.clear(); - //multi_expose_transaction_dataref.clear(); context().logger().info("Closing plugin"); } diff --git a/plugins/damaris/damaris_api_call_handler.cxx b/plugins/damaris/damaris_api_call_handler.cxx index 5560ef352..c6f85285a 100644 --- a/plugins/damaris/damaris_api_call_handler.cxx +++ b/plugins/damaris/damaris_api_call_handler.cxx @@ -51,6 +51,20 @@ Damaris_api_call_handler::Damaris_api_call_handler(std::string cfg_object, PDI:: m_communicator = comm; } +Damaris_api_call_handler::Damaris_api_call_handler(std::string cfg_object, PDI::Expression comm, bool init_on_event, bool start_on_event, bool stop_on_event) +{ + xml_config_object = cfg_object; + m_communicator = comm; + m_init_on_event = init_on_event; + m_start_on_event = start_on_event; + m_stop_on_event = stop_on_event; +} + +std::string Damaris_api_call_handler::get_event_name(Event_type event_type) +{ + return event_names.at(event_type); +} + bool Damaris_api_call_handler::is_damaris_api_call_event(std::string event_name) { for(auto event : event_names) { @@ -61,14 +75,23 @@ bool Damaris_api_call_handler::is_damaris_api_call_event(std::string event_name) } -void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptr &m_damaris, std::string event_name, list expose_dataname) +void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptr &m_damaris, std::string event_name, list expose_dataname, ...) { //************************************************************ */ //Events : Damaris Initialize and Damaris Start //************************************************************ */ if(event_name == event_names.at(Event_type::DAMARIS_INITIALIZE) || event_name == event_names.at(Event_type::DAMARIS_INITIALIZE_ALIAS)) { - damaris_pdi_init(ctx, m_damaris, xml_config_object.c_str()); + + damaris_pdi_init(ctx, m_damaris, xml_config_object.c_str()); + + if (!m_start_on_event) { + + ctx.logger().info("Plugin sent damaris_start() to Damaris, in initialize"); + + std::string start_event_name = this->get_event_name(Event_type::DAMARIS_START); + PDI_status_t status = PDI_event(start_event_name.c_str()); + } } else if(event_name == event_names.at(Event_type::DAMARIS_START)) { // DAMARIS_START @@ -314,37 +337,48 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptrc_str(), ++arg_pos, expose_dataname.size()); - - if (arg_pos == 1) - { - PDI_access(it->c_str(), (void**)&var_name, PDI_IN); - arg1_name = it->c_str(); - } - else if (arg_pos == 2){ - PDI_access(it->c_str(), (void**)&block, PDI_IN); - arg2_name = it->c_str(); - } - else if (arg_pos == 3){ - PDI_access(it->c_str(), (void**)&position, PDI_IN); - arg3_name = it->c_str(); + char* var_name; std::string arg1_name = "bpos_var_name"; + int32_t* block; std::string arg2_name = "dom"; + int64_t* position; std::string arg3_name = "position"; + + va_list extra_args; + va_start(extra_args, expose_dataname); + string data_name = va_arg(extra_args, string); + if(!data_name.empty()) { + var_name = (char*)data_name.c_str(); + *block = va_arg(extra_args, int32_t); + position = va_arg(extra_args, int64_t*); + } + else { + //Retrive parameters! sent via Multi expose, the three last sent data + int arg_pos = 0; + int nb_awaited_args = 3; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) + { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } + else if (arg_pos == 2){ + PDI_access(it->c_str(), (void**)&block, PDI_IN); + arg2_name = it->c_str(); + } + else if (arg_pos == 3){ + PDI_access(it->c_str(), (void**)&position, PDI_IN); + arg3_name = it->c_str(); + } + else + //if(nb_awaited_args <= arg_pos) + break; } - else - //if(nb_awaited_args <= arg_pos) - break; } ctx.logger().info("------------------- CALLING damaris_pdi_set_block_position arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, (int32_t) *block, arg3_name, *(int64_t*)position); @@ -356,38 +390,49 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptrc_str(), ++arg_pos, expose_dataname.size()); - - if (arg_pos == 1) - { - PDI_access(it->c_str(), (void**)&var_name, PDI_IN); - arg1_name = it->c_str(); - } - else if (arg_pos == 2){ - PDI_access(it->c_str(), (void**)&block, PDI_IN); - arg2_name = it->c_str(); - } - else if (arg_pos == 3){ - PDI_access(it->c_str(), (void**)&data, PDI_IN); - arg3_name = it->c_str(); + char* var_name; std::string arg1_name = "wb_var_name"; + int32_t* block; std::string arg2_name = "dom"; + void* data; std::string arg3_name = "data"; + + va_list extra_args; + va_start(extra_args, expose_dataname); + //if(string data_name = va_arg(extra_args, string)) { + string data_name = va_arg(extra_args, string); + if(!data_name.empty()) { + var_name = (char*)data_name.c_str(); + *block = va_arg(extra_args, int32_t); + data = va_arg(extra_args, void*);//const void* + } + else { + //Retrive parameters! sent via Multi expose, the three last sent data + int arg_pos = 0; + int nb_awaited_args = 3; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) + { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } + else if (arg_pos == 2){ + PDI_access(it->c_str(), (void**)&block, PDI_IN); + arg2_name = it->c_str(); + } + else if (arg_pos == 3){ + PDI_access(it->c_str(), (void**)&data, PDI_IN); + arg3_name = it->c_str(); + } + else + //if(nb_awaited_args <= arg_pos) + break; } - else - //if(nb_awaited_args <= arg_pos) - break; } ctx.logger().info("------------------- CALLING damaris_pdi_write_block arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, (int32_t) *block, arg3_name, *(int*)data); @@ -401,6 +446,7 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptrdamaris_pdi_end_iteration() ; //iteration++; @@ -418,11 +464,21 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptrdamaris_pdi_stop(); } - else if(event_name == event_names.at(Event_type::DAMARIS_FINALIZE)) { + else if(event_name == event_names.at(Event_type::DAMARIS_FINALIZE) + || event_name == event_names.at(Event_type::DAMARIS_FINALIZE_ALIAS)) { if (!m_damaris) { ctx.logger().warn("Trying to call damaris_strop() before plugin initialization (`{}')", event_name); return; } + + if (!m_stop_on_event) { + ctx.logger().info("Plugin sent damaris_stop() to Damaris, in finalization"); + + //std::string stop_event_name = this->get_event_name(Event_type::DAMARIS_STOP); + //PDI_status_t status = PDI_event(stop_event_name.c_str()); + + int stop_err = m_damaris->damaris_pdi_stop(); + } int err = m_damaris->damaris_pdi_finalize(); } diff --git a/plugins/damaris/damaris_api_call_handler.h b/plugins/damaris/damaris_api_call_handler.h index 24c6604d2..a257cc756 100644 --- a/plugins/damaris/damaris_api_call_handler.h +++ b/plugins/damaris/damaris_api_call_handler.h @@ -55,17 +55,20 @@ enum class Event_type { , DAMARIS_WRITE_BLOCK = 6 , DAMARIS_CLIENT_COMM_GET = 7 , DAMARIS_PARAMETER_SET = 8 - , DAMARIS_PARAMETER_GET = 9 - , DAMARIS_END_ITERATION = 10 - , DAMARIS_STOP = 11 - , DAMARIS_FINALIZE = 12 + , DAMARIS_PARAMETER_GET = 10 + , DAMARIS_END_ITERATION = 12 + , DAMARIS_GET_ITERATION = 13 + , DAMARIS_SIGNAL = 15 + , DAMARIS_BIND = 16 + , DAMARIS_STOP = 17 + , DAMARIS_FINALIZE = 18 + , DAMARIS_FINALIZE_ALIAS = 19 }; const std::unordered_map event_names = { {Event_type::DAMARIS_INITIALIZE, "initialize"} ,{Event_type::DAMARIS_INITIALIZE_ALIAS, "init"} ,{Event_type::DAMARIS_START, "damaris_start"} - ,{Event_type::DAMARIS_END_ITERATION, "damaris_end_iteration"} ,{Event_type::DAMARIS_SET_POSITION, "damaris_set_position"} ,{Event_type::DAMARIS_SET_BLOCK_POSITION, "damaris_set_block_position"} ,{Event_type::DAMARIS_WRITE, "damaris_write"} @@ -73,8 +76,13 @@ const std::unordered_map event_names = { ,{Event_type::DAMARIS_CLIENT_COMM_GET, "damaris_client_comm_get"} ,{Event_type::DAMARIS_PARAMETER_SET, "damaris_parameter_set"} ,{Event_type::DAMARIS_PARAMETER_GET, "damaris_parameter_get"} + ,{Event_type::DAMARIS_END_ITERATION, "damaris_end_iteration"} + ,{Event_type::DAMARIS_GET_ITERATION, "damaris_get_iteration"} + ,{Event_type::DAMARIS_SIGNAL, "damaris_signal"} + ,{Event_type::DAMARIS_BIND, "damaris_bind"} ,{Event_type::DAMARIS_STOP, "damaris_stop"} ,{Event_type::DAMARIS_FINALIZE, "finalize"} + ,{Event_type::DAMARIS_FINALIZE_ALIAS, "finalization"} }; class Damaris_api_call_handler @@ -82,13 +90,20 @@ class Damaris_api_call_handler std::string xml_config_object; PDI::Expression m_communicator; + bool m_init_on_event = false; + bool m_start_on_event = false; + bool m_stop_on_event = false; + public: + Damaris_api_call_handler(std::string cfg_object, PDI::Expression comm, bool init_on_event, bool start_on_event, bool stop_on_event); Damaris_api_call_handler(std::string cfg_object, PDI::Expression comm); Damaris_api_call_handler(std::string cfg_object); + std::string get_event_name(Event_type event_type); + bool is_damaris_api_call_event(std::string event_name); - void damaris_api_call_event(Context& ctx, unique_ptr &m_damaris, std::string event_name, list expose_dataname); + void damaris_api_call_event(Context& ctx, unique_ptr &m_damaris, std::string event_name, list expose_dataname, ...); private: void damaris_pdi_init(Context& ctx, unique_ptr &m_damaris, const char* damaris_xml_object) ; diff --git a/plugins/damaris/damaris_cfg.cxx b/plugins/damaris/damaris_cfg.cxx index ef288fab4..44212d010 100644 --- a/plugins/damaris/damaris_cfg.cxx +++ b/plugins/damaris/damaris_cfg.cxx @@ -61,6 +61,19 @@ using std::unordered_map; namespace damaris_pdi { +namespace { + + bool load_desc(unordered_map& descs, Context& ctx, const string& name, Desc_type desc_type) + { + auto&& result = descs.emplace(name, desc_type); + if (!result.second) { + //ctx.logger().warn("Duplicate use of a descriptor `{}' in `{}' (previously used in `{}')", name, desc_names.at(desc_type), desc_names.at(result.first->second)); + } + return result.second; + } + +} // namespace + /** * This variable contains Damaris xml config nested groups, with dataset elements to display in the XML config * It is possible to have nested groups, but in most of the cases, @@ -102,7 +115,13 @@ Damaris_cfg::Damaris_cfg(Context& ctx, PC_tree_t tree) } } else if (key == "init_on_event") { - m_init_on_event = to_long(value);// Default = true + m_init_on_event = to_long(value);// Default = false + } + else if (key == "start_on_event") { + m_start_on_event = to_long(value);// Default = false + } + else if (key == "stop_on_event") { + m_stop_on_event = to_long(value);// Default = false } else if (key == "parameters") { parse_parameters_tree(ctx, value); @@ -125,6 +144,24 @@ Damaris_cfg::Damaris_cfg(Context& ctx, PC_tree_t tree) else if (key == "pyscript") { parse_pyscript_tree(ctx, value); } + + else if (key == "write") { + parse_write_tree(ctx, value); + } + + else if (key == "after_write") { + if(!PC_status(value)) + { + if (!PC_status(PC_get(value, "[0]"))) {//Array [ev0,ev1,ev3] + each(value, [&](PC_tree_t event_name) { + m_after_write_events.emplace_back(to_string(event_name)); + }); + } + else {//ev0 + m_after_write_events.emplace_back(to_string(value)); + } + } + } /*else { throw Config_error{key_tree, "Unknown key in Damaris configuration: `{}'", key}; }*/ @@ -156,7 +193,7 @@ Damaris_cfg::Damaris_cfg(Context& ctx, PC_tree_t tree) m_xml_config_object = damarisXMLModifyModel.GetConfigString(); - printf("-------------------------------------------------------XML OBJECT MODIFIED----------------------------------------------\n%s", damarisXMLModifyModel.GetConfigString().c_str()); + //printf("-------------------------------------------------------XML OBJECT MODIFIED----------------------------------------------\n%s", damarisXMLModifyModel.GetConfigString().c_str()); } void Damaris_cfg::parse_architecture_tree(Context& ctx, PC_tree_t arch_tree){ @@ -280,6 +317,8 @@ void Damaris_cfg::parse_parameters_tree(Context& ctx, PC_tree_t parameters_tree_ depends_on_metadata.insert( {metadata_name, false} ); + + load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); }); } else {//d1 @@ -288,6 +327,8 @@ void Damaris_cfg::parse_parameters_tree(Context& ctx, PC_tree_t parameters_tree_ depends_on_metadata.insert( {metadata_name, false} ); + + load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); ctx.logger().info("--------------------------------------------------------------------------------PARAMETER {} depends on {}", prmxml.param_name_, metadata_name); } @@ -757,6 +798,95 @@ void Damaris_cfg::parse_pyscript_tree(Context& ctx, PC_tree_t pyscript_tree) damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); } +void Damaris_cfg::parse_write_tree(Context& ctx, PC_tree_t write_tree_list) +{ + // opt_each(write_tree_list, [&](PC_tree_t writes_tree) {//list of ds map + each(write_tree_list, [&](PC_tree_t writet_key, PC_tree_t write_ds_tree) {//each dataset to write + + std::string ds_name = to_string(writet_key);//the name of the data to write, if dataset not specified afterward! + Dataset_Write_Info ds_write_info; + + //dataset + PC_tree_t ds_name_tree = PC_get(write_ds_tree, ".dataset"); + if(!PC_status(ds_name_tree)) + { + ds_name = to_string(ds_name_tree); + std::cout << "INFO: damaris_cfg write_ds_tree :: ds_name = '" << ds_name << "'" << std::endl ; + } + //when + PC_tree_t ds_when_tree = PC_get(write_ds_tree, ".when"); + if(!PC_status(ds_when_tree)) + { + ds_write_info.when = to_string(ds_when_tree); + std::cout << "INFO: damaris_cfg write_ds_tree :: when = '" << ds_write_info.when << "'" << std::endl ; + } + //position + PC_tree_t ds_position_tree = PC_get(write_ds_tree, ".position"); + if(!PC_status(ds_position_tree)) + { + if (!PC_status(PC_get(ds_position_tree, "[0]"))) {//Array [p0,p1,p3] (1 to 3 elements) + int position_dim; PC_len(ds_position_tree, &position_dim); + std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: " << position_dim << std::endl ; + + int pos_idx = 0; + each(ds_position_tree, [&](PC_tree_t dim) { + ds_write_info.position[pos_idx] = to_string(dim); + pos_idx++; + }); + } + else {//p0 + ds_write_info.position[0] = to_string(ds_position_tree); + std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: 1" << std::endl ; + } + } + //block + PC_tree_t ds_block_tree = PC_get(write_ds_tree, ".block"); + if(!PC_status(ds_block_tree)) + { + ds_write_info.block = to_string(ds_block_tree); + std::cout << "INFO: damaris_cfg write_ds_tree :: block = '" << ds_write_info.block << "'" << std::endl ; + } + + /* + each(write_ds_tree, [&](PC_tree_t wdst_key, PC_tree_t value) {//storage info + std::string key = to_string(wdst_key); + + if (key == "dataset") { + ds_name = to_string(value); + } + else if (key == "when") { + ds_write_info.when = to_string(value); + } + else if (key == "position") { + if (!PC_status(PC_get(value, "[0]"))) {//Array [p0,p1,p3] (1 to 3 elements) + int position_dim; PC_len(value, &position_dim); + std::cout << "INFO: damaris_cfg ds '"<< ds_name <<"' will be written in dims: " << position_dim << std::endl ; + + int pos_idx = 0; + each(value, [&](PC_tree_t dim) { + ds_write_info.position[pos_idx] = to_long(dim); + pos_idx++; + }); + } + else {//p0 + ds_write_info.position[0] = to_long(value); + } + } + else if (key == "block") { + ds_write_info.block = to_long(value); + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized write map string: " << key << std::endl ; + } + }); + */ + + m_datasets_to_write.emplace(ds_name, ds_write_info); + + load_desc(m_descs, ctx, ds_name, Desc_type::DATA_TO_WRITE_WITH_BLOCK); + }); + //}); +} void Damaris_cfg::parse_log_tree(Context& ctx, PC_tree_t config) { @@ -810,6 +940,21 @@ void Damaris_cfg::parse_log_tree(Context& ctx, PC_tree_t config) } + + bool Damaris_cfg::is_dataset_to_write(std::string data_name) + { + bool is_dataset_to_write = false; + for(auto &datasets_to_write : m_datasets_to_write) { + if(data_name == datasets_to_write.first) + { + is_dataset_to_write = true; + break; + } + } + + return is_dataset_to_write; + } + bool Damaris_cfg::is_needed_metadata(std::string data_name) { bool is_needed_metadata = false; @@ -1108,10 +1253,38 @@ const std::unordered_map& Damaris_ return m_groups; } +const unordered_map& Damaris_cfg::descs() const +{ + return m_descs; +} + +const std::unordered_map& Damaris_cfg::datasets_to_write() const +{ + return m_datasets_to_write; +} + +Dataset_Write_Info Damaris_cfg::get_dataset_write_info(std::string data_name) const +{ + try{ + return m_datasets_to_write.at(data_name); + } catch (...) { + assert(false && "Trying to get inexistant damaris awaited dataset!"); + } +} bool Damaris_cfg::init_on_event() const { return m_init_on_event; } +bool Damaris_cfg::start_on_event() const +{ + return m_start_on_event; +} + +bool Damaris_cfg::stop_on_event() const +{ + return m_stop_on_event; +} + } // namespace damaris_pdi \ No newline at end of file diff --git a/plugins/damaris/damaris_cfg.h b/plugins/damaris/damaris_cfg.h index f2905f485..741c632aa 100644 --- a/plugins/damaris/damaris_cfg.h +++ b/plugins/damaris/damaris_cfg.h @@ -46,6 +46,8 @@ using PDI::Context; using std::unique_ptr; +using std::list; +using std::string; namespace damaris_pdi { @@ -68,12 +70,18 @@ struct Architecture_type { }; enum class Desc_type { - MPI_COMM, - STATUS, - DATA_SIZE, - HEAD, - STAGE_DIR, - STAGE_STATUS + DATA_TO_WRITE + ,DATA_TO_WRITE_WITH_BLOCK + //,DATA_TO_READ + ,PRM_REQUIRED_METADATA + ,PRM_TO_GET + ,PRM_TO_SET +}; + +struct Dataset_Write_Info { + PDI::Expression when = "1";//By default, always write as long as there are iteration going on + /*int64_t* */ PDI::Expression position[3] = {"0", "0", "0"};//Max Dim is 3 + /*int32_t */ PDI::Expression block = "0";//when domain = 1, which is the default behaviour }; @@ -90,7 +98,9 @@ class Damaris_cfg std::string m_xml_config_object; damaris::model::ModifyModel damarisXMLModifyModel; - bool m_init_on_event = true; + bool m_init_on_event = false; + bool m_start_on_event = false; + bool m_stop_on_event = false; int m_arch_domains ; int m_dc_cores_pernode ; @@ -112,7 +122,10 @@ class Damaris_cfg std::unordered_map m_groups; damaris::model::DamarisParaviewXML *m_paraview = NULL; damaris::model::DamarisPyScriptXML *m_pyscript = NULL; - + + std::unordered_map m_descs ; + std::unordered_map m_datasets_to_write; + list m_after_write_events; //In damaris parameter play similar role than metadata in PDI, in that other variable can be expressed by them // Here we express parameter in terms of PDI metadata, and when metadata are expose, @@ -163,6 +176,7 @@ void parse_storages_tree(Context& ctx, PC_tree_t storages_tree_list); void parse_meshes_tree(Context& ctx, PC_tree_t meshes_tree_list); void parse_paraview_tree(Context& ctx, PC_tree_t paraview_tree); void parse_pyscript_tree(Context& ctx, PC_tree_t pyscript_tree); +void parse_write_tree(Context& ctx, PC_tree_t write_tree_list); void parse_log_tree(Context& ctx, PC_tree_t config); void init_xml_config_object(){ @@ -184,14 +198,30 @@ void init_xml_config_object(){ const std::unordered_map& storages() const; const std::unordered_map& meshes() const; const std::unordered_map& groups() const; + + const std::unordered_map& descs() const; + const std::unordered_map& datasets_to_write() const; + + Dataset_Write_Info get_dataset_write_info(std::string data_name) const; + list get_after_write_events() const + { + return m_after_write_events; + } + bool is_there_after_write_events() const + { + return m_after_write_events.size(); + } bool init_on_event() const; + bool start_on_event() const; + bool stop_on_event() const; const std::unordered_map>& recover_var() const; const std::unordered_map>>& send_file() const; + bool is_dataset_to_write(std::string data_name); bool is_needed_metadata(std::string data_name); std::unordered_map> get_updatable_parameters(Context& ctx); diff --git a/plugins/damaris/example/CMakeLists.txt b/plugins/damaris/example/CMakeLists.txt index 19c2192f8..ddba576ba 100644 --- a/plugins/damaris/example/CMakeLists.txt +++ b/plugins/damaris/example/CMakeLists.txt @@ -1,3 +1,7 @@ add_subdirectory (storage) add_subdirectory (paraview) -add_subdirectory (python) \ No newline at end of file +add_subdirectory (python) + +add_executable (exemple exemple.c) +target_link_libraries (exemple PDI::PDI_C MPI::MPI_CXX) +set_target_properties (exemple PROPERTIES LINK_FLAGS "-Wl,-export-dynamic") \ No newline at end of file diff --git a/plugins/damaris/example/example.c b/plugins/damaris/example/example.c new file mode 100644 index 000000000..ffb2e31fa --- /dev/null +++ b/plugins/damaris/example/example.c @@ -0,0 +1,280 @@ +/******************************************************************************* + * Copyright (C) 2015-2019 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pdi.h" + +void init(int dsize[2], int pcoord[2], double dat[dsize[0]][dsize[1]]) +{ + for (int yy = 0; yy < dsize[0]; ++yy) { + for (int xx = 0; xx < dsize[1]; ++xx) { + dat[yy][xx] = 0; + } + } + if (pcoord[1] == 0) { + for (int yy = 0; yy < dsize[0]; ++yy) { + dat[yy][0] = 1000000; + } + } +} + +void iter(int dsize[2], double cur[dsize[0]][dsize[1]], double next[dsize[0]][dsize[1]]) +{ + int xx, yy; + for (xx = 0; xx < dsize[1]; ++xx) { + next[0][xx] = cur[0][xx]; + } + for (yy = 1; yy < dsize[0] - 1; ++yy) { + next[yy][0] = cur[yy][0]; + for (xx = 1; xx < dsize[1] - 1; ++xx) { + next[yy][xx] + = (cur[yy][xx] * .5) + (cur[yy][xx - 1] * .125) + (cur[yy][xx + 1] * .125) + (cur[yy - 1][xx] * .125) + (cur[yy + 1][xx] * .125); + } + next[yy][dsize[1] - 1] = cur[yy][dsize[1] - 1]; + } + for (xx = 0; xx < dsize[1]; ++xx) { + next[dsize[0] - 1][xx] = cur[dsize[0] - 1][xx]; + } +} + +void exchange(MPI_Comm cart_com, int dsize[2], double cur[dsize[0]][dsize[1]]) +{ + MPI_Status status; + int rank_source, rank_dest; + static MPI_Datatype column, row; + static int initialized = 0; + + if (!initialized) { + MPI_Type_vector(dsize[0] - 2, 1, dsize[1], MPI_DOUBLE, &column); + MPI_Type_commit(&column); + MPI_Type_contiguous(dsize[1] - 2, MPI_DOUBLE, &row); + MPI_Type_commit(&row); + initialized = 1; + } + + /* send down */ + MPI_Cart_shift(cart_com, 0, 1, &rank_source, &rank_dest); + MPI_Sendrecv( + &cur[dsize[0] - 2][1], + 1, + row, + rank_dest, + 100, /* send row before ghost */ + &cur[0][1], + 1, + row, + rank_source, + 100, /* receive 1st row (ghost) */ + cart_com, + &status + ); + + /* send up */ + MPI_Cart_shift(cart_com, 0, -1, &rank_source, &rank_dest); + MPI_Sendrecv( + &cur[1][1], + 1, + row, + rank_dest, + 100, /* send column after ghost */ + &cur[dsize[0] - 1][1], + 1, + row, + rank_source, + 100, /* receive last column (ghost) */ + cart_com, + &status + ); + + /* send to the right */ + MPI_Cart_shift(cart_com, 1, 1, &rank_source, &rank_dest); + MPI_Sendrecv( + &cur[1][dsize[1] - 2], + 1, + column, + rank_dest, + 100, /* send column before ghost */ + &cur[1][0], + 1, + column, + rank_source, + 100, /* receive 1st column (ghost) */ + cart_com, + &status + ); + + /* send to the left */ + MPI_Cart_shift(cart_com, 1, -1, &rank_source, &rank_dest); + MPI_Sendrecv( + &cur[1][1], + 1, + column, + rank_dest, + 100, /* send column after ghost */ + &cur[1][dsize[1] - 1], + 1, + column, + rank_source, + 100, /* receive last column (ghost) */ + cart_com, + &status + ); +} + +int main(int argc, char* argv[]) +{ + MPI_Init(&argc, &argv); + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + PC_tree_t conf = PC_parse_path(argv[1]); + + MPI_Comm main_comm = MPI_COMM_WORLD; + PDI_init(PC_get(conf, ".pdi")); + PDI_event("init"); + + int is_client = 1; + + //PDI_multi_expose("damaris_start" + //,"is_client", &is_client, PDI_INOUT + //, NULL); + + if(is_client) { + //*******************************************************************Only damaris clients run this section + + //Gets the communicator that the clients must use. + //damaris_client_comm_get(&comm); + //PDI_multi_expose("damaris_client_comm_get" + //,"client_comm", &main_comm, PDI_INOUT + //, NULL); + + PDI_expose("mpi_comm", &main_comm, PDI_INOUT); + + int psize_1d; + MPI_Comm_size(main_comm, &psize_1d); + int pcoord_1d; + MPI_Comm_rank(main_comm, &pcoord_1d); + + PDI_expose("mpi_rank", &pcoord_1d, PDI_OUT); + PDI_expose("mpi_size", &psize_1d, PDI_OUT); + //PDI_event("init"); + + long longval; + + int dsize[2]; + PC_int(PC_get(conf, ".datasize[0]"), &longval); + dsize[0] = longval; + PC_int(PC_get(conf, ".datasize[1]"), &longval); + dsize[1] = longval; + + int psize[2]; + PC_int(PC_get(conf, ".parallelism.height"), &longval); + psize[0] = longval; + PC_int(PC_get(conf, ".parallelism.width"), &longval); + psize[1] = longval; + + double duration; + PC_double(PC_get(conf, ".duration"), &duration); + + // get local & add ghosts to sizes + assert(dsize[0] % psize[0] == 0); + dsize[0] = dsize[0] / psize[0] + 2; + assert(dsize[1] % psize[1] == 0); + dsize[1] = dsize[1] / psize[1] + 2; + + assert(psize[1] * psize[0] == psize_1d); + + int cart_period[2] = {0, 0}; + MPI_Comm cart_com; + MPI_Cart_create(main_comm, 2, psize, cart_period, 1, &cart_com); + int pcoord[2]; + MPI_Cart_coords(cart_com, pcoord_1d, 2, pcoord); + + int ii = 0; + PDI_expose("iter", &ii, PDI_OUT); + PDI_expose("dsize", dsize, PDI_OUT); + PDI_expose("psize", psize, PDI_OUT); + PDI_expose("pcoord", pcoord, PDI_OUT); + + double(*cur)[dsize[1]] = malloc(sizeof(double) * dsize[1] * dsize[0]); + double(*next)[dsize[1]] = malloc(sizeof(double) * dsize[1] * dsize[0]); + + init(dsize, pcoord, cur); + + PDI_event("main_loop"); + double start = MPI_Wtime(); + int next_reduce = 0; + for (ii = 0;; ++ii) { + PDI_multi_expose("newiter", "iter", &ii, PDI_INOUT, "main_field", cur, PDI_INOUT, NULL); + + iter(dsize, cur, next); + exchange(cart_com, dsize, next); + double(*tmp)[dsize[1]] = cur; + cur = next; + next = tmp; + + if (ii >= next_reduce) { + double local_time, global_time; + local_time = MPI_Wtime() - start; + MPI_Allreduce(&local_time, &global_time, 1, MPI_DOUBLE, MPI_MAX, main_comm); + if (global_time >= duration) { + if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; STOP!!!\n", ii, global_time); + break; + } + int rem_iter = .9 * (duration - global_time) * (ii + 1) / (global_time + 0.1); + if (rem_iter < 1) rem_iter = 1; + next_reduce = ii + rem_iter; + if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; next_reduce=%7d\n", ii, global_time, next_reduce); + } + //PDI_event("damaris_end_iteration"); + } + //PDI_event("finalization"); + PDI_expose("iter", &ii, PDI_OUT); + PDI_expose("main_field", cur, PDI_OUT); + + //PDI_event("damaris_stop"); + //*******************************************************************END if(is_client) + }//END if(is_client) + PDI_event("finalization"); + + PDI_finalize(); + + PC_tree_destroy(&conf); + + //free(cur); + //free(next); + + MPI_Finalize(); +} diff --git a/plugins/damaris/example/example.yml b/plugins/damaris/example/example.yml new file mode 100644 index 000000000..d0e76d281 --- /dev/null +++ b/plugins/damaris/example/example.yml @@ -0,0 +1,108 @@ +# duration in seconds +duration: 0.75 +# global [height, width] (excluding boundary conditions or ghosts) +datasize: [60, 12] +# degree of parallelism +parallelism: { height: 3, width: 1 } + +# only the following config is passed to PDI +pdi: + metadata: # type of small values for which PDI keeps a copy + iter: int # current iteration id + dsize: { size: 2, type: array, subtype: int } # local data size including ghosts/boundary + psize: { size: 2, type: array, subtype: int } # number of processes in each dimension + pcoord: { size: 2, type: array, subtype: int } # coordinate of the process + data: # type of values for which PDI does not keep a copy + main_field: { size: [ '$dsize[0]', '$dsize[1]' ], type: array, subtype: double } + + plugins: + #mpi: + damaris: + init_on_event: 1 + communicator: MPI_COMM_WORLD + architecture: + sim_name: example + domains: 1 + dedicated: + core: 0 + node: 0 + parameters: + - parameter: + name: dsize0 + type: int + value: '$dsize[0]' + depends_on: dsize + - parameter: + name: dsize1 + type: int + value: '$dsize[1]' + depends_on: dsize + - parameter: + name: psize0 + type: int + value: '$psize[0]' + depends_on: psize + - parameter: + name: psize1 + type: int + value: '$psize[1]' + depends_on: psize + datasets: + - dataset: + name: main_field + layout: main_field_layout + mesh: mesh2d + centering: zonal + storage: hdf5_example + script: + visualizable: true + time_varying: true + #comment: This is the zonal pressure from our test simulation + layouts: + - layout: + name: main_field_layout + type: double + global: 'psize0*(dsize0-2),psize1*(dsize1-2)' + dimensions: [ 'dsize0', 'dsize1' ] # process dim, with ghosts/boundaries + ghosts: '1:1,1:1' + storages: + - storage: + name: hdf5_example + type: HDF5 + file_mode: Collective # or FilePerCore + files_path: # Where to save files + #frequency: 1 + + #Events sections + write: + main_field: # the name of the data to write, if dataset not specified afterward! + dataset: main_field + #when: '$iter<10' # do only write the first 10 iterations (0...9), Default at every iteration. + position: ['$pcoord[0]', '$pcoord[1]'] + #block: [...] # To be defined + after_write: damaris_end_iteration # applied for all the data... + # - *: aw_event # OR [aw_event1, aw_event1, ...] # applied for all the data... + # - data1_name: d1_aw_event # OR [d1_aw_event1, d1_aw_event2, ...] + # - data2_name: d2_aw_event # OR [d2_aw_event1, d2_aw_event2, ...] + + # TODO: + # a list or map of data (damaris parameters) to get/set (default: empty) + # if a prm is to be set and get, priority most be defined, and a politic of recurence if this happen several time (default: RR) + # Ex. + # paremeter_get: + # - prm1: + # priority: 0 + # paremeter_set: + # - prm1: + # priority: 1 + # - prm2: + paremeter_get: + paremeter_set: + + #Optional config, has a default behavior + log: + #file_name: example # default = $sim_name + rotation_size: 5 + log_level: info + flush: true + From 89787e464944d9ba3c3fdd9fe0bc70da7b958564 Mon Sep 17 00:00:00 2001 From: Etienne Ndamlabin Date: Thu, 27 Feb 2025 11:34:04 +0100 Subject: [PATCH 03/42] Debugging the mpi communicator issue; The Damaris plugin works alongside other plugins (trace, mpi, Decl'HDF5, etc.) --- plugins/damaris/damaris.cxx | 62 + plugins/damaris/damaris_cfg.cxx | 2626 +++++++++-------- plugins/damaris/damaris_cfg.h | 443 +-- .../damaris/example/HDF5_files/example_It0.h5 | Bin 0 -> 7808 bytes .../damaris/example/HDF5_files/example_It1.h5 | Bin 0 -> 7808 bytes .../damaris/example/HDF5_files/example_It2.h5 | Bin 0 -> 7808 bytes .../damaris/example/HDF5_files/example_It3.h5 | Bin 0 -> 7808 bytes .../damaris/example/HDF5_files/example_It4.h5 | Bin 0 -> 7808 bytes .../damaris/example/HDF5_files/example_It5.h5 | Bin 0 -> 7808 bytes .../damaris/example/HDF5_files/example_It6.h5 | Bin 0 -> 7808 bytes .../damaris/example/HDF5_files/example_It7.h5 | Bin 0 -> 7808 bytes .../damaris/example/HDF5_files/example_It8.h5 | Bin 0 -> 7808 bytes .../damaris/example/HDF5_files/example_It9.h5 | Bin 0 -> 7808 bytes plugins/damaris/example/example.c | 17 +- plugins/damaris/example/example.yml | 46 +- plugins/damaris/example/paraview/image.yml | 133 + 16 files changed, 1836 insertions(+), 1491 deletions(-) create mode 100644 plugins/damaris/example/HDF5_files/example_It0.h5 create mode 100644 plugins/damaris/example/HDF5_files/example_It1.h5 create mode 100644 plugins/damaris/example/HDF5_files/example_It2.h5 create mode 100644 plugins/damaris/example/HDF5_files/example_It3.h5 create mode 100644 plugins/damaris/example/HDF5_files/example_It4.h5 create mode 100644 plugins/damaris/example/HDF5_files/example_It5.h5 create mode 100644 plugins/damaris/example/HDF5_files/example_It6.h5 create mode 100644 plugins/damaris/example/HDF5_files/example_It7.h5 create mode 100644 plugins/damaris/example/HDF5_files/example_It8.h5 create mode 100644 plugins/damaris/example/HDF5_files/example_It9.h5 create mode 100644 plugins/damaris/example/paraview/image.yml diff --git a/plugins/damaris/damaris.cxx b/plugins/damaris/damaris.cxx index 563ec7290..50f9ab3b2 100644 --- a/plugins/damaris/damaris.cxx +++ b/plugins/damaris/damaris.cxx @@ -65,6 +65,7 @@ using std::string; using std::unique_ptr; using std::unordered_map; using std::unordered_set; +using std::dynamic_pointer_cast; using namespace PDI; using namespace damaris_pdi; @@ -216,6 +217,67 @@ class damaris_plugin: public Plugin { context().logger().error("The Damaris need write access over the data (`{}')", name); } } + else if(m_config.is_parameter_to_update(name)){ + std::pair prm_to_update_info = m_config.get_parameter_to_update_info(name); + std::string prm_name = prm_to_update_info.first; + size_t size; + + Ref_r rref = ref; + Ref_rw rwref = ref; + + if (rref && prm_to_update_info.second == Desc_type::PRM_TO_SET) { + Datatype_sptr ref_type = rref.type(); + if (auto&& scalar_type = dynamic_pointer_cast(ref_type)) { + size = rref.scalar_value(); + } else { + throw Type_error{"Damaris paramegter must be a scalar"}; + } + + std::string prm_set_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_PARAMETER_SET); + m_event_handler.damaris_api_call_event(context(), m_damaris, prm_set_event_name, multi_expose_transaction_dataname, prm_name, name, size); + } + else if (rwref && prm_to_update_info.second == Desc_type::PRM_TO_GET) { + Datatype_sptr ref_type = rwref.type(); + if (auto&& scalar_type = dynamic_pointer_cast(ref_type)) { + size = rwref.scalar_value(); + } else { + throw Type_error{"Damaris paramegter must be a scalar"}; + } + + std::string prm_get_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_PARAMETER_GET); + m_event_handler.damaris_api_call_event(context(), m_damaris, prm_get_event_name, multi_expose_transaction_dataname, prm_name, name, size); + } + else { + //Error handling! + } + } + //is_client_get !? + else if(name == m_config.is_client_dataset_name()) { + context().logger().info("'{}' == m_config.is_client_dataset_name() = '{}'", name, (name == m_config.is_client_dataset_name())); + + if (Ref_w wref = ref) { + *static_cast(wref.get()) = m_damaris->get_is_client(); + context().logger().info("------------------- CALLED is_client_dataset_name Return is_client = '{}')", m_damaris->get_is_client()); + } + else { + //MayBe a PDI_multi_expose is under traitement + multi_expose_transaction_dataname.emplace_back(name); + } + } + //client_comm_get !? + else if(name == m_config.client_comm_get_dataset_name()) { + if (Ref_w wref = ref) { + MPI_Comm client_comm; + int err = m_damaris->damaris_pdi_client_comm_get(&client_comm); + + *static_cast(wref.get()) = client_comm; + context().logger().info("------------------- CALLED is_client_dataset_name Return client_comm SETED)"); + } + else { + //MayBe a PDI_multi_expose is under traitement + multi_expose_transaction_dataname.emplace_back(name); + } + } else {//Handle other situations... multi_expose_transaction_dataname.emplace_back(name); //multi_expose_transaction_dataref.emplace_back(ref); diff --git a/plugins/damaris/damaris_cfg.cxx b/plugins/damaris/damaris_cfg.cxx index 44212d010..cfad4f274 100644 --- a/plugins/damaris/damaris_cfg.cxx +++ b/plugins/damaris/damaris_cfg.cxx @@ -23,1268 +23,1366 @@ * THE SOFTWARE. ******************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "damaris_cfg.h" - -using PDI::Context; -using PDI::each; -using PDI::opt_each; -using PDI::Config_error; -using PDI::Value_error; -using PDI::Expression; -using PDI::Impl_error; -using PDI::Ref; -using PDI::Ref_w; -using PDI::Ref_r; -using PDI::len; -using PDI::to_long; -using PDI::to_double; -using PDI::to_string; -using std::function; -using std::list; -using std::map; -using std::string; -using std::unique_ptr; -using std::unordered_map; - - - -namespace damaris_pdi { - -namespace { - - bool load_desc(unordered_map& descs, Context& ctx, const string& name, Desc_type desc_type) - { - auto&& result = descs.emplace(name, desc_type); - if (!result.second) { - //ctx.logger().warn("Duplicate use of a descriptor `{}' in `{}' (previously used in `{}')", name, desc_names.at(desc_type), desc_names.at(result.first->second)); - } - return result.second; - } - -} // namespace - - /** - * This variable contains Damaris xml config nested groups, with dataset elements to display in the XML config - * It is possible to have nested groups, but in most of the cases, - * we just have root groups containing directly the dataset elements - */ - std::vector root_groups_xml; - - // Array to store the nested groups names - const unsigned max_nested_groups = 5; - std::string nested_groups_names[max_nested_groups]; - char ds_elt_full_name_delimiter = '/'; - - void retrive_nested_groups(std::string& dataset_elt_full_name, char delimiter, std::string nested_groups_names[], unsigned& index); - template - void insert_dataset_elts_to_group(DS_TYPE varxml, std::string nested_groups_names[], unsigned index); - //void insert_dataset_elts_to_group(damaris::model::DamarisVarXML varxml, std::string nested_groups_names[], unsigned index); - - -// This constructor is called on the construction of the damaris_plugin struct/object -// This code is a mapping of the Damaris src/model/Model.xsd schema to PDI YAML -// The mapping should allow us to recreate a Damaris XML object from what is present -// in the YML file -Damaris_cfg::Damaris_cfg(Context& ctx, PC_tree_t tree) - :m_communicator{"MPI_COMM_WORLD"} -{ - init_xml_config_object(); - - each(tree, [&](PC_tree_t key_tree, PC_tree_t value) { - string key = to_string(key_tree); - if (key == "architecture") { - //default_when = to_string(value); - parse_architecture_tree(ctx, value); - } - else if (key == "communicator") { - - m_communicator = to_string(value); - if (!m_communicator) { - throw Config_error{key_tree, "no MPI communicator set", key}; - } - } - else if (key == "init_on_event") { - m_init_on_event = to_long(value);// Default = false - } - else if (key == "start_on_event") { - m_start_on_event = to_long(value);// Default = false - } - else if (key == "stop_on_event") { - m_stop_on_event = to_long(value);// Default = false - } - else if (key == "parameters") { - parse_parameters_tree(ctx, value); - } - else if (key == "datasets") { - parse_datasets_tree(ctx, value); - } - else if (key == "layouts") { - parse_layouts_tree(ctx, value); - } - else if (key == "meshes") { - parse_meshes_tree(ctx, value); - } - else if (key == "storages") { - parse_storages_tree(ctx, value); - } - else if (key == "paraview") { - parse_paraview_tree(ctx, value); - } - else if (key == "pyscript") { - parse_pyscript_tree(ctx, value); - } - - else if (key == "write") { - parse_write_tree(ctx, value); - } - - else if (key == "after_write") { - if(!PC_status(value)) - { - if (!PC_status(PC_get(value, "[0]"))) {//Array [ev0,ev1,ev3] - each(value, [&](PC_tree_t event_name) { - m_after_write_events.emplace_back(to_string(event_name)); - }); - } - else {//ev0 - m_after_write_events.emplace_back(to_string(value)); - } - } - } - /*else { - throw Config_error{key_tree, "Unknown key in Damaris configuration: `{}'", key}; - }*/ - }); - - parse_log_tree(ctx, tree); - - //Insert grouped dataset elements - for (int root_group_id = 0; root_group_id < root_groups_xml.size(); root_group_id++) { - damaris::model::DamarisGroupXML root_gp_xml = root_groups_xml[root_group_id]; - - m_groups.emplace(root_gp_xml.get_name() , root_gp_xml) ; - std::map find_replace_map = - { - {"_DATASET_ELEMENT_REGEX_", root_gp_xml.ReturnXMLForGroup() + "\n_DATASET_ELEMENT_REGEX_"} - }; - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - } - - //CleanUp XML OBJECT - std::map find_replace_map = - { - {"_DATASET_ELEMENT_REGEX_", ""} - ,{"_STORAGE_ELEMENT_REGEX_", ""} - ,{"_PLUGINS_REGEX_", ""} - ,{"_SCRIPTS_REGEX_", ""} - }; - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - - m_xml_config_object = damarisXMLModifyModel.GetConfigString(); - - //printf("-------------------------------------------------------XML OBJECT MODIFIED----------------------------------------------\n%s", damarisXMLModifyModel.GetConfigString().c_str()); -} - -void Damaris_cfg::parse_architecture_tree(Context& ctx, PC_tree_t arch_tree){ - - std::map find_replace_map = {}; - - //simulation name & Buffer - std::string sim_name = "damaris_pdi_simu"; - PC_tree_t sim_name_tree = PC_get(arch_tree, ".sim_name"); - if(!PC_status(sim_name_tree)) - { - sim_name = to_string(sim_name_tree); - } - //Buffer - std::string buffer_name = sim_name + "_buffer"; - long buffer_size = 67108864; - PC_tree_t buffer_size_tree = PC_get(arch_tree, ".buffer_size"); - if(!PC_status(buffer_size_tree)) - { - buffer_size = to_long(buffer_size_tree); - } - find_replace_map.insert({ - {"_SIM_NAME_",sim_name} - ,{"_SHMEM_BUFFER_BYTES_REGEX_", std::to_string(buffer_size)} - ,{"_SHMEM_NAME_", buffer_name} - }); - - //domains - int m_arch_domains = 1; - PC_tree_t domains_tree = PC_get(arch_tree, ".domains"); - if(!PC_status(domains_tree)) - { - m_arch_domains = to_long(domains_tree); - } - find_replace_map.insert({"_DOMAINS_REGEX_", std::to_string(m_arch_domains)}); - - //dedicated - int m_dc_cores_pernode = 0; - int m_dc_nodes = 0; - PC_tree_t arch_dedicated_tree = PC_get(arch_tree, ".dedicated"); - if(!PC_status(arch_dedicated_tree)) - { - int nb_subkey_dc = len(arch_dedicated_tree); - - for (int subkey_dc_id = 0; subkey_dc_id < nb_subkey_dc; subkey_dc_id++) { - string key_str = to_string(PC_get(arch_dedicated_tree, "{%d}", subkey_dc_id)); - - if (key_str == "core") { - m_dc_cores_pernode = to_long(PC_get(arch_dedicated_tree, ".core")); - } else if (key_str == "node") { - m_dc_nodes = to_long(PC_get(arch_dedicated_tree, ".node")); - } - } - } - find_replace_map.insert( - { - {"_DC_REGEX_", std::to_string(m_dc_cores_pernode)} - ,{"_DN_REGEX_", std::to_string(m_dc_nodes)} - } - ); - - //placement not yet used - PC_tree_t arch_placement_tree = PC_get(arch_tree, ".placement"); - if(!PC_status(arch_placement_tree)) - { - int nb_subkey_dc = len(arch_placement_tree); - - for (int subkey_pl_id = 0; subkey_pl_id < nb_subkey_dc; subkey_pl_id++) { - string key_str = to_string(PC_get(arch_placement_tree, "{%d}", subkey_pl_id)); - - if (key_str == "start") { - m_placement_start = to_long(PC_get(arch_placement_tree, ".start")); - } - else if (key_str == "stride") { - m_placement_stride = to_long(PC_get(arch_placement_tree, ".stride")); - } - else if (key_str == "blocksize") { - m_placement_blocksize = to_long(PC_get(arch_placement_tree, ".blocksize")); - } - else if (key_str == "mask") { - m_placement_mask_str = to_string(PC_get(arch_placement_tree, ".mask")); - } - } - //TODO: find_replace_map.insert( ); - } - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); -} - -void Damaris_cfg::parse_parameters_tree(Context& ctx, PC_tree_t parameters_tree_list) -{ - opt_each(parameters_tree_list, [&](PC_tree_t parameters_tree) {//each parameters (list of parameter) - each(parameters_tree, [&](PC_tree_t prm_tree_key, PC_tree_t parameter_tree) {//each parameter - - damaris::model::DamarisParameterXML prmxml{} ; - std::map find_replace_map = {}; - std::unordered_map depends_on_metadata; - bool is_dependent = false; + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include "damaris_cfg.h" + + using PDI::Context; + using PDI::each; + using PDI::opt_each; + using PDI::Config_error; + using PDI::Value_error; + using PDI::Expression; + using PDI::Impl_error; + using PDI::Ref; + using PDI::Ref_w; + using PDI::Ref_r; + using PDI::len; + using PDI::to_long; + using PDI::to_double; + using PDI::to_string; + using std::function; + using std::list; + using std::map; + using std::string; + using std::unique_ptr; + using std::unordered_map; + + + + namespace damaris_pdi { + + namespace { + + bool load_desc(unordered_map& descs, Context& ctx, const string& name, Desc_type desc_type) + { + auto&& result = descs.emplace(name, desc_type); + if (!result.second) { + //ctx.logger().warn("Duplicate use of a descriptor `{}' in `{}' (previously used in `{}')", name, desc_names.at(desc_type), desc_names.at(result.first->second)); + } + return result.second; + } + + } // namespace + + /** + * This variable contains Damaris xml config nested groups, with dataset elements to display in the XML config + * It is possible to have nested groups, but in most of the cases, + * we just have root groups containing directly the dataset elements + */ + std::vector root_groups_xml; + + // Array to store the nested groups names + const unsigned max_nested_groups = 5; + std::string nested_groups_names[max_nested_groups]; + char ds_elt_full_name_delimiter = '/'; + + void retrive_nested_groups(std::string& dataset_elt_full_name, char delimiter, std::string nested_groups_names[], unsigned& index); + template + void insert_dataset_elts_to_group(DS_TYPE varxml, std::string nested_groups_names[], unsigned index); + //void insert_dataset_elts_to_group(damaris::model::DamarisVarXML varxml, std::string nested_groups_names[], unsigned index); + + + // This constructor is called on the construction of the damaris_plugin struct/object + // This code is a mapping of the Damaris src/model/Model.xsd schema to PDI YAML + // The mapping should allow us to recreate a Damaris XML object from what is present + // in the YML file + Damaris_cfg::Damaris_cfg(Context& ctx, PC_tree_t tree) + :m_communicator{"MPI_COMM_WORLD"} + { + init_xml_config_object(); + + each(tree, [&](PC_tree_t key_tree, PC_tree_t value) { + string key = to_string(key_tree); + if (key == "architecture") { + //default_when = to_string(value); + parse_architecture_tree(ctx, value); + } + else if (key == "communicator") { + + m_communicator = to_string(value); + if (!m_communicator) { + throw Config_error{key_tree, "no MPI communicator set", key}; + } + } + else if (key == "init_on_event") { + m_init_on_event = to_long(value);// Default = false + } + else if (key == "start_on_event") { + m_start_on_event = to_long(value);// Default = false + } + else if (key == "stop_on_event") { + m_stop_on_event = to_long(value);// Default = false + } + else if (key == "parameters") { + parse_parameters_tree(ctx, value); + } + else if (key == "datasets") { + parse_datasets_tree(ctx, value); + } + else if (key == "layouts") { + parse_layouts_tree(ctx, value); + } + else if (key == "meshes") { + parse_meshes_tree(ctx, value); + } + else if (key == "storages") { + parse_storages_tree(ctx, value); + } + else if (key == "paraview") { + parse_paraview_tree(ctx, value); + } + else if (key == "pyscript") { + parse_pyscript_tree(ctx, value); + } + + else if (key == "write") { + parse_write_tree(ctx, value); + } + + else if (key == "parameter_get") { + parse_parameter_to_update_tree(ctx, value, Desc_type::PRM_TO_GET); + } + + else if (key == "parameter_set") { + parse_parameter_to_update_tree(ctx, value, Desc_type::PRM_TO_SET); + } + + else if (key == "after_write") { + if(!PC_status(value)) + { + if (!PC_status(PC_get(value, "[0]"))) {//Array [ev0,ev1,ev3] + each(value, [&](PC_tree_t event_name) { + m_after_write_events.emplace_back(to_string(event_name)); + }); + } + else {//ev0 + m_after_write_events.emplace_back(to_string(value)); + } + } + } + + else if (key == "start" || key == "get_is_client" || key == "is_client_get") { + if(!PC_status(value)) + { + m_is_client_dataset_name = to_string(value); + load_desc(m_descs, ctx, m_is_client_dataset_name, Desc_type::IS_CLIENT_GET); + } + } + + else if (key == "client_comm_get") { + if(!PC_status(value)) + { + m_client_comm_get_dataset_name = to_string(value); + load_desc(m_descs, ctx, m_client_comm_get_dataset_name, Desc_type::CLIENT_COMM_GET); + } + } + /*else { + throw Config_error{key_tree, "Unknown key in Damaris configuration: `{}'", key}; + }*/ + }); + + parse_log_tree(ctx, tree); + + //Insert grouped dataset elements + for (int root_group_id = 0; root_group_id < root_groups_xml.size(); root_group_id++) { + damaris::model::DamarisGroupXML root_gp_xml = root_groups_xml[root_group_id]; + + m_groups.emplace(root_gp_xml.get_name() , root_gp_xml) ; + std::map find_replace_map = + { + {"_DATASET_ELEMENT_REGEX_", root_gp_xml.ReturnXMLForGroup() + "\n_DATASET_ELEMENT_REGEX_"} + }; + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } + + //CleanUp XML OBJECT + std::map find_replace_map = + { + {"_DATASET_ELEMENT_REGEX_", ""} + ,{"_STORAGE_ELEMENT_REGEX_", ""} + ,{"_PLUGINS_REGEX_", ""} + ,{"_SCRIPTS_REGEX_", ""} + }; + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + + m_xml_config_object = damarisXMLModifyModel.GetConfigString(); + + //printf("-------------------------------------------------------XML OBJECT MODIFIED----------------------------------------------\n%s", damarisXMLModifyModel.GetConfigString().c_str()); + } + + void Damaris_cfg::parse_architecture_tree(Context& ctx, PC_tree_t arch_tree){ + + std::map find_replace_map = {}; + + //simulation name & Buffer + std::string sim_name = "damaris_pdi_simu"; + PC_tree_t sim_name_tree = PC_get(arch_tree, ".sim_name"); + if(!PC_status(sim_name_tree)) + { + sim_name = to_string(sim_name_tree); + } + //Buffer + std::string buffer_name = sim_name + "_buffer"; + long buffer_size = 67108864; + PC_tree_t buffer_size_tree = PC_get(arch_tree, ".buffer_size"); + if(!PC_status(buffer_size_tree)) + { + buffer_size = to_long(buffer_size_tree); + } + find_replace_map.insert({ + {"_SIM_NAME_",sim_name} + ,{"_SHMEM_BUFFER_BYTES_REGEX_", std::to_string(buffer_size)} + ,{"_SHMEM_NAME_", buffer_name} + }); + + //domains + int m_arch_domains = 1; + PC_tree_t domains_tree = PC_get(arch_tree, ".domains"); + if(!PC_status(domains_tree)) + { + m_arch_domains = to_long(domains_tree); + } + find_replace_map.insert({"_DOMAINS_REGEX_", std::to_string(m_arch_domains)}); + + //dedicated + int m_dc_cores_pernode = 0; + int m_dc_nodes = 0; + PC_tree_t arch_dedicated_tree = PC_get(arch_tree, ".dedicated"); + if(!PC_status(arch_dedicated_tree)) + { + int nb_subkey_dc = len(arch_dedicated_tree); + + for (int subkey_dc_id = 0; subkey_dc_id < nb_subkey_dc; subkey_dc_id++) { + string key_str = to_string(PC_get(arch_dedicated_tree, "{%d}", subkey_dc_id)); + + if (key_str == "core") { + m_dc_cores_pernode = to_long(PC_get(arch_dedicated_tree, ".core")); + } else if (key_str == "node") { + m_dc_nodes = to_long(PC_get(arch_dedicated_tree, ".node")); + } + } + } + find_replace_map.insert( + { + {"_DC_REGEX_", std::to_string(m_dc_cores_pernode)} + ,{"_DN_REGEX_", std::to_string(m_dc_nodes)} + } + ); + + //placement not yet used + PC_tree_t arch_placement_tree = PC_get(arch_tree, ".placement"); + if(!PC_status(arch_placement_tree)) + { + int nb_subkey_dc = len(arch_placement_tree); + + for (int subkey_pl_id = 0; subkey_pl_id < nb_subkey_dc; subkey_pl_id++) { + string key_str = to_string(PC_get(arch_placement_tree, "{%d}", subkey_pl_id)); + + if (key_str == "start") { + m_placement_start = to_long(PC_get(arch_placement_tree, ".start")); + } + else if (key_str == "stride") { + m_placement_stride = to_long(PC_get(arch_placement_tree, ".stride")); + } + else if (key_str == "blocksize") { + m_placement_blocksize = to_long(PC_get(arch_placement_tree, ".blocksize")); + } + else if (key_str == "mask") { + m_placement_mask_str = to_string(PC_get(arch_placement_tree, ".mask")); + } + } + //TODO: find_replace_map.insert( ); + } + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } + + void Damaris_cfg::parse_parameters_tree(Context& ctx, PC_tree_t parameters_tree_list) + { + opt_each(parameters_tree_list, [&](PC_tree_t parameters_tree) {//each parameters (list of parameter) + each(parameters_tree, [&](PC_tree_t prm_tree_key, PC_tree_t parameter_tree) {//each parameter + + damaris::model::DamarisParameterXML prmxml{} ; + std::map find_replace_map = {}; + std::unordered_map depends_on_metadata; + bool is_dependent = false; + + each(parameter_tree, [&](PC_tree_t prm_key, PC_tree_t value) {//parameter info + std::string key = to_string(prm_key); + + if (key == "name") { + prmxml.param_name_ = to_string(value); + } + else if (key == "type") { + prmxml.param_datatype_ = to_string(value); + } + else if (key == "value") { + prmxml.param_value_ = to_string(value); + m_parameter_expression.emplace(prmxml.param_name_, to_string(value)); + } + else if (key == "depends_on") { + is_dependent = true; + if (!PC_status(PC_get(value, "[0]"))) {//Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter + //int idx = 0; + each(value, [&](PC_tree_t metadata_name_tree) { + std::string metadata_name = to_string(metadata_name_tree); + + depends_on_metadata.insert( + {metadata_name, false} + ); + + load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); + }); + } + else {//d1 + std::string metadata_name = to_string(value); + //depends_on_metadata[metadata_name] = false; + depends_on_metadata.insert( + {metadata_name, false} + ); + + load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); + ctx.logger().info("--------------------------------------------------------------------------------PARAMETER {} depends on {}", prmxml.param_name_, metadata_name); + } + + + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized parameter map string: " << key << std::endl ; + } + }); + //m_parameter_expression.emplace(prmxml.param_name_, prmxml.param_value_); + m_parameter_depends_on.emplace(prmxml.param_name_, depends_on_metadata); + //set default value if depend on metadata + std::string numbers_types[] = {"short", "int", "integer", "float", "real", "double"}; + if(is_dependent && std::find(std::begin(numbers_types), std::end(numbers_types), prmxml.param_datatype_)) { + prmxml.param_value_ = "1"; //"0" + } + else { + ///??? + } + + m_parameters.emplace(prmxml.param_name_ , prmxml) ; + find_replace_map.insert( + {"_DATASET_ELEMENT_REGEX_", prmxml.ReturnXMLForParameter() + "\n_DATASET_ELEMENT_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + }); + }); + } + + void Damaris_cfg::parse_datasets_tree(Context& ctx, PC_tree_t datasets_tree_list) + { + opt_each(datasets_tree_list, [&](PC_tree_t datasets_tree) {//each datasets (list of dataset) + each(datasets_tree, [&](PC_tree_t ds_tree_key, PC_tree_t dataset_tree) {//each dataset + + damaris::model::DamarisVarXML vxml{} ; + std::map find_replace_map = {}; + unsigned name_index = 0; + std::string dataset_elt_full_name; + + each(dataset_tree, [&](PC_tree_t ds_key, PC_tree_t value) {//dataset info + std::string key = to_string(ds_key); + + int tf; // 0 is false, anything else is true + if (key == "name") { + dataset_elt_full_name = to_string(value); + retrive_nested_groups(dataset_elt_full_name + , ds_elt_full_name_delimiter + , nested_groups_names + , name_index); + + vxml.var_name_ = nested_groups_names[name_index-1]; //to_string(value); + } + else if (key == "layout") { + vxml.layout_name_ = to_string(value); + } + else if (key == "mesh") { + vxml.mesh_ = to_string(value); + } + else if (key == "centering") { + std::string t_centering = to_string(value); + vxml.set_centering(t_centering) ; + } + else if (key == "storage") { + vxml.store_ = to_string(value); + } + else if (key == "script") { + vxml.script_ = to_string(value); + } + else if (key == "unit") { + vxml.unit_ = to_string(value); + } + else if (key == "select_mem") { + vxml.select_mem_ = to_string(value); + } + else if (key == "select_file") { + vxml.select_file_ = to_string(value); + } + else if (key == "select_subset") { + vxml.select_subset_ = to_string(value); + } + else if (key == "ref") { + vxml.ref_ = to_string(value); + } + else if (key == "type") { + std::string in_type = to_string(value); + vxml.set_type( in_type ); + } + else if (key == "comment") { + vxml.comment_ = to_string(value); + } + else if (key == "visualizable") { + PC_bool(value, &tf); + vxml.visualizable_ = (tf == 0) ? false : true ; + } + else if (key == "time_varying") { + PC_bool(value, &tf); + vxml.time_varying_ = (tf == 0) ? false : true ; + } + else if (key == "enabled") { + PC_bool(value, &tf); + vxml.enabled_ = (tf == 0) ? false : true ; + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized variable map string: " << key << std::endl ; + } + }); + + if(dataset_elt_full_name.empty()) + throw Value_error{"ERROR: damaris_cfg variable name must not be empty"}; + + //m_datasets.emplace(vxml.var_name_ , vxml) ; + m_datasets.emplace(dataset_elt_full_name , vxml) ; + ctx.logger().info("------------------- Parsing damaris Variable '{}' , name_index = {} ", dataset_elt_full_name, name_index); + + if(name_index == 1) { + find_replace_map.insert( + {"_DATASET_ELEMENT_REGEX_", vxml.ReturnXMLForVariable() + "\n_DATASET_ELEMENT_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } + else {//In nested groups + insert_dataset_elts_to_group(vxml, nested_groups_names, name_index); + } + }); + }); + } + + void Damaris_cfg::parse_layouts_tree(Context& ctx, PC_tree_t layouts_tree_list) + { + opt_each(layouts_tree_list, [&](PC_tree_t layouts_tree) {//each layouts (list of layout) + each(layouts_tree, [&](PC_tree_t lts_key, PC_tree_t layout_tree) {//each layout + + damaris::model::DamarisLayoutXML layoutxml{} ; + std::map find_replace_map = {}; + unsigned name_index = 0; + std::string dataset_elt_full_name; + + each(layout_tree, [&](PC_tree_t lt_key, PC_tree_t value) {//layout info + std::string key = to_string(lt_key); + + int intb; // 0 is false, anything else is true + if (key == "name") { + dataset_elt_full_name = to_string(value); + retrive_nested_groups(dataset_elt_full_name + , ds_elt_full_name_delimiter + , nested_groups_names + , name_index); + + layoutxml.layout_name_ = nested_groups_names[name_index-1]; //to_string(value); + } + else if (key == "type") { + std::string in_datatype = to_string(value); + layoutxml.set_datatype( in_datatype ); + } + else if (key == "dimensions") { + + //Is there a way to determine if an expression is ready to be evaluated? ei, all the conponent have a value + if (!PC_status(PC_get(value, "[0]"))) {//Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter + int nb_layout_dims2; PC_len(value, &nb_layout_dims2); + std::cout << "INFO: damaris_cfg nb_layout_dims has dims2: " << nb_layout_dims2 << std::endl ; + + std::string dims_list = ""; + each(value, [&](PC_tree_t dim) { + dims_list += to_string(dim) + ","; + }); + dims_list.pop_back(); + layoutxml.layout_dimensions_ = dims_list; + } + else {//"d1,d2,d3" for instance, each di an expreession of of Damaris Parameter + layoutxml.layout_dimensions_ = to_string(value); + } + + } + else if (key == "global") { + layoutxml.layout_dims_global_ = to_string(value); + } + else if (key == "ghosts") { + layoutxml.layout_ghosts_ = to_string(value); + } + else if (key == "language") { + std::string in_language = to_string(value); + layoutxml.set_language( in_language ); + } + else if (key == "visualizable") { + PC_bool(value, &intb); + bool in_visualizable = (intb == 0) ? false : true ; + layoutxml.layout_visualizable_ = in_visualizable; + } + else if (key == "comment") { + layoutxml.layout_comment_ = to_string(value); + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized layout map string: " << key << std::endl ; + } + }); + + if(dataset_elt_full_name.empty()) + throw Value_error{"ERROR: damaris_cfg layout name must not be empty"}; + + //m_layouts.emplace(layoutxml.layout_name_ , layoutxml) ; + m_layouts.emplace(dataset_elt_full_name , layoutxml) ; + ctx.logger().info("------------------- Parsing damaris Layout '{}' , name_index = {} ", dataset_elt_full_name, name_index); + + if(name_index == 1) { + find_replace_map.insert( + {"_DATASET_ELEMENT_REGEX_", layoutxml.ReturnXMLForLayout() + "\n_DATASET_ELEMENT_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } + else {//In nested groups + insert_dataset_elts_to_group(layoutxml, nested_groups_names, name_index); + } + }); + }); + } + + void Damaris_cfg::parse_meshes_tree(Context& ctx, PC_tree_t meshes_tree_list) + { + opt_each(meshes_tree_list, [&](PC_tree_t meshes_tree) {//each meshes (list of mesh) + each(meshes_tree, [&](PC_tree_t meshes_tree_key, PC_tree_t mesh_tree) {//each mesh + + damaris::model::DamarisMeshXML meshxml{} ; + std::map find_replace_map = {}; + unsigned name_index = 0; + std::string dataset_elt_full_name; + + each(mesh_tree, [&](PC_tree_t mesh_tree_key, PC_tree_t value) {//mesh info + std::string key = to_string(mesh_tree_key); + + int tf; // 0 is false, anything else is true + if (key == "name") { + dataset_elt_full_name = to_string(value); + retrive_nested_groups(dataset_elt_full_name + , ds_elt_full_name_delimiter + , nested_groups_names + , name_index); + + //meshxml.set_name(to_string(value)); + meshxml.set_name(nested_groups_names[name_index-1]); + } + else if (key == "type") { + meshxml.set_type(to_string(value)); + } + else if (key == "topology") { + meshxml.set_topology(to_long(value)); + } + else if (key == "coordinates") {//Liste of coordinates + opt_each(value, [&](PC_tree_t coords_tree) {//each meshes (list of mesh) + each(coords_tree, [&](PC_tree_t coord_key, PC_tree_t coord_tree) {//each mesh + std::string coord_name, coord_unit = "", coord_label = "", coord_comment = ""; + + each(coord_tree, [&](PC_tree_t ct_tree_key, PC_tree_t value) {//mesh info + std::string coord_info_key = to_string(ct_tree_key); + + int tf; // 0 is false, anything else is true + if (coord_info_key == "name") { + coord_name = to_string(value); + } else if (coord_info_key == "unit") { + coord_unit = to_string(value); + } else if (coord_info_key == "label") { + coord_label = to_string(value); + } else if (coord_info_key == "comment") { + coord_comment = to_string(value); + } else { + std::cerr << "ERROR: damaris_cfg unrecogognized coord map string: " << key << std::endl ; + } + }); + meshxml.add_coord(coord_name, coord_unit, coord_label, coord_comment); + }); + }); + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized storage map string: " << key << std::endl ; + } + }); + + if(dataset_elt_full_name.empty()) + throw Value_error{"ERROR: damaris_cfg mesh name must not be empty} groups"}; + + //m_meshes.emplace(meshxml.get_name() , meshxml) ; + m_meshes.emplace(meshxml.get_name() , meshxml) ; + ctx.logger().info("------------------- Parsing damaris Mesh '{}' , name_index = {} ", dataset_elt_full_name, name_index); + + if(name_index == 1) { + find_replace_map.insert( + {"_DATASET_ELEMENT_REGEX_", meshxml.ReturnXMLForMesh() + "\n_DATASET_ELEMENT_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } + else {//In nested groups + insert_dataset_elts_to_group(meshxml, nested_groups_names, name_index); + } + }); + }); + } + + void Damaris_cfg::parse_storages_tree(Context& ctx, PC_tree_t storages_tree_list) + { + opt_each(storages_tree_list, [&](PC_tree_t storages_tree) {//each storages (list of storage) + each(storages_tree, [&](PC_tree_t storagest_key, PC_tree_t storage_tree) {//each storage + + damaris::model::DamarisStoreXML store{} ; + std::map find_replace_map = {}; + + each(storage_tree, [&](PC_tree_t st_key, PC_tree_t value) {//storage info + std::string key = to_string(st_key); + + int tf; // 0 is false, anything else is true + if (key == "name") { + store.store_name_ = to_string(value); + } + else if (key == "type") { + store.store_type_ = to_string(value); + } + else if (key == "file_mode") { + store.store_opt_FileMode_ = to_string(value); + } + else if (key == "files_path") { + store.store_opt_FilesPath_ = to_string(value); + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized storage map string: " << key << std::endl ; + } + }); + m_storages.emplace(store.store_name_ , store) ; + + find_replace_map.insert( + {"_STORAGE_ELEMENT_REGEX_", store.ReturnXMLForStore() + "\n_STORAGE_ELEMENT_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + }); + }); + } + + void Damaris_cfg::parse_paraview_tree(Context& ctx, PC_tree_t paraview_tree) + { + damaris::model::DamarisParaviewXML paraviewxml{} ; + std::map find_replace_map = {}; + + each(paraview_tree, [&](PC_tree_t lt_key, PC_tree_t value) {//layout info + std::string key = to_string(lt_key); + + int intb; // 0 is false, anything else is true + if (key == "update_frequency") { + int in_update_frequency = to_long(value); + paraviewxml.set_update_frequency( in_update_frequency ); + } + else if (key == "realtime_timestep") { + float in_realtime_timestep = (float) to_double(value); + paraviewxml.set_realtime_timestep( in_realtime_timestep ); + } + else if (key == "end_iteration") { + int in_end_iteration = to_long(value); + paraviewxml.set_end_iteration( in_end_iteration ); + } + else if (key == "write_vtk") { + int in_write_vtk = to_long(value); + paraviewxml.set_write_vtk( in_write_vtk ); + } + else if (key == "write_vtk_binary") { + PC_bool(value, &intb); + bool in_write_vtk_binary = (intb == 0) ? false : true ; + paraviewxml.set_write_vtk_binary( in_write_vtk_binary ); + } + else if (key == "comment") { + std::string in_comment = to_string(value); + paraviewxml.set_comment( in_comment ); + } + else if (key == "scripts" || key == "script") { + + if (!PC_status(PC_get(value, "[0]"))) {//Array //[script1, script2, script3] + int nb_paraview_scripts; PC_len(value, &nb_paraview_scripts); + std::cout << "INFO: damaris_cfg nb paraview scripts: " << nb_paraview_scripts << std::endl ; + + each(value, [&](PC_tree_t script) { + paraviewxml.add_script(to_string(script)); + }); + } + else { + paraviewxml.add_script(to_string(value)); + } + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized paraview map string: " << key << std::endl ; + } + }); + + m_paraview = ¶viewxml ; + + find_replace_map.insert( + {"_PLUGINS_REGEX_", paraviewxml.ReturnXMLForParaview() + "\n_PLUGINS_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } + + void Damaris_cfg::parse_pyscript_tree(Context& ctx, PC_tree_t pyscript_tree) + { + damaris::model::DamarisPyScriptXML pyscriptxml{} ; + std::map find_replace_map = {}; + + each(pyscript_tree, [&](PC_tree_t py_key, PC_tree_t value) {//layout info + std::string key = to_string(py_key); + + int intb; // 0 is false, anything else is true + if (key == "name") { + pyscriptxml.pyscript_name_ = to_string(value); + } + else if (key == "file") { + pyscriptxml.pyscript_file_ = to_string(value); + } + else if (key == "scheduler_file") { + pyscriptxml.scheduler_file_ = to_string(value); + } + else if (key == "execution") { + pyscriptxml.execution_ = to_string(value); + } + else if (key == "language") { + pyscriptxml.language_ = to_string(value); + } + else if (key == "scope") { + pyscriptxml.scope_ = to_string(value); + } + else if (key == "external") { + PC_bool(value, &intb); + bool in_external = (intb == 0) ? false : true ; + pyscriptxml.external_ = in_external; + } + else if (key == "frequency") { + pyscriptxml.frequency_ = to_long(value); + } + else if (key == "nthreads") { + pyscriptxml.nthreads_ = to_long(value); + } + else if (key == "timeout") { + pyscriptxml.timeout_ = to_long(value); + } + else if (key == "keep_workers_") { + pyscriptxml.keep_workers_ = to_string(value);//yes/no + } + else if (key == "comment") { + pyscriptxml.comment_ = to_string(value); + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized pyscript map string: " << key << std::endl ; + } + }); + + m_pyscript = &pyscriptxml ; + + find_replace_map.insert( + {"_SCRIPTS_REGEX_", pyscriptxml.ReturnXMLForPyScript() + "\n_SCRIPTS_REGEX_"} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } + + void Damaris_cfg::parse_write_tree(Context& ctx, PC_tree_t write_tree_list) + { + // opt_each(write_tree_list, [&](PC_tree_t writes_tree) {//list of ds map + each(write_tree_list, [&](PC_tree_t writet_key, PC_tree_t write_ds_tree) {//each dataset to write + + std::string ds_name = to_string(writet_key);//the name of the data to write, if dataset not specified afterward! + Dataset_Write_Info ds_write_info; + + //dataset + PC_tree_t ds_name_tree = PC_get(write_ds_tree, ".dataset"); + if(!PC_status(ds_name_tree)) + { + ds_name = to_string(ds_name_tree); + std::cout << "INFO: damaris_cfg write_ds_tree :: ds_name = '" << ds_name << "'" << std::endl ; + } + //when + PC_tree_t ds_when_tree = PC_get(write_ds_tree, ".when"); + if(!PC_status(ds_when_tree)) + { + ds_write_info.when = to_string(ds_when_tree); + std::cout << "INFO: damaris_cfg write_ds_tree :: when = '" << ds_write_info.when << "'" << std::endl ; + } + //position + PC_tree_t ds_position_tree = PC_get(write_ds_tree, ".position"); + if(!PC_status(ds_position_tree)) + { + if (!PC_status(PC_get(ds_position_tree, "[0]"))) {//Array [p0,p1,p3] (1 to 3 elements) + int position_dim; PC_len(ds_position_tree, &position_dim); + std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: " << position_dim << std::endl ; + + int pos_idx = 0; + each(ds_position_tree, [&](PC_tree_t dim) { + ds_write_info.position[pos_idx] = to_string(dim); + pos_idx++; + }); + } + else {//p0 + ds_write_info.position[0] = to_string(ds_position_tree); + std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: 1" << std::endl ; + } + } + //block + PC_tree_t ds_block_tree = PC_get(write_ds_tree, ".block"); + if(!PC_status(ds_block_tree)) + { + ds_write_info.block = to_string(ds_block_tree); + std::cout << "INFO: damaris_cfg write_ds_tree :: block = '" << ds_write_info.block << "'" << std::endl ; + } + + /* + each(write_ds_tree, [&](PC_tree_t wdst_key, PC_tree_t value) {//storage info + std::string key = to_string(wdst_key); + + if (key == "dataset") { + ds_name = to_string(value); + } + else if (key == "when") { + ds_write_info.when = to_string(value); + } + else if (key == "position") { + if (!PC_status(PC_get(value, "[0]"))) {//Array [p0,p1,p3] (1 to 3 elements) + int position_dim; PC_len(value, &position_dim); + std::cout << "INFO: damaris_cfg ds '"<< ds_name <<"' will be written in dims: " << position_dim << std::endl ; + + int pos_idx = 0; + each(value, [&](PC_tree_t dim) { + ds_write_info.position[pos_idx] = to_long(dim); + pos_idx++; + }); + } + else {//p0 + ds_write_info.position[0] = to_long(value); + } + } + else if (key == "block") { + ds_write_info.block = to_long(value); + } + else { + std::cerr << "ERROR: damaris_cfg unrecogognized write map string: " << key << std::endl ; + } + }); + */ + + m_datasets_to_write.emplace(ds_name, ds_write_info); + + load_desc(m_descs, ctx, ds_name, Desc_type::DATA_TO_WRITE_WITH_BLOCK); + }); + //}); + } + + + + void Damaris_cfg::parse_parameter_to_update_tree(Context& ctx, PC_tree_t ptu_tree, Desc_type op_type) + { + if (!PC_status(ptu_tree)) { // it's a name:{config...} mapping + each(ptu_tree, [&](PC_tree_t ptu_metadata, PC_tree_t ptu_prmname) { + std::string metadata = to_string(ptu_metadata); + std::string prm_name = to_string(ptu_metadata); + std::pair prm_to_update_info; + + if(!PC_status(ptu_prmname)) + { + if(to_string(ptu_prmname) != "") + prm_name = to_string(ptu_prmname); + } + + prm_to_update_info.first = prm_name; + prm_to_update_info.second = op_type; + m_parameter_to_update.emplace(metadata, prm_to_update_info); + load_desc(m_descs, ctx, metadata, op_type); + }); + } + else if (!PC_status(PC_get(ptu_tree, "[0]"))) {//Array [prm0,prm1,prm3,...] / it's a list of names only + each(ptu_tree, [&](PC_tree_t prm_name_t) { + std::pair prm_to_update_info; + std::string metadata = to_string(prm_name_t); + std::string prm_name = to_string(prm_name_t); + + prm_to_update_info.first = prm_name; + prm_to_update_info.second = op_type; + m_parameter_to_update.emplace(metadata, prm_to_update_info); + load_desc(m_descs, ctx, metadata, op_type); + }); + } + else {//prm0 + std::pair prm_to_update_info; + std::string metadata = to_string(ptu_tree); + std::string prm_name = to_string(ptu_tree); + + prm_to_update_info.first = prm_name; + prm_to_update_info.second = op_type; + m_parameter_to_update.emplace(metadata, prm_to_update_info); + load_desc(m_descs, ctx, metadata, op_type); + } + } + + void Damaris_cfg::parse_log_tree(Context& ctx, PC_tree_t config) + { + std::map find_replace_map = {}; + + //Log File Name + std::string log_file_name = "damaris_pdi_simu"; + PC_tree_t log_file_name_tree = PC_get(config, ".log.file_name"); + if(!PC_status(log_file_name_tree)) + { + log_file_name = to_string(log_file_name_tree); + } + else { + PC_tree_t sim_name_tree = PC_get(config, ".architecture.sim_name"); + if(!PC_status(sim_name_tree)) + { + log_file_name = to_string(sim_name_tree); + } + } + + std::string log_rotation_size = "5"; + PC_tree_t log_rotation_size_tree = PC_get(config, ".log.rotation_size"); + if(!PC_status(log_rotation_size_tree)) + { + log_rotation_size = to_string(log_rotation_size_tree); + } + + std::string log_level = "info"; + PC_tree_t log_level_tree = PC_get(config, ".log.log_level"); + if(!PC_status(log_level_tree)) + { + log_level = to_string(log_level_tree); + } + + std::string log_flush = "true"; + PC_tree_t log_flush_tree = PC_get(config, ".log.flush"); + if(!PC_status(log_flush_tree)) + { + log_flush = to_string(log_flush_tree); + } + + find_replace_map.insert({ + {"_SIM_LOG_NAME_",log_file_name} + ,{"_LOG_ROTATION_SIZE_", log_rotation_size} + ,{"_LOG_FLUSH_", log_flush} + ,{"_LOG_LEVEL_", log_level} + }); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } + + + + bool Damaris_cfg::is_dataset_to_write(std::string data_name) + { + bool is_dataset_to_write = false; + for(auto &datasets_to_write : m_datasets_to_write) { + if(data_name == datasets_to_write.first) + { + is_dataset_to_write = true; + break; + } + } + + return is_dataset_to_write; + } + + bool Damaris_cfg::is_parameter_to_update(std::string data_name) + { + bool is_parameter_to_update = false; + for(auto ¶meter_to_update : m_parameter_to_update) { + if(data_name == parameter_to_update.first) + { + is_parameter_to_update = true; + break; + } + } + + return is_parameter_to_update; + } + + bool Damaris_cfg::is_needed_metadata(std::string data_name) + { + bool is_needed_metadata = false; + for(auto &prm_depends_on : m_parameter_depends_on) { + auto &prm_name = prm_depends_on.first; + auto &prm_depends_on_data = prm_depends_on.second; + for(auto &depends_on_data : prm_depends_on_data) { + //auto &depends_on_data_name = depends_on_data.first; + //auto &depends_on_data_state = depends_on_data.second; + + if(data_name == depends_on_data.first && depends_on_data.second == false) + { + depends_on_data.second = true; + is_needed_metadata = true; + } + } + } + + return is_needed_metadata; + } + + + //std::vector + //std::unordered_map> Damaris_cfg::get_updatable_parameters() + std::unordered_map> Damaris_cfg::get_updatable_parameters(Context& ctx) + { + std::unordered_map> updatable_parameters; + for(auto prm_depends_on : m_parameter_depends_on) { + auto prm_name = prm_depends_on.first; + auto prm_depends_on_data = prm_depends_on.second; + bool to_be_updated = (prm_depends_on_data.size() > 0);//true; + for(auto depends_on_data : prm_depends_on_data) { + auto depends_on_data_name = depends_on_data.first; + auto depends_on_data_state = depends_on_data.second; + + if(!depends_on_data_state) + { + to_be_updated = false; + break; + } + } + if(to_be_updated) {//Update the parameter + PDI::Expression prm_value = m_parameter_expression.at(prm_name); + damaris::model::DamarisParameterXML prmxml = m_parameters.at(prm_name); + prmxml.param_value_ = prm_value.to_string(ctx); + //ctx.logger().info("------------------------------------------------------------------------------------In get_updatable_parameters `{}' prmxml.param_value_ = '{}'", prm_name, prmxml.param_value_); + std::pair update_info; + update_info.first = prm_value.to_string(ctx); + update_info.second = prmxml.param_datatype_; + + updatable_parameters.emplace(prm_name, update_info); + } + } + + return updatable_parameters; + } + + + void Damaris_cfg::reset_parameter_depends_on(std::string prm_name) { + if (m_parameter_depends_on.find(prm_name) == m_parameter_depends_on.end()) { + // not found + // handle the error + } else { + std::unordered_map prm_depends_on_data = m_parameter_depends_on.at(prm_name); + for(auto depends_on_data : prm_depends_on_data) { + depends_on_data.second = false; + } + } + } + + void Damaris_cfg::reset_parameter_depends_on(std::vector prm_list) { + for (auto prm_name : prm_list) { + reset_parameter_depends_on(prm_name); + } + } + + void Damaris_cfg::reset_all_parameters_depends_on() { + for(auto prm_depends_on : m_parameter_depends_on) { + auto prm_name = prm_depends_on.first; + auto prm_depends_on_data = prm_depends_on.second; + + for(auto depends_on_data : prm_depends_on_data) { + depends_on_data.second = false; + } + } + } + + + // Retrive nested groups names from a dataset_elt_full_name (gp1/gp2/.../dataset_elt_name) + void retrive_nested_groups(std::string& dataset_elt_full_name, char delimiter, std::string nested_groups_names[], unsigned& index) + { + // Creating an input string stream from the dataset_elt_full_name + std::istringstream namestream(dataset_elt_full_name); + + // Tmp string + string gp_name; + + // Retrive names from the string stream separated by the delimiter + while (getline(namestream, gp_name, delimiter)) { + if(index == max_nested_groups) { + throw Value_error{"Damaris variable/layout/mesh can be nested in more than {} groups", max_nested_groups}; + } + // Add the gp_name to the array + nested_groups_names[index++] = gp_name; + } + //If index==1, there is no group, ie: nested_groups_names[index-1] = dataset_elt_full_name + } + + + template + void insert_dataset_elts_to_group(DS_TYPE ds_elt_xml, std::string nested_groups_names[], unsigned index) + { + std::string nearest_group_name = nested_groups_names[index -2]; + bool root_group_exists = false; + damaris::model::DamarisGroupXML *nearest_parent_group = NULL; + for (int root_group_id = 0; root_group_id < root_groups_xml.size(); root_group_id++) { + damaris::model::DamarisGroupXML *root_gp_xml = &root_groups_xml[root_group_id]; + + if(nested_groups_names[0] == root_gp_xml->get_name()) + { + if(nearest_group_name == root_gp_xml->get_name()) + { + //printf("-------------------------------------------------------------------------------------In root_gp_xml.get_name() = %s, FOR Variable %s, nearest_group_name == root_gp_xml.get_name() = %d\n", root_gp_xml->get_name().c_str(), nested_groups_names[index -1].c_str(), (nearest_group_name == root_gp_xml->get_name())); + //root_gp_xml->add_variable(ds_elt_xml); + root_gp_xml->add_ds_element(ds_elt_xml); + + //free(root_gp_xml); + return; + } + nearest_parent_group = root_gp_xml; + root_group_exists = true; + break; + } + + //free(root_gp_xml); + } + + //Insertion in an existing nested group + bool insertion_group_found = false; + int group_id = 1; + if(root_group_exists) + { + while (group_id <= (index - 2) && !insertion_group_found) { + std::string group_name = nested_groups_names[group_id]; + + insertion_group_found = true; + std::vector sub_groups = nearest_parent_group->get_sub_groups(); + for (int group_id = 0; group_id < sub_groups.size(); group_id++) { + if(group_name == sub_groups[group_id].get_name()) + { + if(nearest_group_name == sub_groups[group_id].get_name()) + { + //(&sub_groups[group_id])->add_variable(ds_elt_xml); + (&sub_groups[group_id])->add_ds_element(ds_elt_xml); + + return; + } + insertion_group_found = false; + nearest_parent_group = &sub_groups[group_id++]; + break; + } + } + } + } + //The nested groups has to be created + else { + damaris::model::DamarisGroupXML root_gp_xml{nested_groups_names[0]}; + + if(nearest_group_name == root_gp_xml.get_name()) + { + //root_gp_xml.add_variable(ds_elt_xml); + root_gp_xml.add_ds_element(ds_elt_xml); + root_groups_xml.emplace_back(root_gp_xml); + + return; + } + + root_groups_xml.emplace_back(root_gp_xml); - each(parameter_tree, [&](PC_tree_t prm_key, PC_tree_t value) {//parameter info - std::string key = to_string(prm_key); - - if (key == "name") { - prmxml.param_name_ = to_string(value); - } - else if (key == "type") { - prmxml.param_datatype_ = to_string(value); - } - else if (key == "value") { - prmxml.param_value_ = to_string(value); - m_parameter_expression.emplace(prmxml.param_name_, to_string(value)); - } - else if (key == "depends_on") { - is_dependent = true; - if (!PC_status(PC_get(value, "[0]"))) {//Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter - //int idx = 0; - each(value, [&](PC_tree_t metadata_name_tree) { - std::string metadata_name = to_string(metadata_name_tree); - - depends_on_metadata.insert( - {metadata_name, false} - ); - - load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); - }); - } - else {//d1 - std::string metadata_name = to_string(value); - //depends_on_metadata[metadata_name] = false; - depends_on_metadata.insert( - {metadata_name, false} - ); - - load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); - ctx.logger().info("--------------------------------------------------------------------------------PARAMETER {} depends on {}", prmxml.param_name_, metadata_name); - } - - - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized parameter map string: " << key << std::endl ; - } - }); - //m_parameter_expression.emplace(prmxml.param_name_, prmxml.param_value_); - m_parameter_depends_on.emplace(prmxml.param_name_, depends_on_metadata); - //set default value if depend on metadata - std::string numbers_types[] = {"short", "int", "integer", "float", "real", "double"}; - if(is_dependent && std::find(std::begin(numbers_types), std::end(numbers_types), prmxml.param_datatype_)) { - prmxml.param_value_ = "1"; //"0" - } - else { - ///??? - } - - m_parameters.emplace(prmxml.param_name_ , prmxml) ; - find_replace_map.insert( - {"_DATASET_ELEMENT_REGEX_", prmxml.ReturnXMLForParameter() + "\n_DATASET_ELEMENT_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - }); - }); -} - -void Damaris_cfg::parse_datasets_tree(Context& ctx, PC_tree_t datasets_tree_list) -{ - opt_each(datasets_tree_list, [&](PC_tree_t datasets_tree) {//each datasets (list of dataset) - each(datasets_tree, [&](PC_tree_t ds_tree_key, PC_tree_t dataset_tree) {//each dataset - - damaris::model::DamarisVarXML vxml{} ; - std::map find_replace_map = {}; - unsigned name_index = 0; - std::string dataset_elt_full_name; - - each(dataset_tree, [&](PC_tree_t ds_key, PC_tree_t value) {//dataset info - std::string key = to_string(ds_key); - - int tf; // 0 is false, anything else is true - if (key == "name") { - dataset_elt_full_name = to_string(value); - retrive_nested_groups(dataset_elt_full_name - , ds_elt_full_name_delimiter - , nested_groups_names - , name_index); - - vxml.var_name_ = nested_groups_names[name_index-1]; //to_string(value); - } - else if (key == "layout") { - vxml.layout_name_ = to_string(value); - } - else if (key == "mesh") { - vxml.mesh_ = to_string(value); - } - else if (key == "centering") { - std::string t_centering = to_string(value); - vxml.set_centering(t_centering) ; - } - else if (key == "storage") { - vxml.store_ = to_string(value); - } - else if (key == "script") { - vxml.script_ = to_string(value); - } - else if (key == "unit") { - vxml.unit_ = to_string(value); - } - else if (key == "select_mem") { - vxml.select_mem_ = to_string(value); - } - else if (key == "select_file") { - vxml.select_file_ = to_string(value); - } - else if (key == "select_subset") { - vxml.select_subset_ = to_string(value); - } - else if (key == "ref") { - vxml.ref_ = to_string(value); - } - else if (key == "type") { - std::string in_type = to_string(value); - vxml.set_type( in_type ); - } - else if (key == "comment") { - vxml.comment_ = to_string(value); - } - else if (key == "visualizable") { - PC_bool(value, &tf); - vxml.visualizable_ = (tf == 0) ? false : true ; - } - else if (key == "time_varying") { - PC_bool(value, &tf); - vxml.time_varying_ = (tf == 0) ? false : true ; - } - else if (key == "enabled") { - PC_bool(value, &tf); - vxml.enabled_ = (tf == 0) ? false : true ; - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized variable map string: " << key << std::endl ; - } - }); - - if(dataset_elt_full_name.empty()) - throw Value_error{"ERROR: damaris_cfg variable name must not be empty"}; - - //m_datasets.emplace(vxml.var_name_ , vxml) ; - m_datasets.emplace(dataset_elt_full_name , vxml) ; - ctx.logger().info("------------------- Parsing damaris Variable '{}' , name_index = {} ", dataset_elt_full_name, name_index); - - if(name_index == 1) { - find_replace_map.insert( - {"_DATASET_ELEMENT_REGEX_", vxml.ReturnXMLForVariable() + "\n_DATASET_ELEMENT_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - } - else {//In nested groups - insert_dataset_elts_to_group(vxml, nested_groups_names, name_index); - } - }); - }); -} - -void Damaris_cfg::parse_layouts_tree(Context& ctx, PC_tree_t layouts_tree_list) -{ - opt_each(layouts_tree_list, [&](PC_tree_t layouts_tree) {//each layouts (list of layout) - each(layouts_tree, [&](PC_tree_t lts_key, PC_tree_t layout_tree) {//each layout - - damaris::model::DamarisLayoutXML layoutxml{} ; - std::map find_replace_map = {}; - unsigned name_index = 0; - std::string dataset_elt_full_name; - - each(layout_tree, [&](PC_tree_t lt_key, PC_tree_t value) {//layout info - std::string key = to_string(lt_key); - - int intb; // 0 is false, anything else is true - if (key == "name") { - dataset_elt_full_name = to_string(value); - retrive_nested_groups(dataset_elt_full_name - , ds_elt_full_name_delimiter - , nested_groups_names - , name_index); - - layoutxml.layout_name_ = nested_groups_names[name_index-1]; //to_string(value); - } - else if (key == "type") { - std::string in_datatype = to_string(value); - layoutxml.set_datatype( in_datatype ); - } - else if (key == "dimensions") { - - //Is there a way to determine if an expression is ready to be evaluated? ei, all the conponent have a value - if (!PC_status(PC_get(value, "[0]"))) {//Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter - int nb_layout_dims2; PC_len(value, &nb_layout_dims2); - std::cout << "INFO: damaris_cfg nb_layout_dims has dims2: " << nb_layout_dims2 << std::endl ; - - std::string dims_list = ""; - each(value, [&](PC_tree_t dim) { - dims_list += to_string(dim) + ","; - }); - dims_list.pop_back(); - layoutxml.layout_dimensions_ = dims_list; - } - else {//"d1,d2,d3" for instance, each di an expreession of of Damaris Parameter - layoutxml.layout_dimensions_ = to_string(value); - } - - } - else if (key == "global") { - layoutxml.layout_dims_global_ = to_string(value); - } - else if (key == "ghosts") { - layoutxml.layout_ghosts_ = to_string(value); - } - else if (key == "language") { - std::string in_language = to_string(value); - layoutxml.set_language( in_language ); - } - else if (key == "visualizable") { - PC_bool(value, &intb); - bool in_visualizable = (intb == 0) ? false : true ; - layoutxml.layout_visualizable_ = in_visualizable; - } - else if (key == "comment") { - layoutxml.layout_comment_ = to_string(value); - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized layout map string: " << key << std::endl ; - } - }); - - if(dataset_elt_full_name.empty()) - throw Value_error{"ERROR: damaris_cfg layout name must not be empty"}; - - //m_layouts.emplace(layoutxml.layout_name_ , layoutxml) ; - m_layouts.emplace(dataset_elt_full_name , layoutxml) ; - ctx.logger().info("------------------- Parsing damaris Layout '{}' , name_index = {} ", dataset_elt_full_name, name_index); - - if(name_index == 1) { - find_replace_map.insert( - {"_DATASET_ELEMENT_REGEX_", layoutxml.ReturnXMLForLayout() + "\n_DATASET_ELEMENT_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - } - else {//In nested groups - insert_dataset_elts_to_group(layoutxml, nested_groups_names, name_index); - } - }); - }); -} - -void Damaris_cfg::parse_meshes_tree(Context& ctx, PC_tree_t meshes_tree_list) -{ - opt_each(meshes_tree_list, [&](PC_tree_t meshes_tree) {//each meshes (list of mesh) - each(meshes_tree, [&](PC_tree_t meshes_tree_key, PC_tree_t mesh_tree) {//each mesh - - damaris::model::DamarisMeshXML meshxml{} ; - std::map find_replace_map = {}; - unsigned name_index = 0; - std::string dataset_elt_full_name; - - each(mesh_tree, [&](PC_tree_t mesh_tree_key, PC_tree_t value) {//mesh info - std::string key = to_string(mesh_tree_key); - - int tf; // 0 is false, anything else is true - if (key == "name") { - dataset_elt_full_name = to_string(value); - retrive_nested_groups(dataset_elt_full_name - , ds_elt_full_name_delimiter - , nested_groups_names - , name_index); - - //meshxml.set_name(to_string(value)); - meshxml.set_name(nested_groups_names[name_index-1]); - } - else if (key == "type") { - meshxml.set_type(to_string(value)); - } - else if (key == "topology") { - meshxml.set_topology(to_long(value)); - } - else if (key == "coordinates") {//Liste of coordinates - opt_each(value, [&](PC_tree_t coords_tree) {//each meshes (list of mesh) - each(coords_tree, [&](PC_tree_t coord_key, PC_tree_t coord_tree) {//each mesh - std::string coord_name, coord_unit = "", coord_label = "", coord_comment = ""; - - each(coord_tree, [&](PC_tree_t ct_tree_key, PC_tree_t value) {//mesh info - std::string coord_info_key = to_string(ct_tree_key); - - int tf; // 0 is false, anything else is true - if (coord_info_key == "name") { - coord_name = to_string(value); - } else if (coord_info_key == "unit") { - coord_unit = to_string(value); - } else if (coord_info_key == "label") { - coord_label = to_string(value); - } else if (coord_info_key == "comment") { - coord_comment = to_string(value); - } else { - std::cerr << "ERROR: damaris_cfg unrecogognized coord map string: " << key << std::endl ; - } - }); - meshxml.add_coord(coord_name, coord_unit, coord_label, coord_comment); - }); - }); - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized storage map string: " << key << std::endl ; - } - }); - - if(dataset_elt_full_name.empty()) - throw Value_error{"ERROR: damaris_cfg mesh name must not be empty} groups"}; - - //m_meshes.emplace(meshxml.get_name() , meshxml) ; - m_meshes.emplace(meshxml.get_name() , meshxml) ; - ctx.logger().info("------------------- Parsing damaris Mesh '{}' , name_index = {} ", dataset_elt_full_name, name_index); - - if(name_index == 1) { - find_replace_map.insert( - {"_DATASET_ELEMENT_REGEX_", meshxml.ReturnXMLForMesh() + "\n_DATASET_ELEMENT_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - } - else {//In nested groups - insert_dataset_elts_to_group(meshxml, nested_groups_names, name_index); - } - }); - }); -} - -void Damaris_cfg::parse_storages_tree(Context& ctx, PC_tree_t storages_tree_list) -{ - opt_each(storages_tree_list, [&](PC_tree_t storages_tree) {//each storages (list of storage) - each(storages_tree, [&](PC_tree_t storagest_key, PC_tree_t storage_tree) {//each storage - - damaris::model::DamarisStoreXML store{} ; - std::map find_replace_map = {}; - - each(storage_tree, [&](PC_tree_t st_key, PC_tree_t value) {//storage info - std::string key = to_string(st_key); - - int tf; // 0 is false, anything else is true - if (key == "name") { - store.store_name_ = to_string(value); - } - else if (key == "type") { - store.store_type_ = to_string(value); - } - else if (key == "file_mode") { - store.store_opt_FileMode_ = to_string(value); - } - else if (key == "files_path") { - store.store_opt_FilesPath_ = to_string(value); - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized storage map string: " << key << std::endl ; - } - }); - m_storages.emplace(store.store_name_ , store) ; - - find_replace_map.insert( - {"_STORAGE_ELEMENT_REGEX_", store.ReturnXMLForStore() + "\n_STORAGE_ELEMENT_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - }); - }); -} - -void Damaris_cfg::parse_paraview_tree(Context& ctx, PC_tree_t paraview_tree) -{ - damaris::model::DamarisParaviewXML paraviewxml{} ; - std::map find_replace_map = {}; - - each(paraview_tree, [&](PC_tree_t lt_key, PC_tree_t value) {//layout info - std::string key = to_string(lt_key); - - int intb; // 0 is false, anything else is true - if (key == "update_frequency") { - int in_update_frequency = to_long(value); - paraviewxml.set_update_frequency( in_update_frequency ); - } - else if (key == "realtime_timestep") { - float in_realtime_timestep = (float) to_double(value); - paraviewxml.set_realtime_timestep( in_realtime_timestep ); - } - else if (key == "end_iteration") { - int in_end_iteration = to_long(value); - paraviewxml.set_end_iteration( in_end_iteration ); - } - else if (key == "write_vtk") { - int in_write_vtk = to_long(value); - paraviewxml.set_write_vtk( in_write_vtk ); - } - else if (key == "write_vtk_binary") { - PC_bool(value, &intb); - bool in_write_vtk_binary = (intb == 0) ? false : true ; - paraviewxml.set_write_vtk_binary( in_write_vtk_binary ); - } - else if (key == "comment") { - std::string in_comment = to_string(value); - paraviewxml.set_comment( in_comment ); - } - else if (key == "scripts" || key == "script") { - - if (!PC_status(PC_get(value, "[0]"))) {//Array //[script1, script2, script3] - int nb_paraview_scripts; PC_len(value, &nb_paraview_scripts); - std::cout << "INFO: damaris_cfg nb paraview scripts: " << nb_paraview_scripts << std::endl ; - - each(value, [&](PC_tree_t script) { - paraviewxml.add_script(to_string(script)); - }); - } - else { - paraviewxml.add_script(to_string(value)); - } - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized paraview map string: " << key << std::endl ; - } - }); - - m_paraview = ¶viewxml ; - - find_replace_map.insert( - {"_PLUGINS_REGEX_", paraviewxml.ReturnXMLForParaview() + "\n_PLUGINS_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); -} - -void Damaris_cfg::parse_pyscript_tree(Context& ctx, PC_tree_t pyscript_tree) -{ - damaris::model::DamarisPyScriptXML pyscriptxml{} ; - std::map find_replace_map = {}; - - each(pyscript_tree, [&](PC_tree_t py_key, PC_tree_t value) {//layout info - std::string key = to_string(py_key); - - int intb; // 0 is false, anything else is true - if (key == "name") { - pyscriptxml.pyscript_name_ = to_string(value); - } - else if (key == "file") { - pyscriptxml.pyscript_file_ = to_string(value); - } - else if (key == "scheduler_file") { - pyscriptxml.scheduler_file_ = to_string(value); - } - else if (key == "execution") { - pyscriptxml.execution_ = to_string(value); - } - else if (key == "language") { - pyscriptxml.language_ = to_string(value); - } - else if (key == "scope") { - pyscriptxml.scope_ = to_string(value); - } - else if (key == "external") { - PC_bool(value, &intb); - bool in_external = (intb == 0) ? false : true ; - pyscriptxml.external_ = in_external; - } - else if (key == "frequency") { - pyscriptxml.frequency_ = to_long(value); - } - else if (key == "nthreads") { - pyscriptxml.nthreads_ = to_long(value); - } - else if (key == "timeout") { - pyscriptxml.timeout_ = to_long(value); - } - else if (key == "keep_workers_") { - pyscriptxml.keep_workers_ = to_string(value);//yes/no - } - else if (key == "comment") { - pyscriptxml.comment_ = to_string(value); - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized pyscript map string: " << key << std::endl ; - } - }); - - m_pyscript = &pyscriptxml ; - - find_replace_map.insert( - {"_SCRIPTS_REGEX_", pyscriptxml.ReturnXMLForPyScript() + "\n_SCRIPTS_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); -} - -void Damaris_cfg::parse_write_tree(Context& ctx, PC_tree_t write_tree_list) -{ - // opt_each(write_tree_list, [&](PC_tree_t writes_tree) {//list of ds map - each(write_tree_list, [&](PC_tree_t writet_key, PC_tree_t write_ds_tree) {//each dataset to write - - std::string ds_name = to_string(writet_key);//the name of the data to write, if dataset not specified afterward! - Dataset_Write_Info ds_write_info; - - //dataset - PC_tree_t ds_name_tree = PC_get(write_ds_tree, ".dataset"); - if(!PC_status(ds_name_tree)) - { - ds_name = to_string(ds_name_tree); - std::cout << "INFO: damaris_cfg write_ds_tree :: ds_name = '" << ds_name << "'" << std::endl ; - } - //when - PC_tree_t ds_when_tree = PC_get(write_ds_tree, ".when"); - if(!PC_status(ds_when_tree)) - { - ds_write_info.when = to_string(ds_when_tree); - std::cout << "INFO: damaris_cfg write_ds_tree :: when = '" << ds_write_info.when << "'" << std::endl ; - } - //position - PC_tree_t ds_position_tree = PC_get(write_ds_tree, ".position"); - if(!PC_status(ds_position_tree)) - { - if (!PC_status(PC_get(ds_position_tree, "[0]"))) {//Array [p0,p1,p3] (1 to 3 elements) - int position_dim; PC_len(ds_position_tree, &position_dim); - std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: " << position_dim << std::endl ; - - int pos_idx = 0; - each(ds_position_tree, [&](PC_tree_t dim) { - ds_write_info.position[pos_idx] = to_string(dim); - pos_idx++; - }); - } - else {//p0 - ds_write_info.position[0] = to_string(ds_position_tree); - std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: 1" << std::endl ; - } - } - //block - PC_tree_t ds_block_tree = PC_get(write_ds_tree, ".block"); - if(!PC_status(ds_block_tree)) - { - ds_write_info.block = to_string(ds_block_tree); - std::cout << "INFO: damaris_cfg write_ds_tree :: block = '" << ds_write_info.block << "'" << std::endl ; - } - - /* - each(write_ds_tree, [&](PC_tree_t wdst_key, PC_tree_t value) {//storage info - std::string key = to_string(wdst_key); - - if (key == "dataset") { - ds_name = to_string(value); - } - else if (key == "when") { - ds_write_info.when = to_string(value); - } - else if (key == "position") { - if (!PC_status(PC_get(value, "[0]"))) {//Array [p0,p1,p3] (1 to 3 elements) - int position_dim; PC_len(value, &position_dim); - std::cout << "INFO: damaris_cfg ds '"<< ds_name <<"' will be written in dims: " << position_dim << std::endl ; - - int pos_idx = 0; - each(value, [&](PC_tree_t dim) { - ds_write_info.position[pos_idx] = to_long(dim); - pos_idx++; - }); - } - else {//p0 - ds_write_info.position[0] = to_long(value); - } - } - else if (key == "block") { - ds_write_info.block = to_long(value); - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized write map string: " << key << std::endl ; - } - }); - */ - - m_datasets_to_write.emplace(ds_name, ds_write_info); - - load_desc(m_descs, ctx, ds_name, Desc_type::DATA_TO_WRITE_WITH_BLOCK); - }); - //}); -} - -void Damaris_cfg::parse_log_tree(Context& ctx, PC_tree_t config) -{ - std::map find_replace_map = {}; - - //Log File Name - std::string log_file_name = "damaris_pdi_simu"; - PC_tree_t log_file_name_tree = PC_get(config, ".log.file_name"); - if(!PC_status(log_file_name_tree)) - { - log_file_name = to_string(log_file_name_tree); - } - else { - PC_tree_t sim_name_tree = PC_get(config, ".architecture.sim_name"); - if(!PC_status(sim_name_tree)) - { - log_file_name = to_string(sim_name_tree); - } - } - - std::string log_rotation_size = "5"; - PC_tree_t log_rotation_size_tree = PC_get(config, ".log.rotation_size"); - if(!PC_status(log_rotation_size_tree)) - { - log_rotation_size = to_string(log_rotation_size_tree); - } - - std::string log_level = "info"; - PC_tree_t log_level_tree = PC_get(config, ".log.log_level"); - if(!PC_status(log_level_tree)) - { - log_level = to_string(log_level_tree); - } - - std::string log_flush = "true"; - PC_tree_t log_flush_tree = PC_get(config, ".log.flush"); - if(!PC_status(log_flush_tree)) - { - log_flush = to_string(log_flush_tree); - } - - find_replace_map.insert({ - {"_SIM_LOG_NAME_",log_file_name} - ,{"_LOG_ROTATION_SIZE_", log_rotation_size} - ,{"_LOG_FLUSH_", log_flush} - ,{"_LOG_LEVEL_", log_level} - }); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); -} - - - - bool Damaris_cfg::is_dataset_to_write(std::string data_name) - { - bool is_dataset_to_write = false; - for(auto &datasets_to_write : m_datasets_to_write) { - if(data_name == datasets_to_write.first) - { - is_dataset_to_write = true; - break; - } - } - - return is_dataset_to_write; - } - - bool Damaris_cfg::is_needed_metadata(std::string data_name) - { - bool is_needed_metadata = false; - for(auto &prm_depends_on : m_parameter_depends_on) { - auto &prm_name = prm_depends_on.first; - auto &prm_depends_on_data = prm_depends_on.second; - for(auto &depends_on_data : prm_depends_on_data) { - //auto &depends_on_data_name = depends_on_data.first; - //auto &depends_on_data_state = depends_on_data.second; - - if(data_name == depends_on_data.first && depends_on_data.second == false) - { - depends_on_data.second = true; - is_needed_metadata = true; - } - } - } - - return is_needed_metadata; - } - - - //std::vector - //std::unordered_map> Damaris_cfg::get_updatable_parameters() - std::unordered_map> Damaris_cfg::get_updatable_parameters(Context& ctx) - { - std::unordered_map> updatable_parameters; - for(auto prm_depends_on : m_parameter_depends_on) { - auto prm_name = prm_depends_on.first; - auto prm_depends_on_data = prm_depends_on.second; - bool to_be_updated = (prm_depends_on_data.size() > 0);//true; - for(auto depends_on_data : prm_depends_on_data) { - auto depends_on_data_name = depends_on_data.first; - auto depends_on_data_state = depends_on_data.second; - - if(!depends_on_data_state) - { - to_be_updated = false; - break; - } - } - if(to_be_updated) {//Update the parameter - PDI::Expression prm_value = m_parameter_expression.at(prm_name); - damaris::model::DamarisParameterXML prmxml = m_parameters.at(prm_name); - prmxml.param_value_ = prm_value.to_string(ctx); - //ctx.logger().info("------------------------------------------------------------------------------------In get_updatable_parameters `{}' prmxml.param_value_ = '{}'", prm_name, prmxml.param_value_); - std::pair update_info; - update_info.first = prm_value.to_string(ctx); - update_info.second = prmxml.param_datatype_; - - updatable_parameters.emplace(prm_name, update_info); - } - } - - return updatable_parameters; - } - - - void Damaris_cfg::reset_parameter_depends_on(std::string prm_name) { - if (m_parameter_depends_on.find(prm_name) == m_parameter_depends_on.end()) { - // not found - // handle the error - } else { - std::unordered_map prm_depends_on_data = m_parameter_depends_on.at(prm_name); - for(auto depends_on_data : prm_depends_on_data) { - depends_on_data.second = false; - } - } - } - - void Damaris_cfg::reset_parameter_depends_on(std::vector prm_list) { - for (auto prm_name : prm_list) { - reset_parameter_depends_on(prm_name); - } - } - - void Damaris_cfg::reset_all_parameters_depends_on() { - for(auto prm_depends_on : m_parameter_depends_on) { - auto prm_name = prm_depends_on.first; - auto prm_depends_on_data = prm_depends_on.second; - - for(auto depends_on_data : prm_depends_on_data) { - depends_on_data.second = false; - } - } - } - - - // Retrive nested groups names from a dataset_elt_full_name (gp1/gp2/.../dataset_elt_name) - void retrive_nested_groups(std::string& dataset_elt_full_name, char delimiter, std::string nested_groups_names[], unsigned& index) - { - // Creating an input string stream from the dataset_elt_full_name - std::istringstream namestream(dataset_elt_full_name); - - // Tmp string - string gp_name; - - // Retrive names from the string stream separated by the delimiter - while (getline(namestream, gp_name, delimiter)) { - if(index == max_nested_groups) { - throw Value_error{"Damaris variable/layout/mesh can be nested in more than {} groups", max_nested_groups}; - } - // Add the gp_name to the array - nested_groups_names[index++] = gp_name; - } - //If index==1, there is no group, ie: nested_groups_names[index-1] = dataset_elt_full_name - } - - - template - void insert_dataset_elts_to_group(DS_TYPE ds_elt_xml, std::string nested_groups_names[], unsigned index) - { - std::string nearest_group_name = nested_groups_names[index -2]; - bool root_group_exists = false; - damaris::model::DamarisGroupXML *nearest_parent_group = NULL; - for (int root_group_id = 0; root_group_id < root_groups_xml.size(); root_group_id++) { - damaris::model::DamarisGroupXML *root_gp_xml = &root_groups_xml[root_group_id]; - - if(nested_groups_names[0] == root_gp_xml->get_name()) - { - if(nearest_group_name == root_gp_xml->get_name()) - { - //printf("-------------------------------------------------------------------------------------In root_gp_xml.get_name() = %s, FOR Variable %s, nearest_group_name == root_gp_xml.get_name() = %d\n", root_gp_xml->get_name().c_str(), nested_groups_names[index -1].c_str(), (nearest_group_name == root_gp_xml->get_name())); - //root_gp_xml->add_variable(ds_elt_xml); - root_gp_xml->add_ds_element(ds_elt_xml); - - //free(root_gp_xml); - return; - } - nearest_parent_group = root_gp_xml; - root_group_exists = true; - break; - } - - //free(root_gp_xml); - } - - //Insertion in an existing nested group - bool insertion_group_found = false; - int group_id = 1; - if(root_group_exists) - { - while (group_id <= (index - 2) && !insertion_group_found) { - std::string group_name = nested_groups_names[group_id]; - - insertion_group_found = true; - std::vector sub_groups = nearest_parent_group->get_sub_groups(); - for (int group_id = 0; group_id < sub_groups.size(); group_id++) { - if(group_name == sub_groups[group_id].get_name()) - { - if(nearest_group_name == sub_groups[group_id].get_name()) - { - //(&sub_groups[group_id])->add_variable(ds_elt_xml); - (&sub_groups[group_id])->add_ds_element(ds_elt_xml); - - return; - } - insertion_group_found = false; - nearest_parent_group = &sub_groups[group_id++]; - break; - } - } - } - } - //The nested groups has to be created - else { - damaris::model::DamarisGroupXML root_gp_xml{nested_groups_names[0]}; - - if(nearest_group_name == root_gp_xml.get_name()) - { - //root_gp_xml.add_variable(ds_elt_xml); - root_gp_xml.add_ds_element(ds_elt_xml); - root_groups_xml.emplace_back(root_gp_xml); - - return; - } - - root_groups_xml.emplace_back(root_gp_xml); - - nearest_parent_group = &root_gp_xml; - insertion_group_found = true; - } - - //Insertion point found - if(insertion_group_found){ - damaris::model::DamarisGroupXML linked_parent_group{nearest_group_name}; - for (unsigned insertion_group_id = (index - 2); insertion_group_id >= group_id; insertion_group_id--) - { - std::string group_name = nested_groups_names[insertion_group_id]; - damaris::model::DamarisGroupXML sub_gp_xml{group_name}; - if(nearest_group_name == sub_gp_xml.get_name()) - { - //sub_gp_xml.add_variable(ds_elt_xml); - sub_gp_xml.add_ds_element(ds_elt_xml); - } - else { - sub_gp_xml.add_sub_group(linked_parent_group); - } - linked_parent_group = sub_gp_xml; - } - nearest_parent_group->add_sub_group(linked_parent_group); - } - - //free(nearest_parent_group); - } - - /* - void insert_dataset_elts_to_group(damaris::model::DamarisVarXML varxml, std::string nested_groups_names[], unsigned index) - { - std::string nearest_group_name = nested_groups_names[index -2]; - bool group_exists = false; - for (int root_group_id = 0; root_group_id < root_groups_xml.size(); root_group_id++) { - damaris::model::DamarisGroupXML *root_gp_xml = &root_groups_xml[root_group_id]; - - if(nearest_group_name == root_gp_xml->get_name()) - { - //printf("-------------------------------------------------------------------------------------In root_gp_xml.get_name() = %s, FOR Variable %s, nearest_group_name == root_gp_xml.get_name() = %d\n", root_gp_xml->get_name().c_str(), nested_groups_names[index -1].c_str(), (nearest_group_name == root_gp_xml->get_name())); - root_gp_xml->add_variable(varxml); - group_exists = true; - break; - } - - std::vector sub_groups = root_gp_xml->get_sub_groups(); - for (int group_id = 0; group_id < sub_groups.size(); group_id++) { - if(nearest_group_name == sub_groups[group_id].get_name()) - { - (&sub_groups[group_id])->add_variable(varxml); - group_exists = true; - break; - } - } - } - - if(!group_exists) - { - damaris::model::DamarisGroupXML root_gp_xml{nested_groups_names[0]}; - int group_id = 1; - while (group_id <= index - 2) { - std::string group_name = nested_groups_names[group_id]; - damaris::model::DamarisGroupXML sub_gp_xml{group_name}; - if(nearest_group_name == sub_gp_xml.get_name()) - { - sub_gp_xml.add_variable(varxml); - } - root_gp_xml.add_sub_group(sub_gp_xml); - group_id++; - } - - if(group_id == 1) { - root_gp_xml.add_variable(varxml); - } - - root_groups_xml.emplace_back(root_gp_xml); - } - } - */ - -const string& Damaris_cfg::xml_config_object( void ) -{ - m_xml_config_object = damarisXMLModifyModel.GetConfigString(); - return m_xml_config_object; -} - -//const PDI::Expression& Damaris_cfg::communicator() const -PDI::Expression Damaris_cfg::communicator() const -{ - return m_communicator; -} - -const unordered_map& Damaris_cfg::datasets() const -{ - return m_datasets; -} -const unordered_map& Damaris_cfg::layouts() const -{ - return m_layouts; -} - -const unordered_map& Damaris_cfg::parameters() const -{ - return m_parameters; -} - -const std::unordered_map& Damaris_cfg::storages() const -{ - return m_storages; -} - -const std::unordered_map& Damaris_cfg::meshes() const -{ - return m_meshes; -} - -const std::unordered_map& Damaris_cfg::groups() const -{ - return m_groups; -} - -const unordered_map& Damaris_cfg::descs() const -{ - return m_descs; -} - -const std::unordered_map& Damaris_cfg::datasets_to_write() const -{ - return m_datasets_to_write; -} - -Dataset_Write_Info Damaris_cfg::get_dataset_write_info(std::string data_name) const -{ - try{ - return m_datasets_to_write.at(data_name); - } catch (...) { - assert(false && "Trying to get inexistant damaris awaited dataset!"); - } -} - -bool Damaris_cfg::init_on_event() const -{ - return m_init_on_event; -} - -bool Damaris_cfg::start_on_event() const -{ - return m_start_on_event; -} - -bool Damaris_cfg::stop_on_event() const -{ - return m_stop_on_event; -} - -} // namespace damaris_pdi \ No newline at end of file + nearest_parent_group = &root_gp_xml; + insertion_group_found = true; + } + + //Insertion point found + if(insertion_group_found){ + damaris::model::DamarisGroupXML linked_parent_group{nearest_group_name}; + for (unsigned insertion_group_id = (index - 2); insertion_group_id >= group_id; insertion_group_id--) + { + std::string group_name = nested_groups_names[insertion_group_id]; + damaris::model::DamarisGroupXML sub_gp_xml{group_name}; + if(nearest_group_name == sub_gp_xml.get_name()) + { + //sub_gp_xml.add_variable(ds_elt_xml); + sub_gp_xml.add_ds_element(ds_elt_xml); + } + else { + sub_gp_xml.add_sub_group(linked_parent_group); + } + linked_parent_group = sub_gp_xml; + } + nearest_parent_group->add_sub_group(linked_parent_group); + } + + //free(nearest_parent_group); + } + + /* + void insert_dataset_elts_to_group(damaris::model::DamarisVarXML varxml, std::string nested_groups_names[], unsigned index) + { + std::string nearest_group_name = nested_groups_names[index -2]; + bool group_exists = false; + for (int root_group_id = 0; root_group_id < root_groups_xml.size(); root_group_id++) { + damaris::model::DamarisGroupXML *root_gp_xml = &root_groups_xml[root_group_id]; + + if(nearest_group_name == root_gp_xml->get_name()) + { + //printf("-------------------------------------------------------------------------------------In root_gp_xml.get_name() = %s, FOR Variable %s, nearest_group_name == root_gp_xml.get_name() = %d\n", root_gp_xml->get_name().c_str(), nested_groups_names[index -1].c_str(), (nearest_group_name == root_gp_xml->get_name())); + root_gp_xml->add_variable(varxml); + group_exists = true; + break; + } + + std::vector sub_groups = root_gp_xml->get_sub_groups(); + for (int group_id = 0; group_id < sub_groups.size(); group_id++) { + if(nearest_group_name == sub_groups[group_id].get_name()) + { + (&sub_groups[group_id])->add_variable(varxml); + group_exists = true; + break; + } + } + } + + if(!group_exists) + { + damaris::model::DamarisGroupXML root_gp_xml{nested_groups_names[0]}; + int group_id = 1; + while (group_id <= index - 2) { + std::string group_name = nested_groups_names[group_id]; + damaris::model::DamarisGroupXML sub_gp_xml{group_name}; + if(nearest_group_name == sub_gp_xml.get_name()) + { + sub_gp_xml.add_variable(varxml); + } + root_gp_xml.add_sub_group(sub_gp_xml); + group_id++; + } + + if(group_id == 1) { + root_gp_xml.add_variable(varxml); + } + + root_groups_xml.emplace_back(root_gp_xml); + } + } + */ + + const string& Damaris_cfg::xml_config_object( void ) + { + m_xml_config_object = damarisXMLModifyModel.GetConfigString(); + return m_xml_config_object; + } + + //const PDI::Expression& Damaris_cfg::communicator() const + PDI::Expression Damaris_cfg::communicator() const + { + return m_communicator; + } + + const unordered_map& Damaris_cfg::datasets() const + { + return m_datasets; + } + const unordered_map& Damaris_cfg::layouts() const + { + return m_layouts; + } + + const unordered_map& Damaris_cfg::parameters() const + { + return m_parameters; + } + + const std::unordered_map& Damaris_cfg::storages() const + { + return m_storages; + } + + const std::unordered_map& Damaris_cfg::meshes() const + { + return m_meshes; + } + + const std::unordered_map& Damaris_cfg::groups() const + { + return m_groups; + } + + const unordered_map& Damaris_cfg::descs() const + { + return m_descs; + } + + const std::unordered_map& Damaris_cfg::datasets_to_write() const + { + return m_datasets_to_write; + } + + const std::unordered_map>& Damaris_cfg::parameter_to_update() const + { + return m_parameter_to_update; + } + + Dataset_Write_Info Damaris_cfg::get_dataset_write_info(std::string data_name) const + { + try{ + return m_datasets_to_write.at(data_name); + } catch (...) { + assert(false && "Trying to get inexistant damaris awaited dataset!"); + } + } + + std::pair Damaris_cfg::get_parameter_to_update_info(std::string data_name) const + { + try{ + return m_parameter_to_update.at(data_name); + } catch (...) { + assert(false && "Trying to get inexistant damaris awaited dataset!"); + } + } + + bool Damaris_cfg::init_on_event() const + { + return m_init_on_event; + } + + bool Damaris_cfg::start_on_event() const + { + return m_start_on_event; + } + + bool Damaris_cfg::stop_on_event() const + { + return m_stop_on_event; + } + + } // namespace damaris_pdi \ No newline at end of file diff --git a/plugins/damaris/damaris_cfg.h b/plugins/damaris/damaris_cfg.h index 741c632aa..f662fd6e2 100644 --- a/plugins/damaris/damaris_cfg.h +++ b/plugins/damaris/damaris_cfg.h @@ -23,215 +23,234 @@ * THE SOFTWARE. ******************************************************************************/ -#ifndef DAMARIS_CFG_H_ -#define DAMARIS_CFG_H_ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -// Definitions of the Damaris XML tag generators -#include -#include -#include - -#include "damaris_wrapper.h" - -using PDI::Context; -using std::unique_ptr; -using std::list; -using std::string; - -namespace damaris_pdi { - -typedef struct placement { - int start ; - int stride ; - int blocksize ; - std::vector mask {} ; -} placement ; - -typedef struct dedicated { - int core ; - int node ; -} dedicated ; - -struct Architecture_type { - int domain ; - placement arch_placement ; - dedicated arch_cores_or_nodes ; -}; - -enum class Desc_type { - DATA_TO_WRITE - ,DATA_TO_WRITE_WITH_BLOCK - //,DATA_TO_READ - ,PRM_REQUIRED_METADATA - ,PRM_TO_GET - ,PRM_TO_SET -}; - -struct Dataset_Write_Info { - PDI::Expression when = "1";//By default, always write as long as there are iteration going on - /*int64_t* */ PDI::Expression position[3] = {"0", "0", "0"};//Max Dim is 3 - /*int32_t */ PDI::Expression block = "0";//when domain = 1, which is the default behaviour -}; - - -struct DamarisXMLGenerators { - damaris::model::DamarisParameterXML params_ ; // Layouts are typically descrived using parameters. Parameters can be shared between layouts. - damaris::model::DamarisVarXML variable_ ; // A variable - damaris::model::DamarisLayoutXML layout_ ; // each variable has one layout (layouts can be sahred) - damaris::model::DamarisMeshXML mesh_ ; // Contains extra elements that need to be part of a Damaris for visualization - damaris::model::DamarisStoreXML store_ ; // Contains the extra elements that need to be part of a Damaris (for HDF5 file w/r) -}; - -class Damaris_cfg -{ - std::string m_xml_config_object; - damaris::model::ModifyModel damarisXMLModifyModel; - - bool m_init_on_event = false; - bool m_start_on_event = false; - bool m_stop_on_event = false; - - int m_arch_domains ; - int m_dc_cores_pernode ; - int m_dc_nodes ; - - - int m_placement_start ; - int m_placement_stride ; - int m_placement_blocksize ; - std::string m_placement_mask_str ; - - PDI::Expression m_communicator; - - std::unordered_map m_datasets; - std::unordered_map m_layouts; - std::unordered_map m_parameters; - std::unordered_map m_storages; - std::unordered_map m_meshes; - std::unordered_map m_groups; - damaris::model::DamarisParaviewXML *m_paraview = NULL; - damaris::model::DamarisPyScriptXML *m_pyscript = NULL; - - std::unordered_map m_descs ; - std::unordered_map m_datasets_to_write; - list m_after_write_events; - - //In damaris parameter play similar role than metadata in PDI, in that other variable can be expressed by them - // Here we express parameter in terms of PDI metadata, and when metadata are expose, - // we need to be awards in order to update parameter value for Damaris - // This variable is intended for that - std::unordered_map> m_parameter_depends_on; - std::unordered_map m_parameter_expression; - - -const std::string XML_CONFIG_TEMPLATE = R"V0G0N( - - - - - - - - - - - _DATASET_ELEMENT_REGEX_ - - - - _STORAGE_ELEMENT_REGEX_ - - - _PLUGINS_REGEX_ - - - - - - _SCRIPTS_REGEX_ - - - - -)V0G0N"; - - -protected: -void parse_architecture_tree(Context& ctx, PC_tree_t arch_tree); -void parse_parameters_tree(Context& ctx, PC_tree_t parameters_tree_list); -void parse_datasets_tree(Context& ctx, PC_tree_t datasets_tree_list); -void parse_layouts_tree(Context& ctx, PC_tree_t layouts_tree_list); -void parse_storages_tree(Context& ctx, PC_tree_t storages_tree_list); -void parse_meshes_tree(Context& ctx, PC_tree_t meshes_tree_list); -void parse_paraview_tree(Context& ctx, PC_tree_t paraview_tree); -void parse_pyscript_tree(Context& ctx, PC_tree_t pyscript_tree); -void parse_write_tree(Context& ctx, PC_tree_t write_tree_list); -void parse_log_tree(Context& ctx, PC_tree_t config); - -void init_xml_config_object(){ - m_xml_config_object = XML_CONFIG_TEMPLATE; - damarisXMLModifyModel = damaris::model::ModifyModel(m_xml_config_object); -} - - -public: - Damaris_cfg(PDI::Context& ctx, PC_tree_t tree); - - const std::string& xml_config_object( void ); - - PDI::Expression communicator() const; - - const std::unordered_map& datasets() const; - const std::unordered_map& layouts() const; - const std::unordered_map& parameters() const; - const std::unordered_map& storages() const; - const std::unordered_map& meshes() const; - const std::unordered_map& groups() const; - - const std::unordered_map& descs() const; - const std::unordered_map& datasets_to_write() const; - - Dataset_Write_Info get_dataset_write_info(std::string data_name) const; - list get_after_write_events() const - { - return m_after_write_events; - } - bool is_there_after_write_events() const - { - return m_after_write_events.size(); - } - - bool init_on_event() const; - bool start_on_event() const; - bool stop_on_event() const; - - const std::unordered_map>& recover_var() const; - - const std::unordered_map>>& send_file() const; - - - bool is_dataset_to_write(std::string data_name); - bool is_needed_metadata(std::string data_name); - - std::unordered_map> get_updatable_parameters(Context& ctx); - - void reset_parameter_depends_on(std::string prm_name); - void reset_parameter_depends_on(std::vector prm_list); - - void reset_all_parameters_depends_on(); -}; // class Damaris_cfg - -} // namespace damaris_pdi - -#endif // DAMARIS_CFG_H_ \ No newline at end of file + #ifndef DAMARIS_CFG_H_ + #define DAMARIS_CFG_H_ + + #include + #include + #include + #include + #include + #include + + #include + #include + #include + + // Definitions of the Damaris XML tag generators + #include + #include + #include + + #include "damaris_wrapper.h" + + using PDI::Context; + using std::unique_ptr; + using std::list; + using std::string; + + namespace damaris_pdi { + + typedef struct placement { + int start ; + int stride ; + int blocksize ; + std::vector mask {} ; + } placement ; + + typedef struct dedicated { + int core ; + int node ; + } dedicated ; + + struct Architecture_type { + int domain ; + placement arch_placement ; + dedicated arch_cores_or_nodes ; + }; + + enum class Desc_type { + DATA_TO_WRITE + ,DATA_TO_WRITE_WITH_BLOCK + //,DATA_TO_READ + ,PRM_REQUIRED_METADATA + ,PRM_TO_GET + ,PRM_TO_SET + ,IS_CLIENT_GET + ,CLIENT_COMM_GET + }; + + struct Dataset_Write_Info { + PDI::Expression when = "1";//By default, always write as long as there are iteration going on + /*int64_t* */ PDI::Expression position[3] = {"0", "0", "0"};//Max Dim is 3 + /*int32_t */ PDI::Expression block = "0";//when domain = 1, which is the default behaviour + }; + + + struct DamarisXMLGenerators { + damaris::model::DamarisParameterXML params_ ; // Layouts are typically descrived using parameters. Parameters can be shared between layouts. + damaris::model::DamarisVarXML variable_ ; // A variable + damaris::model::DamarisLayoutXML layout_ ; // each variable has one layout (layouts can be sahred) + damaris::model::DamarisMeshXML mesh_ ; // Contains extra elements that need to be part of a Damaris for visualization + damaris::model::DamarisStoreXML store_ ; // Contains the extra elements that need to be part of a Damaris (for HDF5 file w/r) + }; + + class Damaris_cfg + { + std::string m_xml_config_object; + damaris::model::ModifyModel damarisXMLModifyModel; + + bool m_init_on_event = false; + bool m_start_on_event = false; + bool m_stop_on_event = false; + + int m_arch_domains ; + int m_dc_cores_pernode ; + int m_dc_nodes ; + + + int m_placement_start ; + int m_placement_stride ; + int m_placement_blocksize ; + std::string m_placement_mask_str ; + + PDI::Expression m_communicator; + + std::unordered_map m_datasets; + std::unordered_map m_layouts; + std::unordered_map m_parameters; + std::unordered_map m_storages; + std::unordered_map m_meshes; + std::unordered_map m_groups; + damaris::model::DamarisParaviewXML *m_paraview = NULL; + damaris::model::DamarisPyScriptXML *m_pyscript = NULL; + + std::unordered_map m_descs ; + std::unordered_map m_datasets_to_write; + list m_after_write_events; + //> + std::unordered_map> m_parameter_to_update; + + //In damaris parameter play similar role than metadata in PDI, in that other variable can be expressed by them + // Here we express parameter in terms of PDI metadata, and when metadata are expose, + // we need to be awards in order to update parameter value for Damaris + // This variable is intended for that + std::unordered_map> m_parameter_depends_on; + std::unordered_map m_parameter_expression; + + std::string m_is_client_dataset_name = ""; + std::string m_client_comm_get_dataset_name = ""; + + + const std::string XML_CONFIG_TEMPLATE = R"V0G0N( + + + + + + + + + + + _DATASET_ELEMENT_REGEX_ + + + + _STORAGE_ELEMENT_REGEX_ + + + _PLUGINS_REGEX_ + + + + + + _SCRIPTS_REGEX_ + + + + + )V0G0N"; + + + protected: + void parse_architecture_tree(Context& ctx, PC_tree_t arch_tree); + void parse_parameters_tree(Context& ctx, PC_tree_t parameters_tree_list); + void parse_datasets_tree(Context& ctx, PC_tree_t datasets_tree_list); + void parse_layouts_tree(Context& ctx, PC_tree_t layouts_tree_list); + void parse_storages_tree(Context& ctx, PC_tree_t storages_tree_list); + void parse_meshes_tree(Context& ctx, PC_tree_t meshes_tree_list); + void parse_paraview_tree(Context& ctx, PC_tree_t paraview_tree); + void parse_pyscript_tree(Context& ctx, PC_tree_t pyscript_tree); + void parse_write_tree(Context& ctx, PC_tree_t write_tree_list); + void parse_parameter_to_update_tree(Context& ctx, PC_tree_t ptu_tree_list, Desc_type op_type); + void parse_log_tree(Context& ctx, PC_tree_t config); + + void init_xml_config_object(){ + m_xml_config_object = XML_CONFIG_TEMPLATE; + damarisXMLModifyModel = damaris::model::ModifyModel(m_xml_config_object); + } + + + public: + Damaris_cfg(PDI::Context& ctx, PC_tree_t tree); + + const std::string& xml_config_object( void ); + + PDI::Expression communicator() const; + + const std::unordered_map& datasets() const; + const std::unordered_map& layouts() const; + const std::unordered_map& parameters() const; + const std::unordered_map& storages() const; + const std::unordered_map& meshes() const; + const std::unordered_map& groups() const; + + const std::unordered_map& descs() const; + const std::unordered_map& datasets_to_write() const; + const std::unordered_map>& parameter_to_update() const; + + Dataset_Write_Info get_dataset_write_info(std::string data_name) const; + std::pair get_parameter_to_update_info(std::string data_name) const; + list get_after_write_events() const + { + return m_after_write_events; + } + bool is_there_after_write_events() const + { + return m_after_write_events.size(); + } + std::string is_client_dataset_name() const + { + return m_is_client_dataset_name; + } + std::string client_comm_get_dataset_name() const + { + return m_client_comm_get_dataset_name; + } + + bool init_on_event() const; + bool start_on_event() const; + bool stop_on_event() const; + + const std::unordered_map>& recover_var() const; + + const std::unordered_map>>& send_file() const; + + + bool is_dataset_to_write(std::string data_name); + bool is_parameter_to_update(std::string data_name); + bool is_needed_metadata(std::string data_name); + + std::unordered_map> get_updatable_parameters(Context& ctx); + + void reset_parameter_depends_on(std::string prm_name); + void reset_parameter_depends_on(std::vector prm_list); + + void reset_all_parameters_depends_on(); + }; // class Damaris_cfg + + } // namespace damaris_pdi + + #endif // DAMARIS_CFG_H_ \ No newline at end of file diff --git a/plugins/damaris/example/HDF5_files/example_It0.h5 b/plugins/damaris/example/HDF5_files/example_It0.h5 new file mode 100644 index 0000000000000000000000000000000000000000..034dd3541a323c92501807cf87449298fa8e5283 GIT binary patch literal 7808 zcmeH`v2MaJ5Qfi5T16?9N{0${Kp7bsvVl}85tNBml!1*_qCh0z88WtS(xDI0k+*_4 z{!gm1bzrFY9VvG{pMT4ret%}e(RFkmi5+1mf!tK7{tg&L+f{U~>#s-*;s@fF=Mp3K z6KSE|gnqqmI!RM0J5^sJwn;Z|S*QiZvm%hCkI(kPGu&GJw1>|W#`Z1W&6oN6X5lL8 z%YiohF&eq7{Of+!p`A*>cuu(wy#``^?w8KDoz3_`oOcJ3TuE~9-G+;@YS%pohUoVV z+NHRIbQNw-@8y%{FXN}7ebM?3W8CB92lD_DAOR8}0TLhq5+DH*AOR8} a0TLhq5+DH*AOR8}0TLhq5+H$pLEs1{h&3Pp literal 0 HcmV?d00001 diff --git a/plugins/damaris/example/HDF5_files/example_It1.h5 b/plugins/damaris/example/HDF5_files/example_It1.h5 new file mode 100644 index 0000000000000000000000000000000000000000..c32c91f72b9a15faa713d7f37d791efe692e5938 GIT binary patch literal 7808 zcmeH`KTE?<6vc0nDxoS^2N4J9=;+W*!3d3Xs?s{Rso=kY`WZ4f=r?ijLpb`Wta*9o zf^<0GkU=~N$?Ir%yw=_BTDbDuI=0>{{V~T??Zl41yMBp9g8G8`mc~V5 z;WpbszX$)txwA=GT0QChUa`&gI&qbIL-k(~7?nq-;lSrOwdd&*Idd3~SF@*!+u6;- zb?kU93m^DpO>DWzZ+wJ=?luld8l4Z|w~D&>p4G_@lfC|-#q1U~Sh2x8iyM~eZqQR0 z=9teCj9aw{>!xg=9rnEMf83ef|CC!_Psb<2@JIW9*vC0q|FAwF0wT}~f$I6IXvG+& z^5=BLM|?N|t|~v`!wGOz`4JyZfUC-n_;3PTRer>W6X2@yBR-q}SCt>};RLv<{D==H Qz*Xf(d^iEF{^k690}ai*m;e9( literal 0 HcmV?d00001 diff --git a/plugins/damaris/example/HDF5_files/example_It2.h5 b/plugins/damaris/example/HDF5_files/example_It2.h5 new file mode 100644 index 0000000000000000000000000000000000000000..b0e6864f59a1283ecd8699161699d3911b4f6c70 GIT binary patch literal 7808 zcmeI0ze>bF5XNVdQn0-4Etv$O1vFHN3D!@Z?qy^wHuFCAHKQ+rJHsyAZA-c3K(#A$re zILTt-B-|ovTJP%o*}jvbs*)-eY4&7`gxGYZI(Rqs+XW#S2`JuDh+m-0uQu+(hpXPDF zTvH8trUSk9=T6(DUe(cUSkZD=^RoSRBXavwPM#m{9}L46ZQo%}&yjp%Za@Mgkc7bG z!wYU6vod@s)VX&I*2%wj^gCdt%4~u(n&=f+*I&iL4Ae{4)qljoE#i{2*JhC zR}deh=G=P@NQWarv*?#X&dE9Fe&PQ5B|~oez0JA$a-H}{5~|UHPxUmCqiBYTUTgnI z5+`ve@hJ+4BmNOBNj(+)@wxroJg0I}^)<>eTC0UD(E{SXBGAvfJG|io*|qxVO?;*> zu8s%Shi8M+%ac%1UuHV+%jjs@`!}4}p(|d&ML~I8^kyZFU&p2Mc`|KnQ1EU>?HOv1 z;;>+PN=0xOwoA^GO_ckEz#xZ+vE~H(~vv`3imGe*zx^4%-p_F#&;(i3k3% z@qiEb{6N5NY5QgV+QI4qKiCqfFZRazYuoDmP0$8McNczKlyW43Bc_-_0q-C&Lw6lN{8vhl6Mq1y(4e!ye*-ww; zGlp?-*lg{eG>^}ZY=(UqbHfj#2jj-S_J$5!F$!M6DpyHwlH%~QpF1Br!>9(Ki_v}gm__|;?YS4DPW$QJ#6Qx%`K-(t{nv%Q z3;pP!ruz8ZMhxXM0t}^zk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa+hfC-G!BPs+uTpa^I9*%(e8kU|;K+_p4Fme+! z^WxJoQ*%-vBCvGn08>CB&B(w8PQMTWltMMYCNMHVOtyiV#{;F&`OLtS4^kgP10WVewkogbx-3FU~prM$m<~NxM zg3V`0cuW)Xr)(HCACw$$fzj~66*3U<(eN1!9|!zFfLC@j{ooBAhSBgD4Ic;mL4a3w zH2vTWp3(e;KX^vNXEb~$>K~1kKll^SX!wkVj|2W7z$-hNe((m*X#Ishct*o#fWwE@ Q<9oCopQQEpDow|S0Zm?<-T(jq literal 0 HcmV?d00001 diff --git a/plugins/damaris/example/HDF5_files/example_It6.h5 b/plugins/damaris/example/HDF5_files/example_It6.h5 new file mode 100644 index 0000000000000000000000000000000000000000..014b3baf150dfc0e885672d00ad16ac90087bca3 GIT binary patch literal 7808 zcmeI0yGsK>5XR>cA0a+4qT&NWN)Z(c8z0~aMnrsJEGz^y@e#onRw9B|s3_Wtg^gGU z+S;c~mqt7P1?{X<^k#P!bU?xAR?Y_Q+nL?{j{7lt7xr+VufHr@9|mlp5EMX#>YB?N zH7}|&CN|?U)Nx1;NG}7r;{g5uYAGKfe?D(wJRS#srtvpQ%b=}5_d+Hi`mYEK#Cyl^ zfhXyyO+96)&J2u|*`?L#g{ArBIh`?e>6!^YR0oPw{pt%=Xrpp)0@}Ho{7OlA9P}$6 zXGUT@pljEK_7Z4+3+e@heip|AWEi6PL5HS;S3}lHDk+U?uDdde0O^mz*87Q((LUVK zW*^4rIjrAUZXg7NfCU2H@%=+puWy{#&po-mW{anCs4!S_ru1TSTB)~NuGAm;NlPX7 z>d^nFdg{gXb+R*ki|RhMoTI{ZG^sQ{|I9|yP(AtwYqwv~XXZI_hw61~oumHJ-@Cd= zDgW5(iSp0xHvFZ3rg?o{`46|A+VF?99r4F9_^Jt?ugK`U@DV;PBFOLkEbpK1%SZSK zpQMWnWPi#3AFKn`zk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa+hfC-G!BPs+uTpa^I9*%(e8kU|;K+_p4Fme+! z^WxJoQ*%-vBCvGn08>CB&B(w8PQMTWltMMYCNMHVOtyiV#{;F&`OLtS4^k+vO8kB`xMe2>=Sle8XRrS14I02-K|SpWb4 literal 0 HcmV?d00001 diff --git a/plugins/damaris/example/HDF5_files/example_It8.h5 b/plugins/damaris/example/HDF5_files/example_It8.h5 new file mode 100644 index 0000000000000000000000000000000000000000..867e5927972d0d48130ccaa4d477e5aca791d93c GIT binary patch literal 7808 zcmeD5aB<`1lHy_j0S*oZ76t(@6Gr@pf(AK=2#gPtPk=HQp>zk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa+hfC-G!BPs+uTpa^I9*%(e8kU|;K+_p4Fme+! z^WxJoQ*%-vBCvGn08>CB&B(w8PQMTWltMMYCNMHVOtyiV#{;F&`OLtS4^kplCA1JHuQy)Cyv^s^l?n?baI zs%bNbW;opB38vW^S-^Bd%Q}0IIDRnY@uwacp!rjHg(fot>4t4W5sw{!dUn}y?FP{d zSO0W^=nG|@0U(;87 z7fhN-j`?2{7X1a8pK(+`kQGQTIJx#N$ovBZ@fX16KiMo#iTP8UN?GK9=FXU7APzD= zX!u|c7nta1 z_`pH}J3Sgc*uw=TIvPH(kibrlh7a~|fr$?F@S*ki46VnPXgxkg>+wBWk5AHie3iE2 F!vKEwsOSIy literal 0 HcmV?d00001 diff --git a/plugins/damaris/example/HDF5_files/example_It9.h5 b/plugins/damaris/example/HDF5_files/example_It9.h5 new file mode 100644 index 0000000000000000000000000000000000000000..ec3edbe8ccb7e7f2ad50427cbf999ee71c947235 GIT binary patch literal 7808 zcmeD5aB<`1lHy_j0S*oZ76t(@6Gr@pf(AK=2#gPtPk=HQp>zk7Ucm%mFfxE31A_!q zTo7tLy1I}cS62q0N|^aD8mf)KfCa+hfC-G!BPs+uTpa^I9*%(e8kU|;K+_p4Fme+! z^WxJoQ*%-vBCvGn08>CB&B(w8PQMTWltMMYCNMHVOtyiV#{;F&`OLtS4^k$~p!qdNTi&n&=^GoH z^(|NaRwKf!qF3Xu5@X}V=pFu&o(x*V|it2lXofy|G2Fq@j@FIe_G7i|8X zW}29P!2SKG`FQg0X!zhS-$uh{G<+y2pGVWrX!;pVKfrdwX#LKB4UCo#qvgYB`7l~O xU@IFyVx#55X!$T&J`CORf!5<2v>u Date: Fri, 28 Mar 2025 11:32:53 +0100 Subject: [PATCH 04/42] share some notes/suggestions --- plugins/damaris/example/example.c | 6 ++-- plugins/damaris/example/example.yml | 50 ++++++++++++++++++----------- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/plugins/damaris/example/example.c b/plugins/damaris/example/example.c index e72132981..b35f3e9a2 100644 --- a/plugins/damaris/example/example.c +++ b/plugins/damaris/example/example.c @@ -163,7 +163,9 @@ int main(int argc, char* argv[]) MPI_Comm main_comm;// = MPI_COMM_WORLD; PDI_init(PC_get(conf, ".pdi")); - PDI_event("init"); + PDI_event("init"); // event "init" is currently reserved for damaris. It is not recommand for plugins to reserve certain names of events. + // we can try to use the key "on_init" for example + // PDI_event("user_init_damaris"); int is_client = 2; @@ -181,7 +183,7 @@ int main(int argc, char* argv[]) //,"client_comm", &main_comm, PDI_INOUT //, NULL); - PDI_expose("mpi_comm", &main_comm, PDI_INOUT); + PDI_expose("mpi_comm", &main_comm, PDI_INOUT); // PDI_IN should be sufficient? //MPI_Comm hdf5_mpi_comm = main_comm; //PDI_expose("hdf5_mpi_comm", &hdf5_mpi_comm, PDI_INOUT); diff --git a/plugins/damaris/example/example.yml b/plugins/damaris/example/example.yml index be1dcd683..153a0a76b 100644 --- a/plugins/damaris/example/example.yml +++ b/plugins/damaris/example/example.yml @@ -14,7 +14,7 @@ pdi: pcoord: { size: 2, type: array, subtype: int } # coordinate of the process mpi_comm: MPI_Comm data: # type of values for which PDI does not keep a copy - #is_client: int + #is_client: int # Question: pourquoi pas d'erreur meme si "is_client" n'est pas déclaré comme data, et que simulation accède à cette donnée? #mpi_comm: MPI_Comm main_field: { size: [ '$dsize[0]', '$dsize[1]' ], type: array, subtype: double } @@ -40,20 +40,23 @@ pdi: size: [1, '$dsize[0]-2', '$dsize[1]-2'] start: [$iter, '($dsize[0]-2)*$pcoord[0]', '($dsize[1]-2)*$pcoord[1]'] damaris: - init_on_event: 1 + + init_on_event: 1 # à simplifier ref set_value plugin ou la doc PDI: on_init, on_data, on_event , on_finalize + #on_init: init_damaris #start_on_event: 1 - communicator: MPI_COMM_WORLD - architecture: + communicator: $MPI_COMM_WORLD # pas utilisé actuellement + architecture: sim_name: example - domains: 1 + domains: 1 # => nb de block par sous domain + # damaris divise le sous domain par block equitablement dedicated: core: 1 node: 0 - parameters: + parameters: # meme but que les metadata, mais la valeur peut changer au cours de l'execution - parameter: name: dsize0 type: int - value: '$dsize[0]' + value: '$dsize[0]' # overwrite the default value 0 depends_on: dsize - parameter: name: dsize1 @@ -74,37 +77,44 @@ pdi: - dataset: name: main_field layout: main_field_layout - mesh: mesh2d + mesh: mesh2d # pour la visualisation centering: zonal storage: hdf5_example script: visualizable: true time_varying: true #comment: This is the zonal pressure from our test simulation - layouts: + layouts: # on ne peut pas modifier la valuer de layout une fois initialisé, travail en cours pour la modification dynamique - layout: - name: main_field_layout + name: main_field_layout # ~hdf5 dataset_selection type: double + # try something like: global: '$psize[0]*($dsize[0]-2), $psize[1]*($dsize[1]-2)' global: 'psize0*(dsize0-2),psize1*(dsize1-2)' dimensions: [ 'dsize0', 'dsize1' ] # process dim, with ghosts/boundaries - ghosts: '1:1,1:1' + ghosts: '1:1,1:1' # 1 ghost à gauche de dim1, 1 ghost à droit de dim1 , 1 ghost à gauche de dim2, 1 ghost à droit de dim2 storages: - storage: name: hdf5_example type: HDF5 file_mode: Collective # or FilePerCore files_path: ./HDF5_files/ # Where to save files + # hdf5 file name defined by damaris #frequency: 1 - + #Events sections - write: - main_field: # the name of the data to write, if dataset not specified afterward! - dataset: main_field + write: + main_field: # the name of the data to write, if dataset not specified afterward! ~meme notion de dataset hdf5 + dataset: main_field when: '$iter<10' # do only write the first 10 iterations (0...9), Default at every iteration. #position: ['$pcoord[0]', '$pcoord[1]'] - position: ['($dsize[0]-2)*$pcoord[0]', '($dsize[1]-2)*$pcoord[1]'] - #block: [...] # To be defined - after_write: damaris_end_iteration # applied for all the data... + position: ['($dsize[0]-2)*$pcoord[0]', '($dsize[1]-2)*$pcoord[1]'] # ~start de dataset_selection par iteration + # damaris "append" file with next iteration + #block: [...] # To be defined # indice de block à écrire = 0 par default => tout le sous-domain + # si "architecture/domains" >1 on peut écrire les block de indice 0 à domains-1 + # after_write: damaris_end_iteration # applied for all the data... + # question: moyen de enlever cette ligne au-desus??? + # on_end_iteration: damaris_end_iteration + # - *: aw_event # OR [aw_event1, aw_event1, ...] # applied for all the data... # - data1_name: d1_aw_event # OR [d1_aw_event1, d1_aw_event2, ...] # - data2_name: d2_aw_event # OR [d2_aw_event1, d2_aw_event2, ...] @@ -122,8 +132,10 @@ pdi: # - prm2: get_is_client: is_client client_comm_get: mpi_comm + + # question: utilisé ou pas??? parameter_get: - parameter_set: + parameter_set: #Optional config, has a default behavior log: From 6458d2bd012ef4d4d6a167e36fc79cb3b8eea447 Mon Sep 17 00:00:00 2001 From: yushan wang Date: Fri, 28 Mar 2025 11:49:48 +0100 Subject: [PATCH 05/42] Update tests.yml to remove CI for draft PRs --- .github/workflows/tests.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d7de22eee..47a939685 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,7 +30,8 @@ name: tests on: push: { branches: [ main, 'v[0-9]+.[0-9]+' ] } - pull_request: + pull_request: + types: [ready_for_review] jobs: spack: strategy: From a71c012a600645ea2b7743cb59cc06cd28a1bff6 Mon Sep 17 00:00:00 2001 From: yushan wang Date: Fri, 28 Mar 2025 11:51:05 +0100 Subject: [PATCH 06/42] remove CI for draft PRs --- .github/workflows/indent.yml | 1 + .github/workflows/pages.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/indent.yml b/.github/workflows/indent.yml index 5ebb33e55..68d546367 100644 --- a/.github/workflows/indent.yml +++ b/.github/workflows/indent.yml @@ -31,6 +31,7 @@ name: indent on: push: { branches: [ main ] } pull_request: + types: [ready_for_review] jobs: indent: runs-on: ubuntu-latest diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 4ecd3fbe1..501f9e2c5 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -31,6 +31,7 @@ name: pages on: push: { branches: [ main, 'v[0-9]+.[0-9]+' ] } pull_request: + types: [ready_for_review] jobs: pages: runs-on: ubuntu-20.04 From cb01081cba017f1bde7eca19fea42558edf2807e Mon Sep 17 00:00:00 2001 From: Etienne Ndamlabin Date: Wed, 2 Apr 2025 16:54:24 +0200 Subject: [PATCH 07/42] Removing specific names and relying on configured event and data names in the YML file! --- plugins/damaris/damaris.cxx | 92 ++++-- plugins/damaris/damaris_api_call_handler.cxx | 114 +++----- plugins/damaris/damaris_api_call_handler.h | 50 +--- plugins/damaris/damaris_cfg.cxx | 284 ++++++++++--------- plugins/damaris/damaris_cfg.h | 61 +++- plugins/damaris/example/example.c | 8 +- plugins/damaris/example/example.yml | 13 +- 7 files changed, 319 insertions(+), 303 deletions(-) diff --git a/plugins/damaris/damaris.cxx b/plugins/damaris/damaris.cxx index 50f9ab3b2..e9a8af2ec 100644 --- a/plugins/damaris/damaris.cxx +++ b/plugins/damaris/damaris.cxx @@ -85,6 +85,9 @@ class damaris_plugin: public Plugin { list multi_expose_transaction_dataname; //list multi_expose_transaction_dataref; + std::string int_numbers_types[3] = {"short", "int", "integer"}; + std::string real_numbers_types[3] = {"float", "real", "double"}; + public: damaris_plugin(Context& ctx, PC_tree_t config) @@ -97,13 +100,26 @@ class damaris_plugin: public Plugin { ctx.callbacks().add_data_callback([this](const std::string& name, Ref ref) { this->data(name, ref); }, desc.first); } - //Trigger other data callback for multi_expose_transaction_dataname OR remove totally !!!? + + //Sim configured event names + for (auto&& event: m_config.events()) { + ctx.callbacks().add_event_callback([this](const std::string& name) { this->event(name); }, + event.first); + } + + //Default event names, maight be called internally + for (auto&& ev_name: event_names) { + //Only if the key if not yet used by an event + if (m_config.events().find(ev_name.second) == m_config.events().end()) + ctx.callbacks().add_event_callback([this](const std::string& name) { this->event(name); }, + ev_name.second); + } - ctx.callbacks().add_event_callback([this](const std::string& name) { this->event(name); }); + //ctx.callbacks().add_event_callback([this](const std::string& name) { this->event(name); }); ctx.logger().info("Plugin loaded successfully"); - if (!m_config.init_on_event() && m_config.communicator()) { + if (m_config.init_on_event().empty() && m_config.communicator()) { //TODO: issue communicator to handle /* MPI_Comm comm = *(static_cast(Ref_r{m_config.communicator().to_ref(context())}.get())); @@ -126,9 +142,6 @@ class damaris_plugin: public Plugin { if(m_config.is_needed_metadata(name)){ std::unordered_map> updatable_parameters = m_config.get_updatable_parameters(context()); - std::string int_numbers_types[] = {"short", "int", "integer"}; - std::string real_numbers_types[] = {"float", "real", "double"}; - std::string prm_name_concat = ""; for(auto prm_update_info : updatable_parameters) { auto prm_name = prm_update_info.first; @@ -218,34 +231,32 @@ class damaris_plugin: public Plugin { } } else if(m_config.is_parameter_to_update(name)){ + context().logger().info("m_config.is_parameter_to_update('{}') = `{}'", name, m_config.is_parameter_to_update(name)); std::pair prm_to_update_info = m_config.get_parameter_to_update_info(name); std::string prm_name = prm_to_update_info.first; size_t size; - Ref_r rref = ref; - Ref_rw rwref = ref; + damaris::model::DamarisParameterXML prmxml = m_config.get_parameter_xml(prm_name); - if (rref && prm_to_update_info.second == Desc_type::PRM_TO_SET) { - Datatype_sptr ref_type = rref.type(); - if (auto&& scalar_type = dynamic_pointer_cast(ref_type)) { - size = rref.scalar_value(); - } else { - throw Type_error{"Damaris paramegter must be a scalar"}; - } + if(std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prmxml.param_datatype_)) { + size = sizeof(int); + } + else if(std::find(std::begin(real_numbers_types), std::end(real_numbers_types), prmxml.param_datatype_)) { + size = sizeof(double); + } + else { + size = sizeof(std::string); + } + + if (prm_to_update_info.second == Desc_type::PRM_TO_SET) { + Ref_r rref = ref; - std::string prm_set_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_PARAMETER_SET); - m_event_handler.damaris_api_call_event(context(), m_damaris, prm_set_event_name, multi_expose_transaction_dataname, prm_name, name, size); + int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), static_cast(rref.get()), size); } - else if (rwref && prm_to_update_info.second == Desc_type::PRM_TO_GET) { - Datatype_sptr ref_type = rwref.type(); - if (auto&& scalar_type = dynamic_pointer_cast(ref_type)) { - size = rwref.scalar_value(); - } else { - throw Type_error{"Damaris paramegter must be a scalar"}; - } + else if (prm_to_update_info.second == Desc_type::PRM_TO_GET) { + Ref_w wref = ref; - std::string prm_get_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_PARAMETER_GET); - m_event_handler.damaris_api_call_event(context(), m_damaris, prm_get_event_name, multi_expose_transaction_dataname, prm_name, name, size); + int msg_err = m_damaris->damaris_pdi_parameter_get(prm_name.c_str(), static_cast(wref.get()), size); } else { //Error handling! @@ -256,6 +267,7 @@ class damaris_plugin: public Plugin { context().logger().info("'{}' == m_config.is_client_dataset_name() = '{}'", name, (name == m_config.is_client_dataset_name())); if (Ref_w wref = ref) { + context().logger().info(":) D) '{}' == m_config.is_client_dataset_name() = '{}' | m_damaris->get_is_client() = '{}'", name, (name == m_config.is_client_dataset_name()), m_damaris->get_is_client()); *static_cast(wref.get()) = m_damaris->get_is_client(); context().logger().info("------------------- CALLED is_client_dataset_name Return is_client = '{}')", m_damaris->get_is_client()); } @@ -288,7 +300,26 @@ class damaris_plugin: public Plugin { void event(const std::string& event_name) { - if(m_event_handler.is_damaris_api_call_event(event_name)){ + //If it a sim configured event + if (m_config.events().find(event_name) != m_config.events().end()) { + if(event_name == m_config.init_on_event()) { + std::string init_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_INITIALIZE); + m_event_handler.damaris_api_call_event(context(), m_damaris, init_event_name, multi_expose_transaction_dataname); + } + else if(event_name == m_config.start_on_event()) { + std::string start_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_START); + m_event_handler.damaris_api_call_event(context(), m_damaris, start_event_name, multi_expose_transaction_dataname); + } + else if(event_name == m_config.end_iteration_on_event()) { + std::string end_it_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_END_ITERATION); + m_event_handler.damaris_api_call_event(context(), m_damaris, end_it_event_name, multi_expose_transaction_dataname); + } + else if(event_name == m_config.finalize_on_event()) { + std::string finalize_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_FINALIZE); + m_event_handler.damaris_api_call_event(context(), m_damaris, finalize_event_name, multi_expose_transaction_dataname); + } + } + else if(m_event_handler.is_damaris_api_call_event(event_name)){ context().logger().info("event `{}' has been triggered", event_name); context().logger().info("is_damaris_api_call_event ( `{}' ) = TRUE", event_name); @@ -304,6 +335,13 @@ class damaris_plugin: public Plugin { ~damaris_plugin() { + + if (m_config.finalize_on_event().empty() && m_damaris) { + std::string finalize_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_FINALIZE); + m_event_handler.damaris_api_call_event(context(), m_damaris, finalize_event_name, multi_expose_transaction_dataname); + //PDI_status_t status = PDI_event(finalize_event_name.c_str()); + } + context().logger().info("Closing plugin"); } diff --git a/plugins/damaris/damaris_api_call_handler.cxx b/plugins/damaris/damaris_api_call_handler.cxx index c6f85285a..c559b808d 100644 --- a/plugins/damaris/damaris_api_call_handler.cxx +++ b/plugins/damaris/damaris_api_call_handler.cxx @@ -25,6 +25,7 @@ #include #include "damaris_api_call_handler.h" +#include "damaris_cfg.h" using PDI::Context; using PDI::Ref; @@ -51,7 +52,7 @@ Damaris_api_call_handler::Damaris_api_call_handler(std::string cfg_object, PDI:: m_communicator = comm; } -Damaris_api_call_handler::Damaris_api_call_handler(std::string cfg_object, PDI::Expression comm, bool init_on_event, bool start_on_event, bool stop_on_event) +Damaris_api_call_handler::Damaris_api_call_handler(std::string cfg_object, PDI::Expression comm, std::string init_on_event, std::string start_on_event, std::string stop_on_event) { xml_config_object = cfg_object; m_communicator = comm; @@ -80,12 +81,11 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptrc_str(), ++arg_pos, expose_dataname.size()); - - if (arg_pos == 1) - { - PDI_access(it->c_str(), (void**)&var_name, PDI_IN); - arg1_name = it->c_str(); - } - else if (arg_pos == 2){ - PDI_access(it->c_str(), (void**)&buffer, PDI_INOUT); - arg2_name = it->c_str(); - } - else if (arg_pos == 3){ - PDI_access(it->c_str(), (void**)&size, PDI_IN); - arg3_name = it->c_str(); - } - else - //if(nb_awaited_args <= arg_pos) - break; - } - ctx.logger().info("------------------- CALLING damaris_pdi_parameter_get arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, *(int *)buffer, arg3_name, *(int*)size); - int err = m_damaris->damaris_pdi_parameter_get((const char*)var_name, (void *) buffer, *(int*)size); + ctx.logger().info("------------------- CALLING damaris_pdi_parameter_get arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, *(int *)buffer, arg3_name, *(int*)size); + int err = m_damaris->damaris_pdi_parameter_get((const char*)var_name, (void *) buffer, *(int*)size); + } + } // DAMARIS_PARAMETER_SET else if(event_name == event_names.at(Event_type::DAMARIS_PARAMETER_SET)) { @@ -187,41 +172,21 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptrc_str(), ++arg_pos, expose_dataname.size()); - - if (arg_pos == 1) - { - PDI_access(it->c_str(), (void**)&var_name, PDI_IN); - arg1_name = it->c_str(); - } - else if (arg_pos == 2){ - PDI_access(it->c_str(), (void**)&buffer, PDI_IN); - arg2_name = it->c_str(); - } - else if (arg_pos == 3){ - PDI_access(it->c_str(), (void**)&size, PDI_IN); - arg3_name = it->c_str(); - } - else - //if(nb_awaited_args <= arg_pos) - break; - } + char* var_name; std::string arg1_name = "prm_name"; + void* buffer; std::string arg2_name = "prm_buffer"; + unsigned int* size; std::string arg3_name = "prm_size"; + + va_list extra_args; + va_start(extra_args, expose_dataname); + string data_name = va_arg(extra_args, string); + if(!data_name.empty()) { + var_name = (char*)data_name.c_str(); + buffer = va_arg(extra_args, void*); + *size = va_arg(extra_args, size_t); - ctx.logger().info("------------------- CALLING damaris_pdi_parameter_set arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, *(int *)buffer, arg3_name, *(int*)size); - int err = m_damaris->damaris_pdi_parameter_set((const char*)var_name, (const void *) buffer, *(int*)size); + ctx.logger().info("------------------- CALLING damaris_pdi_parameter_set arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, *(int *)buffer, arg3_name, *(int*)size); + int err = m_damaris->damaris_pdi_parameter_set((const char*)var_name, (const void *) buffer, *(int*)size); + } } // DAMARIS_CLIENT_COMM_GET else if(event_name == event_names.at(Event_type::DAMARIS_CLIENT_COMM_GET)) { @@ -464,14 +429,13 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptrdamaris_pdi_stop(); } - else if(event_name == event_names.at(Event_type::DAMARIS_FINALIZE) - || event_name == event_names.at(Event_type::DAMARIS_FINALIZE_ALIAS)) { + else if(event_name == event_names.at(Event_type::DAMARIS_FINALIZE)) { if (!m_damaris) { ctx.logger().warn("Trying to call damaris_strop() before plugin initialization (`{}')", event_name); return; } - if (!m_stop_on_event) { + if (m_stop_on_event.empty()) { ctx.logger().info("Plugin sent damaris_stop() to Damaris, in finalization"); //std::string stop_event_name = this->get_event_name(Event_type::DAMARIS_STOP); diff --git a/plugins/damaris/damaris_api_call_handler.h b/plugins/damaris/damaris_api_call_handler.h index a257cc756..52602dc4d 100644 --- a/plugins/damaris/damaris_api_call_handler.h +++ b/plugins/damaris/damaris_api_call_handler.h @@ -37,6 +37,7 @@ #include #include "damaris_wrapper.h" +#include "damaris_cfg.h" using PDI::Context; using std::list; @@ -45,57 +46,18 @@ using std::unique_ptr; namespace damaris_pdi { -enum class Event_type { - DAMARIS_INITIALIZE = 0 - , DAMARIS_INITIALIZE_ALIAS = 1 - , DAMARIS_START = 2 - , DAMARIS_SET_POSITION = 3 - , DAMARIS_SET_BLOCK_POSITION = 4 - , DAMARIS_WRITE = 5 - , DAMARIS_WRITE_BLOCK = 6 - , DAMARIS_CLIENT_COMM_GET = 7 - , DAMARIS_PARAMETER_SET = 8 - , DAMARIS_PARAMETER_GET = 10 - , DAMARIS_END_ITERATION = 12 - , DAMARIS_GET_ITERATION = 13 - , DAMARIS_SIGNAL = 15 - , DAMARIS_BIND = 16 - , DAMARIS_STOP = 17 - , DAMARIS_FINALIZE = 18 - , DAMARIS_FINALIZE_ALIAS = 19 -}; - -const std::unordered_map event_names = { - {Event_type::DAMARIS_INITIALIZE, "initialize"} - ,{Event_type::DAMARIS_INITIALIZE_ALIAS, "init"} - ,{Event_type::DAMARIS_START, "damaris_start"} - ,{Event_type::DAMARIS_SET_POSITION, "damaris_set_position"} - ,{Event_type::DAMARIS_SET_BLOCK_POSITION, "damaris_set_block_position"} - ,{Event_type::DAMARIS_WRITE, "damaris_write"} - ,{Event_type::DAMARIS_WRITE_BLOCK, "damaris_write_block"} - ,{Event_type::DAMARIS_CLIENT_COMM_GET, "damaris_client_comm_get"} - ,{Event_type::DAMARIS_PARAMETER_SET, "damaris_parameter_set"} - ,{Event_type::DAMARIS_PARAMETER_GET, "damaris_parameter_get"} - ,{Event_type::DAMARIS_END_ITERATION, "damaris_end_iteration"} - ,{Event_type::DAMARIS_GET_ITERATION, "damaris_get_iteration"} - ,{Event_type::DAMARIS_SIGNAL, "damaris_signal"} - ,{Event_type::DAMARIS_BIND, "damaris_bind"} - ,{Event_type::DAMARIS_STOP, "damaris_stop"} - ,{Event_type::DAMARIS_FINALIZE, "finalize"} - ,{Event_type::DAMARIS_FINALIZE_ALIAS, "finalization"} -}; - class Damaris_api_call_handler { std::string xml_config_object; PDI::Expression m_communicator; - bool m_init_on_event = false; - bool m_start_on_event = false; - bool m_stop_on_event = false; + std::string m_init_on_event = ""; + std::string m_start_on_event = ""; + std::string m_stop_on_event = ""; + std::string m_finalize_on_event = ""; public: - Damaris_api_call_handler(std::string cfg_object, PDI::Expression comm, bool init_on_event, bool start_on_event, bool stop_on_event); + Damaris_api_call_handler(std::string cfg_object, PDI::Expression comm, std::string init_on_event, std::string start_on_event, std::string stop_on_event); Damaris_api_call_handler(std::string cfg_object, PDI::Expression comm); Damaris_api_call_handler(std::string cfg_object); diff --git a/plugins/damaris/damaris_cfg.cxx b/plugins/damaris/damaris_cfg.cxx index cfad4f274..7ec2cb547 100644 --- a/plugins/damaris/damaris_cfg.cxx +++ b/plugins/damaris/damaris_cfg.cxx @@ -63,9 +63,18 @@ namespace { - bool load_desc(unordered_map& descs, Context& ctx, const string& name, Desc_type desc_type) + bool load_desc(unordered_map& descs, Context& ctx, const string& name, Desc_type desc_type) + { + auto&& result = descs.emplace(name, desc_type); + if (!result.second) { + //ctx.logger().warn("Duplicate use of a descriptor `{}' in `{}' (previously used in `{}')", name, desc_names.at(desc_type), desc_names.at(result.first->second)); + } + return result.second; + } + + bool load_event(unordered_map& events, Context& ctx, const string& name, Event_type event_type) { - auto&& result = descs.emplace(name, desc_type); + auto&& result = events.emplace(name, event_type); if (!result.second) { //ctx.logger().warn("Duplicate use of a descriptor `{}' in `{}' (previously used in `{}')", name, desc_names.at(desc_type), desc_names.at(result.first->second)); } @@ -114,17 +123,28 @@ throw Config_error{key_tree, "no MPI communicator set", key}; } } - else if (key == "init_on_event") { - m_init_on_event = to_long(value);// Default = false + else if (key == "init_on_event" || key == "on_init") { + m_init_on_event = to_string(value); + load_event(m_events, ctx, m_init_on_event, Event_type::DAMARIS_INITIALIZE); + } + else if (key == "finalize_on_event" || key == "on_finalize") { + m_finalize_on_event = to_string(value); + load_event(m_events, ctx, m_finalize_on_event, Event_type::DAMARIS_FINALIZE); } else if (key == "start_on_event") { - m_start_on_event = to_long(value);// Default = false + m_start_on_event = to_string(value); + load_event(m_events, ctx, m_start_on_event, Event_type::DAMARIS_START); } else if (key == "stop_on_event") { - m_stop_on_event = to_long(value);// Default = false + m_stop_on_event = to_string(value); + load_event(m_events, ctx, m_stop_on_event, Event_type::DAMARIS_STOP); + } + else if (key == "end_iteration_on_event") { + m_end_iteration_on_event = to_string(value); + load_event(m_events, ctx, m_end_iteration_on_event, Event_type::DAMARIS_END_ITERATION); } else if (key == "parameters") { - parse_parameters_tree(ctx, value); + parse_parameters_tree(ctx, value); } else if (key == "datasets") { parse_datasets_tree(ctx, value); @@ -190,6 +210,13 @@ throw Config_error{key_tree, "Unknown key in Damaris configuration: `{}'", key}; }*/ }); + + std::string end_it_event_name = event_names.at(Event_type::DAMARIS_END_ITERATION); + //Add only if it does not exist yet + if(std::find(m_after_write_events.begin(), m_after_write_events.end(), end_it_event_name) == m_after_write_events.end() + && m_end_iteration_on_event.empty()){ + m_after_write_events.emplace_back(end_it_event_name); + } parse_log_tree(ctx, tree); @@ -823,139 +850,97 @@ } void Damaris_cfg::parse_write_tree(Context& ctx, PC_tree_t write_tree_list) - { - // opt_each(write_tree_list, [&](PC_tree_t writes_tree) {//list of ds map - each(write_tree_list, [&](PC_tree_t writet_key, PC_tree_t write_ds_tree) {//each dataset to write - - std::string ds_name = to_string(writet_key);//the name of the data to write, if dataset not specified afterward! - Dataset_Write_Info ds_write_info; - - //dataset - PC_tree_t ds_name_tree = PC_get(write_ds_tree, ".dataset"); - if(!PC_status(ds_name_tree)) - { - ds_name = to_string(ds_name_tree); - std::cout << "INFO: damaris_cfg write_ds_tree :: ds_name = '" << ds_name << "'" << std::endl ; - } - //when - PC_tree_t ds_when_tree = PC_get(write_ds_tree, ".when"); - if(!PC_status(ds_when_tree)) - { - ds_write_info.when = to_string(ds_when_tree); - std::cout << "INFO: damaris_cfg write_ds_tree :: when = '" << ds_write_info.when << "'" << std::endl ; - } - //position - PC_tree_t ds_position_tree = PC_get(write_ds_tree, ".position"); - if(!PC_status(ds_position_tree)) - { - if (!PC_status(PC_get(ds_position_tree, "[0]"))) {//Array [p0,p1,p3] (1 to 3 elements) - int position_dim; PC_len(ds_position_tree, &position_dim); - std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: " << position_dim << std::endl ; - - int pos_idx = 0; - each(ds_position_tree, [&](PC_tree_t dim) { - ds_write_info.position[pos_idx] = to_string(dim); - pos_idx++; - }); - } - else {//p0 - ds_write_info.position[0] = to_string(ds_position_tree); - std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: 1" << std::endl ; - } - } - //block - PC_tree_t ds_block_tree = PC_get(write_ds_tree, ".block"); - if(!PC_status(ds_block_tree)) - { - ds_write_info.block = to_string(ds_block_tree); - std::cout << "INFO: damaris_cfg write_ds_tree :: block = '" << ds_write_info.block << "'" << std::endl ; - } - - /* - each(write_ds_tree, [&](PC_tree_t wdst_key, PC_tree_t value) {//storage info - std::string key = to_string(wdst_key); - - if (key == "dataset") { - ds_name = to_string(value); - } - else if (key == "when") { - ds_write_info.when = to_string(value); - } - else if (key == "position") { - if (!PC_status(PC_get(value, "[0]"))) {//Array [p0,p1,p3] (1 to 3 elements) - int position_dim; PC_len(value, &position_dim); - std::cout << "INFO: damaris_cfg ds '"<< ds_name <<"' will be written in dims: " << position_dim << std::endl ; - - int pos_idx = 0; - each(value, [&](PC_tree_t dim) { - ds_write_info.position[pos_idx] = to_long(dim); - pos_idx++; - }); - } - else {//p0 - ds_write_info.position[0] = to_long(value); - } - } - else if (key == "block") { - ds_write_info.block = to_long(value); - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized write map string: " << key << std::endl ; - } - }); - */ - - m_datasets_to_write.emplace(ds_name, ds_write_info); - - load_desc(m_descs, ctx, ds_name, Desc_type::DATA_TO_WRITE_WITH_BLOCK); - }); - //}); + { + each(write_tree_list, [&](PC_tree_t writet_key, PC_tree_t write_ds_tree) {//each dataset to write + + std::string ds_name = to_string(writet_key);//the name of the data to write, if dataset not specified afterward! + Dataset_Write_Info ds_write_info; + + //dataset + PC_tree_t ds_name_tree = PC_get(write_ds_tree, ".dataset"); + if(!PC_status(ds_name_tree)) + { + ds_name = to_string(ds_name_tree); + std::cout << "INFO: damaris_cfg write_ds_tree :: ds_name = '" << ds_name << "'" << std::endl ; + } + //when + PC_tree_t ds_when_tree = PC_get(write_ds_tree, ".when"); + if(!PC_status(ds_when_tree)) + { + ds_write_info.when = to_string(ds_when_tree); + std::cout << "INFO: damaris_cfg write_ds_tree :: when = '" << ds_write_info.when << "'" << std::endl ; + } + //position + PC_tree_t ds_position_tree = PC_get(write_ds_tree, ".position"); + if(!PC_status(ds_position_tree)) + { + if (!PC_status(PC_get(ds_position_tree, "[0]"))) {//Array [p0,p1,p3] (1 to 3 elements) + int position_dim; PC_len(ds_position_tree, &position_dim); + std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: " << position_dim << std::endl ; + + int pos_idx = 0; + each(ds_position_tree, [&](PC_tree_t dim) { + ds_write_info.position[pos_idx] = to_string(dim); + pos_idx++; + }); + } + else {//p0 + ds_write_info.position[0] = to_string(ds_position_tree); + std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: 1" << std::endl ; + } + } + //block + PC_tree_t ds_block_tree = PC_get(write_ds_tree, ".block"); + if(!PC_status(ds_block_tree)) + { + ds_write_info.block = to_string(ds_block_tree); + std::cout << "INFO: damaris_cfg write_ds_tree :: block = '" << ds_write_info.block << "'" << std::endl ; + } + + m_datasets_to_write.emplace(ds_name, ds_write_info); + + load_desc(m_descs, ctx, ds_name, Desc_type::DATA_TO_WRITE_WITH_BLOCK); + }); } void Damaris_cfg::parse_parameter_to_update_tree(Context& ctx, PC_tree_t ptu_tree, Desc_type op_type) - { - if (!PC_status(ptu_tree)) { // it's a name:{config...} mapping - each(ptu_tree, [&](PC_tree_t ptu_metadata, PC_tree_t ptu_prmname) { - std::string metadata = to_string(ptu_metadata); - std::string prm_name = to_string(ptu_metadata); - std::pair prm_to_update_info; - - if(!PC_status(ptu_prmname)) - { - if(to_string(ptu_prmname) != "") - prm_name = to_string(ptu_prmname); - } - - prm_to_update_info.first = prm_name; - prm_to_update_info.second = op_type; - m_parameter_to_update.emplace(metadata, prm_to_update_info); - load_desc(m_descs, ctx, metadata, op_type); - }); - } - else if (!PC_status(PC_get(ptu_tree, "[0]"))) {//Array [prm0,prm1,prm3,...] / it's a list of names only - each(ptu_tree, [&](PC_tree_t prm_name_t) { - std::pair prm_to_update_info; - std::string metadata = to_string(prm_name_t); - std::string prm_name = to_string(prm_name_t); - - prm_to_update_info.first = prm_name; - prm_to_update_info.second = op_type; - m_parameter_to_update.emplace(metadata, prm_to_update_info); - load_desc(m_descs, ctx, metadata, op_type); - }); - } - else {//prm0 - std::pair prm_to_update_info; - std::string metadata = to_string(ptu_tree); - std::string prm_name = to_string(ptu_tree); - - prm_to_update_info.first = prm_name; - prm_to_update_info.second = op_type; - m_parameter_to_update.emplace(metadata, prm_to_update_info); - load_desc(m_descs, ctx, metadata, op_type); - } + { + if (!PC_status(PC_get(ptu_tree, "[0]"))) {//Array [prm0,prm1,prm3,...] / it's a list of names only + std::cout << "INFO: damaris_cfg parameter_set or _get :: Array [prm0,prm1,prm3,...] / it's a list of names only " << std::endl ; + each(ptu_tree, [&](PC_tree_t prm_name_t) { + std::pair prm_to_update_info; + std::string metadata = to_string(prm_name_t); + std::string prm_name = to_string(prm_name_t); + + prm_to_update_info.first = prm_name; + prm_to_update_info.second = op_type; + m_parameter_to_update.emplace(metadata, prm_to_update_info); + load_desc(m_descs, ctx, metadata, op_type); + std::cout << "INFO: damaris_cfg parameter_set or _get :: metadata = "<< metadata <<" and prm_name = "<< prm_name <<" " << std::endl ; + }); + } + else if (!PC_status(ptu_tree)) { // it's a name:{config...} mapping + std::cout << "INFO: damaris_cfg parameter_set or _get :: it's a name:{config...} mapping " << std::endl ; + each(ptu_tree, [&](PC_tree_t ptu_metadata, PC_tree_t ptu_prmname) { + std::string metadata = to_string(ptu_metadata); + std::string prm_name = to_string(ptu_metadata); + std::pair prm_to_update_info; + + if(!PC_status(ptu_prmname)) + { + if(to_string(ptu_prmname) != "") + prm_name = to_string(ptu_prmname); + } + + prm_to_update_info.first = prm_name; + prm_to_update_info.second = op_type; + m_parameter_to_update.emplace(metadata, prm_to_update_info); + load_desc(m_descs, ctx, metadata, op_type); + std::cout << "INFO: damaris_cfg parameter_set or _get :: metadata = "<< metadata <<" and prm_name = "<< prm_name <<" " << std::endl ; + }); + } } void Damaris_cfg::parse_log_tree(Context& ctx, PC_tree_t config) @@ -1321,6 +1306,11 @@ { return m_parameters; } + +const damaris::model::DamarisParameterXML Damaris_cfg::get_parameter_xml(string prm_name) const +{ + return m_parameters.at(prm_name); +} const std::unordered_map& Damaris_cfg::storages() const { @@ -1342,6 +1332,11 @@ return m_descs; } + const unordered_map& Damaris_cfg::events() const + { + return m_events; + } + const std::unordered_map& Damaris_cfg::datasets_to_write() const { return m_datasets_to_write; @@ -1370,19 +1365,30 @@ } } - bool Damaris_cfg::init_on_event() const + std::string Damaris_cfg::init_on_event() const { - return m_init_on_event; + return m_init_on_event; } - bool Damaris_cfg::start_on_event() const + std::string Damaris_cfg::finalize_on_event() const + { + return m_finalize_on_event; + } + + + std::string Damaris_cfg::start_on_event() const { return m_start_on_event; } - bool Damaris_cfg::stop_on_event() const + std::string Damaris_cfg::stop_on_event() const { return m_stop_on_event; } + std::string Damaris_cfg::end_iteration_on_event() const + { + return m_end_iteration_on_event; + } + } // namespace damaris_pdi \ No newline at end of file diff --git a/plugins/damaris/damaris_cfg.h b/plugins/damaris/damaris_cfg.h index f662fd6e2..6496f2697 100644 --- a/plugins/damaris/damaris_cfg.h +++ b/plugins/damaris/damaris_cfg.h @@ -55,7 +55,7 @@ int start ; int stride ; int blocksize ; - std::vector mask {} ; + std::vector mask {} ;//std::vector mask {} ??? } placement ; typedef struct dedicated { @@ -79,6 +79,43 @@ ,IS_CLIENT_GET ,CLIENT_COMM_GET }; + + enum class Event_type { + DAMARIS_INITIALIZE = 0 + , DAMARIS_START = 1 + , DAMARIS_SET_POSITION = 2 + , DAMARIS_SET_BLOCK_POSITION = 3 + , DAMARIS_WRITE = 4 + , DAMARIS_WRITE_BLOCK = 5 + , DAMARIS_CLIENT_COMM_GET = 6 + , DAMARIS_PARAMETER_SET = 7 + , DAMARIS_PARAMETER_GET = 8 + , DAMARIS_END_ITERATION = 9 + , DAMARIS_GET_ITERATION = 10 + , DAMARIS_SIGNAL = 11 + , DAMARIS_BIND = 12 + , DAMARIS_STOP = 13 + , DAMARIS_FINALIZE = 14 + }; + + /** These default event names are for internal use. If a configured name is given, these ones will be surcharged */ +const std::unordered_map event_names = { + {Event_type::DAMARIS_INITIALIZE, "initialize"} + ,{Event_type::DAMARIS_START, "damaris_start"} + ,{Event_type::DAMARIS_SET_POSITION, "damaris_set_position"} + ,{Event_type::DAMARIS_SET_BLOCK_POSITION, "damaris_set_block_position"} + ,{Event_type::DAMARIS_WRITE, "damaris_write"} + ,{Event_type::DAMARIS_WRITE_BLOCK, "damaris_write_block"} + ,{Event_type::DAMARIS_CLIENT_COMM_GET, "damaris_client_comm_get"} + ,{Event_type::DAMARIS_PARAMETER_SET, "damaris_parameter_set"} + ,{Event_type::DAMARIS_PARAMETER_GET, "damaris_parameter_get"} + ,{Event_type::DAMARIS_END_ITERATION, "damaris_end_iteration"} + ,{Event_type::DAMARIS_GET_ITERATION, "damaris_get_iteration"} + ,{Event_type::DAMARIS_SIGNAL, "damaris_signal"} + ,{Event_type::DAMARIS_BIND, "damaris_bind"} + ,{Event_type::DAMARIS_STOP, "damaris_stop"} + ,{Event_type::DAMARIS_FINALIZE, "finalize"} +}; struct Dataset_Write_Info { PDI::Expression when = "1";//By default, always write as long as there are iteration going on @@ -100,9 +137,12 @@ std::string m_xml_config_object; damaris::model::ModifyModel damarisXMLModifyModel; - bool m_init_on_event = false; - bool m_start_on_event = false; - bool m_stop_on_event = false; + std::string m_init_on_event = ""; + std::string m_start_on_event = ""; + std::string m_stop_on_event = ""; + std::string m_end_iteration_on_event = ""; + std::string m_finalize_on_event = ""; + int m_arch_domains ; int m_dc_cores_pernode ; @@ -125,7 +165,8 @@ damaris::model::DamarisParaviewXML *m_paraview = NULL; damaris::model::DamarisPyScriptXML *m_pyscript = NULL; - std::unordered_map m_descs ; + std::unordered_map m_descs ; + std::unordered_map m_events; std::unordered_map m_datasets_to_write; list m_after_write_events; //> @@ -203,11 +244,13 @@ const std::unordered_map& datasets() const; const std::unordered_map& layouts() const; const std::unordered_map& parameters() const; + const damaris::model::DamarisParameterXML get_parameter_xml(string prm_name) const; const std::unordered_map& storages() const; const std::unordered_map& meshes() const; const std::unordered_map& groups() const; const std::unordered_map& descs() const; + const std::unordered_map& events() const; const std::unordered_map& datasets_to_write() const; const std::unordered_map>& parameter_to_update() const; @@ -230,9 +273,11 @@ return m_client_comm_get_dataset_name; } - bool init_on_event() const; - bool start_on_event() const; - bool stop_on_event() const; + std::string init_on_event() const; + std::string start_on_event() const; + std::string stop_on_event() const; + std::string end_iteration_on_event() const; + std::string finalize_on_event() const; const std::unordered_map>& recover_var() const; diff --git a/plugins/damaris/example/example.c b/plugins/damaris/example/example.c index b35f3e9a2..faf208235 100644 --- a/plugins/damaris/example/example.c +++ b/plugins/damaris/example/example.c @@ -163,11 +163,9 @@ int main(int argc, char* argv[]) MPI_Comm main_comm;// = MPI_COMM_WORLD; PDI_init(PC_get(conf, ".pdi")); - PDI_event("init"); // event "init" is currently reserved for damaris. It is not recommand for plugins to reserve certain names of events. - // we can try to use the key "on_init" for example - // PDI_event("user_init_damaris"); + PDI_event("init"); - int is_client = 2; + int is_client = -1; PDI_expose("is_client", &is_client, PDI_IN); printf("-------------------------------------------------------------------------------------D: :) ;) is_client = %d\n", is_client); @@ -183,7 +181,7 @@ int main(int argc, char* argv[]) //,"client_comm", &main_comm, PDI_INOUT //, NULL); - PDI_expose("mpi_comm", &main_comm, PDI_INOUT); // PDI_IN should be sufficient? + PDI_expose("mpi_comm", &main_comm, PDI_INOUT); //MPI_Comm hdf5_mpi_comm = main_comm; //PDI_expose("hdf5_mpi_comm", &hdf5_mpi_comm, PDI_INOUT); diff --git a/plugins/damaris/example/example.yml b/plugins/damaris/example/example.yml index 153a0a76b..753f2531c 100644 --- a/plugins/damaris/example/example.yml +++ b/plugins/damaris/example/example.yml @@ -14,7 +14,8 @@ pdi: pcoord: { size: 2, type: array, subtype: int } # coordinate of the process mpi_comm: MPI_Comm data: # type of values for which PDI does not keep a copy - #is_client: int # Question: pourquoi pas d'erreur meme si "is_client" n'est pas déclaré comme data, et que simulation accède à cette donnée? + # Question: pourquoi pas d'erreur meme si "is_client" n'est pas déclaré comme data, et que simulation accède à cette donnée? + #is_client: int #mpi_comm: MPI_Comm main_field: { size: [ '$dsize[0]', '$dsize[1]' ], type: array, subtype: double } @@ -40,10 +41,11 @@ pdi: size: [1, '$dsize[0]-2', '$dsize[1]-2'] start: [$iter, '($dsize[0]-2)*$pcoord[0]', '($dsize[1]-2)*$pcoord[1]'] damaris: - - init_on_event: 1 # à simplifier ref set_value plugin ou la doc PDI: on_init, on_data, on_event , on_finalize - #on_init: init_damaris - #start_on_event: 1 + + on_init: init #or init_on_event + #start_on_event: damaris_start + #end_iteration_on_event: damaris_end_iteration + on_finalize: finalization #Or finalize_on_event communicator: $MPI_COMM_WORLD # pas utilisé actuellement architecture: sim_name: example @@ -144,3 +146,4 @@ pdi: log_level: info flush: true + From d02cbe5ea238ce58582c825a87064149d12630ed Mon Sep 17 00:00:00 2001 From: Etienne Ndamlabin Date: Mon, 7 Apr 2025 12:05:40 +0200 Subject: [PATCH 08/42] Removing damaris parameters from yaml and only using PDI metadata. Each element requiring any metadata value uses depends_on YAML attribute to ensure an update of its attributes value to Damaris lib once the metadata are exposed (using Damaris Parameters in the background)! --- plugins/damaris/damaris.cxx | 43 +++++--- plugins/damaris/damaris_cfg.cxx | 148 ++++++++++++++++++++++++++-- plugins/damaris/damaris_cfg.h | 2 + plugins/damaris/example/example.yml | 59 ++--------- 4 files changed, 181 insertions(+), 71 deletions(-) diff --git a/plugins/damaris/damaris.cxx b/plugins/damaris/damaris.cxx index e9a8af2ec..88ef69261 100644 --- a/plugins/damaris/damaris.cxx +++ b/plugins/damaris/damaris.cxx @@ -87,7 +87,8 @@ class damaris_plugin: public Plugin { std::string int_numbers_types[3] = {"short", "int", "integer"}; std::string real_numbers_types[3] = {"float", "real", "double"}; - + + int iteration = 0;//for debugging public: damaris_plugin(Context& ctx, PC_tree_t config) @@ -96,10 +97,14 @@ class damaris_plugin: public Plugin { , m_event_handler{m_config.xml_config_object(), m_config.communicator(), m_config.init_on_event() , m_config.start_on_event(), m_config.stop_on_event()} { + + std::string data_cb_concat = ""; for (auto&& desc: m_config.descs()) {//add data callback only for awaited data ctx.callbacks().add_data_callback([this](const std::string& name, Ref ref) { this->data(name, ref); }, desc.first); + data_cb_concat.append(desc.first + ", "); } + context().logger().info("Data for callback : {}", data_cb_concat); //Sim configured event names for (auto&& event: m_config.events()) { @@ -136,7 +141,7 @@ class damaris_plugin: public Plugin { void data(const std::string& name, Ref ref) { - //context().logger().info("data `{}' has been exposed", name); + context().logger().info("data `{}' has been exposed", name); //Update damaris parameters if(m_config.is_needed_metadata(name)){ @@ -148,18 +153,26 @@ class damaris_plugin: public Plugin { auto update_info = prm_update_info.second; { std::string prm_value = update_info.first; - std::string prm_type = update_info.second; + std::string prm_type = update_info.second; void* prm_value_buffer; size_t prm_buffer_size; - if(std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prm_type)) { + if(std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prm_type) != std::end(int_numbers_types)) { + std::cout << "int_numbers_types contains " << prm_type << '\n'; int prm_long_value = std::atoi(prm_value.c_str()); prm_value_buffer = &prm_long_value; prm_buffer_size = sizeof(int); - int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), prm_value_buffer, prm_buffer_size); + int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), prm_value_buffer, prm_buffer_size); + + //checking if it works! + /*int new_prm_val; + m_damaris->damaris_pdi_parameter_get(prm_name.c_str(), &new_prm_val, prm_buffer_size); + context().logger().info("---------------------------------------------------------> Parameter '{}' updated successfully, new value '{}' vs Sent Value '{}'", prm_name, new_prm_val, prm_long_value); + */ } - else if(std::find(std::begin(real_numbers_types), std::end(real_numbers_types), prm_type)) { + else if(std::find(std::begin(real_numbers_types), std::end(real_numbers_types), prm_type) != std::end(real_numbers_types)) { + std::cout << "real_numbers_types contains " << prm_type << '\n'; double prm_dbl_value = std::atof(prm_value.c_str()); prm_value_buffer = &prm_dbl_value; prm_buffer_size = sizeof(double); @@ -167,6 +180,7 @@ class damaris_plugin: public Plugin { int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), prm_value_buffer, prm_buffer_size); } else { + std::cout << "String === " << prm_type << '\n'; std::string prm_string_value = prm_value; prm_value_buffer = &prm_string_value; prm_buffer_size = sizeof(std::string); @@ -178,9 +192,11 @@ class damaris_plugin: public Plugin { prm_name_concat.append(prm_name + ", "); m_config.reset_parameter_depends_on(prm_name); } - prm_name_concat.pop_back(); - prm_name_concat.pop_back(); - context().logger().info("data `{}' Is a needed metadata for the evaluation of parameters {}", name, prm_name_concat); + if(updatable_parameters.size() > 0){ + prm_name_concat.pop_back(); + prm_name_concat.pop_back(); + context().logger().info("data `{}' Is a needed metadata for the evaluation of parameters {}", name, prm_name_concat); + } } else if(m_config.is_dataset_to_write(name)){ context().logger().info("is_dataset_to_write(`{}') = '{}'", name, m_config.is_dataset_to_write(name)); @@ -229,6 +245,11 @@ class damaris_plugin: public Plugin { else{ context().logger().error("The Damaris need write access over the data (`{}')", name); } + + //Debugging + //iteration++; + //if(iteration == 2) + // exit(0); } else if(m_config.is_parameter_to_update(name)){ context().logger().info("m_config.is_parameter_to_update('{}') = `{}'", name, m_config.is_parameter_to_update(name)); @@ -238,10 +259,10 @@ class damaris_plugin: public Plugin { damaris::model::DamarisParameterXML prmxml = m_config.get_parameter_xml(prm_name); - if(std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prmxml.param_datatype_)) { + if(std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prmxml.param_datatype_) != std::end(int_numbers_types)) { size = sizeof(int); } - else if(std::find(std::begin(real_numbers_types), std::end(real_numbers_types), prmxml.param_datatype_)) { + else if(std::find(std::begin(real_numbers_types), std::end(real_numbers_types), prmxml.param_datatype_) != std::end(real_numbers_types)) { size = sizeof(double); } else { diff --git a/plugins/damaris/damaris_cfg.cxx b/plugins/damaris/damaris_cfg.cxx index 7ec2cb547..5daec0404 100644 --- a/plugins/damaris/damaris_cfg.cxx +++ b/plugins/damaris/damaris_cfg.cxx @@ -33,6 +33,7 @@ #include #include #include + #include #include "damaris_cfg.h" @@ -100,6 +101,9 @@ void insert_dataset_elts_to_group(DS_TYPE varxml, std::string nested_groups_names[], unsigned index); //void insert_dataset_elts_to_group(damaris::model::DamarisVarXML varxml, std::string nested_groups_names[], unsigned index); + std::string numbers_types[] = {"short", "int", "integer", "float", "real", "double"}; + std::string int_numbers_types[3] = {"short", "int", "integer"}; + std::string real_numbers_types[3] = {"float", "real", "double"}; // This constructor is called on the construction of the damaris_plugin struct/object // This code is a mapping of the Damaris src/model/Model.xsd schema to PDI YAML @@ -244,7 +248,8 @@ m_xml_config_object = damarisXMLModifyModel.GetConfigString(); - //printf("-------------------------------------------------------XML OBJECT MODIFIED----------------------------------------------\n%s", damarisXMLModifyModel.GetConfigString().c_str()); + printf("-------------------------------------------------------XML OBJECT MODIFIED----------------------------------------------\n%s", damarisXMLModifyModel.GetConfigString().c_str()); + //exit(0); } void Damaris_cfg::parse_architecture_tree(Context& ctx, PC_tree_t arch_tree){ @@ -392,9 +397,11 @@ //m_parameter_expression.emplace(prmxml.param_name_, prmxml.param_value_); m_parameter_depends_on.emplace(prmxml.param_name_, depends_on_metadata); //set default value if depend on metadata - std::string numbers_types[] = {"short", "int", "integer", "float", "real", "double"}; - if(is_dependent && std::find(std::begin(numbers_types), std::end(numbers_types), prmxml.param_datatype_)) { - prmxml.param_value_ = "1"; //"0" + if(is_dependent && std::find(std::begin(numbers_types), std::end(numbers_types), prmxml.param_datatype_) != std::end(numbers_types)) { + if(std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prmxml.param_datatype_) != std::end(int_numbers_types)) + prmxml.param_value_ = "1"; //"0" + else + prmxml.param_value_ = "1.0"; //"0" } else { ///??? @@ -520,6 +527,11 @@ std::map find_replace_map = {}; unsigned name_index = 0; std::string dataset_elt_full_name; + std::unordered_map depends_on_metadata; + bool is_dependent = false; + std::string depends_on_str = ""; + std::string in_datatype; + int nb_dims; each(layout_tree, [&](PC_tree_t lt_key, PC_tree_t value) {//layout info std::string key = to_string(lt_key); @@ -535,7 +547,7 @@ layoutxml.layout_name_ = nested_groups_names[name_index-1]; //to_string(value); } else if (key == "type") { - std::string in_datatype = to_string(value); + in_datatype = to_string(value); layoutxml.set_datatype( in_datatype ); } else if (key == "dimensions") { @@ -556,12 +568,37 @@ layoutxml.layout_dimensions_ = to_string(value); } + nb_dims = count(layoutxml.layout_dimensions_.begin(),layoutxml.layout_dimensions_.end(),',') + 1; } - else if (key == "global") { - layoutxml.layout_dims_global_ = to_string(value); + else if (key == "global") { + //Is there a way to determine if an expression is ready to be evaluated? ei, all the conponent have a value + if (!PC_status(PC_get(value, "[0]"))) {//Array //[dg1,dg2,dg3] for instance, each di an expreession of of Damaris Parameter + + std::string dims_global_list = ""; + each(value, [&](PC_tree_t dim) { + dims_global_list += to_string(dim) + ","; + }); + dims_global_list.pop_back(); + layoutxml.layout_dims_global_ = dims_global_list; + } + else {//"dg1,dg2,dg3" for instance, each di an expreession of of Damaris Parameter + layoutxml.layout_dims_global_ = to_string(value); + } } else if (key == "ghosts") { - layoutxml.layout_ghosts_ = to_string(value); + //Is there a way to determine if an expression is ready to be evaluated? ei, all the conponent have a value + if (!PC_status(PC_get(value, "[0]"))) {//Array //['g11:g12','g21:g22','g31:g32'] for instance, each di an expreession of of Damaris Parameter + + std::string ghosts_list = ""; + each(value, [&](PC_tree_t dim) { + ghosts_list += to_string(dim) + ","; + }); + ghosts_list.pop_back(); + layoutxml.layout_ghosts_ = ghosts_list; + } + else {//"g11:g12,g21:g22,g31:g32" for instance, each di an expreession of of Damaris Parameter + layoutxml.layout_ghosts_ = to_string(value); + } } else if (key == "language") { std::string in_language = to_string(value); @@ -575,10 +612,105 @@ else if (key == "comment") { layoutxml.layout_comment_ = to_string(value); } + else if (key == "depends_on") { + is_dependent = true; + if (!PC_status(PC_get(value, "[0]"))) {//Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter + //int idx = 0; + each(value, [&](PC_tree_t metadata_name_tree) { + std::string metadata_name = to_string(metadata_name_tree); + depends_on_str += metadata_name+", "; + + depends_on_metadata.insert( + {metadata_name, false} + ); + + //load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); + }); + depends_on_str.pop_back();//' ' + depends_on_str.pop_back();//',' + } + else {//d1 + std::string metadata_name = to_string(value); + depends_on_str = metadata_name; + //depends_on_metadata[metadata_name] = false; + depends_on_metadata.insert( + {metadata_name, false} + ); + + //load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); + } + depends_on_str = "["+depends_on_str+"]"; + + } else { std::cerr << "ERROR: damaris_cfg unrecogognized layout map string: " << key << std::endl ; } }); + m_layout_depends_on.emplace(layoutxml.layout_name_, depends_on_metadata); + //set default value if depend on metadata + //if(is_dependent && std::find(std::begin(numbers_types), std::end(numbers_types), in_datatype)) { + if(is_dependent) { + std::stringstream ss_dims(layoutxml.layout_dimensions_), ss_globals(layoutxml.layout_dims_global_); + std::string tmp; + std::vector dim_list, global_list; + + while (std::getline(ss_dims, tmp, ',')) { + dim_list.push_back(tmp); + } + while (std::getline(ss_globals, tmp, ',')) { + global_list.push_back(tmp); + } + + ctx.logger().info("------------------- OLD layoutxml.layout_dimensions_ '{}' | layoutxml.layout_dims_global_ '{}'", layoutxml.layout_dimensions_, layoutxml.layout_dims_global_); + + ctx.logger().info("------------------- dim_list[0] = '{}' | global_list[0] = '{}'", dim_list[0], global_list[0]); + + std::string prm_config_yaml + = "";//"parameters: \n"; + + layoutxml.layout_dimensions_ = ""; + std::string new_globals = ""; + //TODO: get the type of the metadata to which the layout depends, to apply it to the parameters + std::string metadatatype = "int"; + + for (int i = 0; i < nb_dims; i++) + { + string dim_name = layoutxml.layout_name_+"_dim"+std::to_string(i); + prm_config_yaml += "- parameter: \n"; + prm_config_yaml += " name: "+dim_name+" \n"; + prm_config_yaml += " type: "+metadatatype+" \n"; + prm_config_yaml += " value: '"+dim_list[i]+"' \n"; + prm_config_yaml += " depends_on: "+depends_on_str+" \n"; + + layoutxml.layout_dimensions_ += dim_name+","; + + if(layoutxml.layout_dims_global_.length() > 1) { + string global_name = layoutxml.layout_name_+"_global"+std::to_string(i); + prm_config_yaml += "- parameter: \n"; + prm_config_yaml += " name: "+global_name+" \n"; + prm_config_yaml += " type: "+metadatatype+" \n"; + prm_config_yaml += " value: '"+global_list[i]+"' \n"; + prm_config_yaml += " depends_on: "+depends_on_str+" \n"; + + new_globals += global_name+","; + } + } + layoutxml.layout_dimensions_.pop_back(); + //the layout_dims_global_ attribute being optional with default value '#', we need to ensure it has been set before modification. + //if(layoutxml.layout_dims_global_ != '#') { + if(layoutxml.layout_dims_global_.length() > 1) { + new_globals.pop_back(); + layoutxml.layout_dims_global_ = new_globals; + } + + //Background creation of parameter + PC_tree_t parameters_conf = PC_parse_string(prm_config_yaml.c_str()); + ctx.logger().info("------------------- parameters_conf = \n '{}'", prm_config_yaml); + parse_parameters_tree(ctx, parameters_conf); + } + else { + ///??? + } if(dataset_elt_full_name.empty()) throw Value_error{"ERROR: damaris_cfg layout name must not be empty"}; diff --git a/plugins/damaris/damaris_cfg.h b/plugins/damaris/damaris_cfg.h index 6496f2697..c7e5f378b 100644 --- a/plugins/damaris/damaris_cfg.h +++ b/plugins/damaris/damaris_cfg.h @@ -178,6 +178,8 @@ const std::unordered_map event_names = { // This variable is intended for that std::unordered_map> m_parameter_depends_on; std::unordered_map m_parameter_expression; + std::unordered_map> m_layout_depends_on; + std::unordered_map m_layout_expression; std::string m_is_client_dataset_name = ""; std::string m_client_comm_get_dataset_name = ""; diff --git a/plugins/damaris/example/example.yml b/plugins/damaris/example/example.yml index 753f2531c..f4cacb9a1 100644 --- a/plugins/damaris/example/example.yml +++ b/plugins/damaris/example/example.yml @@ -20,8 +20,8 @@ pdi: main_field: { size: [ '$dsize[0]', '$dsize[1]' ], type: array, subtype: double } plugins: - trace: ~ mpi: + trace: ~ decl_hdf5: file: data_2.h5 communicator: $mpi_comm #$MPI_COMM_WORLD # the MPI communicator used for HDF5 parallel synchronized write @@ -53,28 +53,7 @@ pdi: # damaris divise le sous domain par block equitablement dedicated: core: 1 - node: 0 - parameters: # meme but que les metadata, mais la valeur peut changer au cours de l'execution - - parameter: - name: dsize0 - type: int - value: '$dsize[0]' # overwrite the default value 0 - depends_on: dsize - - parameter: - name: dsize1 - type: int - value: '$dsize[1]' - depends_on: dsize - - parameter: - name: psize0 - type: int - value: '$psize[0]' - depends_on: psize - - parameter: - name: psize1 - type: int - value: '$psize[1]' - depends_on: psize + node: 0 datasets: - dataset: name: main_field @@ -90,10 +69,10 @@ pdi: - layout: name: main_field_layout # ~hdf5 dataset_selection type: double - # try something like: global: '$psize[0]*($dsize[0]-2), $psize[1]*($dsize[1]-2)' - global: 'psize0*(dsize0-2),psize1*(dsize1-2)' - dimensions: [ 'dsize0', 'dsize1' ] # process dim, with ghosts/boundaries + global: '$psize[0]*($dsize[0]-2),$psize[1]*($dsize[1]-2)' + dimensions: [ '$dsize[0]', '$dsize[1]' ] # process dim, with ghosts/boundaries ghosts: '1:1,1:1' # 1 ghost à gauche de dim1, 1 ghost à droit de dim1 , 1 ghost à gauche de dim2, 1 ghost à droit de dim2 + depends_on: [dsize, psize] # This will help ensure an update of the layout attributes value to Damaris lib once the metadata are exposed (using Damaris Parameters in the background)! storages: - storage: name: hdf5_example @@ -101,8 +80,7 @@ pdi: file_mode: Collective # or FilePerCore files_path: ./HDF5_files/ # Where to save files # hdf5 file name defined by damaris - #frequency: 1 - + #frequency: 1 #Events sections write: main_field: # the name of the data to write, if dataset not specified afterward! ~meme notion de dataset hdf5 @@ -113,31 +91,8 @@ pdi: # damaris "append" file with next iteration #block: [...] # To be defined # indice de block à écrire = 0 par default => tout le sous-domain # si "architecture/domains" >1 on peut écrire les block de indice 0 à domains-1 - # after_write: damaris_end_iteration # applied for all the data... - # question: moyen de enlever cette ligne au-desus??? - # on_end_iteration: damaris_end_iteration - - # - *: aw_event # OR [aw_event1, aw_event1, ...] # applied for all the data... - # - data1_name: d1_aw_event # OR [d1_aw_event1, d1_aw_event2, ...] - # - data2_name: d2_aw_event # OR [d2_aw_event1, d2_aw_event2, ...] - - # TODO: - # a list or map of data (damaris parameters) to get/set (default: empty). This is basically for time-varying parameters... - # if a prm is to be set and get, priority most be defined, and a politic of recurence if this happen several time (default: RR) - # Ex. - # parameter_get: - # - prm1: - # priority: 0 - # parameter_set: - # - prm1: - # priority: 1 - # - prm2: get_is_client: is_client - client_comm_get: mpi_comm - - # question: utilisé ou pas??? - parameter_get: - parameter_set: + client_comm_get: mpi_comm #Optional config, has a default behavior log: From d7cd877f5324aa71db0bd9f22737bd0c9dbac35c Mon Sep 17 00:00:00 2001 From: yushan wang Date: Thu, 19 Jun 2025 15:15:26 +0200 Subject: [PATCH 09/42] Delete .vscode directory --- .vscode/settings.json | 90 ------------------------------------------- 1 file changed, 90 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index e7427eab5..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "files.associations": { - "cctype": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "csetjmp": "cpp", - "csignal": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "any": "cpp", - "array": "cpp", - "atomic": "cpp", - "barrier": "cpp", - "bit": "cpp", - "*.tcc": "cpp", - "bitset": "cpp", - "cfenv": "cpp", - "charconv": "cpp", - "chrono": "cpp", - "cinttypes": "cpp", - "codecvt": "cpp", - "compare": "cpp", - "complex": "cpp", - "concepts": "cpp", - "condition_variable": "cpp", - "coroutine": "cpp", - "cstdint": "cpp", - "cuchar": "cpp", - "deque": "cpp", - "forward_list": "cpp", - "list": "cpp", - "map": "cpp", - "set": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "unordered_set": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "optional": "cpp", - "random": "cpp", - "ratio": "cpp", - "regex": "cpp", - "source_location": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "fstream": "cpp", - "future": "cpp", - "initializer_list": "cpp", - "iomanip": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "latch": "cpp", - "limits": "cpp", - "mutex": "cpp", - "new": "cpp", - "numbers": "cpp", - "ostream": "cpp", - "ranges": "cpp", - "scoped_allocator": "cpp", - "semaphore": "cpp", - "shared_mutex": "cpp", - "span": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "stop_token": "cpp", - "streambuf": "cpp", - "syncstream": "cpp", - "thread": "cpp", - "typeindex": "cpp", - "typeinfo": "cpp", - "valarray": "cpp", - "variant": "cpp" - } -} \ No newline at end of file From 491dc4c233f4ef10f845f200b1315b8518001cdb Mon Sep 17 00:00:00 2001 From: Etienne Ndamlabin Date: Mon, 8 Sep 2025 15:38:41 +0200 Subject: [PATCH 10/42] Add robustness + some bugs fixing --- .../damaris/cmake/DamarisPluginUtils.cmake | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 plugins/damaris/cmake/DamarisPluginUtils.cmake diff --git a/plugins/damaris/cmake/DamarisPluginUtils.cmake b/plugins/damaris/cmake/DamarisPluginUtils.cmake new file mode 100644 index 000000000..b0b9fb1c2 --- /dev/null +++ b/plugins/damaris/cmake/DamarisPluginUtils.cmake @@ -0,0 +1,37 @@ +# Function to compare two versions +# Returns 1 if version1 >= version2, 0 otherwise +function(version_greater_equal version1 version2 result) + string(REGEX MATCHALL "[0-9]+" v1_parts "${version1}") + string(REGEX MATCHALL "[0-9]+" v2_parts "${version2}") + + # pad missing parts with 0 + list(LENGTH v1_parts len1) + list(LENGTH v2_parts len2) + if(len1 LESS 3) + math(EXPR pad "3 - ${len1}") + foreach(_i RANGE ${pad}) + list(APPEND v1_parts 0) + endforeach() + endif() + if(len2 LESS 3) + math(EXPR pad "3 - ${len2}") + foreach(_i RANGE ${pad}) + list(APPEND v2_parts 0) + endforeach() + endif() + + set(_result 1) + foreach(i RANGE 0 2) + list(GET v1_parts ${i} v1i) + list(GET v2_parts ${i} v2i) + if(v1i GREATER v2i) + set(_result 1) + break() + elseif(v1i LESS v2i) + set(_result 0) + break() + endif() + endforeach() + + set(${result} ${_result} PARENT_SCOPE) +endfunction() From c2a3ca2ce46de0aae4fb44c80429564528f0a9ca Mon Sep 17 00:00:00 2001 From: Etienne Ndamlabin Date: Mon, 8 Sep 2025 15:39:28 +0200 Subject: [PATCH 11/42] Add robustness + some bugs fixing --- plugins/damaris/CMakeLists.txt | 17 +- plugins/damaris/cmake/FindDamaris.cmake | 54 +++++- plugins/damaris/damaris.cxx | 34 +++- plugins/damaris/damaris_api_call_handler.cxx | 157 +++++++++++------- plugins/damaris/damaris_cfg.h | 11 ++ plugins/damaris/example/example.c | 24 +-- plugins/damaris/tests/CMakeLists.txt | 53 ++++++ plugins/damaris/tests/damaris_mpi_test_01.c | 120 +++++++++++++ plugins/damaris/tests/damaris_mpi_test_01.yml | 68 ++++++++ 9 files changed, 437 insertions(+), 101 deletions(-) create mode 100644 plugins/damaris/tests/CMakeLists.txt create mode 100644 plugins/damaris/tests/damaris_mpi_test_01.c create mode 100644 plugins/damaris/tests/damaris_mpi_test_01.yml diff --git a/plugins/damaris/CMakeLists.txt b/plugins/damaris/CMakeLists.txt index 1afc10c08..7018a52b5 100644 --- a/plugins/damaris/CMakeLists.txt +++ b/plugins/damaris/CMakeLists.txt @@ -33,31 +33,34 @@ project(pdi_damaris_plugin LANGUAGES C CXX) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") # TODO: -#include(CTest) +include(CTest) include(GNUInstallDirs) #Damaris -set(Damaris_DEPS damaris MPI::MPI_C MPI::MPI_CXX) -find_package(Damaris) +#set(Damaris_DEPS damaris MPI::MPI_C MPI::MPI_CXX) +set(Damaris_DEPS MPI::MPI_C MPI::MPI_CXX) +find_package(Damaris 1.12.0 REQUIRED) if (Damaris_FOUND) - message(STATUS "The Damaris library was found") + message(STATUS "The Damaris library was found (${Damaris_LIBRARIES_PATH}/libdamaris.so)") # Adds the libraries used - Damaris and its dependencies to the link line # target_link_libraries(mysim PUBLIC ${Damaris_LIBRARIES}) # This creates a definition of a pre-processor variable (PROG_HAS_DAMARIS) # that can be used as a guard in the C/C++ code: # target_compile_definitions(mysim PRIVATE PROG_HAS_DAMARIS) + list(APPEND Damaris_DEPS damaris) + #list(APPEND Damaris_DEPS ${Damaris_LIBRARIES}) + include_directories(${Damaris_INCLUDE_DIRS} ${Damaris_INCLUDE_DIRS}/damaris) + link_directories(${Damaris_LIBRARIES_PATH}) else() message(STATUS "The Damaris library was NOT found") endif() -include_directories(${Damaris_INCLUDE_DIRS} ${Damaris_INCLUDE_DIRS}/damaris) -link_directories(${Damaris_LIBRARIES_PATH}) # MPI find_package(MPI REQUIRED COMPONENTS CXX C) # PDI -find_package(PDI REQUIRED COMPONENTS plugins) +find_package(PDI 1.9.2 REQUIRED COMPONENTS plugins) # The plugin add_library(pdi_damaris_plugin MODULE diff --git a/plugins/damaris/cmake/FindDamaris.cmake b/plugins/damaris/cmake/FindDamaris.cmake index 050ad1ff5..6bfcf109b 100644 --- a/plugins/damaris/cmake/FindDamaris.cmake +++ b/plugins/damaris/cmake/FindDamaris.cmake @@ -12,17 +12,59 @@ asynchronous, in situ processing capabilities to MPI based simulation codes. #include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) #include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) include(FindPackageHandleStandardArgs) +include(DamarisPluginUtils) -set(Damaris_BASE_DIR /usr/lib/damaris /opt/damaris) -set(Damaris_VERSIONS 1.11.1 1.12.0) +set(Damaris_BASE_DIR /usr/local/lib/damaris /opt/damaris) +set(Damaris_VERSIONS 1.12.0) +set(MIN_REQUIRED_VERSIONS "1.12.0") #Find Damaris base install dir set(Damaris_CANDIDATES ${Damaris_ROOT}) foreach(base_dir ${Damaris_BASE_DIR}) - list(APPEND Damaris_CANDIDATES ${base_dir}) #In case no version dir exists - foreach(version ${Damaris_VERSIONS}) - list(APPEND Damaris_CANDIDATES ${base_dir}/${version}) - endforeach() + if(EXISTS "${base_dir}" AND IS_DIRECTORY "${base_dir}") + list(APPEND Damaris_CANDIDATES ${base_dir}) #In case no version dir exists + + if(DEFINED Damaris_VERSION) + message(STATUS "Provided damaris version: ${Damaris_VERSION}") + string(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+$" IS_VERSION "${Damaris_VERSION}") + + if(IS_VERSION AND (EXISTS "${base_dir}/${Damaris_VERSION}" AND IS_DIRECTORY "${base_dir}/${Damaris_VERSION}")) + version_greater_equal(${Damaris_VERSION} ${MIN_REQUIRED_VERSIONS} IS_GE) + + if(IS_GE) + list(APPEND Damaris_CANDIDATES ${base_dir}/${FOLDER_NAME}) + else() + message(STATUS "damaris_plugin requires at least version \"1.12.0\", provided: ${Damaris_VERSION}") + endif() + elseif(IS_VERSION) + message(STATUS "No Damaris installation with version \"${Damaris_VERSION}\" folder!") + endif() + else() + # Get all subdirectories + file(GLOB SUBFOLDERS LIST_DIRECTORIES true "${base_dir}/*") + + foreach(SUB "${SUBFOLDERS}") + # Get the folder name only (without path) + get_filename_component(FOLDER_NAME "${SUB}" NAME) + + # Check if the folder name matches x.y.z + string(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+$" IS_VERSION "${FOLDER_NAME}") + + if(IS_VERSION) + version_greater_equal(${FOLDER_NAME} ${MIN_REQUIRED_VERSIONS} IS_GE) + + if(IS_GE) + list(APPEND Damaris_CANDIDATES ${base_dir}/${FOLDER_NAME}) + #else() + endif() + endif() + endforeach() + endif() + + #foreach(version ${Damaris_VERSIONS}) + #list(APPEND Damaris_CANDIDATES ${base_dir}/${version}) + #endforeach() + endif() endforeach() set(Damaris_INC_SUFFIXES) diff --git a/plugins/damaris/damaris.cxx b/plugins/damaris/damaris.cxx index 88ef69261..0d0945d5b 100644 --- a/plugins/damaris/damaris.cxx +++ b/plugins/damaris/damaris.cxx @@ -89,6 +89,8 @@ class damaris_plugin: public Plugin { std::string real_numbers_types[3] = {"float", "real", "double"}; int iteration = 0;//for debugging + int datasets_to_write_count = 0;//The number of data already written in the current iteration + public: damaris_plugin(Context& ctx, PC_tree_t config) @@ -214,17 +216,29 @@ class damaris_plugin: public Plugin { ,ds_write_info.position[1].to_long(context()) ,ds_write_info.position[2].to_long(context()) }; - context().logger().info("data `{}' will be written at: block '{}' and position '{}:{}:{}', when = '{}'", name, block, position[0], position[1], position[2], ds_write_info.when.to_long(context())); - + const void* data = static_cast(rref.get()); - std::string set_block_pos_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_SET_BLOCK_POSITION); - m_event_handler.damaris_api_call_event(context(), m_damaris, set_block_pos_event_name, multi_expose_transaction_dataname, name, block, position); + if(block > 0) { + context().logger().info("data `{}' will be written at: block '{}' and position '{}:{}:{}', when = '{}'", name, block, position[0], position[1], position[2], ds_write_info.when.to_long(context())); + + std::string set_block_pos_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_SET_BLOCK_POSITION); + m_event_handler.damaris_api_call_event(context(), m_damaris, set_block_pos_event_name, multi_expose_transaction_dataname, name, block, position); + + std::string write_block_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_WRITE_BLOCK); + m_event_handler.damaris_api_call_event(context(), m_damaris, write_block_event_name, multi_expose_transaction_dataname, name, block, data); + } + else { + std::string set_pos_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_SET_POSITION); + m_event_handler.damaris_api_call_event(context(), m_damaris, set_pos_event_name, multi_expose_transaction_dataname, name, position); - std::string write_block_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_WRITE_BLOCK); - m_event_handler.damaris_api_call_event(context(), m_damaris, write_block_event_name, multi_expose_transaction_dataname, name, block, data); - - if(m_config.is_there_after_write_events()) { + std::string write_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_WRITE); + m_event_handler.damaris_api_call_event(context(), m_damaris, write_event_name, multi_expose_transaction_dataname, name, data); + } + + datasets_to_write_count++; + //Wait until all datasets are written before launching end of iteration operations + if(m_config.is_there_after_write_events() && datasets_to_write_count == m_config.datasets_to_write().size()) { list after_write_events = m_config.get_after_write_events(); for (auto it = after_write_events.begin(); it != after_write_events.end(); it++) { std::string aw_event = it->c_str(); @@ -239,6 +253,7 @@ class damaris_plugin: public Plugin { } } + datasets_to_write_count = 0; } } } @@ -358,8 +373,9 @@ class damaris_plugin: public Plugin { { if (m_config.finalize_on_event().empty() && m_damaris) { + context().logger().info("Calling DAMARIS_FINALIZE in ~damaris_plugin()"); std::string finalize_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_FINALIZE); - m_event_handler.damaris_api_call_event(context(), m_damaris, finalize_event_name, multi_expose_transaction_dataname); + //m_event_handler.damaris_api_call_event(context(), m_damaris, finalize_event_name, multi_expose_transaction_dataname); //PDI_status_t status = PDI_event(finalize_event_name.c_str()); } diff --git a/plugins/damaris/damaris_api_call_handler.cxx b/plugins/damaris/damaris_api_call_handler.cxx index c559b808d..49544e5e1 100644 --- a/plugins/damaris/damaris_api_call_handler.cxx +++ b/plugins/damaris/damaris_api_call_handler.cxx @@ -226,35 +226,48 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptrc_str(), ++arg_pos, expose_dataname.size()); - - if (arg_pos == 1) - { - PDI_access(it->c_str(), (void**)&var_name, PDI_IN); - arg1_name = it->c_str(); - } - else if (arg_pos == 2){ - PDI_access(it->c_str(), (void**)&position, PDI_IN); - arg2_name = it->c_str(); + char* var_name; std::string arg1_name = "pos_var_name"; + int64_t* position; std::string arg2_name = "position"; + + va_list extra_args; + va_start(extra_args, expose_dataname); + string data_name = va_arg(extra_args, string); + if(!data_name.empty()) { + var_name = (char*)data_name.c_str(); + position = va_arg(extra_args, int64_t*); + } + else { + + //Retrive parameters! sent via Multi expose, the two last sent data + char* var_name; std::string arg1_name; + int64_t* position; std::string arg2_name; + int arg_pos = 0; + int nb_awaited_args = 2; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) + { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } + else if (arg_pos == 2){ + PDI_access(it->c_str(), (void**)&position, PDI_IN); + arg2_name = it->c_str(); + } + else + //if(nb_awaited_args <= arg_pos) + break; } - else - //if(nb_awaited_args <= arg_pos) - break; } - ctx.logger().info("------------------- CALLING damaris_pdi_set_position arg_pos({}==='{}', {}==={})", arg1_name, var_name, arg2_name, *(int64_t*)position); + ctx.logger().info("------------------- CALLING damaris_pdi_set_position arg_pos({}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, *(int64_t*)position); int err = m_damaris->damaris_pdi_set_position((const char*)var_name, (const int64_t*)position); } // DAMARIS_WRITE @@ -263,33 +276,45 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptrc_str(), ++arg_pos, expose_dataname.size()); - - if (arg_pos == 1) - { - PDI_access(it->c_str(), (void**)&var_name, PDI_IN); - arg1_name = it->c_str(); - } - else if (arg_pos == 2){ - PDI_access(it->c_str(), (void**)&data, PDI_IN); - arg2_name = it->c_str(); + va_list extra_args; + va_start(extra_args, expose_dataname); + //if(string data_name = va_arg(extra_args, string)) { + string data_name = va_arg(extra_args, string); + if(!data_name.empty()) { + var_name = (char*)data_name.c_str(); + data = va_arg(extra_args, void*);//const void* + } + else { + //Retrive parameters! sent via Multi expose, the two last sent data + char* var_name; std::string arg1_name; + void* data; std::string arg2_name; + int arg_pos = 0; + int nb_awaited_args = 2; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) + { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } + else if (arg_pos == 2){ + PDI_access(it->c_str(), (void**)&data, PDI_IN); + arg2_name = it->c_str(); + } + else + //if(nb_awaited_args <= arg_pos) + break; } - else - //if(nb_awaited_args <= arg_pos) - break; } ctx.logger().info("------------------- CALLING damaris_pdi_write arg_pos({}==='{}', {}==={})", arg1_name, var_name, arg2_name, *(int*)data); @@ -410,7 +435,7 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptrdamaris_pdi_end_iteration() ; //iteration++; @@ -435,16 +460,26 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptrget_event_name(Event_type::DAMARIS_STOP); - //PDI_status_t status = PDI_event(stop_event_name.c_str()); - - int stop_err = m_damaris->damaris_pdi_stop(); + try { + if (m_stop_on_event.empty() && m_damaris->get_is_client()) { + ctx.logger().info("Plugin sent damaris_stop() to Damaris, in finalization"); + + //std::string stop_event_name = this->get_event_name(Event_type::DAMARIS_STOP); + //PDI_status_t status = PDI_event(stop_event_name.c_str()); + + int stop_err = m_damaris->damaris_pdi_stop(); + } + + ctx.logger().info("Plugin sent damaris_finalize() to Damaris"); + int err = m_damaris->damaris_pdi_finalize(); + if(err == DAMARIS_OK) { + ctx.logger().info("Damaris finalized successfully!"); + } + } catch (const std::exception &e) { + ctx.logger().error("Issue when finalizing Damaris: {}", e.what()); + } catch (...) { + ctx.logger().error("An issue occurred when finalizing Damaris."); } - - int err = m_damaris->damaris_pdi_finalize(); } else { assert(false && "Unexpected damaris event type"); diff --git a/plugins/damaris/damaris_cfg.h b/plugins/damaris/damaris_cfg.h index c7e5f378b..78070fcf5 100644 --- a/plugins/damaris/damaris_cfg.h +++ b/plugins/damaris/damaris_cfg.h @@ -233,6 +233,17 @@ const std::unordered_map event_names = { void init_xml_config_object(){ m_xml_config_object = XML_CONFIG_TEMPLATE; damarisXMLModifyModel = damaris::model::ModifyModel(m_xml_config_object); + + /* + m_init_on_event = ""; + m_start_on_event = ""; + m_stop_on_event = ""; + m_end_iteration_on_event = ""; + m_finalize_on_event = ""; + + m_paraview = NULL; + m_pyscript = NULL; + */ } diff --git a/plugins/damaris/example/example.c b/plugins/damaris/example/example.c index faf208235..bb60da9a4 100644 --- a/plugins/damaris/example/example.c +++ b/plugins/damaris/example/example.c @@ -161,29 +161,18 @@ int main(int argc, char* argv[]) PC_tree_t conf = PC_parse_path(argv[1]); - MPI_Comm main_comm;// = MPI_COMM_WORLD; + MPI_Comm main_comm = MPI_COMM_WORLD; PDI_init(PC_get(conf, ".pdi")); PDI_event("init"); int is_client = -1; - PDI_expose("is_client", &is_client, PDI_IN); - printf("-------------------------------------------------------------------------------------D: :) ;) is_client = %d\n", is_client); - - //return 0; + //PDI_expose("is_client", &is_client, PDI_IN); + PDI_expose("is_client", &is_client, PDI_INOUT); // <-- allow plugin to set + PDI_expose("mpi_comm", &main_comm, PDI_INOUT); // <-- allow plugin to set if(is_client) { //*******************************************************************Only damaris clients run this section - - //Gets the communicator that the clients must use. - //damaris_client_comm_get(&comm); - //PDI_multi_expose("damaris_client_comm_get" - //,"client_comm", &main_comm, PDI_INOUT - //, NULL); - - PDI_expose("mpi_comm", &main_comm, PDI_INOUT); - //MPI_Comm hdf5_mpi_comm = main_comm; - //PDI_expose("hdf5_mpi_comm", &hdf5_mpi_comm, PDI_INOUT); int psize_1d; MPI_Comm_size(main_comm, &psize_1d); @@ -263,18 +252,17 @@ int main(int argc, char* argv[]) } //PDI_event("damaris_end_iteration"); } - //PDI_event("finalization"); + PDI_event("finalization"); PDI_expose("iter", &ii, PDI_OUT); PDI_expose("main_field", cur, PDI_OUT); + //moved here to be in the scope, since if(is_client) has been added free(cur); free(next); //PDI_event("damaris_stop"); //*******************************************************************END if(is_client) }//END if(is_client) - - PDI_event("finalization"); PDI_finalize(); diff --git a/plugins/damaris/tests/CMakeLists.txt b/plugins/damaris/tests/CMakeLists.txt new file mode 100644 index 000000000..ad760def6 --- /dev/null +++ b/plugins/damaris/tests/CMakeLists.txt @@ -0,0 +1,53 @@ +#============================================================================= +# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the names of CEA, nor the names of the contributors may be used to +# endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +cmake_minimum_required(VERSION 3.16...3.29) + +set(RUNTEST_DIR "${CMAKE_CURRENT_LIST_DIR}/../cmake/runtest-dir") + +# Add the plugin path to PDI_PLUGIN_PATH +set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" PROPERTY TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/TestPath.cmake") +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/TestPath.cmake" + CONTENT " +set(PDI_PLUGIN_PATH \"\$ENV{PDI_PLUGIN_PATH}\")\n +if(\"x\${PDI_PLUGIN_PATH}x\" STREQUAL xx)\n +set(ENV{PDI_PLUGIN_PATH} \"\$\")\n +else()\n +set(ENV{PDI_PLUGIN_PATH} \"\$:\${PDI_PLUGIN_PATH}\")\n +endif() +" +) + +# Damaris plugin test +add_executable(damaris_mpi_test_01 damaris_mpi_test_01.c) +target_link_libraries(damaris_mpi_test_01 damaris MPI::MPI_C MPI::MPI_CXX) +add_test(NAME damaris_mpi_test_01 COMMAND "${RUNTEST_DIR}" "${MPIEXEC}" "${MPIEXEC_NUMPROC_FLAG}" 2 ${MPIEXEC_PREFLAGS} "$" ${MPIEXEC_POSTFLAGS} "${CMAKE_CURRENT_SOURCE_DIR}/damaris_mpi_test_01.yml") +set_property(TEST damaris_mpi_test_01 PROPERTY PROCESSORS 1) + diff --git a/plugins/damaris/tests/damaris_mpi_test_01.c b/plugins/damaris/tests/damaris_mpi_test_01.c new file mode 100644 index 000000000..6d68f91b2 --- /dev/null +++ b/plugins/damaris/tests/damaris_mpi_test_01.c @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (C) 2015-2019 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include +#include +#include +#include +#include + +#define IMX 10 +#define JMX 5 + +int main(int argc, char* argv[]) +{ + int values[JMX][IMX], cp_values[JMX][IMX]; + double reals[JMX][IMX], cp_reals[JMX][IMX]; + int i, j, input; + int ni = IMX, nj = JMX; // PDI only + + MPI_Init(&argc, &argv); + assert(argc == 2 && "Needs 1 single arg: config file"); + + PC_tree_t conf = PC_parse_path(argv[1]); + MPI_Comm world = MPI_COMM_WORLD; + PDI_init(conf); + int rank; + MPI_Comm_rank(world, &rank); + + char filename[4096]; + snprintf(filename, 4096, "decl_hdf5_mpi_test_01_C_r%d.h5", rank); + remove(filename); + + // Fill arrays + for (j = 0; j < JMX; ++j) { + for (i = 0; i < IMX; ++i) { + values[j][i] = i; + reals[j][i] = (double)(i) + 0.1 * (i % 10); + cp_values[j][i] = -1; + cp_reals[j][i] = -1.0; + } + } + + input = 0; + PDI_expose("rank", &rank, PDI_OUT); + PDI_expose("input", &input, PDI_OUT); + // Set size for PDI + PDI_expose("ni", &ni, PDI_OUT); + PDI_expose("nj", &nj, PDI_OUT); + + // Test that export/exchange works + PDI_expose("input", &input, PDI_OUT); + PDI_expose("reals", &reals, PDI_OUT); // output real + PDI_expose("values", &values, PDI_INOUT); // output integers + + input = 1; + // Import should also work + PDI_expose("input", &input, PDI_OUT); // update metadata => HDF5 now import only + PDI_expose("reals", &cp_reals, PDI_IN); // input real + PDI_expose("values", &cp_values, PDI_INOUT); // input integers + + // So the data should be the same + fprintf(stderr, "Data exported | Data imported\n"); + for (j = 0; j < JMX; ++j) { + for (i = 0; i < IMX; ++i) { + fprintf(stderr, "%10d %4d\n", values[j][i], cp_values[j][i]); + fprintf(stderr, "%10.2f %2.2f\n", reals[j][i], cp_reals[j][i]); + if (values[j][i] != cp_values[j][i] || reals[j][i] != cp_reals[j][i]) { + fprintf( + stderr, + "[%d]: values[%d][%d] = %10d should be equal to cp_values[%d][%d] = %4d\n", + rank, + j, + i, + values[j][i], + j, + i, + cp_values[j][i] + ); + fprintf( + stderr, + "[%d]: reals[%d][%d] = %11.2f should be equal to cp_reals[%d][%d] = %5.2f\n", + rank, + j, + i, + reals[j][i], + j, + i, + cp_reals[j][i] + ); + MPI_Abort(MPI_COMM_WORLD, -1); + } + } + } + + PDI_finalize(); + PC_tree_destroy(&conf); + MPI_Finalize(); +} diff --git a/plugins/damaris/tests/damaris_mpi_test_01.yml b/plugins/damaris/tests/damaris_mpi_test_01.yml new file mode 100644 index 000000000..c4d1f8adc --- /dev/null +++ b/plugins/damaris/tests/damaris_mpi_test_01.yml @@ -0,0 +1,68 @@ +# duration in seconds +duration: 0.75 +# global [height, width] (excluding boundary conditions or ghosts) +datasize: [60, 12] +# degree of parallelism +parallelism: { height: 3, width: 1 } + +# only the following config is passed to PDI +pdi: + metadata: # type of small values for which PDI keeps a copy + iter: int # current iteration id + dsize: { size: 2, type: array, subtype: int } # local data size including ghosts/boundary + psize: { size: 2, type: array, subtype: int } # number of processes in each dimension + pcoord: { size: 2, type: array, subtype: int } # coordinate of the process + data: + main_field: { size: [ '$dsize[0]', '$dsize[1]' ], type: array, subtype: double } + + plugins: + mpi: + damaris: + + on_init: init #or init_on_event + #start_on_event: damaris_start + #end_iteration_on_event: damaris_end_iteration + on_finalize: finalization #Or finalize_on_event + communicator: $MPI_COMM_WORLD # pas utilisé actuellement + architecture: + sim_name: example + domains: 1 # => nb de block par sous domain + # damaris divise le sous domain par block equitablement + dedicated: + core: 1 + node: 0 + datasets: + - dataset: + name: main_field + layout: main_field_layout + mesh: mesh2d # pour la visualisation + centering: zonal + storage: hdf5_example + script: + visualizable: true + time_varying: true + #comment: This is the zonal pressure from our test simulation + layouts: # on ne peut pas modifier la valuer de layout une fois initialisé, travail en cours pour la modification dynamique + - layout: + name: main_field_layout # ~hdf5 dataset_selection + type: double + global: '$psize[0]*($dsize[0]-2),$psize[1]*($dsize[1]-2)' + dimensions: [ '$dsize[0]', '$dsize[1]' ] # process dim, with ghosts/boundaries + ghosts: '1:1,1:1' # 1 ghost à gauche de dim1, 1 ghost à droit de dim1 , 1 ghost à gauche de dim2, 1 ghost à droit de dim2 + depends_on: [dsize, psize] # This will help ensure an update of the layout attributes value to Damaris lib once the metadata are exposed (using Damaris Parameters in the background)! + storages: + - storage: + name: hdf5_example + type: HDF5 + file_mode: Collective # or FilePerCore + files_path: ./HDF5_files/ # Where to save files + # hdf5 file name defined by damaris + #frequency: 1 + + #Optional config, has a default behavior + log: + #file_name: example # default = $sim_name + rotation_size: 5 + log_level: info + flush: true + From 9ea38fc45074bce6c7affb94845eaa8ba2bcd1b1 Mon Sep 17 00:00:00 2001 From: Etienne Ndamlabin Date: Thu, 11 Sep 2025 10:38:00 +0200 Subject: [PATCH 12/42] Check whether the HDF5 files_path exists, and create it if not! --- plugins/damaris/damaris_cfg.cxx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/plugins/damaris/damaris_cfg.cxx b/plugins/damaris/damaris_cfg.cxx index 5daec0404..e1a9fbe33 100644 --- a/plugins/damaris/damaris_cfg.cxx +++ b/plugins/damaris/damaris_cfg.cxx @@ -23,6 +23,8 @@ * THE SOFTWARE. ******************************************************************************/ + #include + #include #include #include #include @@ -839,6 +841,18 @@ } else if (key == "files_path") { store.store_opt_FilesPath_ = to_string(value); + //Ensure the folder exists + struct stat st; + if (stat(store.store_opt_FilesPath_.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) { + ctx.logger().info("HDF5 files_path exists: '{}'", to_string(value)); + } else { + if (mkdir(store.store_opt_FilesPath_.c_str(), 0775) == -1) { + ctx.logger().info("Error during the creation of the HDF5 files_path: '{}'", strerror(errno)); + exit(1); + } else { + ctx.logger().info("HDF5 files_path created successfully: '{}'", to_string(value)); + } + } } else { std::cerr << "ERROR: damaris_cfg unrecogognized storage map string: " << key << std::endl ; From 9a1738e6676624f556b29c64ffd6a54e56d1dfd8 Mon Sep 17 00:00:00 2001 From: Etienne Ndamlabin Date: Thu, 6 Nov 2025 17:46:13 +0100 Subject: [PATCH 13/42] Resolve double finalize issue (thanks to Jacques Morice help :) ), adding auto initialize without on_init event, and adding some cmake instruction in enforce finding of Damaris when Damaris_ROOT is provided. --- plugins/damaris/CMakeLists.txt | 5 ++ plugins/damaris/cmake/FindDamaris.cmake | 2 +- plugins/damaris/damaris.cxx | 44 +++++++++++------ plugins/damaris/damaris_async_gather.h | 66 +++++++++++++++++++++++++ plugins/damaris/damaris_cfg.cxx | 44 ++++++++--------- plugins/damaris/damaris_wrapper.cxx | 2 +- 6 files changed, 123 insertions(+), 40 deletions(-) create mode 100644 plugins/damaris/damaris_async_gather.h diff --git a/plugins/damaris/CMakeLists.txt b/plugins/damaris/CMakeLists.txt index 7018a52b5..c1e6de2de 100644 --- a/plugins/damaris/CMakeLists.txt +++ b/plugins/damaris/CMakeLists.txt @@ -52,6 +52,11 @@ if (Damaris_FOUND) #list(APPEND Damaris_DEPS ${Damaris_LIBRARIES}) include_directories(${Damaris_INCLUDE_DIRS} ${Damaris_INCLUDE_DIRS}/damaris) link_directories(${Damaris_LIBRARIES_PATH}) + + + message(STATUS "Embedding RPATH for Damaris: ${Damaris_LIBRARIES_PATH}") + set(CMAKE_INSTALL_RPATH "${Damaris_LIBRARIES_PATH}") + set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) else() message(STATUS "The Damaris library was NOT found") endif() diff --git a/plugins/damaris/cmake/FindDamaris.cmake b/plugins/damaris/cmake/FindDamaris.cmake index 6bfcf109b..85155fc0d 100644 --- a/plugins/damaris/cmake/FindDamaris.cmake +++ b/plugins/damaris/cmake/FindDamaris.cmake @@ -14,7 +14,7 @@ asynchronous, in situ processing capabilities to MPI based simulation codes. include(FindPackageHandleStandardArgs) include(DamarisPluginUtils) -set(Damaris_BASE_DIR /usr/local/lib/damaris /opt/damaris) +set(Damaris_BASE_DIR /usr/local/lib/damaris /usr/lib/damaris /opt/damaris) set(Damaris_VERSIONS 1.12.0) set(MIN_REQUIRED_VERSIONS "1.12.0") diff --git a/plugins/damaris/damaris.cxx b/plugins/damaris/damaris.cxx index 0d0945d5b..b3fcf69e6 100644 --- a/plugins/damaris/damaris.cxx +++ b/plugins/damaris/damaris.cxx @@ -125,24 +125,12 @@ class damaris_plugin: public Plugin { //ctx.callbacks().add_event_callback([this](const std::string& name) { this->event(name); }); ctx.logger().info("Plugin loaded successfully"); - - if (m_config.init_on_event().empty() && m_config.communicator()) { - //TODO: issue communicator to handle - /* - MPI_Comm comm = *(static_cast(Ref_r{m_config.communicator().to_ref(context())}.get())); - //context().logger().info("communicator `{}'", m_config.communicator().to_string(context())); - - m_damaris.reset(new Damaris_wrapper{context(), m_config.xml_config_object().c_str(), comm}); - context().logger().info("Plugin initialized successfully"); - */ - - std::string init_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_INITIALIZE); - PDI_status_t status = PDI_event(init_event_name.c_str()); - } } void data(const std::string& name, Ref ref) { + ensure_damaris_is_initialized(""); + context().logger().info("data `{}' has been exposed", name); //Update damaris parameters @@ -336,6 +324,8 @@ class damaris_plugin: public Plugin { void event(const std::string& event_name) { + ensure_damaris_is_initialized(event_name); + //If it a sim configured event if (m_config.events().find(event_name) != m_config.events().end()) { if(event_name == m_config.init_on_event()) { @@ -369,14 +359,36 @@ class damaris_plugin: public Plugin { } } + void ensure_damaris_is_initialized(const std::string& event_name) + { + if (!m_damaris) { + if (m_config.events().find(event_name) != m_config.events().end()) { + //Means the first action received by the plugin wasn't fir initialization... + if (!m_config.init_on_event().empty() && event_name != m_config.init_on_event()) { + context().logger().error("Trying to use {} plugin before the initialization of the Damaris library!", pretty_name()); + } + else if (event_name == m_config.init_on_event()) + return;//The init will follows + } + this->damaris_init(); + } + } + + void damaris_init() + { + context().logger().info("In damaris_init()"); + std::string init_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_INITIALIZE); + m_event_handler.damaris_api_call_event(context(), m_damaris, init_event_name, multi_expose_transaction_dataname); + } + + ~damaris_plugin() { if (m_config.finalize_on_event().empty() && m_damaris) { context().logger().info("Calling DAMARIS_FINALIZE in ~damaris_plugin()"); std::string finalize_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_FINALIZE); - //m_event_handler.damaris_api_call_event(context(), m_damaris, finalize_event_name, multi_expose_transaction_dataname); - //PDI_status_t status = PDI_event(finalize_event_name.c_str()); + m_event_handler.damaris_api_call_event(context(), m_damaris, finalize_event_name, multi_expose_transaction_dataname); } context().logger().info("Closing plugin"); diff --git a/plugins/damaris/damaris_async_gather.h b/plugins/damaris/damaris_async_gather.h new file mode 100644 index 000000000..311f1c632 --- /dev/null +++ b/plugins/damaris/damaris_async_gather.h @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2024 National Institute for Research in Digital Science and Technology (Inria) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + + #ifndef Damaris_async_gather_H_ + #define Damaris_async_gather_H_ + + #include + #include + #include + #include + #include + #include + + #include + #include + #include + + // Definitions of the Damaris XML tag generators + #include + #include + #include + + #include "damaris_wrapper.h" + + using PDI::Context; + using std::unique_ptr; + using std::list; + using std::string; + + namespace damaris_pdi { + + class Damaris_async_gather + { + + + + public: + Damaris_async_gather(PDI::Context& ctx, PC_tree_t tree); + + }; // class Damaris_async_gather + + } // namespace damaris_pdi + + #endif // Damaris_async_gather_H_ \ No newline at end of file diff --git a/plugins/damaris/damaris_cfg.cxx b/plugins/damaris/damaris_cfg.cxx index e1a9fbe33..84ba5bcf8 100644 --- a/plugins/damaris/damaris_cfg.cxx +++ b/plugins/damaris/damaris_cfg.cxx @@ -250,7 +250,7 @@ m_xml_config_object = damarisXMLModifyModel.GetConfigString(); - printf("-------------------------------------------------------XML OBJECT MODIFIED----------------------------------------------\n%s", damarisXMLModifyModel.GetConfigString().c_str()); + //printf("-------------------------------------------------------XML OBJECT MODIFIED----------------------------------------------\n%s", damarisXMLModifyModel.GetConfigString().c_str()); //exit(0); } @@ -387,7 +387,7 @@ ); load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); - ctx.logger().info("--------------------------------------------------------------------------------PARAMETER {} depends on {}", prmxml.param_name_, metadata_name); + //ctx.logger().info("--------------------------------------------------------------------------------PARAMETER {} depends on {}", prmxml.param_name_, metadata_name); } @@ -503,7 +503,7 @@ //m_datasets.emplace(vxml.var_name_ , vxml) ; m_datasets.emplace(dataset_elt_full_name , vxml) ; - ctx.logger().info("------------------- Parsing damaris Variable '{}' , name_index = {} ", dataset_elt_full_name, name_index); + //ctx.logger().info("------------------- Parsing damaris Variable '{}' , name_index = {} ", dataset_elt_full_name, name_index); if(name_index == 1) { find_replace_map.insert( @@ -557,7 +557,7 @@ //Is there a way to determine if an expression is ready to be evaluated? ei, all the conponent have a value if (!PC_status(PC_get(value, "[0]"))) {//Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter int nb_layout_dims2; PC_len(value, &nb_layout_dims2); - std::cout << "INFO: damaris_cfg nb_layout_dims has dims2: " << nb_layout_dims2 << std::endl ; + //std::cout << "INFO: damaris_cfg nb_layout_dims has dims2: " << nb_layout_dims2 << std::endl ; std::string dims_list = ""; each(value, [&](PC_tree_t dim) { @@ -663,9 +663,9 @@ global_list.push_back(tmp); } - ctx.logger().info("------------------- OLD layoutxml.layout_dimensions_ '{}' | layoutxml.layout_dims_global_ '{}'", layoutxml.layout_dimensions_, layoutxml.layout_dims_global_); + //ctx.logger().info("------------------- OLD layoutxml.layout_dimensions_ '{}' | layoutxml.layout_dims_global_ '{}'", layoutxml.layout_dimensions_, layoutxml.layout_dims_global_); - ctx.logger().info("------------------- dim_list[0] = '{}' | global_list[0] = '{}'", dim_list[0], global_list[0]); + //ctx.logger().info("------------------- dim_list[0] = '{}' | global_list[0] = '{}'", dim_list[0], global_list[0]); std::string prm_config_yaml = "";//"parameters: \n"; @@ -707,7 +707,7 @@ //Background creation of parameter PC_tree_t parameters_conf = PC_parse_string(prm_config_yaml.c_str()); - ctx.logger().info("------------------- parameters_conf = \n '{}'", prm_config_yaml); + //ctx.logger().info("------------------- parameters_conf = \n '{}'", prm_config_yaml); parse_parameters_tree(ctx, parameters_conf); } else { @@ -719,7 +719,7 @@ //m_layouts.emplace(layoutxml.layout_name_ , layoutxml) ; m_layouts.emplace(dataset_elt_full_name , layoutxml) ; - ctx.logger().info("------------------- Parsing damaris Layout '{}' , name_index = {} ", dataset_elt_full_name, name_index); + //ctx.logger().info("------------------- Parsing damaris Layout '{}' , name_index = {} ", dataset_elt_full_name, name_index); if(name_index == 1) { find_replace_map.insert( @@ -801,7 +801,7 @@ //m_meshes.emplace(meshxml.get_name() , meshxml) ; m_meshes.emplace(meshxml.get_name() , meshxml) ; - ctx.logger().info("------------------- Parsing damaris Mesh '{}' , name_index = {} ", dataset_elt_full_name, name_index); + //ctx.logger().info("------------------- Parsing damaris Mesh '{}' , name_index = {} ", dataset_elt_full_name, name_index); if(name_index == 1) { find_replace_map.insert( @@ -844,13 +844,13 @@ //Ensure the folder exists struct stat st; if (stat(store.store_opt_FilesPath_.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) { - ctx.logger().info("HDF5 files_path exists: '{}'", to_string(value)); + //ctx.logger().info("HDF5 files_path exists: '{}'", to_string(value)); } else { if (mkdir(store.store_opt_FilesPath_.c_str(), 0775) == -1) { - ctx.logger().info("Error during the creation of the HDF5 files_path: '{}'", strerror(errno)); + //ctx.logger().info("Error during the creation of the HDF5 files_path: '{}'", strerror(errno)); exit(1); } else { - ctx.logger().info("HDF5 files_path created successfully: '{}'", to_string(value)); + //ctx.logger().info("HDF5 files_path created successfully: '{}'", to_string(value)); } } } @@ -908,7 +908,7 @@ if (!PC_status(PC_get(value, "[0]"))) {//Array //[script1, script2, script3] int nb_paraview_scripts; PC_len(value, &nb_paraview_scripts); - std::cout << "INFO: damaris_cfg nb paraview scripts: " << nb_paraview_scripts << std::endl ; + // std::cout << "INFO: damaris_cfg nb paraview scripts: " << nb_paraview_scripts << std::endl ; each(value, [&](PC_tree_t script) { paraviewxml.add_script(to_string(script)); @@ -1007,14 +1007,14 @@ if(!PC_status(ds_name_tree)) { ds_name = to_string(ds_name_tree); - std::cout << "INFO: damaris_cfg write_ds_tree :: ds_name = '" << ds_name << "'" << std::endl ; + // std::cout << "INFO: damaris_cfg write_ds_tree :: ds_name = '" << ds_name << "'" << std::endl ; } //when PC_tree_t ds_when_tree = PC_get(write_ds_tree, ".when"); if(!PC_status(ds_when_tree)) { ds_write_info.when = to_string(ds_when_tree); - std::cout << "INFO: damaris_cfg write_ds_tree :: when = '" << ds_write_info.when << "'" << std::endl ; + // std::cout << "INFO: damaris_cfg write_ds_tree :: when = '" << ds_write_info.when << "'" << std::endl ; } //position PC_tree_t ds_position_tree = PC_get(write_ds_tree, ".position"); @@ -1022,7 +1022,7 @@ { if (!PC_status(PC_get(ds_position_tree, "[0]"))) {//Array [p0,p1,p3] (1 to 3 elements) int position_dim; PC_len(ds_position_tree, &position_dim); - std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: " << position_dim << std::endl ; + // std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: " << position_dim << std::endl ; int pos_idx = 0; each(ds_position_tree, [&](PC_tree_t dim) { @@ -1032,7 +1032,7 @@ } else {//p0 ds_write_info.position[0] = to_string(ds_position_tree); - std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: 1" << std::endl ; + // std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: 1" << std::endl ; } } //block @@ -1040,7 +1040,7 @@ if(!PC_status(ds_block_tree)) { ds_write_info.block = to_string(ds_block_tree); - std::cout << "INFO: damaris_cfg write_ds_tree :: block = '" << ds_write_info.block << "'" << std::endl ; + // std::cout << "INFO: damaris_cfg write_ds_tree :: block = '" << ds_write_info.block << "'" << std::endl ; } m_datasets_to_write.emplace(ds_name, ds_write_info); @@ -1054,7 +1054,7 @@ void Damaris_cfg::parse_parameter_to_update_tree(Context& ctx, PC_tree_t ptu_tree, Desc_type op_type) { if (!PC_status(PC_get(ptu_tree, "[0]"))) {//Array [prm0,prm1,prm3,...] / it's a list of names only - std::cout << "INFO: damaris_cfg parameter_set or _get :: Array [prm0,prm1,prm3,...] / it's a list of names only " << std::endl ; + // std::cout << "INFO: damaris_cfg parameter_set or _get :: Array [prm0,prm1,prm3,...] / it's a list of names only " << std::endl ; each(ptu_tree, [&](PC_tree_t prm_name_t) { std::pair prm_to_update_info; std::string metadata = to_string(prm_name_t); @@ -1064,11 +1064,11 @@ prm_to_update_info.second = op_type; m_parameter_to_update.emplace(metadata, prm_to_update_info); load_desc(m_descs, ctx, metadata, op_type); - std::cout << "INFO: damaris_cfg parameter_set or _get :: metadata = "<< metadata <<" and prm_name = "<< prm_name <<" " << std::endl ; + // std::cout << "INFO: damaris_cfg parameter_set or _get :: metadata = "<< metadata <<" and prm_name = "<< prm_name <<" " << std::endl ; }); } else if (!PC_status(ptu_tree)) { // it's a name:{config...} mapping - std::cout << "INFO: damaris_cfg parameter_set or _get :: it's a name:{config...} mapping " << std::endl ; + // std::cout << "INFO: damaris_cfg parameter_set or _get :: it's a name:{config...} mapping " << std::endl ; each(ptu_tree, [&](PC_tree_t ptu_metadata, PC_tree_t ptu_prmname) { std::string metadata = to_string(ptu_metadata); std::string prm_name = to_string(ptu_metadata); @@ -1084,7 +1084,7 @@ prm_to_update_info.second = op_type; m_parameter_to_update.emplace(metadata, prm_to_update_info); load_desc(m_descs, ctx, metadata, op_type); - std::cout << "INFO: damaris_cfg parameter_set or _get :: metadata = "<< metadata <<" and prm_name = "<< prm_name <<" " << std::endl ; + // std::cout << "INFO: damaris_cfg parameter_set or _get :: metadata = "<< metadata <<" and prm_name = "<< prm_name <<" " << std::endl ; }); } } diff --git a/plugins/damaris/damaris_wrapper.cxx b/plugins/damaris/damaris_wrapper.cxx index 00caf901c..87ef1af83 100644 --- a/plugins/damaris/damaris_wrapper.cxx +++ b/plugins/damaris/damaris_wrapper.cxx @@ -228,7 +228,7 @@ int Damaris_wrapper::damaris_pdi_get_iteration(int* iteration) Damaris_wrapper::~Damaris_wrapper() { // Call before MPI_Finalize() - damaris_finalize(); + //damaris_finalize();//Commented to avoid double finalize bug, Thank you Jacques :) } } // namespace damaris_pdi \ No newline at end of file From db29c2c4ecda51013506305e88c3ba4f62441cff Mon Sep 17 00:00:00 2001 From: Etienne Ndamlabin Date: Thu, 5 Mar 2026 12:39:14 +0100 Subject: [PATCH 14/42] Hide is_client from user: The condition to do that is to always have this sequence at the end of the simulation: PDI_finalize(); MPI_Finalize(); Or provide in the yml conf the code following PDI_finalize(); Code like the following could not be handled: PDI_finalize(); PC_tree_destroy(&conf); free(cur); free(next); MPI_Finalize(); --- plugins/damaris/damaris.cxx | 20 ++++++++++---------- plugins/damaris/damaris_api_call_handler.cxx | 15 ++++++++++++++- plugins/damaris/damaris_cfg.cxx | 12 ++++++++---- plugins/damaris/damaris_cfg.h | 6 +++--- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/plugins/damaris/damaris.cxx b/plugins/damaris/damaris.cxx index b3fcf69e6..25cb6c182 100644 --- a/plugins/damaris/damaris.cxx +++ b/plugins/damaris/damaris.cxx @@ -148,7 +148,7 @@ class damaris_plugin: public Plugin { void* prm_value_buffer; size_t prm_buffer_size; if(std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prm_type) != std::end(int_numbers_types)) { - std::cout << "int_numbers_types contains " << prm_type << '\n'; + //std::cout << "int_numbers_types contains " << prm_type << '\n'; int prm_long_value = std::atoi(prm_value.c_str()); prm_value_buffer = &prm_long_value; prm_buffer_size = sizeof(int); @@ -162,7 +162,7 @@ class damaris_plugin: public Plugin { */ } else if(std::find(std::begin(real_numbers_types), std::end(real_numbers_types), prm_type) != std::end(real_numbers_types)) { - std::cout << "real_numbers_types contains " << prm_type << '\n'; + //std::cout << "real_numbers_types contains " << prm_type << '\n'; double prm_dbl_value = std::atof(prm_value.c_str()); prm_value_buffer = &prm_dbl_value; prm_buffer_size = sizeof(double); @@ -170,7 +170,7 @@ class damaris_plugin: public Plugin { int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), prm_value_buffer, prm_buffer_size); } else { - std::cout << "String === " << prm_type << '\n'; + //std::cout << "String === " << prm_type << '\n'; std::string prm_string_value = prm_value; prm_value_buffer = &prm_string_value; prm_buffer_size = sizeof(std::string); @@ -255,7 +255,7 @@ class damaris_plugin: public Plugin { // exit(0); } else if(m_config.is_parameter_to_update(name)){ - context().logger().info("m_config.is_parameter_to_update('{}') = `{}'", name, m_config.is_parameter_to_update(name)); + //context().logger().info("m_config.is_parameter_to_update('{}') = `{}'", name, m_config.is_parameter_to_update(name)); std::pair prm_to_update_info = m_config.get_parameter_to_update_info(name); std::string prm_name = prm_to_update_info.first; size_t size; @@ -288,12 +288,12 @@ class damaris_plugin: public Plugin { } //is_client_get !? else if(name == m_config.is_client_dataset_name()) { - context().logger().info("'{}' == m_config.is_client_dataset_name() = '{}'", name, (name == m_config.is_client_dataset_name())); + //context().logger().info("'{}' == m_config.is_client_dataset_name() = '{}'", name, (name == m_config.is_client_dataset_name())); if (Ref_w wref = ref) { - context().logger().info(":) D) '{}' == m_config.is_client_dataset_name() = '{}' | m_damaris->get_is_client() = '{}'", name, (name == m_config.is_client_dataset_name()), m_damaris->get_is_client()); + //context().logger().info(":) D) '{}' == m_config.is_client_dataset_name() = '{}' | m_damaris->get_is_client() = '{}'", name, (name == m_config.is_client_dataset_name()), m_damaris->get_is_client()); *static_cast(wref.get()) = m_damaris->get_is_client(); - context().logger().info("------------------- CALLED is_client_dataset_name Return is_client = '{}')", m_damaris->get_is_client()); + //context().logger().info("------------------- CALLED is_client_dataset_name Return is_client = '{}')", m_damaris->get_is_client()); } else { //MayBe a PDI_multi_expose is under traitement @@ -307,7 +307,7 @@ class damaris_plugin: public Plugin { int err = m_damaris->damaris_pdi_client_comm_get(&client_comm); *static_cast(wref.get()) = client_comm; - context().logger().info("------------------- CALLED is_client_dataset_name Return client_comm SETED)"); + //context().logger().info("------------------- CALLED is_client_dataset_name Return client_comm SETED)"); } else { //MayBe a PDI_multi_expose is under traitement @@ -346,9 +346,9 @@ class damaris_plugin: public Plugin { } } else if(m_event_handler.is_damaris_api_call_event(event_name)){ - context().logger().info("event `{}' has been triggered", event_name); + //context().logger().info("event `{}' has been triggered", event_name); - context().logger().info("is_damaris_api_call_event ( `{}' ) = TRUE", event_name); + //context().logger().info("is_damaris_api_call_event ( `{}' ) = TRUE", event_name); m_event_handler.damaris_api_call_event(context(), m_damaris, event_name, multi_expose_transaction_dataname); multi_expose_transaction_dataname.clear(); diff --git a/plugins/damaris/damaris_api_call_handler.cxx b/plugins/damaris/damaris_api_call_handler.cxx index 49544e5e1..f3e55ac41 100644 --- a/plugins/damaris/damaris_api_call_handler.cxx +++ b/plugins/damaris/damaris_api_call_handler.cxx @@ -23,6 +23,7 @@ * THE SOFTWARE. ******************************************************************************/ +#include #include #include "damaris_api_call_handler.h" #include "damaris_cfg.h" @@ -106,7 +107,7 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptrdamaris_pdi_start(&is_client); m_damaris->set_is_client(is_client); - ctx.logger().info("------------------- CALLED damaris_pdi_start Return IS_CLIENT = '{}')", is_client); + //ctx.logger().info("------------------- CALLED damaris_pdi_start Return IS_CLIENT = '{}')", is_client); int arg_pos = 0; int nb_awaited_args = 1; @@ -132,6 +133,18 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptr event_names = { std::unordered_map> m_layout_depends_on; std::unordered_map m_layout_expression; - std::string m_is_client_dataset_name = ""; + static std::string m_is_client_dataset_name; std::string m_client_comm_get_dataset_name = ""; @@ -277,9 +277,9 @@ const std::unordered_map event_names = { { return m_after_write_events.size(); } - std::string is_client_dataset_name() const + static std::string is_client_dataset_name() { - return m_is_client_dataset_name; + return m_is_client_dataset_name; } std::string client_comm_get_dataset_name() const { From f2e80c788372bc4c86d8775fdb976a89c88e435e Mon Sep 17 00:00:00 2001 From: jmorice91 Date: Mon, 9 Mar 2026 12:06:24 +0100 Subject: [PATCH 15/42] Revert "Hide is_client from user:" (#16) This reverts commit db29c2c4ecda51013506305e88c3ba4f62441cff. --- plugins/damaris/damaris.cxx | 20 ++++++++++---------- plugins/damaris/damaris_api_call_handler.cxx | 15 +-------------- plugins/damaris/damaris_cfg.cxx | 12 ++++-------- plugins/damaris/damaris_cfg.h | 6 +++--- 4 files changed, 18 insertions(+), 35 deletions(-) diff --git a/plugins/damaris/damaris.cxx b/plugins/damaris/damaris.cxx index 25cb6c182..b3fcf69e6 100644 --- a/plugins/damaris/damaris.cxx +++ b/plugins/damaris/damaris.cxx @@ -148,7 +148,7 @@ class damaris_plugin: public Plugin { void* prm_value_buffer; size_t prm_buffer_size; if(std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prm_type) != std::end(int_numbers_types)) { - //std::cout << "int_numbers_types contains " << prm_type << '\n'; + std::cout << "int_numbers_types contains " << prm_type << '\n'; int prm_long_value = std::atoi(prm_value.c_str()); prm_value_buffer = &prm_long_value; prm_buffer_size = sizeof(int); @@ -162,7 +162,7 @@ class damaris_plugin: public Plugin { */ } else if(std::find(std::begin(real_numbers_types), std::end(real_numbers_types), prm_type) != std::end(real_numbers_types)) { - //std::cout << "real_numbers_types contains " << prm_type << '\n'; + std::cout << "real_numbers_types contains " << prm_type << '\n'; double prm_dbl_value = std::atof(prm_value.c_str()); prm_value_buffer = &prm_dbl_value; prm_buffer_size = sizeof(double); @@ -170,7 +170,7 @@ class damaris_plugin: public Plugin { int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), prm_value_buffer, prm_buffer_size); } else { - //std::cout << "String === " << prm_type << '\n'; + std::cout << "String === " << prm_type << '\n'; std::string prm_string_value = prm_value; prm_value_buffer = &prm_string_value; prm_buffer_size = sizeof(std::string); @@ -255,7 +255,7 @@ class damaris_plugin: public Plugin { // exit(0); } else if(m_config.is_parameter_to_update(name)){ - //context().logger().info("m_config.is_parameter_to_update('{}') = `{}'", name, m_config.is_parameter_to_update(name)); + context().logger().info("m_config.is_parameter_to_update('{}') = `{}'", name, m_config.is_parameter_to_update(name)); std::pair prm_to_update_info = m_config.get_parameter_to_update_info(name); std::string prm_name = prm_to_update_info.first; size_t size; @@ -288,12 +288,12 @@ class damaris_plugin: public Plugin { } //is_client_get !? else if(name == m_config.is_client_dataset_name()) { - //context().logger().info("'{}' == m_config.is_client_dataset_name() = '{}'", name, (name == m_config.is_client_dataset_name())); + context().logger().info("'{}' == m_config.is_client_dataset_name() = '{}'", name, (name == m_config.is_client_dataset_name())); if (Ref_w wref = ref) { - //context().logger().info(":) D) '{}' == m_config.is_client_dataset_name() = '{}' | m_damaris->get_is_client() = '{}'", name, (name == m_config.is_client_dataset_name()), m_damaris->get_is_client()); + context().logger().info(":) D) '{}' == m_config.is_client_dataset_name() = '{}' | m_damaris->get_is_client() = '{}'", name, (name == m_config.is_client_dataset_name()), m_damaris->get_is_client()); *static_cast(wref.get()) = m_damaris->get_is_client(); - //context().logger().info("------------------- CALLED is_client_dataset_name Return is_client = '{}')", m_damaris->get_is_client()); + context().logger().info("------------------- CALLED is_client_dataset_name Return is_client = '{}')", m_damaris->get_is_client()); } else { //MayBe a PDI_multi_expose is under traitement @@ -307,7 +307,7 @@ class damaris_plugin: public Plugin { int err = m_damaris->damaris_pdi_client_comm_get(&client_comm); *static_cast(wref.get()) = client_comm; - //context().logger().info("------------------- CALLED is_client_dataset_name Return client_comm SETED)"); + context().logger().info("------------------- CALLED is_client_dataset_name Return client_comm SETED)"); } else { //MayBe a PDI_multi_expose is under traitement @@ -346,9 +346,9 @@ class damaris_plugin: public Plugin { } } else if(m_event_handler.is_damaris_api_call_event(event_name)){ - //context().logger().info("event `{}' has been triggered", event_name); + context().logger().info("event `{}' has been triggered", event_name); - //context().logger().info("is_damaris_api_call_event ( `{}' ) = TRUE", event_name); + context().logger().info("is_damaris_api_call_event ( `{}' ) = TRUE", event_name); m_event_handler.damaris_api_call_event(context(), m_damaris, event_name, multi_expose_transaction_dataname); multi_expose_transaction_dataname.clear(); diff --git a/plugins/damaris/damaris_api_call_handler.cxx b/plugins/damaris/damaris_api_call_handler.cxx index f3e55ac41..49544e5e1 100644 --- a/plugins/damaris/damaris_api_call_handler.cxx +++ b/plugins/damaris/damaris_api_call_handler.cxx @@ -23,7 +23,6 @@ * THE SOFTWARE. ******************************************************************************/ -#include #include #include "damaris_api_call_handler.h" #include "damaris_cfg.h" @@ -107,7 +106,7 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptrdamaris_pdi_start(&is_client); m_damaris->set_is_client(is_client); - //ctx.logger().info("------------------- CALLED damaris_pdi_start Return IS_CLIENT = '{}')", is_client); + ctx.logger().info("------------------- CALLED damaris_pdi_start Return IS_CLIENT = '{}')", is_client); int arg_pos = 0; int nb_awaited_args = 1; @@ -133,18 +132,6 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptr event_names = { std::unordered_map> m_layout_depends_on; std::unordered_map m_layout_expression; - static std::string m_is_client_dataset_name; + std::string m_is_client_dataset_name = ""; std::string m_client_comm_get_dataset_name = ""; @@ -277,9 +277,9 @@ const std::unordered_map event_names = { { return m_after_write_events.size(); } - static std::string is_client_dataset_name() + std::string is_client_dataset_name() const { - return m_is_client_dataset_name; + return m_is_client_dataset_name; } std::string client_comm_get_dataset_name() const { From dfeb9564c915b361907d7a3155f9efecf89d4289 Mon Sep 17 00:00:00 2001 From: yushan wang Date: Thu, 5 Mar 2026 15:13:29 +0100 Subject: [PATCH 16/42] update dependencies --- plugins/damaris/CMakeLists.txt | 7 +++++- plugins/damaris/example/example.c | 36 ++++++++++++++++++------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/plugins/damaris/CMakeLists.txt b/plugins/damaris/CMakeLists.txt index c1e6de2de..85584c83d 100644 --- a/plugins/damaris/CMakeLists.txt +++ b/plugins/damaris/CMakeLists.txt @@ -66,6 +66,11 @@ find_package(MPI REQUIRED COMPONENTS CXX C) # PDI find_package(PDI 1.9.2 REQUIRED COMPONENTS plugins) +find_package(HDF5 REQUIRED COMPONENTS C) +find_package(XercesC REQUIRED) +find_package(Boost 1.65.0 REQUIRED COMPONENTS thread log log_setup filesystem date_time ) + +set(other_deps hdf5::hdf5 XercesC::XercesC Boost::filesystem Boost::log Boost::log_setup) # The plugin add_library(pdi_damaris_plugin MODULE @@ -73,7 +78,7 @@ add_library(pdi_damaris_plugin MODULE damaris_cfg.cxx damaris_wrapper.cxx damaris_api_call_handler.cxx) -target_link_libraries(pdi_damaris_plugin PUBLIC PDI::PDI_plugins ${Damaris_DEPS}) +target_link_libraries(pdi_damaris_plugin PUBLIC PDI::PDI_plugins ${Damaris_DEPS} ${other_deps}) set_target_properties(pdi_damaris_plugin PROPERTIES CXX_VISIBILITY_PRESET hidden) # installation diff --git a/plugins/damaris/example/example.c b/plugins/damaris/example/example.c index bb60da9a4..f48e4ca48 100644 --- a/plugins/damaris/example/example.c +++ b/plugins/damaris/example/example.c @@ -158,10 +158,16 @@ int main(int argc, char* argv[]) fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); } - + PC_tree_t conf = PC_parse_path(argv[1]); MPI_Comm main_comm = MPI_COMM_WORLD; + int world_size; + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + if(world_size!=4) { + fprintf(stderr, "Please use 4 mpi processes in total\n"); + exit(1); + } PDI_init(PC_get(conf, ".pdi")); PDI_event("init"); @@ -228,7 +234,7 @@ int main(int argc, char* argv[]) PDI_event("main_loop"); double start = MPI_Wtime(); int next_reduce = 0; - for (ii = 0;; ++ii) { + for (ii = 0; ii<10; ++ii) { PDI_multi_expose("newiter", "iter", &ii, PDI_INOUT, "main_field", cur, PDI_INOUT, NULL); iter(dsize, cur, next); @@ -237,19 +243,19 @@ int main(int argc, char* argv[]) cur = next; next = tmp; - if (ii >= next_reduce) { - double local_time, global_time; - local_time = MPI_Wtime() - start; - MPI_Allreduce(&local_time, &global_time, 1, MPI_DOUBLE, MPI_MAX, main_comm); - if (global_time >= duration) { - if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; STOP!!!\n", ii, global_time); - break; - } - int rem_iter = .9 * (duration - global_time) * (ii + 1) / (global_time + 0.1); - if (rem_iter < 1) rem_iter = 1; - next_reduce = ii + rem_iter; - if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; next_reduce=%7d\n", ii, global_time, next_reduce); - } + // if (ii >= next_reduce) { + // double local_time, global_time; + // local_time = MPI_Wtime() - start; + // MPI_Allreduce(&local_time, &global_time, 1, MPI_DOUBLE, MPI_MAX, main_comm); + // if (global_time >= duration) { + // if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; STOP!!!\n", ii, global_time); + // break; + // } + // int rem_iter = .9 * (duration - global_time) * (ii + 1) / (global_time + 0.1); + // if (rem_iter < 1) rem_iter = 1; + // next_reduce = ii + rem_iter; + // if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; next_reduce=%7d\n", ii, global_time, next_reduce); + // } //PDI_event("damaris_end_iteration"); } PDI_event("finalization"); From a5d7c501fb2f79069c2146223d9c37ad40399acf Mon Sep 17 00:00:00 2001 From: yushan wang Date: Mon, 9 Mar 2026 10:17:51 +0100 Subject: [PATCH 17/42] remove bits/stdc++ header --- plugins/damaris/damaris.cxx | 9 ++++----- plugins/damaris/damaris_cfg.cxx | 3 +-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/plugins/damaris/damaris.cxx b/plugins/damaris/damaris.cxx index b3fcf69e6..b3199f532 100644 --- a/plugins/damaris/damaris.cxx +++ b/plugins/damaris/damaris.cxx @@ -28,7 +28,6 @@ #include #include -#include #include #include #include @@ -211,17 +210,17 @@ class damaris_plugin: public Plugin { context().logger().info("data `{}' will be written at: block '{}' and position '{}:{}:{}', when = '{}'", name, block, position[0], position[1], position[2], ds_write_info.when.to_long(context())); std::string set_block_pos_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_SET_BLOCK_POSITION); - m_event_handler.damaris_api_call_event(context(), m_damaris, set_block_pos_event_name, multi_expose_transaction_dataname, name, block, position); + m_event_handler.damaris_api_call_event(context(), m_damaris, set_block_pos_event_name, multi_expose_transaction_dataname, name.c_str(), block, position); std::string write_block_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_WRITE_BLOCK); - m_event_handler.damaris_api_call_event(context(), m_damaris, write_block_event_name, multi_expose_transaction_dataname, name, block, data); + m_event_handler.damaris_api_call_event(context(), m_damaris, write_block_event_name, multi_expose_transaction_dataname, name.c_str(), block, data); } else { std::string set_pos_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_SET_POSITION); - m_event_handler.damaris_api_call_event(context(), m_damaris, set_pos_event_name, multi_expose_transaction_dataname, name, position); + m_event_handler.damaris_api_call_event(context(), m_damaris, set_pos_event_name, multi_expose_transaction_dataname, name.c_str(), position); std::string write_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_WRITE); - m_event_handler.damaris_api_call_event(context(), m_damaris, write_event_name, multi_expose_transaction_dataname, name, data); + m_event_handler.damaris_api_call_event(context(), m_damaris, write_event_name, multi_expose_transaction_dataname, name.c_str(), data); } datasets_to_write_count++; diff --git a/plugins/damaris/damaris_cfg.cxx b/plugins/damaris/damaris_cfg.cxx index 84ba5bcf8..e73d09030 100644 --- a/plugins/damaris/damaris_cfg.cxx +++ b/plugins/damaris/damaris_cfg.cxx @@ -35,8 +35,7 @@ #include #include #include - #include - + #include "damaris_cfg.h" using PDI::Context; From 8752bb7cbd669f58ff28e5be342b8fd3ffb703d6 Mon Sep 17 00:00:00 2001 From: yushan wang Date: Mon, 9 Mar 2026 10:18:14 +0100 Subject: [PATCH 18/42] fix POD error with va_arg --- plugins/damaris/damaris_api_call_handler.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/damaris/damaris_api_call_handler.cxx b/plugins/damaris/damaris_api_call_handler.cxx index 49544e5e1..96132ebf4 100644 --- a/plugins/damaris/damaris_api_call_handler.cxx +++ b/plugins/damaris/damaris_api_call_handler.cxx @@ -151,7 +151,7 @@ void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptr Date: Mon, 9 Mar 2026 10:20:04 +0100 Subject: [PATCH 19/42] revert change to CMake --- plugins/damaris/CMakeLists.txt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/plugins/damaris/CMakeLists.txt b/plugins/damaris/CMakeLists.txt index 85584c83d..c1e6de2de 100644 --- a/plugins/damaris/CMakeLists.txt +++ b/plugins/damaris/CMakeLists.txt @@ -66,11 +66,6 @@ find_package(MPI REQUIRED COMPONENTS CXX C) # PDI find_package(PDI 1.9.2 REQUIRED COMPONENTS plugins) -find_package(HDF5 REQUIRED COMPONENTS C) -find_package(XercesC REQUIRED) -find_package(Boost 1.65.0 REQUIRED COMPONENTS thread log log_setup filesystem date_time ) - -set(other_deps hdf5::hdf5 XercesC::XercesC Boost::filesystem Boost::log Boost::log_setup) # The plugin add_library(pdi_damaris_plugin MODULE @@ -78,7 +73,7 @@ add_library(pdi_damaris_plugin MODULE damaris_cfg.cxx damaris_wrapper.cxx damaris_api_call_handler.cxx) -target_link_libraries(pdi_damaris_plugin PUBLIC PDI::PDI_plugins ${Damaris_DEPS} ${other_deps}) +target_link_libraries(pdi_damaris_plugin PUBLIC PDI::PDI_plugins ${Damaris_DEPS}) set_target_properties(pdi_damaris_plugin PROPERTIES CXX_VISIBILITY_PRESET hidden) # installation From 6c786456b34ac751b1ff4c4d4e1b51a16fec2ee0 Mon Sep 17 00:00:00 2001 From: yushan wang Date: Mon, 9 Mar 2026 10:36:39 +0100 Subject: [PATCH 20/42] update copyright --- plugins/damaris/damaris.cxx | 2 +- plugins/damaris/damaris_api_call_handler.cxx | 2 +- plugins/damaris/damaris_cfg.cxx | 4 ++-- plugins/damaris/example/example.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/damaris/damaris.cxx b/plugins/damaris/damaris.cxx index b3199f532..27366dfea 100644 --- a/plugins/damaris/damaris.cxx +++ b/plugins/damaris/damaris.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2024 National Institute for Research in Digital Science and Technology (Inria) * All rights reserved. * diff --git a/plugins/damaris/damaris_api_call_handler.cxx b/plugins/damaris/damaris_api_call_handler.cxx index 96132ebf4..63f601e9e 100644 --- a/plugins/damaris/damaris_api_call_handler.cxx +++ b/plugins/damaris/damaris_api_call_handler.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2024 National Institute for Research in Digital Science and Technology (Inria) * All rights reserved. * diff --git a/plugins/damaris/damaris_cfg.cxx b/plugins/damaris/damaris_cfg.cxx index e73d09030..08a8fd63b 100644 --- a/plugins/damaris/damaris_cfg.cxx +++ b/plugins/damaris/damaris_cfg.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2024 National Institute for Research in Digital Science and Technology (Inria) * All rights reserved. * @@ -35,7 +35,7 @@ #include #include #include - + #include "damaris_cfg.h" using PDI::Context; diff --git a/plugins/damaris/example/example.c b/plugins/damaris/example/example.c index f48e4ca48..cc7fc0f76 100644 --- a/plugins/damaris/example/example.c +++ b/plugins/damaris/example/example.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2019 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without From a787c17a19baa86d07f75b6e5cd708fdd6964a34 Mon Sep 17 00:00:00 2001 From: yushan wang Date: Mon, 9 Mar 2026 10:39:59 +0100 Subject: [PATCH 21/42] fix merge conflit --- plugins/damaris/damaris.cxx | 238 +- plugins/damaris/damaris_api_call_handler.cxx | 939 +++--- plugins/damaris/damaris_cfg.cxx | 2723 ++++++++---------- plugins/damaris/example/example.c | 198 +- 4 files changed, 1992 insertions(+), 2106 deletions(-) diff --git a/plugins/damaris/damaris.cxx b/plugins/damaris/damaris.cxx index 27366dfea..4b94b5d35 100644 --- a/plugins/damaris/damaris.cxx +++ b/plugins/damaris/damaris.cxx @@ -23,16 +23,16 @@ * THE SOFTWARE. ******************************************************************************/ -#include -#include #include #include +#include +#include +#include #include #include #include #include -#include #include @@ -42,83 +42,80 @@ #include #include +#include "damaris_api_call_handler.h" #include "damaris_cfg.h" #include "damaris_wrapper.h" -#include "damaris_api_call_handler.h" namespace { -using PDI::Datatype_sptr; using PDI::Context; +using PDI::Datatype_sptr; using PDI::Error; using PDI::Plugin; using PDI::Ref; -using PDI::Ref_w; using PDI::Ref_r; +using PDI::Ref_w; using PDI::to_string; +using std::dynamic_pointer_cast; using std::get; -using std::pair; using std::list; +using std::pair; using std::string; using std::unique_ptr; using std::unordered_map; using std::unordered_set; -using std::dynamic_pointer_cast; using namespace PDI; using namespace damaris_pdi; -class damaris_plugin: public Plugin { - +class damaris_plugin: public Plugin +{ Damaris_cfg m_config; Damaris_api_call_handler m_event_handler; - + unique_ptr m_damaris; - - static pair, unordered_set> dependencies() - { - return {{"mpi"}, {"mpi"}}; - } + + static pair, unordered_set> dependencies() { return {{"mpi"}, {"mpi"}}; } list multi_expose_transaction_dataname; //list multi_expose_transaction_dataref; - std::string int_numbers_types[3] = {"short", "int", "integer"}; + std::string int_numbers_types[3] = {"short", "int", "integer"}; std::string real_numbers_types[3] = {"float", "real", "double"}; - - int iteration = 0;//for debugging - int datasets_to_write_count = 0;//The number of data already written in the current iteration -public: + int iteration = 0; //for debugging + int datasets_to_write_count = 0; //The number of data already written in the current iteration +public: damaris_plugin(Context& ctx, PC_tree_t config) : Plugin{ctx} , m_config{ctx, config} - , m_event_handler{m_config.xml_config_object(), m_config.communicator(), m_config.init_on_event() - , m_config.start_on_event(), m_config.stop_on_event()} + , m_event_handler{ + m_config.xml_config_object(), + m_config.communicator(), + m_config.init_on_event(), + m_config.start_on_event(), + m_config.stop_on_event() + } { - std::string data_cb_concat = ""; - for (auto&& desc: m_config.descs()) {//add data callback only for awaited data - ctx.callbacks().add_data_callback([this](const std::string& name, Ref ref) { this->data(name, ref); }, - desc.first); - data_cb_concat.append(desc.first + ", "); + for (auto&& desc: m_config.descs()) { //add data callback only for awaited data + ctx.callbacks().add_data_callback([this](const std::string& name, Ref ref) { this->data(name, ref); }, desc.first); + data_cb_concat.append(desc.first + ", "); } context().logger().info("Data for callback : {}", data_cb_concat); - + //Sim configured event names for (auto&& event: m_config.events()) { - ctx.callbacks().add_event_callback([this](const std::string& name) { this->event(name); }, - event.first); + ctx.callbacks().add_event_callback([this](const std::string& name) { this->event(name); }, event.first); } - + //Default event names, maight be called internally for (auto&& ev_name: event_names) { //Only if the key if not yet used by an event if (m_config.events().find(ev_name.second) == m_config.events().end()) - ctx.callbacks().add_event_callback([this](const std::string& name) { this->event(name); }, - ev_name.second); + ctx.callbacks().add_event_callback([this](const std::string& name) { this->event(name); }, ev_name.second); } //ctx.callbacks().add_event_callback([this](const std::string& name) { this->event(name); }); @@ -127,22 +124,22 @@ class damaris_plugin: public Plugin { } void data(const std::string& name, Ref ref) - { + { ensure_damaris_is_initialized(""); context().logger().info("data `{}' has been exposed", name); //Update damaris parameters - if(m_config.is_needed_metadata(name)){ + if (m_config.is_needed_metadata(name)) { std::unordered_map> updatable_parameters = m_config.get_updatable_parameters(context()); std::string prm_name_concat = ""; - for(auto prm_update_info : updatable_parameters) { - auto prm_name = prm_update_info.first; - auto update_info = prm_update_info.second; + for (auto prm_update_info: updatable_parameters) { + auto prm_name = prm_update_info.first; + auto update_info = prm_update_info.second; { - std::string prm_value = update_info.first; - std::string prm_type = update_info.second; + std::string prm_value = update_info.first; + std::string prm_type = update_info.second; void* prm_value_buffer; size_t prm_buffer_size; @@ -151,9 +148,9 @@ class damaris_plugin: public Plugin { int prm_long_value = std::atoi(prm_value.c_str()); prm_value_buffer = &prm_long_value; prm_buffer_size = sizeof(int); - - int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), prm_value_buffer, prm_buffer_size); - + + int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), prm_value_buffer, prm_buffer_size); + //checking if it works! /*int new_prm_val; m_damaris->damaris_pdi_parameter_get(prm_name.c_str(), &new_prm_val, prm_buffer_size); @@ -174,77 +171,103 @@ class damaris_plugin: public Plugin { prm_value_buffer = &prm_string_value; prm_buffer_size = sizeof(std::string); - int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), prm_value_buffer, prm_buffer_size); + int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), prm_value_buffer, prm_buffer_size); } } prm_name_concat.append(prm_name + ", "); m_config.reset_parameter_depends_on(prm_name); } - if(updatable_parameters.size() > 0){ + if (updatable_parameters.size() > 0) { prm_name_concat.pop_back(); prm_name_concat.pop_back(); context().logger().info("data `{}' Is a needed metadata for the evaluation of parameters {}", name, prm_name_concat); } - } - else if(m_config.is_dataset_to_write(name)){ + } else if (m_config.is_dataset_to_write(name)) { context().logger().info("is_dataset_to_write(`{}') = '{}'", name, m_config.is_dataset_to_write(name)); if (Ref_r rref = ref) { Dataset_Write_Info ds_write_info = m_config.get_dataset_write_info(name); //Only write when autorized! - if(ds_write_info.when.to_long(context())) { + if (ds_write_info.when.to_long(context())) { context().logger().info("data `{}' will be written when = '{}'", name, ds_write_info.when.to_long(context())); int32_t block = ds_write_info.block.to_long(context()); context().logger().info("data `{}' will be written in block = '{}'", name, block); - int64_t position[3] = { - ds_write_info.position[0].to_long(context()) - ,ds_write_info.position[1].to_long(context()) - ,ds_write_info.position[2].to_long(context()) - }; - + int64_t position[3] + = {ds_write_info.position[0].to_long(context()), + ds_write_info.position[1].to_long(context()), + ds_write_info.position[2].to_long(context())}; + const void* data = static_cast(rref.get()); - if(block > 0) { - context().logger().info("data `{}' will be written at: block '{}' and position '{}:{}:{}', when = '{}'", name, block, position[0], position[1], position[2], ds_write_info.when.to_long(context())); - + if (block > 0) { + context().logger().info( + "data `{}' will be written at: block '{}' and position '{}:{}:{}', when = '{}'", + name, + block, + position[0], + position[1], + position[2], + ds_write_info.when.to_long(context()) + ); + std::string set_block_pos_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_SET_BLOCK_POSITION); - m_event_handler.damaris_api_call_event(context(), m_damaris, set_block_pos_event_name, multi_expose_transaction_dataname, name.c_str(), block, position); - + m_event_handler.damaris_api_call_event( + context(), + m_damaris, + set_block_pos_event_name, + multi_expose_transaction_dataname, + name.c_str(), + block, + position + ); + std::string write_block_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_WRITE_BLOCK); - m_event_handler.damaris_api_call_event(context(), m_damaris, write_block_event_name, multi_expose_transaction_dataname, name.c_str(), block, data); - } - else { + m_event_handler.damaris_api_call_event( + context(), + m_damaris, + write_block_event_name, + multi_expose_transaction_dataname, + name.c_str(), + block, + data + ); + } else { std::string set_pos_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_SET_POSITION); - m_event_handler.damaris_api_call_event(context(), m_damaris, set_pos_event_name, multi_expose_transaction_dataname, name.c_str(), position); + m_event_handler.damaris_api_call_event( + context(), + m_damaris, + set_pos_event_name, + multi_expose_transaction_dataname, + name.c_str(), + position + ); std::string write_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_WRITE); - m_event_handler.damaris_api_call_event(context(), m_damaris, write_event_name, multi_expose_transaction_dataname, name.c_str(), data); + m_event_handler + .damaris_api_call_event(context(), m_damaris, write_event_name, multi_expose_transaction_dataname, name.c_str(), data); } - + datasets_to_write_count++; //Wait until all datasets are written before launching end of iteration operations - if(m_config.is_there_after_write_events() && datasets_to_write_count == m_config.datasets_to_write().size()) { + if (m_config.is_there_after_write_events() && datasets_to_write_count == m_config.datasets_to_write().size()) { list after_write_events = m_config.get_after_write_events(); for (auto it = after_write_events.begin(); it != after_write_events.end(); it++) { std::string aw_event = it->c_str(); - if(m_event_handler.is_damaris_api_call_event(aw_event)){ + if (m_event_handler.is_damaris_api_call_event(aw_event)) { context().logger().info("event `{}' has been triggered", aw_event); context().logger().info("is_damaris_api_call_event ( `{}' ) = TRUE", aw_event); m_event_handler.damaris_api_call_event(context(), m_damaris, aw_event, {}); //m_event_handler.damaris_api_call_event(context(), m_damaris, aw_event, list expose_dataname = {}); - } - else {//Non Damaris call event - + } else { //Non Damaris call event } } datasets_to_write_count = 0; } - } - } - else{ + } + } else { context().logger().error("The Damaris need write access over the data (`{}')", name); } @@ -261,27 +284,25 @@ class damaris_plugin: public Plugin { damaris::model::DamarisParameterXML prmxml = m_config.get_parameter_xml(prm_name); - if(std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prmxml.param_datatype_) != std::end(int_numbers_types)) { - size = sizeof(int); - } - else if(std::find(std::begin(real_numbers_types), std::end(real_numbers_types), prmxml.param_datatype_) != std::end(real_numbers_types)) { - size = sizeof(double); - } - else { - size = sizeof(std::string); + if (std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prmxml.param_datatype_) != std::end(int_numbers_types)) { + size = sizeof(int); + } else if (std::find(std::begin(real_numbers_types), std::end(real_numbers_types), prmxml.param_datatype_) + != std::end(real_numbers_types)) + { + size = sizeof(double); + } else { + size = sizeof(std::string); } if (prm_to_update_info.second == Desc_type::PRM_TO_SET) { Ref_r rref = ref; - int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), static_cast(rref.get()), size); - } - else if (prm_to_update_info.second == Desc_type::PRM_TO_GET) { + int msg_err = m_damaris->damaris_pdi_parameter_set(prm_name.c_str(), static_cast(rref.get()), size); + } else if (prm_to_update_info.second == Desc_type::PRM_TO_GET) { Ref_w wref = ref; - int msg_err = m_damaris->damaris_pdi_parameter_get(prm_name.c_str(), static_cast(wref.get()), size); - } - else { + int msg_err = m_damaris->damaris_pdi_parameter_get(prm_name.c_str(), static_cast(wref.get()), size); + } else { //Error handling! } } @@ -300,9 +321,10 @@ class damaris_plugin: public Plugin { } } //client_comm_get !? - else if(name == m_config.client_comm_get_dataset_name()) { + else if (name == m_config.client_comm_get_dataset_name()) + { if (Ref_w wref = ref) { - MPI_Comm client_comm; + MPI_Comm client_comm; int err = m_damaris->damaris_pdi_client_comm_get(&client_comm); *static_cast(wref.get()) = client_comm; @@ -312,8 +334,7 @@ class damaris_plugin: public Plugin { //MayBe a PDI_multi_expose is under traitement multi_expose_transaction_dataname.emplace_back(name); } - } - else {//Handle other situations... + } else { //Handle other situations... multi_expose_transaction_dataname.emplace_back(name); //multi_expose_transaction_dataref.emplace_back(ref); } @@ -327,19 +348,16 @@ class damaris_plugin: public Plugin { //If it a sim configured event if (m_config.events().find(event_name) != m_config.events().end()) { - if(event_name == m_config.init_on_event()) { + if (event_name == m_config.init_on_event()) { std::string init_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_INITIALIZE); m_event_handler.damaris_api_call_event(context(), m_damaris, init_event_name, multi_expose_transaction_dataname); - } - else if(event_name == m_config.start_on_event()) { + } else if (event_name == m_config.start_on_event()) { std::string start_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_START); m_event_handler.damaris_api_call_event(context(), m_damaris, start_event_name, multi_expose_transaction_dataname); - } - else if(event_name == m_config.end_iteration_on_event()) { + } else if (event_name == m_config.end_iteration_on_event()) { std::string end_it_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_END_ITERATION); m_event_handler.damaris_api_call_event(context(), m_damaris, end_it_event_name, multi_expose_transaction_dataname); - } - else if(event_name == m_config.finalize_on_event()) { + } else if (event_name == m_config.finalize_on_event()) { std::string finalize_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_FINALIZE); m_event_handler.damaris_api_call_event(context(), m_damaris, finalize_event_name, multi_expose_transaction_dataname); } @@ -352,25 +370,22 @@ class damaris_plugin: public Plugin { multi_expose_transaction_dataname.clear(); //multi_expose_transaction_dataref.clear(); - } - else {//Non Damaris call event - + } else { //Non Damaris call event } } void ensure_damaris_is_initialized(const std::string& event_name) { - if (!m_damaris) { + if (!m_damaris) { if (m_config.events().find(event_name) != m_config.events().end()) { - //Means the first action received by the plugin wasn't fir initialization... + //Means the first action received by the plugin wasn't fir initialization... if (!m_config.init_on_event().empty() && event_name != m_config.init_on_event()) { context().logger().error("Trying to use {} plugin before the initialization of the Damaris library!", pretty_name()); - } - else if (event_name == m_config.init_on_event()) - return;//The init will follows + } else if (event_name == m_config.init_on_event()) + return; //The init will follows } this->damaris_init(); - } + } } void damaris_init() @@ -380,10 +395,8 @@ class damaris_plugin: public Plugin { m_event_handler.damaris_api_call_event(context(), m_damaris, init_event_name, multi_expose_transaction_dataname); } - ~damaris_plugin() { - if (m_config.finalize_on_event().empty() && m_damaris) { context().logger().info("Calling DAMARIS_FINALIZE in ~damaris_plugin()"); std::string finalize_event_name = m_event_handler.get_event_name(Event_type::DAMARIS_FINALIZE); @@ -392,7 +405,6 @@ class damaris_plugin: public Plugin { context().logger().info("Closing plugin"); } - /** Pretty name for the plugin that will be shown in the logger * @@ -402,6 +414,6 @@ class damaris_plugin: public Plugin { }; // class damaris_plugin -} // namespace +} // namespace -PDI_PLUGIN(damaris) \ No newline at end of file +PDI_PLUGIN(damaris) diff --git a/plugins/damaris/damaris_api_call_handler.cxx b/plugins/damaris/damaris_api_call_handler.cxx index 63f601e9e..9aeca6dcb 100644 --- a/plugins/damaris/damaris_api_call_handler.cxx +++ b/plugins/damaris/damaris_api_call_handler.cxx @@ -29,481 +29,540 @@ using PDI::Context; using PDI::Ref; -using PDI::Ref_w; using PDI::Ref_r; -using std::unordered_map; -using std::map; -using std::unordered_set; +using PDI::Ref_w; using std::list; +using std::map; using std::string; using std::unique_ptr; - +using std::unordered_map; +using std::unordered_set; namespace damaris_pdi { Damaris_api_call_handler::Damaris_api_call_handler(std::string cfg_object) { - xml_config_object = cfg_object; + xml_config_object = cfg_object; } Damaris_api_call_handler::Damaris_api_call_handler(std::string cfg_object, PDI::Expression comm) { - xml_config_object = cfg_object; - m_communicator = comm; + xml_config_object = cfg_object; + m_communicator = comm; } -Damaris_api_call_handler::Damaris_api_call_handler(std::string cfg_object, PDI::Expression comm, std::string init_on_event, std::string start_on_event, std::string stop_on_event) +Damaris_api_call_handler::Damaris_api_call_handler( + std::string cfg_object, + PDI::Expression comm, + std::string init_on_event, + std::string start_on_event, + std::string stop_on_event +) { - xml_config_object = cfg_object; - m_communicator = comm; - m_init_on_event = init_on_event; - m_start_on_event = start_on_event; - m_stop_on_event = stop_on_event; + xml_config_object = cfg_object; + m_communicator = comm; + m_init_on_event = init_on_event; + m_start_on_event = start_on_event; + m_stop_on_event = stop_on_event; } std::string Damaris_api_call_handler::get_event_name(Event_type event_type) { - return event_names.at(event_type); + return event_names.at(event_type); } bool Damaris_api_call_handler::is_damaris_api_call_event(std::string event_name) -{ - for(auto event : event_names) { - if(event_name == event.second) - return true; - } - return false; +{ + for (auto event: event_names) { + if (event_name == event.second) return true; + } + return false; } - -void Damaris_api_call_handler::damaris_api_call_event(Context& ctx, unique_ptr &m_damaris, std::string event_name, list expose_dataname, ...) +void Damaris_api_call_handler::damaris_api_call_event( + Context& ctx, + unique_ptr& m_damaris, + std::string event_name, + list expose_dataname, + ... +) { - //************************************************************ */ - //Events : Damaris Initialize and Damaris Start - //************************************************************ */ - if(event_name == event_names.at(Event_type::DAMARIS_INITIALIZE)) { - - damaris_pdi_init(ctx, m_damaris, xml_config_object.c_str()); + //************************************************************ */ + //Events : Damaris Initialize and Damaris Start + //************************************************************ */ + if (event_name == event_names.at(Event_type::DAMARIS_INITIALIZE)) { + damaris_pdi_init(ctx, m_damaris, xml_config_object.c_str()); if (m_start_on_event.empty()) { - - ctx.logger().info("Plugin sent damaris_start() to Damaris, in initialize"); + ctx.logger().info("Plugin sent damaris_start() to Damaris, in initialize"); std::string start_event_name = this->get_event_name(Event_type::DAMARIS_START); - PDI_status_t status = PDI_event(start_event_name.c_str()); + PDI_status_t status = PDI_event(start_event_name.c_str()); + } + } else if (event_name == event_names.at(Event_type::DAMARIS_START)) { + // DAMARIS_START + // The following call starts the servers. Servers will run inside this + // function until they are asked to stop by clients. On clients, + // is_client will be set to 1 (0 on servers). + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_start() before plugin initialization (`{}')", event_name); + return; + } + std::string arg1_name; + int is_client; + int err = m_damaris->damaris_pdi_start(&is_client); + m_damaris->set_is_client(is_client); + //ctx.logger().info("------------------- CALLED damaris_pdi_start Return IS_CLIENT = '{}')", is_client); + + int arg_pos = 0; + int nb_awaited_args = 1; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1 && strcmp("is_client", it->c_str()) == 0) { + ctx.logger().info("------------------- CALLED damaris_pdi_start {} = '{}')", arg1_name, is_client); + + int* inout_is_client; + PDI_access(it->c_str(), (void**)&inout_is_client, PDI_INOUT); + *inout_is_client = is_client; + arg1_name = it->c_str(); + } else + //if(nb_awaited_args <= arg_pos) + break; + } + + //-----------------------Workaround to hide is_client from user----------------------- + //If it is a server and no `if(is_client) {}` closure: + // - all its clients have ended + // - we can stop it from here, since there is no more if(is_client) {} closure + if (!is_client && Damaris_cfg::is_client_dataset_name().empty()) // + { + ctx.logger().info( + "------------------- In if(!is_client): Damaris_cfg::is_client_dataset_name() = '{}')", + Damaris_cfg::is_client_dataset_name() + ); + PDI_finalize(); + MPI_Finalize(); + exit(0); + } + } + + //************************************************************ */ + //Events that rely on Multi expose + //************************************************************ */ + // DAMARIS_PARAMETER_GET + else if (event_name == event_names.at(Event_type::DAMARIS_PARAMETER_GET)) + { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_parameter_get() before plugin initialization (`{}')", event_name); + return; + } + ctx.logger().info("------------------- INNNNN DAMARIS_PARAMETER_GET Event..."); + + char* var_name; + std::string arg1_name = "prm_name"; + void* buffer; + std::string arg2_name = "prm_buffer"; + unsigned int* size; + std::string arg3_name = "prm_size"; + + va_list extra_args; + va_start(extra_args, expose_dataname); + string data_name = va_arg(extra_args, const char*); + if (!data_name.empty()) { + var_name = (char*)data_name.c_str(); + buffer = va_arg(extra_args, void*); + ctx.logger().info("------------------- INNNNN DAMARIS_PARAMETER_GET Event.. EXTRA ARGS.... AFTER buffer"); + *size = va_arg(extra_args, int); + ctx.logger().info("------------------- INNNNN DAMARIS_PARAMETER_GET Event.. EXTRA ARGS.... AFTER size..."); + + + ctx.logger().info( + "------------------- CALLING damaris_pdi_parameter_get arg_pos({}==='{}', {}==='{}', {}==='{}')", + arg1_name, + var_name, + arg2_name, + *(int*)buffer, + arg3_name, + *(int*)size + ); + int err = m_damaris->damaris_pdi_parameter_get((const char*)var_name, (void*)buffer, *(int*)size); + } + + } + // DAMARIS_PARAMETER_SET + else if (event_name == event_names.at(Event_type::DAMARIS_PARAMETER_SET)) + { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_parameter_set() before plugin initialization (`{}')", event_name); + return; } - } - else if(event_name == event_names.at(Event_type::DAMARIS_START)) { - // DAMARIS_START - // The following call starts the servers. Servers will run inside this - // function until they are asked to stop by clients. On clients, - // is_client will be set to 1 (0 on servers). - if (!m_damaris) { - ctx.logger().warn("Trying to call damaris_start() before plugin initialization (`{}')", event_name); - return; - } - std::string arg1_name; - int is_client; - int err = m_damaris->damaris_pdi_start(&is_client); - m_damaris->set_is_client(is_client); - ctx.logger().info("------------------- CALLED damaris_pdi_start Return IS_CLIENT = '{}')", is_client); - - int arg_pos = 0; - int nb_awaited_args = 1; - int transaction_data_size = expose_dataname.size(); - auto it = expose_dataname.begin(); - //Position to the first needed parameter - advance(it, (transaction_data_size - nb_awaited_args)); - //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { - //while (arg_pos < nb_awaited_args) - for (; it != expose_dataname.end(); it++) { - ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); - - if (arg_pos == 1 && strcmp("is_client", it->c_str()) == 0) - { - ctx.logger().info("------------------- CALLED damaris_pdi_start {} = '{}')", arg1_name, is_client); - - int *inout_is_client; - PDI_access(it->c_str(), (void**)&inout_is_client, PDI_INOUT); - *inout_is_client = is_client; - arg1_name = it->c_str(); - } - else - //if(nb_awaited_args <= arg_pos) - break; - } - } - - //************************************************************ */ - //Events that rely on Multi expose - //************************************************************ */ - // DAMARIS_PARAMETER_GET - else if(event_name == event_names.at(Event_type::DAMARIS_PARAMETER_GET)) { - if (!m_damaris) { - ctx.logger().warn("Trying to call damaris_parameter_get() before plugin initialization (`{}')", event_name); - return; - } - ctx.logger().info("------------------- INNNNN DAMARIS_PARAMETER_GET Event..."); - - char* var_name; std::string arg1_name = "prm_name"; - void* buffer; std::string arg2_name = "prm_buffer"; - unsigned int* size; std::string arg3_name = "prm_size"; - - va_list extra_args; - va_start(extra_args, expose_dataname); - string data_name = va_arg(extra_args, const char*); - if(!data_name.empty()) { - var_name = (char*)data_name.c_str(); - buffer = va_arg(extra_args, void*); - ctx.logger().info("------------------- INNNNN DAMARIS_PARAMETER_GET Event.. EXTRA ARGS.... AFTER buffer"); - *size = va_arg(extra_args, int); - ctx.logger().info("------------------- INNNNN DAMARIS_PARAMETER_GET Event.. EXTRA ARGS.... AFTER size..."); - - - ctx.logger().info("------------------- CALLING damaris_pdi_parameter_get arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, *(int *)buffer, arg3_name, *(int*)size); - int err = m_damaris->damaris_pdi_parameter_get((const char*)var_name, (void *) buffer, *(int*)size); - } - - } - // DAMARIS_PARAMETER_SET - else if(event_name == event_names.at(Event_type::DAMARIS_PARAMETER_SET)) { - if (!m_damaris) { - ctx.logger().warn("Trying to call damaris_parameter_set() before plugin initialization (`{}')", event_name); - return; - } - - char* var_name; std::string arg1_name = "prm_name"; - void* buffer; std::string arg2_name = "prm_buffer"; - unsigned int* size; std::string arg3_name = "prm_size"; - - va_list extra_args; - va_start(extra_args, expose_dataname); - string data_name = va_arg(extra_args, const char*); - if(!data_name.empty()) { - var_name = (char*)data_name.c_str(); - buffer = va_arg(extra_args, void*); - *size = va_arg(extra_args, size_t); - - ctx.logger().info("------------------- CALLING damaris_pdi_parameter_set arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, *(int *)buffer, arg3_name, *(int*)size); - int err = m_damaris->damaris_pdi_parameter_set((const char*)var_name, (const void *) buffer, *(int*)size); - } - } - // DAMARIS_CLIENT_COMM_GET - else if(event_name == event_names.at(Event_type::DAMARIS_CLIENT_COMM_GET)) { - - MPI_Comm client_comm; std::string arg1_name; - - int err = m_damaris->damaris_pdi_client_comm_get(&client_comm); - - int arg_pos = 0; - int nb_awaited_args = 1; - int transaction_data_size = expose_dataname.size(); - auto it = expose_dataname.begin(); - //Position to the first needed parameter - advance(it, (transaction_data_size - nb_awaited_args)); - //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { - //while (arg_pos < nb_awaited_args) - for (; it != expose_dataname.end(); it++) { - ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); - - if (arg_pos == 1) - { - static MPI_Comm* comm; - PDI_access(it->c_str(), (void**)&comm, PDI_INOUT); - *comm = client_comm;//Update the value - arg1_name = it->c_str(); - } - else - //if(nb_awaited_args <= arg_pos) - break; - } - //ctx.logger().info("------------------- CALLING damaris_pdi_client_comm_get arg_pos({}==='{}')", arg1_name, client_comm); - } - // DAMARIS_SET_POSITION - else if(event_name == event_names.at(Event_type::DAMARIS_SET_POSITION)) { - if (!m_damaris) { - ctx.logger().warn("Trying to call damaris_set_position() before plugin initialization (`{}')", event_name); - return; - } - - char* var_name; std::string arg1_name = "pos_var_name"; - int64_t* position; std::string arg2_name = "position"; - - va_list extra_args; - va_start(extra_args, expose_dataname); - string data_name = va_arg(extra_args, const char*); - if(!data_name.empty()) { - var_name = (char*)data_name.c_str(); - position = va_arg(extra_args, int64_t*); - } - else { - - //Retrive parameters! sent via Multi expose, the two last sent data - char* var_name; std::string arg1_name; - int64_t* position; std::string arg2_name; - int arg_pos = 0; - int nb_awaited_args = 2; - int transaction_data_size = expose_dataname.size(); - auto it = expose_dataname.begin(); - //Position to the first needed parameter - advance(it, (transaction_data_size - nb_awaited_args)); - //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { - //while (arg_pos < nb_awaited_args) - for (; it != expose_dataname.end(); it++) { - ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); - - if (arg_pos == 1) - { - PDI_access(it->c_str(), (void**)&var_name, PDI_IN); - arg1_name = it->c_str(); - } - else if (arg_pos == 2){ - PDI_access(it->c_str(), (void**)&position, PDI_IN); - arg2_name = it->c_str(); - } - else - //if(nb_awaited_args <= arg_pos) - break; - } - } - - ctx.logger().info("------------------- CALLING damaris_pdi_set_position arg_pos({}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, *(int64_t*)position); - int err = m_damaris->damaris_pdi_set_position((const char*)var_name, (const int64_t*)position); - } - // DAMARIS_WRITE - else if(event_name == event_names.at(Event_type::DAMARIS_WRITE)) { - if (!m_damaris) { - ctx.logger().warn("Trying to call damaris_write() before plugin initialization (`{}')", event_name); - return; - } - char* var_name; std::string arg1_name = "w_var_name"; - void* data; std::string arg2_name = "data"; - - va_list extra_args; - va_start(extra_args, expose_dataname); - //if(string data_name = va_arg(extra_args, string)) { - string data_name = va_arg(extra_args, const char*); - if(!data_name.empty()) { - var_name = (char*)data_name.c_str(); - data = va_arg(extra_args, void*);//const void* - } - else { - //Retrive parameters! sent via Multi expose, the two last sent data - char* var_name; std::string arg1_name; - void* data; std::string arg2_name; - int arg_pos = 0; - int nb_awaited_args = 2; - int transaction_data_size = expose_dataname.size(); - auto it = expose_dataname.begin(); - //Position to the first needed parameter - advance(it, (transaction_data_size - nb_awaited_args)); - //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { - //while (arg_pos < nb_awaited_args) - for (; it != expose_dataname.end(); it++) { - ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); - - if (arg_pos == 1) - { - PDI_access(it->c_str(), (void**)&var_name, PDI_IN); - arg1_name = it->c_str(); - } - else if (arg_pos == 2){ - PDI_access(it->c_str(), (void**)&data, PDI_IN); - arg2_name = it->c_str(); - } - else - //if(nb_awaited_args <= arg_pos) - break; - } - } - - ctx.logger().info("------------------- CALLING damaris_pdi_write arg_pos({}==='{}', {}==={})", arg1_name, var_name, arg2_name, *(int*)data); - int err = m_damaris->damaris_pdi_write((const char*)var_name, (void*)data); - } - // DAMARIS_SET_BLOCK_POSITION - else if(event_name == event_names.at(Event_type::DAMARIS_SET_BLOCK_POSITION)) { - if (!m_damaris) { - ctx.logger().warn("Trying to call damaris_set_position() before plugin initialization (`{}')", event_name); - return; - } - - char* var_name; std::string arg1_name = "bpos_var_name"; - int32_t* block; std::string arg2_name = "dom"; - int64_t* position; std::string arg3_name = "position"; - - va_list extra_args; - va_start(extra_args, expose_dataname); - string data_name = va_arg(extra_args, const char*); - if(!data_name.empty()) { - var_name = (char*)data_name.c_str(); - *block = va_arg(extra_args, int32_t); - position = va_arg(extra_args, int64_t*); - } - else { - //Retrive parameters! sent via Multi expose, the three last sent data - int arg_pos = 0; - int nb_awaited_args = 3; - int transaction_data_size = expose_dataname.size(); - auto it = expose_dataname.begin(); - //Position to the first needed parameter - advance(it, (transaction_data_size - nb_awaited_args)); - //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { - //while (arg_pos < nb_awaited_args) - for (; it != expose_dataname.end(); it++) { - ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); - - if (arg_pos == 1) - { - PDI_access(it->c_str(), (void**)&var_name, PDI_IN); - arg1_name = it->c_str(); - } - else if (arg_pos == 2){ - PDI_access(it->c_str(), (void**)&block, PDI_IN); - arg2_name = it->c_str(); - } - else if (arg_pos == 3){ - PDI_access(it->c_str(), (void**)&position, PDI_IN); - arg3_name = it->c_str(); - } - else - //if(nb_awaited_args <= arg_pos) - break; - } - } - - ctx.logger().info("------------------- CALLING damaris_pdi_set_block_position arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, (int32_t) *block, arg3_name, *(int64_t*)position); - int err = m_damaris->damaris_pdi_set_block_position((const char*)var_name, (int32_t) *block, (const int64_t*)position); - } - // DAMARIS_WRITE_BLOCK - else if(event_name == event_names.at(Event_type::DAMARIS_WRITE_BLOCK)) { - if (!m_damaris) { - ctx.logger().warn("Trying to call damaris_write() before plugin initialization (`{}')", event_name); - return; - } - char* var_name; std::string arg1_name = "wb_var_name"; - int32_t* block; std::string arg2_name = "dom"; - void* data; std::string arg3_name = "data"; - - va_list extra_args; - va_start(extra_args, expose_dataname); - //if(string data_name = va_arg(extra_args, string)) { - string data_name = va_arg(extra_args, const char*); - if(!data_name.empty()) { - var_name = (char*)data_name.c_str(); - *block = va_arg(extra_args, int32_t); - data = va_arg(extra_args, void*);//const void* - } - else { - //Retrive parameters! sent via Multi expose, the three last sent data - int arg_pos = 0; - int nb_awaited_args = 3; - int transaction_data_size = expose_dataname.size(); - auto it = expose_dataname.begin(); - //Position to the first needed parameter - advance(it, (transaction_data_size - nb_awaited_args)); - //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { - //while (arg_pos < nb_awaited_args) - for (; it != expose_dataname.end(); it++) { - ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); - - if (arg_pos == 1) - { - PDI_access(it->c_str(), (void**)&var_name, PDI_IN); - arg1_name = it->c_str(); - } - else if (arg_pos == 2){ - PDI_access(it->c_str(), (void**)&block, PDI_IN); - arg2_name = it->c_str(); - } - else if (arg_pos == 3){ - PDI_access(it->c_str(), (void**)&data, PDI_IN); - arg3_name = it->c_str(); - } - else - //if(nb_awaited_args <= arg_pos) - break; - } - } - - ctx.logger().info("------------------- CALLING damaris_pdi_write_block arg_pos({}==='{}', {}==='{}', {}==='{}')", arg1_name, var_name, arg2_name, (int32_t) *block, arg3_name, *(int*)data); - int err = m_damaris->damaris_pdi_write_block((const char*)var_name, (int32_t) *block, (void*)data); - } - - //************************************************************ */ - //Events : End Iteration / Damaris Stop and Damaris Finalize - //************************************************************ */ - else if (event_name == event_names.at(Event_type::DAMARIS_END_ITERATION)) { - if (m_damaris) { - - //ctx.logger().info("Plugin called damaris_end_iteration()"); - - int err = m_damaris->damaris_pdi_end_iteration() ; - //iteration++; - - ctx.logger().info("Plugin sent damaris_end_iteration() to Damaris"); - } else { - ctx.logger().warn("Trying to call damaris_end_iteration() before plugin initialization (`{}')", event_name); - } - } - else if(event_name == event_names.at(Event_type::DAMARIS_STOP)) { - // DAMARIS_STOP is called and the Daamris server processes will return from the damaris_start() call - if (!m_damaris) { - ctx.logger().warn("Trying to call damaris_strop() before plugin initialization (`{}')", event_name); - return; - } - - int err = m_damaris->damaris_pdi_stop(); - } - else if(event_name == event_names.at(Event_type::DAMARIS_FINALIZE)) { - if (!m_damaris) { - ctx.logger().warn("Trying to call damaris_strop() before plugin initialization (`{}')", event_name); - return; - } - - try { - if (m_stop_on_event.empty() && m_damaris->get_is_client()) { - ctx.logger().info("Plugin sent damaris_stop() to Damaris, in finalization"); - - //std::string stop_event_name = this->get_event_name(Event_type::DAMARIS_STOP); - //PDI_status_t status = PDI_event(stop_event_name.c_str()); - - int stop_err = m_damaris->damaris_pdi_stop(); - } - - ctx.logger().info("Plugin sent damaris_finalize() to Damaris"); - int err = m_damaris->damaris_pdi_finalize(); - if(err == DAMARIS_OK) { - ctx.logger().info("Damaris finalized successfully!"); - } - } catch (const std::exception &e) { - ctx.logger().error("Issue when finalizing Damaris: {}", e.what()); - } catch (...) { - ctx.logger().error("An issue occurred when finalizing Damaris."); - } - } - else { - assert(false && "Unexpected damaris event type"); - } -} + char* var_name; + std::string arg1_name = "prm_name"; + void* buffer; + std::string arg2_name = "prm_buffer"; + unsigned int* size; + std::string arg3_name = "prm_size"; + + va_list extra_args; + va_start(extra_args, expose_dataname); + string data_name = va_arg(extra_args, const char*); + if (!data_name.empty()) { + var_name = (char*)data_name.c_str(); + buffer = va_arg(extra_args, void*); + *size = va_arg(extra_args, size_t); + + ctx.logger().info( + "------------------- CALLING damaris_pdi_parameter_set arg_pos({}==='{}', {}==='{}', {}==='{}')", + arg1_name, + var_name, + arg2_name, + *(int*)buffer, + arg3_name, + *(int*)size + ); + int err = m_damaris->damaris_pdi_parameter_set((const char*)var_name, (const void*)buffer, *(int*)size); + } + } + // DAMARIS_CLIENT_COMM_GET + else if (event_name == event_names.at(Event_type::DAMARIS_CLIENT_COMM_GET)) + { + MPI_Comm client_comm; + std::string arg1_name; + + int err = m_damaris->damaris_pdi_client_comm_get(&client_comm); + + int arg_pos = 0; + int nb_awaited_args = 1; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) { + static MPI_Comm* comm; + PDI_access(it->c_str(), (void**)&comm, PDI_INOUT); + *comm = client_comm; //Update the value + arg1_name = it->c_str(); + } else + //if(nb_awaited_args <= arg_pos) + break; + } + //ctx.logger().info("------------------- CALLING damaris_pdi_client_comm_get arg_pos({}==='{}')", arg1_name, client_comm); + } + // DAMARIS_SET_POSITION + else if (event_name == event_names.at(Event_type::DAMARIS_SET_POSITION)) + { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_set_position() before plugin initialization (`{}')", event_name); + return; + } -void Damaris_api_call_handler::damaris_pdi_init(Context& ctx, unique_ptr &m_damaris, const char* damaris_xml_object) + char* var_name; + std::string arg1_name = "pos_var_name"; + int64_t* position; + std::string arg2_name = "position"; + + va_list extra_args; + va_start(extra_args, expose_dataname); + string data_name = va_arg(extra_args, const char*); + if (!data_name.empty()) { + var_name = (char*)data_name.c_str(); + position = va_arg(extra_args, int64_t*); + } else { + //Retrive parameters! sent via Multi expose, the two last sent data + char* var_name; + std::string arg1_name; + int64_t* position; + std::string arg2_name; + int arg_pos = 0; + int nb_awaited_args = 2; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } else if (arg_pos == 2) { + PDI_access(it->c_str(), (void**)&position, PDI_IN); + arg2_name = it->c_str(); + } else + //if(nb_awaited_args <= arg_pos) + break; + } + } + + ctx.logger().info( + "------------------- CALLING damaris_pdi_set_position arg_pos({}==='{}', {}==='{}')", + arg1_name, + var_name, + arg2_name, + *(int64_t*)position + ); + int err = m_damaris->damaris_pdi_set_position((const char*)var_name, (const int64_t*)position); + } + // DAMARIS_WRITE + else if (event_name == event_names.at(Event_type::DAMARIS_WRITE)) + { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_write() before plugin initialization (`{}')", event_name); + return; + } + char* var_name; + std::string arg1_name = "w_var_name"; + void* data; + std::string arg2_name = "data"; + + va_list extra_args; + va_start(extra_args, expose_dataname); + //if(string data_name = va_arg(extra_args, string)) { + string data_name = va_arg(extra_args, const char*); + if (!data_name.empty()) { + var_name = (char*)data_name.c_str(); + data = va_arg(extra_args, void*); //const void* + } else { + //Retrive parameters! sent via Multi expose, the two last sent data + char* var_name; + std::string arg1_name; + void* data; + std::string arg2_name; + int arg_pos = 0; + int nb_awaited_args = 2; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } else if (arg_pos == 2) { + PDI_access(it->c_str(), (void**)&data, PDI_IN); + arg2_name = it->c_str(); + } else + //if(nb_awaited_args <= arg_pos) + break; + } + } + + ctx.logger().info("------------------- CALLING damaris_pdi_write arg_pos({}==='{}', {}==={})", arg1_name, var_name, arg2_name, *(int*)data); + int err = m_damaris->damaris_pdi_write((const char*)var_name, (void*)data); + } + // DAMARIS_SET_BLOCK_POSITION + else if (event_name == event_names.at(Event_type::DAMARIS_SET_BLOCK_POSITION)) + { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_set_position() before plugin initialization (`{}')", event_name); + return; + } + + char* var_name; + std::string arg1_name = "bpos_var_name"; + int32_t* block; + std::string arg2_name = "dom"; + int64_t* position; + std::string arg3_name = "position"; + + va_list extra_args; + va_start(extra_args, expose_dataname); + string data_name = va_arg(extra_args, const char*); + if (!data_name.empty()) { + var_name = (char*)data_name.c_str(); + *block = va_arg(extra_args, int32_t); + position = va_arg(extra_args, int64_t*); + } else { + //Retrive parameters! sent via Multi expose, the three last sent data + int arg_pos = 0; + int nb_awaited_args = 3; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } else if (arg_pos == 2) { + PDI_access(it->c_str(), (void**)&block, PDI_IN); + arg2_name = it->c_str(); + } else if (arg_pos == 3) { + PDI_access(it->c_str(), (void**)&position, PDI_IN); + arg3_name = it->c_str(); + } else + //if(nb_awaited_args <= arg_pos) + break; + } + } + + ctx.logger().info( + "------------------- CALLING damaris_pdi_set_block_position arg_pos({}==='{}', {}==='{}', {}==='{}')", + arg1_name, + var_name, + arg2_name, + (int32_t)*block, + arg3_name, + *(int64_t*)position + ); + int err = m_damaris->damaris_pdi_set_block_position((const char*)var_name, (int32_t)*block, (const int64_t*)position); + } + // DAMARIS_WRITE_BLOCK + else if (event_name == event_names.at(Event_type::DAMARIS_WRITE_BLOCK)) + { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_write() before plugin initialization (`{}')", event_name); + return; + } + char* var_name; + std::string arg1_name = "wb_var_name"; + int32_t* block; + std::string arg2_name = "dom"; + void* data; + std::string arg3_name = "data"; + + va_list extra_args; + va_start(extra_args, expose_dataname); + //if(string data_name = va_arg(extra_args, string)) { + string data_name = va_arg(extra_args, const char*); + if (!data_name.empty()) { + var_name = (char*)data_name.c_str(); + *block = va_arg(extra_args, int32_t); + data = va_arg(extra_args, void*); //const void* + } else { + //Retrive parameters! sent via Multi expose, the three last sent data + int arg_pos = 0; + int nb_awaited_args = 3; + int transaction_data_size = expose_dataname.size(); + auto it = expose_dataname.begin(); + //Position to the first needed parameter + advance(it, (transaction_data_size - nb_awaited_args)); + //for (auto it = expose_dataname.rbegin(); it != expose_dataname.rend(); ++it) { + //while (arg_pos < nb_awaited_args) + for (; it != expose_dataname.end(); it++) { + ctx.logger().info("Multi expose: Reclaiming `{}' ({}/{})", it->c_str(), ++arg_pos, expose_dataname.size()); + + if (arg_pos == 1) { + PDI_access(it->c_str(), (void**)&var_name, PDI_IN); + arg1_name = it->c_str(); + } else if (arg_pos == 2) { + PDI_access(it->c_str(), (void**)&block, PDI_IN); + arg2_name = it->c_str(); + } else if (arg_pos == 3) { + PDI_access(it->c_str(), (void**)&data, PDI_IN); + arg3_name = it->c_str(); + } else + //if(nb_awaited_args <= arg_pos) + break; + } + } + + ctx.logger().info( + "------------------- CALLING damaris_pdi_write_block arg_pos({}==='{}', {}==='{}', {}==='{}')", + arg1_name, + var_name, + arg2_name, + (int32_t)*block, + arg3_name, + *(int*)data + ); + int err = m_damaris->damaris_pdi_write_block((const char*)var_name, (int32_t)*block, (void*)data); + } + + //************************************************************ */ + //Events : End Iteration / Damaris Stop and Damaris Finalize + //************************************************************ */ + else if (event_name == event_names.at(Event_type::DAMARIS_END_ITERATION)) + { + if (m_damaris) { + //ctx.logger().info("Plugin called damaris_end_iteration()"); + + int err = m_damaris->damaris_pdi_end_iteration(); + //iteration++; + + ctx.logger().info("Plugin sent damaris_end_iteration() to Damaris"); + } else { + ctx.logger().warn("Trying to call damaris_end_iteration() before plugin initialization (`{}')", event_name); + } + } else if (event_name == event_names.at(Event_type::DAMARIS_STOP)) { + // DAMARIS_STOP is called and the Daamris server processes will return from the damaris_start() call + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_strop() before plugin initialization (`{}')", event_name); + return; + } + + int err = m_damaris->damaris_pdi_stop(); + } else if (event_name == event_names.at(Event_type::DAMARIS_FINALIZE)) { + if (!m_damaris) { + ctx.logger().warn("Trying to call damaris_strop() before plugin initialization (`{}')", event_name); + return; + } + + try { + if (m_stop_on_event.empty() && m_damaris->get_is_client()) { + ctx.logger().info("Plugin sent damaris_stop() to Damaris, in finalization"); + + //std::string stop_event_name = this->get_event_name(Event_type::DAMARIS_STOP); + //PDI_status_t status = PDI_event(stop_event_name.c_str()); + + int stop_err = m_damaris->damaris_pdi_stop(); + } + + ctx.logger().info("Plugin sent damaris_finalize() to Damaris"); + int err = m_damaris->damaris_pdi_finalize(); + if (err == DAMARIS_OK) { + ctx.logger().info("Damaris finalized successfully!"); + } + } catch (const std::exception& e) { + ctx.logger().error("Issue when finalizing Damaris: {}", e.what()); + } catch (...) { + ctx.logger().error("An issue occurred when finalizing Damaris."); + } + } else { + assert(false && "Unexpected damaris event type"); + } +} + +void Damaris_api_call_handler::damaris_pdi_init(Context& ctx, unique_ptr& m_damaris, const char* damaris_xml_object) { - if (!m_damaris) { - MPI_Comm comm = MPI_COMM_WORLD; - if (m_communicator) { + if (!m_damaris) { + MPI_Comm comm = MPI_COMM_WORLD; + if (m_communicator) { //comm = static_cast(m_communicator.to_string(ctx)); - //comm = *(static_cast(Ref_r{m_communicator.to_ref(ctx)}.get())); - } - - // This creator method calls damaris_initialize(), passin in an XML file, so if we want to - // pre-fill our xml file, we need to do this somehow before: - // PDI_expose("mpi_comm", &main_comm, PDI_INOUT); - - m_damaris.reset(new Damaris_wrapper{ctx, damaris_xml_object, comm}); - - ctx.logger().info("Plugin initialized successfully"); - } + //comm = *(static_cast(Ref_r{m_communicator.to_ref(ctx)}.get())); + } + + // This creator method calls damaris_initialize(), passin in an XML file, so if we want to + // pre-fill our xml file, we need to do this somehow before: + // PDI_expose("mpi_comm", &main_comm, PDI_INOUT); + + m_damaris.reset(new Damaris_wrapper{ctx, damaris_xml_object, comm}); + + ctx.logger().info("Plugin initialized successfully"); + } } } // namespace damaris_pdi diff --git a/plugins/damaris/damaris_cfg.cxx b/plugins/damaris/damaris_cfg.cxx index 08a8fd63b..74cc68fa9 100644 --- a/plugins/damaris/damaris_cfg.cxx +++ b/plugins/damaris/damaris_cfg.cxx @@ -23,1359 +23,1172 @@ * THE SOFTWARE. ******************************************************************************/ - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #include "damaris_cfg.h" - - using PDI::Context; - using PDI::each; - using PDI::opt_each; - using PDI::Config_error; - using PDI::Value_error; - using PDI::Expression; - using PDI::Impl_error; - using PDI::Ref; - using PDI::Ref_w; - using PDI::Ref_r; - using PDI::len; - using PDI::to_long; - using PDI::to_double; - using PDI::to_string; - using std::function; - using std::list; - using std::map; - using std::string; - using std::unique_ptr; - using std::unordered_map; - - - - namespace damaris_pdi { - - namespace { - - bool load_desc(unordered_map& descs, Context& ctx, const string& name, Desc_type desc_type) - { - auto&& result = descs.emplace(name, desc_type); - if (!result.second) { - //ctx.logger().warn("Duplicate use of a descriptor `{}' in `{}' (previously used in `{}')", name, desc_names.at(desc_type), desc_names.at(result.first->second)); - } - return result.second; - } - - bool load_event(unordered_map& events, Context& ctx, const string& name, Event_type event_type) - { - auto&& result = events.emplace(name, event_type); - if (!result.second) { - //ctx.logger().warn("Duplicate use of a descriptor `{}' in `{}' (previously used in `{}')", name, desc_names.at(desc_type), desc_names.at(result.first->second)); - } - return result.second; - } - - } // namespace - - /** +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "damaris_cfg.h" + +using PDI::Config_error; +using PDI::Context; +using PDI::each; +using PDI::Expression; +using PDI::Impl_error; +using PDI::len; +using PDI::opt_each; +using PDI::Ref; +using PDI::Ref_r; +using PDI::Ref_w; +using PDI::to_double; +using PDI::to_long; +using PDI::to_string; +using PDI::Value_error; +using std::function; +using std::list; +using std::map; +using std::string; +using std::unique_ptr; +using std::unordered_map; + +namespace damaris_pdi { + +namespace { + +bool load_desc(unordered_map& descs, Context& ctx, const string& name, Desc_type desc_type) +{ + auto&& result = descs.emplace(name, desc_type); + if (!result.second) { + //ctx.logger().warn("Duplicate use of a descriptor `{}' in `{}' (previously used in `{}')", name, desc_names.at(desc_type), desc_names.at(result.first->second)); + } + return result.second; +} + +bool load_event(unordered_map& events, Context& ctx, const string& name, Event_type event_type) +{ + auto&& result = events.emplace(name, event_type); + if (!result.second) { + //ctx.logger().warn("Duplicate use of a descriptor `{}' in `{}' (previously used in `{}')", name, desc_names.at(desc_type), desc_names.at(result.first->second)); + } + return result.second; +} + +} // namespace + +/** * This variable contains Damaris xml config nested groups, with dataset elements to display in the XML config * It is possible to have nested groups, but in most of the cases, * we just have root groups containing directly the dataset elements */ - std::vector root_groups_xml; - - // Array to store the nested groups names - const unsigned max_nested_groups = 5; - std::string nested_groups_names[max_nested_groups]; - char ds_elt_full_name_delimiter = '/'; - - void retrive_nested_groups(std::string& dataset_elt_full_name, char delimiter, std::string nested_groups_names[], unsigned& index); - template - void insert_dataset_elts_to_group(DS_TYPE varxml, std::string nested_groups_names[], unsigned index); - //void insert_dataset_elts_to_group(damaris::model::DamarisVarXML varxml, std::string nested_groups_names[], unsigned index); - - std::string numbers_types[] = {"short", "int", "integer", "float", "real", "double"}; - std::string int_numbers_types[3] = {"short", "int", "integer"}; - std::string real_numbers_types[3] = {"float", "real", "double"}; - - // This constructor is called on the construction of the damaris_plugin struct/object - // This code is a mapping of the Damaris src/model/Model.xsd schema to PDI YAML - // The mapping should allow us to recreate a Damaris XML object from what is present - // in the YML file - Damaris_cfg::Damaris_cfg(Context& ctx, PC_tree_t tree) - :m_communicator{"MPI_COMM_WORLD"} - { - init_xml_config_object(); - - each(tree, [&](PC_tree_t key_tree, PC_tree_t value) { - string key = to_string(key_tree); - if (key == "architecture") { - //default_when = to_string(value); - parse_architecture_tree(ctx, value); - } - else if (key == "communicator") { - - m_communicator = to_string(value); - if (!m_communicator) { - throw Config_error{key_tree, "no MPI communicator set", key}; - } - } - else if (key == "init_on_event" || key == "on_init") { - m_init_on_event = to_string(value); - load_event(m_events, ctx, m_init_on_event, Event_type::DAMARIS_INITIALIZE); - } - else if (key == "finalize_on_event" || key == "on_finalize") { - m_finalize_on_event = to_string(value); - load_event(m_events, ctx, m_finalize_on_event, Event_type::DAMARIS_FINALIZE); - } - else if (key == "start_on_event") { - m_start_on_event = to_string(value); - load_event(m_events, ctx, m_start_on_event, Event_type::DAMARIS_START); - } - else if (key == "stop_on_event") { - m_stop_on_event = to_string(value); - load_event(m_events, ctx, m_stop_on_event, Event_type::DAMARIS_STOP); - } - else if (key == "end_iteration_on_event") { - m_end_iteration_on_event = to_string(value); - load_event(m_events, ctx, m_end_iteration_on_event, Event_type::DAMARIS_END_ITERATION); - } - else if (key == "parameters") { - parse_parameters_tree(ctx, value); - } - else if (key == "datasets") { - parse_datasets_tree(ctx, value); - } - else if (key == "layouts") { - parse_layouts_tree(ctx, value); - } - else if (key == "meshes") { - parse_meshes_tree(ctx, value); - } - else if (key == "storages") { - parse_storages_tree(ctx, value); - } - else if (key == "paraview") { - parse_paraview_tree(ctx, value); - } - else if (key == "pyscript") { - parse_pyscript_tree(ctx, value); - } - - else if (key == "write") { - parse_write_tree(ctx, value); - } - - else if (key == "parameter_get") { - parse_parameter_to_update_tree(ctx, value, Desc_type::PRM_TO_GET); - } - - else if (key == "parameter_set") { - parse_parameter_to_update_tree(ctx, value, Desc_type::PRM_TO_SET); - } - - else if (key == "after_write") { - if(!PC_status(value)) - { - if (!PC_status(PC_get(value, "[0]"))) {//Array [ev0,ev1,ev3] - each(value, [&](PC_tree_t event_name) { - m_after_write_events.emplace_back(to_string(event_name)); - }); - } - else {//ev0 - m_after_write_events.emplace_back(to_string(value)); - } - } - } - - else if (key == "start" || key == "get_is_client" || key == "is_client_get") { - if(!PC_status(value)) - { - m_is_client_dataset_name = to_string(value); - load_desc(m_descs, ctx, m_is_client_dataset_name, Desc_type::IS_CLIENT_GET); - } - } - - else if (key == "client_comm_get") { - if(!PC_status(value)) - { - m_client_comm_get_dataset_name = to_string(value); - load_desc(m_descs, ctx, m_client_comm_get_dataset_name, Desc_type::CLIENT_COMM_GET); - } - } - /*else { +std::vector root_groups_xml; + +// Array to store the nested groups names +const unsigned max_nested_groups = 5; +std::string nested_groups_names[max_nested_groups]; +char ds_elt_full_name_delimiter = '/'; + +void retrive_nested_groups(std::string& dataset_elt_full_name, char delimiter, std::string nested_groups_names[], unsigned& index); +template +void insert_dataset_elts_to_group(DS_TYPE varxml, std::string nested_groups_names[], unsigned index); +//void insert_dataset_elts_to_group(damaris::model::DamarisVarXML varxml, std::string nested_groups_names[], unsigned index); + +std::string numbers_types[] = {"short", "int", "integer", "float", "real", "double"}; +std::string int_numbers_types[3] = {"short", "int", "integer"}; +std::string real_numbers_types[3] = {"float", "real", "double"}; + +// This constructor is called on the construction of the damaris_plugin struct/object +// This code is a mapping of the Damaris src/model/Model.xsd schema to PDI YAML +// The mapping should allow us to recreate a Damaris XML object from what is present +// in the YML file +Damaris_cfg::Damaris_cfg(Context& ctx, PC_tree_t tree) + : m_communicator{"MPI_COMM_WORLD"} +{ + m_is_client_dataset_name = ""; + init_xml_config_object(); + + each(tree, [&](PC_tree_t key_tree, PC_tree_t value) { + string key = to_string(key_tree); + if (key == "architecture") { + //default_when = to_string(value); + parse_architecture_tree(ctx, value); + } else if (key == "communicator") { + m_communicator = to_string(value); + if (!m_communicator) { + throw Config_error{key_tree, "no MPI communicator setted", key}; + } + } else if (key == "init_on_event" || key == "on_init") { + m_init_on_event = to_string(value); + load_event(m_events, ctx, m_init_on_event, Event_type::DAMARIS_INITIALIZE); + } else if (key == "finalize_on_event" || key == "on_finalize") { + m_finalize_on_event = to_string(value); + load_event(m_events, ctx, m_finalize_on_event, Event_type::DAMARIS_FINALIZE); + } else if (key == "start_on_event") { + m_start_on_event = to_string(value); + load_event(m_events, ctx, m_start_on_event, Event_type::DAMARIS_START); + } else if (key == "stop_on_event") { + m_stop_on_event = to_string(value); + load_event(m_events, ctx, m_stop_on_event, Event_type::DAMARIS_STOP); + } else if (key == "end_iteration_on_event") { + m_end_iteration_on_event = to_string(value); + load_event(m_events, ctx, m_end_iteration_on_event, Event_type::DAMARIS_END_ITERATION); + } else if (key == "parameters") { + parse_parameters_tree(ctx, value); + } else if (key == "datasets") { + parse_datasets_tree(ctx, value); + } else if (key == "layouts") { + parse_layouts_tree(ctx, value); + } else if (key == "meshes") { + parse_meshes_tree(ctx, value); + } else if (key == "storages") { + parse_storages_tree(ctx, value); + } else if (key == "paraview") { + parse_paraview_tree(ctx, value); + } else if (key == "pyscript") { + parse_pyscript_tree(ctx, value); + } + + else if (key == "write") + { + parse_write_tree(ctx, value); + } + + else if (key == "parameter_get") + { + parse_parameter_to_update_tree(ctx, value, Desc_type::PRM_TO_GET); + } + + else if (key == "parameter_set") + { + parse_parameter_to_update_tree(ctx, value, Desc_type::PRM_TO_SET); + } + + else if (key == "after_write") + { + if (!PC_status(value)) { + if (!PC_status(PC_get(value, "[0]"))) { //Array [ev0,ev1,ev3] + each(value, [&](PC_tree_t event_name) { m_after_write_events.emplace_back(to_string(event_name)); }); + } else { //ev0 + m_after_write_events.emplace_back(to_string(value)); + } + } + } + + else if (key == "start" || key == "get_is_client" || key == "is_client_get") + { + if (!PC_status(value)) { + m_is_client_dataset_name = to_string(value); + load_desc(m_descs, ctx, m_is_client_dataset_name, Desc_type::IS_CLIENT_GET); + } + } + + else if (key == "client_comm_get") + { + if (!PC_status(value)) { + m_client_comm_get_dataset_name = to_string(value); + load_desc(m_descs, ctx, m_client_comm_get_dataset_name, Desc_type::CLIENT_COMM_GET); + } + } + /*else { throw Config_error{key_tree, "Unknown key in Damaris configuration: `{}'", key}; }*/ - }); + }); - std::string end_it_event_name = event_names.at(Event_type::DAMARIS_END_ITERATION); - //Add only if it does not exist yet - if(std::find(m_after_write_events.begin(), m_after_write_events.end(), end_it_event_name) == m_after_write_events.end() - && m_end_iteration_on_event.empty()){ - m_after_write_events.emplace_back(end_it_event_name); - } - - parse_log_tree(ctx, tree); - - //Insert grouped dataset elements - for (int root_group_id = 0; root_group_id < root_groups_xml.size(); root_group_id++) { - damaris::model::DamarisGroupXML root_gp_xml = root_groups_xml[root_group_id]; - - m_groups.emplace(root_gp_xml.get_name() , root_gp_xml) ; - std::map find_replace_map = - { - {"_DATASET_ELEMENT_REGEX_", root_gp_xml.ReturnXMLForGroup() + "\n_DATASET_ELEMENT_REGEX_"} - }; - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - } - - //CleanUp XML OBJECT - std::map find_replace_map = - { - {"_DATASET_ELEMENT_REGEX_", ""} - ,{"_STORAGE_ELEMENT_REGEX_", ""} - ,{"_PLUGINS_REGEX_", ""} - ,{"_SCRIPTS_REGEX_", ""} - }; - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - - m_xml_config_object = damarisXMLModifyModel.GetConfigString(); - - //printf("-------------------------------------------------------XML OBJECT MODIFIED----------------------------------------------\n%s", damarisXMLModifyModel.GetConfigString().c_str()); - //exit(0); - } - - void Damaris_cfg::parse_architecture_tree(Context& ctx, PC_tree_t arch_tree){ - - std::map find_replace_map = {}; - - //simulation name & Buffer - std::string sim_name = "damaris_pdi_simu"; - PC_tree_t sim_name_tree = PC_get(arch_tree, ".sim_name"); - if(!PC_status(sim_name_tree)) - { - sim_name = to_string(sim_name_tree); - } - //Buffer - std::string buffer_name = sim_name + "_buffer"; - long buffer_size = 67108864; - PC_tree_t buffer_size_tree = PC_get(arch_tree, ".buffer_size"); - if(!PC_status(buffer_size_tree)) - { - buffer_size = to_long(buffer_size_tree); - } - find_replace_map.insert({ - {"_SIM_NAME_",sim_name} - ,{"_SHMEM_BUFFER_BYTES_REGEX_", std::to_string(buffer_size)} - ,{"_SHMEM_NAME_", buffer_name} - }); - - //domains - int m_arch_domains = 1; - PC_tree_t domains_tree = PC_get(arch_tree, ".domains"); - if(!PC_status(domains_tree)) - { - m_arch_domains = to_long(domains_tree); - } - find_replace_map.insert({"_DOMAINS_REGEX_", std::to_string(m_arch_domains)}); - - //dedicated - int m_dc_cores_pernode = 0; - int m_dc_nodes = 0; - PC_tree_t arch_dedicated_tree = PC_get(arch_tree, ".dedicated"); - if(!PC_status(arch_dedicated_tree)) - { - int nb_subkey_dc = len(arch_dedicated_tree); - - for (int subkey_dc_id = 0; subkey_dc_id < nb_subkey_dc; subkey_dc_id++) { - string key_str = to_string(PC_get(arch_dedicated_tree, "{%d}", subkey_dc_id)); - - if (key_str == "core") { - m_dc_cores_pernode = to_long(PC_get(arch_dedicated_tree, ".core")); - } else if (key_str == "node") { - m_dc_nodes = to_long(PC_get(arch_dedicated_tree, ".node")); - } - } - } - find_replace_map.insert( - { - {"_DC_REGEX_", std::to_string(m_dc_cores_pernode)} - ,{"_DN_REGEX_", std::to_string(m_dc_nodes)} - } - ); - - //placement not yet used - PC_tree_t arch_placement_tree = PC_get(arch_tree, ".placement"); - if(!PC_status(arch_placement_tree)) - { - int nb_subkey_dc = len(arch_placement_tree); - - for (int subkey_pl_id = 0; subkey_pl_id < nb_subkey_dc; subkey_pl_id++) { - string key_str = to_string(PC_get(arch_placement_tree, "{%d}", subkey_pl_id)); - - if (key_str == "start") { - m_placement_start = to_long(PC_get(arch_placement_tree, ".start")); - } - else if (key_str == "stride") { - m_placement_stride = to_long(PC_get(arch_placement_tree, ".stride")); - } - else if (key_str == "blocksize") { - m_placement_blocksize = to_long(PC_get(arch_placement_tree, ".blocksize")); - } - else if (key_str == "mask") { - m_placement_mask_str = to_string(PC_get(arch_placement_tree, ".mask")); - } - } - //TODO: find_replace_map.insert( ); - } - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - } - - void Damaris_cfg::parse_parameters_tree(Context& ctx, PC_tree_t parameters_tree_list) - { - opt_each(parameters_tree_list, [&](PC_tree_t parameters_tree) {//each parameters (list of parameter) - each(parameters_tree, [&](PC_tree_t prm_tree_key, PC_tree_t parameter_tree) {//each parameter - - damaris::model::DamarisParameterXML prmxml{} ; - std::map find_replace_map = {}; - std::unordered_map depends_on_metadata; - bool is_dependent = false; - - each(parameter_tree, [&](PC_tree_t prm_key, PC_tree_t value) {//parameter info - std::string key = to_string(prm_key); - - if (key == "name") { - prmxml.param_name_ = to_string(value); - } - else if (key == "type") { - prmxml.param_datatype_ = to_string(value); - } - else if (key == "value") { - prmxml.param_value_ = to_string(value); - m_parameter_expression.emplace(prmxml.param_name_, to_string(value)); - } - else if (key == "depends_on") { - is_dependent = true; - if (!PC_status(PC_get(value, "[0]"))) {//Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter - //int idx = 0; - each(value, [&](PC_tree_t metadata_name_tree) { - std::string metadata_name = to_string(metadata_name_tree); - - depends_on_metadata.insert( - {metadata_name, false} - ); - - load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); - }); - } - else {//d1 - std::string metadata_name = to_string(value); - //depends_on_metadata[metadata_name] = false; - depends_on_metadata.insert( - {metadata_name, false} - ); - - load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); - //ctx.logger().info("--------------------------------------------------------------------------------PARAMETER {} depends on {}", prmxml.param_name_, metadata_name); - } - - - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized parameter map string: " << key << std::endl ; - } - }); - //m_parameter_expression.emplace(prmxml.param_name_, prmxml.param_value_); - m_parameter_depends_on.emplace(prmxml.param_name_, depends_on_metadata); - //set default value if depend on metadata - if(is_dependent && std::find(std::begin(numbers_types), std::end(numbers_types), prmxml.param_datatype_) != std::end(numbers_types)) { - if(std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prmxml.param_datatype_) != std::end(int_numbers_types)) - prmxml.param_value_ = "1"; //"0" - else - prmxml.param_value_ = "1.0"; //"0" - } - else { - ///??? - } - - m_parameters.emplace(prmxml.param_name_ , prmxml) ; - find_replace_map.insert( - {"_DATASET_ELEMENT_REGEX_", prmxml.ReturnXMLForParameter() + "\n_DATASET_ELEMENT_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - }); - }); - } - - void Damaris_cfg::parse_datasets_tree(Context& ctx, PC_tree_t datasets_tree_list) - { - opt_each(datasets_tree_list, [&](PC_tree_t datasets_tree) {//each datasets (list of dataset) - each(datasets_tree, [&](PC_tree_t ds_tree_key, PC_tree_t dataset_tree) {//each dataset - - damaris::model::DamarisVarXML vxml{} ; - std::map find_replace_map = {}; - unsigned name_index = 0; - std::string dataset_elt_full_name; - - each(dataset_tree, [&](PC_tree_t ds_key, PC_tree_t value) {//dataset info - std::string key = to_string(ds_key); - - int tf; // 0 is false, anything else is true - if (key == "name") { - dataset_elt_full_name = to_string(value); - retrive_nested_groups(dataset_elt_full_name - , ds_elt_full_name_delimiter - , nested_groups_names - , name_index); - - vxml.var_name_ = nested_groups_names[name_index-1]; //to_string(value); - } - else if (key == "layout") { - vxml.layout_name_ = to_string(value); - } - else if (key == "mesh") { - vxml.mesh_ = to_string(value); - } - else if (key == "centering") { - std::string t_centering = to_string(value); - vxml.set_centering(t_centering) ; - } - else if (key == "storage") { - vxml.store_ = to_string(value); - } - else if (key == "script") { - vxml.script_ = to_string(value); - } - else if (key == "unit") { - vxml.unit_ = to_string(value); - } - else if (key == "select_mem") { - vxml.select_mem_ = to_string(value); - } - else if (key == "select_file") { - vxml.select_file_ = to_string(value); - } - else if (key == "select_subset") { - vxml.select_subset_ = to_string(value); - } - else if (key == "ref") { - vxml.ref_ = to_string(value); - } - else if (key == "type") { - std::string in_type = to_string(value); - vxml.set_type( in_type ); - } - else if (key == "comment") { - vxml.comment_ = to_string(value); - } - else if (key == "visualizable") { - PC_bool(value, &tf); - vxml.visualizable_ = (tf == 0) ? false : true ; - } - else if (key == "time_varying") { - PC_bool(value, &tf); - vxml.time_varying_ = (tf == 0) ? false : true ; - } - else if (key == "enabled") { - PC_bool(value, &tf); - vxml.enabled_ = (tf == 0) ? false : true ; - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized variable map string: " << key << std::endl ; - } - }); - - if(dataset_elt_full_name.empty()) - throw Value_error{"ERROR: damaris_cfg variable name must not be empty"}; - - //m_datasets.emplace(vxml.var_name_ , vxml) ; - m_datasets.emplace(dataset_elt_full_name , vxml) ; - //ctx.logger().info("------------------- Parsing damaris Variable '{}' , name_index = {} ", dataset_elt_full_name, name_index); - - if(name_index == 1) { - find_replace_map.insert( - {"_DATASET_ELEMENT_REGEX_", vxml.ReturnXMLForVariable() + "\n_DATASET_ELEMENT_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - } - else {//In nested groups - insert_dataset_elts_to_group(vxml, nested_groups_names, name_index); - } - }); - }); - } - - void Damaris_cfg::parse_layouts_tree(Context& ctx, PC_tree_t layouts_tree_list) - { - opt_each(layouts_tree_list, [&](PC_tree_t layouts_tree) {//each layouts (list of layout) - each(layouts_tree, [&](PC_tree_t lts_key, PC_tree_t layout_tree) {//each layout - - damaris::model::DamarisLayoutXML layoutxml{} ; - std::map find_replace_map = {}; - unsigned name_index = 0; - std::string dataset_elt_full_name; - std::unordered_map depends_on_metadata; - bool is_dependent = false; - std::string depends_on_str = ""; - std::string in_datatype; - int nb_dims; - - each(layout_tree, [&](PC_tree_t lt_key, PC_tree_t value) {//layout info - std::string key = to_string(lt_key); - - int intb; // 0 is false, anything else is true - if (key == "name") { - dataset_elt_full_name = to_string(value); - retrive_nested_groups(dataset_elt_full_name - , ds_elt_full_name_delimiter - , nested_groups_names - , name_index); - - layoutxml.layout_name_ = nested_groups_names[name_index-1]; //to_string(value); - } - else if (key == "type") { - in_datatype = to_string(value); - layoutxml.set_datatype( in_datatype ); - } - else if (key == "dimensions") { - - //Is there a way to determine if an expression is ready to be evaluated? ei, all the conponent have a value - if (!PC_status(PC_get(value, "[0]"))) {//Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter - int nb_layout_dims2; PC_len(value, &nb_layout_dims2); - //std::cout << "INFO: damaris_cfg nb_layout_dims has dims2: " << nb_layout_dims2 << std::endl ; - - std::string dims_list = ""; - each(value, [&](PC_tree_t dim) { - dims_list += to_string(dim) + ","; - }); - dims_list.pop_back(); - layoutxml.layout_dimensions_ = dims_list; - } - else {//"d1,d2,d3" for instance, each di an expreession of of Damaris Parameter - layoutxml.layout_dimensions_ = to_string(value); - } - - nb_dims = count(layoutxml.layout_dimensions_.begin(),layoutxml.layout_dimensions_.end(),',') + 1; - } - else if (key == "global") { - //Is there a way to determine if an expression is ready to be evaluated? ei, all the conponent have a value - if (!PC_status(PC_get(value, "[0]"))) {//Array //[dg1,dg2,dg3] for instance, each di an expreession of of Damaris Parameter - - std::string dims_global_list = ""; - each(value, [&](PC_tree_t dim) { - dims_global_list += to_string(dim) + ","; - }); - dims_global_list.pop_back(); - layoutxml.layout_dims_global_ = dims_global_list; - } - else {//"dg1,dg2,dg3" for instance, each di an expreession of of Damaris Parameter - layoutxml.layout_dims_global_ = to_string(value); - } - } - else if (key == "ghosts") { - //Is there a way to determine if an expression is ready to be evaluated? ei, all the conponent have a value - if (!PC_status(PC_get(value, "[0]"))) {//Array //['g11:g12','g21:g22','g31:g32'] for instance, each di an expreession of of Damaris Parameter - - std::string ghosts_list = ""; - each(value, [&](PC_tree_t dim) { - ghosts_list += to_string(dim) + ","; - }); - ghosts_list.pop_back(); - layoutxml.layout_ghosts_ = ghosts_list; - } - else {//"g11:g12,g21:g22,g31:g32" for instance, each di an expreession of of Damaris Parameter - layoutxml.layout_ghosts_ = to_string(value); - } - } - else if (key == "language") { - std::string in_language = to_string(value); - layoutxml.set_language( in_language ); - } - else if (key == "visualizable") { - PC_bool(value, &intb); - bool in_visualizable = (intb == 0) ? false : true ; - layoutxml.layout_visualizable_ = in_visualizable; - } - else if (key == "comment") { - layoutxml.layout_comment_ = to_string(value); - } - else if (key == "depends_on") { - is_dependent = true; - if (!PC_status(PC_get(value, "[0]"))) {//Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter - //int idx = 0; - each(value, [&](PC_tree_t metadata_name_tree) { - std::string metadata_name = to_string(metadata_name_tree); - depends_on_str += metadata_name+", "; - - depends_on_metadata.insert( - {metadata_name, false} - ); - - //load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); - }); - depends_on_str.pop_back();//' ' - depends_on_str.pop_back();//',' - } - else {//d1 - std::string metadata_name = to_string(value); - depends_on_str = metadata_name; - //depends_on_metadata[metadata_name] = false; - depends_on_metadata.insert( - {metadata_name, false} - ); - - //load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); - } - depends_on_str = "["+depends_on_str+"]"; - - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized layout map string: " << key << std::endl ; - } - }); - m_layout_depends_on.emplace(layoutxml.layout_name_, depends_on_metadata); - //set default value if depend on metadata - //if(is_dependent && std::find(std::begin(numbers_types), std::end(numbers_types), in_datatype)) { - if(is_dependent) { - std::stringstream ss_dims(layoutxml.layout_dimensions_), ss_globals(layoutxml.layout_dims_global_); - std::string tmp; - std::vector dim_list, global_list; - - while (std::getline(ss_dims, tmp, ',')) { - dim_list.push_back(tmp); - } - while (std::getline(ss_globals, tmp, ',')) { - global_list.push_back(tmp); - } - - //ctx.logger().info("------------------- OLD layoutxml.layout_dimensions_ '{}' | layoutxml.layout_dims_global_ '{}'", layoutxml.layout_dimensions_, layoutxml.layout_dims_global_); - - //ctx.logger().info("------------------- dim_list[0] = '{}' | global_list[0] = '{}'", dim_list[0], global_list[0]); - - std::string prm_config_yaml - = "";//"parameters: \n"; - - layoutxml.layout_dimensions_ = ""; - std::string new_globals = ""; - //TODO: get the type of the metadata to which the layout depends, to apply it to the parameters - std::string metadatatype = "int"; - - for (int i = 0; i < nb_dims; i++) - { - string dim_name = layoutxml.layout_name_+"_dim"+std::to_string(i); - prm_config_yaml += "- parameter: \n"; - prm_config_yaml += " name: "+dim_name+" \n"; - prm_config_yaml += " type: "+metadatatype+" \n"; - prm_config_yaml += " value: '"+dim_list[i]+"' \n"; - prm_config_yaml += " depends_on: "+depends_on_str+" \n"; - - layoutxml.layout_dimensions_ += dim_name+","; - - if(layoutxml.layout_dims_global_.length() > 1) { - string global_name = layoutxml.layout_name_+"_global"+std::to_string(i); - prm_config_yaml += "- parameter: \n"; - prm_config_yaml += " name: "+global_name+" \n"; - prm_config_yaml += " type: "+metadatatype+" \n"; - prm_config_yaml += " value: '"+global_list[i]+"' \n"; - prm_config_yaml += " depends_on: "+depends_on_str+" \n"; - - new_globals += global_name+","; - } - } - layoutxml.layout_dimensions_.pop_back(); - //the layout_dims_global_ attribute being optional with default value '#', we need to ensure it has been set before modification. - //if(layoutxml.layout_dims_global_ != '#') { - if(layoutxml.layout_dims_global_.length() > 1) { - new_globals.pop_back(); - layoutxml.layout_dims_global_ = new_globals; - } - - //Background creation of parameter - PC_tree_t parameters_conf = PC_parse_string(prm_config_yaml.c_str()); - //ctx.logger().info("------------------- parameters_conf = \n '{}'", prm_config_yaml); - parse_parameters_tree(ctx, parameters_conf); - } - else { - ///??? - } - - if(dataset_elt_full_name.empty()) - throw Value_error{"ERROR: damaris_cfg layout name must not be empty"}; - - //m_layouts.emplace(layoutxml.layout_name_ , layoutxml) ; - m_layouts.emplace(dataset_elt_full_name , layoutxml) ; - //ctx.logger().info("------------------- Parsing damaris Layout '{}' , name_index = {} ", dataset_elt_full_name, name_index); - - if(name_index == 1) { - find_replace_map.insert( - {"_DATASET_ELEMENT_REGEX_", layoutxml.ReturnXMLForLayout() + "\n_DATASET_ELEMENT_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - } - else {//In nested groups - insert_dataset_elts_to_group(layoutxml, nested_groups_names, name_index); - } - }); - }); - } - - void Damaris_cfg::parse_meshes_tree(Context& ctx, PC_tree_t meshes_tree_list) - { - opt_each(meshes_tree_list, [&](PC_tree_t meshes_tree) {//each meshes (list of mesh) - each(meshes_tree, [&](PC_tree_t meshes_tree_key, PC_tree_t mesh_tree) {//each mesh - - damaris::model::DamarisMeshXML meshxml{} ; - std::map find_replace_map = {}; - unsigned name_index = 0; - std::string dataset_elt_full_name; - - each(mesh_tree, [&](PC_tree_t mesh_tree_key, PC_tree_t value) {//mesh info - std::string key = to_string(mesh_tree_key); - - int tf; // 0 is false, anything else is true - if (key == "name") { - dataset_elt_full_name = to_string(value); - retrive_nested_groups(dataset_elt_full_name - , ds_elt_full_name_delimiter - , nested_groups_names - , name_index); - - //meshxml.set_name(to_string(value)); - meshxml.set_name(nested_groups_names[name_index-1]); - } - else if (key == "type") { - meshxml.set_type(to_string(value)); - } - else if (key == "topology") { - meshxml.set_topology(to_long(value)); - } - else if (key == "coordinates") {//Liste of coordinates - opt_each(value, [&](PC_tree_t coords_tree) {//each meshes (list of mesh) - each(coords_tree, [&](PC_tree_t coord_key, PC_tree_t coord_tree) {//each mesh - std::string coord_name, coord_unit = "", coord_label = "", coord_comment = ""; - - each(coord_tree, [&](PC_tree_t ct_tree_key, PC_tree_t value) {//mesh info - std::string coord_info_key = to_string(ct_tree_key); - - int tf; // 0 is false, anything else is true - if (coord_info_key == "name") { - coord_name = to_string(value); - } else if (coord_info_key == "unit") { - coord_unit = to_string(value); - } else if (coord_info_key == "label") { - coord_label = to_string(value); - } else if (coord_info_key == "comment") { - coord_comment = to_string(value); - } else { - std::cerr << "ERROR: damaris_cfg unrecogognized coord map string: " << key << std::endl ; - } - }); - meshxml.add_coord(coord_name, coord_unit, coord_label, coord_comment); - }); - }); - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized storage map string: " << key << std::endl ; - } - }); - - if(dataset_elt_full_name.empty()) - throw Value_error{"ERROR: damaris_cfg mesh name must not be empty} groups"}; - - //m_meshes.emplace(meshxml.get_name() , meshxml) ; - m_meshes.emplace(meshxml.get_name() , meshxml) ; - //ctx.logger().info("------------------- Parsing damaris Mesh '{}' , name_index = {} ", dataset_elt_full_name, name_index); - - if(name_index == 1) { - find_replace_map.insert( - {"_DATASET_ELEMENT_REGEX_", meshxml.ReturnXMLForMesh() + "\n_DATASET_ELEMENT_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - } - else {//In nested groups - insert_dataset_elts_to_group(meshxml, nested_groups_names, name_index); - } - }); - }); - } - - void Damaris_cfg::parse_storages_tree(Context& ctx, PC_tree_t storages_tree_list) - { - opt_each(storages_tree_list, [&](PC_tree_t storages_tree) {//each storages (list of storage) - each(storages_tree, [&](PC_tree_t storagest_key, PC_tree_t storage_tree) {//each storage - - damaris::model::DamarisStoreXML store{} ; - std::map find_replace_map = {}; - - each(storage_tree, [&](PC_tree_t st_key, PC_tree_t value) {//storage info - std::string key = to_string(st_key); - - int tf; // 0 is false, anything else is true - if (key == "name") { - store.store_name_ = to_string(value); - } - else if (key == "type") { - store.store_type_ = to_string(value); - } - else if (key == "file_mode") { - store.store_opt_FileMode_ = to_string(value); - } - else if (key == "files_path") { - store.store_opt_FilesPath_ = to_string(value); - //Ensure the folder exists - struct stat st; - if (stat(store.store_opt_FilesPath_.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) { - //ctx.logger().info("HDF5 files_path exists: '{}'", to_string(value)); - } else { - if (mkdir(store.store_opt_FilesPath_.c_str(), 0775) == -1) { - //ctx.logger().info("Error during the creation of the HDF5 files_path: '{}'", strerror(errno)); - exit(1); - } else { - //ctx.logger().info("HDF5 files_path created successfully: '{}'", to_string(value)); - } - } - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized storage map string: " << key << std::endl ; - } - }); - m_storages.emplace(store.store_name_ , store) ; - - find_replace_map.insert( - {"_STORAGE_ELEMENT_REGEX_", store.ReturnXMLForStore() + "\n_STORAGE_ELEMENT_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - }); - }); - } - - void Damaris_cfg::parse_paraview_tree(Context& ctx, PC_tree_t paraview_tree) - { - damaris::model::DamarisParaviewXML paraviewxml{} ; - std::map find_replace_map = {}; - - each(paraview_tree, [&](PC_tree_t lt_key, PC_tree_t value) {//layout info - std::string key = to_string(lt_key); - - int intb; // 0 is false, anything else is true - if (key == "update_frequency") { - int in_update_frequency = to_long(value); - paraviewxml.set_update_frequency( in_update_frequency ); - } - else if (key == "realtime_timestep") { - float in_realtime_timestep = (float) to_double(value); - paraviewxml.set_realtime_timestep( in_realtime_timestep ); - } - else if (key == "end_iteration") { - int in_end_iteration = to_long(value); - paraviewxml.set_end_iteration( in_end_iteration ); - } - else if (key == "write_vtk") { - int in_write_vtk = to_long(value); - paraviewxml.set_write_vtk( in_write_vtk ); - } - else if (key == "write_vtk_binary") { - PC_bool(value, &intb); - bool in_write_vtk_binary = (intb == 0) ? false : true ; - paraviewxml.set_write_vtk_binary( in_write_vtk_binary ); - } - else if (key == "comment") { - std::string in_comment = to_string(value); - paraviewxml.set_comment( in_comment ); - } - else if (key == "scripts" || key == "script") { - - if (!PC_status(PC_get(value, "[0]"))) {//Array //[script1, script2, script3] - int nb_paraview_scripts; PC_len(value, &nb_paraview_scripts); - // std::cout << "INFO: damaris_cfg nb paraview scripts: " << nb_paraview_scripts << std::endl ; - - each(value, [&](PC_tree_t script) { - paraviewxml.add_script(to_string(script)); - }); - } - else { - paraviewxml.add_script(to_string(value)); - } - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized paraview map string: " << key << std::endl ; - } - }); - - m_paraview = ¶viewxml ; - - find_replace_map.insert( - {"_PLUGINS_REGEX_", paraviewxml.ReturnXMLForParaview() + "\n_PLUGINS_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - } - - void Damaris_cfg::parse_pyscript_tree(Context& ctx, PC_tree_t pyscript_tree) - { - damaris::model::DamarisPyScriptXML pyscriptxml{} ; - std::map find_replace_map = {}; - - each(pyscript_tree, [&](PC_tree_t py_key, PC_tree_t value) {//layout info - std::string key = to_string(py_key); - - int intb; // 0 is false, anything else is true - if (key == "name") { - pyscriptxml.pyscript_name_ = to_string(value); - } - else if (key == "file") { - pyscriptxml.pyscript_file_ = to_string(value); - } - else if (key == "scheduler_file") { - pyscriptxml.scheduler_file_ = to_string(value); - } - else if (key == "execution") { - pyscriptxml.execution_ = to_string(value); - } - else if (key == "language") { - pyscriptxml.language_ = to_string(value); - } - else if (key == "scope") { - pyscriptxml.scope_ = to_string(value); - } - else if (key == "external") { - PC_bool(value, &intb); - bool in_external = (intb == 0) ? false : true ; - pyscriptxml.external_ = in_external; - } - else if (key == "frequency") { - pyscriptxml.frequency_ = to_long(value); - } - else if (key == "nthreads") { - pyscriptxml.nthreads_ = to_long(value); - } - else if (key == "timeout") { - pyscriptxml.timeout_ = to_long(value); - } - else if (key == "keep_workers_") { - pyscriptxml.keep_workers_ = to_string(value);//yes/no - } - else if (key == "comment") { - pyscriptxml.comment_ = to_string(value); - } - else { - std::cerr << "ERROR: damaris_cfg unrecogognized pyscript map string: " << key << std::endl ; - } - }); - - m_pyscript = &pyscriptxml ; - - find_replace_map.insert( - {"_SCRIPTS_REGEX_", pyscriptxml.ReturnXMLForPyScript() + "\n_SCRIPTS_REGEX_"} - ); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - } - - void Damaris_cfg::parse_write_tree(Context& ctx, PC_tree_t write_tree_list) - { - each(write_tree_list, [&](PC_tree_t writet_key, PC_tree_t write_ds_tree) {//each dataset to write - - std::string ds_name = to_string(writet_key);//the name of the data to write, if dataset not specified afterward! - Dataset_Write_Info ds_write_info; - - //dataset - PC_tree_t ds_name_tree = PC_get(write_ds_tree, ".dataset"); - if(!PC_status(ds_name_tree)) - { - ds_name = to_string(ds_name_tree); - // std::cout << "INFO: damaris_cfg write_ds_tree :: ds_name = '" << ds_name << "'" << std::endl ; - } - //when - PC_tree_t ds_when_tree = PC_get(write_ds_tree, ".when"); - if(!PC_status(ds_when_tree)) - { - ds_write_info.when = to_string(ds_when_tree); - // std::cout << "INFO: damaris_cfg write_ds_tree :: when = '" << ds_write_info.when << "'" << std::endl ; - } - //position - PC_tree_t ds_position_tree = PC_get(write_ds_tree, ".position"); - if(!PC_status(ds_position_tree)) - { - if (!PC_status(PC_get(ds_position_tree, "[0]"))) {//Array [p0,p1,p3] (1 to 3 elements) - int position_dim; PC_len(ds_position_tree, &position_dim); - // std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: " << position_dim << std::endl ; - - int pos_idx = 0; - each(ds_position_tree, [&](PC_tree_t dim) { - ds_write_info.position[pos_idx] = to_string(dim); - pos_idx++; - }); - } - else {//p0 - ds_write_info.position[0] = to_string(ds_position_tree); - // std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: 1" << std::endl ; - } - } - //block - PC_tree_t ds_block_tree = PC_get(write_ds_tree, ".block"); - if(!PC_status(ds_block_tree)) - { - ds_write_info.block = to_string(ds_block_tree); - // std::cout << "INFO: damaris_cfg write_ds_tree :: block = '" << ds_write_info.block << "'" << std::endl ; - } - - m_datasets_to_write.emplace(ds_name, ds_write_info); - - load_desc(m_descs, ctx, ds_name, Desc_type::DATA_TO_WRITE_WITH_BLOCK); - }); - } - - - - void Damaris_cfg::parse_parameter_to_update_tree(Context& ctx, PC_tree_t ptu_tree, Desc_type op_type) - { - if (!PC_status(PC_get(ptu_tree, "[0]"))) {//Array [prm0,prm1,prm3,...] / it's a list of names only - // std::cout << "INFO: damaris_cfg parameter_set or _get :: Array [prm0,prm1,prm3,...] / it's a list of names only " << std::endl ; - each(ptu_tree, [&](PC_tree_t prm_name_t) { - std::pair prm_to_update_info; - std::string metadata = to_string(prm_name_t); - std::string prm_name = to_string(prm_name_t); - - prm_to_update_info.first = prm_name; - prm_to_update_info.second = op_type; - m_parameter_to_update.emplace(metadata, prm_to_update_info); - load_desc(m_descs, ctx, metadata, op_type); - // std::cout << "INFO: damaris_cfg parameter_set or _get :: metadata = "<< metadata <<" and prm_name = "<< prm_name <<" " << std::endl ; - }); - } - else if (!PC_status(ptu_tree)) { // it's a name:{config...} mapping - // std::cout << "INFO: damaris_cfg parameter_set or _get :: it's a name:{config...} mapping " << std::endl ; - each(ptu_tree, [&](PC_tree_t ptu_metadata, PC_tree_t ptu_prmname) { - std::string metadata = to_string(ptu_metadata); - std::string prm_name = to_string(ptu_metadata); - std::pair prm_to_update_info; - - if(!PC_status(ptu_prmname)) - { - if(to_string(ptu_prmname) != "") - prm_name = to_string(ptu_prmname); - } - - prm_to_update_info.first = prm_name; - prm_to_update_info.second = op_type; - m_parameter_to_update.emplace(metadata, prm_to_update_info); - load_desc(m_descs, ctx, metadata, op_type); - // std::cout << "INFO: damaris_cfg parameter_set or _get :: metadata = "<< metadata <<" and prm_name = "<< prm_name <<" " << std::endl ; - }); - } - } - - void Damaris_cfg::parse_log_tree(Context& ctx, PC_tree_t config) - { - std::map find_replace_map = {}; - - //Log File Name - std::string log_file_name = "damaris_pdi_simu"; - PC_tree_t log_file_name_tree = PC_get(config, ".log.file_name"); - if(!PC_status(log_file_name_tree)) - { - log_file_name = to_string(log_file_name_tree); - } - else { - PC_tree_t sim_name_tree = PC_get(config, ".architecture.sim_name"); - if(!PC_status(sim_name_tree)) - { - log_file_name = to_string(sim_name_tree); - } - } - - std::string log_rotation_size = "5"; - PC_tree_t log_rotation_size_tree = PC_get(config, ".log.rotation_size"); - if(!PC_status(log_rotation_size_tree)) - { - log_rotation_size = to_string(log_rotation_size_tree); - } - - std::string log_level = "info"; - PC_tree_t log_level_tree = PC_get(config, ".log.log_level"); - if(!PC_status(log_level_tree)) - { - log_level = to_string(log_level_tree); - } - - std::string log_flush = "true"; - PC_tree_t log_flush_tree = PC_get(config, ".log.flush"); - if(!PC_status(log_flush_tree)) - { - log_flush = to_string(log_flush_tree); - } - - find_replace_map.insert({ - {"_SIM_LOG_NAME_",log_file_name} - ,{"_LOG_ROTATION_SIZE_", log_rotation_size} - ,{"_LOG_FLUSH_", log_flush} - ,{"_LOG_LEVEL_", log_level} - }); - - //Update the xml config - damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); - } - - - - bool Damaris_cfg::is_dataset_to_write(std::string data_name) - { - bool is_dataset_to_write = false; - for(auto &datasets_to_write : m_datasets_to_write) { - if(data_name == datasets_to_write.first) - { - is_dataset_to_write = true; - break; - } - } - - return is_dataset_to_write; - } - - bool Damaris_cfg::is_parameter_to_update(std::string data_name) - { - bool is_parameter_to_update = false; - for(auto ¶meter_to_update : m_parameter_to_update) { - if(data_name == parameter_to_update.first) - { - is_parameter_to_update = true; - break; - } - } - - return is_parameter_to_update; - } - - bool Damaris_cfg::is_needed_metadata(std::string data_name) - { - bool is_needed_metadata = false; - for(auto &prm_depends_on : m_parameter_depends_on) { - auto &prm_name = prm_depends_on.first; - auto &prm_depends_on_data = prm_depends_on.second; - for(auto &depends_on_data : prm_depends_on_data) { - //auto &depends_on_data_name = depends_on_data.first; - //auto &depends_on_data_state = depends_on_data.second; - - if(data_name == depends_on_data.first && depends_on_data.second == false) - { - depends_on_data.second = true; - is_needed_metadata = true; - } - } - } - - return is_needed_metadata; - } - - - //std::vector - //std::unordered_map> Damaris_cfg::get_updatable_parameters() - std::unordered_map> Damaris_cfg::get_updatable_parameters(Context& ctx) - { - std::unordered_map> updatable_parameters; - for(auto prm_depends_on : m_parameter_depends_on) { - auto prm_name = prm_depends_on.first; - auto prm_depends_on_data = prm_depends_on.second; - bool to_be_updated = (prm_depends_on_data.size() > 0);//true; - for(auto depends_on_data : prm_depends_on_data) { - auto depends_on_data_name = depends_on_data.first; - auto depends_on_data_state = depends_on_data.second; - - if(!depends_on_data_state) - { - to_be_updated = false; - break; - } - } - if(to_be_updated) {//Update the parameter - PDI::Expression prm_value = m_parameter_expression.at(prm_name); - damaris::model::DamarisParameterXML prmxml = m_parameters.at(prm_name); - prmxml.param_value_ = prm_value.to_string(ctx); - //ctx.logger().info("------------------------------------------------------------------------------------In get_updatable_parameters `{}' prmxml.param_value_ = '{}'", prm_name, prmxml.param_value_); - std::pair update_info; - update_info.first = prm_value.to_string(ctx); - update_info.second = prmxml.param_datatype_; - - updatable_parameters.emplace(prm_name, update_info); - } - } - - return updatable_parameters; - } - - - void Damaris_cfg::reset_parameter_depends_on(std::string prm_name) { - if (m_parameter_depends_on.find(prm_name) == m_parameter_depends_on.end()) { - // not found - // handle the error - } else { - std::unordered_map prm_depends_on_data = m_parameter_depends_on.at(prm_name); - for(auto depends_on_data : prm_depends_on_data) { - depends_on_data.second = false; - } - } - } - - void Damaris_cfg::reset_parameter_depends_on(std::vector prm_list) { - for (auto prm_name : prm_list) { - reset_parameter_depends_on(prm_name); - } - } - - void Damaris_cfg::reset_all_parameters_depends_on() { - for(auto prm_depends_on : m_parameter_depends_on) { - auto prm_name = prm_depends_on.first; - auto prm_depends_on_data = prm_depends_on.second; - - for(auto depends_on_data : prm_depends_on_data) { - depends_on_data.second = false; - } - } - } - - - // Retrive nested groups names from a dataset_elt_full_name (gp1/gp2/.../dataset_elt_name) - void retrive_nested_groups(std::string& dataset_elt_full_name, char delimiter, std::string nested_groups_names[], unsigned& index) - { - // Creating an input string stream from the dataset_elt_full_name - std::istringstream namestream(dataset_elt_full_name); - - // Tmp string - string gp_name; - - // Retrive names from the string stream separated by the delimiter - while (getline(namestream, gp_name, delimiter)) { - if(index == max_nested_groups) { - throw Value_error{"Damaris variable/layout/mesh can be nested in more than {} groups", max_nested_groups}; - } - // Add the gp_name to the array - nested_groups_names[index++] = gp_name; - } - //If index==1, there is no group, ie: nested_groups_names[index-1] = dataset_elt_full_name - } - - - template - void insert_dataset_elts_to_group(DS_TYPE ds_elt_xml, std::string nested_groups_names[], unsigned index) - { - std::string nearest_group_name = nested_groups_names[index -2]; - bool root_group_exists = false; - damaris::model::DamarisGroupXML *nearest_parent_group = NULL; - for (int root_group_id = 0; root_group_id < root_groups_xml.size(); root_group_id++) { - damaris::model::DamarisGroupXML *root_gp_xml = &root_groups_xml[root_group_id]; - - if(nested_groups_names[0] == root_gp_xml->get_name()) - { - if(nearest_group_name == root_gp_xml->get_name()) - { - //printf("-------------------------------------------------------------------------------------In root_gp_xml.get_name() = %s, FOR Variable %s, nearest_group_name == root_gp_xml.get_name() = %d\n", root_gp_xml->get_name().c_str(), nested_groups_names[index -1].c_str(), (nearest_group_name == root_gp_xml->get_name())); - //root_gp_xml->add_variable(ds_elt_xml); - root_gp_xml->add_ds_element(ds_elt_xml); - - //free(root_gp_xml); - return; - } - nearest_parent_group = root_gp_xml; - root_group_exists = true; - break; - } - - //free(root_gp_xml); - } - - //Insertion in an existing nested group - bool insertion_group_found = false; - int group_id = 1; - if(root_group_exists) - { - while (group_id <= (index - 2) && !insertion_group_found) { - std::string group_name = nested_groups_names[group_id]; - - insertion_group_found = true; - std::vector sub_groups = nearest_parent_group->get_sub_groups(); - for (int group_id = 0; group_id < sub_groups.size(); group_id++) { - if(group_name == sub_groups[group_id].get_name()) - { - if(nearest_group_name == sub_groups[group_id].get_name()) - { - //(&sub_groups[group_id])->add_variable(ds_elt_xml); - (&sub_groups[group_id])->add_ds_element(ds_elt_xml); - - return; - } - insertion_group_found = false; - nearest_parent_group = &sub_groups[group_id++]; - break; - } - } - } - } - //The nested groups has to be created - else { - damaris::model::DamarisGroupXML root_gp_xml{nested_groups_names[0]}; - - if(nearest_group_name == root_gp_xml.get_name()) - { - //root_gp_xml.add_variable(ds_elt_xml); - root_gp_xml.add_ds_element(ds_elt_xml); - root_groups_xml.emplace_back(root_gp_xml); - - return; - } - - root_groups_xml.emplace_back(root_gp_xml); - - nearest_parent_group = &root_gp_xml; - insertion_group_found = true; - } - - //Insertion point found - if(insertion_group_found){ - damaris::model::DamarisGroupXML linked_parent_group{nearest_group_name}; - for (unsigned insertion_group_id = (index - 2); insertion_group_id >= group_id; insertion_group_id--) - { - std::string group_name = nested_groups_names[insertion_group_id]; - damaris::model::DamarisGroupXML sub_gp_xml{group_name}; - if(nearest_group_name == sub_gp_xml.get_name()) - { - //sub_gp_xml.add_variable(ds_elt_xml); - sub_gp_xml.add_ds_element(ds_elt_xml); - } - else { - sub_gp_xml.add_sub_group(linked_parent_group); - } - linked_parent_group = sub_gp_xml; - } - nearest_parent_group->add_sub_group(linked_parent_group); - } - - //free(nearest_parent_group); - } - - /* + std::string end_it_event_name = event_names.at(Event_type::DAMARIS_END_ITERATION); + //Add only if it does not exist yet + if (std::find(m_after_write_events.begin(), m_after_write_events.end(), end_it_event_name) == m_after_write_events.end() + && m_end_iteration_on_event.empty()) + { + m_after_write_events.emplace_back(end_it_event_name); + } + + parse_log_tree(ctx, tree); + + //Insert grouped dataset elements + for (int root_group_id = 0; root_group_id < root_groups_xml.size(); root_group_id++) { + damaris::model::DamarisGroupXML root_gp_xml = root_groups_xml[root_group_id]; + + m_groups.emplace(root_gp_xml.get_name(), root_gp_xml); + std::map find_replace_map + = {{"_DATASET_ELEMENT_REGEX_", root_gp_xml.ReturnXMLForGroup() + "\n_DATASET_ELEMENT_REGEX_"}}; + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } + + //CleanUp XML OBJECT + std::map find_replace_map + = {{"_DATASET_ELEMENT_REGEX_", ""}, {"_STORAGE_ELEMENT_REGEX_", ""}, {"_PLUGINS_REGEX_", ""}, {"_SCRIPTS_REGEX_", ""}}; + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + + m_xml_config_object = damarisXMLModifyModel.GetConfigString(); + + //printf("-------------------------------------------------------XML OBJECT MODIFIED----------------------------------------------\n%s", damarisXMLModifyModel.GetConfigString().c_str()); + //exit(0); +} + +void Damaris_cfg::parse_architecture_tree(Context& ctx, PC_tree_t arch_tree) +{ + std::map find_replace_map = {}; + + //simulation name & Buffer + std::string sim_name = "damaris_pdi_simu"; + PC_tree_t sim_name_tree = PC_get(arch_tree, ".sim_name"); + if (!PC_status(sim_name_tree)) { + sim_name = to_string(sim_name_tree); + } + //Buffer + std::string buffer_name = sim_name + "_buffer"; + long buffer_size = 67108864; + PC_tree_t buffer_size_tree = PC_get(arch_tree, ".buffer_size"); + if (!PC_status(buffer_size_tree)) { + buffer_size = to_long(buffer_size_tree); + } + find_replace_map.insert({{"_SIM_NAME_", sim_name}, {"_SHMEM_BUFFER_BYTES_REGEX_", std::to_string(buffer_size)}, {"_SHMEM_NAME_", buffer_name}}); + + //domains + int m_arch_domains = 1; + PC_tree_t domains_tree = PC_get(arch_tree, ".domains"); + if (!PC_status(domains_tree)) { + m_arch_domains = to_long(domains_tree); + } + find_replace_map.insert({"_DOMAINS_REGEX_", std::to_string(m_arch_domains)}); + + //dedicated + int m_dc_cores_pernode = 0; + int m_dc_nodes = 0; + PC_tree_t arch_dedicated_tree = PC_get(arch_tree, ".dedicated"); + if (!PC_status(arch_dedicated_tree)) { + int nb_subkey_dc = len(arch_dedicated_tree); + + for (int subkey_dc_id = 0; subkey_dc_id < nb_subkey_dc; subkey_dc_id++) { + string key_str = to_string(PC_get(arch_dedicated_tree, "{%d}", subkey_dc_id)); + + if (key_str == "core") { + m_dc_cores_pernode = to_long(PC_get(arch_dedicated_tree, ".core")); + } else if (key_str == "node") { + m_dc_nodes = to_long(PC_get(arch_dedicated_tree, ".node")); + } + } + } + find_replace_map.insert({{"_DC_REGEX_", std::to_string(m_dc_cores_pernode)}, {"_DN_REGEX_", std::to_string(m_dc_nodes)}}); + + //placement not yet used + PC_tree_t arch_placement_tree = PC_get(arch_tree, ".placement"); + if (!PC_status(arch_placement_tree)) { + int nb_subkey_dc = len(arch_placement_tree); + + for (int subkey_pl_id = 0; subkey_pl_id < nb_subkey_dc; subkey_pl_id++) { + string key_str = to_string(PC_get(arch_placement_tree, "{%d}", subkey_pl_id)); + + if (key_str == "start") { + m_placement_start = to_long(PC_get(arch_placement_tree, ".start")); + } else if (key_str == "stride") { + m_placement_stride = to_long(PC_get(arch_placement_tree, ".stride")); + } else if (key_str == "blocksize") { + m_placement_blocksize = to_long(PC_get(arch_placement_tree, ".blocksize")); + } else if (key_str == "mask") { + m_placement_mask_str = to_string(PC_get(arch_placement_tree, ".mask")); + } + } + //TODO: find_replace_map.insert( ); + } + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); +} + +void Damaris_cfg::parse_parameters_tree(Context& ctx, PC_tree_t parameters_tree_list) +{ + opt_each(parameters_tree_list, [&](PC_tree_t parameters_tree) { //each parameters (list of parameter) + each(parameters_tree, [&](PC_tree_t prm_tree_key, PC_tree_t parameter_tree) { //each parameter + damaris::model::DamarisParameterXML prmxml{}; + std::map find_replace_map = {}; + std::unordered_map depends_on_metadata; + bool is_dependent = false; + + each(parameter_tree, [&](PC_tree_t prm_key, PC_tree_t value) { //parameter info + std::string key = to_string(prm_key); + + if (key == "name") { + prmxml.param_name_ = to_string(value); + } else if (key == "type") { + prmxml.param_datatype_ = to_string(value); + } else if (key == "value") { + prmxml.param_value_ = to_string(value); + m_parameter_expression.emplace(prmxml.param_name_, to_string(value)); + } else if (key == "depends_on") { + is_dependent = true; + if (!PC_status(PC_get(value, "[0]"))) { //Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter + //int idx = 0; + each(value, [&](PC_tree_t metadata_name_tree) { + std::string metadata_name = to_string(metadata_name_tree); + + depends_on_metadata.insert({metadata_name, false}); + + load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); + }); + } else { //d1 + std::string metadata_name = to_string(value); + //depends_on_metadata[metadata_name] = false; + depends_on_metadata.insert({metadata_name, false}); + + load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); + //ctx.logger().info("--------------------------------------------------------------------------------PARAMETER {} depends on {}", prmxml.param_name_, metadata_name); + } + + + } else { + std::cerr << "ERROR: damaris_cfg unrecogognized parameter map string: " << key << std::endl; + } + }); + //m_parameter_expression.emplace(prmxml.param_name_, prmxml.param_value_); + m_parameter_depends_on.emplace(prmxml.param_name_, depends_on_metadata); + //set default value if depend on metadata + if (is_dependent && std::find(std::begin(numbers_types), std::end(numbers_types), prmxml.param_datatype_) != std::end(numbers_types)) { + if (std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prmxml.param_datatype_) != std::end(int_numbers_types)) + prmxml.param_value_ = "1"; //"0" + else + prmxml.param_value_ = "1.0"; //"0" + } else { + ///??? + } + + m_parameters.emplace(prmxml.param_name_, prmxml); + find_replace_map.insert({"_DATASET_ELEMENT_REGEX_", prmxml.ReturnXMLForParameter() + "\n_DATASET_ELEMENT_REGEX_"}); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + }); + }); +} + +void Damaris_cfg::parse_datasets_tree(Context& ctx, PC_tree_t datasets_tree_list) +{ + opt_each(datasets_tree_list, [&](PC_tree_t datasets_tree) { //each datasets (list of dataset) + each(datasets_tree, [&](PC_tree_t ds_tree_key, PC_tree_t dataset_tree) { //each dataset + damaris::model::DamarisVarXML vxml{}; + std::map find_replace_map = {}; + unsigned name_index = 0; + std::string dataset_elt_full_name; + + each(dataset_tree, [&](PC_tree_t ds_key, PC_tree_t value) { //dataset info + std::string key = to_string(ds_key); + + int tf; // 0 is false, anything else is true + if (key == "name") { + dataset_elt_full_name = to_string(value); + retrive_nested_groups(dataset_elt_full_name, ds_elt_full_name_delimiter, nested_groups_names, name_index); + + vxml.var_name_ = nested_groups_names[name_index - 1]; //to_string(value); + } else if (key == "layout") { + vxml.layout_name_ = to_string(value); + } else if (key == "mesh") { + vxml.mesh_ = to_string(value); + } else if (key == "centering") { + std::string t_centering = to_string(value); + vxml.set_centering(t_centering); + } else if (key == "storage") { + vxml.store_ = to_string(value); + } else if (key == "script") { + vxml.script_ = to_string(value); + } else if (key == "unit") { + vxml.unit_ = to_string(value); + } else if (key == "select_mem") { + vxml.select_mem_ = to_string(value); + } else if (key == "select_file") { + vxml.select_file_ = to_string(value); + } else if (key == "select_subset") { + vxml.select_subset_ = to_string(value); + } else if (key == "ref") { + vxml.ref_ = to_string(value); + } else if (key == "type") { + std::string in_type = to_string(value); + vxml.set_type(in_type); + } else if (key == "comment") { + vxml.comment_ = to_string(value); + } else if (key == "visualizable") { + PC_bool(value, &tf); + vxml.visualizable_ = (tf == 0) ? false : true; + } else if (key == "time_varying") { + PC_bool(value, &tf); + vxml.time_varying_ = (tf == 0) ? false : true; + } else if (key == "enabled") { + PC_bool(value, &tf); + vxml.enabled_ = (tf == 0) ? false : true; + } else { + throw Value_error{"RROR: damaris_cfg unrecogognized variable map string: " + key}; + } + }); + + if (dataset_elt_full_name.empty()) throw Value_error{"ERROR: damaris_cfg variable name must not be empty"}; + + //m_datasets.emplace(vxml.var_name_ , vxml) ; + m_datasets.emplace(dataset_elt_full_name, vxml); + //ctx.logger().info("------------------- Parsing damaris Variable '{}' , name_index = {} ", dataset_elt_full_name, name_index); + + if (name_index == 1) { + find_replace_map.insert({"_DATASET_ELEMENT_REGEX_", vxml.ReturnXMLForVariable() + "\n_DATASET_ELEMENT_REGEX_"}); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } else { //In nested groups + insert_dataset_elts_to_group(vxml, nested_groups_names, name_index); + } + }); + }); +} + +void Damaris_cfg::parse_layouts_tree(Context& ctx, PC_tree_t layouts_tree_list) +{ + opt_each(layouts_tree_list, [&](PC_tree_t layouts_tree) { //each layouts (list of layout) + each(layouts_tree, [&](PC_tree_t lts_key, PC_tree_t layout_tree) { //each layout + damaris::model::DamarisLayoutXML layoutxml{}; + std::map find_replace_map = {}; + unsigned name_index = 0; + std::string dataset_elt_full_name; + std::unordered_map depends_on_metadata; + bool is_dependent = false; + std::string depends_on_str = ""; + std::string in_datatype; + int nb_dims; + + each(layout_tree, [&](PC_tree_t lt_key, PC_tree_t value) { //layout info + std::string key = to_string(lt_key); + + int intb; // 0 is false, anything else is true + if (key == "name") { + dataset_elt_full_name = to_string(value); + retrive_nested_groups(dataset_elt_full_name, ds_elt_full_name_delimiter, nested_groups_names, name_index); + + layoutxml.layout_name_ = nested_groups_names[name_index - 1]; //to_string(value); + } else if (key == "type") { + in_datatype = to_string(value); + layoutxml.set_datatype(in_datatype); + } else if (key == "dimensions") { + //Is there a way to determine if an expression is ready to be evaluated? ei, all the conponent have a value + if (!PC_status(PC_get(value, "[0]"))) { //Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter + int nb_layout_dims2; + PC_len(value, &nb_layout_dims2); + //std::cout << "INFO: damaris_cfg nb_layout_dims has dims2: " << nb_layout_dims2 << std::endl ; + + std::string dims_list = ""; + each(value, [&](PC_tree_t dim) { dims_list += to_string(dim) + ","; }); + dims_list.pop_back(); + layoutxml.layout_dimensions_ = dims_list; + } else { //"d1,d2,d3" for instance, each di an expreession of of Damaris Parameter + layoutxml.layout_dimensions_ = to_string(value); + } + + nb_dims = count(layoutxml.layout_dimensions_.begin(), layoutxml.layout_dimensions_.end(), ',') + 1; + } else if (key == "global") { + //Is there a way to determine if an expression is ready to be evaluated? ei, all the conponent have a value + if (!PC_status(PC_get(value, "[0]"))) { //Array //[dg1,dg2,dg3] for instance, each di an expreession of of Damaris Parameter + + std::string dims_global_list = ""; + each(value, [&](PC_tree_t dim) { dims_global_list += to_string(dim) + ","; }); + dims_global_list.pop_back(); + layoutxml.layout_dims_global_ = dims_global_list; + } else { //"dg1,dg2,dg3" for instance, each di an expreession of of Damaris Parameter + layoutxml.layout_dims_global_ = to_string(value); + } + } else if (key == "ghosts") { + //Is there a way to determine if an expression is ready to be evaluated? ei, all the conponent have a value + if (!PC_status( + PC_get(value, "[0]") + )) { //Array //['g11:g12','g21:g22','g31:g32'] for instance, each di an expreession of of Damaris Parameter + + std::string ghosts_list = ""; + each(value, [&](PC_tree_t dim) { ghosts_list += to_string(dim) + ","; }); + ghosts_list.pop_back(); + layoutxml.layout_ghosts_ = ghosts_list; + } else { //"g11:g12,g21:g22,g31:g32" for instance, each di an expreession of of Damaris Parameter + layoutxml.layout_ghosts_ = to_string(value); + } + } else if (key == "language") { + std::string in_language = to_string(value); + layoutxml.set_language(in_language); + } else if (key == "visualizable") { + PC_bool(value, &intb); + bool in_visualizable = (intb == 0) ? false : true; + layoutxml.layout_visualizable_ = in_visualizable; + } else if (key == "comment") { + layoutxml.layout_comment_ = to_string(value); + } else if (key == "depends_on") { + is_dependent = true; + if (!PC_status(PC_get(value, "[0]"))) { //Array //[d1,d2,d3] for instance, each di an expreession of of Damaris Parameter + //int idx = 0; + each(value, [&](PC_tree_t metadata_name_tree) { + std::string metadata_name = to_string(metadata_name_tree); + depends_on_str += metadata_name + ", "; + + depends_on_metadata.insert({metadata_name, false}); + + //load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); + }); + depends_on_str.pop_back(); //' ' + depends_on_str.pop_back(); //',' + } else { //d1 + std::string metadata_name = to_string(value); + depends_on_str = metadata_name; + //depends_on_metadata[metadata_name] = false; + depends_on_metadata.insert({metadata_name, false}); + + //load_desc(m_descs, ctx, metadata_name, Desc_type::PRM_REQUIRED_METADATA); + } + depends_on_str = "[" + depends_on_str + "]"; + + } else { + throw Value_error{"RROR: damaris_cfg unrecogognized layout map string: " + key}; + } + }); + m_layout_depends_on.emplace(layoutxml.layout_name_, depends_on_metadata); + //set default value if depend on metadata + //if(is_dependent && std::find(std::begin(numbers_types), std::end(numbers_types), in_datatype)) { + if (is_dependent) { + std::stringstream ss_dims(layoutxml.layout_dimensions_), ss_globals(layoutxml.layout_dims_global_); + std::string tmp; + std::vector dim_list, global_list; + + while (std::getline(ss_dims, tmp, ',')) { + dim_list.push_back(tmp); + } + while (std::getline(ss_globals, tmp, ',')) { + global_list.push_back(tmp); + } + + //ctx.logger().info("------------------- OLD layoutxml.layout_dimensions_ '{}' | layoutxml.layout_dims_global_ '{}'", layoutxml.layout_dimensions_, layoutxml.layout_dims_global_); + + //ctx.logger().info("------------------- dim_list[0] = '{}' | global_list[0] = '{}'", dim_list[0], global_list[0]); + + std::string prm_config_yaml = ""; //"parameters: \n"; + + layoutxml.layout_dimensions_ = ""; + std::string new_globals = ""; + //TODO: get the type of the metadata to which the layout depends, to apply it to the parameters + std::string metadatatype = "int"; + + for (int i = 0; i < nb_dims; i++) { + string dim_name = layoutxml.layout_name_ + "_dim" + std::to_string(i); + prm_config_yaml += "- parameter: \n"; + prm_config_yaml += " name: " + dim_name + " \n"; + prm_config_yaml += " type: " + metadatatype + " \n"; + prm_config_yaml += " value: '" + dim_list[i] + "' \n"; + prm_config_yaml += " depends_on: " + depends_on_str + " \n"; + + layoutxml.layout_dimensions_ += dim_name + ","; + + if (layoutxml.layout_dims_global_.length() > 1) { + string global_name = layoutxml.layout_name_ + "_global" + std::to_string(i); + prm_config_yaml += "- parameter: \n"; + prm_config_yaml += " name: " + global_name + " \n"; + prm_config_yaml += " type: " + metadatatype + " \n"; + prm_config_yaml += " value: '" + global_list[i] + "' \n"; + prm_config_yaml += " depends_on: " + depends_on_str + " \n"; + + new_globals += global_name + ","; + } + } + layoutxml.layout_dimensions_.pop_back(); + //the layout_dims_global_ attribute being optional with default value '#', we need to ensure it has been set before modification. + //if(layoutxml.layout_dims_global_ != '#') { + if (layoutxml.layout_dims_global_.length() > 1) { + new_globals.pop_back(); + layoutxml.layout_dims_global_ = new_globals; + } + + //Background creation of parameter + PC_tree_t parameters_conf = PC_parse_string(prm_config_yaml.c_str()); + //ctx.logger().info("------------------- parameters_conf = \n '{}'", prm_config_yaml); + parse_parameters_tree(ctx, parameters_conf); + } else { + ///??? + } + + if (dataset_elt_full_name.empty()) throw Value_error{"ERROR: damaris_cfg layout name must not be empty"}; + + //m_layouts.emplace(layoutxml.layout_name_ , layoutxml) ; + m_layouts.emplace(dataset_elt_full_name, layoutxml); + //ctx.logger().info("------------------- Parsing damaris Layout '{}' , name_index = {} ", dataset_elt_full_name, name_index); + + if (name_index == 1) { + find_replace_map.insert({"_DATASET_ELEMENT_REGEX_", layoutxml.ReturnXMLForLayout() + "\n_DATASET_ELEMENT_REGEX_"}); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } else { //In nested groups + insert_dataset_elts_to_group(layoutxml, nested_groups_names, name_index); + } + }); + }); +} + +void Damaris_cfg::parse_meshes_tree(Context& ctx, PC_tree_t meshes_tree_list) +{ + opt_each(meshes_tree_list, [&](PC_tree_t meshes_tree) { //each meshes (list of mesh) + each(meshes_tree, [&](PC_tree_t meshes_tree_key, PC_tree_t mesh_tree) { //each mesh + damaris::model::DamarisMeshXML meshxml{}; + std::map find_replace_map = {}; + unsigned name_index = 0; + std::string dataset_elt_full_name; + + each(mesh_tree, [&](PC_tree_t mesh_tree_key, PC_tree_t value) { //mesh info + std::string key = to_string(mesh_tree_key); + + int tf; // 0 is false, anything else is true + if (key == "name") { + dataset_elt_full_name = to_string(value); + retrive_nested_groups(dataset_elt_full_name, ds_elt_full_name_delimiter, nested_groups_names, name_index); + + //meshxml.set_name(to_string(value)); + meshxml.set_name(nested_groups_names[name_index - 1]); + } else if (key == "type") { + meshxml.set_type(to_string(value)); + } else if (key == "topology") { + meshxml.set_topology(to_long(value)); + } else if (key == "coordinates") { //Liste of coordinates + opt_each(value, [&](PC_tree_t coords_tree) { //each meshes (list of mesh) + each(coords_tree, [&](PC_tree_t coord_key, PC_tree_t coord_tree) { //each mesh + std::string coord_name, coord_unit = "", coord_label = "", coord_comment = ""; + + each(coord_tree, [&](PC_tree_t ct_tree_key, PC_tree_t value) { //mesh info + std::string coord_info_key = to_string(ct_tree_key); + + int tf; // 0 is false, anything else is true + if (coord_info_key == "name") { + coord_name = to_string(value); + } else if (coord_info_key == "unit") { + coord_unit = to_string(value); + } else if (coord_info_key == "label") { + coord_label = to_string(value); + } else if (coord_info_key == "comment") { + coord_comment = to_string(value); + } else { + std::cerr << "ERROR: damaris_cfg unrecogognized coord map string: " << key << std::endl; + } + }); + meshxml.add_coord(coord_name, coord_unit, coord_label, coord_comment); + }); + }); + } else { + std::cerr << "ERROR: damaris_cfg unrecogognized storage map string: " << key << std::endl; + } + }); + + if (dataset_elt_full_name.empty()) throw Value_error{"ERROR: damaris_cfg mesh name must not be empty} groups"}; + + //m_meshes.emplace(meshxml.get_name() , meshxml) ; + m_meshes.emplace(meshxml.get_name(), meshxml); + //ctx.logger().info("------------------- Parsing damaris Mesh '{}' , name_index = {} ", dataset_elt_full_name, name_index); + + if (name_index == 1) { + find_replace_map.insert({"_DATASET_ELEMENT_REGEX_", meshxml.ReturnXMLForMesh() + "\n_DATASET_ELEMENT_REGEX_"}); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + } else { //In nested groups + insert_dataset_elts_to_group(meshxml, nested_groups_names, name_index); + } + }); + }); +} + +void Damaris_cfg::parse_storages_tree(Context& ctx, PC_tree_t storages_tree_list) +{ + opt_each(storages_tree_list, [&](PC_tree_t storages_tree) { //each storages (list of storage) + each(storages_tree, [&](PC_tree_t storagest_key, PC_tree_t storage_tree) { //each storage + damaris::model::DamarisStoreXML store{}; + std::map find_replace_map = {}; + + each(storage_tree, [&](PC_tree_t st_key, PC_tree_t value) { //storage info + std::string key = to_string(st_key); + + int tf; // 0 is false, anything else is true + if (key == "name") { + store.store_name_ = to_string(value); + } else if (key == "type") { + store.store_type_ = to_string(value); + } else if (key == "file_mode") { + store.store_opt_FileMode_ = to_string(value); + } else if (key == "files_path") { + store.store_opt_FilesPath_ = to_string(value); + //Ensure the folder exists + struct stat st; + if (stat(store.store_opt_FilesPath_.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) { + //ctx.logger().info("HDF5 files_path exists: '{}'", to_string(value)); + } else { + if (mkdir(store.store_opt_FilesPath_.c_str(), 0775) == -1) { + //ctx.logger().info("Error during the creation of the HDF5 files_path: '{}'", strerror(errno)); + exit(1); + } else { + //ctx.logger().info("HDF5 files_path created successfully: '{}'", to_string(value)); + } + } + } else { + std::cerr << "ERROR: damaris_cfg unrecogognized storage map string: " << key << std::endl; + } + }); + m_storages.emplace(store.store_name_, store); + + find_replace_map.insert({"_STORAGE_ELEMENT_REGEX_", store.ReturnXMLForStore() + "\n_STORAGE_ELEMENT_REGEX_"}); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); + }); + }); +} + +void Damaris_cfg::parse_paraview_tree(Context& ctx, PC_tree_t paraview_tree) +{ + damaris::model::DamarisParaviewXML paraviewxml{}; + std::map find_replace_map = {}; + + each(paraview_tree, [&](PC_tree_t lt_key, PC_tree_t value) { //layout info + std::string key = to_string(lt_key); + + int intb; // 0 is false, anything else is true + if (key == "update_frequency") { + int in_update_frequency = to_long(value); + paraviewxml.set_update_frequency(in_update_frequency); + } else if (key == "realtime_timestep") { + float in_realtime_timestep = (float)to_double(value); + paraviewxml.set_realtime_timestep(in_realtime_timestep); + } else if (key == "end_iteration") { + int in_end_iteration = to_long(value); + paraviewxml.set_end_iteration(in_end_iteration); + } else if (key == "write_vtk") { + int in_write_vtk = to_long(value); + paraviewxml.set_write_vtk(in_write_vtk); + } else if (key == "write_vtk_binary") { + PC_bool(value, &intb); + bool in_write_vtk_binary = (intb == 0) ? false : true; + paraviewxml.set_write_vtk_binary(in_write_vtk_binary); + } else if (key == "comment") { + std::string in_comment = to_string(value); + paraviewxml.set_comment(in_comment); + } else if (key == "scripts" || key == "script") { + if (!PC_status(PC_get(value, "[0]"))) { //Array //[script1, script2, script3] + int nb_paraview_scripts; + PC_len(value, &nb_paraview_scripts); + // std::cout << "INFO: damaris_cfg nb paraview scripts: " << nb_paraview_scripts << std::endl ; + + each(value, [&](PC_tree_t script) { paraviewxml.add_script(to_string(script)); }); + } else { + paraviewxml.add_script(to_string(value)); + } + } else { + std::cerr << "ERROR: damaris_cfg unrecogognized paraview map string: " << key << std::endl; + } + }); + + m_paraview = ¶viewxml; + + find_replace_map.insert({"_PLUGINS_REGEX_", paraviewxml.ReturnXMLForParaview() + "\n_PLUGINS_REGEX_"}); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); +} + +void Damaris_cfg::parse_pyscript_tree(Context& ctx, PC_tree_t pyscript_tree) +{ + damaris::model::DamarisPyScriptXML pyscriptxml{}; + std::map find_replace_map = {}; + + each(pyscript_tree, [&](PC_tree_t py_key, PC_tree_t value) { //layout info + std::string key = to_string(py_key); + + int intb; // 0 is false, anything else is true + if (key == "name") { + pyscriptxml.pyscript_name_ = to_string(value); + } else if (key == "file") { + pyscriptxml.pyscript_file_ = to_string(value); + } else if (key == "scheduler_file") { + pyscriptxml.scheduler_file_ = to_string(value); + } else if (key == "execution") { + pyscriptxml.execution_ = to_string(value); + } else if (key == "language") { + pyscriptxml.language_ = to_string(value); + } else if (key == "scope") { + pyscriptxml.scope_ = to_string(value); + } else if (key == "external") { + PC_bool(value, &intb); + bool in_external = (intb == 0) ? false : true; + pyscriptxml.external_ = in_external; + } else if (key == "frequency") { + pyscriptxml.frequency_ = to_long(value); + } else if (key == "nthreads") { + pyscriptxml.nthreads_ = to_long(value); + } else if (key == "timeout") { + pyscriptxml.timeout_ = to_long(value); + } else if (key == "keep_workers_") { + pyscriptxml.keep_workers_ = to_string(value); //yes/no + } else if (key == "comment") { + pyscriptxml.comment_ = to_string(value); + } else { + std::cerr << "ERROR: damaris_cfg unrecogognized pyscript map string: " << key << std::endl; + } + }); + + m_pyscript = &pyscriptxml; + + find_replace_map.insert({"_SCRIPTS_REGEX_", pyscriptxml.ReturnXMLForPyScript() + "\n_SCRIPTS_REGEX_"}); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); +} + +void Damaris_cfg::parse_write_tree(Context& ctx, PC_tree_t write_tree_list) +{ + each(write_tree_list, [&](PC_tree_t writet_key, PC_tree_t write_ds_tree) { //each dataset to write + std::string ds_name = to_string(writet_key); //the name of the data to write, if dataset not specified afterward! + Dataset_Write_Info ds_write_info; + + //dataset + PC_tree_t ds_name_tree = PC_get(write_ds_tree, ".dataset"); + if (!PC_status(ds_name_tree)) { + ds_name = to_string(ds_name_tree); + // std::cout << "INFO: damaris_cfg write_ds_tree :: ds_name = '" << ds_name << "'" << std::endl ; + } + //when + PC_tree_t ds_when_tree = PC_get(write_ds_tree, ".when"); + if (!PC_status(ds_when_tree)) { + ds_write_info.when = to_string(ds_when_tree); + // std::cout << "INFO: damaris_cfg write_ds_tree :: when = '" << ds_write_info.when << "'" << std::endl ; + } + //position + PC_tree_t ds_position_tree = PC_get(write_ds_tree, ".position"); + if (!PC_status(ds_position_tree)) { + if (!PC_status(PC_get(ds_position_tree, "[0]"))) { //Array [p0,p1,p3] (1 to 3 elements) + int position_dim; + PC_len(ds_position_tree, &position_dim); + // std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: " << position_dim << std::endl ; + + int pos_idx = 0; + each(ds_position_tree, [&](PC_tree_t dim) { + ds_write_info.position[pos_idx] = to_string(dim); + pos_idx++; + }); + } else { //p0 + ds_write_info.position[0] = to_string(ds_position_tree); + // std::cout << "INFO: damaris_cfg write_ds_tree :: '"<< ds_name <<"' will be written in dims: 1" << std::endl ; + } + } + //block + PC_tree_t ds_block_tree = PC_get(write_ds_tree, ".block"); + if (!PC_status(ds_block_tree)) { + ds_write_info.block = to_string(ds_block_tree); + // std::cout << "INFO: damaris_cfg write_ds_tree :: block = '" << ds_write_info.block << "'" << std::endl ; + } + + m_datasets_to_write.emplace(ds_name, ds_write_info); + + load_desc(m_descs, ctx, ds_name, Desc_type::DATA_TO_WRITE_WITH_BLOCK); + }); +} + +void Damaris_cfg::parse_parameter_to_update_tree(Context& ctx, PC_tree_t ptu_tree, Desc_type op_type) +{ + if (!PC_status(PC_get(ptu_tree, "[0]"))) { //Array [prm0,prm1,prm3,...] / it's a list of names only + // std::cout << "INFO: damaris_cfg parameter_set or _get :: Array [prm0,prm1,prm3,...] / it's a list of names only " << std::endl ; + each(ptu_tree, [&](PC_tree_t prm_name_t) { + std::pair prm_to_update_info; + std::string metadata = to_string(prm_name_t); + std::string prm_name = to_string(prm_name_t); + + prm_to_update_info.first = prm_name; + prm_to_update_info.second = op_type; + m_parameter_to_update.emplace(metadata, prm_to_update_info); + load_desc(m_descs, ctx, metadata, op_type); + // std::cout << "INFO: damaris_cfg parameter_set or _get :: metadata = "<< metadata <<" and prm_name = "<< prm_name <<" " << std::endl ; + }); + } else if (!PC_status(ptu_tree)) { // it's a name:{config...} mapping + // std::cout << "INFO: damaris_cfg parameter_set or _get :: it's a name:{config...} mapping " << std::endl ; + each(ptu_tree, [&](PC_tree_t ptu_metadata, PC_tree_t ptu_prmname) { + std::string metadata = to_string(ptu_metadata); + std::string prm_name = to_string(ptu_metadata); + std::pair prm_to_update_info; + + if (!PC_status(ptu_prmname)) { + if (to_string(ptu_prmname) != "") prm_name = to_string(ptu_prmname); + } + + prm_to_update_info.first = prm_name; + prm_to_update_info.second = op_type; + m_parameter_to_update.emplace(metadata, prm_to_update_info); + load_desc(m_descs, ctx, metadata, op_type); + // std::cout << "INFO: damaris_cfg parameter_set or _get :: metadata = "<< metadata <<" and prm_name = "<< prm_name <<" " << std::endl ; + }); + } +} + +void Damaris_cfg::parse_log_tree(Context& ctx, PC_tree_t config) +{ + std::map find_replace_map = {}; + + //Log File Name + std::string log_file_name = "damaris_pdi_simu"; + PC_tree_t log_file_name_tree = PC_get(config, ".log.file_name"); + if (!PC_status(log_file_name_tree)) { + log_file_name = to_string(log_file_name_tree); + } else { + PC_tree_t sim_name_tree = PC_get(config, ".architecture.sim_name"); + if (!PC_status(sim_name_tree)) { + log_file_name = to_string(sim_name_tree); + } + } + + std::string log_rotation_size = "5"; + PC_tree_t log_rotation_size_tree = PC_get(config, ".log.rotation_size"); + if (!PC_status(log_rotation_size_tree)) { + log_rotation_size = to_string(log_rotation_size_tree); + } + + std::string log_level = "info"; + PC_tree_t log_level_tree = PC_get(config, ".log.log_level"); + if (!PC_status(log_level_tree)) { + log_level = to_string(log_level_tree); + } + + std::string log_flush = "true"; + PC_tree_t log_flush_tree = PC_get(config, ".log.flush"); + if (!PC_status(log_flush_tree)) { + log_flush = to_string(log_flush_tree); + } + + find_replace_map.insert( + {{"_SIM_LOG_NAME_", log_file_name}, {"_LOG_ROTATION_SIZE_", log_rotation_size}, {"_LOG_FLUSH_", log_flush}, {"_LOG_LEVEL_", log_level}} + ); + + //Update the xml config + damarisXMLModifyModel.RepalceWithRegEx(find_replace_map); +} + +bool Damaris_cfg::is_dataset_to_write(std::string data_name) +{ + bool is_dataset_to_write = false; + for (auto& datasets_to_write: m_datasets_to_write) { + if (data_name == datasets_to_write.first) { + is_dataset_to_write = true; + break; + } + } + + return is_dataset_to_write; +} + +bool Damaris_cfg::is_parameter_to_update(std::string data_name) +{ + bool is_parameter_to_update = false; + for (auto& parameter_to_update: m_parameter_to_update) { + if (data_name == parameter_to_update.first) { + is_parameter_to_update = true; + break; + } + } + + return is_parameter_to_update; +} + +bool Damaris_cfg::is_needed_metadata(std::string data_name) +{ + bool is_needed_metadata = false; + for (auto& prm_depends_on: m_parameter_depends_on) { + auto& prm_name = prm_depends_on.first; + auto& prm_depends_on_data = prm_depends_on.second; + for (auto& depends_on_data: prm_depends_on_data) { + //auto &depends_on_data_name = depends_on_data.first; + //auto &depends_on_data_state = depends_on_data.second; + + if (data_name == depends_on_data.first && depends_on_data.second == false) { + depends_on_data.second = true; + is_needed_metadata = true; + } + } + } + + return is_needed_metadata; +} + +//std::vector +//std::unordered_map> Damaris_cfg::get_updatable_parameters() +std::unordered_map> Damaris_cfg::get_updatable_parameters(Context& ctx) +{ + std::unordered_map> updatable_parameters; + for (auto prm_depends_on: m_parameter_depends_on) { + auto prm_name = prm_depends_on.first; + auto prm_depends_on_data = prm_depends_on.second; + bool to_be_updated = (prm_depends_on_data.size() > 0); //true; + for (auto depends_on_data: prm_depends_on_data) { + auto depends_on_data_name = depends_on_data.first; + auto depends_on_data_state = depends_on_data.second; + + if (!depends_on_data_state) { + to_be_updated = false; + break; + } + } + if (to_be_updated) { //Update the parameter + PDI::Expression prm_value = m_parameter_expression.at(prm_name); + damaris::model::DamarisParameterXML prmxml = m_parameters.at(prm_name); + prmxml.param_value_ = prm_value.to_string(ctx); + //ctx.logger().info("------------------------------------------------------------------------------------In get_updatable_parameters `{}' prmxml.param_value_ = '{}'", prm_name, prmxml.param_value_); + std::pair update_info; + update_info.first = prm_value.to_string(ctx); + update_info.second = prmxml.param_datatype_; + + updatable_parameters.emplace(prm_name, update_info); + } + } + + return updatable_parameters; +} + +void Damaris_cfg::reset_parameter_depends_on(std::string prm_name) +{ + if (m_parameter_depends_on.find(prm_name) == m_parameter_depends_on.end()) { + // not found + // handle the error + } else { + std::unordered_map prm_depends_on_data = m_parameter_depends_on.at(prm_name); + for (auto depends_on_data: prm_depends_on_data) { + depends_on_data.second = false; + } + } +} + +void Damaris_cfg::reset_parameter_depends_on(std::vector prm_list) +{ + for (auto prm_name: prm_list) { + reset_parameter_depends_on(prm_name); + } +} + +void Damaris_cfg::reset_all_parameters_depends_on() +{ + for (auto prm_depends_on: m_parameter_depends_on) { + auto prm_name = prm_depends_on.first; + auto prm_depends_on_data = prm_depends_on.second; + + for (auto depends_on_data: prm_depends_on_data) { + depends_on_data.second = false; + } + } +} + +// Retrive nested groups names from a dataset_elt_full_name (gp1/gp2/.../dataset_elt_name) +void retrive_nested_groups(std::string& dataset_elt_full_name, char delimiter, std::string nested_groups_names[], unsigned& index) +{ + // Creating an input string stream from the dataset_elt_full_name + std::istringstream namestream(dataset_elt_full_name); + + // Tmp string + string gp_name; + + // Retrive names from the string stream separated by the delimiter + while (getline(namestream, gp_name, delimiter)) { + if (index == max_nested_groups) { + throw Value_error{"Damaris variable/layout/mesh can be nested in more than {} groups", max_nested_groups}; + } + // Add the gp_name to the array + nested_groups_names[index++] = gp_name; + } + //If index==1, there is no group, ie: nested_groups_names[index-1] = dataset_elt_full_name +} + +template +void insert_dataset_elts_to_group(DS_TYPE ds_elt_xml, std::string nested_groups_names[], unsigned index) +{ + std::string nearest_group_name = nested_groups_names[index - 2]; + bool root_group_exists = false; + damaris::model::DamarisGroupXML* nearest_parent_group = NULL; + for (int root_group_id = 0; root_group_id < root_groups_xml.size(); root_group_id++) { + damaris::model::DamarisGroupXML* root_gp_xml = &root_groups_xml[root_group_id]; + + if (nested_groups_names[0] == root_gp_xml->get_name()) { + if (nearest_group_name == root_gp_xml->get_name()) { + //printf("-------------------------------------------------------------------------------------In root_gp_xml.get_name() = %s, FOR Variable %s, nearest_group_name == root_gp_xml.get_name() = %d\n", root_gp_xml->get_name().c_str(), nested_groups_names[index -1].c_str(), (nearest_group_name == root_gp_xml->get_name())); + //root_gp_xml->add_variable(ds_elt_xml); + root_gp_xml->add_ds_element(ds_elt_xml); + + //free(root_gp_xml); + return; + } + nearest_parent_group = root_gp_xml; + root_group_exists = true; + break; + } + + //free(root_gp_xml); + } + + //Insertion in an existing nested group + bool insertion_group_found = false; + int group_id = 1; + if (root_group_exists) { + while (group_id <= (index - 2) && !insertion_group_found) { + std::string group_name = nested_groups_names[group_id]; + + insertion_group_found = true; + std::vector sub_groups = nearest_parent_group->get_sub_groups(); + for (int group_id = 0; group_id < sub_groups.size(); group_id++) { + if (group_name == sub_groups[group_id].get_name()) { + if (nearest_group_name == sub_groups[group_id].get_name()) { + //(&sub_groups[group_id])->add_variable(ds_elt_xml); + (&sub_groups[group_id])->add_ds_element(ds_elt_xml); + + return; + } + insertion_group_found = false; + nearest_parent_group = &sub_groups[group_id++]; + break; + } + } + } + } + //The nested groups has to be created + else { + damaris::model::DamarisGroupXML root_gp_xml{nested_groups_names[0]}; + + if (nearest_group_name == root_gp_xml.get_name()) { + //root_gp_xml.add_variable(ds_elt_xml); + root_gp_xml.add_ds_element(ds_elt_xml); + root_groups_xml.emplace_back(root_gp_xml); + + return; + } + + root_groups_xml.emplace_back(root_gp_xml); + + nearest_parent_group = &root_gp_xml; + insertion_group_found = true; + } + + //Insertion point found + if (insertion_group_found) { + damaris::model::DamarisGroupXML linked_parent_group{nearest_group_name}; + for (unsigned insertion_group_id = (index - 2); insertion_group_id >= group_id; insertion_group_id--) { + std::string group_name = nested_groups_names[insertion_group_id]; + damaris::model::DamarisGroupXML sub_gp_xml{group_name}; + if (nearest_group_name == sub_gp_xml.get_name()) { + //sub_gp_xml.add_variable(ds_elt_xml); + sub_gp_xml.add_ds_element(ds_elt_xml); + } else { + sub_gp_xml.add_sub_group(linked_parent_group); + } + linked_parent_group = sub_gp_xml; + } + nearest_parent_group->add_sub_group(linked_parent_group); + } + + //free(nearest_parent_group); +} + +/* void insert_dataset_elts_to_group(damaris::model::DamarisVarXML varxml, std::string nested_groups_names[], unsigned index) { std::string nearest_group_name = nested_groups_names[index -2]; @@ -1425,115 +1238,117 @@ } } */ - - const string& Damaris_cfg::xml_config_object( void ) - { - m_xml_config_object = damarisXMLModifyModel.GetConfigString(); - return m_xml_config_object; - } - - //const PDI::Expression& Damaris_cfg::communicator() const - PDI::Expression Damaris_cfg::communicator() const - { - return m_communicator; - } - - const unordered_map& Damaris_cfg::datasets() const - { - return m_datasets; - } - const unordered_map& Damaris_cfg::layouts() const - { - return m_layouts; - } - - const unordered_map& Damaris_cfg::parameters() const - { - return m_parameters; - } + +const string& Damaris_cfg::xml_config_object(void) +{ + m_xml_config_object = damarisXMLModifyModel.GetConfigString(); + return m_xml_config_object; +} + +//const PDI::Expression& Damaris_cfg::communicator() const +PDI::Expression Damaris_cfg::communicator() const +{ + return m_communicator; +} + +const unordered_map& Damaris_cfg::datasets() const +{ + return m_datasets; +} + +const unordered_map& Damaris_cfg::layouts() const +{ + return m_layouts; +} + +const unordered_map& Damaris_cfg::parameters() const +{ + return m_parameters; +} const damaris::model::DamarisParameterXML Damaris_cfg::get_parameter_xml(string prm_name) const { - return m_parameters.at(prm_name); + return m_parameters.at(prm_name); } - - const std::unordered_map& Damaris_cfg::storages() const - { - return m_storages; - } - - const std::unordered_map& Damaris_cfg::meshes() const - { - return m_meshes; - } - - const std::unordered_map& Damaris_cfg::groups() const - { - return m_groups; - } - - const unordered_map& Damaris_cfg::descs() const - { - return m_descs; - } - - const unordered_map& Damaris_cfg::events() const - { - return m_events; - } - - const std::unordered_map& Damaris_cfg::datasets_to_write() const - { - return m_datasets_to_write; - } - - const std::unordered_map>& Damaris_cfg::parameter_to_update() const - { - return m_parameter_to_update; - } - - Dataset_Write_Info Damaris_cfg::get_dataset_write_info(std::string data_name) const - { - try{ - return m_datasets_to_write.at(data_name); - } catch (...) { - assert(false && "Trying to get inexistant damaris awaited dataset!"); - } - } - - std::pair Damaris_cfg::get_parameter_to_update_info(std::string data_name) const - { - try{ - return m_parameter_to_update.at(data_name); - } catch (...) { - assert(false && "Trying to get inexistant damaris awaited dataset!"); - } - } - - std::string Damaris_cfg::init_on_event() const - { - return m_init_on_event; - } - - std::string Damaris_cfg::finalize_on_event() const - { - return m_finalize_on_event; - } - - - std::string Damaris_cfg::start_on_event() const - { - return m_start_on_event; - } - - std::string Damaris_cfg::stop_on_event() const - { - return m_stop_on_event; - } - - std::string Damaris_cfg::end_iteration_on_event() const - { - return m_end_iteration_on_event; - } - - } // namespace damaris_pdi \ No newline at end of file + +const std::unordered_map& Damaris_cfg::storages() const +{ + return m_storages; +} + +const std::unordered_map& Damaris_cfg::meshes() const +{ + return m_meshes; +} + +const std::unordered_map& Damaris_cfg::groups() const +{ + return m_groups; +} + +const unordered_map& Damaris_cfg::descs() const +{ + return m_descs; +} + +const unordered_map& Damaris_cfg::events() const +{ + return m_events; +} + +const std::unordered_map& Damaris_cfg::datasets_to_write() const +{ + return m_datasets_to_write; +} + +const std::unordered_map>& Damaris_cfg::parameter_to_update() const +{ + return m_parameter_to_update; +} + +Dataset_Write_Info Damaris_cfg::get_dataset_write_info(std::string data_name) const +{ + try { + return m_datasets_to_write.at(data_name); + } catch (...) { + assert(false && "Trying to get inexistant damaris awaited dataset!"); + } +} + +std::pair Damaris_cfg::get_parameter_to_update_info(std::string data_name) const +{ + try { + return m_parameter_to_update.at(data_name); + } catch (...) { + assert(false && "Trying to get inexistant damaris awaited dataset!"); + } +} + +std::string Damaris_cfg::init_on_event() const +{ + return m_init_on_event; +} + +std::string Damaris_cfg::finalize_on_event() const +{ + return m_finalize_on_event; +} + +std::string Damaris_cfg::start_on_event() const +{ + return m_start_on_event; +} + +std::string Damaris_cfg::stop_on_event() const +{ + return m_stop_on_event; +} + +std::string Damaris_cfg::end_iteration_on_event() const +{ + return m_end_iteration_on_event; +} + +std::string Damaris_cfg::m_is_client_dataset_name = ""; + +} // namespace damaris_pdi diff --git a/plugins/damaris/example/example.c b/plugins/damaris/example/example.c index cc7fc0f76..8e7ca52bd 100644 --- a/plugins/damaris/example/example.c +++ b/plugins/damaris/example/example.c @@ -158,117 +158,117 @@ int main(int argc, char* argv[]) fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); } - + PC_tree_t conf = PC_parse_path(argv[1]); MPI_Comm main_comm = MPI_COMM_WORLD; int world_size; MPI_Comm_size(MPI_COMM_WORLD, &world_size); - if(world_size!=4) { + if (world_size != 4) { fprintf(stderr, "Please use 4 mpi processes in total\n"); exit(1); } PDI_init(PC_get(conf, ".pdi")); PDI_event("init"); - + int is_client = -1; - + //PDI_expose("is_client", &is_client, PDI_IN); - PDI_expose("is_client", &is_client, PDI_INOUT); // <-- allow plugin to set - PDI_expose("mpi_comm", &main_comm, PDI_INOUT); // <-- allow plugin to set - - if(is_client) { - //*******************************************************************Only damaris clients run this section - - int psize_1d; - MPI_Comm_size(main_comm, &psize_1d); - int pcoord_1d; - MPI_Comm_rank(main_comm, &pcoord_1d); - - PDI_expose("mpi_rank", &pcoord_1d, PDI_OUT); - PDI_expose("mpi_size", &psize_1d, PDI_OUT); - //PDI_event("init"); - - long longval; - - int dsize[2]; - PC_int(PC_get(conf, ".datasize[0]"), &longval); - dsize[0] = longval; - PC_int(PC_get(conf, ".datasize[1]"), &longval); - dsize[1] = longval; - - int psize[2]; - PC_int(PC_get(conf, ".parallelism.height"), &longval); - psize[0] = longval; - PC_int(PC_get(conf, ".parallelism.width"), &longval); - psize[1] = longval; - - double duration; - PC_double(PC_get(conf, ".duration"), &duration); - - // get local & add ghosts to sizes - assert(dsize[0] % psize[0] == 0); - dsize[0] = dsize[0] / psize[0] + 2; - assert(dsize[1] % psize[1] == 0); - dsize[1] = dsize[1] / psize[1] + 2; - - assert(psize[1] * psize[0] == psize_1d); - - int cart_period[2] = {0, 0}; - MPI_Comm cart_com; - MPI_Cart_create(main_comm, 2, psize, cart_period, 1, &cart_com); - int pcoord[2]; - MPI_Cart_coords(cart_com, pcoord_1d, 2, pcoord); - - int ii = 0; - PDI_expose("iter", &ii, PDI_OUT); - PDI_expose("dsize", dsize, PDI_OUT); - PDI_expose("psize", psize, PDI_OUT); - PDI_expose("pcoord", pcoord, PDI_OUT); - - double(*cur)[dsize[1]] = malloc(sizeof(double) * dsize[1] * dsize[0]); - double(*next)[dsize[1]] = malloc(sizeof(double) * dsize[1] * dsize[0]); - - init(dsize, pcoord, cur); - - PDI_event("main_loop"); - double start = MPI_Wtime(); - int next_reduce = 0; - for (ii = 0; ii<10; ++ii) { - PDI_multi_expose("newiter", "iter", &ii, PDI_INOUT, "main_field", cur, PDI_INOUT, NULL); - - iter(dsize, cur, next); - exchange(cart_com, dsize, next); - double(*tmp)[dsize[1]] = cur; - cur = next; - next = tmp; - - // if (ii >= next_reduce) { - // double local_time, global_time; - // local_time = MPI_Wtime() - start; - // MPI_Allreduce(&local_time, &global_time, 1, MPI_DOUBLE, MPI_MAX, main_comm); - // if (global_time >= duration) { - // if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; STOP!!!\n", ii, global_time); - // break; - // } - // int rem_iter = .9 * (duration - global_time) * (ii + 1) / (global_time + 0.1); - // if (rem_iter < 1) rem_iter = 1; - // next_reduce = ii + rem_iter; - // if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; next_reduce=%7d\n", ii, global_time, next_reduce); - // } - //PDI_event("damaris_end_iteration"); - } - PDI_event("finalization"); - PDI_expose("iter", &ii, PDI_OUT); - PDI_expose("main_field", cur, PDI_OUT); - - //moved here to be in the scope, since if(is_client) has been added - free(cur); - free(next); - - //PDI_event("damaris_stop"); - //*******************************************************************END if(is_client) - }//END if(is_client) + PDI_expose("is_client", &is_client, PDI_INOUT); // <-- allow plugin to set + PDI_expose("mpi_comm", &main_comm, PDI_INOUT); // <-- allow plugin to set + + if (is_client) { + //*******************************************************************Only damaris clients run this section + + int psize_1d; + MPI_Comm_size(main_comm, &psize_1d); + int pcoord_1d; + MPI_Comm_rank(main_comm, &pcoord_1d); + + PDI_expose("mpi_rank", &pcoord_1d, PDI_OUT); + PDI_expose("mpi_size", &psize_1d, PDI_OUT); + //PDI_event("init"); + + long longval; + + int dsize[2]; + PC_int(PC_get(conf, ".datasize[0]"), &longval); + dsize[0] = longval; + PC_int(PC_get(conf, ".datasize[1]"), &longval); + dsize[1] = longval; + + int psize[2]; + PC_int(PC_get(conf, ".parallelism.height"), &longval); + psize[0] = longval; + PC_int(PC_get(conf, ".parallelism.width"), &longval); + psize[1] = longval; + + double duration; + PC_double(PC_get(conf, ".duration"), &duration); + + // get local & add ghosts to sizes + assert(dsize[0] % psize[0] == 0); + dsize[0] = dsize[0] / psize[0] + 2; + assert(dsize[1] % psize[1] == 0); + dsize[1] = dsize[1] / psize[1] + 2; + + assert(psize[1] * psize[0] == psize_1d); + + int cart_period[2] = {0, 0}; + MPI_Comm cart_com; + MPI_Cart_create(main_comm, 2, psize, cart_period, 1, &cart_com); + int pcoord[2]; + MPI_Cart_coords(cart_com, pcoord_1d, 2, pcoord); + + int ii = 0; + PDI_expose("iter", &ii, PDI_OUT); + PDI_expose("dsize", dsize, PDI_OUT); + PDI_expose("psize", psize, PDI_OUT); + PDI_expose("pcoord", pcoord, PDI_OUT); + + double (*cur)[dsize[1]] = malloc(sizeof(double) * dsize[1] * dsize[0]); + double (*next)[dsize[1]] = malloc(sizeof(double) * dsize[1] * dsize[0]); + + init(dsize, pcoord, cur); + + PDI_event("main_loop"); + double start = MPI_Wtime(); + int next_reduce = 0; + for (ii = 0; ii < 10; ++ii) { + PDI_multi_expose("newiter", "iter", &ii, PDI_INOUT, "main_field", cur, PDI_INOUT, NULL); + + iter(dsize, cur, next); + exchange(cart_com, dsize, next); + double (*tmp)[dsize[1]] = cur; + cur = next; + next = tmp; + + // if (ii >= next_reduce) { + // double local_time, global_time; + // local_time = MPI_Wtime() - start; + // MPI_Allreduce(&local_time, &global_time, 1, MPI_DOUBLE, MPI_MAX, main_comm); + // if (global_time >= duration) { + // if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; STOP!!!\n", ii, global_time); + // break; + // } + // int rem_iter = .9 * (duration - global_time) * (ii + 1) / (global_time + 0.1); + // if (rem_iter < 1) rem_iter = 1; + // next_reduce = ii + rem_iter; + // if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; next_reduce=%7d\n", ii, global_time, next_reduce); + // } + //PDI_event("damaris_end_iteration"); + } + PDI_event("finalization"); + PDI_expose("iter", &ii, PDI_OUT); + PDI_expose("main_field", cur, PDI_OUT); + + //moved here to be in the scope, since if(is_client) has been added + free(cur); + free(next); + + //PDI_event("damaris_stop"); + //*******************************************************************END if(is_client) + } //END if(is_client) PDI_finalize(); From 16881826f7ede6b8629d2b4cb4f799e026cc9631 Mon Sep 17 00:00:00 2001 From: yushan wang Date: Mon, 9 Mar 2026 10:41:48 +0100 Subject: [PATCH 22/42] update author --- plugins/damaris/AUTHORS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/damaris/AUTHORS b/plugins/damaris/AUTHORS index 80a2da924..f58f6f3a2 100644 --- a/plugins/damaris/AUTHORS +++ b/plugins/damaris/AUTHORS @@ -10,3 +10,9 @@ Josh Bowden - Inria (joshua-charles.bowden@inria.fr) Etienne Ndamlabin - Inria (jean-etienne.ndamlabin-mboula@inria.fr) * Maintainer (Oct. 2024 - ...) * (Re-)Design and initial implementation + +Jacques Morice - CEA (jacques.morice@cea.fr) +* Developper + +Yushan Wang - CEA (yushan.wang@cea.fr) +* Developper \ No newline at end of file From db06cf929c06b17d7d12f34733e7f22ca6895ff4 Mon Sep 17 00:00:00 2001 From: yushan wang Date: Mon, 9 Mar 2026 15:33:07 +0100 Subject: [PATCH 23/42] fix helper message for example --- plugins/damaris/example/example.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/damaris/example/example.c b/plugins/damaris/example/example.c index 8e7ca52bd..6f607cc12 100644 --- a/plugins/damaris/example/example.c +++ b/plugins/damaris/example/example.c @@ -164,8 +164,8 @@ int main(int argc, char* argv[]) MPI_Comm main_comm = MPI_COMM_WORLD; int world_size; MPI_Comm_size(MPI_COMM_WORLD, &world_size); - if (world_size != 4) { - fprintf(stderr, "Please use 4 mpi processes in total\n"); + if (world_size < 4) { + fprintf(stderr, "Please use at least 4 mpi processes\n"); exit(1); } PDI_init(PC_get(conf, ".pdi")); From abbf39282f568a2491113de4e4e615884cab70df Mon Sep 17 00:00:00 2001 From: yushan wang Date: Mon, 9 Mar 2026 17:14:15 +0100 Subject: [PATCH 24/42] fix merge conflit --- plugins/damaris/example/example.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/damaris/example/example.c b/plugins/damaris/example/example.c index 6f607cc12..47d6c071d 100644 --- a/plugins/damaris/example/example.c +++ b/plugins/damaris/example/example.c @@ -158,7 +158,7 @@ int main(int argc, char* argv[]) fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); } - + PC_tree_t conf = PC_parse_path(argv[1]); MPI_Comm main_comm = MPI_COMM_WORLD; From 0e72d6371646dfdbfae58dbdaf1f849dbb0f86f6 Mon Sep 17 00:00:00 2001 From: yushan wang Date: Mon, 9 Mar 2026 17:16:36 +0100 Subject: [PATCH 25/42] fix merge conflict --- plugins/damaris/damaris_api_call_handler.cxx | 14 -------------- plugins/damaris/damaris_cfg.cxx | 2 -- plugins/damaris/example/CMakeLists.txt | 12 ++++++------ 3 files changed, 6 insertions(+), 22 deletions(-) diff --git a/plugins/damaris/damaris_api_call_handler.cxx b/plugins/damaris/damaris_api_call_handler.cxx index 9aeca6dcb..9a3b31cb3 100644 --- a/plugins/damaris/damaris_api_call_handler.cxx +++ b/plugins/damaris/damaris_api_call_handler.cxx @@ -137,20 +137,6 @@ void Damaris_api_call_handler::damaris_api_call_event( break; } - //-----------------------Workaround to hide is_client from user----------------------- - //If it is a server and no `if(is_client) {}` closure: - // - all its clients have ended - // - we can stop it from here, since there is no more if(is_client) {} closure - if (!is_client && Damaris_cfg::is_client_dataset_name().empty()) // - { - ctx.logger().info( - "------------------- In if(!is_client): Damaris_cfg::is_client_dataset_name() = '{}')", - Damaris_cfg::is_client_dataset_name() - ); - PDI_finalize(); - MPI_Finalize(); - exit(0); - } } //************************************************************ */ diff --git a/plugins/damaris/damaris_cfg.cxx b/plugins/damaris/damaris_cfg.cxx index 74cc68fa9..5b6e892f9 100644 --- a/plugins/damaris/damaris_cfg.cxx +++ b/plugins/damaris/damaris_cfg.cxx @@ -1349,6 +1349,4 @@ std::string Damaris_cfg::end_iteration_on_event() const return m_end_iteration_on_event; } -std::string Damaris_cfg::m_is_client_dataset_name = ""; - } // namespace damaris_pdi diff --git a/plugins/damaris/example/CMakeLists.txt b/plugins/damaris/example/CMakeLists.txt index ddba576ba..f0b5539f5 100644 --- a/plugins/damaris/example/CMakeLists.txt +++ b/plugins/damaris/example/CMakeLists.txt @@ -1,7 +1,7 @@ -add_subdirectory (storage) -add_subdirectory (paraview) -add_subdirectory (python) +# add_subdirectory (storage) +# add_subdirectory (paraview) +# add_subdirectory (python) -add_executable (exemple exemple.c) -target_link_libraries (exemple PDI::PDI_C MPI::MPI_CXX) -set_target_properties (exemple PROPERTIES LINK_FLAGS "-Wl,-export-dynamic") \ No newline at end of file +add_executable (example example.c) +target_link_libraries (example PDI::PDI_C MPI::MPI_CXX) +# set_target_properties (example PROPERTIES LINK_FLAGS "-Wl,-export-dynamic") \ No newline at end of file From c45a9697e0f04691e415994692c0e4b2f527ab0d Mon Sep 17 00:00:00 2001 From: Etienne Ndamlabin <88906611+endamlabin@users.noreply.github.com> Date: Wed, 1 Apr 2026 10:49:56 +0200 Subject: [PATCH 26/42] Ensure each PDI_access has an associated PDI_release (resolves #20) (#23) --- plugins/damaris/damaris_api_call_handler.cxx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plugins/damaris/damaris_api_call_handler.cxx b/plugins/damaris/damaris_api_call_handler.cxx index 9a3b31cb3..8eac5bddc 100644 --- a/plugins/damaris/damaris_api_call_handler.cxx +++ b/plugins/damaris/damaris_api_call_handler.cxx @@ -132,6 +132,7 @@ void Damaris_api_call_handler::damaris_api_call_event( PDI_access(it->c_str(), (void**)&inout_is_client, PDI_INOUT); *inout_is_client = is_client; arg1_name = it->c_str(); + PDI_release(it->c_str()); } else //if(nb_awaited_args <= arg_pos) break; @@ -241,6 +242,7 @@ void Damaris_api_call_handler::damaris_api_call_event( PDI_access(it->c_str(), (void**)&comm, PDI_INOUT); *comm = client_comm; //Update the value arg1_name = it->c_str(); + PDI_release(it->c_str()); } else //if(nb_awaited_args <= arg_pos) break; @@ -286,9 +288,11 @@ void Damaris_api_call_handler::damaris_api_call_event( if (arg_pos == 1) { PDI_access(it->c_str(), (void**)&var_name, PDI_IN); arg1_name = it->c_str(); + PDI_release(it->c_str()); } else if (arg_pos == 2) { PDI_access(it->c_str(), (void**)&position, PDI_IN); arg2_name = it->c_str(); + PDI_release(it->c_str()); } else //if(nb_awaited_args <= arg_pos) break; @@ -343,9 +347,11 @@ void Damaris_api_call_handler::damaris_api_call_event( if (arg_pos == 1) { PDI_access(it->c_str(), (void**)&var_name, PDI_IN); arg1_name = it->c_str(); + PDI_release(it->c_str()); } else if (arg_pos == 2) { PDI_access(it->c_str(), (void**)&data, PDI_IN); arg2_name = it->c_str(); + PDI_release(it->c_str()); } else //if(nb_awaited_args <= arg_pos) break; @@ -393,12 +399,15 @@ void Damaris_api_call_handler::damaris_api_call_event( if (arg_pos == 1) { PDI_access(it->c_str(), (void**)&var_name, PDI_IN); arg1_name = it->c_str(); + PDI_release(it->c_str()); } else if (arg_pos == 2) { PDI_access(it->c_str(), (void**)&block, PDI_IN); arg2_name = it->c_str(); + PDI_release(it->c_str()); } else if (arg_pos == 3) { PDI_access(it->c_str(), (void**)&position, PDI_IN); arg3_name = it->c_str(); + PDI_release(it->c_str()); } else //if(nb_awaited_args <= arg_pos) break; @@ -454,12 +463,15 @@ void Damaris_api_call_handler::damaris_api_call_event( if (arg_pos == 1) { PDI_access(it->c_str(), (void**)&var_name, PDI_IN); arg1_name = it->c_str(); + PDI_release(it->c_str()); } else if (arg_pos == 2) { PDI_access(it->c_str(), (void**)&block, PDI_IN); arg2_name = it->c_str(); + PDI_release(it->c_str()); } else if (arg_pos == 3) { PDI_access(it->c_str(), (void**)&data, PDI_IN); arg3_name = it->c_str(); + PDI_release(it->c_str()); } else //if(nb_awaited_args <= arg_pos) break; From 787009da025b8ff7f2566d8554db0566d7357c52 Mon Sep 17 00:00:00 2001 From: Etienne Ndamlabin <88906611+endamlabin@users.noreply.github.com> Date: Wed, 1 Apr 2026 11:24:44 +0200 Subject: [PATCH 27/42] Hide is_client from user, and ending damaris server in background: (#18) * Hide is_client from user, and ending damaris server in background: - The condition to do that is to always have this sequence at the end of the simulation: PDI_finalize(); MPI_Finalize(); - Or provide in the yml conf the code following PDI_finalize(); - Code like the following could not be handled for the moment. But in the future by providing the instructions to execute...: PDI_finalize(); PC_tree_destroy(&conf); free(cur); free(next); MPI_Finalize(); * update copyright * Removing on_init and on_finalize --- plugins/damaris/damaris.cxx | 6 +- plugins/damaris/damaris_api_call_handler.cxx | 15 ++ plugins/damaris/damaris_cfg.cxx | 4 + plugins/damaris/damaris_cfg.h | 18 +- plugins/damaris/example/example.c | 184 +++++++++---------- plugins/damaris/example/example.yml | 9 +- 6 files changed, 119 insertions(+), 117 deletions(-) diff --git a/plugins/damaris/damaris.cxx b/plugins/damaris/damaris.cxx index 4b94b5d35..e4d4b4904 100644 --- a/plugins/damaris/damaris.cxx +++ b/plugins/damaris/damaris.cxx @@ -127,7 +127,7 @@ class damaris_plugin: public Plugin { ensure_damaris_is_initialized(""); - context().logger().info("data `{}' has been exposed", name); + //context().logger().info("data `{}' has been exposed", name);//too verbose //Update damaris parameters if (m_config.is_needed_metadata(name)) { @@ -144,7 +144,7 @@ class damaris_plugin: public Plugin void* prm_value_buffer; size_t prm_buffer_size; if(std::find(std::begin(int_numbers_types), std::end(int_numbers_types), prm_type) != std::end(int_numbers_types)) { - std::cout << "int_numbers_types contains " << prm_type << '\n'; + //std::cout << "int_numbers_types contains " << prm_type << '\n';//Can be too verbose int prm_long_value = std::atoi(prm_value.c_str()); prm_value_buffer = &prm_long_value; prm_buffer_size = sizeof(int); @@ -184,7 +184,7 @@ class damaris_plugin: public Plugin context().logger().info("data `{}' Is a needed metadata for the evaluation of parameters {}", name, prm_name_concat); } } else if (m_config.is_dataset_to_write(name)) { - context().logger().info("is_dataset_to_write(`{}') = '{}'", name, m_config.is_dataset_to_write(name)); + //context().logger().info("is_dataset_to_write(`{}') = '{}'", name, m_config.is_dataset_to_write(name));//too verbose if (Ref_r rref = ref) { Dataset_Write_Info ds_write_info = m_config.get_dataset_write_info(name); diff --git a/plugins/damaris/damaris_api_call_handler.cxx b/plugins/damaris/damaris_api_call_handler.cxx index 8eac5bddc..34aa89823 100644 --- a/plugins/damaris/damaris_api_call_handler.cxx +++ b/plugins/damaris/damaris_api_call_handler.cxx @@ -138,6 +138,21 @@ void Damaris_api_call_handler::damaris_api_call_event( break; } + //-----------------------Workaround to hide is_client from user----------------------- + //If it is a server and no `if(is_client) {}` closure: + // - all its clients have ended + // - we can stop it from here, since there is no more if(is_client) {} closure + if(!is_client && Damaris_cfg::is_client_dataset_name().empty()) { + + //TODO: consider (in the future) a user code to execute if defined (dc_ending_operations) + if(!Damaris_cfg::client_comm_get_dataset_name().empty()) { + //release the Damaris clients mpi comm + PDI_release(Damaris_cfg::client_comm_get_dataset_name().c_str()); + } + PDI_finalize(); + MPI_Finalize(); + exit(0); + } } //************************************************************ */ diff --git a/plugins/damaris/damaris_cfg.cxx b/plugins/damaris/damaris_cfg.cxx index 5b6e892f9..3873c23ea 100644 --- a/plugins/damaris/damaris_cfg.cxx +++ b/plugins/damaris/damaris_cfg.cxx @@ -1348,5 +1348,9 @@ std::string Damaris_cfg::end_iteration_on_event() const { return m_end_iteration_on_event; } + + +std::string Damaris_cfg::m_is_client_dataset_name = ""; +std::string Damaris_cfg::m_client_comm_get_dataset_name = ""; } // namespace damaris_pdi diff --git a/plugins/damaris/damaris_cfg.h b/plugins/damaris/damaris_cfg.h index 78070fcf5..57e7dc628 100644 --- a/plugins/damaris/damaris_cfg.h +++ b/plugins/damaris/damaris_cfg.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2024 National Institute for Research in Digital Science and Technology (Inria) * All rights reserved. * @@ -181,8 +181,8 @@ const std::unordered_map event_names = { std::unordered_map> m_layout_depends_on; std::unordered_map m_layout_expression; - std::string m_is_client_dataset_name = ""; - std::string m_client_comm_get_dataset_name = ""; + static std::string m_is_client_dataset_name; + static std::string m_client_comm_get_dataset_name; const std::string XML_CONFIG_TEMPLATE = R"V0G0N( @@ -271,19 +271,19 @@ const std::unordered_map event_names = { std::pair get_parameter_to_update_info(std::string data_name) const; list get_after_write_events() const { - return m_after_write_events; + return m_after_write_events; } bool is_there_after_write_events() const { - return m_after_write_events.size(); + return m_after_write_events.size(); } - std::string is_client_dataset_name() const + static std::string is_client_dataset_name() { - return m_is_client_dataset_name; + return m_is_client_dataset_name; } - std::string client_comm_get_dataset_name() const + static std::string client_comm_get_dataset_name() { - return m_client_comm_get_dataset_name; + return m_client_comm_get_dataset_name; } std::string init_on_event() const; diff --git a/plugins/damaris/example/example.c b/plugins/damaris/example/example.c index 47d6c071d..484b3f2e9 100644 --- a/plugins/damaris/example/example.c +++ b/plugins/damaris/example/example.c @@ -169,113 +169,95 @@ int main(int argc, char* argv[]) exit(1); } PDI_init(PC_get(conf, ".pdi")); - PDI_event("init"); - - int is_client = -1; - - //PDI_expose("is_client", &is_client, PDI_IN); - PDI_expose("is_client", &is_client, PDI_INOUT); // <-- allow plugin to set - PDI_expose("mpi_comm", &main_comm, PDI_INOUT); // <-- allow plugin to set - - if (is_client) { - //*******************************************************************Only damaris clients run this section - - int psize_1d; - MPI_Comm_size(main_comm, &psize_1d); - int pcoord_1d; - MPI_Comm_rank(main_comm, &pcoord_1d); - - PDI_expose("mpi_rank", &pcoord_1d, PDI_OUT); - PDI_expose("mpi_size", &psize_1d, PDI_OUT); - //PDI_event("init"); - - long longval; - - int dsize[2]; - PC_int(PC_get(conf, ".datasize[0]"), &longval); - dsize[0] = longval; - PC_int(PC_get(conf, ".datasize[1]"), &longval); - dsize[1] = longval; - - int psize[2]; - PC_int(PC_get(conf, ".parallelism.height"), &longval); - psize[0] = longval; - PC_int(PC_get(conf, ".parallelism.width"), &longval); - psize[1] = longval; - - double duration; - PC_double(PC_get(conf, ".duration"), &duration); - - // get local & add ghosts to sizes - assert(dsize[0] % psize[0] == 0); - dsize[0] = dsize[0] / psize[0] + 2; - assert(dsize[1] % psize[1] == 0); - dsize[1] = dsize[1] / psize[1] + 2; - - assert(psize[1] * psize[0] == psize_1d); - - int cart_period[2] = {0, 0}; - MPI_Comm cart_com; - MPI_Cart_create(main_comm, 2, psize, cart_period, 1, &cart_com); - int pcoord[2]; - MPI_Cart_coords(cart_com, pcoord_1d, 2, pcoord); - - int ii = 0; - PDI_expose("iter", &ii, PDI_OUT); - PDI_expose("dsize", dsize, PDI_OUT); - PDI_expose("psize", psize, PDI_OUT); - PDI_expose("pcoord", pcoord, PDI_OUT); - - double (*cur)[dsize[1]] = malloc(sizeof(double) * dsize[1] * dsize[0]); - double (*next)[dsize[1]] = malloc(sizeof(double) * dsize[1] * dsize[0]); - - init(dsize, pcoord, cur); - - PDI_event("main_loop"); - double start = MPI_Wtime(); - int next_reduce = 0; - for (ii = 0; ii < 10; ++ii) { - PDI_multi_expose("newiter", "iter", &ii, PDI_INOUT, "main_field", cur, PDI_INOUT, NULL); - - iter(dsize, cur, next); - exchange(cart_com, dsize, next); - double (*tmp)[dsize[1]] = cur; - cur = next; - next = tmp; - - // if (ii >= next_reduce) { - // double local_time, global_time; - // local_time = MPI_Wtime() - start; - // MPI_Allreduce(&local_time, &global_time, 1, MPI_DOUBLE, MPI_MAX, main_comm); - // if (global_time >= duration) { - // if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; STOP!!!\n", ii, global_time); - // break; - // } - // int rem_iter = .9 * (duration - global_time) * (ii + 1) / (global_time + 0.1); - // if (rem_iter < 1) rem_iter = 1; - // next_reduce = ii + rem_iter; - // if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; next_reduce=%7d\n", ii, global_time, next_reduce); - // } - //PDI_event("damaris_end_iteration"); - } - PDI_event("finalization"); - PDI_expose("iter", &ii, PDI_OUT); - PDI_expose("main_field", cur, PDI_OUT); - - //moved here to be in the scope, since if(is_client) has been added - free(cur); - free(next); - //PDI_event("damaris_stop"); - //*******************************************************************END if(is_client) - } //END if(is_client) + PDI_expose("mpi_comm", &main_comm, PDI_INOUT); // <-- allow plugin to set, returns Damaris client comm + + int psize_1d; + MPI_Comm_size(main_comm, &psize_1d); + int pcoord_1d; + MPI_Comm_rank(main_comm, &pcoord_1d); + + PDI_expose("mpi_rank", &pcoord_1d, PDI_OUT); + PDI_expose("mpi_size", &psize_1d, PDI_OUT); + + long longval; + + int dsize[2]; + PC_int(PC_get(conf, ".datasize[0]"), &longval); + dsize[0] = longval; + PC_int(PC_get(conf, ".datasize[1]"), &longval); + dsize[1] = longval; + + int psize[2]; + PC_int(PC_get(conf, ".parallelism.height"), &longval); + psize[0] = longval; + PC_int(PC_get(conf, ".parallelism.width"), &longval); + psize[1] = longval; + + double duration; + PC_double(PC_get(conf, ".duration"), &duration); + + // get local & add ghosts to sizes + assert(dsize[0] % psize[0] == 0); + dsize[0] = dsize[0] / psize[0] + 2; + assert(dsize[1] % psize[1] == 0); + dsize[1] = dsize[1] / psize[1] + 2; + + assert(psize[1] * psize[0] == psize_1d); + + int cart_period[2] = {0, 0}; + MPI_Comm cart_com; + MPI_Cart_create(main_comm, 2, psize, cart_period, 1, &cart_com); + int pcoord[2]; + MPI_Cart_coords(cart_com, pcoord_1d, 2, pcoord); + + int ii = 0; + PDI_expose("iter", &ii, PDI_OUT); + PDI_expose("dsize", dsize, PDI_OUT); + PDI_expose("psize", psize, PDI_OUT); + PDI_expose("pcoord", pcoord, PDI_OUT); + + double (*cur)[dsize[1]] = malloc(sizeof(double) * dsize[1] * dsize[0]); + double (*next)[dsize[1]] = malloc(sizeof(double) * dsize[1] * dsize[0]); + + init(dsize, pcoord, cur); + + PDI_event("main_loop"); + double start = MPI_Wtime(); + int next_reduce = 0; + for (ii = 0; ii < 10; ++ii) { + PDI_multi_expose("newiter", "iter", &ii, PDI_INOUT, "main_field", cur, PDI_INOUT, NULL); + + iter(dsize, cur, next); + exchange(cart_com, dsize, next); + double (*tmp)[dsize[1]] = cur; + cur = next; + next = tmp; + + // if (ii >= next_reduce) { + // double local_time, global_time; + // local_time = MPI_Wtime() - start; + // MPI_Allreduce(&local_time, &global_time, 1, MPI_DOUBLE, MPI_MAX, main_comm); + // if (global_time >= duration) { + // if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; STOP!!!\n", ii, global_time); + // break; + // } + // int rem_iter = .9 * (duration - global_time) * (ii + 1) / (global_time + 0.1); + // if (rem_iter < 1) rem_iter = 1; + // next_reduce = ii + rem_iter; + // if (0 == pcoord_1d) printf("iter=%7d; time=%7.3f; next_reduce=%7d\n", ii, global_time, next_reduce); + // } + //PDI_event("damaris_end_iteration"); + } + PDI_expose("iter", &ii, PDI_OUT); + PDI_expose("main_field", cur, PDI_OUT); PDI_finalize(); PC_tree_destroy(&conf); - //free(cur); - //free(next); + free(cur); + free(next); MPI_Finalize(); } diff --git a/plugins/damaris/example/example.yml b/plugins/damaris/example/example.yml index f4cacb9a1..6c20ec17e 100644 --- a/plugins/damaris/example/example.yml +++ b/plugins/damaris/example/example.yml @@ -42,10 +42,10 @@ pdi: start: [$iter, '($dsize[0]-2)*$pcoord[0]', '($dsize[1]-2)*$pcoord[1]'] damaris: - on_init: init #or init_on_event + #on_init: init #or init_on_event #start_on_event: damaris_start #end_iteration_on_event: damaris_end_iteration - on_finalize: finalization #Or finalize_on_event + #on_finalize: finalization #Or finalize_on_event communicator: $MPI_COMM_WORLD # pas utilisé actuellement architecture: sim_name: example @@ -91,8 +91,9 @@ pdi: # damaris "append" file with next iteration #block: [...] # To be defined # indice de block à écrire = 0 par default => tout le sous-domain # si "architecture/domains" >1 on peut écrire les block de indice 0 à domains-1 - get_is_client: is_client - client_comm_get: mpi_comm + #get_is_client: is_client #Needed only when is_client is used + dc_ending_operations: #Will be used in the future to provide couple of instructions to execute at the end of the simulation, for the dedicated cores. MayBe relying on user_code plugin!!? + client_comm_get: mpi_comm #Needed to return the Damaris client comm #Optional config, has a default behavior log: From 96f09301fa6c0f58a8165aa06c9de49af2ce52e4 Mon Sep 17 00:00:00 2001 From: Etienne Ndamlabin <88906611+endamlabin@users.noreply.github.com> Date: Thu, 16 Apr 2026 12:21:17 +0200 Subject: [PATCH 28/42] Example damaris only (#19) * Example with only Damaris API (resolves #10) --- .../example/ex_damaris_only/CMakeLists.txt | 21 ++ .../ex_damaris_only/example_damaris_api.xml | 44 +++ .../ex_damaris_only/example_damaris_only.c | 259 ++++++++++++++++++ 3 files changed, 324 insertions(+) create mode 100644 plugins/damaris/example/ex_damaris_only/CMakeLists.txt create mode 100644 plugins/damaris/example/ex_damaris_only/example_damaris_api.xml create mode 100644 plugins/damaris/example/ex_damaris_only/example_damaris_only.c diff --git a/plugins/damaris/example/ex_damaris_only/CMakeLists.txt b/plugins/damaris/example/ex_damaris_only/CMakeLists.txt new file mode 100644 index 000000000..0c9596507 --- /dev/null +++ b/plugins/damaris/example/ex_damaris_only/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.22) + +project(example_damaris_only VERSION 1.0.0) + +add_executable(example_damaris_only example_damaris_only.c) + + +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake") +include(GNUInstallDirs) + +# MPI +find_package(MPI REQUIRED) + +find_package(Damaris 1.12.0 REQUIRED) +include_directories(${Damaris_INCLUDE_DIRS} ${Damaris_INCLUDE_DIRS}/damaris) + +target_link_directories(${PROJECT_NAME} + PUBLIC ${Damaris_LIBRARIES_PATH} +) + +target_link_libraries(${PROJECT_NAME} damaris) diff --git a/plugins/damaris/example/ex_damaris_only/example_damaris_api.xml b/plugins/damaris/example/ex_damaris_only/example_damaris_api.xml new file mode 100644 index 000000000..b0380e124 --- /dev/null +++ b/plugins/damaris/example/ex_damaris_only/example_damaris_api.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/damaris/example/ex_damaris_only/example_damaris_only.c b/plugins/damaris/example/ex_damaris_only/example_damaris_only.c new file mode 100644 index 000000000..e821d984e --- /dev/null +++ b/plugins/damaris/example/ex_damaris_only/example_damaris_only.c @@ -0,0 +1,259 @@ +/******************************************************************************* + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include "Damaris.h" + +void init(int dsize[2], int pcoord[2], double dat[dsize[0]][dsize[1]]) +{ + for (int yy = 0; yy < dsize[0]; ++yy) { + for (int xx = 0; xx < dsize[1]; ++xx) { + dat[yy][xx] = 0; + } + } + if (pcoord[1] == 0) { + for (int yy = 0; yy < dsize[0]; ++yy) { + dat[yy][0] = 1000000; + } + } +} + +void iter(int dsize[2], double cur[dsize[0]][dsize[1]], double next[dsize[0]][dsize[1]]) +{ + int xx, yy; + for (xx = 0; xx < dsize[1]; ++xx) { + next[0][xx] = cur[0][xx]; + } + for (yy = 1; yy < dsize[0] - 1; ++yy) { + next[yy][0] = cur[yy][0]; + for (xx = 1; xx < dsize[1] - 1; ++xx) { + next[yy][xx] + = (cur[yy][xx] * .5) + (cur[yy][xx - 1] * .125) + (cur[yy][xx + 1] * .125) + (cur[yy - 1][xx] * .125) + (cur[yy + 1][xx] * .125); + } + next[yy][dsize[1] - 1] = cur[yy][dsize[1] - 1]; + } + for (xx = 0; xx < dsize[1]; ++xx) { + next[dsize[0] - 1][xx] = cur[dsize[0] - 1][xx]; + } +} + +void exchange(MPI_Comm cart_com, int dsize[2], double cur[dsize[0]][dsize[1]]) +{ + MPI_Status status; + int rank_source, rank_dest; + static MPI_Datatype column, row; + static int initialized = 0; + + if (!initialized) { + MPI_Type_vector(dsize[0] - 2, 1, dsize[1], MPI_DOUBLE, &column); + MPI_Type_commit(&column); + MPI_Type_contiguous(dsize[1] - 2, MPI_DOUBLE, &row); + MPI_Type_commit(&row); + initialized = 1; + } + + /* send down */ + MPI_Cart_shift(cart_com, 0, 1, &rank_source, &rank_dest); + MPI_Sendrecv( + &cur[dsize[0] - 2][1], + 1, + row, + rank_dest, + 100, /* send row before ghost */ + &cur[0][1], + 1, + row, + rank_source, + 100, /* receive 1st row (ghost) */ + cart_com, + &status + ); + + /* send up */ + MPI_Cart_shift(cart_com, 0, -1, &rank_source, &rank_dest); + MPI_Sendrecv( + &cur[1][1], + 1, + row, + rank_dest, + 100, /* send column after ghost */ + &cur[dsize[0] - 1][1], + 1, + row, + rank_source, + 100, /* receive last column (ghost) */ + cart_com, + &status + ); + + /* send to the right */ + MPI_Cart_shift(cart_com, 1, 1, &rank_source, &rank_dest); + MPI_Sendrecv( + &cur[1][dsize[1] - 2], + 1, + column, + rank_dest, + 100, /* send column before ghost */ + &cur[1][0], + 1, + column, + rank_source, + 100, /* receive 1st column (ghost) */ + cart_com, + &status + ); + + /* send to the left */ + MPI_Cart_shift(cart_com, 1, -1, &rank_source, &rank_dest); + MPI_Sendrecv( + &cur[1][1], + 1, + column, + rank_dest, + 100, /* send column after ghost */ + &cur[1][dsize[1] - 1], + 1, + column, + rank_source, + 100, /* receive last column (ghost) */ + cart_com, + &status + ); +} + +int main(int argc, char* argv[]) +{ + MPI_Init(&argc, &argv); + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + // All processes must initialize Damaris with the XML configuration + // - client process = heat simulation process + // - server process = damaris process for writting hdf5 file. + damaris_initialize(argv[1], MPI_COMM_WORLD); + + int is_client; + + int err = damaris_start(&is_client); + printf("-------------------------------------------------------------------------------------D: :) ;) is_client = %d\n", is_client); + + MPI_Comm main_comm = MPI_COMM_WORLD; + damaris_client_comm_get(&main_comm); // <-- returns Damaris client comm + + // Again, we check that servers have been started properly and that + // this process is a client. + if((err == DAMARIS_OK || err == DAMARIS_NO_SERVER) && is_client) { + + int psize_1d; + MPI_Comm_size(main_comm, &psize_1d); + int pcoord_1d; + MPI_Comm_rank(main_comm, &pcoord_1d); + + long longval; + + int dsize[2]; + damaris_parameter_get("global_height" , &longval , sizeof(int)); + dsize[0] = longval; + damaris_parameter_get("global_width" , &longval , sizeof(int)); + dsize[1] = longval; + + int psize[2]; + damaris_parameter_get("parallelism_h" , &longval , sizeof(int)); + psize[0] = longval; + damaris_parameter_get("parallelism_w" , &longval , sizeof(int)); + psize[1] = longval; + + // get local & add ghosts to sizes + assert(dsize[0] % psize[0] == 0); + dsize[0] = dsize[0] / psize[0] + 2; + assert(dsize[1] % psize[1] == 0); + dsize[1] = dsize[1] / psize[1] + 2; + + printf("(psize[1] * psize[0] == psize_1d) === (%d * %d == %d) \n", psize[1], psize[0], psize_1d); + assert(psize[1] * psize[0] == psize_1d); + + int cart_period[2] = {0, 0}; + MPI_Comm cart_com; + MPI_Cart_create(main_comm, 2, psize, cart_period, 1, &cart_com); + int pcoord[2]; + MPI_Cart_coords(cart_com, pcoord_1d, 2, pcoord); + + int ii = 0; + int main_field_layout_global0 = psize[0]*(dsize[0]-2); + int main_field_layout_global1 = psize[1]*(dsize[1]-2); + damaris_parameter_set("main_field_layout_global0" , &main_field_layout_global0, sizeof(int)) ; + damaris_parameter_set("main_field_layout_global1" , &main_field_layout_global1, sizeof(int)) ; + damaris_parameter_set("main_field_layout_dim0" , &dsize[0], sizeof(int)) ; + damaris_parameter_set("main_field_layout_dim1" , &dsize[1], sizeof(int)) ; + + + double(*cur)[dsize[1]] = malloc(sizeof(double) * dsize[1] * dsize[0]); + double(*next)[dsize[1]] = malloc(sizeof(double) * dsize[1] * dsize[0]); + + init(dsize, pcoord, cur); + + int64_t position_main_field[2]; + + position_main_field[0] = (dsize[0]-2)*pcoord[0]; + position_main_field[1] = (dsize[1]-2)*pcoord[1]; + + double start = MPI_Wtime(); + int next_reduce = 0; + for (ii = 0;ii < 10; ++ii) { + //Iteration write + damaris_set_position("main_field",position_main_field); + damaris_write("main_field",cur); + damaris_end_iteration(); + + iter(dsize, cur, next); + exchange(cart_com, dsize, next); + double(*tmp)[dsize[1]] = cur; + cur = next; + next = tmp; + } + //Last write + damaris_set_position("main_field",position_main_field); + damaris_write("main_field",cur); + damaris_end_iteration(); + + damaris_stop(); + free(cur); + free(next); + } + + damaris_finalize(); + + MPI_Finalize(); + return 0; +} From e8185b86a3ce95f80ff56ba52c9d554a3a600bf5 Mon Sep 17 00:00:00 2001 From: jmorice91 Date: Thu, 16 Apr 2026 12:22:18 +0200 Subject: [PATCH 29/42] fix#21, destruction of conf (#28) * fix destruction of conf --------- Co-authored-by: yushan wang --- plugins/damaris/damaris_api_call_handler.cxx | 21 ++++++++++++++++++-- plugins/damaris/example/example.c | 4 ++++ plugins/damaris/example/example.yml | 1 + 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/plugins/damaris/damaris_api_call_handler.cxx b/plugins/damaris/damaris_api_call_handler.cxx index 34aa89823..d11a37588 100644 --- a/plugins/damaris/damaris_api_call_handler.cxx +++ b/plugins/damaris/damaris_api_call_handler.cxx @@ -1,6 +1,6 @@ /******************************************************************************* - * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) - * Copyright (C) 2024 National Institute for Research in Digital Science and Technology (Inria) + * Copyright (C) 2025-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2024-2026 National Institute for Research in Digital Science and Technology (Inria) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -149,7 +149,24 @@ void Damaris_api_call_handler::damaris_api_call_event( //release the Damaris clients mpi comm PDI_release(Damaris_cfg::client_comm_get_dataset_name().c_str()); } + + // Get the pointer of PC_tree_t as a (void*) + uintptr_t *conf; + PDI_access("conf_yaml", (void**)&conf, PDI_IN); + PDI_release("conf_yaml"); + + // Get the pointer of PC_tree_t as is object type (need to be done before PDI_finalize) + uintptr_t cc_conf=*conf; + PC_tree_t *vv_conf = reinterpret_cast (cc_conf); + PDI_finalize(); + + if (PC_tree_destroy(vv_conf)) { + printf("Damaris server: Error in PC_tree_destroy\n"); + } + vv_conf = NULL; + conf = NULL; + MPI_Finalize(); exit(0); } diff --git a/plugins/damaris/example/example.c b/plugins/damaris/example/example.c index 484b3f2e9..eb1b5d8ec 100644 --- a/plugins/damaris/example/example.c +++ b/plugins/damaris/example/example.c @@ -170,6 +170,10 @@ int main(int argc, char* argv[]) } PDI_init(PC_get(conf, ".pdi")); + // expose the pointer of conf + uintptr_t pconf = (uintptr_t) &conf; + PDI_expose("conf_yaml", &pconf, PDI_OUT); + PDI_expose("mpi_comm", &main_comm, PDI_INOUT); // <-- allow plugin to set, returns Damaris client comm int psize_1d; diff --git a/plugins/damaris/example/example.yml b/plugins/damaris/example/example.yml index 6c20ec17e..26665aa78 100644 --- a/plugins/damaris/example/example.yml +++ b/plugins/damaris/example/example.yml @@ -13,6 +13,7 @@ pdi: psize: { size: 2, type: array, subtype: int } # number of processes in each dimension pcoord: { size: 2, type: array, subtype: int } # coordinate of the process mpi_comm: MPI_Comm + conf_yaml: uintptr_t data: # type of values for which PDI does not keep a copy # Question: pourquoi pas d'erreur meme si "is_client" n'est pas déclaré comme data, et que simulation accède à cette donnée? #is_client: int From 1e262397233db3d5c5b47d52d0ecf699f843b9cc Mon Sep 17 00:00:00 2001 From: yushan wang Date: Mon, 20 Apr 2026 09:32:11 +0200 Subject: [PATCH 30/42] Patch from main to damaris plugin (#33) * Datasets as regex (#583) * First version with regex * fix #582, update authors README and indent * update changelog * adding class for test * fix indent * fix indent * fix spdlog * adding test in parallel * fix error on file * Update plugins/decl_hdf5/README.md Co-authored-by: Benoit Martin * Update plugins/decl_hdf5/README.md Co-authored-by: Benoit Martin * fix #582, fix request change --------- Co-authored-by: Benoit Martin * Add macOS CI (#576) * Add macOS CI * Remove chunking check on a non-chunked dataset * Use MPI oversubscription * Disable unqualified std cast call * Use float type instead of integer * Use storage instead of computation * Disable zsh test * use `H5Pget_layout` to check if dataset is chunked * remove warning : cast hsize_t to int before `printf` * Re-enable zsh test with a new env.bash path * add call to `build_and_run_all_tests` and add workaround for macos * add netcdf * initialize CMAKE_FLAGS * disable PYTHON for macos * install hdf5-mpi on macos 14 and 15 * build hdf5 from source + add -j4 * Update copyright headers * Update AUTHORS * Update CHANGELOG.md fixes #556, fixes #565, fixes #587, fixes #588 --------- Co-authored-by: Julien Bigot Co-authored-by: yushan wang Co-authored-by: Benoit Martin Co-authored-by: Julien Bigot * Fix libyaml cmake policy version (#594) * add CMAKE_POLICY_VERSION_MINIMUM to 3.5 when building libyaml * fix #593 * update changelog and add comment * Fix github action (CI) access issue of tests.xml (#584) * Fix github action (CI) access issue of tests.xml * Fix #585 github action (CI) access issue of tests.xml, and go through PR checklist * Fix #585 github action (CI) access issue of tests.xml, using an other folder 'tmp_dir_test' containing the tests output, rather than docker's tmpfs * Update AUTHORS --------- Co-authored-by: Benoit Martin * Add CODEOWNERS (#591) * Add CODEOWNERS --------- Co-authored-by: Benoit Martin Co-authored-by: yushan wang * Check of the HDF5 API version to use in error handler (#600) * Ensuring the use of a compatible HDF5 API versions during errors handling Fix #567 --------- Co-authored-by: Anida Khizar Co-authored-by: Julien Bigot Co-authored-by: yushan wang * 592 improvement hdf5 dataset as regex (#597) * fix#592, comment about dataset as regex * Fix #592, reduce the interior loop * fix copyright * add fmt/range * fix indent * sort name of dataset in case of multiple regex found * fix indent * Fix #592, dsets as vector, introduce struct for explicit dataset * change Dataset_explicit_type to class * Apply suggestion from @jbigot * Update plugins/decl_hdf5/dataset_explicit_type.h * Update plugins/decl_hdf5/dataset_explicit_type.h * Update plugins/decl_hdf5/dataset_explicit_type.h * Update plugins/decl_hdf5/dataset_explicit_type.h * add std:optional and remove unnecessary comment --------- Co-authored-by: Julien Bigot * Add workflow_dispatch in pages * Fix #598, add workflow_dispatch in pages * fix in PC parser * fix in PC parser * add test for catching possible error * catch config error in google test * Use GTest's 'ASSERT_NO_FATAL_FAILURE' to catch a write failure Co-authored-by: Julien Bigot * code cleaning * Using PDI_NULL_Handler for error catching. Co-authored-by: Benoit Martin * add rwx right to tmp_dir_test --------- Co-authored-by: Julien Bigot Co-authored-by: Benoit Martin * PDI Release 1.9.3 Update the embedded versions of paraconf, pybind11 & zpp to fix a build issue with recent cmake. (#632) Sort Doxyfile for easier update Update to be compatible with latest Doxygen (#629) * Make all pages subpages of the About page * Remove the hand-crafted module page and use the generated topics page instead * Update the layout file * Add missing options in the Doxyfile * Set MARKDOWN_STRICT=NO to prevent backquote errors * Set PAGE_OUTLINE_PANEL=NO to prevent generation of a useless index * Minor CSS update to handle the additional level in the generated HTML * Fix two minor doc bugs Fix #631 Fix #629 * Cleanup changelogs before release * Fix HDF5 compression test for MacOS 26 Fix #627 Co-authored-by: Julian Auriac * Indent * Remove Deisa plugin (#639) * Update the version of dependencies Update the version of dependencies according to our policy: oldest supported Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: CMake 3.22, Doxygen 1.9.1, HDF5 1.10.7, mpi4py 3.1.3, NetCDF 4.8.1, numpy 1.21.5, pyyaml 5.4.1 pybind11 2.9.1, Python 3.10.6, spdlog 1.9.2 * Rely on standard Find* from cmake as much as possible * Add policy(PUSH) in cmake to prevent leaks * Include FindHDF5 from CMake 4.1 and backport it to 3.22 to use its fix for HL Fix #613 * Fix default CMAKE_BUILD_TYPE value (#619) * Fix default CMAKE_BUILD_TYPE value * Mock PDI Fix #438 Co-authored-by: Julian Auriac Co-authored-by: Benoit Martin * Update dependencies on googletest & benchmark * PDI Release 1.10.0 * Changelog minor fix * Adding missing LICENSE files and fix some minor indent * Support multiple consecutive calls to `find_package(PDI)` Fix #526 Co-authored-by: Benoit Martin * add-compression-in-decl_netcdf (#604) Add deflate and chunking to Decl'NetCDF * Enable hdf5 subfiling2 (#650) enable HDF5 subfiling support, add test. note: to set the subfiling stripe size (64Mo for example), use `export H5FD_SUBFILING_STRIPE_SIZE= 67108864`. * add type check for reading data from netCDF file (#646) * add type and sign check for integer read * add size check for float and double variable read * Disable unit tests for JSON dependency (#651) * Update versions of the langagues standard we use (#659) Update the versions of the languages standard we use * We require versions of compilers that support more recent versions of the standard already. This is not a user facing change. * Fix for C++ 20 - some incorrect use of fmt:: are only detected now with the use of C++ 20 - C++ 20 introduced mirror operator == that lead to some abiguous calls - Bump embedded spdlog to 1.15 because 1.14 had issues with C++ 20 Fix #660 * fix pybind11 on macos (#655) * fix pybind11 linking error on macos and enable Python based plugins for macOS CI * enable netcdf in macos CI (#667) * enable netcdf in macos CI * Update clang-format to version 18 (#673) Match the version in test_env:v4 * Renamed some error codes and deprecated the old ones (#671) Fix #670 * Finish moving to clang-format 18 * Fully qualify `std::move` calls (#676) Prevent a compilation warning and incorrect usages Fix #675 Co-authored-by: yushan wang * Enhance subfiling environment checking and update usage notes (#654) * Enhance README with subfiling usage notes Added important notes for using subfiling correctly. * add MPI thread level check * update readme * fix * fix * update test for subfiling counting * add subfiling stripe size in test * make subfiling_stripe_size configurable in yaml * update readme * make subfiling a new class and add stripe size configuration * update readme * indent * Add subfiling.cxx to decl_hdf5 plugin sources * update upon review notes * enable subfiling check test only if supported * remove subfiling check count test * pass subfiling test from c to cxx * indent * update readme [skip ci] * remove unnecessary headers fropm test * add header in test * throw an error if stripe_size is negative * fix indent [skip ci] * use warning when stripe_size is 0 * Replace Config_error with Spectree_error * Move Spectree_error usage to a consistent location * Improved testing framework (#669) * Added `pdi/testing.h` that should be used t test plugins. * Ported `plugins/decl_hdf5/tests/decl_hdf5_tests.cxx` as an example. * Fixed a minor bug discovered along the way in Decl'HDF5 Fix #668 * Do some tests in sequential to not use all CI if everything fails (#674) * Do some tests in sequential to not use all CI if everything fails * Do not run benchmarks by default Fix #679 * Fix a bug that was introduced in mock PDI with the (unreleased) move to C++ 20 mock PDI now relies on C++ 20 features when compiling in C++ but did not advertize it * Fix target_compile_features syntax for PDI_C --------- Co-authored-by: jmorice91 Co-authored-by: Benoit Martin Co-authored-by: Thomas Padioleau Co-authored-by: Julien Bigot Co-authored-by: Benoit Martin Co-authored-by: Julien Bigot Co-authored-by: JAuriac <56091659+JAuriac@users.noreply.github.com> Co-authored-by: AnidaKhizar Co-authored-by: Anida Khizar Co-authored-by: Julian Auriac Co-authored-by: Benoit Martin --- .github/CODEOWNERS | 51 + .github/actions/test/action.yml | 19 +- .github/pull_request_template.md | 3 +- .github/workflows/pages.yml | 9 +- .github/workflows/tests.yml | 91 +- AUTHORS | 13 +- CHANGELOG.md | 51 + CMakeLists.txt | 144 +- README.md | 1 - bin/build_and_run_all_tests | 118 +- bin/test_indent | 8 +- cmake/Findyaml.cmake | 34 +- cmake/SuperBuild.cmake | 39 +- cmake_test/AUTHORS | 10 + cmake_test/CHANGELOG.md | 10 + cmake_test/CMakeLists.txt | 129 + {vendor/paraconf-1.0.0 => cmake_test}/LICENSE | 0 .../subdir}/CMakeLists.txt | 18 +- example/AUTHORS | 3 - example/CHANGELOG.md | 8 + example/CMakeLists.txt | 37 +- example/cmake/DefaultKind.cmake | 66 - .../cmake/FindPackageHandleStandardArgs.cmake | 386 - example/cmake/FindPackageMessage.cmake | 47 - example/cmake/FindPython/Support.cmake | 1244 - example/cmake/FindPython3.cmake | 174 - .../cmake/SelectLibraryConfigurations.cmake | 71 - example/deisa.yml | 33 - example/deisa_client.py | 26 - example/example.c | 29 +- mock_pdi/AUTHORS | 5 + mock_pdi/CHANGELOG.md | 25 + .../indent.yml => mock_pdi/CMakeLists.txt | 19 +- mock_pdi/LICENSE | 26 + mock_pdi/PDIConfig.cmake | 65 + .../PDIConfigVersion.cmake | 30 +- mock_pdi/pdi.h | 156 + pdi/CHANGELOG.md | 60 + pdi/CMakeLists.txt | 58 +- pdi/CONTRIBUTING.md | 8 +- pdi/VERSION | 2 +- pdi/benchmarks/CMakeLists.txt | 13 +- pdi/cmake/CMakeFindDependencyMacro.cmake | 66 - pdi/cmake/DefaultKind.cmake | 9 +- pdi/cmake/FindDoxygen.cmake | 1118 - pdi/cmake/FindGMock.cmake | 342 - pdi/cmake/FindPackageHandleStandardArgs.cmake | 386 - pdi/cmake/FindPackageMessage.cmake | 47 - pdi/cmake/FindPython/Support.cmake | 1244 - pdi/cmake/FindPython3.cmake | 174 - pdi/cmake/FindPython3Path.cmake | 7 +- pdi/cmake/PDIConfig.cmake.in | 155 +- pdi/cmake/SelectLibraryConfigurations.cmake | 71 - pdi/docs/About.md | 20 +- pdi/docs/CMakeLists.txt | 20 +- pdi/docs/CheckList.md | 10 +- pdi/docs/Doxyfile | 547 +- pdi/docs/First_steps/CMakeLists.txt | 4 +- pdi/docs/Plugins.md | 3 +- pdi/docs/Source_installation.md | 87 +- pdi/docs/Using_PDI.md | 208 +- pdi/docs/_template/header.html | 2 +- pdi/docs/_template/layout.xml | 298 +- pdi/docs/_template/style.css | 11 +- pdi/docs/modules.md | 23 - pdi/include/pdi.h | 31 +- pdi/include/pdi/error.h | 85 +- pdi/include/pdi/expression.h | 6 +- pdi/include/pdi/logger.h | 11 +- pdi/include/pdi/ref_any.h | 44 +- pdi/include/pdi/testing.h | 286 + pdi/src/array_datatype.cxx | 13 +- pdi/src/callbacks.cxx | 9 +- pdi/src/context.cxx | 7 +- pdi/src/context_proxy.cxx | 7 +- pdi/src/data_descriptor_impl.cxx | 10 +- pdi/src/datatype_template.cxx | 109 +- pdi/src/expression.cxx | 7 +- pdi/src/expression/impl/mapping.cxx | 5 +- pdi/src/expression/impl/operation.cxx | 4 +- .../expression/impl/reference_expression.cxx | 12 +- pdi/src/expression/impl/sequence.cxx | 5 +- pdi/src/global_context.cxx | 6 +- pdi/src/paraconf_wrapper.cxx | 14 +- pdi/src/pdi.cxx | 9 +- pdi/src/plugin_store.cxx | 10 +- pdi/src/pointer_datatype.cxx | 11 +- pdi/src/python/pdi.cxx | 3 +- pdi/src/python/python_ref_wrapper.cxx | 4 +- pdi/src/python/tools.cxx | 4 +- pdi/src/record_datatype.cxx | 17 +- pdi/src/scalar_datatype.cxx | 7 +- pdi/src/tuple_datatype.cxx | 17 +- pdi/tests/CMakeLists.txt | 10 +- pdi/tests/PDI_data_descriptor.cxx | 10 +- pdi/tests/PDI_error.cxx | 5 +- pdi/tests/PDI_python_tools.cxx | 3 +- pdi/tests/PDI_record_datatype_empty.cxx | 4 +- pdi/tests/PDI_ref_any.cxx | 4 +- pdi/tests/expression.cxx | 54 +- pdi/tests/fortran/CMakeLists.txt | 4 +- pdi/tests/modulo.cxx | 54 +- plugins/decl_hdf5/AUTHORS | 8 + plugins/decl_hdf5/CHANGELOG.md | 29 + plugins/decl_hdf5/CMakeLists.txt | 14 +- plugins/decl_hdf5/README.md | 47 +- plugins/decl_hdf5/attribute_op.cxx | 16 +- plugins/decl_hdf5/benchmarks/CMakeLists.txt | 11 +- plugins/decl_hdf5/cmake/FindHDF5.cmake | 1206 - .../cmake/FindPackageHandleStandardArgs.cmake | 466 - .../decl_hdf5/cmake/FindPackageMessage.cmake | 48 - .../cmake/SelectLibraryConfigurations.cmake | 80 - plugins/decl_hdf5/dataset_explicit_type.h | 105 + plugins/decl_hdf5/dataset_op.cxx | 75 +- plugins/decl_hdf5/dataset_op.h | 9 +- plugins/decl_hdf5/file_op.cxx | 100 +- plugins/decl_hdf5/file_op.h | 13 +- plugins/decl_hdf5/hdf5_wrapper.cxx | 5 +- plugins/decl_hdf5/hdf5_wrapper.h | 96 +- plugins/decl_hdf5/selection.cxx | 12 +- plugins/decl_hdf5/selection.h | 4 +- .../decl_hdf5/subfiling.cxx | 63 +- plugins/decl_hdf5/subfiling.h | 87 + plugins/decl_hdf5/tests/CMakeLists.txt | 31 +- .../tests/compatibility_tests/CMakeLists.txt | 4 +- .../tests/decl_hdf5_mpi_subfiling.cxx | 181 + .../decl_hdf5/tests/decl_hdf5_mpi_test_08.c | 224 + .../tests/decl_hdf5_test_IO_options.c | 156 +- .../tests/decl_hdf5_test_deflate.cxx | 110 +- plugins/decl_hdf5/tests/decl_hdf5_tests.cxx | 1601 +- .../decl_hdf5/tests/fortran/CMakeLists.txt | 4 +- plugins/decl_netcdf/AUTHORS | 1 + plugins/decl_netcdf/CHANGELOG.md | 16 + plugins/decl_netcdf/CMakeLists.txt | 10 +- plugins/decl_netcdf/README.md | 21 + .../cmake/{ => 4.1}/FindHDF5.cmake | 605 +- .../4.1/SelectLibraryConfigurations.cmake | 185 + plugins/decl_netcdf/cmake/FindNetCDF.cmake | 23 +- .../cmake/FindPackageHandleStandardArgs.cmake | 386 - .../cmake/FindPackageMessage.cmake | 47 - .../cmake/SelectLibraryConfigurations.cmake | 71 - plugins/decl_netcdf/dnc_file_context.cxx | 20 +- plugins/decl_netcdf/dnc_io.cxx | 11 +- plugins/decl_netcdf/dnc_netcdf_file.cxx | 241 +- plugins/decl_netcdf/dnc_variable.cxx | 24 +- plugins/decl_netcdf/dnc_variable.h | 23 +- plugins/decl_netcdf/tests/CMakeLists.txt | 14 +- .../decl_netcdf/tests/decl_netcdf_tests.cxx | 308 +- plugins/deisa/AUTHORS | 18 - plugins/deisa/CHANGELOG.md | 40 - plugins/deisa/CMakeLists.txt | 39 - plugins/deisa/README.md | 55 - .../cmake/FindPackageHandleStandardArgs.cmake | 386 - plugins/deisa/cmake/FindPackageMessage.cmake | 47 - plugins/deisa/cmake/FindPython/Support.cmake | 1244 - plugins/deisa/cmake/FindPython3.cmake | 174 - .../cmake/SelectLibraryConfigurations.cmake | 71 - plugins/deisa/deisa.cxx | 220 - plugins/json/AUTHORS | 3 + plugins/json/CHANGELOG.md | 27 + plugins/json/CMakeLists.txt | 9 +- .../cmake/FindPackageHandleStandardArgs.cmake | 386 - plugins/json/cmake/FindPackageMessage.cmake | 47 - plugins/json/json.cxx | 6 +- plugins/json/tests/CMakeLists.txt | 13 +- .../json/tests/cmake/compare_content.cmake | 6 +- plugins/mpi/CHANGELOG.md | 13 + plugins/mpi/CMakeLists.txt | 5 +- .../cmake/FindPackageHandleStandardArgs.cmake | 386 - plugins/mpi/cmake/FindPackageMessage.cmake | 47 - plugins/mpi/mpi.cxx | 17 +- plugins/mpi/tests/CMakeLists.txt | 4 +- plugins/pycall/CHANGELOG.md | 11 + plugins/pycall/CMakeLists.txt | 9 +- .../cmake/FindPackageHandleStandardArgs.cmake | 386 - plugins/pycall/cmake/FindPackageMessage.cmake | 47 - plugins/pycall/cmake/FindPython/Support.cmake | 1244 - plugins/pycall/cmake/FindPython3.cmake | 174 - .../cmake/SelectLibraryConfigurations.cmake | 71 - plugins/pycall/pycall.cxx | 6 +- plugins/pycall/tests/CMakeLists.txt | 4 +- plugins/serialize/CHANGELOG.md | 13 + plugins/serialize/CMakeLists.txt | 5 +- .../cmake/FindPackageHandleStandardArgs.cmake | 386 - .../serialize/cmake/FindPackageMessage.cmake | 47 - plugins/serialize/serialize.cxx | 10 +- plugins/serialize/tests/CMakeLists.txt | 8 +- plugins/set_value/CHANGELOG.md | 17 +- plugins/set_value/CMakeLists.txt | 7 +- .../cmake/FindPackageHandleStandardArgs.cmake | 386 - .../set_value/cmake/FindPackageMessage.cmake | 47 - .../set_value/cmake/FindPython/Support.cmake | 1229 - plugins/set_value/cmake/FindPython3.cmake | 165 - plugins/set_value/set_operation.cxx | 4 +- plugins/set_value/tests/CMakeLists.txt | 4 +- plugins/set_value/tests/Python/CMakeLists.txt | 6 +- plugins/set_value/trigger.cxx | 5 +- plugins/trace/CHANGELOG.md | 11 + plugins/trace/CMakeLists.txt | 5 +- .../cmake/FindPackageHandleStandardArgs.cmake | 386 - plugins/trace/cmake/FindPackageMessage.cmake | 47 - plugins/user_code/CHANGELOG.md | 11 + plugins/user_code/CMakeLists.txt | 5 +- .../cmake/FindPackageHandleStandardArgs.cmake | 386 - .../user_code/cmake/FindPackageMessage.cmake | 47 - plugins/user_code/tests/CMakeLists.txt | 4 +- plugins/user_code/user_code.cxx | 3 +- spack.yaml | 25 +- test_api/AUTHORS | 2 + test_api/CHANGELOG.md | 25 + test_api/CMakeLists.txt | 49 + test_api/LICENSE | 26 + test_api/cmake/runtest-dir | 18 + .../src/ypath.h => test_api/test_api.c | 17 +- .../src/tools.h => test_api/test_api.cpp | 30 +- test_api/test_api.h | 159 + tests/CHANGELOG.md | 8 + tests/CMakeLists.txt | 20 +- vendor/benchmark-38df9da/.clang-tidy | 6 - .../benchmark-38df9da/.github/libcxx-setup.sh | 26 - .../.github/workflows/clang-format-lint.yml | 18 - .../.github/workflows/pre-commit.yml | 38 - .../.github/workflows/test_bindings.yml | 30 - .../.github/workflows/wheels.yml | 90 - vendor/benchmark-38df9da/.travis.yml | 208 - .../python/google_benchmark/version.py | 7 - .../cmake/CXXFeatureCheck.cmake | 82 - .../cmake/Modules/FindLLVMAr.cmake | 16 - .../cmake/Modules/FindLLVMNm.cmake | 16 - .../cmake/Modules/FindLLVMRanLib.cmake | 15 - .../cmake/Modules/FindPFM.cmake | 28 - vendor/benchmark-38df9da/test/cxx03_test.cc | 62 - .../tools/libpfm.BUILD.bazel | 22 - .../benchmark-38df9da/tools/requirements.txt | 2 - vendor/benchmark-4ed29ae/.bazelversion | 1 + .../.clang-format | 0 vendor/benchmark-4ed29ae/.clang-tidy | 37 + vendor/benchmark-4ed29ae/.clang-tidy.ignore | 1 + .../.github/ISSUE_TEMPLATE/bug_report.md | 0 .../.github/ISSUE_TEMPLATE/feature_request.md | 0 .../benchmark-4ed29ae/.github/dependabot.yml | 11 + .../.github/install_bazel.sh | 2 +- .../benchmark-4ed29ae/.github/libcxx-setup.sh | 35 + .../.github/workflows/bazel.yml | 17 +- .../workflows/build-and-test-min-cmake.yml | 9 +- .../workflows/build-and-test-perfcounters.yml | 10 +- .../.github/workflows/build-and-test.yml | 84 +- .../.github/workflows/clang-format-lint.yml | 22 + .../.github/workflows/clang-tidy-lint.yml} | 16 +- .../.github/workflows/doxygen.yml | 8 +- .../.github/workflows/ossf.yml | 27 + .../.github/workflows/pre-commit.yml | 22 + .../.github/workflows/sanitizer.yml | 9 +- .../.github/workflows/test_bindings.yml | 36 + .../.github/workflows/wheels.yml | 84 + vendor/benchmark-4ed29ae/.gitignore | 69 + .../.pre-commit-config.yaml | 10 +- .../.ycm_extra_conf.py | 8 +- .../AUTHORS | 4 + .../BUILD.bazel | 27 +- .../CMakeLists.txt | 50 +- .../CONTRIBUTING.md | 0 .../CONTRIBUTORS | 5 + .../LICENSE | 0 .../MODULE.bazel | 16 +- .../README.md | 6 +- .../WORKSPACE | 4 - .../WORKSPACE.bzlmod | 0 .../_config.yml | 0 .../appveyor.yml | 0 .../bazel/benchmark_deps.bzl | 10 +- .../bindings/python/google_benchmark/BUILD | 9 +- .../python/google_benchmark/__init__.py | 35 +- .../python/google_benchmark/benchmark.cc | 77 +- .../python/google_benchmark/example.py | 9 +- .../cmake/AddCXXCompilerFlag.cmake | 0 .../cmake/CXXFeatureCheck.cmake | 100 + .../cmake/Config.cmake.in | 1 + .../cmake/GetGitVersion.cmake | 0 .../cmake/GoogleTest.cmake | 0 .../cmake/GoogleTest.cmake.in | 7 +- .../cmake/benchmark.pc.in | 2 +- .../cmake/benchmark_main.pc.in | 2 +- .../cmake/gnu_posix_regex.cpp | 0 .../cmake/llvm-toolchain.cmake | 0 .../cmake/posix_regex.cpp | 0 .../cmake/pthread_affinity.cpp | 0 .../cmake/split_list.cmake | 0 .../cmake/std_regex.cpp | 0 .../cmake/steady_clock.cpp | 0 .../cmake/thread_safety_attributes.cpp | 0 .../docs/AssemblyTests.md | 0 .../docs/_config.yml | 0 .../docs/assets/images/icon.png | Bin .../docs/assets/images/icon.xcf | Bin .../docs/assets/images/icon_black.png | Bin .../docs/assets/images/icon_black.xcf | Bin .../docs/dependencies.md | 6 + .../docs/index.md | 0 .../docs/perf_counters.md | 0 .../platform_specific_build_instructions.md | 8 +- .../docs/python_bindings.md | 0 .../docs/random_interleaving.md | 0 .../docs/reducing_variance.md | 50 +- .../docs/releasing.md | 19 +- .../docs/tools.md | 0 .../docs/user_guide.md | 165 +- .../include/benchmark/benchmark.h | 558 +- .../include/benchmark/export.h | 0 .../pyproject.toml | 33 +- .../setup.py | 65 +- .../src/CMakeLists.txt | 28 +- .../src/arraysize.h | 0 .../src/benchmark.cc | 188 +- .../src/benchmark_api_internal.cc | 23 +- .../src/benchmark_api_internal.h | 19 +- .../src/benchmark_main.cc | 2 +- .../src/benchmark_name.cc | 4 +- .../src/benchmark_register.cc | 102 +- .../src/benchmark_register.h | 1 + .../src/benchmark_runner.cc | 235 +- .../src/benchmark_runner.h | 22 +- .../src/check.cc | 5 +- .../src/check.h | 16 +- .../src/colorprint.cc | 22 +- .../src/colorprint.h | 7 +- .../src/commandlineflags.cc | 53 +- .../src/commandlineflags.h | 4 + .../src/complexity.cc | 25 +- .../src/complexity.h | 0 .../src/console_reporter.cc | 25 +- .../src/counter.cc | 18 +- .../src/counter.h | 0 .../src/csv_reporter.cc | 23 +- .../src/cycleclock.h | 24 +- .../src/internal_macros.h | 10 + .../src/json_reporter.cc | 50 +- .../src/log.h | 12 - .../src/mutex.h | 0 .../src/perf_counters.cc | 10 +- .../src/perf_counters.h | 0 .../src/re.h | 10 +- .../src/reporter.cc | 31 +- .../src/statistics.cc | 46 +- .../src/statistics.h | 0 .../src/string_util.cc | 30 +- .../src/string_util.h | 1 - .../src/sysinfo.cc | 255 +- .../src/thread_manager.h | 24 +- .../src/thread_timer.h | 0 .../src/timers.cc | 24 +- .../src/timers.h | 0 .../test/AssemblyTests.cmake | 0 .../test/BUILD | 25 +- .../test/CMakeLists.txt | 61 +- .../test/args_product_test.cc | 0 .../test/basic_test.cc | 8 +- .../test/benchmark_gtest.cc | 0 .../benchmark_min_time_flag_iters_test.cc | 26 +- .../test/benchmark_min_time_flag_time_test.cc | 33 +- .../test/benchmark_name_gtest.cc | 0 .../benchmark_random_interleaving_gtest.cc | 5 +- ...benchmark_setup_teardown_cb_types_gtest.cc | 126 + .../test/benchmark_setup_teardown_test.cc | 22 +- .../test/benchmark_test.cc | 80 +- .../test/clobber_memory_assembly_test.cc | 0 .../test/commandlineflags_gtest.cc | 0 .../test/complexity_test.cc | 61 +- vendor/benchmark-4ed29ae/test/cxx11_test.cc | 12 + .../test/diagnostics_test.cc | 27 +- .../test/display_aggregates_only_test.cc | 4 + .../test/donotoptimize_assembly_test.cc | 7 +- .../test/donotoptimize_test.cc | 8 +- .../test/filter_test.cc | 26 +- .../test/fixture_test.cc | 0 .../test/internal_threading_test.cc | 15 +- .../test/link_main_test.cc | 5 +- .../test/locale_impermeability_test.cc | 47 + .../test/manual_threading_test.cc | 175 + .../test/map_test.cc | 7 +- .../test/memory_manager_test.cc | 7 +- .../test/memory_results_gtest.cc | 101 + .../test/min_time_parse_gtest.cc | 0 .../test/multiple_ranges_test.cc | 4 +- .../test/options_test.cc | 4 +- .../test/output_test.h | 14 +- .../test/output_test_helper.cc | 111 +- .../benchmark-4ed29ae/test/overload_test.cc | 35 + .../test/perf_counters_gtest.cc | 8 +- .../test/perf_counters_test.cc | 9 +- .../test/profiler_manager_gtest.cc | 42 + .../test/profiler_manager_iterations_test.cc | 62 + .../test/profiler_manager_test.cc | 54 + .../test/register_benchmark_test.cc | 23 +- .../test/repetitions_test.cc | 11 +- .../test/report_aggregates_only_test.cc | 3 + .../test/reporter_output_test.cc | 23 +- .../test/skip_with_error_test.cc | 26 +- .../test/spec_arg_test.cc | 10 +- .../test/spec_arg_verbosity_test.cc | 6 +- .../test/state_assembly_test.cc | 1 + .../test/statistics_gtest.cc | 0 .../test/string_util_gtest.cc | 184 +- .../test/templated_fixture_method_test.cc | 26 + .../test/templated_fixture_test.cc | 0 .../test/time_unit_gtest.cc | 4 +- .../test/user_counters_tabular_test.cc | 15 +- .../test/user_counters_test.cc | 58 +- .../test/user_counters_thousands_test.cc | 10 +- .../test/user_counters_threads_test.cc | 622 + .../tools/BUILD.bazel | 1 + .../tools/compare.py | 39 +- .../tools/gbench/Inputs/test1_run1.json | 0 .../tools/gbench/Inputs/test1_run2.json | 0 .../tools/gbench/Inputs/test2_run.json | 0 .../tools/gbench/Inputs/test3_run0.json | 0 .../tools/gbench/Inputs/test3_run1.json | 0 .../tools/gbench/Inputs/test4_run.json | 0 .../tools/gbench/Inputs/test4_run0.json | 0 .../tools/gbench/Inputs/test4_run1.json | 0 .../tools/gbench/Inputs/test5_run0.json | 0 .../tools/gbench/Inputs/test5_run1.json | 0 .../tools/gbench/__init__.py | 0 .../tools/gbench/report.py | 118 +- .../tools/gbench/util.py | 50 +- .../tools/libpfm.BUILD.bazel | 242 + .../benchmark-4ed29ae/tools/requirements.txt | 2 + .../tools/strip_asm.py | 16 +- .../.clang-format | 0 .../.github/ISSUE_TEMPLATE/00-bug_report.yml | 0 .../ISSUE_TEMPLATE/10-feature_request.yml | 0 .../.github/ISSUE_TEMPLATE/config.yml | 0 vendor/googletest-56efe39/.gitignore | 89 + .../BUILD.bazel | 40 +- .../CMakeLists.txt | 4 +- .../CONTRIBUTING.md | 0 .../CONTRIBUTORS | 0 .../LICENSE | 0 .../MODULE.bazel | 52 +- .../README.md | 22 +- vendor/googletest-56efe39/WORKSPACE | 61 + .../WORKSPACE.bzlmod | 0 .../googletest-56efe39/ci/linux-presubmit.sh | 177 + .../ci/macos-presubmit.sh | 21 +- .../ci/windows-presubmit.bat | 87 + .../docs/_config.yml | 0 .../docs/_data/navigation.yml | 0 .../docs/_layouts/default.html | 14 +- .../docs/_sass/main.scss | 0 .../docs/advanced.md | 170 +- .../docs/assets/css/style.scss | 0 .../docs/community_created_documentation.md | 0 .../docs/faq.md | 13 - .../docs/gmock_cheat_sheet.md | 2 +- .../docs/gmock_cook_book.md | 86 +- .../docs/gmock_faq.md | 0 .../docs/gmock_for_dummies.md | 0 .../docs/index.md | 0 .../docs/pkgconfig.md | 0 .../docs/platforms.md | 0 .../docs/primer.md | 4 +- .../docs/quickstart-bazel.md | 65 +- .../docs/quickstart-cmake.md | 6 +- .../docs/reference/actions.md | 7 +- .../docs/reference/assertions.md | 11 +- .../docs/reference/matchers.md | 48 +- .../docs/reference/mocking.md | 0 .../docs/reference/testing.md | 99 +- .../docs/samples.md | 0 .../googletest-56efe39/fake_fuchsia_sdk.bzl | 61 + .../googlemock/CMakeLists.txt | 0 .../googlemock/README.md | 0 .../googlemock/cmake/gmock.pc.in | 0 .../googlemock/cmake/gmock_main.pc.in | 0 .../googlemock/docs/README.md | 0 .../googlemock/include/gmock/gmock-actions.h | 200 +- .../include/gmock/gmock-cardinalities.h | 4 +- .../include/gmock/gmock-function-mocker.h | 0 .../googlemock/include/gmock/gmock-matchers.h | 661 +- .../include/gmock/gmock-more-actions.h | 16 +- .../include/gmock/gmock-more-matchers.h | 2 +- .../include/gmock/gmock-nice-strict.h | 18 +- .../include/gmock/gmock-spec-builders.h | 32 +- .../googlemock/include/gmock/gmock.h | 0 .../include/gmock/internal/custom/README.md | 0 .../internal/custom/gmock-generated-actions.h | 0 .../gmock/internal/custom/gmock-matchers.h | 0 .../gmock/internal/custom/gmock-port.h | 0 .../gmock/internal/gmock-internal-utils.h | 24 +- .../include/gmock/internal/gmock-port.h | 7 +- .../include/gmock/internal/gmock-pp.h | 0 .../googlemock/src/gmock-all.cc | 0 .../googlemock/src/gmock-cardinalities.cc | 8 +- .../googlemock/src/gmock-internal-utils.cc | 4 +- .../googlemock/src/gmock-matchers.cc | 0 .../googlemock/src/gmock-spec-builders.cc | 34 +- .../googlemock/src/gmock.cc | 0 .../googlemock/src/gmock_main.cc | 0 .../googlemock/test/BUILD.bazel | 1 + .../googlemock/test/gmock-actions_test.cc | 109 +- .../test/gmock-cardinalities_test.cc | 12 +- .../test/gmock-function-mocker_test.cc | 6 +- .../test/gmock-internal-utils_test.cc | 4 +- .../test/gmock-matchers-arithmetic_test.cc | 247 +- .../test/gmock-matchers-comparisons_test.cc | 197 +- .../test/gmock-matchers-containers_test.cc | 346 +- .../test/gmock-matchers-misc_test.cc | 113 +- .../googlemock/test/gmock-matchers_test.h | 0 .../test/gmock-more-actions_test.cc | 87 +- .../googlemock/test/gmock-nice-strict_test.cc | 0 .../googlemock/test/gmock-port_test.cc | 0 .../googlemock/test/gmock-pp-string_test.cc | 0 .../googlemock/test/gmock-pp_test.cc | 2 +- .../test/gmock-spec-builders_test.cc | 17 +- .../googlemock/test/gmock_all_test.cc | 0 .../googlemock/test/gmock_ex_test.cc | 0 .../googlemock/test/gmock_leak_test.py | 0 .../googlemock/test/gmock_leak_test_.cc | 0 .../googlemock/test/gmock_link2_test.cc | 0 .../googlemock/test/gmock_link_test.cc | 0 .../googlemock/test/gmock_link_test.h | 2 +- .../googlemock/test/gmock_output_test.py | 0 .../googlemock/test/gmock_output_test_.cc | 0 .../test/gmock_output_test_golden.txt | 8 +- .../googlemock/test/gmock_stress_test.cc | 0 .../googlemock/test/gmock_test.cc | 0 .../googlemock/test/gmock_test_utils.py | 0 .../googletest/CMakeLists.txt | 3 - .../googletest/README.md | 12 +- .../googletest/cmake/Config.cmake.in | 0 .../googletest/cmake/gtest.pc.in | 0 .../googletest/cmake/gtest_main.pc.in | 0 .../googletest/cmake/internal_utils.cmake | 23 +- .../googletest/cmake/libgtest.la.in | 0 .../googletest/docs/README.md | 0 .../include/gtest/gtest-assertion-result.h | 9 +- .../include/gtest/gtest-death-test.h | 6 +- .../googletest/include/gtest/gtest-matchers.h | 106 +- .../googletest/include/gtest/gtest-message.h | 0 .../include/gtest/gtest-param-test.h | 134 +- .../googletest/include/gtest/gtest-printers.h | 187 +- .../googletest/include/gtest/gtest-spi.h | 4 +- .../include/gtest/gtest-test-part.h | 8 +- .../include/gtest/gtest-typed-test.h | 138 +- .../googletest/include/gtest/gtest.h | 54 +- .../include/gtest/gtest_pred_impl.h | 0 .../googletest/include/gtest/gtest_prod.h | 0 .../include/gtest/internal/custom/README.md | 0 .../gtest/internal/custom/gtest-port.h | 0 .../gtest/internal/custom/gtest-printers.h | 0 .../include/gtest/internal/custom/gtest.h | 0 .../internal/gtest-death-test-internal.h | 22 +- .../include/gtest/internal/gtest-filepath.h | 2 +- .../include/gtest/internal/gtest-internal.h | 125 +- .../include/gtest/internal/gtest-param-util.h | 105 +- .../include/gtest/internal/gtest-port-arch.h | 2 + .../include/gtest/internal/gtest-port.h | 319 +- .../include/gtest/internal/gtest-string.h | 4 +- .../include/gtest/internal/gtest-type-util.h | 0 .../googletest/samples/prime_tables.h | 0 .../googletest/samples/sample1.cc | 0 .../googletest/samples/sample1.h | 0 .../googletest/samples/sample10_unittest.cc | 0 .../googletest/samples/sample1_unittest.cc | 0 .../googletest/samples/sample2.cc | 0 .../googletest/samples/sample2.h | 0 .../googletest/samples/sample2_unittest.cc | 0 .../googletest/samples/sample3-inl.h | 0 .../googletest/samples/sample3_unittest.cc | 0 .../googletest/samples/sample4.cc | 0 .../googletest/samples/sample4.h | 0 .../googletest/samples/sample4_unittest.cc | 0 .../googletest/samples/sample5_unittest.cc | 0 .../googletest/samples/sample6_unittest.cc | 0 .../googletest/samples/sample7_unittest.cc | 0 .../googletest/samples/sample8_unittest.cc | 0 .../googletest/samples/sample9_unittest.cc | 0 .../googletest/src/gtest-all.cc | 0 .../googletest/src/gtest-assertion-result.cc | 0 .../googletest/src/gtest-death-test.cc | 0 .../googletest/src/gtest-filepath.cc | 0 .../googletest/src/gtest-internal-inl.h | 4 + .../googletest/src/gtest-matchers.cc | 0 .../googletest/src/gtest-port.cc | 10 +- .../googletest/src/gtest-printers.cc | 20 +- .../googletest/src/gtest-test-part.cc | 0 .../googletest/src/gtest-typed-test.cc | 0 .../googletest/src/gtest.cc | 272 +- .../googletest/src/gtest_main.cc | 0 .../googletest/test/BUILD.bazel | 69 +- .../googletest-break-on-failure-unittest.py | 0 .../googletest-break-on-failure-unittest_.cc | 0 .../test/googletest-catch-exceptions-test.py | 0 .../test/googletest-catch-exceptions-test_.cc | 0 .../googletest/test/googletest-color-test.py | 1 + .../googletest/test/googletest-color-test_.cc | 0 .../test/googletest-death-test-test.cc | 2 +- .../test/googletest-death-test_ex_test.cc | 0 .../test/googletest-env-var-test.py | 0 .../test/googletest-env-var-test_.cc | 0 ...no-test-linked-test-with-disabled-test_.cc | 38 + ...-no-test-linked-test-with-enabled-test_.cc | 38 + .../googletest-fail-if-no-test-linked-test.py | 165 + ...oogletest-fail-if-no-test-selected-test.py | 91 + .../test/googletest-failfast-unittest.py | 0 .../test/googletest-failfast-unittest_.cc | 0 .../test/googletest-filepath-test.cc | 0 .../test/googletest-filter-unittest.py | 19 + .../test/googletest-filter-unittest_.cc | 0 .../googletest-global-environment-unittest.py | 0 ...googletest-global-environment-unittest_.cc | 0 .../test/googletest-json-outfiles-test.py | 0 .../test/googletest-json-output-unittest.py | 111 +- .../test/googletest-list-tests-unittest.py | 0 .../test/googletest-list-tests-unittest_.cc | 0 .../test/googletest-listener-test.cc | 0 .../test/googletest-message-test.cc | 0 .../test/googletest-options-test.cc | 0 .../googletest-output-test-golden-lin.txt | 2 +- .../googletest/test/googletest-output-test.py | 0 .../test/googletest-output-test_.cc | 0 ...oogletest-param-test-invalid-name1-test.py | 0 ...ogletest-param-test-invalid-name1-test_.cc | 0 ...oogletest-param-test-invalid-name2-test.py | 0 ...ogletest-param-test-invalid-name2-test_.cc | 0 .../test/googletest-param-test-test.cc | 74 +- .../test/googletest-param-test-test.h | 0 .../test/googletest-param-test2-test.cc | 0 .../googletest/test/googletest-port-test.cc | 18 +- .../test/googletest-printers-test.cc | 118 +- .../test/googletest-setuptestsuite-test.py | 0 .../test/googletest-setuptestsuite-test_.cc | 4 +- .../test/googletest-shuffle-test.py | 0 .../test/googletest-shuffle-test_.cc | 0 .../test/googletest-test-part-test.cc | 0 .../test/googletest-throw-on-failure-test.py | 0 .../test/googletest-throw-on-failure-test_.cc | 0 .../test/googletest-uninitialized-test.py | 0 .../test/googletest-uninitialized-test_.cc | 0 .../googletest/test/gtest-typed-test2_test.cc | 0 .../googletest/test/gtest-typed-test_test.cc | 0 .../googletest/test/gtest-typed-test_test.h | 0 .../test/gtest-unittest-api_test.cc | 0 .../googletest/test/gtest_all_test.cc | 0 .../test/gtest_assert_by_exception_test.cc | 0 .../googletest/test/gtest_dirs_test.cc | 0 .../googletest/test/gtest_environment_test.cc | 0 .../googletest/test/gtest_help_test.py | 0 .../googletest/test/gtest_help_test_.cc | 0 .../googletest/test/gtest_json_test_utils.py | 0 .../test/gtest_list_output_unittest.py | 0 .../test/gtest_list_output_unittest_.cc | 0 .../googletest/test/gtest_main_unittest.cc | 0 .../googletest/test/gtest_no_test_unittest.cc | 0 .../test/gtest_pred_impl_unittest.cc | 0 .../test/gtest_premature_exit_test.cc | 0 .../googletest/test/gtest_prod_test.cc | 0 .../googletest/test/gtest_repeat_test.cc | 0 .../test/gtest_skip_check_output_test.py | 0 ...test_skip_environment_check_output_test.py | 0 .../gtest_skip_in_environment_setup_test.cc | 0 .../googletest/test/gtest_skip_test.cc | 0 .../googletest/test/gtest_sole_header_test.cc | 0 .../googletest/test/gtest_stress_test.cc | 4 +- .../gtest_test_macro_stack_footprint_test.cc | 0 .../googletest/test/gtest_test_utils.py | 0 .../googletest/test/gtest_testbridge_test.py | 0 .../googletest/test/gtest_testbridge_test_.cc | 0 .../test/gtest_throw_on_failure_ex_test.cc | 0 .../googletest/test/gtest_unittest.cc | 85 +- .../test/gtest_xml_outfile1_test_.cc | 0 .../test/gtest_xml_outfile2_test_.cc | 0 .../test/gtest_xml_outfiles_test.py | 0 .../test/gtest_xml_output_unittest.py | 93 +- .../test/gtest_xml_output_unittest_.cc | 22 +- .../googletest/test/gtest_xml_test_utils.py | 0 .../googletest/test/production.cc | 0 .../googletest/test/production.h | 0 vendor/googletest-56efe39/googletest_deps.bzl | 44 + vendor/googletest-b4aaf97/WORKSPACE | 29 - .../googletest-b4aaf97/ci/linux-presubmit.sh | 139 - .../ci/windows-presubmit.bat | 58 - .../googletest-b4aaf97/fake_fuchsia_sdk.bzl | 33 - vendor/googletest-b4aaf97/googletest_deps.bzl | 28 - vendor/netcdf-c-4.9.2/CMakeLists.txt | 2707 - .../baseline/test_anon_dim.2.syn.d4d | 12 - .../baseline/test_anon_dim.2.syn.d4m | 9 - .../baseline/test_anon_dim.2.syn.d4p | 21 - .../dap4_test/baseline/test_anon_dim.syn.d4d | 11 - .../dap4_test/baseline/test_anon_dim.syn.d4m | 7 - .../dap4_test/baseline/test_anon_dim.syn.d4p | 18 - .../baseline/test_atomic_array.5.nc.d4d | 28 - .../baseline/test_atomic_array.5.nc.d4m | 15 - .../baseline/test_atomic_array.5.nc.d4p | 34 - .../baseline/test_atomic_array.8.nc.d4d | 12 - .../baseline/test_atomic_array.8.nc.d4m | 9 - .../baseline/test_atomic_array.8.nc.d4p | 21 - .../baseline/test_atomic_array.9.nc.d4m | 9 - .../baseline/test_atomic_array.9.nc.d4p | 21 - .../baseline/test_atomic_array.syn.d4d | 51 - .../baseline/test_atomic_types.syn.d4d | 58 - .../baseline/test_atomic_types.syn.d4m | 27 - .../baseline/test_atomic_types.syn.d4p | 51 - .../baseline/test_enum_array.4.nc.d4p | 40 - .../baseline/test_one_vararray.1.nc.d4m | 9 - .../baseline/test_one_vararray.1.nc.d4p | 21 - .../baseline/test_one_vararray.3.nc.d4d | 12 - .../baseline/test_one_vararray.3.nc.d4m | 9 - .../baseline/test_one_vararray.3.nc.d4p | 21 - .../dap4_test/baseline/test_opaque.nc.d4m | 7 - .../baseline/test_opaque_array.7.nc.d4m | 12 - .../baseline/test_opaque_array.7.nc.d4p | 23 - .../baseline/test_sequence_1.syn.d4d | 14 - .../baseline/test_sequence_1.syn.d4m | 11 - .../baseline/test_sequence_1.syn.d4p | 20 - .../baseline/test_sequence_2.syn.d4d | 17 - .../baseline/test_sequence_2.syn.d4m | 13 - .../baseline/test_sequence_2.syn.d4p | 25 - .../baseline/test_struct_array.6.nc.d4d | 19 - .../baseline/test_struct_array.6.nc.d4m | 14 - .../baseline/test_struct_array.6.nc.d4p | 28 - .../baseline/test_struct_array.syn.d4d | 29 - .../baseline/test_struct_array.syn.d4m | 16 - .../baseline/test_struct_array.syn.d4p | 34 - .../baselinehyrax/amsre_20060131v5.dat.hyrax | 63723 ---------------- .../baselineraw/test_anon_dim.2.syn.dmp | 12 - .../baselineraw/test_anon_dim.syn.dmp | 11 - .../baselineraw/test_atomic_array.9.nc.dmp | 12 - .../baselineraw/test_atomic_array.syn.dmp | 50 - .../baselineraw/test_atomic_types.syn.dmp | 58 - .../baselineraw/test_enum_array.4.nc.dmp | 18 - .../baselineraw/test_fillmismatch.nc.dmp | 7 - .../baselineraw/test_one_vararray.1.nc.dmp | 12 - .../baselineraw/test_opaque_array.7.nc.dmp | 16 - .../baselineraw/test_sequence_1.syn.dmp | 14 - .../baselineraw/test_sequence_2.syn.dmp | 17 - .../baselineraw/test_struct_array.syn.dmp | 29 - .../baselineremote/test_anon_dim.syn.dmp | 13 - .../baselineremote/test_atomic_array.syn.dmp | 54 - .../baselineremote/test_atomic_types.syn.dmp | 60 - .../baselineremote/test_sequence_1.syn.dmp | 16 - .../baselineremote/test_sequence_2.syn.dmp | 19 - .../baselineremote/test_struct_array.syn.dmp | 31 - .../baselineremote/test_struct_nested.nc.dmp | 23 - .../baselineremote/test_struct_nested3.nc.dmp | 20 - .../baselineremote/test_vlen10.nc.dmp | 19 - .../baselineremote/test_vlen11.nc.dmp | 19 - .../baselineremote/test_vlen3.hdf5.dmp | 18 - .../baselineremote/test_vlen4.nc.dmp | 20 - .../baselineremote/test_vlen5.hdf5.dmp | 20 - .../baselineremote/test_vlen9.nc.dmp | 21 - .../baselinethredds/GOES16_TEST1.nc4.thredds | 458 - .../cdltestfiles/test_atomic_array.cdl | 39 - .../dap4_test/cdltestfiles/test_fill.cdl | 11 - .../dap4_test/cdltestfiles/test_vlen3.cdl | 13 - .../dap4_test/cdltestfiles/test_vlen5.cdl | 16 - .../dap4_test/daptestfiles/CMakeLists.txt | 13 - .../daptestfiles/test_anon_dim.syn.dap | Bin 481 -> 0 bytes .../daptestfiles/test_atomic_types.syn.dap | Bin 1904 -> 0 bytes .../daptestfiles/test_one_vararray.nc.dap | Bin 502 -> 0 bytes .../dap4_test/daptestfiles/test_opaque.nc.dap | Bin 456 -> 0 bytes .../daptestfiles/test_sequence_1.syn.dap | Bin 506 -> 0 bytes .../daptestfiles/test_sequence_2.syn.dap | Bin 565 -> 0 bytes .../daptestfiles/test_struct_array.syn.dap | Bin 938 -> 0 bytes .../dap4_test/dmrtestfiles/CMakeLists.txt | 13 - .../dmrtestfiles/test_anon_dim.syn.dmr | 15 - .../dmrtestfiles/test_atomic_types.syn.dmr | 48 - .../dmrtestfiles/test_sequence_1.syn.dmr | 15 - .../dmrtestfiles/test_sequence_2.syn.dmr | 17 - .../dmrtestfiles/test_struct_array.syn.dmr | 27 - .../dap4_test/misctestfiles/CMakeLists.txt | 13 - .../dap4_test/misctestfiles/fnoc1.dap | Bin 26161 -> 0 bytes .../misctestfiles/test_fillmismatch.nc.dap | Bin 599 -> 0 bytes .../nctestfiles/test_atomic_array.nc | Bin 14523 -> 0 bytes .../nctestfiles/test_atomic_types.nc | Bin 13136 -> 0 bytes .../dap4_test/nctestfiles/test_enum.nc | Bin 1239 -> 0 bytes .../dap4_test/nctestfiles/test_enum_2.nc | Bin 1428 -> 0 bytes .../dap4_test/nctestfiles/test_enum_array.nc | Bin 8293 -> 0 bytes .../dap4_test/nctestfiles/test_fill.nc | Bin 1271 -> 0 bytes .../dap4_test/nctestfiles/test_groups1.nc | Bin 8469 -> 0 bytes .../dap4_test/nctestfiles/test_one_var.nc | Bin 603 -> 0 bytes .../nctestfiles/test_one_vararray.nc | Bin 6248 -> 0 bytes .../dap4_test/nctestfiles/test_opaque.nc | Bin 711 -> 0 bytes .../nctestfiles/test_opaque_array.nc | Bin 6272 -> 0 bytes .../dap4_test/nctestfiles/test_struct1.nc | Bin 805 -> 0 bytes .../nctestfiles/test_struct_array.nc | Bin 6534 -> 0 bytes .../nctestfiles/test_struct_nested.nc | Bin 1330 -> 0 bytes .../nctestfiles/test_struct_nested3.nc | Bin 1206 -> 0 bytes .../dap4_test/nctestfiles/test_struct_type.nc | Bin 805 -> 0 bytes .../dap4_test/nctestfiles/test_unlim1.nc | Bin 10266 -> 0 bytes .../dap4_test/nctestfiles/test_utf8.nc | Bin 6272 -> 0 bytes .../dap4_test/nctestfiles/test_vlen1.nc | Bin 4863 -> 0 bytes .../dap4_test/nctestfiles/test_vlen2.nc | Bin 6336 -> 0 bytes .../dap4_test/nctestfiles/test_vlen3.nc | Bin 4982 -> 0 bytes .../dap4_test/nctestfiles/test_vlen4.nc | Bin 4990 -> 0 bytes .../dap4_test/nctestfiles/test_vlen5.nc | Bin 6272 -> 0 bytes .../dap4_test/nctestfiles/test_vlen6.nc | Bin 6272 -> 0 bytes .../dap4_test/nctestfiles/test_vlen7.nc | Bin 6256 -> 0 bytes .../dap4_test/nctestfiles/test_vlen8.nc | Bin 6304 -> 0 bytes vendor/netcdf-c-4.9.2/dap4_test/test_data.c | 68 - .../dap4_test/test_fillmismatch.sh | 39 - vendor/netcdf-c-4.9.2/dap4_test/test_hyrax.sh | 56 - vendor/netcdf-c-4.9.2/dap4_test/test_meta.sh | 61 - .../netcdf-c-4.9.2/dap4_test/test_remote.sh | 90 - .../netcdf-c-4.9.2/dap4_test/test_thredds.sh | 61 - vendor/netcdf-c-4.9.2/docs/footer.html | 21 - vendor/netcdf-c-4.9.2/docs/internal.dox | 538 - vendor/netcdf-c-4.9.2/include/Makefile.am | 46 - vendor/netcdf-c-4.9.2/include/nc.h | 80 - vendor/netcdf-c-4.9.2/include/nchttp.h | 49 - vendor/netcdf-c-4.9.2/include/ncs3sdk.h | 31 - vendor/netcdf-c-4.9.2/include/netcdf_aux.h | 97 - vendor/netcdf-c-4.9.2/libdap4/CMakeLists.txt | 37 - vendor/netcdf-c-4.9.2/libdap4/d4chunk.c | 189 - vendor/netcdf-c-4.9.2/libdap4/d4varx.c | 193 - .../netcdf-c-4.9.2/libdispatch/CMakeLists.txt | 52 - vendor/netcdf-c-4.9.2/libdispatch/ddispatch.c | 145 - vendor/netcdf-c-4.9.2/libdispatch/dhttp.c | 707 - vendor/netcdf-c-4.9.2/libdispatch/dinstance.c | 885 - vendor/netcdf-c-4.9.2/libdispatch/ds3util.c | 264 - .../libdispatch/utf8proc_data.c | 14386 ---- vendor/netcdf-c-4.9.2/libhdf5/CMakeLists.txt | 27 - vendor/netcdf-c-4.9.2/liblib/CMakeLists.txt | 210 - .../netcdf-c-4.9.2/libncpoco/CMakeLists.txt | 8 - vendor/netcdf-c-4.9.2/libncxml/CMakeLists.txt | 14 - vendor/netcdf-c-4.9.2/libsrc/CMakeLists.txt | 77 - vendor/netcdf-c-4.9.2/nc-config.in | 283 - .../nc_test4/ref_fixedstring.cdl | 9 - .../nc_test4/ref_fixedstring.h5 | Bin 2057 -> 0 bytes .../nc_test4/test_filter_vlen.c | 276 - .../nc_test4/tst_filter_avail.c | 106 - vendor/netcdf-c-4.9.2/ncdump/CMakeLists.txt | 351 - vendor/netcdf-c-4.9.2/ncdump/ref_pathcvt.txt | 45 - vendor/netcdf-c-4.9.2/ncdump/testpathcvt.sh | 48 - vendor/netcdf-c-4.9.2/ncdump/tst_mud.sh | 35 - vendor/netcdf-c-4.9.2/ncdump/tst_nccopy5.sh | 202 - .../netcdf-c-4.9.2/nczarr_test/CMakeLists.txt | 155 - vendor/netcdf-c-4.9.2/nczarr_test/Makefile.am | 219 - .../ref_byte_fill_value_null.zarr.zip | Bin 1666 -> 0 bytes .../nczarr_test/ref_jsonconvention.zmap | 5 - .../netcdf-c-4.9.2/nczarr_test/ref_misc1.dmp | 97 - .../nczarr_test/ref_oldformat.zip | Bin 5433 -> 0 bytes vendor/netcdf-c-4.9.2/nczarr_test/ref_rem.dmp | 10 - .../nczarr_test/ref_ut_map_create.cdl | 1 - .../nczarr_test/ref_ut_mapapi_create.cdl | 1 - .../netcdf-c-4.9.2/nczarr_test/run_interop.sh | 92 - .../nczarr_test/run_jsonconvention.sh | 34 - .../nczarr_test/run_nczfilter.sh | 14 - .../nczarr_test/run_s3_cleanup.sh | 19 - .../nczarr_test/run_ut_chunk.sh | 60 - .../netcdf-c-4.9.2/nczarr_test/ut_chunking.c | 93 - .../nczarr_test/ut_projections.c | 137 - vendor/netcdf-c-4.9.2/oc2/dapy.h | 87 - vendor/netcdf-c-4.9.2/plugins/CMakeLists.txt | 144 - vendor/netcdf-c-4.9.2/plugins/h5misc.h | 40 - vendor/netcdf-c-4.9.2/postinstall.sh.in | 136 - .../netcdf-c-4.9.2/unit_test/CMakeLists.txt | 40 - vendor/netcdf-c-4.9.2/unit_test/run_aws.sh | 31 - vendor/netcdf-c-4.9.2/unit_test/test_aws.c | 177 - vendor/netcdf-c-4.9.2/unit_test/test_ncuri.c | 97 - vendor/netcdf-c-4.9.3/CITATION.cff | 59 + .../CMakeInstallation.cmake | 72 +- vendor/netcdf-c-4.9.3/CMakeLists.txt | 1943 + .../COMPILE.cmake.txt | 8 +- .../COPYRIGHT | 0 .../CTestConfig.cmake.in | 0 .../CTestCustom.cmake.in} | 7 + .../FixBundle.cmake.in | 0 .../INSTALL.md | 19 +- .../Makefile.am | 78 +- .../Makefile.in | 228 +- .../README.md | 4 +- .../RELEASE_NOTES.md | 319 +- .../acinclude.m4 | 45 - .../aclocal.m4 | 421 +- .../cmake/ConfigUser.cmake | 0 vendor/netcdf-c-4.9.3/cmake/check_hdf5.cmake | 55 + .../netcdf-c-4.9.3/cmake/dependencies.cmake | 512 + vendor/netcdf-c-4.9.3/cmake/deprecated.cmake | 39 + .../cmake/modules/FindBlosc.cmake | 9 +- .../cmake/modules/FindBz2.cmake | 0 .../cmake/modules/FindBzip2.cmake | 0 .../cmake/modules/FindHDF4.cmake | 0 .../cmake/modules/FindMakeDist.cmake | 0 .../cmake/modules/FindPNETCDF.cmake | 80 + .../cmake/modules/FindSzip.cmake | 19 +- .../cmake/modules/FindXDR.cmake | 0 .../cmake/modules/FindZLIB.cmake | 0 .../cmake/modules/FindZip.cmake | 0 .../cmake/modules/FindZstd.cmake | 0 .../cmake/modules/windows/FindHDF5.cmake | 0 .../cmake/netcdf_functions_macros.cmake | 339 + .../cmake_uninstall.cmake.in | 0 .../compile | 11 +- .../config.guess | 112 +- .../config.h.cmake.in | 156 +- .../config.h.in | 346 +- .../config.sub | 251 +- .../configure | 9048 ++- .../configure.ac | 1166 +- .../dap4_test/CMakeLists.txt | 60 +- .../dap4_test/Makefile.am | 54 +- .../dap4_test/Makefile.in | 243 +- .../dap4_test/baseline/CMakeLists.txt | 0 .../baseline/test_atomic_array.nc.d4d | 3 +- .../baseline/test_atomic_array.nc.d4m | 5 +- .../baseline/test_atomic_array.nc.d4p | 7 +- .../baseline/test_atomic_types.nc.d4d | 3 +- .../baseline/test_atomic_types.nc.d4m | 5 +- .../baseline/test_atomic_types.nc.d4p | 9 +- .../dap4_test/baseline/test_enum_1.nc.d4d} | 3 +- .../dap4_test/baseline/test_enum_1.nc.d4m} | 3 +- .../dap4_test/baseline/test_enum_1.nc.d4p} | 7 +- .../dap4_test/baseline/test_enum_2.nc.d4d | 3 +- .../dap4_test/baseline/test_enum_2.nc.d4m | 1 - .../dap4_test/baseline/test_enum_2.nc.d4p | 5 +- .../dap4_test/baseline/test_enum_3.nc.d4d | 12 + .../dap4_test/baseline/test_enum_3.nc.d4m | 9 + .../dap4_test/baseline/test_enum_3.nc.d4p | 27 + .../dap4_test/baseline/test_enum_array.nc.d4d | 3 +- .../dap4_test/baseline/test_enum_array.nc.d4m | 1 - .../dap4_test/baseline/test_enum_array.nc.d4p | 5 +- .../dap4_test/baseline/test_fill.nc.d4d} | 5 +- .../dap4_test/baseline/test_fill.nc.d4m | 5 +- .../dap4_test/baseline/test_fill.nc.d4p | 9 +- .../dap4_test/baseline/test_fill_2.nc.d4d | 27 + .../dap4_test/baseline/test_fill_2.nc.d4m} | 17 +- .../dap4_test/baseline/test_fill_2.nc.d4p} | 54 +- .../dap4_test/baseline/test_groups1.nc.d4d | 3 +- .../dap4_test/baseline/test_groups1.nc.d4m | 1 - .../dap4_test/baseline/test_groups1.nc.d4p | 3 + .../dap4_test/baseline/test_misc1.nc.d4d | 24 + .../dap4_test/baseline/test_misc1.nc.d4m | 17 + .../dap4_test/baseline/test_misc1.nc.d4p | 42 + .../dap4_test/baseline/test_one_var.nc.d4d} | 1 - .../dap4_test/baseline/test_one_var.nc.d4m | 1 - .../dap4_test/baseline/test_one_var.nc.d4p | 3 + .../baseline/test_one_vararray.nc.d4d} | 1 - .../baseline/test_one_vararray.nc.d4m | 1 - .../baseline/test_one_vararray.nc.d4p | 3 + .../dap4_test/baseline/test_opaque.nc.d4d | 3 +- .../dap4_test/baseline/test_opaque.nc.d4m | 6 + .../dap4_test/baseline/test_opaque.nc.d4p | 5 +- .../baseline/test_opaque_array.nc.d4d | 3 +- .../baseline/test_opaque_array.nc.d4m | 5 +- .../baseline/test_opaque_array.nc.d4p | 5 +- .../dap4_test/baseline/test_struct1.nc.d4d | 3 +- .../dap4_test/baseline/test_struct1.nc.d4m | 1 - .../dap4_test/baseline/test_struct1.nc.d4p | 3 + .../baseline/test_struct_array.nc.d4d | 3 +- .../baseline/test_struct_array.nc.d4m | 1 - .../baseline/test_struct_array.nc.d4p | 3 + .../baseline/test_struct_nested.nc.d4d | 3 +- .../baseline/test_struct_nested.nc.d4m | 1 - .../baseline/test_struct_nested.nc.d4p | 3 + .../baseline/test_struct_nested3.nc.d4d | 3 +- .../baseline/test_struct_nested3.nc.d4m | 1 - .../baseline/test_struct_nested3.nc.d4p | 3 + .../baseline/test_struct_type.nc.d4d | 3 +- .../baseline/test_struct_type.nc.d4m | 1 - .../baseline/test_struct_type.nc.d4p | 3 + .../dap4_test/baseline/test_test.nc.d4d | 9 + .../dap4_test/baseline/test_test.nc.d4m | 6 + .../dap4_test/baseline/test_test.nc.d4p | 23 + .../dap4_test/baseline/test_unlim.nc.d4d | 37 + .../dap4_test/baseline/test_unlim.nc.d4m | 22 + .../dap4_test/baseline/test_unlim.nc.d4p | 63 + .../dap4_test/baseline/test_unlim1.nc.d4d | 14 +- .../dap4_test/baseline/test_unlim1.nc.d4m | 10 +- .../dap4_test/baseline/test_unlim1.nc.d4p | 37 +- .../dap4_test/baseline/test_utf8.nc.d4d | 3 +- .../dap4_test/baseline/test_utf8.nc.d4m | 1 - .../dap4_test/baseline/test_utf8.nc.d4p | 3 + .../dap4_test/baseline/test_vlen1.nc.d4d | 3 +- .../dap4_test/baseline/test_vlen1.nc.d4m | 1 - .../dap4_test/baseline/test_vlen1.nc.d4p | 9 +- .../dap4_test/baseline/test_vlen11.nc.d4d | 12 + .../dap4_test/baseline/test_vlen11.nc.d4m | 9 + .../dap4_test/baseline/test_vlen11.nc.d4p | 26 + .../dap4_test/baseline/test_vlen2.nc.d4d | 3 +- .../dap4_test/baseline/test_vlen2.nc.d4m | 1 - .../dap4_test/baseline/test_vlen2.nc.d4p | 6 + .../dap4_test/baseline/test_vlen3.nc.d4d | 3 +- .../dap4_test/baseline/test_vlen3.nc.d4m | 1 - .../dap4_test/baseline/test_vlen3.nc.d4p | 3 + .../dap4_test/baseline/test_vlen4.nc.d4d | 5 +- .../dap4_test/baseline/test_vlen4.nc.d4m | 3 +- .../dap4_test/baseline/test_vlen4.nc.d4p | 7 +- .../dap4_test/baseline/test_vlen5.nc.d4d | 3 +- .../dap4_test/baseline/test_vlen5.nc.d4m | 1 - .../dap4_test/baseline/test_vlen5.nc.d4p | 3 + .../dap4_test/baseline/test_vlen6.nc.d4d | 3 +- .../dap4_test/baseline/test_vlen6.nc.d4m | 1 - .../dap4_test/baseline/test_vlen6.nc.d4p | 6 + .../dap4_test/baseline/test_vlen7.nc.d4d | 3 +- .../dap4_test/baseline/test_vlen7.nc.d4m | 1 - .../dap4_test/baseline/test_vlen7.nc.d4p | 6 + .../dap4_test/baseline/test_vlen8.nc.d4d | 3 +- .../dap4_test/baseline/test_vlen8.nc.d4m | 1 - .../dap4_test/baseline/test_vlen8.nc.d4p | 6 + .../dap4_test/baseline/test_zerodim.nc.d4d | 24 + .../dap4_test/baseline/test_zerodim.nc.d4m | 17 + .../dap4_test/baseline/test_zerodim.nc.d4p | 42 + .../dap4_test/baselinehyrax}/CMakeLists.txt | 0 .../baselinehyrax/amsre_20060131v5.dat.hyrax | 14 + .../nc4_nc_classic_comp.nc.hyrax | 6 +- .../nc4_nc_classic_no_comp.nc.hyrax | 104 + .../baselinehyrax/nc4_strings.nc.hyrax | 32 + .../baselinehyrax/nc4_strings_comp.nc.hyrax | 0 .../nc4_unsigned_types.nc.hyrax | 2 +- .../nc4_unsigned_types_comp.nc.hyrax | 2 +- .../baselinehyrax/ref_tst_compounds.nc.hyrax | 5 +- .../dap4_test/baselineraw}/CMakeLists.txt | 0 .../baselineraw/test_atomic_array.nc.ncdump} | 1 - .../baselineraw/test_atomic_types.nc.ncdump} | 1 - .../baselineraw/test_enum_1.nc.ncdump} | 3 +- .../baselineraw/test_enum_2.nc.ncdump} | 1 - .../baselineraw/test_enum_3.nc.ncdump | 12 + .../baselineraw/test_enum_array.nc.ncdump} | 1 - .../baselineraw/test_fill.nc.ncdump} | 7 +- .../baselineraw/test_fill_2.nc.ncdump | 27 + .../baselineraw/test_groups1.nc.ncdump} | 1 - .../baselineraw/test_misc1.nc.ncdump | 24 + .../baselineraw/test_one_var.nc.ncdump} | 3 +- .../baselineraw/test_one_vararray.nc.ncdump} | 3 +- .../baselineraw/test_opaque.nc.ncdump} | 3 - .../baselineraw/test_opaque_array.nc.ncdump} | 1 - .../baselineraw/test_struct1.nc.ncdump} | 1 - .../baselineraw/test_struct_array.nc.ncdump} | 1 - .../baselineraw/test_struct_nested.nc.ncdump} | 1 - .../test_struct_nested3.nc.ncdump} | 1 - .../baselineraw/test_struct_type.nc.ncdump} | 1 - .../dap4_test/baselineraw/test_test.nc.ncdump | 9 + .../baselineraw/test_unlim.nc.ncdump | 37 + .../baselineraw/test_unlim1.nc.ncdump} | 12 +- .../baselineraw/test_utf8.nc.ncdump} | 1 - .../baselineraw/test_vlen1.nc.ncdump} | 1 - .../baselineraw/test_vlen11.nc.ncdump | 12 + .../baselineraw/test_vlen2.nc.ncdump} | 1 - .../baselineraw/test_vlen3.nc.ncdump} | 1 - .../baselineraw/test_vlen4.nc.ncdump} | 3 +- .../baselineraw/test_vlen5.nc.ncdump} | 1 - .../baselineraw/test_vlen6.nc.ncdump} | 1 - .../baselineraw/test_vlen7.nc.ncdump} | 1 - .../baselineraw/test_vlen8.nc.ncdump} | 1 - .../baselineraw/test_zerodim.nc.ncdump | 24 + .../dap4_test/baselineremote}/CMakeLists.txt | 0 .../test_atomic_array.1.nc.ncdump} | 14 +- .../test_atomic_array.2.nc.ncdump} | 6 +- .../test_atomic_array.3.nc.ncdump} | 6 +- .../test_atomic_array.nc.ncdump} | 3 - .../test_atomic_types.nc.ncdump} | 3 - .../baselineremote/test_enum_1.nc.ncdump} | 5 +- .../baselineremote/test_enum_2.nc.ncdump} | 3 - .../baselineremote/test_enum_3.nc.ncdump | 12 + .../test_enum_array.6.nc.ncdump} | 6 +- .../baselineremote/test_enum_array.nc.ncdump} | 3 - .../baselineremote/test_fill.nc.ncdump} | 7 +- .../baselineremote/test_fill_2.nc.ncdump | 27 + .../baselineremote/test_groups1.nc.ncdump} | 3 - .../baselineremote/test_misc1.nc.ncdump | 24 + .../baselineremote/test_one_var.nc.ncdump} | 3 - .../test_one_vararray.4.nc.ncdump} | 6 +- .../test_one_vararray.5.nc.ncdump} | 6 +- .../test_one_vararray.nc.ncdump} | 3 - .../baselineremote/test_opaque.nc.ncdump} | 3 +- .../test_opaque_array.7.nc.ncdump} | 8 +- .../test_opaque_array.nc.ncdump} | 3 - .../baselineremote/test_struct1.nc.ncdump} | 3 - .../test_struct_array.8.nc.ncdump} | 6 +- .../test_struct_array.nc.ncdump} | 3 - .../test_struct_nested.nc.ncdump} | 3 - .../test_struct_nested3.nc.ncdump} | 3 - .../test_struct_type.nc.ncdump} | 3 - .../baselineremote/test_test.nc.ncdump | 9 + .../baselineremote/test_unlim.nc.ncdump | 37 + .../baselineremote/test_unlim1.nc.ncdump | 37 + .../baselineremote/test_utf8.nc.ncdump} | 3 - .../baselineremote/test_vlen1.nc.ncdump} | 5 +- .../baselineremote/test_vlen11.nc.ncdump | 12 + .../baselineremote/test_vlen2.nc.ncdump} | 5 +- .../baselineremote/test_vlen3.nc.ncdump} | 5 +- .../baselineremote/test_vlen4.nc.ncdump} | 7 +- .../baselineremote/test_vlen5.nc.ncdump} | 5 +- .../baselineremote/test_vlen6.nc.ncdump} | 5 +- .../baselineremote/test_vlen7.nc.ncdump} | 5 +- .../baselineremote/test_vlen8.nc.ncdump} | 5 +- .../baselineremote/test_zerodim.nc.ncdump | 24 + .../2004050300_eta_211.nc.thredds | 40 + .../dap4_test/baselinethredds/CMakeLists.txt | 24 + .../baselinethredds/H.1.1.nc.thredds | 49 + vendor/netcdf-c-4.9.3/dap4_test/build.sh | 277 + .../dap4_test/cdltestfiles}/CMakeLists.txt | 0 .../cdltestfiles/test_atomic_array.cdl} | 27 +- .../cdltestfiles/test_atomic_types.cdl | 0 .../dap4_test/cdltestfiles/test_enum_1.cdl} | 2 +- .../dap4_test/cdltestfiles/test_enum_2.cdl | 0 .../dap4_test/cdltestfiles/test_enum_3.cdl | 11 + .../cdltestfiles/test_enum_array.cdl | 0 .../dap4_test/cdltestfiles/test_fill.cdl} | 3 - .../dap4_test/cdltestfiles/test_groups1.cdl | 0 .../dap4_test/cdltestfiles/test_misc1.cdl} | 13 +- .../dap4_test/cdltestfiles/test_one_var.cdl | 0 .../cdltestfiles/test_one_vararray.cdl | 0 .../dap4_test/cdltestfiles/test_opaque.cdl | 0 .../cdltestfiles/test_opaque_array.cdl | 0 .../dap4_test/cdltestfiles/test_struct1.cdl | 0 .../cdltestfiles/test_struct_array.cdl | 0 .../cdltestfiles/test_struct_nested.cdl | 0 .../cdltestfiles/test_struct_nested3.cdl | 2 +- .../cdltestfiles/test_struct_type.cdl | 0 .../dap4_test/cdltestfiles/test_test.cdl | 11 + .../dap4_test/cdltestfiles/test_unlim.cdl | 34 + .../dap4_test/cdltestfiles/test_unlim1.cdl | 0 .../dap4_test/cdltestfiles/test_utf8.cdl | 0 .../dap4_test/cdltestfiles/test_vlen1.cdl | 0 .../dap4_test/cdltestfiles/test_vlen10.cdl | 14 + .../dap4_test/cdltestfiles/test_vlen11.cdl | 13 + .../dap4_test/cdltestfiles/test_vlen2.cdl | 0 .../dap4_test/cdltestfiles/test_vlen3.cdl | 12 + .../dap4_test/cdltestfiles/test_vlen4.cdl | 0 .../dap4_test/cdltestfiles/test_vlen5.cdl | 14 + .../dap4_test/cdltestfiles/test_vlen6.cdl | 0 .../dap4_test/cdltestfiles/test_vlen7.cdl | 0 .../dap4_test/cdltestfiles/test_vlen8.cdl | 0 .../dap4_test/cdltestfiles/test_vlen9.cdl | 16 + .../dap4_test/cdltestfiles/test_zerodim.cdl | 23 + vendor/netcdf-c-4.9.3/dap4_test/d4manifest.sh | 51 + .../dap4_test/d4test_common.sh | 45 +- vendor/netcdf-c-4.9.3/dap4_test/dump.c | 96 + .../dap4_test/findtestserver4.c | 4 +- .../dap4_test/pingurl4.c | 8 +- .../dap4_test/rawtestfiles}/CMakeLists.txt | 0 .../rawtestfiles/test_atomic_array.1.nc.dap} | Bin 943 -> 1042 bytes .../rawtestfiles/test_atomic_array.1.nc.dmr} | 5 +- .../rawtestfiles/test_atomic_array.2.nc.dap} | Bin 564 -> 701 bytes .../rawtestfiles/test_atomic_array.2.nc.dmr} | 3 + .../rawtestfiles/test_atomic_array.3.nc.dap} | Bin 564 -> 701 bytes .../rawtestfiles/test_atomic_array.3.nc.dmr} | 3 + .../rawtestfiles}/test_atomic_array.nc.dap | Bin 2232 -> 2408 bytes .../rawtestfiles}/test_atomic_array.nc.dmr | 7 +- .../rawtestfiles}/test_atomic_types.nc.dap | Bin 1923 -> 1962 bytes .../rawtestfiles}/test_atomic_types.nc.dmr | 9 +- .../rawtestfiles/test_enum_1.nc.dap} | Bin 1236 -> 1367 bytes .../rawtestfiles/test_enum_1.nc.dmr} | 7 +- .../rawtestfiles}/test_enum_2.nc.dap | Bin 1294 -> 1423 bytes .../rawtestfiles}/test_enum_2.nc.dmr | 5 +- .../dap4_test/rawtestfiles/test_enum_3.nc.dap | Bin 0 -> 836 bytes .../dap4_test/rawtestfiles/test_enum_3.nc.dmr | 22 + .../rawtestfiles/test_enum_array.6.nc.dap} | Bin 1379 -> 1508 bytes .../rawtestfiles/test_enum_array.6.nc.dmr} | 5 +- .../rawtestfiles}/test_enum_array.nc.dap | Bin 1310 -> 1550 bytes .../rawtestfiles}/test_enum_array.nc.dmr | 5 +- .../dap4_test/rawtestfiles}/test_fill.nc.dap | Bin 598 -> 724 bytes .../dap4_test/rawtestfiles}/test_fill.nc.dmr | 9 +- .../rawtestfiles/test_fill_2.nc.dap} | Bin 2222 -> 1953 bytes .../rawtestfiles/test_fill_2.nc.dmr} | 54 +- .../rawtestfiles}/test_groups1.nc.dap | Bin 1155 -> 1280 bytes .../rawtestfiles}/test_groups1.nc.dmr | 3 + .../dap4_test/rawtestfiles/test_misc1.nc.dap | Bin 0 -> 1434 bytes .../dap4_test/rawtestfiles/test_misc1.nc.dmr | 39 + .../rawtestfiles}/test_one_var.nc.dap | Bin 416 -> 553 bytes .../rawtestfiles}/test_one_var.nc.dmr | 3 + .../rawtestfiles/test_one_vararray.4.nc.dap} | Bin 554 -> 691 bytes .../rawtestfiles/test_one_vararray.4.nc.dmr} | 3 + .../rawtestfiles/test_one_vararray.5.nc.dap | Bin 0 -> 697 bytes .../rawtestfiles/test_one_vararray.5.nc.dmr} | 6 +- .../rawtestfiles/test_one_vararray.nc.dap} | Bin 599 -> 736 bytes .../rawtestfiles}/test_one_vararray.nc.dmr | 3 + .../rawtestfiles/test_opaque.nc.dap} | Bin 571 -> 567 bytes .../rawtestfiles}/test_opaque.nc.dmr | 5 +- .../rawtestfiles}/test_opaque_array.7.nc.dap | Bin 644 -> 755 bytes .../rawtestfiles}/test_opaque_array.7.nc.dmr | 5 +- .../rawtestfiles}/test_opaque_array.nc.dap | Bin 615 -> 828 bytes .../rawtestfiles}/test_opaque_array.nc.dmr | 5 +- .../rawtestfiles}/test_struct1.nc.dap | Bin 495 -> 632 bytes .../rawtestfiles}/test_struct1.nc.dmr | 3 + .../rawtestfiles/test_struct_array.8.nc.dap} | Bin 678 -> 815 bytes .../rawtestfiles/test_struct_array.8.nc.dmr} | 3 + .../rawtestfiles}/test_struct_array.nc.dap | Bin 716 -> 957 bytes .../rawtestfiles}/test_struct_array.nc.dmr | 3 + .../rawtestfiles}/test_struct_nested.nc.dap | Bin 693 -> 830 bytes .../rawtestfiles}/test_struct_nested.nc.dmr | 3 + .../rawtestfiles}/test_struct_nested3.nc.dap | Bin 606 -> 743 bytes .../rawtestfiles}/test_struct_nested3.nc.dmr | 3 + .../rawtestfiles}/test_struct_type.nc.dap | Bin 499 -> 636 bytes .../rawtestfiles}/test_struct_type.nc.dmr | 3 + .../dap4_test/rawtestfiles/test_test.nc.dap | Bin 0 -> 754 bytes .../dap4_test/rawtestfiles/test_test.nc.dmr | 20 + .../dap4_test/rawtestfiles/test_unlim.nc.dap | Bin 0 -> 2135 bytes .../dap4_test/rawtestfiles/test_unlim.nc.dmr | 60 + .../rawtestfiles}/test_unlim1.nc.dap | Bin 1735 -> 2136 bytes .../rawtestfiles}/test_unlim1.nc.dmr | 37 +- .../dap4_test/rawtestfiles}/test_utf8.nc.dap | Bin 522 -> 659 bytes .../dap4_test/rawtestfiles}/test_utf8.nc.dmr | 3 + .../dap4_test/rawtestfiles}/test_vlen1.nc.dap | Bin 480 -> 721 bytes .../dap4_test/rawtestfiles}/test_vlen1.nc.dmr | 6 + .../dap4_test/rawtestfiles/test_vlen11.nc.dap | Bin 0 -> 714 bytes .../rawtestfiles/test_vlen11.nc.dmr} | 17 +- .../dap4_test/rawtestfiles}/test_vlen2.nc.dap | Bin 696 -> 937 bytes .../dap4_test/rawtestfiles}/test_vlen2.nc.dmr | 6 + .../dap4_test/rawtestfiles}/test_vlen3.nc.dap | Bin 539 -> 676 bytes .../dap4_test/rawtestfiles}/test_vlen3.nc.dmr | 3 + .../dap4_test/rawtestfiles}/test_vlen4.nc.dap | Bin 586 -> 721 bytes .../dap4_test/rawtestfiles}/test_vlen4.nc.dmr | 4 +- .../dap4_test/rawtestfiles}/test_vlen5.nc.dap | Bin 617 -> 754 bytes .../dap4_test/rawtestfiles}/test_vlen5.nc.dmr | 3 + .../dap4_test/rawtestfiles}/test_vlen6.nc.dap | Bin 560 -> 801 bytes .../dap4_test/rawtestfiles}/test_vlen6.nc.dmr | 6 + .../dap4_test/rawtestfiles}/test_vlen7.nc.dap | Bin 540 -> 781 bytes .../dap4_test/rawtestfiles}/test_vlen7.nc.dmr | 6 + .../dap4_test/rawtestfiles}/test_vlen8.nc.dap | Bin 666 -> 907 bytes .../dap4_test/rawtestfiles}/test_vlen8.nc.dmr | 6 + .../rawtestfiles/test_zerodim.nc.dap | Bin 0 -> 1436 bytes .../rawtestfiles/test_zerodim.nc.dmr | 39 + .../dap4_test/test_common.h | 20 +- .../dap4_test/test_constraints.sh | 51 + .../dap4_test/test_curlopt.sh} | 0 .../netcdf-c-4.9.3/dap4_test/test_dap4url.sh | 80 + vendor/netcdf-c-4.9.3/dap4_test/test_data.c | 163 + .../dap4_test/test_data.sh | 22 +- .../dap4_test/test_earthdata.sh | 36 + vendor/netcdf-c-4.9.3/dap4_test/test_hyrax.sh | 84 + .../dap4_test/test_meta.c | 2 +- vendor/netcdf-c-4.9.3/dap4_test/test_meta.sh | 59 + .../dap4_test/test_parse.c | 2 +- .../dap4_test/test_parse.sh | 22 +- .../dap4_test/test_raw.sh | 23 +- .../netcdf-c-4.9.3/dap4_test/test_remote.sh | 49 + .../netcdf-c-4.9.3/dap4_test/test_thredds.sh | 68 + .../depcomp | 15 +- .../docs/CMakeLists.txt | 15 +- .../docs/COPYRIGHT.md | 0 .../docs/Doxyfile.in | 769 +- .../docs/DoxygenLayout.xml | 0 .../docs/FAQ.md | 45 +- .../docs/Makefile.am | 14 +- .../docs/Makefile.in | 74 +- .../docs/all-error-codes.md | 9 + .../docs/architecture.dox | 0 .../docs/attribute_conventions.md | 197 + .../docs/auth.md | 151 +- .../docs/building-with-cmake.md | 29 +- .../docs/byterange.md | 48 +- vendor/netcdf-c-4.9.3/docs/cloud.md | 349 + .../docs/credits.md | 4 +- .../docs/dispatch.md | 92 +- .../docs/doxygen-awesome-css/.npmignore | 3 + .../docs/doxygen-awesome-css/Doxyfile | 2793 + .../docs/doxygen-awesome-css/LICENSE} | 13 +- .../docs/doxygen-awesome-css/README.md | 171 + .../doxygen-awesome-css/docs/customization.md | 119 + .../doxygen-awesome-css/docs/extensions.md | 279 + .../docs/img/darkmode_toggle.png | Bin 0 -> 11523 bytes .../docs/img/fancy_scrollbars_firefox.png | Bin 0 -> 37200 bytes .../docs/img/fancy_scrollbars_webkit.gif | Bin 0 -> 5614878 bytes .../docs/img/fragment_copy_button.png | Bin 0 -> 32871 bytes .../docs/img/interactive_toc_mobile.png | Bin 0 -> 16425 bytes .../docs/img/paragraph_link.png | Bin 0 -> 12629 bytes .../docs/doxygen-awesome-css/docs/tricks.md | 127 + .../doxygen-awesome-darkmode-toggle.js | 157 + .../doxygen-awesome-fragment-copy-button.js | 85 + .../doxygen-awesome-interactive-toc.js | 81 + .../doxygen-awesome-paragraph-link.js | 51 + ...n-awesome-sidebar-only-darkmode-toggle.css | 40 + .../doxygen-awesome-sidebar-only.css | 116 + .../doxygen-awesome-tabs.js | 90 + .../doxygen-awesome-css/doxygen-awesome.css | 2669 + .../doxygen-custom/custom-alternative.css | 54 + .../doxygen-custom/custom.css | 57 + .../doxygen-custom/header.html | 90 + .../toggle-alternative-theme.js | 12 + .../doxygen-awesome-css/img/screenshot.png | Bin 0 -> 216518 bytes .../doxygen-awesome-css/img/testimage.png | Bin 0 -> 4792 bytes .../img/theme-variants-base.drawio.svg | 117 + .../theme-variants-sidebar-only.drawio.svg | 102 + .../include/MyLibrary/example.hpp | 169 + .../include/MyLibrary/subclass-example.hpp | 46 + .../docs/doxygen-awesome-css/logo.drawio.svg | 1 + .../docs/doxygen-awesome-css/package.json | 34 + .../docs/file_format_specifications.md | 747 + .../docs/filters.md | 247 +- vendor/netcdf-c-4.9.3/docs/footer.html | 17 + .../docs/groups.dox | 0 vendor/netcdf-c-4.9.3/docs/header.html | 80 + .../docs/images/InstallTreeWindows.png | Bin .../docs/images/Makefile.am | 0 .../docs/images/Makefile.in | 58 +- .../docs/images/aqua.jpg | Bin .../docs/images/chunking2.png | Bin .../docs/images/compatibility3.png | Bin .../docs/images/compression.png | Bin .../docs/images/deptree.jpg | Bin .../docs/images/groups.png | Bin .../docs/images/nc-classic-uml.png | Bin .../docs/images/nc4-model.png | Bin .../docs/images/ncatts.png | Bin .../docs/images/nccoords.png | Bin .../docs/images/ncfile.png | Bin .../docs/images/netcdf_architecture.png | Bin .../docs/images/pnetcdf.png | Bin .../docs/images/quantize_performance.png | Bin .../docs/images/quantize_pi.png | Bin .../docs/images/terra.jpg | Bin .../docs/images/uniLogo.png | Bin .../docs/indexing.dox | 2 +- .../docs/inmeminternal.dox | 0 .../docs/inmemory.md | 0 .../docs/install-fortran.md | 2 +- vendor/netcdf-c-4.9.3/docs/internal.md | 771 + .../docs/known_problems.md | 35 +- .../docs/mainpage.dox | 19 +- .../docs/nczarr.md | 750 +- vendor/netcdf-c-4.9.3/docs/netcdf-50x50.png | Bin 0 -> 2059 bytes .../docs/netcdf.m4 | 0 .../docs/notes.md | 0 .../docs/obsolete/fan_utils.html | 0 vendor/netcdf-c-4.9.3/docs/pluginpath.md | 208 + .../docs/quantize.md | 0 vendor/netcdf-c-4.9.3/docs/quickstart_env.md | 157 + .../netcdf-c-4.9.3/docs/quickstart_filters.md | 45 + .../netcdf-c-4.9.3/docs/quickstart_paths.md | 110 + .../docs/testserver.dox | 0 .../docs/tutorial.dox | 41 +- .../docs/windows-binaries.md | 27 +- .../examples/C/CMakeLists.txt | 0 .../examples/C/Makefile.am | 4 +- .../examples/C/Makefile.in | 160 +- .../examples/C/filter_example.c | 2 +- .../examples/C/format.c | 2 +- .../examples/C/parallel_vara.c | 0 .../examples/C/pres_temp_4D_rd.c | 4 +- .../examples/C/pres_temp_4D_wr.c | 22 +- .../examples/C/quick_large_files.c | 0 .../examples/C/quick_small_files.c | 0 .../examples/C/run_examples.sh | 0 .../examples/C/run_examples4.sh | 0 .../examples/C/run_filter.sh | 0 .../examples/C/run_par_test.sh.in | 0 .../examples/C/sfc_pres_temp_more.c | 0 .../examples/C/sfc_pres_temp_rd.c | 8 +- .../examples/C/sfc_pres_temp_wr.c | 16 +- .../examples/C/simple.c | 0 .../examples/C/simple_nc4_rd.c | 0 .../examples/C/simple_nc4_wr.c | 0 .../examples/C/simple_xy_nc4_rd.c | 0 .../examples/C/simple_xy_nc4_wr.c | 0 .../examples/C/simple_xy_rd.c | 0 .../examples/C/simple_xy_wr.c | 0 .../examples/CDL/CMakeLists.txt | 0 .../examples/CDL/Makefile.am | 0 .../examples/CDL/Makefile.in | 122 +- .../examples/CDL/do_comps.sh | 0 .../examples/CDL/pres_temp_4D.cdl | 0 .../examples/CDL/sfc_pres_temp.cdl | 0 .../examples/CDL/simple_xy.cdl | 0 .../examples/CMakeLists.txt | 2 +- .../examples/Makefile.am | 2 +- .../examples/Makefile.in | 60 +- .../fuzz/CMakeLists.txt | 0 .../fuzz/Makefile.am | 0 .../fuzz/fuzz_open.c | 0 .../h5_test/CMakeLists.txt | 17 +- .../h5_test/Makefile.am | 29 +- .../h5_test/Makefile.in | 229 +- .../h5_test/h5_err_macros.h | 0 .../h5_test/ref_tst_compounds.nc | Bin .../h5_test/ref_tst_h_compounds.h5 | Bin .../h5_test/ref_tst_h_compounds2.h5 | Bin .../h5_test/run_h5_zstd_tests.sh | 24 + .../h5_test/run_par_tests.sh | 0 .../h5_test/run_par_tests.sh.in | 0 .../h5_test/tst_h_atts.c | 7 +- .../h5_test/tst_h_atts3.c | 10 +- .../h5_test/tst_h_atts4.c | 6 +- .../h5_test/tst_h_compounds.c | 38 +- .../h5_test/tst_h_compounds2.c | 0 .../h5_test/tst_h_dimscales.c | 9 +- .../h5_test/tst_h_dimscales1.c | 0 .../h5_test/tst_h_dimscales2.c | 21 +- .../h5_test/tst_h_dimscales3.c | 0 .../h5_test/tst_h_dimscales4.c | 2 +- .../h5_test/tst_h_enums.c | 12 +- .../h5_test/tst_h_files.c | 22 +- .../h5_test/tst_h_files2.c | 0 .../h5_test/tst_h_files4.c | 21 +- .../h5_test/tst_h_grps.c | 0 .../h5_test/tst_h_ints.c | 0 .../h5_test/tst_h_mem.c | 2 +- .../h5_test/tst_h_opaques.c | 0 .../h5_test/tst_h_par.c | 8 +- .../h5_test/tst_h_par_compress.c | 64 +- .../h5_test/tst_h_rename.c | 8 +- .../h5_test/tst_h_strings.c | 0 .../h5_test/tst_h_strings1.c | 0 .../h5_test/tst_h_strings2.c | 7 +- .../h5_test/tst_h_vars.c | 12 +- .../h5_test/tst_h_vars2.c | 14 +- .../h5_test/tst_h_vars3.c | 0 .../h5_test/tst_h_vl.c | 3 +- .../h5_test/tst_h_wrt_cmp.c | 0 vendor/netcdf-c-4.9.3/h5_test/tst_h_zstd.c | 185 + .../hdf4_test/CMakeLists.txt | 16 +- .../hdf4_test/Makefile.am | 4 +- .../hdf4_test/Makefile.in | 152 +- .../hdf4_test/ref_chunked.hdf4 | Bin .../hdf4_test/ref_contiguous.hdf4 | Bin .../hdf4_test/run_formatx_hdf4.sh | 0 .../hdf4_test/run_get_hdf4_files.sh | 14 +- .../hdf4_test/tst_chunk_hdf4.c | 0 .../hdf4_test/tst_h4_lendian.c | 0 .../hdf4_test/tst_hdf4_extra.c | 0 .../hdf4_test/tst_interops2.c | 2 +- .../hdf4_test/tst_interops3.c | 0 .../include/CMakeLists.txt | 31 +- vendor/netcdf-c-4.9.3/include/Makefile.am | 68 + .../include/Makefile.in | 121 +- .../include/XGetopt.h | 0 .../include/ceconstraints.h | 0 .../include/err_macros.h | 0 .../include/fbits.h | 0 .../include/hdf4dispatch.h | 0 .../include/hdf5dispatch.h | 0 .../include/hdf5internal.h | 14 +- .../include/isnan.h | 0 vendor/netcdf-c-4.9.3/include/nc.h | 148 + .../include/nc3dispatch.h | 0 .../include/nc3internal.h | 1 - .../include/nc4dispatch.h | 0 .../include/nc4internal.h | 152 +- .../include/nc_logging.h | 6 +- .../include/nc_provenance.h | 0 .../include/nc_tests.h | 0 .../include/ncauth.h | 0 .../include/ncbytes.h | 1 + .../include/ncconfigure.h | 98 +- .../include/nccrc.h | 0 .../include/ncdap.h | 14 +- .../include/ncdimscale.h | 0 .../include/ncdispatch.h | 8 +- .../include/ncexhash.h | 0 .../include/ncexternl.h | 0 .../include/nchashmap.h | 0 vendor/netcdf-c-4.9.3/include/nchttp.h | 62 + .../include/ncindex.h | 0 .../include/ncjson.h | 51 +- .../include/nclist.h | 7 +- .../include/nclog.h | 23 +- .../include/ncmodel.h | 0 .../include/ncoffsets.h | 10 + .../include/ncpathmgr.h | 19 +- vendor/netcdf-c-4.9.3/include/ncplugins.h | 39 + vendor/netcdf-c-4.9.3/include/ncproplist.h | 108 + .../include/ncrc.h | 33 +- vendor/netcdf-c-4.9.3/include/ncs3sdk.h | 83 + .../include/nctestserver.h | 16 +- .../include/nctime.h | 4 +- .../include/ncuri.h | 30 +- .../include/ncutf8.h | 0 .../include/ncxcache.h | 0 .../include/ncxml.h | 0 .../include/netcdf.h | 96 +- vendor/netcdf-c-4.9.3/include/netcdf_aux.h | 252 + .../include/netcdf_dispatch.h | 0 .../include/netcdf_dispatch.h.in | 0 .../include/netcdf_f.h | 0 .../include/netcdf_filter.h | 63 +- .../include/netcdf_filter_build.h | 0 .../include/netcdf_filter_hdf5_build.h | 6 +- .../include/netcdf_json.h | 191 +- .../include/netcdf_mem.h | 0 .../include/netcdf_meta.h | 17 +- .../include/netcdf_meta.h.in | 17 +- .../include/netcdf_par.h | 0 .../netcdf-c-4.9.3/include/netcdf_proplist.h | 459 + .../include/onstack.h | 2 +- .../include/rnd.h | 0 .../install-sh | 14 +- .../lib_flags.am | 10 +- .../libdap2/CMakeLists.txt | 34 + .../libdap2/Makefile.am | 4 +- .../libdap2/Makefile.in | 103 +- .../libdap2/cache.c | 35 +- .../libdap2/cdf.c | 49 +- .../libdap2/constraints.c | 57 +- .../libdap2/constraints.h | 0 .../libdap2/dapattr.c | 3 +- .../libdap2/dapcvt.c | 15 +- .../libdap2/dapdebug.c | 0 .../libdap2/dapdebug.h | 1 + .../libdap2/dapdump.c | 33 +- .../libdap2/dapdump.h | 0 .../libdap2/dapincludes.h | 0 .../libdap2/dapnc.h | 0 .../libdap2/dapodom.c | 24 +- .../libdap2/dapodom.h | 6 +- .../libdap2/daputil.c | 36 +- .../libdap2/daputil.h | 0 .../libdap2/dce.y | 0 .../libdap2/dceconstraints.c | 25 +- .../libdap2/dceconstraints.h | 0 .../libdap2/dcelex.c | 5 +- .../libdap2/dceparse.c | 9 +- .../libdap2/dceparselex.h | 0 .../libdap2/dcetab.c | 1445 +- .../libdap2/dcetab.h | 26 +- .../libdap2/getvara.c | 40 +- .../libdap2/getvara.h | 0 .../libdap2/nccommon.h | 0 .../libdap2/ncd2dispatch.c | 104 +- .../libdap2/ncd2dispatch.h | 0 .../libdap2/ncdaperr.c | 0 vendor/netcdf-c-4.9.3/libdap4/CMakeLists.txt | 64 + .../libdap4/Makefile.am | 4 +- .../libdap4/Makefile.in | 104 +- .../libdap4/d4bytes.h | 0 vendor/netcdf-c-4.9.3/libdap4/d4chunk.c | 178 + .../libdap4/d4chunk.h | 0 .../libdap4/d4curlfunctions.c | 73 +- .../libdap4/d4curlfunctions.h | 0 .../libdap4/d4cvt.c | 0 .../libdap4/d4data.c | 277 +- .../libdap4/d4debug.c | 25 +- .../libdap4/d4debug.h | 5 +- .../libdap4/d4dump.c | 23 +- .../libdap4/d4file.c | 463 +- .../libdap4/d4fix.c | 169 +- .../libdap4/d4http.c | 79 +- .../libdap4/d4http.h | 0 .../libdap4/d4includes.h | 0 .../libdap4/d4meta.c | 251 +- .../libdap4/d4odom.c | 7 +- .../libdap4/d4odom.h | 2 +- .../libdap4/d4parser.c | 146 +- .../libdap4/d4printer.c | 20 +- .../libdap4/d4read.c | 133 +- .../libdap4/d4read.h | 2 +- .../libdap4/d4swap.c | 122 +- .../libdap4/d4util.c | 110 +- .../libdap4/d4util.h | 12 +- vendor/netcdf-c-4.9.3/libdap4/d4varx.c | 321 + .../libdap4/ncd4.h | 71 +- .../libdap4/ncd4dispatch.c | 23 +- .../libdap4/ncd4dispatch.h | 0 .../libdap4/ncd4types.h | 132 +- .../netcdf-c-4.9.3/libdispatch/CMakeLists.txt | 109 + .../libdispatch/Makefile.am | 29 +- .../libdispatch/Makefile.in | 297 +- .../libdispatch}/XGetopt.c | 0 .../libdispatch/awsincludes.h | 3 + .../libdispatch/datt.c | 0 .../libdispatch/dattget.c | 0 .../libdispatch/dattinq.c | 0 .../libdispatch/dattput.c | 0 .../libdispatch/dauth.c | 17 +- .../libdispatch/daux.c | 377 +- .../libdispatch/dcompound.c | 0 .../libdispatch/dcopy.c | 119 +- .../libdispatch/dcrc32.c | 5 +- .../libdispatch/dcrc32.h | 0 .../libdispatch/dcrc64.c | 0 .../libdispatch/ddim.c | 0 vendor/netcdf-c-4.9.3/libdispatch/ddispatch.c | 476 + .../libdispatch/denum.c | 0 .../libdispatch/derror.c | 6 +- .../libdispatch/dfile.c | 52 +- .../libdispatch/dfilter.c | 104 +- .../libdispatch/dgroup.c | 0 vendor/netcdf-c-4.9.3/libdispatch/dhttp.c | 869 + .../libdispatch/dinfermodel.c | 466 +- vendor/netcdf-c-4.9.3/libdispatch/dinstance.c | 557 + .../libdispatch/dinstance_intern.c | 610 + .../libdispatch/dinternal.c | 0 vendor/netcdf-c-4.9.3/libdispatch/dmissing.c | 208 + .../libdispatch/dnotnc3.c | 0 .../libdispatch/dnotnc4.c | 2 + .../libdispatch/doffsets.c | 0 .../libdispatch/dopaque.c | 0 .../libdispatch/dparallel.c | 4 +- .../libdispatch/dpathmgr.c | 75 +- vendor/netcdf-c-4.9.3/libdispatch/dplugins.c | 340 + .../libdispatch/drc.c | 554 +- .../libdispatch/dreadonly.c | 0 .../libdispatch/dreg.c | 17 +- vendor/netcdf-c-4.9.3/libdispatch/ds3util.c | 974 + .../libdispatch/dstring.c | 75 - .../libdispatch/dtype.c | 0 .../libdispatch/dutf8.c | 2 +- .../libdispatch/dutil.c | 79 +- .../libdispatch/dv2i.c | 6 +- .../libdispatch/dvar.c | 36 +- .../libdispatch/dvarget.c | 35 +- .../libdispatch/dvarinq.c | 0 .../libdispatch/dvarput.c | 24 +- .../libdispatch/dvlen.c | 84 +- .../libdispatch/nc.c | 2 +- .../libdispatch/ncbytes.c | 8 +- .../netcdf-c-4.9.3/libdispatch/nccurl_hmac.c | 165 + .../netcdf-c-4.9.3/libdispatch/nccurl_hmac.h | 80 + .../netcdf-c-4.9.3/libdispatch/nccurl_setup.h | 51 + .../libdispatch/nccurl_sha256.c | 556 + .../libdispatch/nccurl_sha256.h | 53 + .../libdispatch/ncexhash.c | 28 +- .../netcdf-c-4.9.3/libdispatch/nch5s3comms.c | 2913 + .../netcdf-c-4.9.3/libdispatch/nch5s3comms.h | 561 + .../libdispatch/nchashmap.c | 20 +- .../libdispatch/ncjson.c | 126 +- .../libdispatch/nclist.c | 85 +- .../libdispatch/nclistmgr.c | 6 +- .../libdispatch/nclog.c | 100 +- .../netcdf-c-4.9.3/libdispatch/ncproplist.c | 350 + vendor/netcdf-c-4.9.3/libdispatch/ncrandom.c | 34 + .../libdispatch/ncs3sdk_aws.cpp} | 583 +- .../netcdf-c-4.9.3/libdispatch/ncs3sdk_h5.c | 1063 + .../libdispatch/ncsettings.hdr | 0 .../libdispatch/nctime.c | 54 +- .../libdispatch/ncuri.c | 316 +- vendor/netcdf-c-4.9.3/libdispatch/ncutil.h | 242 + .../libdispatch/ncxcache.c | 3 +- .../libdispatch/utf8proc.c | 295 +- .../libdispatch/utf8proc.h | 152 +- .../libdispatch/utf8proc_data.c | 16960 ++++ .../libhdf4/CMakeLists.txt | 16 +- .../libhdf4/Makefile.am | 0 .../libhdf4/Makefile.in | 81 +- .../libhdf4/hdf4dispatch.c | 0 .../libhdf4/hdf4file.c | 2 +- .../libhdf4/hdf4func.c | 0 .../libhdf4/hdf4var.c | 0 vendor/netcdf-c-4.9.3/libhdf5/CMakeLists.txt | 38 + .../libhdf5/H5FDhttp.c | 34 +- .../libhdf5/H5FDhttp.h | 4 +- .../libhdf5/Makefile.am | 4 +- .../libhdf5/Makefile.in | 107 +- .../libhdf5/hdf5attr.c | 189 +- .../libhdf5/hdf5create.c | 9 +- .../libhdf5/hdf5debug.c | 29 +- .../libhdf5/hdf5debug.h | 1 + .../libhdf5/hdf5dim.c | 3 +- .../libhdf5/hdf5dispatch.c | 8 +- .../libhdf5/hdf5err.h | 0 .../libhdf5/hdf5file.c | 21 +- .../libhdf5/hdf5filter.c | 232 +- .../libhdf5/hdf5grp.c | 0 .../libhdf5/hdf5internal.c | 63 +- .../libhdf5/hdf5open.c | 317 +- vendor/netcdf-c-4.9.3/libhdf5/hdf5plugins.c | 245 + .../libhdf5/hdf5set_format_compatibility.c | 0 .../libhdf5/hdf5type.c | 31 +- .../libhdf5/hdf5var.c | 130 +- .../libhdf5/nc4hdf.c | 135 +- .../libhdf5/nc4info.c | 0 .../libhdf5/nc4mem.c | 0 .../libhdf5/nc4memcb.c | 6 +- vendor/netcdf-c-4.9.3/liblib/CMakeLists.txt | 220 + .../liblib/Makefile.am | 25 +- .../liblib/Makefile.in | 138 +- .../liblib/nc_initialize.c | 32 +- .../netcdf-c-4.9.3/libncpoco/CMakeLists.txt | 15 + .../libncpoco/COPYRIGHT | 0 .../libncpoco/Makefile.am | 0 .../libncpoco/Makefile.in | 81 +- .../libncpoco/README.md | 0 .../libncpoco/cp_unix.c | 2 +- .../libncpoco/cp_win32.c | 7 +- .../libncpoco/ncpoco.c | 11 + .../libncpoco/ncpoco.h | 3 + vendor/netcdf-c-4.9.3/libncxml/CMakeLists.txt | 26 + .../libncxml/Makefile.am | 23 +- .../libncxml/Makefile.in | 114 +- .../libncxml/license.txt | 0 .../libncxml/ncxml_tinyxml2.cpp | 0 .../libncxml/ncxml_xml2.c | 4 +- .../libncxml/tinyxml2.cpp | 41 +- .../libncxml/tinyxml2.h | 10 +- .../libnczarr/CMakeLists.txt | 41 +- .../libnczarr/Makefile.am | 13 +- .../libnczarr/Makefile.in | 125 +- .../libnczarr/zarr.c | 168 +- .../libnczarr/zarr.h | 19 +- .../libnczarr/zattr.c | 46 +- .../libnczarr/zcache.h | 4 +- .../libnczarr/zchunking.c | 33 +- .../libnczarr/zchunking.h | 24 +- .../libnczarr/zclose.c | 95 +- .../libnczarr/zcreate.c | 5 +- .../libnczarr/zcvt.c | 8 +- .../libnczarr/zdebug.c | 2 +- .../libnczarr/zdebug.h | 6 +- .../libnczarr/zdim.c | 23 +- .../libnczarr/zdispatch.c | 10 +- .../libnczarr/zdispatch.h | 0 .../libnczarr/zfile.c | 5 +- .../libnczarr/zfilter.c | 808 +- .../libnczarr/zfilter.h | 6 - .../libnczarr/zgrp.c | 0 .../libnczarr/zincludes.h | 2 +- .../libnczarr/zinternal.c | 18 +- .../libnczarr/zinternal.h | 88 +- .../libnczarr/zmap.c | 113 +- .../libnczarr/zmap.h | 30 +- .../libnczarr/zmap_file.c | 203 +- .../libnczarr/zmap_s3sdk.c | 104 +- .../libnczarr/zmap_zip.c | 93 +- .../libnczarr/zodom.c | 37 +- .../libnczarr/zodom.h | 5 +- .../libnczarr/zopen.c | 2 +- vendor/netcdf-c-4.9.3/libnczarr/zplugins.c | 772 + vendor/netcdf-c-4.9.3/libnczarr/zplugins.h | 45 + .../libnczarr/zprov.c | 0 .../libnczarr/zprovenance.h | 0 .../libnczarr/zsync.c | 1749 +- .../libnczarr/ztype.c | 9 +- .../libnczarr/zutil.c | 134 +- .../libnczarr/zvar.c | 193 +- .../libnczarr/zwalk.c | 220 +- .../libnczarr/zxcache.c | 160 +- .../libnetcdf.settings.in | 11 +- vendor/netcdf-c-4.9.3/libsrc/CMakeLists.txt | 103 + .../libsrc/Makefile.am | 13 +- .../libsrc/Makefile.in | 101 +- .../libsrc/attr.c | 923 +- .../libsrc/attr.m4 | 17 +- .../libsrc/dim.c | 19 +- .../libsrc/ffio.c | 2 +- .../libsrc/httpio.c | 37 +- .../libsrc/lookup3.c | 0 .../libsrc/memio.c | 18 +- .../libsrc/mmapio.c | 36 +- .../libsrc/nc3dispatch.c | 0 .../libsrc/nc3internal.c | 57 +- .../libsrc/ncio.c | 16 +- .../libsrc/ncio.h | 0 .../libsrc/ncstdio.c | 0 .../libsrc/ncx.c | 37018 +++++---- .../libsrc/ncx.h | 0 .../libsrc/ncx.m4 | 270 +- .../libsrc/netcdf.3 | 0 .../libsrc/posixio.c | 45 +- .../libsrc/pstdint.h | 20 +- .../libsrc/putget.c | 18 +- .../libsrc/putget.m4 | 18 +- .../libsrc/s3io.c | 2 +- .../libsrc/v1hpg.c | 96 +- .../libsrc/var.c | 42 +- .../libsrc4/CMakeLists.txt | 35 +- .../libsrc4/Makefile.am | 0 .../libsrc4/Makefile.in | 81 +- .../libsrc4/nc4attr.c | 56 +- .../libsrc4/nc4cache.c | 4 +- .../libsrc4/nc4dim.c | 6 +- .../libsrc4/nc4dispatch.c | 22 +- .../libsrc4/nc4grp.c | 17 +- .../libsrc4/nc4internal.c | 326 +- .../libsrc4/nc4type.c | 217 +- .../libsrc4/nc4var.c | 211 +- .../libsrc4/ncfunc.c | 0 .../libsrc4/ncindex.c | 12 +- .../libsrcp/CMakeLists.txt | 11 +- .../libsrcp/Makefile.am | 0 .../libsrcp/Makefile.in | 81 +- .../libsrcp/ncpdispatch.c | 0 .../ltmain.sh | 736 +- .../m4/libtool.m4 | 462 +- .../m4/ltoptions.m4 | 106 +- .../m4/ltsugar.m4 | 2 +- .../m4/ltversion.m4 | 12 +- .../m4/lt~obsolete.m4 | 2 +- .../missing | 75 +- .../nc-config.cmake.in | 140 +- vendor/netcdf-c-4.9.3/nc-config.in | 302 + .../nc_perf/CMakeLists.txt | 4 +- .../nc_perf/Makefile.am | 4 +- .../nc_perf/Makefile.in | 164 +- .../nc_perf/bigmeta.c | 0 .../nc_perf/bm_file.c | 47 +- .../nc_perf/bm_many_atts.c | 4 +- .../nc_perf/bm_many_objs.c | 6 +- .../nc_perf/bm_netcdf4_recs.c | 0 .../nc_perf/gfs_sample.cdl | 0 .../nc_perf/openbigmeta.c | 0 .../nc_perf/perftest.sh | 0 .../nc_perf/run_bm_elena.sh | 0 .../nc_perf/run_bm_test1.sh | 0 .../nc_perf/run_bm_test2.sh | 0 .../nc_perf/run_gfs_test.sh.in | 0 .../nc_perf/run_knmi_bm.sh | 4 +- .../nc_perf/run_par_bm_test.sh.in | 0 .../nc_perf/run_tst_chunks.sh | 0 .../nc_perf/tst_ar4.c | 0 .../nc_perf/tst_ar4_3d.c | 0 .../nc_perf/tst_ar4_4d.c | 3 +- .../nc_perf/tst_attsperf.c | 8 +- .../nc_perf/tst_bm_rando.c | 6 +- .../nc_perf/tst_chunks3.c | 36 +- .../nc_perf/tst_compress.c | 4 +- .../nc_perf/tst_compress_par.c | 4 +- .../nc_perf/tst_create_files.c | 10 +- .../nc_perf/tst_files2.c | 16 +- .../nc_perf/tst_files3.c | 3 +- .../nc_perf/tst_h_many_atts.c | 2 +- .../nc_perf/tst_knmi.c | 0 .../nc_perf/tst_mem.c | 0 .../nc_perf/tst_mem1.c | 0 .../nc_perf/tst_utils.c | 3 +- .../nc_perf/tst_wrf_reads.c | 6 +- .../nc_test/CMakeLists.txt | 26 +- .../nc_test/Makefile.am | 26 +- .../nc_test/Makefile.in | 205 +- .../nc_test/bad_cdf5_begin.nc | Bin .../nc_test/error.c | 0 .../nc_test/error.h | 0 .../nc_test/f03tst_open_mem.nc | Bin .../nc_test/large_files.c | 2 +- .../nc_test/nc_enddef.cdl | 0 .../nc_test/nc_test.c | 9 +- .../nc_test/quick_large_files.c | 2 +- .../nc_test/ref_tst_diskless2.cdl | 0 .../nc_test/ref_tst_diskless3_create.cdl | 0 .../nc_test/ref_tst_diskless3_open.cdl | 0 .../nc_test/ref_tst_http_nc3.cdl | 0 .../nc_test/ref_tst_http_nc4a.cdl | 0 .../nc_test/ref_tst_http_nc4b.cdl | 0 .../nc_test/ref_tst_http_nc4c.cdl} | 0 .../nc_test/ref_tst_http_nc4e.cdl} | 0 .../nc_test/ref_tst_http_nc4f.cdl | 0 .../nc_test/run_cdf5.sh | 0 .../nc_test/run_diskless.sh | 0 .../nc_test/run_diskless2.sh | 0 .../nc_test/run_diskless5.sh | 0 .../nc_test/run_inmemory.sh | 0 .../nc_test/run_mmap.sh | 0 .../nc_test/run_pnetcdf_tests.sh.in | 0 .../nc_test/t_nc.c | 15 +- .../nc_test/test_byterange.sh | 51 +- .../nc_test/test_get.c | 0 .../nc_test/test_get.m4 | 0 .../nc_test/test_put.c | 0 .../nc_test/test_put.m4 | 0 .../nc_test/test_read.c | 0 .../nc_test/test_read.m4 | 0 .../nc_test/test_write.c | 2 +- .../nc_test/test_write.m4 | 2 +- .../nc_test/testnc3perf.c | 12 +- .../nc_test/tests.h | 2 +- .../nc_test/tst_addvar.c | 2 +- .../nc_test/tst_atts3.c | 2 +- .../nc_test/tst_big_rvar.c | 2 +- .../nc_test/tst_big_var.c | 2 +- .../nc_test/tst_big_var2.c | 2 +- .../nc_test/tst_big_var6.c | 2 +- .../nc_test/tst_byterange.c | 0 .../nc_test/tst_cdf5_begin.c | 0 .../nc_test/tst_cdf5format.c | 6 +- .../nc_test/tst_def_var_fill.c | 7 +- .../nc_test/tst_default_format.c | 4 +- .../nc_test/tst_default_format_pnetcdf.c | 6 +- .../nc_test/tst_diskless.c | 51 +- .../nc_test/tst_diskless2.c | 0 .../nc_test/tst_diskless3.c | 16 +- .../nc_test/tst_diskless4.c | 31 +- .../nc_test/tst_diskless5.c | 0 .../nc_test/tst_diskless5.cdl | 0 .../nc_test/tst_diskless6.c | 2 +- .../nc_test/tst_err_enddef.c | 0 .../nc_test/tst_formats.c | 17 +- .../nc_test/tst_formatx_pnetcdf.c | 0 .../nc_test/tst_global_fillval.c | 9 +- .../nc_test/tst_inmemory.c | 24 +- .../nc_test/tst_inq_type.c | 4 +- .../nc_test/tst_large.c | 2 +- .../nc_test/tst_large_cdf5.c | 2 +- .../nc_test/tst_max_var_dims.c | 0 .../nc_test/tst_meta.c | 0 .../nc_test/tst_misc.c | 4 +- .../nc_test/tst_names.c | 2 +- .../nc_test/tst_nofill.c | 8 +- .../nc_test/tst_nofill2.c | 4 +- .../nc_test/tst_nofill3.c | 4 +- .../nc_test/tst_norm.c | 0 .../nc_test/tst_open_cdf5.c | 0 .../nc_test/tst_open_mem.c | 2 +- .../nc_test/tst_parallel2.c | 2 +- .../nc_test/tst_pnetcdf.c | 8 +- .../nc_test/tst_small.c | 24 +- .../nc_test/tst_utf8_phrases.c | 19 +- .../nc_test/tst_utf8_validate.c | 4 +- .../nc_test/util.c | 34 +- .../nc_test4/CMakeLists.txt | 41 +- .../nc_test4/Makefile.am | 98 +- .../nc_test4/Makefile.in | 498 +- .../nc_test4/build_fixedstring.c | 0 .../nc_test4/bzip2.cdl | 0 .../nc_test4/cdm_sea_soundings.c | 6 +- .../nc_test4/h5testszip.c | 0 .../nc_test4/noop.cdl | 0 .../nc_test4/noop1.cdl | 0 .../nc_test4/ref_any.cdl | 0 .../nc_test4/ref_bloscx.cdl | 0 .../nc_test4/ref_bzip2.c | 0 .../nc_test4/ref_fillonly.cdl | 0 .../nc_test4/ref_filter_order_create.txt | 0 .../nc_test4/ref_filter_order_read.txt | 0 .../nc_test4/ref_filter_repeat.txt | 0 .../nc_test4/ref_filtered.cdl | 0 .../nc_test4/ref_filteredvv.cdl | 0 .../nc_test4/ref_fixedstring.cdl | 16 + .../nc_test4/ref_hdf5_compat1.nc | Bin .../nc_test4/ref_hdf5_compat2.nc | Bin .../nc_test4/ref_hdf5_compat3.nc | Bin .../nc_test4/ref_multi.cdl | 0 .../nc_test4/ref_nccopyF.cdl | 0 .../nc_test4/ref_ncgenF.cdl | 0 .../nc_test4/ref_szip.cdl | 0 .../nc_test4/ref_szip.h5 | Bin .../nc_test4/ref_tmp_tst_warn_out.txt | 4 + .../nc_test4/ref_tst_compounds.nc | Bin .../nc_test4/ref_tst_dims.nc | Bin .../nc_test4/ref_tst_interops4.nc | Bin .../nc_test4/ref_tst_xplatform2_1.nc | Bin .../nc_test4/ref_tst_xplatform2_2.nc | Bin .../nc_test4/ref_unfiltered.cdl | 0 .../nc_test4/ref_unfilteredvv.cdl | 0 .../nc_test4/renamegroup.c | 0 .../nc_test4/run_empty_vlen_test.sh | 0 .../nc_test4/run_grp_rename.sh | 0 .../nc_test4/run_par_test.sh.in | 12 + .../nc_test4/run_par_warn_test.sh.in | 20 + .../netcdf-c-4.9.3/nc_test4/run_zstd_test.sh | 33 + .../nc_test4/t_type.c | 0 .../nc_test4/tdset.h5 | Bin .../nc_test4/test_fillonly.sh | 0 .../nc_test4/test_filter.c | 2 +- .../nc_test4/test_filter_misc.c | 22 +- .../nc_test4/test_filter_order.c | 21 +- .../nc_test4/test_filter_repeat.c | 21 +- .../nc_test4/test_szip.c | 0 .../nc_test4/tst_alignment.c | 0 .../nc_test4/tst_atts.c | 4 +- .../nc_test4/tst_atts1.c | 3 +- .../nc_test4/tst_atts2.c | 2 +- .../nc_test4/tst_atts3.c | 14 +- .../nc_test4/tst_atts_string_rewrite.c | 0 .../nc_test4/tst_bloscfail.sh | 1 - .../nc_test4/tst_broken_files.c | 0 .../nc_test4/tst_bug1442.c | 0 .../nc_test4/tst_bug324.c | 0 .../nc_test4/tst_camrun.c | 2 +- .../nc_test4/tst_charvlenbug.c | 0 .../nc_test4/tst_chunks.c | 18 +- .../nc_test4/tst_chunks2.c | 44 +- .../nc_test4/tst_compounds.c | 25 +- .../nc_test4/tst_compounds2.c | 4 +- .../nc_test4/tst_compounds3.c | 6 +- .../nc_test4/tst_converts.c | 4 +- .../nc_test4/tst_converts2.c | 2 +- .../nc_test4/tst_coords.c | 14 +- .../nc_test4/tst_coords2.c | 0 .../nc_test4/tst_coords3.c | 0 .../nc_test4/tst_dims.c | 16 +- .../nc_test4/tst_dims2.c | 6 +- .../nc_test4/tst_dims3.c | 12 +- .../nc_test4/tst_elatefill.c | 2 +- .../nc_test4/tst_empty_vlen_unlim.c | 0 .../nc_test4/tst_endian_fill.c | 2 +- .../nc_test4/tst_enums.c | 0 .../nc_test4/tst_files.c | 8 +- .../nc_test4/tst_files4.c | 0 .../nc_test4/tst_files5.c | 0 .../nc_test4/tst_files6.c | 0 .../nc_test4/tst_fill_attr_vanish.c | 0 .../nc_test4/tst_fillbug.c | 0 .../nc_test4/tst_fillonly.c | 0 .../nc_test4/tst_fills.c | 0 .../nc_test4/tst_fills2.c | 0 .../nc_test4/tst_filter.sh | 0 .../nc_test4/tst_filter_misc.sh | 114 + .../netcdf-c-4.9.3/nc_test4/tst_filter_vlen.c | 286 + .../nc_test4/tst_filter_vlen.sh | 105 + .../nc_test4/tst_filterinstall.sh | 12 +- .../nc_test4/tst_filterparser.c | 8 +- .../nc_test4/tst_fixedstring.sh | 7 +- .../nc_test4/tst_grps.c | 4 +- .../nc_test4/tst_grps2.c | 0 .../nc_test4/tst_h5_endians.c | 168 + .../nc_test4/tst_h_refs.c | 0 .../nc_test4/tst_h_scalar.c | 6 +- .../nc_test4/tst_h_strbug.c | 3 +- .../nc_test4/tst_h_transient_types.c | 129 + .../nc_test4/tst_hdf5_file_compat.c | 0 .../nc_test4/tst_interops.c | 0 .../nc_test4/tst_interops4.c | 8 +- .../nc_test4/tst_interops5.c | 16 +- .../nc_test4/tst_interops6.c | 0 .../nc_test4/tst_interops_dims.c | 0 .../nc_test4/tst_large.c | 0 .../nc_test4/tst_large2.c | 2 +- .../nc_test4/tst_misc.sh | 0 .../nc_test4/tst_mode.c | 0 .../nc_test4/tst_mpi_parallel.c | 0 .../nc_test4/tst_multifilter.c | 2 +- .../nc_test4/tst_nc4perf.c | 8 +- .../nc_test4/tst_opaques.c | 0 .../nc_test4/tst_parallel.c | 2 +- .../nc_test4/tst_parallel3.c | 2 +- .../nc_test4/tst_parallel4.c | 2 +- .../nc_test4/tst_parallel5.c | 54 + .../nc_test4/tst_parallel6.c | 0 .../nc_test4/tst_parallel_compress.c | 3 +- .../nc_test4/tst_parallel_zlib.c | 4 +- .../nc_test4/tst_put_vars.c | 2 +- .../nc_test4/tst_put_vars_two_unlim_dim.c | 12 +- .../nc_test4/tst_quantize.c | 185 +- .../nc_test4/tst_quantize_par.c | 4 +- .../nc_test4/tst_rehash.c | 0 .../nc_test4/tst_rename.c | 0 .../nc_test4/tst_rename2.c | 12 +- .../nc_test4/tst_rename3.c | 6 +- .../nc_test4/tst_simplerw_coll_r.c | 2 +- .../nc_test4/tst_specific_filters.sh | 15 +- .../nc_test4/tst_strings.c | 8 +- .../nc_test4/tst_strings2.c | 0 .../nc_test4/tst_sync.c | 0 .../nc_test4/tst_szip.sh | 0 .../nc_test4/tst_types.c | 4 +- .../nc_test4/tst_udf.c | 0 .../nc_test4/tst_unknown.sh | 6 + .../nc_test4/tst_unlim_vars.c | 22 +- .../nc_test4/tst_utf8.c | 4 +- .../nc_test4/tst_v2.c | 0 .../nc_test4/tst_varms.c | 6 +- .../nc_test4/tst_vars.c | 28 +- .../nc_test4/tst_vars2.c | 42 +- .../nc_test4/tst_vars3.c | 2 +- .../nc_test4/tst_vars4.c | 0 .../nc_test4/tst_virtual_datasets.c | 1 + .../nc_test4/tst_vl.c | 13 +- .../nc_test4/tst_vlenstr.c | 49 +- vendor/netcdf-c-4.9.3/nc_test4/tst_warn.c | 35 + .../nc_test4/tst_xplatform.c | 0 .../nc_test4/tst_xplatform2.c | 10 +- vendor/netcdf-c-4.9.3/nc_test4/tst_zstd.c | 78 + .../nc_test4/unknown.cdl | 0 .../ncdap_test/CMakeLists.txt | 32 +- .../ncdap_test/Makefile.am | 51 +- .../ncdap_test/Makefile.in | 307 +- .../ncdap_test/expected3/123.nc.dmp | 0 .../ncdap_test/expected3/123bears.nc.dmp | 0 .../expected3/1990-S1700101.HDF.WVC_Lat.dmp | 0 .../ncdap_test/expected3/1998-6-avhrr.dat.dmp | 0 .../ncdap_test/expected3/CMakeLists.txt | 0 .../ncdap_test/expected3/D1.dmp | 0 .../ncdap_test/expected3/Drifters.dmp | 0 .../ncdap_test/expected3/EOSDB.dmp | 0 .../ncdap_test/expected3/Makefile.am | 0 .../ncdap_test/expected3/Makefile.in | 58 +- .../ncdap_test/expected3/NestedSeq.dmp | 0 .../ncdap_test/expected3/NestedSeq2.dmp | 0 .../ncdap_test/expected3/OverideExample.dmp | 0 .../expected3/SimpleDrdsExample.dmp | 0 .../ncdap_test/expected3/b31.dmp | 0 .../ncdap_test/expected3/b31a.dmp | 0 .../ncdap_test/expected3/bears.nc.dmp | 0 .../expected3/ber-2002-10-01.nc.dmp | 0 .../ncdap_test/expected3/ceopL2AIRS2-2.nc.dmp | 0 .../expected3/coads_climatology2.nc.dmp | 0 .../ncdap_test/expected3/data.nc.dmp | 0 .../ncdap_test/expected3/fillmismatch.nc.dmp | 0 .../ncdap_test/expected3/fnoc1.nc.dmp | 0 .../ncdap_test/expected3/in.nc.dmp | 0 .../ncdap_test/expected3/in1.nc.dmp | 0 .../ncdap_test/expected3/in_2.nc.dmp | 0 .../expected3/in_no_three_double_dmn.nc.dmp | 0 .../ncdap_test/expected3/in_v.nc.dmp | 0 .../ncdap_test/expected3/ingrid.dmp | 0 .../ncdap_test/expected3/kwcase.nc.dmp | 0 .../ncdap_test/expected3/nestedDAS.dmp | 0 .../ncdap_test/expected3/pbug0001b.dmp | 0 .../ncdap_test/expected3/saco1.nc.dmp | 0 .../ncdap_test/expected3/synth1.dmp | 0 .../ncdap_test/expected3/synth10.dmp | 0 .../ncdap_test/expected3/synth2.dmp | 0 .../ncdap_test/expected3/synth3.dmp | 0 .../ncdap_test/expected3/synth4.dmp | 0 .../ncdap_test/expected3/synth5.dmp | 0 .../ncdap_test/expected3/synth6.dmp | 0 .../ncdap_test/expected3/synth7.dmp | 0 .../ncdap_test/expected3/synth8.dmp | 0 .../ncdap_test/expected3/synth9.dmp | 0 .../ncdap_test/expected3/test.01.dmp | 0 .../ncdap_test/expected3/test.02.dmp | 0 .../ncdap_test/expected3/test.03.dmp | 0 .../ncdap_test/expected3/test.04.dmp | 0 .../ncdap_test/expected3/test.05.dmp | 0 .../ncdap_test/expected3/test.06a.dmp | 0 .../ncdap_test/expected3/test.07.dmp | 0 .../ncdap_test/expected3/test.07a.dmp | 0 .../ncdap_test/expected3/test.21.dmp | 0 .../ncdap_test/expected3/test.22.dmp | 0 .../ncdap_test/expected3/test.23.dmp | 0 .../ncdap_test/expected3/test.31.dmp | 0 .../ncdap_test/expected3/test.50.dmp | 0 .../ncdap_test/expected3/test.53.dmp | 0 .../ncdap_test/expected3/test.55.dmp | 0 .../ncdap_test/expected3/test.56.dmp | 0 .../ncdap_test/expected3/test.57.dmp | 0 .../ncdap_test/expected3/test.66.dmp | 0 .../ncdap_test/expected3/test.67.dmp | 0 .../ncdap_test/expected3/test.68.dmp | 0 .../ncdap_test/expected3/test.69.dmp | 0 .../ncdap_test/expected3/test.PointFile.dmp | 0 .../ncdap_test/expected3/test.an1.dmp | 0 .../ncdap_test/expected3/test.dfp1.dmp | 0 .../ncdap_test/expected3/test.dfr1.dmp | 0 .../ncdap_test/expected3/test.dfr2.dmp | 0 .../ncdap_test/expected3/test.dfr3.dmp | 0 .../ncdap_test/expected3/test.gr1.dmp | 0 .../ncdap_test/expected3/test.gr2.dmp | 0 .../ncdap_test/expected3/test.gr3.dmp | 0 .../ncdap_test/expected3/test.gr4.dmp | 0 .../ncdap_test/expected3/test.gr5.dmp | 0 .../ncdap_test/expected3/test.nc.dmp | 0 .../ncdap_test/expected3/test.sds1.dmp | 0 .../ncdap_test/expected3/test.sds2.dmp | 0 .../ncdap_test/expected3/test.sds3.dmp | 0 .../ncdap_test/expected3/test.sds4.dmp | 0 .../ncdap_test/expected3/test.sds5.dmp | 0 .../ncdap_test/expected3/test.sds6.dmp | 0 .../ncdap_test/expected3/test.sds7.dmp | 0 .../ncdap_test/expected3/test.vs1.dmp | 0 .../ncdap_test/expected3/test.vs2.dmp | 0 .../ncdap_test/expected3/test.vs3.dmp | 0 .../ncdap_test/expected3/test.vs4.dmp | 0 .../ncdap_test/expected3/test.vs5.dmp | 0 .../ncdap_test/expected3/testData.nc.dmp | 0 .../ncdap_test/expected3/text.nc.dmp | 0 .../ncdap_test/expected3/whoi.dmp | 0 .../ncdap_test/expectedhyrax}/CMakeLists.txt | 0 .../ECMWF_ERA-40_subset.nc.hyrax | 23 + .../ncdap_test/expectedhyrax/Makefile.am | 8 + .../ncdap_test/expectedhyrax/Makefile.in | 629 + ...ami_0000-09-01_64x128_L26_c030918.nc.hyrax | 34 + .../ncdap_test/expectremote3}/CMakeLists.txt | 0 .../ncdap_test/expectremote3/D1.dmp | 0 .../ncdap_test/expectremote3/Drifters.dmp | 0 .../ncdap_test/expectremote3/EOSDB.dmp | 0 .../expectremote3/GLOBEC_cetaceans.1.dmp | 0 .../expectremote3/GLOBEC_cetaceans.2.dmp | 0 .../ncdap_test/expectremote3/Makefile.am | 0 .../ncdap_test/expectremote3/Makefile.in | 58 +- .../ncdap_test/expectremote3/NestedSeq.dmp | 0 .../ncdap_test/expectremote3/NestedSeq2.dmp | 0 .../expectremote3/OverideExample.dmp | 0 .../expectremote3/SimpleDrdsExample.dmp | 0 .../Surface_METAR_20120101_0000.nc.1.dmp | 0 .../ncdap_test/expectremote3/b31.dmp | 0 .../ncdap_test/expectremote3/b31a.dmp | 0 .../ncdap_test/expectremote3/ingrid.dmp | 0 .../ncdap_test/expectremote3/nestedDAS.dmp | 0 .../ncdap_test/expectremote3/test.01.1.dmp | 0 .../ncdap_test/expectremote3/test.01.dmp | 0 .../ncdap_test/expectremote3/test.02.1.dmp | 0 .../ncdap_test/expectremote3/test.02.dmp | 0 .../ncdap_test/expectremote3/test.03.1.dmp | 0 .../ncdap_test/expectremote3/test.03.2.dmp | 0 .../ncdap_test/expectremote3/test.03.dmp | 0 .../ncdap_test/expectremote3/test.04.1.dmp | 0 .../ncdap_test/expectremote3/test.04.dmp | 0 .../ncdap_test/expectremote3/test.05.1.dmp | 0 .../ncdap_test/expectremote3/test.05.dmp | 0 .../ncdap_test/expectremote3/test.06.1.dmp | 0 .../ncdap_test/expectremote3/test.06.dmp | 0 .../ncdap_test/expectremote3/test.06a.dmp | 0 .../ncdap_test/expectremote3/test.07.1.dmp | 0 .../ncdap_test/expectremote3/test.07.3.dmp | 0 .../ncdap_test/expectremote3/test.07.4.dmp | 0 .../ncdap_test/expectremote3/test.07.dmp | 0 .../ncdap_test/expectremote3/test.07a.dmp | 0 .../ncdap_test/expectremote3/test.21.dmp | 0 .../ncdap_test/expectremote3/test.22.dmp | 0 .../ncdap_test/expectremote3/test.23.dmp | 0 .../ncdap_test/expectremote3/test.31.dmp | 0 .../ncdap_test/expectremote3/test.50.dmp | 0 .../ncdap_test/expectremote3/test.53.dmp | 0 .../ncdap_test/expectremote3/test.55.dmp | 0 .../ncdap_test/expectremote3/test.56.dmp | 0 .../ncdap_test/expectremote3/test.57.dmp | 0 .../ncdap_test/expectremote3/test.66.dmp | 0 .../ncdap_test/expectremote3/test.67.dmp | 0 .../ncdap_test/expectremote3/test.68.dmp | 0 .../ncdap_test/expectremote3/test.69.dmp | 0 .../ncdap_test/expectremote3/test.an1.dmp | 0 .../ncdap_test/expectremote3/test.dfp1.dmp | 0 .../ncdap_test/expectremote3/test.gr1.dmp | 0 .../ncdap_test/expectremote3/test.gr2.dmp | 0 .../ncdap_test/expectremote3/test.gr3.dmp | 0 .../ncdap_test/expectremote3/test.gr4.dmp | 0 .../ncdap_test/expectremote3/test.gr5.dmp | 0 .../ncdap_test/expectremote3/test.nc.dmp | 0 .../ncdap_test/expectremote3/test.sds1.dmp | 0 .../ncdap_test/expectremote3/test.sds2.dmp | 0 .../ncdap_test/expectremote3/test.sds3.dmp | 0 .../ncdap_test/expectremote3/test.sds4.dmp | 0 .../ncdap_test/expectremote3/test.sds5.dmp | 0 .../ncdap_test/expectremote3/test.vs1.dmp | 0 .../ncdap_test/expectremote3/test.vs2.dmp | 0 .../ncdap_test/expectremote3/test.vs3.dmp | 0 .../ncdap_test/expectremote3/test.vs4.dmp | 0 .../ncdap_test/expectremote3/test.vs5.dmp | 0 .../ncdap_test/expectremote3/whoi.dmp | 0 .../ncdap_test/findtestserver.c | 4 +- .../ncdap_test/findtestserver.c.in | 4 +- .../ncdap_test/manyurls.h | 0 .../ncdap_test/pingurl.c | 8 +- .../ncdap_test/t_dap.c | 0 .../ncdap_test/t_dap3a.c | 2 +- .../ncdap_test/t_misc.c | 0 .../ncdap_test/t_ncf330.c | 0 .../ncdap_test/t_srcdir.h | 0 .../ncdap_test/test_cvt.c | 2 +- .../ncdap_test/test_manyurls.c | 6 + .../ncdap_test/test_nstride_cached.c | 2 +- .../ncdap_test/test_partvar.c | 0 .../ncdap_test/test_vara.c | 8 +- .../ncdap_test/test_varm3.c | 42 +- .../ncdap_test/testauth.sh | 16 +- .../ncdap_test/testdata3/123.nc.das | 0 .../ncdap_test/testdata3/123.nc.dds | 0 .../ncdap_test/testdata3/123.nc.dods | Bin .../ncdap_test/testdata3/123bears.nc.das | 0 .../ncdap_test/testdata3/123bears.nc.dds | 0 .../ncdap_test/testdata3/123bears.nc.dods | Bin .../testdata3/1990-S1700101.HDF.WVC_Lat.das | 0 .../testdata3/1990-S1700101.HDF.WVC_Lat.dds | 0 .../testdata3/1990-S1700101.HDF.WVC_Lat.dods | Bin .../ncdap_test/testdata3/1998-6-avhrr.dat.das | 0 .../ncdap_test/testdata3/1998-6-avhrr.dat.dds | 0 .../testdata3/1998-6-avhrr.dat.dods | Bin .../ncdap_test/testdata3}/CMakeLists.txt | 3 +- .../ncdap_test/testdata3/D1.das | 0 .../ncdap_test/testdata3/D1.dds | 0 .../ncdap_test/testdata3/D1.dods | Bin .../ncdap_test/testdata3/Drifters.das | 0 .../ncdap_test/testdata3/Drifters.dds | 0 .../ncdap_test/testdata3/Drifters.dods | Bin .../ncdap_test/testdata3/EOSDB.das | 0 .../ncdap_test/testdata3/EOSDB.dds | 0 .../ncdap_test/testdata3/EOSDB.dods | Bin .../ncdap_test/testdata3/Makefile.am | 0 .../ncdap_test/testdata3/Makefile.in | 58 +- .../ncdap_test/testdata3/NestedSeq.das | 0 .../ncdap_test/testdata3/NestedSeq.dds | 0 .../ncdap_test/testdata3/NestedSeq.dods | Bin .../ncdap_test/testdata3/NestedSeq2.das | 0 .../ncdap_test/testdata3/NestedSeq2.dds | 0 .../ncdap_test/testdata3/NestedSeq2.dods | Bin .../ncdap_test/testdata3/OverideExample.das | 0 .../ncdap_test/testdata3/OverideExample.dds | 0 .../ncdap_test/testdata3/OverideExample.dods | Bin .../testdata3/SimpleDrdsExample.das | 0 .../testdata3/SimpleDrdsExample.dds | 0 .../testdata3/SimpleDrdsExample.dods | Bin .../ncdap_test/testdata3/b31.das | 0 .../ncdap_test/testdata3/b31.dds | 0 .../ncdap_test/testdata3/b31.dods | Bin .../ncdap_test/testdata3/b31a.das | 0 .../ncdap_test/testdata3/b31a.dds | 0 .../ncdap_test/testdata3/b31a.dods | Bin .../ncdap_test/testdata3/bears.nc.das | 0 .../ncdap_test/testdata3/bears.nc.dds | 0 .../ncdap_test/testdata3/bears.nc.dods | Bin .../testdata3/ber-2002-10-01.nc.das | 0 .../testdata3/ber-2002-10-01.nc.dds | 0 .../testdata3/ber-2002-10-01.nc.dods | Bin .../ncdap_test/testdata3/ceopL2AIRS2-2.nc.das | 0 .../ncdap_test/testdata3/ceopL2AIRS2-2.nc.dds | 0 .../testdata3/ceopL2AIRS2-2.nc.dods | Bin .../ncdap_test/testdata3/ceopL2AIRS2.nc.das | 0 .../ncdap_test/testdata3/ceopL2AIRS2.nc.dds | 0 .../ncdap_test/testdata3/ceopL2AIRS2.nc.dods | Bin .../ncdap_test/testdata3/data.nc.das | 0 .../ncdap_test/testdata3/data.nc.dds | 0 .../ncdap_test/testdata3/data.nc.dods | Bin .../ncdap_test/testdata3/fillmismatch.nc.das | 0 .../ncdap_test/testdata3/fillmismatch.nc.dds | 0 .../ncdap_test/testdata3/fillmismatch.nc.dods | Bin .../ncdap_test/testdata3/fnoc1.nc.das | 0 .../ncdap_test/testdata3/fnoc1.nc.dds | 0 .../ncdap_test/testdata3/fnoc1.nc.dods | Bin .../ncdap_test/testdata3/in.nc.das | 0 .../ncdap_test/testdata3/in.nc.dds | 0 .../ncdap_test/testdata3/in.nc.dods | 0 .../ncdap_test/testdata3/in1.nc.das | 0 .../ncdap_test/testdata3/in1.nc.dds | 0 .../ncdap_test/testdata3/in1.nc.dods | 0 .../ncdap_test/testdata3/in_2.nc.das | 0 .../ncdap_test/testdata3/in_2.nc.dds | 0 .../ncdap_test/testdata3/in_2.nc.dods | 0 .../testdata3/in_no_three_double_dmn.nc.das | 0 .../testdata3/in_no_three_double_dmn.nc.dds | 0 .../testdata3/in_no_three_double_dmn.nc.dods | 0 .../ncdap_test/testdata3/in_v.nc.das | 0 .../ncdap_test/testdata3/in_v.nc.dds | 0 .../ncdap_test/testdata3/in_v.nc.dods | Bin .../ncdap_test/testdata3/ingrid.das | 0 .../ncdap_test/testdata3/ingrid.dds | 0 .../ncdap_test/testdata3/ingrid.dods | Bin .../ncdap_test/testdata3/kwcase.nc.das | 0 .../ncdap_test/testdata3/kwcase.nc.dds | 0 .../ncdap_test/testdata3/kwcase.nc.dods | Bin .../ncdap_test/testdata3/nestedDAS.das | 0 .../ncdap_test/testdata3/nestedDAS.dds | 0 .../ncdap_test/testdata3/nestedDAS.dods | Bin .../ncdap_test/testdata3/pbug0001b.das | 0 .../ncdap_test/testdata3/pbug0001b.dds | 0 .../ncdap_test/testdata3/pbug0001b.dods | Bin .../ncdap_test/testdata3/saco1.nc.das | 0 .../ncdap_test/testdata3/saco1.nc.dds | 0 .../ncdap_test/testdata3/saco1.nc.dods | Bin .../ncdap_test/testdata3/synth1.das | 0 .../ncdap_test/testdata3/synth1.dds | 0 .../ncdap_test/testdata3/synth1.dods | Bin .../ncdap_test/testdata3/synth10.das | 0 .../ncdap_test/testdata3/synth10.dds | 0 .../ncdap_test/testdata3/synth10.dods | Bin .../ncdap_test/testdata3/synth2.das | 0 .../ncdap_test/testdata3/synth2.dds | 0 .../ncdap_test/testdata3/synth2.dods | Bin .../ncdap_test/testdata3/synth3.das | 0 .../ncdap_test/testdata3/synth3.dds | 0 .../ncdap_test/testdata3/synth3.dods | Bin .../ncdap_test/testdata3/synth4.das | 0 .../ncdap_test/testdata3/synth4.dds | 0 .../ncdap_test/testdata3/synth4.dods | Bin .../ncdap_test/testdata3/synth5.das | 0 .../ncdap_test/testdata3/synth5.dds | 0 .../ncdap_test/testdata3/synth5.dods | Bin .../ncdap_test/testdata3/synth6.das | 0 .../ncdap_test/testdata3/synth6.dds | 0 .../ncdap_test/testdata3/synth6.dods | Bin .../ncdap_test/testdata3/synth7.das | 0 .../ncdap_test/testdata3/synth7.dds | 0 .../ncdap_test/testdata3/synth7.dods | Bin .../ncdap_test/testdata3/test.01.das | 0 .../ncdap_test/testdata3/test.01.dds | 0 .../ncdap_test/testdata3/test.01.dods | Bin .../ncdap_test/testdata3/test.02.das | 0 .../ncdap_test/testdata3/test.02.dds | 0 .../ncdap_test/testdata3/test.02.dods | Bin .../ncdap_test/testdata3/test.03.das | 0 .../ncdap_test/testdata3/test.03.dds | 0 .../ncdap_test/testdata3/test.03.dods | Bin .../ncdap_test/testdata3/test.04.das | 0 .../ncdap_test/testdata3/test.04.dds | 0 .../ncdap_test/testdata3/test.04.dods | Bin .../ncdap_test/testdata3/test.05.das | 0 .../ncdap_test/testdata3/test.05.dds | 0 .../ncdap_test/testdata3/test.05.dods | Bin .../ncdap_test/testdata3/test.06.das | 0 .../ncdap_test/testdata3/test.06.dds | 0 .../ncdap_test/testdata3/test.06.dods | Bin .../ncdap_test/testdata3/test.06a.das | 0 .../ncdap_test/testdata3/test.06a.dds | 0 .../ncdap_test/testdata3/test.06a.dods | Bin .../ncdap_test/testdata3/test.07.das | 0 .../ncdap_test/testdata3/test.07.dds | 0 .../ncdap_test/testdata3/test.07.dods | Bin .../ncdap_test/testdata3/test.07a.das | 0 .../ncdap_test/testdata3/test.07a.dds | 0 .../ncdap_test/testdata3/test.07a.dods | Bin .../ncdap_test/testdata3/test.21.das | 0 .../ncdap_test/testdata3/test.21.dds | 0 .../ncdap_test/testdata3/test.21.dods | Bin .../ncdap_test/testdata3/test.22.das | 0 .../ncdap_test/testdata3/test.22.dds | 0 .../ncdap_test/testdata3/test.22.dods | Bin .../ncdap_test/testdata3/test.23.das | 0 .../ncdap_test/testdata3/test.23.dds | 0 .../ncdap_test/testdata3/test.23.dods | Bin .../ncdap_test/testdata3/test.31.das | 0 .../ncdap_test/testdata3/test.31.dds | 0 .../ncdap_test/testdata3/test.31.dods | Bin .../ncdap_test/testdata3/test.32.das | 0 .../ncdap_test/testdata3/test.32.dds | 0 .../ncdap_test/testdata3/test.32.dods | Bin .../ncdap_test/testdata3/test.50.das | 0 .../ncdap_test/testdata3/test.50.dds | 0 .../ncdap_test/testdata3/test.50.dods | Bin .../ncdap_test/testdata3/test.53.das | 0 .../ncdap_test/testdata3/test.53.dds | 0 .../ncdap_test/testdata3/test.53.dods | Bin .../ncdap_test/testdata3/test.55.das | 0 .../ncdap_test/testdata3/test.55.dds | 0 .../ncdap_test/testdata3/test.55.dods | Bin .../ncdap_test/testdata3/test.56.das | 0 .../ncdap_test/testdata3/test.56.dds | 0 .../ncdap_test/testdata3/test.56.dods | Bin .../ncdap_test/testdata3/test.57.das | 0 .../ncdap_test/testdata3/test.57.dds | 0 .../ncdap_test/testdata3/test.57.dods | Bin .../ncdap_test/testdata3/test.66.das | 0 .../ncdap_test/testdata3/test.66.dds | 0 .../ncdap_test/testdata3/test.66.dods | Bin .../ncdap_test/testdata3/test.67.das | 0 .../ncdap_test/testdata3/test.67.dds | 0 .../ncdap_test/testdata3/test.67.dods | Bin .../ncdap_test/testdata3/test.68.das | 0 .../ncdap_test/testdata3/test.68.dds | 0 .../ncdap_test/testdata3/test.68.dods | 0 .../ncdap_test/testdata3/test.69.das | 0 .../ncdap_test/testdata3/test.69.dds | 0 .../ncdap_test/testdata3/test.69.dods | Bin .../ncdap_test/testdata3/test.PointFile.das | 0 .../ncdap_test/testdata3/test.PointFile.dds | 0 .../ncdap_test/testdata3/test.PointFile.dods | Bin .../ncdap_test/testdata3/test.SwathFile.das | 0 .../ncdap_test/testdata3/test.SwathFile.dds | 0 .../ncdap_test/testdata3/test.SwathFile.dods | Bin .../ncdap_test/testdata3/test.an1.das | 0 .../ncdap_test/testdata3/test.an1.dds | 0 .../ncdap_test/testdata3/test.an1.dods | 0 .../ncdap_test/testdata3/test.dfp1.das | 0 .../ncdap_test/testdata3/test.dfp1.dds | 0 .../ncdap_test/testdata3/test.dfp1.dods | 0 .../ncdap_test/testdata3/test.dfr1.das | 0 .../ncdap_test/testdata3/test.dfr1.dds | 0 .../ncdap_test/testdata3/test.dfr1.dods | Bin .../ncdap_test/testdata3/test.dfr2.das | 0 .../ncdap_test/testdata3/test.dfr2.dds | 0 .../ncdap_test/testdata3/test.dfr2.dods | Bin .../ncdap_test/testdata3/test.dfr3.das | 0 .../ncdap_test/testdata3/test.dfr3.dds | 0 .../ncdap_test/testdata3/test.dfr3.dods | Bin .../ncdap_test/testdata3/test.gr1.das | 0 .../ncdap_test/testdata3/test.gr1.dds | 0 .../ncdap_test/testdata3/test.gr1.dods | Bin .../ncdap_test/testdata3/test.gr2.das | 0 .../ncdap_test/testdata3/test.gr2.dds | 0 .../ncdap_test/testdata3/test.gr2.dods | Bin .../ncdap_test/testdata3/test.gr3.das | 0 .../ncdap_test/testdata3/test.gr3.dds | 0 .../ncdap_test/testdata3/test.gr3.dods | Bin .../ncdap_test/testdata3/test.gr4.das | 0 .../ncdap_test/testdata3/test.gr4.dds | 0 .../ncdap_test/testdata3/test.gr4.dods | Bin .../ncdap_test/testdata3/test.gr5.das | 0 .../ncdap_test/testdata3/test.gr5.dds | 0 .../ncdap_test/testdata3/test.gr5.dods | Bin .../ncdap_test/testdata3/test.nc.das | 0 .../ncdap_test/testdata3/test.nc.dds | 0 .../ncdap_test/testdata3/test.nc.dods | Bin .../ncdap_test/testdata3/test.sds1.das | 0 .../ncdap_test/testdata3/test.sds1.dds | 0 .../ncdap_test/testdata3/test.sds1.dods | Bin .../ncdap_test/testdata3/test.sds2.das | 0 .../ncdap_test/testdata3/test.sds2.dds | 0 .../ncdap_test/testdata3/test.sds2.dods | Bin .../ncdap_test/testdata3/test.sds3.das | 0 .../ncdap_test/testdata3/test.sds3.dds | 0 .../ncdap_test/testdata3/test.sds3.dods | Bin .../ncdap_test/testdata3/test.sds4.das | 0 .../ncdap_test/testdata3/test.sds4.dds | 0 .../ncdap_test/testdata3/test.sds4.dods | Bin .../ncdap_test/testdata3/test.sds5.das | 0 .../ncdap_test/testdata3/test.sds5.dds | 0 .../ncdap_test/testdata3/test.sds5.dods | Bin .../ncdap_test/testdata3/test.sds6.das | 0 .../ncdap_test/testdata3/test.sds6.dds | 0 .../ncdap_test/testdata3/test.sds6.dods | Bin .../ncdap_test/testdata3/test.sds7.das | 0 .../ncdap_test/testdata3/test.sds7.dds | 0 .../ncdap_test/testdata3/test.sds7.dods | Bin .../ncdap_test/testdata3/test.vs1.das | 0 .../ncdap_test/testdata3/test.vs1.dds | 0 .../ncdap_test/testdata3/test.vs1.dods | Bin .../ncdap_test/testdata3/test.vs2.das | 0 .../ncdap_test/testdata3/test.vs2.dds | 0 .../ncdap_test/testdata3/test.vs2.dods | Bin .../ncdap_test/testdata3/test.vs3.das | 0 .../ncdap_test/testdata3/test.vs3.dds | 0 .../ncdap_test/testdata3/test.vs3.dods | Bin .../ncdap_test/testdata3/test.vs4.das | 0 .../ncdap_test/testdata3/test.vs4.dds | 0 .../ncdap_test/testdata3/test.vs4.dods | Bin .../ncdap_test/testdata3/test.vs5.das | 0 .../ncdap_test/testdata3/test.vs5.dds | 0 .../ncdap_test/testdata3/test.vs5.dods | Bin .../ncdap_test/testdata3/testfile.nc.das | 0 .../ncdap_test/testdata3/testfile.nc.dds | 0 .../ncdap_test/testdata3/testfile.nc.dods | Bin .../ncdap_test/testdata3/text.nc.das | 0 .../ncdap_test/testdata3/text.nc.dds | 0 .../ncdap_test/testdata3/text.nc.dods | Bin .../ncdap_test/testdata3/whoi.das | 0 .../ncdap_test/testdata3/whoi.dds | 0 .../ncdap_test/testdata3/whoi.dods | Bin .../ncdap_test/testurl.sh | 0 .../ncdap_test/tst_ber.sh | 0 .../ncdap_test/tst_encode.sh | 1 - .../ncdap_test/tst_filelists.sh | 0 .../ncdap_test/tst_fillmismatch.sh | 13 +- .../ncdap_test/tst_formatx.sh | 0 vendor/netcdf-c-4.9.3/ncdap_test/tst_hyrax.sh | 67 + .../ncdap_test/tst_longremote3.sh | 0 .../ncdap_test/tst_ncdap3.sh | 2 +- .../ncdap_test/tst_remote3.sh | 0 .../ncdap_test/tst_urls.sh | 10 +- .../ncdap_test/tst_utils.sh | 0 .../ncdap_test/tst_zero_len_var.sh | 0 vendor/netcdf-c-4.9.3/ncdump/CMakeLists.txt | 365 + .../ncdump/L512.bin | 0 .../ncdump/Makefile.am | 15 +- .../ncdump/Makefile.in | 210 +- .../ncdump/bom.c | 0 .../ncdump/cdl.h | 0 .../ncdump/cdl/CMakeLists.txt | 0 .../ncdump/cdl/Makefile.am | 0 .../ncdump/cdl/Makefile.in | 58 +- .../ncdump/cdl/bigf1.cdl | 0 .../ncdump/cdl/bigf2.cdl | 0 .../ncdump/cdl/bigf3.cdl | 0 .../ncdump/cdl/bigr1.cdl | 0 .../ncdump/cdl/bigr2.cdl | 0 .../ncdump/cdl/bigr3.cdl | 0 .../ncdump/cdl/c0.cdl | 0 .../ncdump/cdl/example_good.cdl | 0 .../ncdump/cdl/fills.cdl | 0 .../ncdump/cdl/n3time.cdl | 0 .../ncdump/cdl/nc_enddef.cdl | 0 .../ncdump/cdl/nc_sync.cdl | 0 .../ncdump/cdl/pres_temp_4D.cdl | 0 .../ncdump/cdl/ref_const_test.cdl | 0 .../ncdump/cdl/ref_ctest1_nc4.cdl | 0 .../ncdump/cdl/ref_ctest1_nc4c.cdl | 0 .../ncdump/cdl/ref_dimscope.cdl | 0 .../ncdump/cdl/ref_keyword.cdl | 0 .../ncdump/cdl/ref_nctst.cdl | 0 .../ncdump/cdl/ref_nctst_64bit_offset.cdl | 0 .../ncdump/cdl/ref_nctst_netcdf4.cdl | 0 .../ncdump/cdl/ref_nctst_netcdf4_classic.cdl | 0 .../ncdump/cdl/ref_niltest.cdl | 0 .../ncdump/cdl/ref_solar.cdl | 0 .../ncdump/cdl/ref_tst_chardata.cdl | 0 .../ncdump/cdl/ref_tst_comp.cdl | 0 .../ncdump/cdl/ref_tst_comp2.cdl | 0 .../ncdump/cdl/ref_tst_comp3.cdl | 0 .../ncdump/cdl/ref_tst_econst.cdl | 0 .../ncdump/cdl/ref_tst_econst2.cdl | 0 .../ncdump/cdl/ref_tst_enum_data.cdl | 0 .../ncdump/cdl/ref_tst_group_data.cdl | 0 .../ncdump/cdl/ref_tst_h_scalar.cdl | 0 .../ncdump/cdl/ref_tst_long_charconst.cdl | 0 .../ncdump/cdl/ref_tst_names.cdl | 0 .../ncdump/cdl/ref_tst_nans.cdl | 0 .../ncdump/cdl/ref_tst_nul3.cdl | 0 .../ncdump/cdl/ref_tst_nul4.cdl | 0 .../ncdump/cdl/ref_tst_opaque_data.cdl | 0 .../ncdump/cdl/ref_tst_small.cdl | 0 .../ncdump/cdl/ref_tst_solar_1.cdl | 0 .../ncdump/cdl/ref_tst_solar_2.cdl | 0 .../ncdump/cdl/ref_tst_special_atts.cdl | 0 .../ncdump/cdl/ref_tst_special_atts3.cdl | 0 .../ncdump/cdl/ref_tst_string_data.cdl | 0 .../ncdump/cdl/ref_tst_unicode.cdl | 0 .../ncdump/cdl/ref_tst_unlim2.cdl | 0 .../ncdump/cdl/ref_tst_utf8.cdl | 0 .../ncdump/cdl/ref_tst_vlen_data.cdl | 0 .../ncdump/cdl/ref_tst_vlen_data2.cdl | 0 .../ncdump/cdl/ref_typescope.cdl | 0 .../ncdump/cdl/sfc_pres_temp.cdl | 0 .../ncdump/cdl/simple_xy.cdl | 0 .../ncdump/cdl/small.cdl | 0 .../ncdump/cdl/small2.cdl | 0 .../ncdump/cdl/test0.cdl | 0 .../ncdump/cdl/tst_chararray.cdl | 0 .../ncdump/cdl/tst_ncml.cdl | 0 .../ncdump/cdl/unlimtest1.cdl | 0 .../ncdump/cdl/unlimtest2.cdl | 0 .../ncdump/chunkspec.c | 22 +- .../ncdump/chunkspec.h | 5 +- .../ncdump/dimmap.c | 0 .../ncdump/dimmap.h | 0 .../ncdump/dumplib.c | 80 +- .../ncdump/dumplib.h | 2 +- vendor/netcdf-c-4.9.3/ncdump/echon.c | 106 + .../ncdump/expected/CMakeLists.txt | 0 .../ncdump/expected/Makefile.am | 0 .../ncdump/expected/Makefile.in | 58 +- .../ncdump/expected/c0.dmp | 0 .../ncdump/expected/example_good.dmp | 0 .../ncdump/expected/fills.dmp | 0 .../ncdump/expected/n3time.dmp | 0 .../ncdump/expected/nc_enddef.dmp | 0 .../ncdump/expected/nc_sync.dmp | 0 .../ncdump/expected/pres_temp_4D.dmp | 0 .../ncdump/expected/ref_const_test.dmp | 0 .../ncdump/expected/ref_ctest1_nc4.dmp | 0 .../ncdump/expected/ref_ctest1_nc4c.dmp | 0 .../ncdump/expected/ref_dimscope.dmp | 0 .../ncdump/expected/ref_keyword.dmp | 0 .../ncdump/expected/ref_nctst.dmp | 0 .../expected/ref_nctst_64bit_offset.dmp | 0 .../ncdump/expected/ref_nctst_netcdf4.dmp | 0 .../expected/ref_nctst_netcdf4_classic.dmp | 0 .../ncdump/expected/ref_niltest.dmp | 0 .../ncdump/expected/ref_solar.dmp | 0 .../ncdump/expected/ref_tst_chardata.dmp | 0 .../ncdump/expected/ref_tst_comp.dmp | 0 .../ncdump/expected/ref_tst_comp2.dmp | 0 .../ncdump/expected/ref_tst_comp3.dmp | 0 .../ncdump/expected/ref_tst_econst.dmp | 0 .../ncdump/expected/ref_tst_econst2.dmp | 0 .../ncdump/expected/ref_tst_enum_data.dmp | 0 .../ncdump/expected/ref_tst_group_data.dmp | 0 .../ncdump/expected/ref_tst_h_scalar.dmp | 0 .../expected/ref_tst_long_charconst.dmp | 0 .../ncdump/expected/ref_tst_names.dmp | 0 .../ncdump/expected/ref_tst_nans.dmp | 0 .../ncdump/expected/ref_tst_nul3.dmp | 0 .../ncdump/expected/ref_tst_nul4.dmp | 0 .../ncdump/expected/ref_tst_opaque_data.dmp | 0 .../ncdump/expected/ref_tst_small.dmp | 0 .../ncdump/expected/ref_tst_solar_1.dmp | 0 .../ncdump/expected/ref_tst_solar_2.dmp | 0 .../ncdump/expected/ref_tst_special_atts.dmp | 0 .../ncdump/expected/ref_tst_special_atts3.dmp | 0 .../ncdump/expected/ref_tst_string_data.dmp | 0 .../ncdump/expected/ref_tst_unicode.dmp | 0 .../ncdump/expected/ref_tst_unlim2.dmp | 0 .../ncdump/expected/ref_tst_utf8.dmp | 0 .../ncdump/expected/ref_tst_vlen_data.dmp | 0 .../ncdump/expected/ref_tst_vlen_data2.dmp | 0 .../ncdump/expected/ref_typescope.dmp | 0 .../ncdump/expected/sfc_pres_temp.dmp | 0 .../ncdump/expected/simple_xy.dmp | 0 .../ncdump/expected/small.dmp | 0 .../ncdump/expected/small2.dmp | 0 .../ncdump/expected/test0.dmp | 0 .../ncdump/expected/tst_chararray.dmp | 0 .../ncdump/expected/tst_ncml.dmp | 0 .../ncdump/expected/unlimtest1.dmp | 0 .../ncdump/expected/unlimtest2.dmp | 0 .../ncdump/indent.c | 0 .../ncdump/indent.h | 0 .../ncdump/inttags.cdl | 0 .../ncdump/inttags4.cdl | 0 .../ncdump/list.c | 3 +- .../ncdump/list.h | 0 .../ncdump/nc4print.c | 0 .../ncdump/nc4printer.c | 31 +- .../ncdump/nccomps.h | 0 .../ncdump/nccopy.1 | 0 .../ncdump/nccopy.c | 108 +- .../ncdump/ncdump.1 | 0 .../ncdump/ncdump.c | 87 +- .../ncdump/ncdump.h | 3 +- .../ncdump/ncfilteravail.c | 2 +- .../ncdump/nchdf5version.c | 2 +- .../ncdump/nciter.c | 11 +- .../ncdump/nciter.h | 0 .../ncdump/ncpathcvt.c | 102 +- .../ncdump/nctime0.c | 9 +- .../ncdump/nctime0.h | 0 .../ncdump/nctrunc.c | 0 .../ncdump/ncvalidator.c | 64 +- .../ncdump/ocprint.c | 33 +- .../ncdump/printfqn.c | 0 .../ncdump/ref1.ncml | 0 .../ncdump/ref_ctest.c | 0 .../ncdump/ref_ctest1_nc4.cdl | 0 .../ncdump/ref_ctest1_nc4c.cdl | 0 .../ncdump/ref_ctest64.c | 0 .../ncdump/ref_ctest_small_3.c | 0 .../ncdump/ref_ctest_small_4.c | 0 .../ncdump/ref_ctest_special_atts_4.c | 0 .../ncdump/ref_inttags.cdl | 0 .../ncdump/ref_inttags4.cdl | 0 .../ncdump/ref_keyword1.cdl | 0 .../ncdump/ref_keyword2.cdl | 0 .../ncdump/ref_keyword3.cdl | 0 .../ncdump/ref_keyword4.cdl | 0 .../ncdump/ref_nc_test_netcdf4.cdl | 0 .../ncdump/ref_nc_test_netcdf4_4_0.nc | Bin .../ncdump/ref_nccopy3_subset.nc | Bin .../ncdump/ref_nccopy_w.cdl | 0 .../ncdump/ref_no_ncproperty.nc | Bin .../ncdump/ref_null_byte_padding_test.nc | Bin vendor/netcdf-c-4.9.3/ncdump/ref_pathcvt.txt | 39 + .../ncdump/ref_provenance_v1.nc | Bin .../ncdump/ref_rcapi.txt | 0 .../ncdump/ref_rcmerge1.txt | 0 .../ncdump/ref_rcmerge2.txt | 0 .../ncdump/ref_rcmerge3.txt | 0 .../ncdump/ref_roman_szip_simple.cdl | 0 .../ncdump/ref_roman_szip_unlim.cdl | 0 .../ncdump/ref_test_360_day_1900.cdl | 0 .../ncdump/ref_test_360_day_1900.nc | Bin .../ncdump/ref_test_365_day_1900.cdl | 0 .../ncdump/ref_test_365_day_1900.nc | Bin .../ncdump/ref_test_366_day_1900.cdl | 0 .../ncdump/ref_test_366_day_1900.nc | Bin .../ncdump/ref_test_corrupt_magic.nc | Bin .../ncdump/ref_times.cdl | 0 .../ncdump/ref_times_nc4.cdl | 0 .../ncdump/ref_tst_charfill.cdl | 0 .../ncdump/ref_tst_comp.cdl | 0 .../netcdf-c-4.9.3/ncdump/ref_tst_comp2.cdl | 19 + .../ncdump/ref_tst_compounds2.cdl | 0 .../ncdump/ref_tst_compounds2.nc | Bin .../ncdump/ref_tst_compounds3.cdl | 0 .../ncdump/ref_tst_compounds3.nc | Bin .../ncdump/ref_tst_compounds4.cdl | 0 .../ncdump/ref_tst_compounds4.nc | Bin .../ncdump/ref_tst_enum_data.cdl | 0 .../ncdump/ref_tst_enum_undef.cdl | 0 .../ncdump/ref_tst_fillbug.cdl | 0 .../ncdump/ref_tst_format_att.cdl | 0 .../ncdump/ref_tst_format_att_64.cdl | 0 .../ncdump/ref_tst_group_data.cdl | 0 .../ncdump/ref_tst_group_data_v23.cdl | 0 .../ncdump/ref_tst_grp_spec.cdl | 0 .../ncdump/ref_tst_grp_spec0.cdl | 0 .../ncdump/ref_tst_irish_rover.nc | Bin .../ncdump/ref_tst_mud4-bc.cdl | 0 .../ncdump/ref_tst_mud4.cdl | 0 .../ncdump/ref_tst_mud4_chars.cdl | 0 .../ncdump/ref_tst_nans.cdl | 0 .../ncdump/ref_tst_nc4_utf8_4.cdl | 0 .../ncdump/ref_tst_ncf213.cdl | 0 .../ncdump/ref_tst_nofilters.cdl | 0 .../ncdump/ref_tst_noncoord.cdl | 0 .../ncdump/ref_tst_opaque_data.cdl | 0 .../ncdump/ref_tst_perdimspecs.cdl | 0 .../ncdump/ref_tst_radix.cdl | 0 .../ncdump/ref_tst_small.cdl | 0 .../ncdump/ref_tst_solar_1.cdl | 0 .../ncdump/ref_tst_solar_2.cdl | 0 .../ncdump/ref_tst_special_atts.cdl | 0 .../ncdump/ref_tst_special_atts3.cdl | 0 .../ncdump/ref_tst_string_data.cdl | 0 .../ncdump/ref_tst_unicode.cdl | 0 .../ncdump/ref_tst_utf8.cdl | 0 .../ncdump/ref_tst_utf8_4.cdl | 0 .../ncdump/ref_tst_vlen_data.cdl | 0 .../ncdump/rewrite-scalar.c | 0 .../ncdump/run_back_comp_tests.sh | 0 .../ncdump/run_ncgen_nc4_tests.sh | 0 .../ncdump/run_ncgen_tests.sh | 4 +- .../ncdump/run_tests.sh | 0 .../ncdump/run_utf8_nc4_tests.sh | 0 .../ncdump/run_utf8_tests.sh | 0 .../ncdump/scope_ancestor_only.cdl | 0 .../ncdump/scope_ancestor_subgroup.cdl | 0 .../ncdump/scope_group_only.cdl | 0 .../ncdump/scope_preorder.cdl | 0 .../ncdump/small.cdl | 0 .../ncdump/small2.cdl | 0 .../ncdump/test0.cdl | 0 .../ncdump/test_keywords.sh | 0 .../ncdump/test_ncdump.sh} | 93 +- .../ncdump/test_radix.sh | 0 .../ncdump/test_rcmerge.sh | 5 +- .../ncdump/test_scope.sh | 0 .../ncdump/test_unicode_directory.sh | 0 .../ncdump/test_unicode_path.sh | 0 vendor/netcdf-c-4.9.3/ncdump/testpathcvt.sh | 67 + .../ncdump/tst_64bit.sh | 2 +- .../ncdump/tst_bom.sh | 11 + .../ncdump/tst_brecs.cdl | 0 .../ncdump/tst_bug321.cdl | 0 .../ncdump/tst_calendars.cdl | 0 .../ncdump/tst_calendars.sh | 0 .../ncdump/tst_calendars_nc4.cdl | 0 .../ncdump/tst_calendars_nc4.sh | 0 .../ncdump/tst_charfill.cdl | 0 .../ncdump/tst_charfill.sh | 0 .../ncdump/tst_chunking.c | 4 +- .../ncdump/tst_comp.c | 3 +- .../ncdump/tst_comp2.c | 4 +- .../ncdump/tst_compress.c | 0 .../ncdump/tst_create_files.c | 7 +- .../ncdump/tst_ctests.sh | 0 .../ncdump/tst_dimsizes.c | 6 +- .../ncdump/tst_dimsizes.sh | 0 .../ncdump/tst_enum_data.c | 0 .../ncdump/tst_enum_undef.c | 0 .../ncdump/tst_fileinfo.c | 0 .../ncdump/tst_fileinfo.sh | 0 .../ncdump/tst_fillbug.c | 2 +- .../ncdump/tst_fillbug.sh | 0 .../ncdump/tst_formatx3.sh | 10 +- .../ncdump/tst_formatx4.sh | 0 .../ncdump/tst_group_data.c | 0 .../ncdump/tst_grp_spec.sh | 0 .../ncdump/tst_h_rdc0.c | 0 .../ncdump/tst_h_scalar.c | 0 .../ncdump/tst_h_scalar.sh | 0 .../ncdump/tst_hdf5_offset.sh | 0 .../ncdump/tst_inmemory_nc3.sh | 0 .../ncdump/tst_inmemory_nc4.sh | 0 .../ncdump/tst_inttags.sh | 0 .../ncdump/tst_inttags4.sh | 0 .../ncdump/tst_iter.sh | 0 .../ncdump/tst_lengths.sh | 2 +- .../ncdump/tst_mslp.cdl | 0 vendor/netcdf-c-4.9.3/ncdump/tst_mud.sh | 81 + .../ncdump/tst_nans.c | 2 +- .../ncdump/tst_nccopy3.sh | 2 +- .../ncdump/tst_nccopy3_subset.sh | 0 .../ncdump/tst_nccopy4.sh | 23 +- vendor/netcdf-c-4.9.3/ncdump/tst_nccopy5.sh | 273 + .../ncdump/tst_nccopy_w3.sh | 0 .../ncdump/tst_nccopy_w4.sh | 0 .../ncdump/tst_ncgen4.sh | 0 .../ncdump/tst_ncgen4_classic.sh | 0 .../ncdump/tst_ncgen4_cycle.sh | 0 .../ncdump/tst_ncgen4_diff.sh | 2 +- .../ncdump/tst_ncgen_shared.sh | 0 .../ncdump/tst_ncml.cdl | 0 vendor/netcdf-c-4.9.3/ncdump/tst_netcdf4.sh | 73 + .../ncdump/tst_netcdf4_4.sh | 0 .../ncdump/tst_null_byte_padding.sh | 0 .../ncdump/tst_opaque_data.c | 4 +- .../ncdump/tst_output.sh | 0 .../ncdump/tst_radix.cdl | 0 .../ncdump/tst_rcapi.c | 0 .../ncdump/tst_rcmerge.c | 0 .../ncdump/tst_special_atts.c | 0 .../ncdump/tst_string_data.c | 0 .../ncdump/tst_unicode.c | 0 .../ncdump/tst_utf8.c | 4 +- .../ncdump/tst_vlen_data.c | 8 +- .../ncdump/tst_vlen_demo.c | 0 .../ncdump/utils.c | 20 +- .../ncdump/utils.h | 4 +- .../ncdump/vardata.c | 54 +- .../ncdump/vardata.h | 0 .../ncgen/CMakeLists.txt | 78 +- .../ncgen/Makefile.am | 0 .../ncgen/Makefile.in | 93 +- .../ncgen/bindata.c | 33 +- .../ncgen/bytebuffer.c | 11 +- .../ncgen/bytebuffer.h | 3 +- .../ncgen/c0.cdl | 0 .../ncgen/c0_4.cdl | 0 .../ncgen/c5.cdl | 0 .../ncgen/cdata.c | 4 +- .../ncgen/compound_datasize_test.cdl | 0 .../ncgen/compound_datasize_test2.cdl | 0 .../ncgen/cvt.c | 36 +- .../ncgen/data.c | 52 +- .../ncgen/data.h | 7 +- .../ncgen/debug.c | 2 - .../ncgen/debug.h | 0 .../ncgen/dump.c | 43 +- .../ncgen/dump.h | 0 .../ncgen/escapes.c | 39 +- .../ncgen/f77data.c | 14 +- .../ncgen/genbin.c | 160 +- .../ncgen/genc.c | 29 +- .../ncgen/genchar.c | 35 +- .../ncgen/generate.c | 26 +- .../ncgen/generate.h | 2 +- .../ncgen/generr.c | 4 +- .../ncgen/generr.h | 0 .../ncgen/genf77.c | 36 +- .../ncgen/genj.c | 15 +- .../ncgen/genlib.c | 0 .../ncgen/genlib.h | 10 +- .../ncgen/getfill.c | 10 +- .../ncgen/includes.h | 0 .../ncgen/internals.html | 0 .../ncgen/jdata.c | 0 .../ncgen/list.c | 0 .../ncgen/list.h | 2 +- .../ncgen/main.c | 4 +- .../ncgen/ncf199.cdl | 0 .../ncgen/ncgen.1 | 0 .../ncgen/ncgen.h | 4 +- .../ncgen/ncgen.l | 62 +- .../ncgen/ncgen.y | 51 +- .../ncgen/ncgenl.c | 72 +- .../ncgen/ncgeny.c | 421 +- .../ncgen/ncgeny.h | 8 +- .../ncgen/ref_camrun.cdl | 0 .../ncgen/semantics.c | 57 +- .../ncgen/tst_gattenum.cdl | 0 .../ncgen/tst_usuffix.cdl | 0 .../ncgen/util.c | 54 +- .../ncgen/util.h | 5 +- .../ncgen3/CMakeLists.txt | 50 +- .../ncgen3/Makefile.am | 0 .../ncgen3/Makefile.in | 148 +- .../ncgen3/c0.cdl | 0 .../ncgen3/escapes.c | 1 - .../ncgen3/generic.h | 0 .../ncgen3/genlib.c | 220 +- .../ncgen3/genlib.h | 0 .../ncgen3/getfill.c | 0 .../ncgen3/init.c | 3 +- .../ncgen3/load.c | 83 +- .../ncgen3/main.c | 0 .../ncgen3/ncgen.h | 3 +- .../ncgen3/ncgen.l | 20 +- .../ncgen3/ncgen.y | 36 +- .../ncgen3/ncgen3.1 | 0 .../ncgen3/ncgenl.c | 863 +- .../ncgen3/ncgeny.c | 1497 +- .../ncgen3/ncgeny.h | 60 +- .../ncgen3/run_nc4_tests.sh | 0 .../ncgen3/run_tests.sh | 0 .../nctest/CMakeLists.txt | 21 +- .../nctest/Makefile.am | 2 +- .../nctest/Makefile.in | 151 +- .../nctest/add.c | 33 +- .../nctest/add.h | 0 .../nctest/atttests.c | 58 +- .../nctest/cdftests.c | 32 +- .../nctest/compare_test_files.sh | 0 .../nctest/dimtests.c | 12 +- .../nctest/driver.c | 6 +- .../nctest/emalloc.c | 7 +- .../nctest/emalloc.h | 0 .../nctest/error.c | 2 - .../nctest/error.h | 0 .../nctest/misctest.c | 0 .../nctest/rec.c | 46 +- .../nctest/ref_nctest_64bit_offset.nc | Bin .../nctest/ref_nctest_classic.nc | Bin .../nctest/slabs.c | 27 +- .../nctest/testcdf.h | 0 .../nctest/tests.h | 0 .../nctest/tst_rename.c | 2 +- .../nctest/val.c | 34 +- .../nctest/val.h | 0 .../nctest/vardef.c | 5 +- .../nctest/varget.c | 5 +- .../nctest/vargetg.c | 5 +- .../nctest/varput.c | 5 +- .../nctest/varputg.c | 5 +- .../nctest/vartests.c | 24 +- .../nctest/vputget.c | 9 +- .../nctest/vputgetg.c | 6 +- .../netcdf-c-4.9.3/nczarr_test/CMakeLists.txt | 246 + vendor/netcdf-c-4.9.3/nczarr_test/Makefile.am | 357 + .../nczarr_test/Makefile.in | 1144 +- .../nczarr_test/bm_chunks3.c | 4 +- .../nczarr_test/bm_timer.h | 0 .../nczarr_test/bm_utils.c | 0 .../nczarr_test/bm_utils.h | 0 .../nczarr_test/ncdumpchunks.c | 117 +- .../nczarr_test/ref_any.cdl | 48 +- .../nczarr_test/ref_avail1.cdl | 0 .../nczarr_test/ref_avail1.dmp | 0 .../nczarr_test/ref_avail1.txt | 0 .../nczarr_test/ref_byte.cdl | 4 +- .../nczarr_test/ref_byte.zarr.zip | Bin .../nczarr_test/ref_byte_fill_value_null.cdl | 4 +- .../ref_byte_fill_value_null.zarr.zip | Bin 0 -> 1945 bytes .../nczarr_test/ref_bzip2.cdl | 0 .../nczarr_test/ref_fillonly.cdl | 0 .../nczarr_test/ref_filtered.cdl | 0 .../nczarr_test/ref_groups.h5 | Bin .../nczarr_test/ref_groups_regular.cdl | 10 +- .../nczarr_test/ref_jsonconvention.cdl | 4 +- .../nczarr_test/ref_jsonconvention.zmap | 5 + .../nczarr_test/ref_misc1.cdl | 0 .../netcdf-c-4.9.3/nczarr_test/ref_misc1.dmp | 97 + .../nczarr_test/ref_misc2.cdl | 0 .../nczarr_test/ref_multi.cdl | 0 .../nczarr_test/ref_nczarr2zarr.cdl | 4 +- .../nczarr_test/ref_ndims.cdl | 0 .../nczarr_test/ref_ndims.dmp | 40 +- .../nczarr_test/ref_newformatpure.cdl | 9 +- .../nczarr_test/ref_noshape.file.zip | Bin 0 -> 1481 bytes .../nczarr_test/ref_notzarr.tar.gz | Bin 0 -> 433 bytes .../nczarr_test/ref_nulls.cdl | 0 .../nczarr_test/ref_nulls_nczarr.baseline | 0 .../nczarr_test/ref_nulls_zarr.baseline | 0 .../nczarr_test/ref_oldformat.cdl | 9 +- .../nczarr_test/ref_oldformat.zip | Bin 0 -> 3342 bytes .../nczarr_test/ref_oldkeys.cdl | 20 + .../nczarr_test/ref_oldkeys.file.zip | Bin 0 -> 1741 bytes .../nczarr_test/ref_oldkeys.zmap | 5 + .../nczarr_test/ref_perdimspecs.cdl | 0 .../nczarr_test/ref_power_901_constants.cdl | 0 .../ref_power_901_constants_orig.zip | Bin .../nczarr_test/ref_purezarr.cdl | 6 +- .../nczarr_test/ref_purezarr_base.cdl | 0 .../nczarr_test/ref_quotes.cdl | 0 .../nczarr_test/ref_quotes_orig.zip | Bin .../nczarr_test/ref_rem.cdl | 0 vendor/netcdf-c-4.9.3/nczarr_test/ref_rem.dmp | 28 + .../nczarr_test/ref_scalar.cdl | 0 .../nczarr_test/ref_scalar_nczarr.cdl | 8 + .../nczarr_test/ref_skip.cdl | 0 .../nczarr_test/ref_skip.txt | 0 .../nczarr_test/ref_skipw.cdl | 0 .../nczarr_test/ref_string.cdl | 0 .../nczarr_test/ref_string_nczarr.baseline | 0 .../nczarr_test/ref_string_zarr.baseline | 0 .../nczarr_test/ref_t_meta_dim1.cdl | 2 +- .../nczarr_test/ref_t_meta_var1.cdl | 4 +- .../nczarr_test/ref_ut_json_build.txt | 0 .../nczarr_test/ref_ut_json_parse.txt | 0 .../nczarr_test/ref_ut_map_create.cdl | 1 + .../nczarr_test/ref_ut_map_readmeta.txt | 0 .../nczarr_test/ref_ut_map_readmeta2.txt | 2 +- .../nczarr_test/ref_ut_map_search.txt | 4 +- .../nczarr_test/ref_ut_map_writedata.cdl | 4 +- .../nczarr_test/ref_ut_map_writemeta.cdl | 2 +- .../nczarr_test/ref_ut_map_writemeta2.cdl | 4 +- .../nczarr_test/ref_ut_mapapi_create.cdl | 1 + .../nczarr_test/ref_ut_mapapi_data.cdl | 2 +- .../nczarr_test/ref_ut_mapapi_meta.cdl | 2 +- .../nczarr_test/ref_ut_mapapi_search.txt | 2 +- .../nczarr_test/ref_ut_proj.txt | 0 .../nczarr_test/ref_ut_testmap_create.cdl | 2 +- .../nczarr_test/ref_whole.cdl | 0 .../nczarr_test/ref_whole.txt | 0 .../nczarr_test/ref_xarray.cdl | 0 .../nczarr_test/ref_zarr_test_data.cdl.gz | Bin 2699 -> 2716 bytes .../nczarr_test/ref_zarr_test_data_2d.cdl.gz | Bin 0 -> 389 bytes .../nczarr_test/ref_zarr_test_data_meta.cdl | 27 + .../nczarr_test/run_chunkcases.sh | 50 +- .../netcdf-c-4.9.3/nczarr_test/run_corrupt.sh | 38 + .../nczarr_test/run_external.sh | 45 + .../nczarr_test/run_fillonlyz.sh | 8 +- .../nczarr_test/run_filter.sh | 34 +- .../netcdf-c-4.9.3/nczarr_test/run_interop.sh | 100 + .../nczarr_test/run_jsonconvention.sh | 38 + .../nczarr_test/run_misc.sh | 18 +- .../nczarr_test/run_nccopyz.sh | 21 +- .../nczarr_test/run_ncgen4.sh | 14 +- .../nczarr_test/run_nczarr_fill.sh | 14 +- .../nczarr_test/run_nczfilter.sh | 16 + .../nczarr_test/run_newformat.sh | 6 +- .../netcdf-c-4.9.3/nczarr_test/run_notzarr.sh | 63 + .../nczarr_test/run_nulls.sh | 10 +- .../netcdf-c-4.9.3/nczarr_test/run_oldkeys.sh | 27 + .../nczarr_test/run_perf_chunks1.sh | 8 +- .../nczarr_test/run_purezarr.sh | 9 +- .../nczarr_test/run_quantize.sh | 8 +- .../nczarr_test/run_scalar.sh | 18 +- .../nczarr_test/run_strings.sh | 13 +- .../nczarr_test/run_unknown.sh | 6 + .../nczarr_test/run_unlim_io.sh | 108 + .../nczarr_test/run_ut_map.sh | 5 +- .../nczarr_test/run_ut_mapapi.sh | 5 + .../nczarr_test/run_ut_misc.sh | 0 .../nczarr_test/s3util.c | 33 +- .../nczarr_test/test_chunkcases.c} | 136 +- .../nczarr_test/test_chunking.c | 138 + .../netcdf-c-4.9.3/nczarr_test/test_endians.c | 338 + .../nczarr_test/test_fillonlyz.c} | 19 +- .../nczarr_test/test_filter_avail.c | 0 .../nczarr_test/test_filter_vlen.c | 287 + .../nczarr_test/test_nczarr.sh | 64 +- .../nczarr_test/test_nczarr_utils.h | 0 .../nczarr_test/test_nczfilter.c} | 0 .../netcdf-c-4.9.3/nczarr_test/test_notzarr.c | 31 + .../nczarr_test/test_put_vars_two_unlim_dim.c | 88 + .../nczarr_test/test_quantize.c | 185 +- .../nczarr_test/test_readcaching.c | 84 + .../nczarr_test/test_unlim_io.c | 125 + .../nczarr_test/test_unlim_vars.c | 288 + .../nczarr_test/test_utils.c} | 275 +- .../nczarr_test/test_utils.h} | 45 +- .../nczarr_test/test_writecaching.c | 99 + .../nczarr_test/test_zchunks.c} | 18 +- .../nczarr_test/test_zchunks2.c} | 65 +- .../nczarr_test/test_zchunks3.c} | 2 +- .../nczarr_test/testfilter.c | 7 +- .../nczarr_test/testfilter_misc.c | 159 +- .../nczarr_test/testfilter_multi.c | 4 +- .../nczarr_test/testfilter_order.c | 10 +- .../nczarr_test/testfilter_repeat.c | 10 +- .../nczarr_test/timer_utils.c | 0 .../nczarr_test/tst_pure_awssdk.cpp | 19 + .../nczarr_test/ut_includes.h | 2 - .../nczarr_test/ut_json.c | 10 +- .../nczarr_test/ut_map.c | 55 +- .../nczarr_test/ut_mapapi.c | 60 +- .../nczarr_test/ut_test.c | 7 +- .../nczarr_test/ut_test.h | 18 +- .../nczarr_test/ut_util.c | 75 +- .../nczarr_test/ut_util.h | 4 +- .../nczarr_test/zhex.c | 13 +- .../nczarr_test/zisjson.c | 7 +- .../nczarr_test/zmapio.c | 71 +- .../nczarr_test/zs3parse.c | 0 .../netCDFConfig.cmake.in | 19 +- .../netcdf.pc.in | 0 .../oc2/CMakeLists.txt | 25 +- .../oc2/Makefile.am | 0 .../oc2/Makefile.in | 72 +- .../oc2/auth.html.in | 0 .../oc2/dap.y | 46 +- .../oc2/daplex.c | 3 +- .../oc2/dapparse.c | 19 +- .../oc2/dapparselex.h | 0 .../oc2/dapy.c | 1887 +- vendor/netcdf-c-4.9.3/oc2/dapy.h | 99 + .../oc2/oc.c | 4 +- .../oc2/oc.css | 0 .../oc2/oc.h | 0 .../oc2/occompile.c | 13 +- .../oc2/occompile.h | 0 .../oc2/occonstraints.h | 0 .../oc2/occurlfunctions.c | 63 +- .../oc2/occurlfunctions.h | 0 .../oc2/ocdata.c | 12 +- .../oc2/ocdata.h | 0 .../oc2/ocdatatypes.h | 0 .../oc2/ocdebug.c | 0 .../oc2/ocdebug.h | 1 + .../oc2/ocdump.c | 45 +- .../oc2/ocdump.h | 0 .../oc2/ochttp.c | 4 +- .../oc2/ochttp.h | 0 .../oc2/ocinternal.c | 46 +- .../oc2/ocinternal.h | 0 .../oc2/ocnode.c | 14 +- .../oc2/ocnode.h | 0 .../oc2/ocread.c | 4 +- .../oc2/ocread.h | 0 .../oc2/ocutil.c | 19 +- .../oc2/ocutil.h | 0 .../oc2/ocx.h | 0 .../oc2/xxdr.c | 9 +- .../oc2/xxdr.h | 0 .../plugins/BZIP2_LICENSE | 0 vendor/netcdf-c-4.9.3/plugins/CMakeLists.txt | 159 + .../plugins/H5Zblosc.c | 6 +- .../plugins/H5Zblosc.h | 5 +- .../plugins/H5Zbzip2.c | 0 .../plugins/H5Zdeflate.c | 2 +- .../plugins/H5Zfletcher32.c | 0 .../plugins/H5Zmisc.c | 206 +- .../plugins/H5Znoop.c | 18 +- .../plugins/H5Znoop1.c | 18 +- .../plugins/H5Zshuffle.c | 0 .../plugins/H5Zszip.c | 0 .../plugins/H5Zszip.h | 0 .../plugins/H5Ztemplate.c | 0 .../plugins/H5Zunknown.c | 0 .../plugins/H5Zutil.c | 0 .../plugins/H5Zzstd.c | 0 .../plugins/H5Zzstd.h | 2 + .../plugins/H5checksum.c | 0 .../plugins/Makefile.am | 89 +- .../plugins/Makefile.in | 406 +- .../plugins/NCZhdf5filters.c | 4 +- .../plugins/NCZmisc.c | 14 +- .../plugins/NCZstdfilters.c | 6 +- .../plugins/blocksort.c | 0 .../plugins/bzlib.c | 0 .../plugins/bzlib.h | 0 .../plugins/bzlib_private.h | 0 .../plugins/compress.c | 0 .../plugins/crctable.c | 0 .../plugins/decompress.c | 0 .../plugins}/findplugin.in | 12 +- .../plugins/h5bzip2.h | 0 vendor/netcdf-c-4.9.3/plugins/h5misc.h | 78 + .../plugins/h5noop.h | 0 .../plugins/huffman.c | 0 .../plugins/randtable.c | 0 vendor/netcdf-c-4.9.3/s3cleanup.in | 108 + vendor/netcdf-c-4.9.3/s3gc.in | 122 + .../test-driver | 15 +- .../test-driver-verbose | 8 +- .../test_common.in | 91 +- .../test_prog.c | 0 .../netcdf-c-4.9.3/unit_test/CMakeLists.txt | 60 + .../unit_test/Makefile.am | 51 +- .../unit_test/Makefile.in | 364 +- vendor/netcdf-c-4.9.3/unit_test/aws_config.c | 89 + .../netcdf-c-4.9.3/unit_test/ncpluginpath.c | 165 + .../unit_test/nctest_netcdf4_classic.nc | Bin .../unit_test/reclaim_tests.cdl | 75 + vendor/netcdf-c-4.9.3/unit_test/ref_get.txt | 3 + vendor/netcdf-c-4.9.3/unit_test/ref_set.txt | 6 + vendor/netcdf-c-4.9.3/unit_test/ref_xget.txt | 1 + vendor/netcdf-c-4.9.3/unit_test/ref_xset.txt | 2 + .../unit_test/run_aws_config.sh | 79 + .../unit_test/run_dfaltpluginpath.sh | 73 + .../unit_test/run_pluginpaths.sh | 131 + .../unit_test/run_reclaim_tests.sh | 16 + vendor/netcdf-c-4.9.3/unit_test/run_s3sdk.sh | 72 + vendor/netcdf-c-4.9.3/unit_test/test_ncuri.c | 165 + .../unit_test/test_pathcvt.c | 16 +- vendor/netcdf-c-4.9.3/unit_test/test_s3sdk.c | 518 + .../unit_test/timer_utils.c | 0 .../unit_test/timer_utils.h | 0 .../unit_test/tst_exhash.c | 2 +- .../unit_test/tst_nc4internal.c | 0 .../unit_test/tst_nclist.c | 0 .../unit_test/tst_pluginpaths.c | 407 + vendor/netcdf-c-4.9.3/unit_test/tst_reclaim.c | 345 + .../unit_test/tst_xcache.c | 8 +- vendor/paraconf-1.0.0/CMakeLists.txt | 136 - vendor/paraconf-1.0.0/README.md | 51 - vendor/paraconf-1.0.0/cmake/SuperBuild.cmake | 367 - .../paraconf-1.0.0/code_generator/README.md | 184 - .../code_generator/examples/PDI_data.yaml | 32 - .../code_generator/examples/PDI_data2.yaml | 28 - .../code_generator/examples/PDI_data3.yaml | 32 - .../code_generator/examples/PDI_data4.yaml | 30 - .../code_generator/examples/PDI_schema.yaml | 25 - .../code_generator/examples/basic_data.yaml | 25 - .../code_generator/examples/basic_schema.yaml | 20 - .../code_generator/examples/full_data.yaml | 69 - .../code_generator/examples/full_schema.yaml | 47 - .../code_generator/examples/generic_data.yaml | 20 - .../examples/generic_schema.yaml | 3 - .../code_generator/examples/include_data.yaml | 32 - .../examples/include_schema.yaml | 22 - .../examples/recursive_data.yaml | 20 - .../examples/recursive_schema.yaml | 15 - vendor/paraconf-1.0.0/code_generator/pcgen | 4 - .../src/c_code_generator/c_data_loader.py | 747 - .../src/c_code_generator/c_free_memory.py | 328 - .../src/c_code_generator/c_functions.py | 136 - .../src/c_code_generator/c_types_generator.py | 246 - .../src/c_code_generator/tools.py | 179 - .../src/c_code_generator/type_handler.py | 257 - .../paraconf-1.0.0/code_generator/src/main.py | 48 - vendor/paraconf-1.0.0/example/AUTHORS | 10 - vendor/paraconf-1.0.0/paraconf/VERSION | 1 - .../paraconf/cmake/GenerateExportHeader.cmake | 443 - .../paraconf/cmake/exportheader.cmake.in | 42 - .../paraconf/cmake/paraconfConfig.cmake | 82 - .../paraconf/include/paraconf.F90 | 26 - .../paraconf/include/paraconf_f90_consts.h | 48 - .../paraconf/include/paraconf_f90_types.h | 36 - .../paraconf/include/paraconff.h | 26 - .../vendor/libyaml-0.2.2/.gitignore | 34 - .../vendor/libyaml-0.2.2/.indent.pro | 1 - .../vendor/libyaml-0.2.2/.makefile | 63 - .../vendor/libyaml-0.2.2/.travis.yml | 27 - .../vendor/libyaml-0.2.2/CMakeLists.txt | 160 - .../vendor/libyaml-0.2.2/LICENSE | 20 - .../vendor/libyaml-0.2.2/Makefile.am | 36 - .../vendor/libyaml-0.2.2/README | 32 - .../vendor/libyaml-0.2.2/announcement.msg | 79 - .../vendor/libyaml-0.2.2/appveyor.yml | 29 - .../vendor/libyaml-0.2.2/bootstrap | 3 - .../vendor/libyaml-0.2.2/cmake/config.h.in | 4 - .../vendor/libyaml-0.2.2/configure.ac | 73 - .../vendor/libyaml-0.2.2/doc/doxygen.cfg | 222 - .../vendor/libyaml-0.2.2/docker/README.mkd | 17 - .../vendor/libyaml-0.2.2/docker/alpine-3.7 | 26 - .../vendor/libyaml-0.2.2/docker/fedora-25 | 26 - .../vendor/libyaml-0.2.2/docker/ubuntu-14.04 | 29 - .../vendor/libyaml-0.2.2/docker/ubuntu-16.04 | 24 - .../libyaml-0.2.2/examples/anchors.yaml | 10 - .../vendor/libyaml-0.2.2/examples/array.yaml | 2 - .../libyaml-0.2.2/examples/global-tag.yaml | 14 - .../vendor/libyaml-0.2.2/examples/json.yaml | 1 - .../libyaml-0.2.2/examples/mapping.yaml | 2 - .../libyaml-0.2.2/examples/numbers.yaml | 1 - .../libyaml-0.2.2/examples/strings.yaml | 7 - .../vendor/libyaml-0.2.2/examples/tags.yaml | 7 - .../libyaml-0.2.2/examples/yaml-version.yaml | 3 - .../vendor/libyaml-0.2.2/include/Makefile.am | 17 - .../vendor/libyaml-0.2.2/include/yaml.h | 1978 - ...zz-testcase-minimized-5607885063061504.yml | 1 - .../vendor/libyaml-0.2.2/src/Makefile.am | 4 - .../vendor/libyaml-0.2.2/src/api.c | 1393 - .../vendor/libyaml-0.2.2/src/dumper.c | 394 - .../vendor/libyaml-0.2.2/src/emitter.c | 2324 - .../vendor/libyaml-0.2.2/src/loader.c | 444 - .../vendor/libyaml-0.2.2/src/parser.c | 1372 - .../vendor/libyaml-0.2.2/src/reader.c | 469 - .../vendor/libyaml-0.2.2/src/scanner.c | 3589 - .../vendor/libyaml-0.2.2/src/writer.c | 141 - .../vendor/libyaml-0.2.2/src/yaml_private.h | 684 - .../vendor/libyaml-0.2.2/tests/CMakeLists.txt | 27 - .../vendor/libyaml-0.2.2/tests/Makefile.am | 9 - .../tests/example-deconstructor-alt.c | 800 - .../tests/example-deconstructor.c | 1127 - .../tests/example-reformatter-alt.c | 217 - .../libyaml-0.2.2/tests/example-reformatter.c | 202 - .../libyaml-0.2.2/tests/run-all-tests.sh | 29 - .../vendor/libyaml-0.2.2/tests/run-dumper.c | 314 - .../tests/run-emitter-test-suite.c | 231 - .../vendor/libyaml-0.2.2/tests/run-emitter.c | 327 - .../vendor/libyaml-0.2.2/tests/run-loader.c | 63 - .../tests/run-parser-test-suite.c | 144 - .../vendor/libyaml-0.2.2/tests/run-parser.c | 63 - .../vendor/libyaml-0.2.2/tests/run-scanner.c | 63 - .../vendor/libyaml-0.2.2/tests/test-reader.c | 354 - .../vendor/libyaml-0.2.2/tests/test-version.c | 29 - .../vendor/libyaml-0.2.2/yaml-0.1.pc.in | 10 - .../vendor/libyaml-0.2.2/yamlConfig.cmake.in | 16 - .../paraconf-1.0.3/.github/workflows/test.yml | 33 + .../paraconf => paraconf-1.0.3}/AUTHORS | 9 +- .../CMakeLists.txt | 112 +- vendor/paraconf-1.0.3/COPYRIGHT.md | 24 + vendor/paraconf-1.0.3/LICENSES/MIT.txt | 18 + .../paraconf => paraconf-1.0.3}/README.md | 58 +- .../paraconf => paraconf-1.0.3}/TODO.md | 8 +- vendor/paraconf-1.0.3/VERSION | 1 + vendor/paraconf-1.0.3/VERSION.license | 4 + .../cmake/Findyaml.cmake | 60 +- .../paraconf-1.0.3/cmake/paraconfConfig.cmake | 66 + vendor/paraconf-1.0.3/cmake/version-uid | 27 + vendor/paraconf-1.0.3/example/CMakeLists.txt | 33 + .../example/example.c | 6 + .../example/example.f90 | 28 +- .../example/example.yml | 7 +- vendor/paraconf-1.0.3/include/paraconf.F90 | 6 + .../include/paraconf.h | 28 +- .../include/paraconf_f90.h | 28 +- .../include/paraconf_f90_consts.h | 28 + .../include/paraconf_f90_types.h | 16 + vendor/paraconf-1.0.3/include/paraconff.h | 6 + .../paraconf => paraconf-1.0.3}/src/api.c | 28 +- .../src/fortran/paraconf.f90 | 28 +- .../src/fortran/paraconf_f90_c.h | 28 +- .../paraconf => paraconf-1.0.3}/src/status.c | 28 +- vendor/paraconf-1.0.3/src/status.h | 37 + vendor/paraconf-1.0.3/src/tools.h | 31 + .../paraconf => paraconf-1.0.3}/src/ypath.c | 28 +- vendor/paraconf-1.0.3/src/ypath.h | 14 + vendor/paraconf-1.0.3/tests/CMakeLists.txt | 17 + .../paraconf => paraconf-1.0.3}/tests/test1.c | 28 +- .../tests/test2.f90 | 28 +- .../tests/test_data.yml | 5 + vendor/pybind11-2.13.1/MANIFEST.in | 6 - vendor/pybind11-2.13.1/docs/Makefile | 192 - .../docs/advanced/cast/custom.rst | 93 - .../docs/advanced/embedding.rst | 262 - .../docs/advanced/smart_ptrs.rst | 174 - vendor/pybind11-2.13.1/docs/changelog.rst | 3121 - vendor/pybind11-2.13.1/docs/requirements.txt | 275 - vendor/pybind11-2.13.1/pybind11/__main__.py | 63 - vendor/pybind11-2.13.1/pybind11/_version.py | 12 - vendor/pybind11-2.13.1/pyproject.toml | 87 - vendor/pybind11-2.13.1/setup.cfg | 43 - vendor/pybind11-2.13.1/setup.py | 149 - .../tests/extra_python_package/test_files.py | 296 - vendor/pybind11-2.13.1/tests/requirements.txt | 13 - vendor/pybind11-2.13.1/tests/test_buffers.py | 230 - vendor/pybind11-2.13.1/tests/test_pickling.py | 95 - vendor/pybind11-2.13.1/tests/test_stl.py | 383 - .../pybind11-2.13.1/tools/make_changelog.py | 92 - vendor/pybind11-2.13.1/tools/pyproject.toml | 3 - .../pybind11-2.13.1/tools/setup_global.py.in | 63 - vendor/pybind11-2.13.1/tools/setup_main.py.in | 44 - .../.appveyor.yml | 0 .../.clang-format | 0 .../.clang-tidy | 3 + .../.cmake-format.yaml | 0 .../.codespell-ignore-lines | 11 + .../.gitattributes | 0 .../.github/CODEOWNERS | 0 .../.github/CONTRIBUTING.md | 149 +- .../.github/ISSUE_TEMPLATE/bug-report.yml | 0 .../.github/ISSUE_TEMPLATE/config.yml | 0 .../.github/dependabot.yml | 0 .../.github/labeler.yml | 2 +- .../.github/labeler_merged.yml | 2 +- .../.github/matchers/pylint.json | 0 .../.github/pull_request_template.md | 10 +- .../.github/workflows/ci.yml | 514 +- .../.github/workflows/configure.yml | 59 +- .../.github/workflows/docs-link.yml | 41 + .../.github/workflows/format.yml | 20 +- .../.github/workflows/labeler.yml | 0 .../.github/workflows/nightlies.yml | 59 + .../.github/workflows/pip.yml | 31 +- .../.github/workflows/reusable-standard.yml | 96 + .../.github/workflows/tests-cibw.yml | 86 + .../.github/workflows/upstream.yml | 0 vendor/pybind11-3.0.1/.gitignore | 53 + .../.pre-commit-config.yaml | 31 +- .../.readthedocs.yml | 0 .../CMakeLists.txt | 172 +- vendor/pybind11-3.0.1/CMakePresets.json | 93 + .../LICENSE | 0 .../README.rst | 67 +- .../SECURITY.md | 0 .../docs/Doxyfile | 0 .../docs/_static/css/custom.css | 0 .../docs/advanced/cast/chrono.rst | 0 .../docs/advanced/cast/custom.rst | 137 + .../docs/advanced/cast/eigen.rst | 2 +- .../docs/advanced/cast/functional.rst | 2 +- .../docs/advanced/cast/index.rst | 0 .../docs/advanced/cast/overview.rst | 4 +- .../docs/advanced/cast/stl.rst | 10 +- .../docs/advanced/cast/strings.rst | 0 .../docs/advanced/classes.rst | 149 +- .../pybind11-3.0.1/docs/advanced/deadlock.md | 391 + .../docs/advanced/deprecated.rst | 179 + .../docs/advanced/embedding.rst | 495 + .../docs/advanced/exceptions.rst | 25 +- .../docs/advanced/functions.rst | 8 +- .../docs/advanced/misc.rst | 198 +- .../docs/advanced/pycpp/index.rst | 0 .../docs/advanced/pycpp/numpy.rst | 46 +- .../docs/advanced/pycpp/object.rst | 0 .../docs/advanced/pycpp/utilities.rst | 0 .../docs/advanced/smart_ptrs.rst | 179 + .../docs/basics.rst | 13 +- .../docs/benchmark.py | 6 +- .../docs/benchmark.rst | 2 +- vendor/pybind11-3.0.1/docs/changelog.md | 3234 + .../docs/classes.rst | 189 +- .../docs/cmake/index.rst | 0 .../docs/compiling.rst | 55 +- .../docs/conf.py | 12 +- .../docs/faq.rst | 65 +- .../docs/index.rst | 1 + .../docs/installing.rst | 2 +- .../docs/limitations.rst | 4 - .../docs/pybind11-logo.png | Bin .../docs/pybind11_vs_boost_python1.png | Bin .../docs/pybind11_vs_boost_python1.svg | 0 .../docs/pybind11_vs_boost_python2.png | Bin .../docs/pybind11_vs_boost_python2.svg | 0 .../docs/reference.rst | 4 +- .../docs/release.rst | 58 +- .../docs/requirements.in | 1 + vendor/pybind11-3.0.1/docs/requirements.txt | 91 + .../docs/upgrade.rst | 154 +- .../include/pybind11/attr.h | 48 +- .../include/pybind11/buffer_info.h | 0 .../include/pybind11/cast.h | 567 +- .../include/pybind11/chrono.h | 5 +- .../include/pybind11/common.h | 0 .../include/pybind11/complex.h | 0 .../include/pybind11/conduit/README.txt | 15 + .../pybind11/conduit/pybind11_conduit_v1.h | 116 + .../conduit/pybind11_platform_abi_id.h | 87 + .../pybind11/conduit/wrap_include_python_h.h | 72 + .../include/pybind11/critical_section.h | 56 + .../include/pybind11/detail/class.h | 139 +- .../include/pybind11/detail/common.h | 462 +- .../include/pybind11/detail/cpp_conduit.h | 75 + .../include/pybind11/detail/descr.h | 60 +- .../detail/dynamic_raw_ptr_cast_if_possible.h | 39 + .../pybind11/detail/exception_translation.h | 71 + .../detail/function_record_pyobject.h | 191 + .../include/pybind11/detail/init.h | 122 +- .../include/pybind11/detail/internals.h | 710 +- .../pybind11/detail/native_enum_data.h | 209 + .../detail/pybind11_namespace_macros.h | 82 + .../pybind11/detail/struct_smart_holder.h | 378 + .../pybind11/detail/type_caster_base.h | 587 +- .../include/pybind11/detail/typeid.h | 0 .../pybind11/detail/using_smart_holder.h | 22 + .../pybind11/detail/value_and_holder.h | 90 + .../include/pybind11/eigen.h | 0 .../include/pybind11/eigen/common.h | 0 .../include/pybind11/eigen/matrix.h | 29 +- .../include/pybind11/eigen/tensor.h | 26 +- .../include/pybind11/embed.h | 93 +- .../include/pybind11/eval.h | 17 +- .../include/pybind11/functional.h | 107 +- .../include/pybind11/gil.h | 76 +- .../include/pybind11/gil_safe_call_once.h | 13 +- .../include/pybind11/gil_simple.h | 37 + .../include/pybind11/iostream.h | 0 .../include/pybind11/native_enum.h | 67 + .../include/pybind11/numpy.h | 361 +- .../include/pybind11/operators.h | 0 .../include/pybind11/options.h | 0 .../include/pybind11/pybind11.h | 1127 +- .../include/pybind11/pytypes.h | 116 +- .../include/pybind11/stl.h | 336 +- .../include/pybind11/stl/filesystem.h | 47 +- .../include/pybind11/stl_bind.h | 46 +- .../include/pybind11/subinterpreter.h | 299 + .../pybind11/trampoline_self_life_support.h | 65 + .../pybind11/type_caster_pyobject_ptr.h | 0 .../include/pybind11/typing.h | 99 +- .../include/pybind11/warnings.h | 75 + .../noxfile.py | 68 +- .../pybind11/__init__.py | 4 +- vendor/pybind11-3.0.1/pybind11/__main__.py | 97 + vendor/pybind11-3.0.1/pybind11/_version.py | 34 + .../pybind11/commands.py | 0 .../pybind11/py.typed | 0 .../pybind11/setup_helpers.py | 2 +- vendor/pybind11-3.0.1/pyproject.toml | 184 + .../tests/CMakeLists.txt | 175 +- .../tests/conftest.py | 89 +- .../tests/constructor_stats.h | 10 +- .../tests/cross_module_gil_utils.cpp | 0 ...s_module_interleaved_error_already_set.cpp | 0 .../pybind11-3.0.1/tests/custom_exceptions.py | 10 + .../tests/eigen_tensor_avoid_stl_array.cpp | 0 .../tests/env.py | 6 + .../pybind11-3.0.1/tests/exo_planet_c_api.cpp | 76 + .../tests/exo_planet_pybind11.cpp | 19 + .../tests/extra_python_package/pytest.ini | 0 .../tests/extra_python_package/test_files.py | 383 + .../tests/extra_setuptools/pytest.ini | 0 .../extra_setuptools/test_setuphelper.py | 0 .../home_planet_very_lonely_traveler.cpp | 13 + .../tests/local_bindings.h | 16 +- .../tests/mod_per_interpreter_gil.cpp | 20 + .../tests/mod_shared_interpreter_gil.cpp | 17 + .../tests/object.h | 0 .../tests/pure_cpp/CMakeLists.txt | 20 + .../tests/pure_cpp/smart_holder_poc.h | 56 + .../tests/pure_cpp/smart_holder_poc_test.cpp | 427 + .../tests/pybind11_cross_module_tests.cpp | 0 .../tests/pybind11_tests.cpp | 12 +- .../tests/pybind11_tests.h | 21 + vendor/pybind11-3.0.1/tests/pyproject.toml | 38 + .../tests/pytest.ini | 3 +- vendor/pybind11-3.0.1/tests/requirements.txt | 18 + .../tests/test_async.cpp | 0 .../tests/test_async.py | 7 +- .../tests/test_buffers.cpp | 183 + vendor/pybind11-3.0.1/tests/test_buffers.py | 401 + .../tests/test_builtin_casters.cpp | 4 + .../tests/test_builtin_casters.py | 27 +- .../tests/test_call_policies.cpp | 4 +- .../tests/test_call_policies.py | 7 + .../tests/test_callbacks.cpp | 46 +- .../tests/test_callbacks.py | 32 +- .../tests/test_chrono.cpp | 0 .../tests/test_chrono.py | 0 .../tests/test_class.cpp | 31 +- .../tests/test_class.py | 72 +- ...ss_release_gil_before_calling_cpp_dtor.cpp | 53 + ...ass_release_gil_before_calling_cpp_dtor.py | 21 + .../tests/test_class_sh_basic.cpp | 248 + .../tests/test_class_sh_basic.py | 248 + .../tests/test_class_sh_disowning.cpp | 41 + .../tests/test_class_sh_disowning.py | 78 + .../tests/test_class_sh_disowning_mi.cpp | 85 + .../tests/test_class_sh_disowning_mi.py | 246 + .../test_class_sh_factory_constructors.cpp | 156 + .../test_class_sh_factory_constructors.py | 53 + .../tests/test_class_sh_inheritance.cpp | 90 + .../tests/test_class_sh_inheritance.py | 63 + .../tests/test_class_sh_mi_thunks.cpp | 93 + .../tests/test_class_sh_mi_thunks.py | 53 + .../tests/test_class_sh_property.cpp | 94 + .../tests/test_class_sh_property.py | 166 + .../test_class_sh_property_non_owning.cpp | 63 + .../test_class_sh_property_non_owning.py | 30 + .../test_class_sh_shared_ptr_copy_move.cpp | 103 + .../test_class_sh_shared_ptr_copy_move.py | 41 + .../tests/test_class_sh_trampoline_basic.cpp | 57 + .../tests/test_class_sh_trampoline_basic.py | 35 + ..._class_sh_trampoline_self_life_support.cpp | 86 + ...t_class_sh_trampoline_self_life_support.py | 38 + ...t_class_sh_trampoline_shared_from_this.cpp | 137 + ...st_class_sh_trampoline_shared_from_this.py | 247 + ...class_sh_trampoline_shared_ptr_cpp_arg.cpp | 92 + ..._class_sh_trampoline_shared_ptr_cpp_arg.py | 154 + .../test_class_sh_trampoline_unique_ptr.cpp | 63 + .../test_class_sh_trampoline_unique_ptr.py | 31 + ...est_class_sh_unique_ptr_custom_deleter.cpp | 30 + ...test_class_sh_unique_ptr_custom_deleter.py | 8 + .../tests/test_class_sh_unique_ptr_member.cpp | 50 + .../tests/test_class_sh_unique_ptr_member.py | 26 + .../test_class_sh_virtual_py_cpp_mix.cpp | 58 + .../tests/test_class_sh_virtual_py_cpp_mix.py | 66 + .../tests/test_cmake_build/CMakeLists.txt | 21 +- .../tests/test_cmake_build/embed.cpp | 0 .../installed_embed/CMakeLists.txt | 11 +- .../installed_function/CMakeLists.txt | 12 +- .../installed_target/CMakeLists.txt | 11 +- .../tests/test_cmake_build/main.cpp | 0 .../subdirectory_embed/CMakeLists.txt | 11 +- .../subdirectory_function/CMakeLists.txt | 11 +- .../subdirectory_target/CMakeLists.txt | 11 +- .../tests/test_cmake_build/test.py | 0 .../tests/test_const_name.cpp | 0 .../tests/test_const_name.py | 0 .../tests/test_constants_and_functions.cpp | 0 .../tests/test_constants_and_functions.py | 0 .../tests/test_copy_move.cpp | 10 +- .../tests/test_copy_move.py | 4 + .../pybind11-3.0.1/tests/test_cpp_conduit.cpp | 22 + .../pybind11-3.0.1/tests/test_cpp_conduit.py | 183 + .../test_cpp_conduit_traveler_bindings.h | 47 + .../tests/test_cpp_conduit_traveler_types.h | 25 + .../test_cross_module_rtti/CMakeLists.txt | 68 + .../tests/test_cross_module_rtti/bindings.cpp | 20 + .../tests/test_cross_module_rtti/catch.cpp | 22 + .../tests/test_cross_module_rtti/lib.cpp | 13 + .../tests/test_cross_module_rtti/lib.h | 30 + .../test_cross_module_rtti.cpp | 50 + .../tests/test_custom_type_casters.cpp | 0 .../tests/test_custom_type_casters.py | 4 +- .../tests/test_custom_type_setup.cpp | 16 +- .../tests/test_custom_type_setup.py | 6 +- .../tests/test_docs_advanced_cast_custom.cpp | 69 + .../tests/test_docs_advanced_cast_custom.py | 40 + .../tests/test_docstring_options.cpp | 0 .../tests/test_docstring_options.py | 12 +- .../tests/test_eigen_matrix.cpp | 8 +- .../tests/test_eigen_matrix.py | 69 +- .../tests/test_eigen_tensor.cpp | 0 .../tests/test_eigen_tensor.inl | 16 +- .../tests/test_eigen_tensor.py | 42 +- .../tests/test_embed/CMakeLists.txt | 17 +- .../tests/test_embed/catch.cpp | 0 .../tests/test_embed/external_module.cpp | 6 +- .../tests/test_embed/test_interpreter.cpp | 122 +- .../tests/test_embed/test_interpreter.py | 0 .../tests/test_embed/test_subinterpreter.cpp | 442 + .../tests/test_embed/test_trampoline.py | 0 .../tests/test_enum.cpp | 16 + .../tests/test_enum.py | 92 +- .../tests/test_eval.cpp | 0 .../tests/test_eval.py | 2 +- .../tests/test_eval_call.py | 0 .../tests/test_exceptions.cpp | 39 + .../tests/test_exceptions.h | 0 .../tests/test_exceptions.py | 39 +- .../tests/test_factory_constructors.cpp | 0 .../tests/test_factory_constructors.py | 21 +- .../tests/test_gil_scoped.cpp | 0 .../tests/test_gil_scoped.py | 53 +- .../tests/test_iostream.cpp | 0 .../tests/test_iostream.py | 4 + .../tests/test_kwargs_and_defaults.cpp | 6 + .../tests/test_kwargs_and_defaults.py | 91 +- .../tests/test_local_bindings.cpp | 0 .../tests/test_local_bindings.py | 2 - .../tests/test_methods_and_attributes.cpp | 2 +- .../tests/test_methods_and_attributes.py | 47 +- .../tests/test_modules.cpp | 15 +- .../tests/test_modules.py | 32 +- .../tests/test_multiple_inheritance.cpp | 0 .../tests/test_multiple_inheritance.py | 25 +- .../tests/test_multiple_interpreters.py | 200 + .../pybind11-3.0.1/tests/test_native_enum.cpp | 258 + .../pybind11-3.0.1/tests/test_native_enum.py | 322 + .../tests/test_numpy_array.cpp | 97 +- .../tests/test_numpy_array.py | 98 +- .../tests/test_numpy_dtypes.cpp | 108 +- .../tests/test_numpy_dtypes.py | 32 +- .../tests/test_numpy_scalars.cpp | 63 + .../tests/test_numpy_scalars.py | 54 + .../tests/test_numpy_vectorize.cpp | 0 .../tests/test_numpy_vectorize.py | 14 +- .../tests/test_opaque_types.cpp | 6 +- .../tests/test_opaque_types.py | 18 +- .../tests/test_operator_overloading.cpp | 0 .../tests/test_operator_overloading.py | 10 +- .../tests/test_pickling.cpp | 5 +- vendor/pybind11-3.0.1/tests/test_pickling.py | 149 + .../test_potentially_slicing_weak_ptr.cpp | 168 + .../test_potentially_slicing_weak_ptr.py | 174 + .../test_python_multiple_inheritance.cpp | 0 .../tests/test_python_multiple_inheritance.py | 0 .../tests/test_pytypes.cpp | 295 +- .../tests/test_pytypes.py | 387 +- .../tests/test_scoped_critical_section.cpp | 275 + .../tests/test_scoped_critical_section.py | 30 + .../tests/test_sequences_and_iterators.cpp | 6 +- .../tests/test_sequences_and_iterators.py | 74 +- .../tests/test_smart_ptr.cpp | 126 +- .../tests/test_smart_ptr.py | 46 +- .../tests/test_stl.cpp | 127 +- vendor/pybind11-3.0.1/tests/test_stl.py | 735 + .../tests/test_stl_binders.cpp | 0 .../tests/test_stl_binders.py | 19 + .../tests/test_tagbased_polymorphic.cpp | 3 +- .../tests/test_tagbased_polymorphic.py | 0 .../tests/test_thread.cpp | 6 + .../tests/test_thread.py | 24 + .../tests/test_type_caster_pyobject_ptr.cpp | 3 +- .../tests/test_type_caster_pyobject_ptr.py | 4 +- ...pe_caster_std_function_specializations.cpp | 46 + ...ype_caster_std_function_specializations.py | 15 + .../tests/test_union.cpp | 0 .../tests/test_union.py | 0 .../tests/test_unnamed_namespace_a.cpp | 1 - .../tests/test_unnamed_namespace_a.py | 8 +- .../tests/test_unnamed_namespace_b.cpp | 0 .../tests/test_unnamed_namespace_b.py | 0 .../tests/test_vector_unique_ptr_member.cpp | 0 .../tests/test_vector_unique_ptr_member.py | 0 .../tests/test_virtual_functions.cpp | 2 +- .../tests/test_virtual_functions.py | 12 +- vendor/pybind11-3.0.1/tests/test_warnings.cpp | 46 + vendor/pybind11-3.0.1/tests/test_warnings.py | 68 + .../tests/valgrind-numpy-scipy.supp | 0 .../tests/valgrind-python.supp | 0 .../tools/FindCatch.cmake | 2 - .../tools/FindEigen3.cmake | 0 .../tools/FindPythonLibsNew.cmake | 12 +- .../tools/JoinPaths.cmake | 0 .../tools/check-style.sh | 0 .../tools/cmake_uninstall.cmake.in | 0 .../codespell_ignore_lines_from_errors.py | 0 .../tools/libsize.py | 0 vendor/pybind11-3.0.1/tools/make_changelog.py | 121 + vendor/pybind11-3.0.1/tools/make_global.py | 33 + .../tools/pybind11.pc.in | 0 .../tools/pybind11Common.cmake | 132 +- .../tools/pybind11Config.cmake.in | 13 +- .../tools/pybind11GuessPythonExtSuffix.cmake | 2 +- .../tools/pybind11NewTools.cmake | 34 +- .../tools/pybind11Tools.cmake | 56 +- .../test-pybind11GuessPythonExtSuffix.cmake | 2 +- .../include/spdlog/fmt/bundled/core.h | 2969 - .../include/spdlog/fmt/bundled/locale.h | 2 - .../include/spdlog/fmt/bundled/ostream.h | 245 - .../include/spdlog/fmt/bundled/std.h | 537 - .../include/spdlog/fmt/bundled/xchar.h | 259 - .../.clang-format | 0 .../.clang-tidy | 0 .../.git-blame-ignore-revs | 0 .../.gitattributes | 0 .../.github/workflows/linux.yml} | 44 +- .../spdlog-1.15.3/.github/workflows/macos.yml | 38 + .../.github/workflows/windows.yml | 148 + vendor/spdlog-1.15.3/.gitignore | 98 + .../CMakeLists.txt | 61 +- .../{spdlog-1.14.1 => spdlog-1.15.3}/INSTALL | 0 .../{spdlog-1.14.1 => spdlog-1.15.3}/LICENSE | 0 .../README.md | 32 +- .../appveyor.yml | 0 .../bench/CMakeLists.txt | 0 .../bench/async_bench.cpp | 2 +- .../bench/bench.cpp | 4 +- .../bench/formatter-bench.cpp | 0 .../bench/latency.cpp | 0 .../bench/utils.h | 0 .../cmake/ide.cmake | 0 .../cmake/pch.h.in | 6 +- .../cmake/spdlog.pc.in | 0 .../cmake/spdlogCPack.cmake | 0 .../cmake/spdlogConfig.cmake.in | 0 .../cmake/utils.cmake | 15 +- .../cmake/version.rc.in | 0 .../example/CMakeLists.txt | 0 .../example/example.cpp | 28 +- .../include/spdlog/async.h | 3 +- .../include/spdlog/async_logger-inl.h | 14 +- .../include/spdlog/async_logger.h | 0 .../include/spdlog/cfg/argv.h | 0 .../include/spdlog/cfg/env.h | 4 +- .../include/spdlog/cfg/helpers-inl.h | 0 .../include/spdlog/cfg/helpers.h | 0 .../include/spdlog/common-inl.h | 0 .../include/spdlog/common.h | 7 +- .../include/spdlog/details/backtracer-inl.h | 0 .../include/spdlog/details/backtracer.h | 0 .../include/spdlog/details/circular_q.h | 0 .../include/spdlog/details/console_globals.h | 0 .../include/spdlog/details/file_helper-inl.h | 3 +- .../include/spdlog/details/file_helper.h | 0 .../include/spdlog/details/fmt_helper.h | 0 .../include/spdlog/details/log_msg-inl.h | 0 .../include/spdlog/details/log_msg.h | 0 .../spdlog/details/log_msg_buffer-inl.h | 0 .../include/spdlog/details/log_msg_buffer.h | 0 .../include/spdlog/details/mpmc_blocking_q.h | 6 +- .../include/spdlog/details/null_mutex.h | 0 .../include/spdlog/details/os-inl.h | 26 +- .../include/spdlog/details/os.h | 4 + .../spdlog/details/periodic_worker-inl.h | 0 .../include/spdlog/details/periodic_worker.h | 0 .../include/spdlog/details/registry-inl.h | 11 +- .../include/spdlog/details/registry.h | 2 + .../spdlog/details/synchronous_factory.h | 0 .../spdlog/details/tcp_client-windows.h | 0 .../include/spdlog/details/tcp_client.h | 0 .../include/spdlog/details/thread_pool-inl.h | 14 +- .../include/spdlog/details/thread_pool.h | 17 +- .../spdlog/details/udp_client-windows.h | 0 .../include/spdlog/details/udp_client.h | 0 .../include/spdlog/details/windows_include.h | 0 .../include/spdlog/fmt/bin_to_hex.h | 6 +- .../include/spdlog/fmt/bundled/args.h | 163 +- .../include/spdlog/fmt/bundled/base.h | 2989 + .../include/spdlog/fmt/bundled/chrono.h | 1488 +- .../include/spdlog/fmt/bundled/color.h | 394 +- .../include/spdlog/fmt/bundled/compile.h | 188 +- .../include/spdlog/fmt/bundled/core.h | 5 + .../spdlog/fmt/bundled/fmt.license.rst | 2 +- .../include/spdlog/fmt/bundled/format-inl.h | 396 +- .../include/spdlog/fmt/bundled/format.h | 3059 +- .../include/spdlog/fmt/bundled/os.h | 272 +- .../include/spdlog/fmt/bundled/ostream.h | 167 + .../include/spdlog/fmt/bundled/printf.h | 412 +- .../include/spdlog/fmt/bundled/ranges.h | 604 +- .../include/spdlog/fmt/bundled/std.h | 728 + .../include/spdlog/fmt/bundled/xchar.h | 369 + .../include/spdlog/fmt/chrono.h | 0 .../include/spdlog/fmt/compile.h | 0 .../include/spdlog/fmt/fmt.h | 4 +- .../include/spdlog/fmt/ostr.h | 0 .../include/spdlog/fmt/ranges.h | 0 .../include/spdlog/fmt/std.h | 0 .../include/spdlog/fmt/xchar.h | 0 .../include/spdlog/formatter.h | 0 .../include/spdlog/fwd.h | 0 .../include/spdlog/logger-inl.h | 0 .../include/spdlog/logger.h | 0 .../include/spdlog/mdc.h | 12 +- .../include/spdlog/pattern_formatter-inl.h | 24 +- .../include/spdlog/pattern_formatter.h | 0 .../include/spdlog/sinks/android_sink.h | 0 .../include/spdlog/sinks/ansicolor_sink-inl.h | 19 +- .../include/spdlog/sinks/ansicolor_sink.h | 9 +- .../include/spdlog/sinks/base_sink-inl.h | 0 .../include/spdlog/sinks/base_sink.h | 8 +- .../spdlog/sinks/basic_file_sink-inl.h | 6 + .../include/spdlog/sinks/basic_file_sink.h | 1 + .../include/spdlog/sinks/callback_sink.h | 2 +- .../include/spdlog/sinks/daily_file_sink.h | 2 + .../include/spdlog/sinks/dist_sink.h | 0 .../include/spdlog/sinks/dup_filter_sink.h | 11 +- .../include/spdlog/sinks/hourly_file_sink.h | 2 + .../include/spdlog/sinks/kafka_sink.h | 0 .../include/spdlog/sinks/mongo_sink.h | 0 .../include/spdlog/sinks/msvc_sink.h | 2 +- .../include/spdlog/sinks/null_sink.h | 2 +- .../include/spdlog/sinks/ostream_sink.h | 0 .../include/spdlog/sinks/qt_sinks.h | 0 .../include/spdlog/sinks/ringbuffer_sink.h | 0 .../spdlog/sinks/rotating_file_sink-inl.h | 47 +- .../include/spdlog/sinks/rotating_file_sink.h | 34 +- .../include/spdlog/sinks/sink-inl.h | 0 .../include/spdlog/sinks/sink.h | 0 .../spdlog/sinks/stdout_color_sinks-inl.h | 0 .../include/spdlog/sinks/stdout_color_sinks.h | 0 .../include/spdlog/sinks/stdout_sinks-inl.h | 9 +- .../include/spdlog/sinks/stdout_sinks.h | 0 .../include/spdlog/sinks/syslog_sink.h | 5 +- .../include/spdlog/sinks/systemd_sink.h | 0 .../include/spdlog/sinks/tcp_sink.h | 0 .../include/spdlog/sinks/udp_sink.h | 0 .../include/spdlog/sinks/win_eventlog_sink.h | 0 .../include/spdlog/sinks/wincolor_sink-inl.h | 9 + .../include/spdlog/sinks/wincolor_sink.h | 0 .../include/spdlog/spdlog-inl.h | 4 + .../include/spdlog/spdlog.h | 21 +- .../include/spdlog/stopwatch.h | 0 .../include/spdlog/tweakme.h | 7 + .../include/spdlog/version.h | 4 +- .../logos/jetbrains-variant-4.svg | 0 .../logos/spdlog.png | Bin .../scripts/ci_setup_clang.sh | 0 .../scripts/extract_version.py | 0 .../scripts/format.sh | 0 .../src/async.cpp | 0 .../src/bundled_fmtlib_format.cpp | 5 +- .../src/cfg.cpp | 0 .../src/color_sinks.cpp | 0 .../src/file_sinks.cpp | 0 .../src/spdlog.cpp | 0 .../src/stdout_sinks.cpp | 0 .../tests/CMakeLists.txt | 17 +- .../tests/includes.h | 7 +- .../tests/main.cpp | 0 .../tests/test_async.cpp | 44 - .../tests/test_backtrace.cpp | 0 .../tests/test_bin_to_hex.cpp | 0 .../tests/test_cfg.cpp | 9 + .../tests/test_circular_q.cpp | 0 .../tests/test_create_dir.cpp | 0 .../tests/test_custom_callbacks.cpp | 4 +- .../tests/test_daily_logger.cpp | 8 +- .../tests/test_dup_filter.cpp | 0 .../tests/test_errors.cpp | 0 .../tests/test_eventlog.cpp | 0 .../tests/test_file_helper.cpp | 0 .../tests/test_file_logging.cpp | 90 +- .../tests/test_fmt_helper.cpp | 0 .../tests/test_macros.cpp | 0 .../tests/test_misc.cpp | 61 +- .../tests/test_mpmc_q.cpp | 0 .../tests/test_pattern_formatter.cpp | 30 + .../tests/test_registry.cpp | 13 + .../tests/test_sink.h | 3 +- .../tests/test_stdout_api.cpp | 0 .../tests/test_stopwatch.cpp | 0 .../tests/test_systemd.cpp | 0 .../tests/test_time_point.cpp | 0 .../tests/utils.cpp | 3 +- .../tests/utils.h | 0 vendor/zpp-1.0.16/.gitignore | 4 - vendor/zpp-1.0.16/AUTHORS | 15 - vendor/zpp-1.0.16/CMakeLists.txt | 54 - vendor/zpp-1.0.16/MANIFEST.in | 4 - vendor/zpp-1.0.16/bin/zpp | 20 - vendor/zpp-1.0.16/bin/zpp.in | 7 - .../examples/cmake_find/CMakeLists.txt | 31 - .../cmake_subdirectory/CMakeLists.txt | 30 - vendor/zpp-1.0.16/examples/makefile/Makefile | 32 - vendor/zpp-1.0.16/release | 24 - vendor/zpp-1.0.16/setup.py | 154 - vendor/zpp-1.0.16/zpp/cmake/BppConfig.cmake | 1 - .../zpp/cmake/BppConfigVersion.cmake | 1 - vendor/zpp-1.0.16/zpp/cmake/ZppConfig.cmake | 49 - .../zpp/cmake/ZppConfigVersion.cmake | 46 - .../zpp-1.0.16/zpp/include/config.Gnu.zpp.sh | 25 - .../zpp/include/config.Intel.zpp.sh | 25 - .../zpp-1.0.16/zpp/include/config.PGI.zpp.sh | 25 - .../zpp-1.0.16/zpp/include/config.XL.zpp.sh | 25 - .../zpp/include/hdf5_fortran.zpp.sh | 47 - vendor/zpp-1.0.16/zpp/version.py | 24 - vendor/zpp-1.0.16/zpp/zpp.mk | 39 - vendor/zpp-1.1.0/.gitignore | 14 + vendor/zpp-1.1.0/AUTHORS | 23 + vendor/zpp-1.1.0/CMakeLists.txt | 23 + vendor/zpp-1.1.0/LICENSES/MIT.txt | 11 + vendor/zpp-1.1.0/MANIFEST.in | 14 + vendor/{zpp-1.0.16 => zpp-1.1.0}/README.md | 10 + vendor/zpp-1.1.0/bin/zpp | 24 + vendor/zpp-1.1.0/bin/zpp.in | 17 + vendor/zpp-1.1.0/bin/zpp_register | 27 + .../examples/cmake_find/CMakeLists.txt | 20 + .../examples/cmake_find/example.F90.zpp | 29 +- .../cmake_subdirectory/CMakeLists.txt | 17 + .../cmake_subdirectory/example.F90.zpp | 29 +- vendor/zpp-1.1.0/examples/makefile/Makefile | 19 + .../examples/makefile/example.F90.zpp | 29 +- vendor/zpp-1.1.0/pyproject.toml | 43 + vendor/zpp-1.1.0/release | 34 + vendor/zpp-1.1.0/setup.py | 13 + .../{zpp-1.0.16 => zpp-1.1.0}/zpp/__init__.py | 69 +- .../zpp/cmake/TestFortType.cmake | 34 +- .../zpp/cmake/Zpp.cmake | 46 +- vendor/zpp-1.1.0/zpp/cmake/ZppConfig.cmake | 29 + .../zpp/cmake/ZppConfigVersion.cmake | 36 + .../zpp/include/base.zpp.sh | 29 +- .../zpp-1.1.0/zpp/include/config.Gnu.zpp.sh | 12 + .../zpp-1.1.0/zpp/include/config.Intel.zpp.sh | 12 + .../zpp-1.1.0/zpp/include/config.PGI.zpp.sh | 12 + vendor/zpp-1.1.0/zpp/include/config.XL.zpp.sh | 12 + .../zpp/include/fortran.zpp.sh | 30 +- .../zpp-1.1.0/zpp/include/hdf5_fortran.zpp.sh | 34 + vendor/zpp-1.1.0/zpp/registration.py | 124 + vendor/zpp-1.1.0/zpp/version.py | 11 + vendor/zpp-1.1.0/zpp/zpp.mk | 26 + 3942 files changed, 151740 insertions(+), 194234 deletions(-) create mode 100644 .github/CODEOWNERS create mode 100644 cmake_test/AUTHORS create mode 100644 cmake_test/CHANGELOG.md create mode 100644 cmake_test/CMakeLists.txt rename {vendor/paraconf-1.0.0 => cmake_test}/LICENSE (100%) rename {vendor/paraconf-1.0.0/paraconf/tests => cmake_test/subdir}/CMakeLists.txt (77%) delete mode 100644 example/cmake/DefaultKind.cmake delete mode 100644 example/cmake/FindPackageHandleStandardArgs.cmake delete mode 100644 example/cmake/FindPackageMessage.cmake delete mode 100644 example/cmake/FindPython/Support.cmake delete mode 100644 example/cmake/FindPython3.cmake delete mode 100644 example/cmake/SelectLibraryConfigurations.cmake delete mode 100644 example/deisa.yml delete mode 100644 example/deisa_client.py create mode 100644 mock_pdi/AUTHORS create mode 100644 mock_pdi/CHANGELOG.md rename .github/workflows/indent.yml => mock_pdi/CMakeLists.txt (85%) create mode 100644 mock_pdi/LICENSE create mode 100644 mock_pdi/PDIConfig.cmake rename vendor/paraconf-1.0.0/example/CMakeLists.txt => mock_pdi/PDIConfigVersion.cmake (67%) create mode 100644 mock_pdi/pdi.h delete mode 100644 pdi/cmake/CMakeFindDependencyMacro.cmake delete mode 100644 pdi/cmake/FindDoxygen.cmake delete mode 100644 pdi/cmake/FindGMock.cmake delete mode 100644 pdi/cmake/FindPackageHandleStandardArgs.cmake delete mode 100644 pdi/cmake/FindPackageMessage.cmake delete mode 100644 pdi/cmake/FindPython/Support.cmake delete mode 100644 pdi/cmake/FindPython3.cmake delete mode 100644 pdi/cmake/SelectLibraryConfigurations.cmake delete mode 100644 pdi/docs/modules.md create mode 100644 pdi/include/pdi/testing.h delete mode 100644 plugins/decl_hdf5/cmake/FindHDF5.cmake delete mode 100644 plugins/decl_hdf5/cmake/FindPackageHandleStandardArgs.cmake delete mode 100644 plugins/decl_hdf5/cmake/FindPackageMessage.cmake delete mode 100644 plugins/decl_hdf5/cmake/SelectLibraryConfigurations.cmake create mode 100644 plugins/decl_hdf5/dataset_explicit_type.h rename vendor/paraconf-1.0.0/paraconf/src/status.h => plugins/decl_hdf5/subfiling.cxx (57%) create mode 100644 plugins/decl_hdf5/subfiling.h create mode 100644 plugins/decl_hdf5/tests/decl_hdf5_mpi_subfiling.cxx create mode 100644 plugins/decl_hdf5/tests/decl_hdf5_mpi_test_08.c rename plugins/decl_netcdf/cmake/{ => 4.1}/FindHDF5.cmake (73%) create mode 100644 plugins/decl_netcdf/cmake/4.1/SelectLibraryConfigurations.cmake delete mode 100644 plugins/decl_netcdf/cmake/FindPackageHandleStandardArgs.cmake delete mode 100644 plugins/decl_netcdf/cmake/FindPackageMessage.cmake delete mode 100644 plugins/decl_netcdf/cmake/SelectLibraryConfigurations.cmake delete mode 100644 plugins/deisa/AUTHORS delete mode 100644 plugins/deisa/CHANGELOG.md delete mode 100644 plugins/deisa/CMakeLists.txt delete mode 100644 plugins/deisa/README.md delete mode 100644 plugins/deisa/cmake/FindPackageHandleStandardArgs.cmake delete mode 100644 plugins/deisa/cmake/FindPackageMessage.cmake delete mode 100644 plugins/deisa/cmake/FindPython/Support.cmake delete mode 100644 plugins/deisa/cmake/FindPython3.cmake delete mode 100644 plugins/deisa/cmake/SelectLibraryConfigurations.cmake delete mode 100644 plugins/deisa/deisa.cxx create mode 100644 plugins/json/CHANGELOG.md delete mode 100644 plugins/json/cmake/FindPackageHandleStandardArgs.cmake delete mode 100644 plugins/json/cmake/FindPackageMessage.cmake delete mode 100644 plugins/mpi/cmake/FindPackageHandleStandardArgs.cmake delete mode 100644 plugins/mpi/cmake/FindPackageMessage.cmake delete mode 100644 plugins/pycall/cmake/FindPackageHandleStandardArgs.cmake delete mode 100644 plugins/pycall/cmake/FindPackageMessage.cmake delete mode 100644 plugins/pycall/cmake/FindPython/Support.cmake delete mode 100644 plugins/pycall/cmake/FindPython3.cmake delete mode 100644 plugins/pycall/cmake/SelectLibraryConfigurations.cmake delete mode 100644 plugins/serialize/cmake/FindPackageHandleStandardArgs.cmake delete mode 100644 plugins/serialize/cmake/FindPackageMessage.cmake delete mode 100644 plugins/set_value/cmake/FindPackageHandleStandardArgs.cmake delete mode 100644 plugins/set_value/cmake/FindPackageMessage.cmake delete mode 100644 plugins/set_value/cmake/FindPython/Support.cmake delete mode 100644 plugins/set_value/cmake/FindPython3.cmake delete mode 100644 plugins/trace/cmake/FindPackageHandleStandardArgs.cmake delete mode 100644 plugins/trace/cmake/FindPackageMessage.cmake delete mode 100644 plugins/user_code/cmake/FindPackageHandleStandardArgs.cmake delete mode 100644 plugins/user_code/cmake/FindPackageMessage.cmake create mode 100644 test_api/AUTHORS create mode 100644 test_api/CHANGELOG.md create mode 100644 test_api/CMakeLists.txt create mode 100644 test_api/LICENSE create mode 100755 test_api/cmake/runtest-dir rename vendor/paraconf-1.0.0/paraconf/src/ypath.h => test_api/test_api.c (85%) rename vendor/paraconf-1.0.0/paraconf/src/tools.h => test_api/test_api.cpp (70%) create mode 100644 test_api/test_api.h delete mode 100644 vendor/benchmark-38df9da/.clang-tidy delete mode 100755 vendor/benchmark-38df9da/.github/libcxx-setup.sh delete mode 100644 vendor/benchmark-38df9da/.github/workflows/clang-format-lint.yml delete mode 100644 vendor/benchmark-38df9da/.github/workflows/pre-commit.yml delete mode 100644 vendor/benchmark-38df9da/.github/workflows/test_bindings.yml delete mode 100644 vendor/benchmark-38df9da/.github/workflows/wheels.yml delete mode 100644 vendor/benchmark-38df9da/.travis.yml delete mode 100644 vendor/benchmark-38df9da/bindings/python/google_benchmark/version.py delete mode 100644 vendor/benchmark-38df9da/cmake/CXXFeatureCheck.cmake delete mode 100644 vendor/benchmark-38df9da/cmake/Modules/FindLLVMAr.cmake delete mode 100644 vendor/benchmark-38df9da/cmake/Modules/FindLLVMNm.cmake delete mode 100644 vendor/benchmark-38df9da/cmake/Modules/FindLLVMRanLib.cmake delete mode 100644 vendor/benchmark-38df9da/cmake/Modules/FindPFM.cmake delete mode 100644 vendor/benchmark-38df9da/test/cxx03_test.cc delete mode 100644 vendor/benchmark-38df9da/tools/libpfm.BUILD.bazel delete mode 100644 vendor/benchmark-38df9da/tools/requirements.txt create mode 100644 vendor/benchmark-4ed29ae/.bazelversion rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/.clang-format (100%) create mode 100644 vendor/benchmark-4ed29ae/.clang-tidy create mode 100644 vendor/benchmark-4ed29ae/.clang-tidy.ignore rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/.github/ISSUE_TEMPLATE/bug_report.md (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/.github/ISSUE_TEMPLATE/feature_request.md (100%) create mode 100644 vendor/benchmark-4ed29ae/.github/dependabot.yml rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/.github/install_bazel.sh (83%) create mode 100755 vendor/benchmark-4ed29ae/.github/libcxx-setup.sh rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/.github/workflows/bazel.yml (57%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/.github/workflows/build-and-test-min-cmake.yml (82%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/.github/workflows/build-and-test-perfcounters.yml (89%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/.github/workflows/build-and-test.yml (60%) create mode 100644 vendor/benchmark-4ed29ae/.github/workflows/clang-format-lint.yml rename vendor/{benchmark-38df9da/.github/workflows/clang-tidy.yml => benchmark-4ed29ae/.github/workflows/clang-tidy-lint.yml} (64%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/.github/workflows/doxygen.yml (82%) create mode 100644 vendor/benchmark-4ed29ae/.github/workflows/ossf.yml create mode 100644 vendor/benchmark-4ed29ae/.github/workflows/pre-commit.yml rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/.github/workflows/sanitizer.yml (87%) create mode 100644 vendor/benchmark-4ed29ae/.github/workflows/test_bindings.yml create mode 100644 vendor/benchmark-4ed29ae/.github/workflows/wheels.yml create mode 100644 vendor/benchmark-4ed29ae/.gitignore rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/.pre-commit-config.yaml (81%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/.ycm_extra_conf.py (94%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/AUTHORS (94%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/BUILD.bazel (85%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/CMakeLists.txt (92%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/CONTRIBUTING.md (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/CONTRIBUTORS (95%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/LICENSE (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/MODULE.bazel (70%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/README.md (95%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/WORKSPACE (77%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/WORKSPACE.bzlmod (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/_config.yml (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/appveyor.yml (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/bazel/benchmark_deps.bzl (84%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/bindings/python/google_benchmark/BUILD (61%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/bindings/python/google_benchmark/__init__.py (86%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/bindings/python/google_benchmark/benchmark.cc (73%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/bindings/python/google_benchmark/example.py (96%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/AddCXXCompilerFlag.cmake (100%) create mode 100644 vendor/benchmark-4ed29ae/cmake/CXXFeatureCheck.cmake rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/Config.cmake.in (76%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/GetGitVersion.cmake (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/GoogleTest.cmake (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/GoogleTest.cmake.in (93%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/benchmark.pc.in (91%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/benchmark_main.pc.in (85%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/gnu_posix_regex.cpp (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/llvm-toolchain.cmake (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/posix_regex.cpp (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/pthread_affinity.cpp (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/split_list.cmake (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/std_regex.cpp (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/steady_clock.cpp (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/cmake/thread_safety_attributes.cpp (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/AssemblyTests.md (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/_config.yml (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/assets/images/icon.png (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/assets/images/icon.xcf (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/assets/images/icon_black.png (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/assets/images/icon_black.xcf (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/dependencies.md (58%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/index.md (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/perf_counters.md (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/platform_specific_build_instructions.md (80%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/python_bindings.md (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/random_interleaving.md (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/reducing_variance.md (69%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/releasing.md (64%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/tools.md (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/docs/user_guide.md (89%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/include/benchmark/benchmark.h (83%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/include/benchmark/export.h (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/pyproject.toml (75%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/setup.py (66%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/CMakeLists.txt (85%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/arraysize.h (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/benchmark.cc (84%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/benchmark_api_internal.cc (86%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/benchmark_api_internal.h (87%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/benchmark_main.cc (91%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/benchmark_name.cc (94%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/benchmark_register.cc (83%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/benchmark_register.h (99%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/benchmark_runner.cc (71%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/benchmark_runner.h (88%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/check.cc (58%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/check.h (84%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/colorprint.cc (87%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/colorprint.h (77%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/commandlineflags.cc (92%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/commandlineflags.h (95%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/complexity.cc (94%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/complexity.h (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/console_reporter.cc (90%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/counter.cc (84%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/counter.h (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/csv_reporter.cc (92%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/cycleclock.h (90%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/internal_macros.h (88%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/json_reporter.cc (89%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/log.h (82%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/mutex.h (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/perf_counters.cc (97%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/perf_counters.h (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/re.h (96%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/reporter.cc (81%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/statistics.cc (90%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/statistics.h (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/string_util.cc (94%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/string_util.h (98%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/sysinfo.cc (86%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/thread_manager.h (54%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/thread_timer.h (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/timers.cc (95%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/src/timers.h (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/AssemblyTests.cmake (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/BUILD (89%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/CMakeLists.txt (88%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/args_product_test.cc (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/basic_test.cc (97%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/benchmark_gtest.cc (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/benchmark_min_time_flag_iters_test.cc (72%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/benchmark_min_time_flag_time_test.cc (69%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/benchmark_name_gtest.cc (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/benchmark_random_interleaving_gtest.cc (95%) create mode 100644 vendor/benchmark-4ed29ae/test/benchmark_setup_teardown_cb_types_gtest.cc rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/benchmark_setup_teardown_test.cc (88%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/benchmark_test.cc (83%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/clobber_memory_assembly_test.cc (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/commandlineflags_gtest.cc (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/complexity_test.cc (84%) create mode 100644 vendor/benchmark-4ed29ae/test/cxx11_test.cc rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/diagnostics_test.cc (74%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/display_aggregates_only_test.cc (95%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/donotoptimize_assembly_test.cc (97%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/donotoptimize_test.cc (90%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/filter_test.cc (85%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/fixture_test.cc (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/internal_threading_test.cc (95%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/link_main_test.cc (51%) create mode 100644 vendor/benchmark-4ed29ae/test/locale_impermeability_test.cc create mode 100644 vendor/benchmark-4ed29ae/test/manual_threading_test.cc rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/map_test.cc (91%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/memory_manager_test.cc (88%) create mode 100644 vendor/benchmark-4ed29ae/test/memory_results_gtest.cc rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/min_time_parse_gtest.cc (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/multiple_ranges_test.cc (97%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/options_test.cc (96%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/output_test.h (95%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/output_test_helper.cc (90%) create mode 100644 vendor/benchmark-4ed29ae/test/overload_test.cc rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/perf_counters_gtest.cc (99%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/perf_counters_test.cc (90%) create mode 100644 vendor/benchmark-4ed29ae/test/profiler_manager_gtest.cc create mode 100644 vendor/benchmark-4ed29ae/test/profiler_manager_iterations_test.cc create mode 100644 vendor/benchmark-4ed29ae/test/profiler_manager_test.cc rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/register_benchmark_test.cc (92%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/repetitions_test.cc (97%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/report_aggregates_only_test.cc (94%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/reporter_output_test.cc (98%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/skip_with_error_test.cc (89%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/spec_arg_test.cc (95%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/spec_arg_verbosity_test.cc (88%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/state_assembly_test.cc (96%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/statistics_gtest.cc (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/string_util_gtest.cc (58%) create mode 100644 vendor/benchmark-4ed29ae/test/templated_fixture_method_test.cc rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/templated_fixture_test.cc (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/time_unit_gtest.cc (89%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/user_counters_tabular_test.cc (98%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/user_counters_test.cc (94%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/test/user_counters_thousands_test.cc (97%) create mode 100644 vendor/benchmark-4ed29ae/test/user_counters_threads_test.cc rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/BUILD.bazel (84%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/compare.py (92%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/gbench/Inputs/test1_run1.json (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/gbench/Inputs/test1_run2.json (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/gbench/Inputs/test2_run.json (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/gbench/Inputs/test3_run0.json (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/gbench/Inputs/test3_run1.json (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/gbench/Inputs/test4_run.json (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/gbench/Inputs/test4_run0.json (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/gbench/Inputs/test4_run1.json (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/gbench/Inputs/test5_run0.json (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/gbench/Inputs/test5_run1.json (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/gbench/__init__.py (100%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/gbench/report.py (94%) rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/gbench/util.py (84%) create mode 100644 vendor/benchmark-4ed29ae/tools/libpfm.BUILD.bazel create mode 100644 vendor/benchmark-4ed29ae/tools/requirements.txt rename vendor/{benchmark-38df9da => benchmark-4ed29ae}/tools/strip_asm.py (94%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/.clang-format (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/.github/ISSUE_TEMPLATE/00-bug_report.yml (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/.github/ISSUE_TEMPLATE/10-feature_request.yml (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/.github/ISSUE_TEMPLATE/config.yml (100%) create mode 100644 vendor/googletest-56efe39/.gitignore rename vendor/{googletest-b4aaf97 => googletest-56efe39}/BUILD.bazel (85%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/CMakeLists.txt (93%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/CONTRIBUTING.md (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/CONTRIBUTORS (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/LICENSE (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/MODULE.bazel (66%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/README.md (85%) create mode 100644 vendor/googletest-56efe39/WORKSPACE rename vendor/{googletest-b4aaf97 => googletest-56efe39}/WORKSPACE.bzlmod (100%) create mode 100644 vendor/googletest-56efe39/ci/linux-presubmit.sh rename vendor/{googletest-b4aaf97 => googletest-56efe39}/ci/macos-presubmit.sh (79%) create mode 100644 vendor/googletest-56efe39/ci/windows-presubmit.bat rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/_config.yml (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/_data/navigation.yml (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/_layouts/default.html (81%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/_sass/main.scss (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/advanced.md (96%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/assets/css/style.scss (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/community_created_documentation.md (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/faq.md (97%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/gmock_cheat_sheet.md (98%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/gmock_cook_book.md (97%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/gmock_faq.md (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/gmock_for_dummies.md (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/index.md (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/pkgconfig.md (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/platforms.md (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/primer.md (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/quickstart-bazel.md (65%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/quickstart-cmake.md (97%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/reference/actions.md (96%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/reference/assertions.md (97%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/reference/matchers.md (90%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/reference/mocking.md (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/reference/testing.md (91%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/docs/samples.md (100%) create mode 100644 vendor/googletest-56efe39/fake_fuchsia_sdk.bzl rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/CMakeLists.txt (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/README.md (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/cmake/gmock.pc.in (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/cmake/gmock_main.pc.in (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/docs/README.md (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/gmock-actions.h (93%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/gmock-cardinalities.h (98%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/gmock-function-mocker.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/gmock-matchers.h (90%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/gmock-more-actions.h (98%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/gmock-more-matchers.h (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/gmock-nice-strict.h (96%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/gmock-spec-builders.h (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/gmock.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/internal/custom/README.md (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/internal/custom/gmock-generated-actions.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/internal/custom/gmock-matchers.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/internal/custom/gmock-port.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/internal/gmock-internal-utils.h (97%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/internal/gmock-port.h (96%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/include/gmock/internal/gmock-pp.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/src/gmock-all.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/src/gmock-cardinalities.cc (96%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/src/gmock-internal-utils.cc (98%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/src/gmock-matchers.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/src/gmock-spec-builders.cc (97%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/src/gmock.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/src/gmock_main.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/BUILD.bazel (98%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-actions_test.cc (96%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-cardinalities_test.cc (98%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-function-mocker_test.cc (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-internal-utils_test.cc (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-matchers-arithmetic_test.cc (87%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-matchers-comparisons_test.cc (92%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-matchers-containers_test.cc (90%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-matchers-misc_test.cc (95%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-matchers_test.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-more-actions_test.cc (95%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-nice-strict_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-port_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-pp-string_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-pp_test.cc (98%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock-spec-builders_test.cc (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock_all_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock_ex_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock_leak_test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock_leak_test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock_link2_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock_link_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock_link_test.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock_output_test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock_output_test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock_output_test_golden.txt (93%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock_stress_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googlemock/test/gmock_test_utils.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/CMakeLists.txt (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/README.md (96%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/cmake/Config.cmake.in (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/cmake/gtest.pc.in (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/cmake/gtest_main.pc.in (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/cmake/internal_utils.cmake (96%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/cmake/libgtest.la.in (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/docs/README.md (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/gtest-assertion-result.h (97%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/gtest-death-test.h (98%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/gtest-matchers.h (91%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/gtest-message.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/gtest-param-test.h (85%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/gtest-printers.h (89%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/gtest-spi.h (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/gtest-test-part.h (96%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/gtest-typed-test.h (74%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/gtest.h (98%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/gtest_pred_impl.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/gtest_prod.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/internal/custom/README.md (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/internal/custom/gtest-port.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/internal/custom/gtest-printers.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/internal/custom/gtest.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/internal/gtest-death-test-internal.h (97%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/internal/gtest-filepath.h (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/internal/gtest-internal.h (95%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/internal/gtest-param-util.h (91%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/internal/gtest-port-arch.h (98%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/internal/gtest-port.h (90%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/internal/gtest-string.h (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/include/gtest/internal/gtest-type-util.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/prime_tables.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample1.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample1.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample10_unittest.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample1_unittest.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample2.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample2.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample2_unittest.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample3-inl.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample3_unittest.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample4.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample4.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample4_unittest.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample5_unittest.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample6_unittest.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample7_unittest.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample8_unittest.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/samples/sample9_unittest.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/src/gtest-all.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/src/gtest-assertion-result.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/src/gtest-death-test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/src/gtest-filepath.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/src/gtest-internal-inl.h (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/src/gtest-matchers.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/src/gtest-port.cc (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/src/gtest-printers.cc (96%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/src/gtest-test-part.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/src/gtest-typed-test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/src/gtest.cc (96%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/src/gtest_main.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/BUILD.bazel (92%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-break-on-failure-unittest.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-break-on-failure-unittest_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-catch-exceptions-test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-catch-exceptions-test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-color-test.py (98%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-color-test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-death-test-test.cc (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-death-test_ex_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-env-var-test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-env-var-test_.cc (100%) create mode 100644 vendor/googletest-56efe39/googletest/test/googletest-fail-if-no-test-linked-test-with-disabled-test_.cc create mode 100644 vendor/googletest-56efe39/googletest/test/googletest-fail-if-no-test-linked-test-with-enabled-test_.cc create mode 100755 vendor/googletest-56efe39/googletest/test/googletest-fail-if-no-test-linked-test.py create mode 100644 vendor/googletest-56efe39/googletest/test/googletest-fail-if-no-test-selected-test.py rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-failfast-unittest.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-failfast-unittest_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-filepath-test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-filter-unittest.py (96%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-filter-unittest_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-global-environment-unittest.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-global-environment-unittest_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-json-outfiles-test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-json-output-unittest.py (89%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-list-tests-unittest.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-list-tests-unittest_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-listener-test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-message-test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-options-test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-output-test-golden-lin.txt (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-output-test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-output-test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-param-test-invalid-name1-test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-param-test-invalid-name1-test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-param-test-invalid-name2-test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-param-test-invalid-name2-test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-param-test-test.cc (94%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-param-test-test.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-param-test2-test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-port-test.cc (99%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-printers-test.cc (94%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-setuptestsuite-test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-setuptestsuite-test_.cc (92%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-shuffle-test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-shuffle-test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-test-part-test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-throw-on-failure-test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-throw-on-failure-test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-uninitialized-test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/googletest-uninitialized-test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest-typed-test2_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest-typed-test_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest-typed-test_test.h (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest-unittest-api_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_all_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_assert_by_exception_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_dirs_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_environment_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_help_test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_help_test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_json_test_utils.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_list_output_unittest.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_list_output_unittest_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_main_unittest.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_no_test_unittest.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_pred_impl_unittest.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_premature_exit_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_prod_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_repeat_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_skip_check_output_test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_skip_environment_check_output_test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_skip_in_environment_setup_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_skip_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_sole_header_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_stress_test.cc (98%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_test_macro_stack_footprint_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_test_utils.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_testbridge_test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_testbridge_test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_throw_on_failure_ex_test.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_unittest.cc (98%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_xml_outfile1_test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_xml_outfile2_test_.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_xml_outfiles_test.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_xml_output_unittest.py (84%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_xml_output_unittest_.cc (90%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/gtest_xml_test_utils.py (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/production.cc (100%) rename vendor/{googletest-b4aaf97 => googletest-56efe39}/googletest/test/production.h (100%) create mode 100644 vendor/googletest-56efe39/googletest_deps.bzl delete mode 100644 vendor/googletest-b4aaf97/WORKSPACE delete mode 100644 vendor/googletest-b4aaf97/ci/linux-presubmit.sh delete mode 100644 vendor/googletest-b4aaf97/ci/windows-presubmit.bat delete mode 100644 vendor/googletest-b4aaf97/fake_fuchsia_sdk.bzl delete mode 100644 vendor/googletest-b4aaf97/googletest_deps.bzl delete mode 100644 vendor/netcdf-c-4.9.2/CMakeLists.txt delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_anon_dim.2.syn.d4d delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_anon_dim.2.syn.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_anon_dim.2.syn.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_anon_dim.syn.d4d delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_anon_dim.syn.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_anon_dim.syn.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_atomic_array.5.nc.d4d delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_atomic_array.5.nc.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_atomic_array.5.nc.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_atomic_array.8.nc.d4d delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_atomic_array.8.nc.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_atomic_array.8.nc.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_atomic_array.9.nc.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_atomic_array.9.nc.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_atomic_array.syn.d4d delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_atomic_types.syn.d4d delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_atomic_types.syn.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_atomic_types.syn.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_enum_array.4.nc.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_one_vararray.1.nc.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_one_vararray.1.nc.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_one_vararray.3.nc.d4d delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_one_vararray.3.nc.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_one_vararray.3.nc.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_opaque.nc.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_opaque_array.7.nc.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_opaque_array.7.nc.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_sequence_1.syn.d4d delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_sequence_1.syn.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_sequence_1.syn.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_sequence_2.syn.d4d delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_sequence_2.syn.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_sequence_2.syn.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_struct_array.6.nc.d4d delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_struct_array.6.nc.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_struct_array.6.nc.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_struct_array.syn.d4d delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_struct_array.syn.d4m delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baseline/test_struct_array.syn.d4p delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselinehyrax/amsre_20060131v5.dat.hyrax delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineraw/test_anon_dim.2.syn.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineraw/test_anon_dim.syn.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineraw/test_atomic_array.9.nc.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineraw/test_atomic_array.syn.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineraw/test_atomic_types.syn.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineraw/test_enum_array.4.nc.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineraw/test_fillmismatch.nc.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineraw/test_one_vararray.1.nc.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineraw/test_opaque_array.7.nc.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineraw/test_sequence_1.syn.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineraw/test_sequence_2.syn.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineraw/test_struct_array.syn.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_anon_dim.syn.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_atomic_array.syn.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_atomic_types.syn.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_sequence_1.syn.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_sequence_2.syn.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_struct_array.syn.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_struct_nested.nc.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_struct_nested3.nc.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen10.nc.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen11.nc.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen3.hdf5.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen4.nc.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen5.hdf5.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen9.nc.dmp delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/baselinethredds/GOES16_TEST1.nc4.thredds delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/cdltestfiles/test_atomic_array.cdl delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/cdltestfiles/test_fill.cdl delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/cdltestfiles/test_vlen3.cdl delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/cdltestfiles/test_vlen5.cdl delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/daptestfiles/CMakeLists.txt delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/daptestfiles/test_anon_dim.syn.dap delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/daptestfiles/test_atomic_types.syn.dap delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/daptestfiles/test_one_vararray.nc.dap delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/daptestfiles/test_opaque.nc.dap delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/daptestfiles/test_sequence_1.syn.dap delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/daptestfiles/test_sequence_2.syn.dap delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/daptestfiles/test_struct_array.syn.dap delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/dmrtestfiles/CMakeLists.txt delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_anon_dim.syn.dmr delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_atomic_types.syn.dmr delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_sequence_1.syn.dmr delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_sequence_2.syn.dmr delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_struct_array.syn.dmr delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/misctestfiles/CMakeLists.txt delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/misctestfiles/fnoc1.dap delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/misctestfiles/test_fillmismatch.nc.dap delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_atomic_array.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_atomic_types.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_enum.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_enum_2.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_enum_array.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_fill.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_groups1.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_one_var.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_one_vararray.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_opaque.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_opaque_array.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_struct1.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_struct_array.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_struct_nested.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_struct_nested3.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_struct_type.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_unlim1.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_utf8.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_vlen1.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_vlen2.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_vlen3.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_vlen4.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_vlen5.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_vlen6.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_vlen7.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/nctestfiles/test_vlen8.nc delete mode 100644 vendor/netcdf-c-4.9.2/dap4_test/test_data.c delete mode 100755 vendor/netcdf-c-4.9.2/dap4_test/test_fillmismatch.sh delete mode 100755 vendor/netcdf-c-4.9.2/dap4_test/test_hyrax.sh delete mode 100755 vendor/netcdf-c-4.9.2/dap4_test/test_meta.sh delete mode 100755 vendor/netcdf-c-4.9.2/dap4_test/test_remote.sh delete mode 100755 vendor/netcdf-c-4.9.2/dap4_test/test_thredds.sh delete mode 100644 vendor/netcdf-c-4.9.2/docs/footer.html delete mode 100644 vendor/netcdf-c-4.9.2/docs/internal.dox delete mode 100644 vendor/netcdf-c-4.9.2/include/Makefile.am delete mode 100644 vendor/netcdf-c-4.9.2/include/nc.h delete mode 100644 vendor/netcdf-c-4.9.2/include/nchttp.h delete mode 100644 vendor/netcdf-c-4.9.2/include/ncs3sdk.h delete mode 100644 vendor/netcdf-c-4.9.2/include/netcdf_aux.h delete mode 100644 vendor/netcdf-c-4.9.2/libdap4/CMakeLists.txt delete mode 100644 vendor/netcdf-c-4.9.2/libdap4/d4chunk.c delete mode 100644 vendor/netcdf-c-4.9.2/libdap4/d4varx.c delete mode 100644 vendor/netcdf-c-4.9.2/libdispatch/CMakeLists.txt delete mode 100644 vendor/netcdf-c-4.9.2/libdispatch/ddispatch.c delete mode 100644 vendor/netcdf-c-4.9.2/libdispatch/dhttp.c delete mode 100644 vendor/netcdf-c-4.9.2/libdispatch/dinstance.c delete mode 100644 vendor/netcdf-c-4.9.2/libdispatch/ds3util.c delete mode 100644 vendor/netcdf-c-4.9.2/libdispatch/utf8proc_data.c delete mode 100644 vendor/netcdf-c-4.9.2/libhdf5/CMakeLists.txt delete mode 100644 vendor/netcdf-c-4.9.2/liblib/CMakeLists.txt delete mode 100755 vendor/netcdf-c-4.9.2/libncpoco/CMakeLists.txt delete mode 100644 vendor/netcdf-c-4.9.2/libncxml/CMakeLists.txt delete mode 100644 vendor/netcdf-c-4.9.2/libsrc/CMakeLists.txt delete mode 100644 vendor/netcdf-c-4.9.2/nc-config.in delete mode 100644 vendor/netcdf-c-4.9.2/nc_test4/ref_fixedstring.cdl delete mode 100755 vendor/netcdf-c-4.9.2/nc_test4/ref_fixedstring.h5 delete mode 100644 vendor/netcdf-c-4.9.2/nc_test4/test_filter_vlen.c delete mode 100644 vendor/netcdf-c-4.9.2/nc_test4/tst_filter_avail.c delete mode 100644 vendor/netcdf-c-4.9.2/ncdump/CMakeLists.txt delete mode 100644 vendor/netcdf-c-4.9.2/ncdump/ref_pathcvt.txt delete mode 100755 vendor/netcdf-c-4.9.2/ncdump/testpathcvt.sh delete mode 100755 vendor/netcdf-c-4.9.2/ncdump/tst_mud.sh delete mode 100755 vendor/netcdf-c-4.9.2/ncdump/tst_nccopy5.sh delete mode 100644 vendor/netcdf-c-4.9.2/nczarr_test/CMakeLists.txt delete mode 100644 vendor/netcdf-c-4.9.2/nczarr_test/Makefile.am delete mode 100644 vendor/netcdf-c-4.9.2/nczarr_test/ref_byte_fill_value_null.zarr.zip delete mode 100644 vendor/netcdf-c-4.9.2/nczarr_test/ref_jsonconvention.zmap delete mode 100644 vendor/netcdf-c-4.9.2/nczarr_test/ref_misc1.dmp delete mode 100644 vendor/netcdf-c-4.9.2/nczarr_test/ref_oldformat.zip delete mode 100644 vendor/netcdf-c-4.9.2/nczarr_test/ref_rem.dmp delete mode 100644 vendor/netcdf-c-4.9.2/nczarr_test/ref_ut_map_create.cdl delete mode 100644 vendor/netcdf-c-4.9.2/nczarr_test/ref_ut_mapapi_create.cdl delete mode 100755 vendor/netcdf-c-4.9.2/nczarr_test/run_interop.sh delete mode 100755 vendor/netcdf-c-4.9.2/nczarr_test/run_jsonconvention.sh delete mode 100755 vendor/netcdf-c-4.9.2/nczarr_test/run_nczfilter.sh delete mode 100755 vendor/netcdf-c-4.9.2/nczarr_test/run_s3_cleanup.sh delete mode 100755 vendor/netcdf-c-4.9.2/nczarr_test/run_ut_chunk.sh delete mode 100755 vendor/netcdf-c-4.9.2/nczarr_test/ut_chunking.c delete mode 100644 vendor/netcdf-c-4.9.2/nczarr_test/ut_projections.c delete mode 100644 vendor/netcdf-c-4.9.2/oc2/dapy.h delete mode 100644 vendor/netcdf-c-4.9.2/plugins/CMakeLists.txt delete mode 100644 vendor/netcdf-c-4.9.2/plugins/h5misc.h delete mode 100644 vendor/netcdf-c-4.9.2/postinstall.sh.in delete mode 100644 vendor/netcdf-c-4.9.2/unit_test/CMakeLists.txt delete mode 100755 vendor/netcdf-c-4.9.2/unit_test/run_aws.sh delete mode 100644 vendor/netcdf-c-4.9.2/unit_test/test_aws.c delete mode 100644 vendor/netcdf-c-4.9.2/unit_test/test_ncuri.c create mode 100644 vendor/netcdf-c-4.9.3/CITATION.cff rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/CMakeInstallation.cmake (61%) create mode 100644 vendor/netcdf-c-4.9.3/CMakeLists.txt rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/COMPILE.cmake.txt (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/COPYRIGHT (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/CTestConfig.cmake.in (100%) rename vendor/{netcdf-c-4.9.2/CTestCustom.cmake => netcdf-c-4.9.3/CTestCustom.cmake.in} (74%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/FixBundle.cmake.in (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/INSTALL.md (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/Makefile.am (82%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/Makefile.in (86%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/README.md (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/RELEASE_NOTES.md (79%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/acinclude.m4 (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/aclocal.m4 (78%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/cmake/ConfigUser.cmake (100%) create mode 100644 vendor/netcdf-c-4.9.3/cmake/check_hdf5.cmake create mode 100644 vendor/netcdf-c-4.9.3/cmake/dependencies.cmake create mode 100644 vendor/netcdf-c-4.9.3/cmake/deprecated.cmake rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/cmake/modules/FindBlosc.cmake (90%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/cmake/modules/FindBz2.cmake (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/cmake/modules/FindBzip2.cmake (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/cmake/modules/FindHDF4.cmake (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/cmake/modules/FindMakeDist.cmake (100%) create mode 100644 vendor/netcdf-c-4.9.3/cmake/modules/FindPNETCDF.cmake rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/cmake/modules/FindSzip.cmake (77%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/cmake/modules/FindXDR.cmake (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/cmake/modules/FindZLIB.cmake (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/cmake/modules/FindZip.cmake (100%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/cmake/modules/FindZstd.cmake (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/cmake/modules/windows/FindHDF5.cmake (100%) create mode 100644 vendor/netcdf-c-4.9.3/cmake/netcdf_functions_macros.cmake rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/cmake_uninstall.cmake.in (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/compile (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/config.guess (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/config.h.cmake.in (84%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/config.h.in (61%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/config.sub (88%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/configure (83%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/configure.ac (68%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/CMakeLists.txt (57%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/Makefile.am (61%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/Makefile.in (85%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/CMakeLists.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_atomic_array.nc.d4d (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_atomic_array.nc.d4m (91%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_atomic_array.nc.d4p (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_atomic_types.nc.d4d (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_atomic_types.nc.d4m (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_atomic_types.nc.d4p (84%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_enum.nc.dmp => netcdf-c-4.9.3/dap4_test/baseline/test_enum_1.nc.d4d} (94%) rename vendor/{netcdf-c-4.9.2/dap4_test/baseline/test_enum.nc.d4m => netcdf-c-4.9.3/dap4_test/baseline/test_enum_1.nc.d4m} (94%) rename vendor/{netcdf-c-4.9.2/dap4_test/baseline/test_enum.nc.d4p => netcdf-c-4.9.3/dap4_test/baseline/test_enum_1.nc.d4p} (83%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_enum_2.nc.d4d (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_enum_2.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_enum_2.nc.d4p (86%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_enum_3.nc.d4d create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_enum_3.nc.d4m create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_enum_3.nc.d4p rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_enum_array.nc.d4d (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_enum_array.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_enum_array.nc.d4p (86%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_fill.nc.dmp => netcdf-c-4.9.3/dap4_test/baseline/test_fill.nc.d4d} (73%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_fill.nc.d4m (58%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_fill.nc.d4p (64%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_fill_2.nc.d4d rename vendor/{netcdf-c-4.9.2/dap4_test/baseline/test_enum_array.4.nc.d4m => netcdf-c-4.9.3/dap4_test/baseline/test_fill_2.nc.d4m} (52%) rename vendor/{netcdf-c-4.9.2/dap4_test/baseline/test_atomic_array.syn.d4p => netcdf-c-4.9.3/dap4_test/baseline/test_fill_2.nc.d4p} (63%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_groups1.nc.d4d (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_groups1.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_groups1.nc.d4p (90%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_misc1.nc.d4d create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_misc1.nc.d4m create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_misc1.nc.d4p rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_one_var.nc.dmp => netcdf-c-4.9.3/dap4_test/baseline/test_one_var.nc.d4d} (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_one_var.nc.d4m (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_one_var.nc.d4p (71%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_one_vararray.nc.dmp => netcdf-c-4.9.3/dap4_test/baseline/test_one_vararray.nc.d4d} (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_one_vararray.nc.d4m (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_one_vararray.nc.d4p (76%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_opaque.nc.d4d (82%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_opaque.nc.d4m rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_opaque.nc.d4p (63%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_opaque_array.nc.d4d (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_opaque_array.nc.d4m (57%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_opaque_array.nc.d4p (71%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct1.nc.d4d (80%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct1.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct1.nc.d4p (77%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct_array.nc.d4d (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct_array.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct_array.nc.d4p (82%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct_nested.nc.d4d (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct_nested.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct_nested.nc.d4p (84%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct_nested3.nc.d4d (88%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct_nested3.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct_nested3.nc.d4p (82%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct_type.nc.d4d (77%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct_type.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_struct_type.nc.d4p (77%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_test.nc.d4d create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_test.nc.d4m create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_test.nc.d4p create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_unlim.nc.d4d create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_unlim.nc.d4m create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_unlim.nc.d4p rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_unlim1.nc.d4d (88%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_unlim1.nc.d4m (83%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_unlim1.nc.d4p (79%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_utf8.nc.d4d (79%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_utf8.nc.d4m (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_utf8.nc.d4p (76%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen1.nc.d4d (84%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen1.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen1.nc.d4p (61%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_vlen11.nc.d4d create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_vlen11.nc.d4m create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_vlen11.nc.d4p rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen2.nc.d4d (91%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen2.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen2.nc.d4p (73%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen3.nc.d4d (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen3.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen3.nc.d4p (80%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen4.nc.d4d (83%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen4.nc.d4m (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen4.nc.d4p (73%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen5.nc.d4d (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen5.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen5.nc.d4p (83%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen6.nc.d4d (88%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen6.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen6.nc.d4p (71%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen7.nc.d4d (87%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen7.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen7.nc.d4p (71%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen8.nc.d4d (91%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen8.nc.d4m (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baseline/test_vlen8.nc.d4p (73%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_zerodim.nc.d4d create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_zerodim.nc.d4m create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baseline/test_zerodim.nc.d4p rename vendor/{netcdf-c-4.9.2/dap4_test/baselinethredds => netcdf-c-4.9.3/dap4_test/baselinehyrax}/CMakeLists.txt (100%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselinehyrax/amsre_20060131v5.dat.hyrax rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baselinehyrax/nc4_nc_classic_comp.nc.hyrax (95%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselinehyrax/nc4_nc_classic_no_comp.nc.hyrax create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselinehyrax/nc4_strings.nc.hyrax rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baselinehyrax/nc4_strings_comp.nc.hyrax (100%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote => netcdf-c-4.9.3/dap4_test/baselinehyrax}/nc4_unsigned_types.nc.hyrax (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baselinehyrax/nc4_unsigned_types_comp.nc.hyrax (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/baselinehyrax/ref_tst_compounds.nc.hyrax (67%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselinehyrax => netcdf-c-4.9.3/dap4_test/baselineraw}/CMakeLists.txt (100%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_atomic_array.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_atomic_array.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_atomic_types.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_atomic_types.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baseline/test_enum.nc.d4d => netcdf-c-4.9.3/dap4_test/baselineraw/test_enum_1.nc.ncdump} (94%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_enum_2.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_enum_2.nc.ncdump} (99%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineraw/test_enum_3.nc.ncdump rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_enum_array.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_enum_array.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baseline/test_fill.nc.d4d => netcdf-c-4.9.3/dap4_test/baselineraw/test_fill.nc.ncdump} (60%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineraw/test_fill_2.nc.ncdump rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_groups1.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_groups1.nc.ncdump} (99%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineraw/test_misc1.nc.ncdump rename vendor/{netcdf-c-4.9.2/dap4_test/baseline/test_one_var.nc.d4d => netcdf-c-4.9.3/dap4_test/baselineraw/test_one_var.nc.ncdump} (60%) rename vendor/{netcdf-c-4.9.2/dap4_test/baseline/test_one_vararray.nc.d4d => netcdf-c-4.9.3/dap4_test/baselineraw/test_one_vararray.nc.ncdump} (69%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_opaque.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_opaque.nc.ncdump} (71%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_opaque_array.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_opaque_array.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_struct1.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_struct1.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_struct_array.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_struct_array.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_struct_nested.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_struct_nested.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_struct_nested3.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_struct_nested3.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_struct_type.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_struct_type.nc.ncdump} (99%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineraw/test_test.nc.ncdump create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineraw/test_unlim.nc.ncdump rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_unlim1.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_unlim1.nc.ncdump} (91%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_utf8.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_utf8.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_vlen1.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_vlen1.nc.ncdump} (99%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineraw/test_vlen11.nc.ncdump rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_vlen2.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_vlen2.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_vlen3.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_vlen3.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_vlen4.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_vlen4.nc.ncdump} (91%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_vlen5.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_vlen5.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_vlen6.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_vlen6.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_vlen7.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_vlen7.nc.ncdump} (99%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_vlen8.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineraw/test_vlen8.nc.ncdump} (99%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineraw/test_zerodim.nc.ncdump rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw => netcdf-c-4.9.3/dap4_test/baselineremote}/CMakeLists.txt (100%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_atomic_array.5.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_atomic_array.1.nc.ncdump} (50%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_atomic_array.8.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_atomic_array.2.nc.ncdump} (57%) rename vendor/{netcdf-c-4.9.2/dap4_test/baseline/test_atomic_array.9.nc.d4d => netcdf-c-4.9.3/dap4_test/baselineremote/test_atomic_array.3.nc.ncdump} (57%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_atomic_array.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_atomic_array.nc.ncdump} (94%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_atomic_types.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_atomic_types.nc.ncdump} (94%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_enum.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_enum_1.nc.ncdump} (83%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_enum_2.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_enum_2.nc.ncdump} (88%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineremote/test_enum_3.nc.ncdump rename vendor/{netcdf-c-4.9.2/dap4_test/baseline/test_enum_array.4.nc.d4d => netcdf-c-4.9.3/dap4_test/baselineremote/test_enum_array.6.nc.ncdump} (81%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_enum_array.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_enum_array.nc.ncdump} (89%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_fill.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_fill.nc.ncdump} (54%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineremote/test_fill_2.nc.ncdump rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_groups1.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_groups1.nc.ncdump} (90%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineremote/test_misc1.nc.ncdump rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_one_var.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_one_var.nc.ncdump} (53%) rename vendor/{netcdf-c-4.9.2/dap4_test/baseline/test_one_vararray.1.nc.d4d => netcdf-c-4.9.3/dap4_test/baselineremote/test_one_vararray.4.nc.ncdump} (55%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_one_vararray.3.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_one_vararray.5.nc.ncdump} (56%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_one_vararray.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_one_vararray.nc.ncdump} (64%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_opaque.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_opaque.nc.ncdump} (67%) rename vendor/{netcdf-c-4.9.2/dap4_test/baseline/test_opaque_array.7.nc.d4d => netcdf-c-4.9.3/dap4_test/baselineremote/test_opaque_array.7.nc.ncdump} (61%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_opaque_array.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_opaque_array.nc.ncdump} (84%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_struct1.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_struct1.nc.ncdump} (70%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineraw/test_struct_array.6.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_struct_array.8.nc.ncdump} (67%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_struct_array.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_struct_array.nc.ncdump} (84%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_struct_nested.hdf5.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_struct_nested.nc.ncdump} (84%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_struct_nested3.hdf5.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_struct_nested3.nc.ncdump} (83%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_struct_type.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_struct_type.nc.ncdump} (70%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineremote/test_test.nc.ncdump create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineremote/test_unlim.nc.ncdump create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineremote/test_unlim1.nc.ncdump rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_utf8.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_utf8.nc.ncdump} (67%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen1.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_vlen1.nc.ncdump} (66%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineremote/test_vlen11.nc.ncdump rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen2.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_vlen2.nc.ncdump} (79%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen3.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_vlen3.nc.ncdump} (75%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen4.hdf5.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_vlen4.nc.ncdump} (72%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen5.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_vlen5.nc.ncdump} (78%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen6.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_vlen6.nc.ncdump} (73%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen7.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_vlen7.nc.ncdump} (71%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_vlen8.nc.dmp => netcdf-c-4.9.3/dap4_test/baselineremote/test_vlen8.nc.ncdump} (78%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselineremote/test_zerodim.nc.ncdump create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselinethredds/2004050300_eta_211.nc.thredds create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselinethredds/CMakeLists.txt create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/baselinethredds/H.1.1.nc.thredds create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/build.sh rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote => netcdf-c-4.9.3/dap4_test/cdltestfiles}/CMakeLists.txt (100%) rename vendor/{netcdf-c-4.9.2/dap4_test/baseline/test_atomic_array.syn.d4m => netcdf-c-4.9.3/dap4_test/cdltestfiles/test_atomic_array.cdl} (62%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_atomic_types.cdl (100%) rename vendor/{netcdf-c-4.9.2/dap4_test/cdltestfiles/test_enum.cdl => netcdf-c-4.9.3/dap4_test/cdltestfiles/test_enum_1.cdl} (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_enum_2.cdl (100%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/cdltestfiles/test_enum_3.cdl rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_enum_array.cdl (100%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/tst_fills.nc.dmp => netcdf-c-4.9.3/dap4_test/cdltestfiles/test_fill.cdl} (73%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_groups1.cdl (100%) rename vendor/{netcdf-c-4.9.2/dap4_test/baselineremote/test_misc1.nc.dmp => netcdf-c-4.9.3/dap4_test/cdltestfiles/test_misc1.cdl} (61%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_one_var.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_one_vararray.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_opaque.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_opaque_array.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_struct1.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_struct_array.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_struct_nested.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_struct_nested3.cdl (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_struct_type.cdl (100%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/cdltestfiles/test_test.cdl create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/cdltestfiles/test_unlim.cdl rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_unlim1.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_utf8.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_vlen1.cdl (100%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/cdltestfiles/test_vlen10.cdl create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/cdltestfiles/test_vlen11.cdl rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_vlen2.cdl (100%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/cdltestfiles/test_vlen3.cdl rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_vlen4.cdl (100%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/cdltestfiles/test_vlen5.cdl rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_vlen6.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_vlen7.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/cdltestfiles/test_vlen8.cdl (100%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/cdltestfiles/test_vlen9.cdl create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/cdltestfiles/test_zerodim.cdl create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/d4manifest.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/d4test_common.sh (63%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/dump.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/findtestserver4.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/pingurl4.c (85%) rename vendor/{netcdf-c-4.9.2/dap4_test/cdltestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/CMakeLists.txt (100%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles/test_atomic_array.5.nc.dap => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_atomic_array.1.nc.dap} (73%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_atomic_array.5.nc.dmr => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_atomic_array.1.nc.dmr} (83%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles/test_atomic_array.8.nc.dap => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_atomic_array.2.nc.dap} (69%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_atomic_array.8.nc.dmr => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_atomic_array.2.nc.dmr} (79%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles/test_atomic_array.9.nc.dap => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_atomic_array.3.nc.dap} (69%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_atomic_array.9.nc.dmr => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_atomic_array.3.nc.dmr} (79%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_atomic_array.nc.dap (77%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_atomic_array.nc.dmr (89%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_atomic_types.nc.dap (78%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_atomic_types.nc.dmr (85%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles/test_enum.nc.dap => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_enum_1.nc.dap} (78%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_enum.nc.dmr => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_enum_1.nc.dmr} (83%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_enum_2.nc.dap (81%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_enum_2.nc.dmr (85%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/rawtestfiles/test_enum_3.nc.dap create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/rawtestfiles/test_enum_3.nc.dmr rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles/test_enum_array.4.nc.dap => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_enum_array.6.nc.dap} (82%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_enum_array.4.nc.dmr => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_enum_array.6.nc.dmr} (87%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_enum_array.nc.dap (75%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_enum_array.nc.dmr (86%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_fill.nc.dap (58%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_fill.nc.dmr (67%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles/test_atomic_array.syn.dap => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_fill_2.nc.dap} (54%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_atomic_array.syn.dmr => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_fill_2.nc.dmr} (63%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_groups1.nc.dap (77%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_groups1.nc.dmr (87%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/rawtestfiles/test_misc1.nc.dap create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/rawtestfiles/test_misc1.nc.dmr rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_one_var.nc.dap (62%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_one_var.nc.dmr (73%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles/test_one_vararray.1.nc.dap => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_one_vararray.4.nc.dap} (69%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_one_vararray.1.nc.dmr => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_one_vararray.4.nc.dmr} (78%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/rawtestfiles/test_one_vararray.5.nc.dap rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_one_vararray.3.nc.dmr => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_one_vararray.5.nc.dmr} (75%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles/test_one_vararray.3.nc.dap => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_one_vararray.nc.dap} (71%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_one_vararray.nc.dmr (77%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles/test_anon_dim.2.syn.dap => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_opaque.nc.dap} (63%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_opaque.nc.dmr (69%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_opaque_array.7.nc.dap (65%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_opaque_array.7.nc.dmr (76%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_opaque_array.nc.dap (52%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_opaque_array.nc.dmr (74%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_struct1.nc.dap (66%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_struct1.nc.dmr (76%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles/test_struct_array.6.nc.dap => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_struct_array.8.nc.dap} (70%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_struct_array.6.nc.dmr => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_struct_array.8.nc.dmr} (81%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_struct_array.nc.dap (60%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_struct_array.nc.dmr (80%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_struct_nested.nc.dap (73%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_struct_nested.nc.dmr (82%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_struct_nested3.nc.dap (71%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_struct_nested3.nc.dmr (80%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_struct_type.nc.dap (66%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_struct_type.nc.dmr (76%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/rawtestfiles/test_test.nc.dap create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/rawtestfiles/test_test.nc.dmr create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/rawtestfiles/test_unlim.nc.dap create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/rawtestfiles/test_unlim.nc.dmr rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_unlim1.nc.dap (73%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_unlim1.nc.dmr (79%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_utf8.nc.dap (63%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_utf8.nc.dmr (76%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen1.nc.dap (53%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen1.nc.dmr (64%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/rawtestfiles/test_vlen11.nc.dap rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles/test_anon_dim.2.syn.dmr => netcdf-c-4.9.3/dap4_test/rawtestfiles/test_vlen11.nc.dmr} (52%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen2.nc.dap (55%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen2.nc.dmr (69%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen3.nc.dap (66%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen3.nc.dmr (77%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen4.nc.dap (66%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen4.nc.dmr (78%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen5.nc.dap (67%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen5.nc.dmr (79%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen6.nc.dap (56%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen6.nc.dmr (67%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen7.nc.dap (57%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen7.nc.dmr (67%) rename vendor/{netcdf-c-4.9.2/dap4_test/daptestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen8.nc.dap (57%) rename vendor/{netcdf-c-4.9.2/dap4_test/dmrtestfiles => netcdf-c-4.9.3/dap4_test/rawtestfiles}/test_vlen8.nc.dmr (69%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/rawtestfiles/test_zerodim.nc.dap create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/rawtestfiles/test_zerodim.nc.dmr rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/test_common.h (88%) create mode 100755 vendor/netcdf-c-4.9.3/dap4_test/test_constraints.sh rename vendor/{netcdf-c-4.9.2/dap4_test/tst_curlopt.sh => netcdf-c-4.9.3/dap4_test/test_curlopt.sh} (100%) create mode 100755 vendor/netcdf-c-4.9.3/dap4_test/test_dap4url.sh create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/test_data.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/test_data.sh (69%) create mode 100644 vendor/netcdf-c-4.9.3/dap4_test/test_earthdata.sh create mode 100755 vendor/netcdf-c-4.9.3/dap4_test/test_hyrax.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/test_meta.c (91%) create mode 100755 vendor/netcdf-c-4.9.3/dap4_test/test_meta.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/test_parse.c (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/test_parse.sh (54%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/dap4_test/test_raw.sh (58%) create mode 100755 vendor/netcdf-c-4.9.3/dap4_test/test_remote.sh create mode 100755 vendor/netcdf-c-4.9.3/dap4_test/test_thredds.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/depcomp (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/CMakeLists.txt (85%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/COPYRIGHT.md (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/Doxyfile.in (76%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/DoxygenLayout.xml (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/FAQ.md (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/Makefile.am (76%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/Makefile.in (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/all-error-codes.md (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/architecture.dox (100%) create mode 100644 vendor/netcdf-c-4.9.3/docs/attribute_conventions.md rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/auth.md (80%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/building-with-cmake.md (76%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/byterange.md (79%) create mode 100644 vendor/netcdf-c-4.9.3/docs/cloud.md rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/credits.md (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/dispatch.md (82%) create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/.npmignore create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/Doxyfile rename vendor/{zpp-1.0.16/LICENSE.txt => netcdf-c-4.9.3/docs/doxygen-awesome-css/LICENSE} (85%) create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/README.md create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/docs/customization.md create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/docs/extensions.md create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/docs/img/darkmode_toggle.png create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/docs/img/fancy_scrollbars_firefox.png create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/docs/img/fancy_scrollbars_webkit.gif create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/docs/img/fragment_copy_button.png create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/docs/img/interactive_toc_mobile.png create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/docs/img/paragraph_link.png create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/docs/tricks.md create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/doxygen-awesome-fragment-copy-button.js create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/doxygen-awesome-interactive-toc.js create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/doxygen-awesome-paragraph-link.js create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/doxygen-awesome-sidebar-only.css create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/doxygen-awesome-tabs.js create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/doxygen-awesome.css create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/doxygen-custom/custom-alternative.css create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/doxygen-custom/custom.css create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/doxygen-custom/header.html create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/doxygen-custom/toggle-alternative-theme.js create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/img/screenshot.png create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/img/testimage.png create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/img/theme-variants-base.drawio.svg create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/img/theme-variants-sidebar-only.drawio.svg create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/include/MyLibrary/example.hpp create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/include/MyLibrary/subclass-example.hpp create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/logo.drawio.svg create mode 100644 vendor/netcdf-c-4.9.3/docs/doxygen-awesome-css/package.json create mode 100644 vendor/netcdf-c-4.9.3/docs/file_format_specifications.md rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/filters.md (88%) create mode 100644 vendor/netcdf-c-4.9.3/docs/footer.html rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/groups.dox (100%) create mode 100644 vendor/netcdf-c-4.9.3/docs/header.html rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/InstallTreeWindows.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/Makefile.in (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/aqua.jpg (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/chunking2.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/compatibility3.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/compression.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/deptree.jpg (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/groups.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/nc-classic-uml.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/nc4-model.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/ncatts.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/nccoords.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/ncfile.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/netcdf_architecture.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/pnetcdf.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/quantize_performance.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/quantize_pi.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/terra.jpg (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/images/uniLogo.png (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/indexing.dox (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/inmeminternal.dox (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/inmemory.md (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/install-fortran.md (99%) create mode 100644 vendor/netcdf-c-4.9.3/docs/internal.md rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/known_problems.md (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/mainpage.dox (77%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/nczarr.md (58%) create mode 100644 vendor/netcdf-c-4.9.3/docs/netcdf-50x50.png rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/netcdf.m4 (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/notes.md (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/obsolete/fan_utils.html (100%) create mode 100644 vendor/netcdf-c-4.9.3/docs/pluginpath.md rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/quantize.md (100%) create mode 100644 vendor/netcdf-c-4.9.3/docs/quickstart_env.md create mode 100644 vendor/netcdf-c-4.9.3/docs/quickstart_filters.md create mode 100644 vendor/netcdf-c-4.9.3/docs/quickstart_paths.md rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/testserver.dox (100%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/tutorial.dox (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/docs/windows-binaries.md (69%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/CMakeLists.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/Makefile.am (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/Makefile.in (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/filter_example.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/format.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/parallel_vara.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/pres_temp_4D_rd.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/pres_temp_4D_wr.c (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/quick_large_files.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/quick_small_files.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/run_examples.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/run_examples4.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/run_filter.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/run_par_test.sh.in (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/sfc_pres_temp_more.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/sfc_pres_temp_rd.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/sfc_pres_temp_wr.c (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/simple.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/simple_nc4_rd.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/simple_nc4_wr.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/simple_xy_nc4_rd.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/simple_xy_nc4_wr.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/simple_xy_rd.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/C/simple_xy_wr.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/CDL/CMakeLists.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/CDL/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/CDL/Makefile.in (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/CDL/do_comps.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/CDL/pres_temp_4D.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/CDL/sfc_pres_temp.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/CDL/simple_xy.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/CMakeLists.txt (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/Makefile.am (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/examples/Makefile.in (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/fuzz/CMakeLists.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/fuzz/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/fuzz/fuzz_open.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/CMakeLists.txt (73%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/Makefile.am (63%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/Makefile.in (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/h5_err_macros.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/ref_tst_compounds.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/ref_tst_h_compounds.h5 (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/ref_tst_h_compounds2.h5 (100%) create mode 100755 vendor/netcdf-c-4.9.3/h5_test/run_h5_zstd_tests.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/run_par_tests.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/run_par_tests.sh.in (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_atts.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_atts3.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_atts4.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_compounds.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_compounds2.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_dimscales.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_dimscales1.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_dimscales2.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_dimscales3.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_dimscales4.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_enums.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_files.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_files2.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_files4.c (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_grps.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_ints.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_mem.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_opaques.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_par.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_par_compress.c (80%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_rename.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_strings.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_strings1.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_strings2.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_vars.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_vars2.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_vars3.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_vl.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/h5_test/tst_h_wrt_cmp.c (100%) create mode 100644 vendor/netcdf-c-4.9.3/h5_test/tst_h_zstd.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/hdf4_test/CMakeLists.txt (67%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/hdf4_test/Makefile.am (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/hdf4_test/Makefile.in (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/hdf4_test/ref_chunked.hdf4 (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/hdf4_test/ref_contiguous.hdf4 (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/hdf4_test/run_formatx_hdf4.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/hdf4_test/run_get_hdf4_files.sh (68%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/hdf4_test/tst_chunk_hdf4.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/hdf4_test/tst_h4_lendian.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/hdf4_test/tst_hdf4_extra.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/hdf4_test/tst_interops2.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/hdf4_test/tst_interops3.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/CMakeLists.txt (52%) create mode 100644 vendor/netcdf-c-4.9.3/include/Makefile.am rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/Makefile.in (85%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/XGetopt.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ceconstraints.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/err_macros.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/fbits.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/hdf4dispatch.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/hdf5dispatch.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/hdf5internal.h (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/isnan.h (100%) create mode 100644 vendor/netcdf-c-4.9.3/include/nc.h rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/nc3dispatch.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/nc3internal.h (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/nc4dispatch.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/nc4internal.h (88%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/nc_logging.h (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/nc_provenance.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/nc_tests.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncauth.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncbytes.h (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncconfigure.h (62%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/nccrc.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncdap.h (79%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncdimscale.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncdispatch.h (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncexhash.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncexternl.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/nchashmap.h (100%) create mode 100644 vendor/netcdf-c-4.9.3/include/nchttp.h rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncindex.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncjson.h (82%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/nclist.h (91%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/nclog.h (72%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncmodel.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncoffsets.h (83%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncpathmgr.h (94%) create mode 100644 vendor/netcdf-c-4.9.3/include/ncplugins.h create mode 100644 vendor/netcdf-c-4.9.3/include/ncproplist.h rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncrc.h (75%) create mode 100644 vendor/netcdf-c-4.9.3/include/ncs3sdk.h rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/nctestserver.h (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/nctime.h (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncuri.h (84%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncutf8.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncxcache.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/ncxml.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/netcdf.h (96%) create mode 100644 vendor/netcdf-c-4.9.3/include/netcdf_aux.h rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/netcdf_dispatch.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/netcdf_dispatch.h.in (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/netcdf_f.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/netcdf_filter.h (69%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/netcdf_filter_build.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/netcdf_filter_hdf5_build.h (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/netcdf_json.h (88%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/netcdf_mem.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/netcdf_meta.h (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/netcdf_meta.h.in (87%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/netcdf_par.h (100%) create mode 100644 vendor/netcdf-c-4.9.3/include/netcdf_proplist.h rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/onstack.h (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/include/rnd.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/install-sh (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/lib_flags.am (75%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/CMakeLists.txt (55%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/Makefile.am (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/Makefile.in (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/cache.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/cdf.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/constraints.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/constraints.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dapattr.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dapcvt.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dapdebug.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dapdebug.h (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dapdump.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dapdump.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dapincludes.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dapnc.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dapodom.c (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dapodom.h (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/daputil.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/daputil.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dce.y (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dceconstraints.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dceconstraints.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dcelex.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dceparse.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dceparselex.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dcetab.c (52%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/dcetab.h (68%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/getvara.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/getvara.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/nccommon.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/ncd2dispatch.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/ncd2dispatch.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap2/ncdaperr.c (100%) create mode 100644 vendor/netcdf-c-4.9.3/libdap4/CMakeLists.txt rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/Makefile.am (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/Makefile.in (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4bytes.h (100%) create mode 100644 vendor/netcdf-c-4.9.3/libdap4/d4chunk.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4chunk.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4curlfunctions.c (87%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4curlfunctions.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4cvt.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4data.c (57%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4debug.c (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4debug.h (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4dump.c (77%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4file.c (59%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4fix.c (71%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4http.c (76%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4http.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4includes.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4meta.c (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4odom.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4odom.h (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4parser.c (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4printer.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4read.c (61%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4read.h (85%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4swap.c (57%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4util.c (82%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/d4util.h (82%) create mode 100644 vendor/netcdf-c-4.9.3/libdap4/d4varx.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/ncd4.h (72%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/ncd4dispatch.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/ncd4dispatch.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdap4/ncd4types.h (77%) create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/CMakeLists.txt rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/Makefile.am (79%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/Makefile.in (84%) rename vendor/{netcdf-c-4.9.2/libsrc => netcdf-c-4.9.3/libdispatch}/XGetopt.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/awsincludes.h (87%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/datt.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dattget.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dattinq.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dattput.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dauth.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/daux.c (71%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dcompound.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dcopy.c (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dcrc32.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dcrc32.h (100%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dcrc64.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/ddim.c (100%) create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/ddispatch.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/denum.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/derror.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dfile.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dfilter.c (83%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dgroup.c (100%) create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/dhttp.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dinfermodel.c (81%) create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/dinstance.c create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/dinstance_intern.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dinternal.c (100%) create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/dmissing.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dnotnc3.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dnotnc4.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/doffsets.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dopaque.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dparallel.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dpathmgr.c (95%) create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/dplugins.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/drc.c (55%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dreadonly.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dreg.c (76%) create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/ds3util.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dstring.c (77%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dtype.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dutf8.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dutil.c (84%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dv2i.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dvar.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dvarget.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dvarinq.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dvarput.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/dvlen.c (75%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/nc.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/ncbytes.c (96%) create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/nccurl_hmac.c create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/nccurl_hmac.h create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/nccurl_setup.h create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/nccurl_sha256.c create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/nccurl_sha256.h rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/ncexhash.c (96%) create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/nch5s3comms.c create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/nch5s3comms.h rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/nchashmap.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/ncjson.c (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/nclist.c (75%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/nclistmgr.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/nclog.c (77%) create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/ncproplist.c create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/ncrandom.c rename vendor/{netcdf-c-4.9.2/libdispatch/ncs3sdk.cpp => netcdf-c-4.9.3/libdispatch/ncs3sdk_aws.cpp} (54%) create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/ncs3sdk_h5.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/ncsettings.hdr (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/nctime.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/ncuri.c (83%) create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/ncutil.h rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/ncxcache.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/utf8proc.c (72%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libdispatch/utf8proc.h (84%) create mode 100644 vendor/netcdf-c-4.9.3/libdispatch/utf8proc_data.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf4/CMakeLists.txt (59%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf4/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf4/Makefile.in (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf4/hdf4dispatch.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf4/hdf4file.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf4/hdf4func.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf4/hdf4var.c (100%) create mode 100644 vendor/netcdf-c-4.9.3/libhdf5/CMakeLists.txt rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/H5FDhttp.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/H5FDhttp.h (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/Makefile.am (87%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/Makefile.in (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5attr.c (80%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5create.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5debug.c (52%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5debug.h (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5dim.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5dispatch.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5err.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5file.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5filter.c (78%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5grp.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5internal.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5open.c (93%) create mode 100644 vendor/netcdf-c-4.9.3/libhdf5/hdf5plugins.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5set_format_compatibility.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5type.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/hdf5var.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/nc4hdf.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/nc4info.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/nc4mem.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libhdf5/nc4memcb.c (99%) create mode 100644 vendor/netcdf-c-4.9.3/liblib/CMakeLists.txt rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/liblib/Makefile.am (86%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/liblib/Makefile.in (88%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/liblib/nc_initialize.c (89%) create mode 100644 vendor/netcdf-c-4.9.3/libncpoco/CMakeLists.txt rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncpoco/COPYRIGHT (100%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncpoco/Makefile.am (100%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncpoco/Makefile.in (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncpoco/README.md (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncpoco/cp_unix.c (98%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncpoco/cp_win32.c (97%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncpoco/ncpoco.c (92%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncpoco/ncpoco.h (96%) mode change 100755 => 100644 create mode 100644 vendor/netcdf-c-4.9.3/libncxml/CMakeLists.txt rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncxml/Makefile.am (63%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncxml/Makefile.in (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncxml/license.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncxml/ncxml_tinyxml2.cpp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncxml/ncxml_xml2.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncxml/tinyxml2.cpp (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libncxml/tinyxml2.h (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/CMakeLists.txt (51%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/Makefile.am (85%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/Makefile.in (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zarr.c (66%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zarr.h (84%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zattr.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zcache.h (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zchunking.c (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zchunking.h (87%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zclose.c (80%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zcreate.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zcvt.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zdebug.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zdebug.h (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zdim.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zdispatch.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zdispatch.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zfile.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zfilter.c (61%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zfilter.h (84%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zgrp.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zincludes.h (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zinternal.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zinternal.h (81%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zmap.c (84%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zmap.h (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zmap_file.c (85%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zmap_s3sdk.c (86%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zmap_zip.c (97%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zodom.c (74%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zodom.h (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zopen.c (98%) create mode 100644 vendor/netcdf-c-4.9.3/libnczarr/zplugins.c create mode 100644 vendor/netcdf-c-4.9.3/libnczarr/zplugins.h rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zprov.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zprovenance.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zsync.c (58%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/ztype.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zutil.c (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zvar.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zwalk.c (78%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnczarr/zxcache.c (86%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libnetcdf.settings.in (86%) create mode 100644 vendor/netcdf-c-4.9.3/libsrc/CMakeLists.txt rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/Makefile.am (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/Makefile.in (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/attr.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/attr.m4 (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/dim.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/ffio.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/httpio.c (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/lookup3.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/memio.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/mmapio.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/nc3dispatch.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/nc3internal.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/ncio.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/ncio.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/ncstdio.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/ncx.c (77%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/ncx.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/ncx.m4 (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/netcdf.3 (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/posixio.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/pstdint.h (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/putget.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/putget.m4 (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/s3io.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/v1hpg.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc/var.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc4/CMakeLists.txt (53%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc4/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc4/Makefile.in (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc4/nc4attr.c (83%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc4/nc4cache.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc4/nc4dim.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc4/nc4dispatch.c (84%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc4/nc4grp.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc4/nc4internal.c (85%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc4/nc4type.c (79%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc4/nc4var.c (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc4/ncfunc.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrc4/ncindex.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrcp/CMakeLists.txt (56%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrcp/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrcp/Makefile.in (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/libsrcp/ncpdispatch.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ltmain.sh (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/m4/libtool.m4 (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/m4/ltoptions.m4 (85%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/m4/ltsugar.m4 (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/m4/ltversion.m4 (69%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/m4/lt~obsolete.m4 (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/missing (77%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc-config.cmake.in (65%) create mode 100644 vendor/netcdf-c-4.9.3/nc-config.in rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/CMakeLists.txt (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/Makefile.am (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/Makefile.in (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/bigmeta.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/bm_file.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/bm_many_atts.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/bm_many_objs.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/bm_netcdf4_recs.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/gfs_sample.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/openbigmeta.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/perftest.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/run_bm_elena.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/run_bm_test1.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/run_bm_test2.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/run_gfs_test.sh.in (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/run_knmi_bm.sh (78%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/run_par_bm_test.sh.in (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/run_tst_chunks.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_ar4.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_ar4_3d.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_ar4_4d.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_attsperf.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_bm_rando.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_chunks3.c (91%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_compress.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_compress_par.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_create_files.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_files2.c (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_files3.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_h_many_atts.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_knmi.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_mem.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_mem1.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_utils.c (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_perf/tst_wrf_reads.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/CMakeLists.txt (87%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/Makefile.am (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/Makefile.in (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/bad_cdf5_begin.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/error.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/error.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/f03tst_open_mem.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/large_files.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/nc_enddef.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/nc_test.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/quick_large_files.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/ref_tst_diskless2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/ref_tst_diskless3_create.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/ref_tst_diskless3_open.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/ref_tst_http_nc3.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/ref_tst_http_nc4a.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/ref_tst_http_nc4b.cdl (100%) rename vendor/{netcdf-c-4.9.2/nc_test/ref_tst_http_nc4e.cdl => netcdf-c-4.9.3/nc_test/ref_tst_http_nc4c.cdl} (100%) rename vendor/{netcdf-c-4.9.2/nc_test/ref_tst_http_nc4c.cdl => netcdf-c-4.9.3/nc_test/ref_tst_http_nc4e.cdl} (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/ref_tst_http_nc4f.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/run_cdf5.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/run_diskless.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/run_diskless2.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/run_diskless5.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/run_inmemory.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/run_mmap.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/run_pnetcdf_tests.sh.in (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/t_nc.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/test_byterange.sh (71%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/test_get.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/test_get.m4 (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/test_put.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/test_put.m4 (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/test_read.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/test_read.m4 (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/test_write.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/test_write.m4 (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/testnc3perf.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tests.h (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_addvar.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_atts3.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_big_rvar.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_big_var.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_big_var2.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_big_var6.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_byterange.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_cdf5_begin.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_cdf5format.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_def_var_fill.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_default_format.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_default_format_pnetcdf.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_diskless.c (87%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_diskless2.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_diskless3.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_diskless4.c (87%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_diskless5.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_diskless5.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_diskless6.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_err_enddef.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_formats.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_formatx_pnetcdf.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_global_fillval.c (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_inmemory.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_inq_type.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_large.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_large_cdf5.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_max_var_dims.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_meta.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_misc.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_names.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_nofill.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_nofill2.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_nofill3.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_norm.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_open_cdf5.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_open_mem.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_parallel2.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_pnetcdf.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_small.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_utf8_phrases.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/tst_utf8_validate.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test/util.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/CMakeLists.txt (79%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/Makefile.am (73%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/Makefile.in (88%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/build_fixedstring.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/bzip2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/cdm_sea_soundings.c (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/h5testszip.c (100%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/noop.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/noop1.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_any.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_bloscx.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_bzip2.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_fillonly.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_filter_order_create.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_filter_order_read.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_filter_repeat.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_filtered.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_filteredvv.cdl (100%) create mode 100644 vendor/netcdf-c-4.9.3/nc_test4/ref_fixedstring.cdl rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_hdf5_compat1.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_hdf5_compat2.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_hdf5_compat3.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_multi.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_nccopyF.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_ncgenF.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_szip.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_szip.h5 (100%) create mode 100644 vendor/netcdf-c-4.9.3/nc_test4/ref_tmp_tst_warn_out.txt rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_tst_compounds.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_tst_dims.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_tst_interops4.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_tst_xplatform2_1.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_tst_xplatform2_2.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_unfiltered.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/ref_unfilteredvv.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/renamegroup.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/run_empty_vlen_test.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/run_grp_rename.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/run_par_test.sh.in (86%) create mode 100644 vendor/netcdf-c-4.9.3/nc_test4/run_par_warn_test.sh.in create mode 100755 vendor/netcdf-c-4.9.3/nc_test4/run_zstd_test.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/t_type.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tdset.h5 (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/test_fillonly.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/test_filter.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/test_filter_misc.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/test_filter_order.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/test_filter_repeat.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/test_szip.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_alignment.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_atts.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_atts1.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_atts2.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_atts3.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_atts_string_rewrite.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_bloscfail.sh (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_broken_files.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_bug1442.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_bug324.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_camrun.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_charvlenbug.c (100%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_chunks.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_chunks2.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_compounds.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_compounds2.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_compounds3.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_converts.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_converts2.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_coords.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_coords2.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_coords3.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_dims.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_dims2.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_dims3.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_elatefill.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_empty_vlen_unlim.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_endian_fill.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_enums.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_files.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_files4.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_files5.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_files6.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_fill_attr_vanish.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_fillbug.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_fillonly.c (100%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_fills.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_fills2.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_filter.sh (100%) create mode 100755 vendor/netcdf-c-4.9.3/nc_test4/tst_filter_misc.sh create mode 100644 vendor/netcdf-c-4.9.3/nc_test4/tst_filter_vlen.c create mode 100755 vendor/netcdf-c-4.9.3/nc_test4/tst_filter_vlen.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_filterinstall.sh (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_filterparser.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_fixedstring.sh (62%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_grps.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_grps2.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_h5_endians.c (50%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_h_refs.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_h_scalar.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_h_strbug.c (98%) create mode 100644 vendor/netcdf-c-4.9.3/nc_test4/tst_h_transient_types.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_hdf5_file_compat.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_interops.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_interops4.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_interops5.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_interops6.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_interops_dims.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_large.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_large2.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_misc.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_mode.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_mpi_parallel.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_multifilter.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_nc4perf.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_opaques.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_parallel.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_parallel3.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_parallel4.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_parallel5.c (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_parallel6.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_parallel_compress.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_parallel_zlib.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_put_vars.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_put_vars_two_unlim_dim.c (87%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_quantize.c (91%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_quantize_par.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_rehash.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_rename.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_rename2.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_rename3.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_simplerw_coll_r.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_specific_filters.sh (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_strings.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_strings2.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_sync.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_szip.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_types.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_udf.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_unknown.sh (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_unlim_vars.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_utf8.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_v2.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_varms.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_vars.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_vars2.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_vars3.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_vars4.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_virtual_datasets.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_vl.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_vlenstr.c (79%) create mode 100644 vendor/netcdf-c-4.9.3/nc_test4/tst_warn.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_xplatform.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/tst_xplatform2.c (99%) create mode 100644 vendor/netcdf-c-4.9.3/nc_test4/tst_zstd.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nc_test4/unknown.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/CMakeLists.txt (80%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/Makefile.am (76%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/Makefile.in (78%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/123.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/123bears.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/1990-S1700101.HDF.WVC_Lat.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/1998-6-avhrr.dat.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/CMakeLists.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/D1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/Drifters.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/EOSDB.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/Makefile.in (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/NestedSeq.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/NestedSeq2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/OverideExample.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/SimpleDrdsExample.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/b31.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/b31a.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/bears.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/ber-2002-10-01.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/ceopL2AIRS2-2.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/coads_climatology2.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/data.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/fillmismatch.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/fnoc1.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/in.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/in1.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/in_2.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/in_no_three_double_dmn.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/in_v.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/ingrid.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/kwcase.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/nestedDAS.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/pbug0001b.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/saco1.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/synth1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/synth10.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/synth2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/synth3.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/synth4.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/synth5.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/synth6.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/synth7.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/synth8.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/synth9.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.01.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.02.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.03.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.04.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.05.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.06a.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.07.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.07a.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.21.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.22.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.23.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.31.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.50.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.53.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.55.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.56.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.57.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.66.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.67.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.68.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.69.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.PointFile.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.an1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.dfp1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.dfr1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.dfr2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.dfr3.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.gr1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.gr2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.gr3.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.gr4.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.gr5.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.sds1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.sds2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.sds3.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.sds4.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.sds5.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.sds6.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.sds7.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.vs1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.vs2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.vs3.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.vs4.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/test.vs5.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/testData.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/text.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expected3/whoi.dmp (100%) rename vendor/{netcdf-c-4.9.2/ncdap_test/expectremote3 => netcdf-c-4.9.3/ncdap_test/expectedhyrax}/CMakeLists.txt (100%) create mode 100644 vendor/netcdf-c-4.9.3/ncdap_test/expectedhyrax/ECMWF_ERA-40_subset.nc.hyrax create mode 100644 vendor/netcdf-c-4.9.3/ncdap_test/expectedhyrax/Makefile.am create mode 100644 vendor/netcdf-c-4.9.3/ncdap_test/expectedhyrax/Makefile.in create mode 100644 vendor/netcdf-c-4.9.3/ncdap_test/expectedhyrax/cami_0000-09-01_64x128_L26_c030918.nc.hyrax rename vendor/{netcdf-c-4.9.2/ncdap_test/testdata3 => netcdf-c-4.9.3/ncdap_test/expectremote3}/CMakeLists.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/D1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/Drifters.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/EOSDB.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/GLOBEC_cetaceans.1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/GLOBEC_cetaceans.2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/Makefile.in (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/NestedSeq.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/NestedSeq2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/OverideExample.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/SimpleDrdsExample.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/Surface_METAR_20120101_0000.nc.1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/b31.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/b31a.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/ingrid.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/nestedDAS.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.01.1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.01.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.02.1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.02.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.03.1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.03.2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.03.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.04.1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.04.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.05.1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.05.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.06.1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.06.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.06a.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.07.1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.07.3.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.07.4.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.07.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.07a.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.21.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.22.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.23.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.31.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.50.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.53.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.55.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.56.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.57.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.66.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.67.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.68.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.69.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.an1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.dfp1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.gr1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.gr2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.gr3.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.gr4.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.gr5.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.nc.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.sds1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.sds2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.sds3.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.sds4.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.sds5.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.vs1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.vs2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.vs3.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.vs4.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/test.vs5.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/expectremote3/whoi.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/findtestserver.c (97%) mode change 100644 => 100755 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/findtestserver.c.in (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/manyurls.h (100%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/pingurl.c (85%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/t_dap.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/t_dap3a.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/t_misc.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/t_ncf330.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/t_srcdir.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/test_cvt.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/test_manyurls.c (91%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/test_nstride_cached.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/test_partvar.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/test_vara.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/test_varm3.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testauth.sh (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/123.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/123.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/123.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/123bears.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/123bears.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/123bears.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/1990-S1700101.HDF.WVC_Lat.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/1990-S1700101.HDF.WVC_Lat.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/1990-S1700101.HDF.WVC_Lat.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/1998-6-avhrr.dat.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/1998-6-avhrr.dat.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/1998-6-avhrr.dat.dods (100%) rename vendor/{netcdf-c-4.9.2/dap4_test/nctestfiles => netcdf-c-4.9.3/ncdap_test/testdata3}/CMakeLists.txt (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/D1.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/D1.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/D1.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/Drifters.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/Drifters.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/Drifters.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/EOSDB.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/EOSDB.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/EOSDB.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/Makefile.in (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/NestedSeq.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/NestedSeq.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/NestedSeq.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/NestedSeq2.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/NestedSeq2.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/NestedSeq2.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/OverideExample.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/OverideExample.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/OverideExample.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/SimpleDrdsExample.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/SimpleDrdsExample.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/SimpleDrdsExample.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/b31.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/b31.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/b31.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/b31a.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/b31a.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/b31a.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/bears.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/bears.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/bears.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/ber-2002-10-01.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/ber-2002-10-01.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/ber-2002-10-01.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/ceopL2AIRS2-2.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/ceopL2AIRS2-2.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/ceopL2AIRS2-2.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/ceopL2AIRS2.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/ceopL2AIRS2.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/ceopL2AIRS2.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/data.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/data.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/data.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/fillmismatch.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/fillmismatch.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/fillmismatch.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/fnoc1.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/fnoc1.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/fnoc1.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in1.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in1.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in1.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in_2.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in_2.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in_2.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in_no_three_double_dmn.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in_no_three_double_dmn.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in_no_three_double_dmn.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in_v.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in_v.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/in_v.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/ingrid.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/ingrid.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/ingrid.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/kwcase.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/kwcase.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/kwcase.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/nestedDAS.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/nestedDAS.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/nestedDAS.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/pbug0001b.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/pbug0001b.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/pbug0001b.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/saco1.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/saco1.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/saco1.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth1.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth1.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth1.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth10.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth10.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth10.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth2.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth2.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth2.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth3.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth3.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth3.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth4.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth4.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth4.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth5.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth5.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth5.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth6.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth6.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth6.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth7.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth7.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/synth7.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.01.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.01.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.01.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.02.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.02.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.02.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.03.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.03.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.03.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.04.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.04.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.04.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.05.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.05.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.05.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.06.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.06.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.06.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.06a.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.06a.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.06a.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.07.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.07.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.07.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.07a.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.07a.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.07a.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.21.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.21.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.21.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.22.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.22.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.22.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.23.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.23.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.23.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.31.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.31.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.31.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.32.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.32.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.32.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.50.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.50.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.50.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.53.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.53.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.53.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.55.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.55.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.55.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.56.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.56.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.56.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.57.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.57.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.57.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.66.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.66.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.66.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.67.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.67.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.67.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.68.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.68.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.68.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.69.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.69.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.69.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.PointFile.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.PointFile.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.PointFile.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.SwathFile.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.SwathFile.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.SwathFile.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.an1.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.an1.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.an1.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.dfp1.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.dfp1.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.dfp1.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.dfr1.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.dfr1.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.dfr1.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.dfr2.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.dfr2.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.dfr2.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.dfr3.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.dfr3.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.dfr3.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr1.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr1.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr1.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr2.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr2.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr2.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr3.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr3.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr3.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr4.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr4.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr4.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr5.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr5.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.gr5.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds1.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds1.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds1.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds2.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds2.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds2.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds3.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds3.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds3.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds4.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds4.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds4.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds5.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds5.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds5.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds6.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds6.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds6.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds7.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds7.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.sds7.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs1.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs1.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs1.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs2.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs2.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs2.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs3.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs3.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs3.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs4.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs4.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs4.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs5.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs5.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/test.vs5.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/testfile.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/testfile.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/testfile.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/text.nc.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/text.nc.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/text.nc.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/whoi.das (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/whoi.dds (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testdata3/whoi.dods (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/testurl.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/tst_ber.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/tst_encode.sh (75%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/tst_filelists.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/tst_fillmismatch.sh (62%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/tst_formatx.sh (100%) create mode 100755 vendor/netcdf-c-4.9.3/ncdap_test/tst_hyrax.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/tst_longremote3.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/tst_ncdap3.sh (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/tst_remote3.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/tst_urls.sh (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/tst_utils.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdap_test/tst_zero_len_var.sh (100%) create mode 100644 vendor/netcdf-c-4.9.3/ncdump/CMakeLists.txt rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/L512.bin (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/Makefile.am (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/Makefile.in (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/bom.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/CMakeLists.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/Makefile.in (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/bigf1.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/bigf2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/bigf3.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/bigr1.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/bigr2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/bigr3.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/c0.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/example_good.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/fills.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/n3time.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/nc_enddef.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/nc_sync.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/pres_temp_4D.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_const_test.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_ctest1_nc4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_ctest1_nc4c.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_dimscope.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_keyword.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_nctst.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_nctst_64bit_offset.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_nctst_netcdf4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_nctst_netcdf4_classic.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_niltest.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_solar.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_chardata.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_comp.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_comp2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_comp3.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_econst.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_econst2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_enum_data.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_group_data.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_h_scalar.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_long_charconst.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_names.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_nans.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_nul3.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_nul4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_opaque_data.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_small.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_solar_1.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_solar_2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_special_atts.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_special_atts3.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_string_data.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_unicode.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_unlim2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_utf8.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_vlen_data.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_tst_vlen_data2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/ref_typescope.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/sfc_pres_temp.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/simple_xy.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/small.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/small2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/test0.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/tst_chararray.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/tst_ncml.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/unlimtest1.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/cdl/unlimtest2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/chunkspec.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/chunkspec.h (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/dimmap.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/dimmap.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/dumplib.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/dumplib.h (98%) create mode 100644 vendor/netcdf-c-4.9.3/ncdump/echon.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/CMakeLists.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/Makefile.in (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/c0.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/example_good.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/fills.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/n3time.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/nc_enddef.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/nc_sync.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/pres_temp_4D.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_const_test.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_ctest1_nc4.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_ctest1_nc4c.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_dimscope.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_keyword.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_nctst.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_nctst_64bit_offset.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_nctst_netcdf4.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_nctst_netcdf4_classic.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_niltest.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_solar.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_chardata.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_comp.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_comp2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_comp3.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_econst.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_econst2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_enum_data.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_group_data.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_h_scalar.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_long_charconst.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_names.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_nans.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_nul3.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_nul4.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_opaque_data.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_small.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_solar_1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_solar_2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_special_atts.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_special_atts3.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_string_data.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_unicode.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_unlim2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_utf8.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_vlen_data.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_tst_vlen_data2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/ref_typescope.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/sfc_pres_temp.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/simple_xy.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/small.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/small2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/test0.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/tst_chararray.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/tst_ncml.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/unlimtest1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/expected/unlimtest2.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/indent.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/indent.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/inttags.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/inttags4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/list.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/list.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/nc4print.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/nc4printer.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/nccomps.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/nccopy.1 (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/nccopy.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ncdump.1 (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ncdump.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ncdump.h (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ncfilteravail.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/nchdf5version.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/nciter.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/nciter.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ncpathcvt.c (71%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/nctime0.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/nctime0.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/nctrunc.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ncvalidator.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ocprint.c (98%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/printfqn.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref1.ncml (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_ctest.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_ctest1_nc4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_ctest1_nc4c.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_ctest64.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_ctest_small_3.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_ctest_small_4.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_ctest_special_atts_4.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_inttags.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_inttags4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_keyword1.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_keyword2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_keyword3.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_keyword4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_nc_test_netcdf4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_nc_test_netcdf4_4_0.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_nccopy3_subset.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_nccopy_w.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_no_ncproperty.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_null_byte_padding_test.nc (100%) create mode 100644 vendor/netcdf-c-4.9.3/ncdump/ref_pathcvt.txt rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_provenance_v1.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_rcapi.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_rcmerge1.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_rcmerge2.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_rcmerge3.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_roman_szip_simple.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_roman_szip_unlim.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_test_360_day_1900.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_test_360_day_1900.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_test_365_day_1900.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_test_365_day_1900.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_test_366_day_1900.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_test_366_day_1900.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_test_corrupt_magic.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_times.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_times_nc4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_charfill.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_comp.cdl (100%) create mode 100644 vendor/netcdf-c-4.9.3/ncdump/ref_tst_comp2.cdl rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_compounds2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_compounds2.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_compounds3.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_compounds3.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_compounds4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_compounds4.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_enum_data.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_enum_undef.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_fillbug.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_format_att.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_format_att_64.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_group_data.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_group_data_v23.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_grp_spec.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_grp_spec0.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_irish_rover.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_mud4-bc.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_mud4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_mud4_chars.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_nans.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_nc4_utf8_4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_ncf213.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_nofilters.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_noncoord.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_opaque_data.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_perdimspecs.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_radix.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_small.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_solar_1.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_solar_2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_special_atts.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_special_atts3.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_string_data.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_unicode.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_utf8.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_utf8_4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/ref_tst_vlen_data.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/rewrite-scalar.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/run_back_comp_tests.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/run_ncgen_nc4_tests.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/run_ncgen_tests.sh (91%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/run_tests.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/run_utf8_nc4_tests.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/run_utf8_tests.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/scope_ancestor_only.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/scope_ancestor_subgroup.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/scope_group_only.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/scope_preorder.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/small.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/small2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/test0.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/test_keywords.sh (100%) rename vendor/{netcdf-c-4.9.2/ncdump/tst_netcdf4.sh => netcdf-c-4.9.3/ncdump/test_ncdump.sh} (50%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/test_radix.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/test_rcmerge.sh (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/test_scope.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/test_unicode_directory.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/test_unicode_path.sh (100%) create mode 100755 vendor/netcdf-c-4.9.3/ncdump/testpathcvt.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_64bit.sh (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_bom.sh (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_brecs.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_bug321.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_calendars.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_calendars.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_calendars_nc4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_calendars_nc4.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_charfill.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_charfill.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_chunking.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_comp.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_comp2.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_compress.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_create_files.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_ctests.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_dimsizes.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_dimsizes.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_enum_data.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_enum_undef.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_fileinfo.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_fileinfo.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_fillbug.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_fillbug.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_formatx3.sh (86%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_formatx4.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_group_data.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_grp_spec.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_h_rdc0.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_h_scalar.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_h_scalar.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_hdf5_offset.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_inmemory_nc3.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_inmemory_nc4.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_inttags.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_inttags4.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_iter.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_lengths.sh (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_mslp.cdl (100%) create mode 100755 vendor/netcdf-c-4.9.3/ncdump/tst_mud.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_nans.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_nccopy3.sh (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_nccopy3_subset.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_nccopy4.sh (90%) create mode 100755 vendor/netcdf-c-4.9.3/ncdump/tst_nccopy5.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_nccopy_w3.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_nccopy_w4.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_ncgen4.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_ncgen4_classic.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_ncgen4_cycle.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_ncgen4_diff.sh (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_ncgen_shared.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_ncml.cdl (100%) create mode 100755 vendor/netcdf-c-4.9.3/ncdump/tst_netcdf4.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_netcdf4_4.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_null_byte_padding.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_opaque_data.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_output.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_radix.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_rcapi.c (100%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_rcmerge.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_special_atts.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_string_data.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_unicode.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_utf8.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_vlen_data.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/tst_vlen_demo.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/utils.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/utils.h (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/vardata.c (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncdump/vardata.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/CMakeLists.txt (62%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/Makefile.in (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/bindata.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/bytebuffer.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/bytebuffer.h (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/c0.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/c0_4.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/c5.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/cdata.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/compound_datasize_test.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/compound_datasize_test2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/cvt.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/data.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/data.h (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/debug.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/debug.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/dump.c (87%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/dump.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/escapes.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/f77data.c (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/genbin.c (80%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/genc.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/genchar.c (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/generate.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/generate.h (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/generr.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/generr.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/genf77.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/genj.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/genlib.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/genlib.h (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/getfill.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/includes.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/internals.html (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/jdata.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/list.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/list.h (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/main.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/ncf199.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/ncgen.1 (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/ncgen.h (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/ncgen.l (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/ncgen.y (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/ncgenl.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/ncgeny.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/ncgeny.h (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/ref_camrun.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/semantics.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/tst_gattenum.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/tst_usuffix.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/util.c (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen/util.h (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/CMakeLists.txt (60%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/Makefile.in (91%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/c0.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/escapes.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/generic.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/genlib.c (88%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/genlib.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/getfill.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/init.c (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/load.c (85%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/main.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/ncgen.h (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/ncgen.l (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/ncgen.y (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/ncgen3.1 (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/ncgenl.c (79%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/ncgeny.c (64%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/ncgeny.h (51%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/run_nc4_tests.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/ncgen3/run_tests.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/CMakeLists.txt (57%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/Makefile.am (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/Makefile.in (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/add.c (83%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/add.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/atttests.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/cdftests.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/compare_test_files.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/dimtests.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/driver.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/emalloc.c (86%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/emalloc.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/error.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/error.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/misctest.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/rec.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/ref_nctest_64bit_offset.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/ref_nctest_classic.nc (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/slabs.c (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/testcdf.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/tests.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/tst_rename.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/val.c (84%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/val.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/vardef.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/varget.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/vargetg.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/varput.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/varputg.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/vartests.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/vputget.c (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nctest/vputgetg.c (97%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/CMakeLists.txt create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/Makefile.am rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/Makefile.in (58%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/bm_chunks3.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/bm_timer.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/bm_utils.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/bm_utils.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ncdumpchunks.c (84%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_any.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_avail1.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_avail1.dmp (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_avail1.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_byte.cdl (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_byte.zarr.zip (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_byte_fill_value_null.cdl (96%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_byte_fill_value_null.zarr.zip rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_bzip2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_fillonly.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_filtered.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_groups.h5 (100%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_groups_regular.cdl (78%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_jsonconvention.cdl (86%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_jsonconvention.zmap rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_misc1.cdl (100%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_misc1.dmp rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_misc2.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_multi.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_nczarr2zarr.cdl (81%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ndims.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ndims.dmp (68%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_newformatpure.cdl (81%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_noshape.file.zip create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_notzarr.tar.gz rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_nulls.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_nulls_nczarr.baseline (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_nulls_zarr.baseline (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_oldformat.cdl (81%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_oldformat.zip create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_oldkeys.cdl create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_oldkeys.file.zip create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_oldkeys.zmap rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_perdimspecs.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_power_901_constants.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_power_901_constants_orig.zip (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_purezarr.cdl (50%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_purezarr_base.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_quotes.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_quotes_orig.zip (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_rem.cdl (100%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_rem.dmp rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_scalar.cdl (100%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_scalar_nczarr.cdl rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_skip.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_skip.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_skipw.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_string.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_string_nczarr.baseline (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_string_zarr.baseline (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_t_meta_dim1.cdl (87%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_t_meta_var1.cdl (86%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ut_json_build.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ut_json_parse.txt (100%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_ut_map_create.cdl rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ut_map_readmeta.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ut_map_readmeta2.txt (75%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ut_map_search.txt (67%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ut_map_writedata.cdl (83%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ut_map_writemeta.cdl (78%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ut_map_writemeta2.cdl (72%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_ut_mapapi_create.cdl rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ut_mapapi_data.cdl (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ut_mapapi_meta.cdl (83%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ut_mapapi_search.txt (78%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ut_proj.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_ut_testmap_create.cdl (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_whole.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_whole.txt (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_xarray.cdl (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ref_zarr_test_data.cdl.gz (65%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_zarr_test_data_2d.cdl.gz create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/ref_zarr_test_data_meta.cdl rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_chunkcases.sh (80%) create mode 100755 vendor/netcdf-c-4.9.3/nczarr_test/run_corrupt.sh create mode 100755 vendor/netcdf-c-4.9.3/nczarr_test/run_external.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_fillonlyz.sh (85%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_filter.sh (82%) create mode 100755 vendor/netcdf-c-4.9.3/nczarr_test/run_interop.sh create mode 100755 vendor/netcdf-c-4.9.3/nczarr_test/run_jsonconvention.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_misc.sh (84%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_nccopyz.sh (85%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_ncgen4.sh (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_nczarr_fill.sh (81%) create mode 100755 vendor/netcdf-c-4.9.3/nczarr_test/run_nczfilter.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_newformat.sh (95%) create mode 100755 vendor/netcdf-c-4.9.3/nczarr_test/run_notzarr.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_nulls.sh (96%) create mode 100755 vendor/netcdf-c-4.9.3/nczarr_test/run_oldkeys.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_perf_chunks1.sh (87%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_purezarr.sh (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_quantize.sh (77%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_scalar.sh (78%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_strings.sh (86%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_unknown.sh (94%) create mode 100755 vendor/netcdf-c-4.9.3/nczarr_test/run_unlim_io.sh rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_ut_map.sh (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_ut_mapapi.sh (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/run_ut_misc.sh (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/s3util.c (93%) rename vendor/{netcdf-c-4.9.2/nczarr_test/tst_chunkcases.c => netcdf-c-4.9.3/nczarr_test/test_chunkcases.c} (52%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/test_chunking.c create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/test_endians.c rename vendor/{netcdf-c-4.9.2/nczarr_test/tst_fillonlyz.c => netcdf-c-4.9.3/nczarr_test/test_fillonlyz.c} (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/test_filter_avail.c (100%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/test_filter_vlen.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/test_nczarr.sh (66%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/test_nczarr_utils.h (100%) rename vendor/{netcdf-c-4.9.2/nczarr_test/tst_nczfilter.c => netcdf-c-4.9.3/nczarr_test/test_nczfilter.c} (100%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/test_notzarr.c create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/test_put_vars_two_unlim_dim.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/test_quantize.c (91%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/test_readcaching.c create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/test_unlim_io.c create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/test_unlim_vars.c rename vendor/{netcdf-c-4.9.2/nczarr_test/tst_utils.c => netcdf-c-4.9.3/nczarr_test/test_utils.c} (59%) rename vendor/{netcdf-c-4.9.2/nczarr_test/tst_utils.h => netcdf-c-4.9.3/nczarr_test/test_utils.h} (72%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/test_writecaching.c rename vendor/{netcdf-c-4.9.2/nczarr_test/tst_zchunks.c => netcdf-c-4.9.3/nczarr_test/test_zchunks.c} (96%) rename vendor/{netcdf-c-4.9.2/nczarr_test/tst_zchunks2.c => netcdf-c-4.9.3/nczarr_test/test_zchunks2.c} (89%) rename vendor/{netcdf-c-4.9.2/nczarr_test/tst_zchunks3.c => netcdf-c-4.9.3/nczarr_test/test_zchunks3.c} (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/testfilter.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/testfilter_misc.c (83%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/testfilter_multi.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/testfilter_order.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/testfilter_repeat.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/timer_utils.c (100%) create mode 100644 vendor/netcdf-c-4.9.3/nczarr_test/tst_pure_awssdk.cpp rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ut_includes.h (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ut_json.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ut_map.c (86%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ut_mapapi.c (90%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ut_test.c (97%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ut_test.h (76%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ut_util.c (87%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/ut_util.h (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/zhex.c (71%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/zisjson.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/zmapio.c (92%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/nczarr_test/zs3parse.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/netCDFConfig.cmake.in (67%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/netcdf.pc.in (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/CMakeLists.txt (53%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/Makefile.am (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/Makefile.in (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/auth.html.in (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/dap.y (83%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/daplex.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/dapparse.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/dapparselex.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/dapy.c (51%) create mode 100644 vendor/netcdf-c-4.9.3/oc2/dapy.h rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/oc.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/oc.css (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/oc.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/occompile.c (97%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/occompile.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/occonstraints.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/occurlfunctions.c (82%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/occurlfunctions.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocdata.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocdata.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocdatatypes.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocdebug.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocdebug.h (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocdump.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocdump.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ochttp.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ochttp.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocinternal.c (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocinternal.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocnode.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocnode.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocread.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocread.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocutil.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocutil.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/ocx.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/xxdr.c (98%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/oc2/xxdr.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/BZIP2_LICENSE (100%) create mode 100644 vendor/netcdf-c-4.9.3/plugins/CMakeLists.txt rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Zblosc.c (99%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Zblosc.h (95%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Zbzip2.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Zdeflate.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Zfletcher32.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Zmisc.c (56%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Znoop.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Znoop1.c (94%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Zshuffle.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Zszip.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Zszip.h (100%) mode change 100755 => 100644 rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Ztemplate.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Zunknown.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Zutil.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Zzstd.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5Zzstd.h (95%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/H5checksum.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/Makefile.am (68%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/Makefile.in (73%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/NCZhdf5filters.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/NCZmisc.c (93%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/NCZstdfilters.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/blocksort.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/bzlib.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/bzlib.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/bzlib_private.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/compress.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/crctable.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/decompress.c (100%) rename vendor/{netcdf-c-4.9.2/nc_test4 => netcdf-c-4.9.3/plugins}/findplugin.in (91%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/h5bzip2.h (100%) create mode 100644 vendor/netcdf-c-4.9.3/plugins/h5misc.h rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/h5noop.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/huffman.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/plugins/randtable.c (100%) create mode 100755 vendor/netcdf-c-4.9.3/s3cleanup.in create mode 100755 vendor/netcdf-c-4.9.3/s3gc.in rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/test-driver (89%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/test-driver-verbose (96%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/test_common.in (69%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/test_prog.c (100%) create mode 100644 vendor/netcdf-c-4.9.3/unit_test/CMakeLists.txt rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/unit_test/Makefile.am (53%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/unit_test/Makefile.in (77%) create mode 100644 vendor/netcdf-c-4.9.3/unit_test/aws_config.c create mode 100644 vendor/netcdf-c-4.9.3/unit_test/ncpluginpath.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/unit_test/nctest_netcdf4_classic.nc (100%) create mode 100644 vendor/netcdf-c-4.9.3/unit_test/reclaim_tests.cdl create mode 100644 vendor/netcdf-c-4.9.3/unit_test/ref_get.txt create mode 100644 vendor/netcdf-c-4.9.3/unit_test/ref_set.txt create mode 100644 vendor/netcdf-c-4.9.3/unit_test/ref_xget.txt create mode 100644 vendor/netcdf-c-4.9.3/unit_test/ref_xset.txt create mode 100755 vendor/netcdf-c-4.9.3/unit_test/run_aws_config.sh create mode 100755 vendor/netcdf-c-4.9.3/unit_test/run_dfaltpluginpath.sh create mode 100755 vendor/netcdf-c-4.9.3/unit_test/run_pluginpaths.sh create mode 100755 vendor/netcdf-c-4.9.3/unit_test/run_reclaim_tests.sh create mode 100755 vendor/netcdf-c-4.9.3/unit_test/run_s3sdk.sh create mode 100644 vendor/netcdf-c-4.9.3/unit_test/test_ncuri.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/unit_test/test_pathcvt.c (95%) create mode 100644 vendor/netcdf-c-4.9.3/unit_test/test_s3sdk.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/unit_test/timer_utils.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/unit_test/timer_utils.h (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/unit_test/tst_exhash.c (99%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/unit_test/tst_nc4internal.c (100%) rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/unit_test/tst_nclist.c (100%) create mode 100644 vendor/netcdf-c-4.9.3/unit_test/tst_pluginpaths.c create mode 100644 vendor/netcdf-c-4.9.3/unit_test/tst_reclaim.c rename vendor/{netcdf-c-4.9.2 => netcdf-c-4.9.3}/unit_test/tst_xcache.c (94%) delete mode 100644 vendor/paraconf-1.0.0/CMakeLists.txt delete mode 100644 vendor/paraconf-1.0.0/README.md delete mode 100644 vendor/paraconf-1.0.0/cmake/SuperBuild.cmake delete mode 100644 vendor/paraconf-1.0.0/code_generator/README.md delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/PDI_data.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/PDI_data2.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/PDI_data3.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/PDI_data4.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/PDI_schema.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/basic_data.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/basic_schema.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/full_data.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/full_schema.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/generic_data.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/generic_schema.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/include_data.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/include_schema.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/recursive_data.yaml delete mode 100644 vendor/paraconf-1.0.0/code_generator/examples/recursive_schema.yaml delete mode 100755 vendor/paraconf-1.0.0/code_generator/pcgen delete mode 100644 vendor/paraconf-1.0.0/code_generator/src/c_code_generator/c_data_loader.py delete mode 100644 vendor/paraconf-1.0.0/code_generator/src/c_code_generator/c_free_memory.py delete mode 100644 vendor/paraconf-1.0.0/code_generator/src/c_code_generator/c_functions.py delete mode 100644 vendor/paraconf-1.0.0/code_generator/src/c_code_generator/c_types_generator.py delete mode 100644 vendor/paraconf-1.0.0/code_generator/src/c_code_generator/tools.py delete mode 100644 vendor/paraconf-1.0.0/code_generator/src/c_code_generator/type_handler.py delete mode 100644 vendor/paraconf-1.0.0/code_generator/src/main.py delete mode 100644 vendor/paraconf-1.0.0/example/AUTHORS delete mode 100644 vendor/paraconf-1.0.0/paraconf/VERSION delete mode 100644 vendor/paraconf-1.0.0/paraconf/cmake/GenerateExportHeader.cmake delete mode 100644 vendor/paraconf-1.0.0/paraconf/cmake/exportheader.cmake.in delete mode 100644 vendor/paraconf-1.0.0/paraconf/cmake/paraconfConfig.cmake delete mode 100644 vendor/paraconf-1.0.0/paraconf/include/paraconf.F90 delete mode 100644 vendor/paraconf-1.0.0/paraconf/include/paraconf_f90_consts.h delete mode 100644 vendor/paraconf-1.0.0/paraconf/include/paraconf_f90_types.h delete mode 100644 vendor/paraconf-1.0.0/paraconf/include/paraconff.h delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/.gitignore delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/.indent.pro delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/.makefile delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/.travis.yml delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/CMakeLists.txt delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/LICENSE delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/Makefile.am delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/README delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/announcement.msg delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/appveyor.yml delete mode 100755 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/bootstrap delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/cmake/config.h.in delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/configure.ac delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/doc/doxygen.cfg delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/docker/README.mkd delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/docker/alpine-3.7 delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/docker/fedora-25 delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/docker/ubuntu-14.04 delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/docker/ubuntu-16.04 delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/examples/anchors.yaml delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/examples/array.yaml delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/examples/global-tag.yaml delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/examples/json.yaml delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/examples/mapping.yaml delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/examples/numbers.yaml delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/examples/strings.yaml delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/examples/tags.yaml delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/examples/yaml-version.yaml delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/include/Makefile.am delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/include/yaml.h delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/regression-inputs/clusterfuzz-testcase-minimized-5607885063061504.yml delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/src/Makefile.am delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/src/api.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/src/dumper.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/src/emitter.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/src/loader.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/src/parser.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/src/reader.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/src/scanner.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/src/writer.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/src/yaml_private.h delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/CMakeLists.txt delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/Makefile.am delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/example-deconstructor-alt.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/example-deconstructor.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/example-reformatter-alt.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/example-reformatter.c delete mode 100755 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/run-all-tests.sh delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/run-dumper.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/run-emitter-test-suite.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/run-emitter.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/run-loader.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/run-parser-test-suite.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/run-parser.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/run-scanner.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/test-reader.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/tests/test-version.c delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/yaml-0.1.pc.in delete mode 100644 vendor/paraconf-1.0.0/vendor/libyaml-0.2.2/yamlConfig.cmake.in create mode 100644 vendor/paraconf-1.0.3/.github/workflows/test.yml rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/AUTHORS (72%) rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/CMakeLists.txt (57%) create mode 100644 vendor/paraconf-1.0.3/COPYRIGHT.md create mode 100644 vendor/paraconf-1.0.3/LICENSES/MIT.txt rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/README.md (54%) rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/TODO.md (55%) create mode 100644 vendor/paraconf-1.0.3/VERSION create mode 100644 vendor/paraconf-1.0.3/VERSION.license rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/cmake/Findyaml.cmake (66%) create mode 100644 vendor/paraconf-1.0.3/cmake/paraconfConfig.cmake create mode 100755 vendor/paraconf-1.0.3/cmake/version-uid create mode 100644 vendor/paraconf-1.0.3/example/CMakeLists.txt rename vendor/{paraconf-1.0.0 => paraconf-1.0.3}/example/example.c (92%) rename vendor/{paraconf-1.0.0 => paraconf-1.0.3}/example/example.f90 (54%) rename vendor/{paraconf-1.0.0 => paraconf-1.0.3}/example/example.yml (68%) create mode 100644 vendor/paraconf-1.0.3/include/paraconf.F90 rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/include/paraconf.h (82%) rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/include/paraconf_f90.h (65%) create mode 100644 vendor/paraconf-1.0.3/include/paraconf_f90_consts.h create mode 100644 vendor/paraconf-1.0.3/include/paraconf_f90_types.h create mode 100644 vendor/paraconf-1.0.3/include/paraconff.h rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/src/api.c (86%) rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/src/fortran/paraconf.f90 (80%) rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/src/fortran/paraconf_f90_c.h (65%) rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/src/status.c (58%) create mode 100644 vendor/paraconf-1.0.3/src/status.h create mode 100644 vendor/paraconf-1.0.3/src/tools.h rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/src/ypath.c (84%) create mode 100644 vendor/paraconf-1.0.3/src/ypath.h create mode 100644 vendor/paraconf-1.0.3/tests/CMakeLists.txt rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/tests/test1.c (63%) rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/tests/test2.f90 (77%) rename vendor/{paraconf-1.0.0/paraconf => paraconf-1.0.3}/tests/test_data.yml (70%) delete mode 100644 vendor/pybind11-2.13.1/MANIFEST.in delete mode 100644 vendor/pybind11-2.13.1/docs/Makefile delete mode 100644 vendor/pybind11-2.13.1/docs/advanced/cast/custom.rst delete mode 100644 vendor/pybind11-2.13.1/docs/advanced/embedding.rst delete mode 100644 vendor/pybind11-2.13.1/docs/advanced/smart_ptrs.rst delete mode 100644 vendor/pybind11-2.13.1/docs/changelog.rst delete mode 100644 vendor/pybind11-2.13.1/docs/requirements.txt delete mode 100644 vendor/pybind11-2.13.1/pybind11/__main__.py delete mode 100644 vendor/pybind11-2.13.1/pybind11/_version.py delete mode 100644 vendor/pybind11-2.13.1/pyproject.toml delete mode 100644 vendor/pybind11-2.13.1/setup.cfg delete mode 100644 vendor/pybind11-2.13.1/setup.py delete mode 100644 vendor/pybind11-2.13.1/tests/extra_python_package/test_files.py delete mode 100644 vendor/pybind11-2.13.1/tests/requirements.txt delete mode 100644 vendor/pybind11-2.13.1/tests/test_buffers.py delete mode 100644 vendor/pybind11-2.13.1/tests/test_pickling.py delete mode 100644 vendor/pybind11-2.13.1/tests/test_stl.py delete mode 100755 vendor/pybind11-2.13.1/tools/make_changelog.py delete mode 100644 vendor/pybind11-2.13.1/tools/pyproject.toml delete mode 100644 vendor/pybind11-2.13.1/tools/setup_global.py.in delete mode 100644 vendor/pybind11-2.13.1/tools/setup_main.py.in rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.appveyor.yml (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.clang-format (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.clang-tidy (96%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.cmake-format.yaml (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.codespell-ignore-lines (69%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.gitattributes (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/CODEOWNERS (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/CONTRIBUTING.md (71%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/ISSUE_TEMPLATE/bug-report.yml (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/ISSUE_TEMPLATE/config.yml (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/dependabot.yml (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/labeler.yml (89%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/labeler_merged.yml (82%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/matchers/pylint.json (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/pull_request_template.md (56%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/workflows/ci.yml (71%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/workflows/configure.yml (57%) create mode 100644 vendor/pybind11-3.0.1/.github/workflows/docs-link.yml rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/workflows/format.yml (68%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/workflows/labeler.yml (100%) create mode 100644 vendor/pybind11-3.0.1/.github/workflows/nightlies.yml rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/workflows/pip.yml (81%) create mode 100644 vendor/pybind11-3.0.1/.github/workflows/reusable-standard.yml create mode 100644 vendor/pybind11-3.0.1/.github/workflows/tests-cibw.yml rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.github/workflows/upstream.yml (100%) create mode 100644 vendor/pybind11-3.0.1/.gitignore rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.pre-commit-config.yaml (87%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/.readthedocs.yml (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/CMakeLists.txt (70%) create mode 100644 vendor/pybind11-3.0.1/CMakePresets.json rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/LICENSE (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/README.rst (81%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/SECURITY.md (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/Doxyfile (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/_static/css/custom.css (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/cast/chrono.rst (100%) create mode 100644 vendor/pybind11-3.0.1/docs/advanced/cast/custom.rst rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/cast/eigen.rst (99%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/cast/functional.rst (98%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/cast/index.rst (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/cast/overview.rst (98%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/cast/stl.rst (97%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/cast/strings.rst (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/classes.rst (88%) create mode 100644 vendor/pybind11-3.0.1/docs/advanced/deadlock.md create mode 100644 vendor/pybind11-3.0.1/docs/advanced/deprecated.rst create mode 100644 vendor/pybind11-3.0.1/docs/advanced/embedding.rst rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/exceptions.rst (95%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/functions.rst (97%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/misc.rst (67%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/pycpp/index.rst (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/pycpp/numpy.rst (90%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/pycpp/object.rst (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/advanced/pycpp/utilities.rst (100%) create mode 100644 vendor/pybind11-3.0.1/docs/advanced/smart_ptrs.rst rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/basics.rst (95%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/benchmark.py (93%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/benchmark.rst (98%) create mode 100644 vendor/pybind11-3.0.1/docs/changelog.md rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/classes.rst (70%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/cmake/index.rst (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/compiling.rst (93%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/conf.py (97%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/faq.rst (84%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/index.rst (96%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/installing.rst (99%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/limitations.rst (92%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/pybind11-logo.png (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/pybind11_vs_boost_python1.png (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/pybind11_vs_boost_python1.svg (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/pybind11_vs_boost_python2.png (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/pybind11_vs_boost_python2.svg (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/reference.rst (96%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/release.rst (66%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/requirements.in (89%) create mode 100644 vendor/pybind11-3.0.1/docs/requirements.txt rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/docs/upgrade.rst (78%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/attr.h (91%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/buffer_info.h (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/cast.h (75%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/chrono.h (97%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/common.h (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/complex.h (100%) create mode 100644 vendor/pybind11-3.0.1/include/pybind11/conduit/README.txt create mode 100644 vendor/pybind11-3.0.1/include/pybind11/conduit/pybind11_conduit_v1.h create mode 100644 vendor/pybind11-3.0.1/include/pybind11/conduit/pybind11_platform_abi_id.h create mode 100644 vendor/pybind11-3.0.1/include/pybind11/conduit/wrap_include_python_h.h create mode 100644 vendor/pybind11-3.0.1/include/pybind11/critical_section.h rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/detail/class.h (87%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/detail/common.h (78%) create mode 100644 vendor/pybind11-3.0.1/include/pybind11/detail/cpp_conduit.h rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/detail/descr.h (72%) create mode 100644 vendor/pybind11-3.0.1/include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h create mode 100644 vendor/pybind11-3.0.1/include/pybind11/detail/exception_translation.h create mode 100644 vendor/pybind11-3.0.1/include/pybind11/detail/function_record_pyobject.h rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/detail/init.h (75%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/detail/internals.h (55%) create mode 100644 vendor/pybind11-3.0.1/include/pybind11/detail/native_enum_data.h create mode 100644 vendor/pybind11-3.0.1/include/pybind11/detail/pybind11_namespace_macros.h create mode 100644 vendor/pybind11-3.0.1/include/pybind11/detail/struct_smart_holder.h rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/detail/type_caster_base.h (69%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/detail/typeid.h (100%) create mode 100644 vendor/pybind11-3.0.1/include/pybind11/detail/using_smart_holder.h create mode 100644 vendor/pybind11-3.0.1/include/pybind11/detail/value_and_holder.h rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/eigen.h (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/eigen/common.h (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/eigen/matrix.h (96%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/eigen/tensor.h (95%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/embed.h (78%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/eval.h (91%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/functional.h (56%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/gil.h (77%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/gil_safe_call_once.h (94%) create mode 100644 vendor/pybind11-3.0.1/include/pybind11/gil_simple.h rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/iostream.h (100%) create mode 100644 vendor/pybind11-3.0.1/include/pybind11/native_enum.h rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/numpy.h (89%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/operators.h (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/options.h (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/pybind11.h (74%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/pytypes.h (96%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/stl.h (55%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/stl/filesystem.h (75%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/stl_bind.h (95%) create mode 100644 vendor/pybind11-3.0.1/include/pybind11/subinterpreter.h create mode 100644 vendor/pybind11-3.0.1/include/pybind11/trampoline_self_life_support.h rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/type_caster_pyobject_ptr.h (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/include/pybind11/typing.h (62%) create mode 100644 vendor/pybind11-3.0.1/include/pybind11/warnings.h rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/noxfile.py (60%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/pybind11/__init__.py (67%) create mode 100644 vendor/pybind11-3.0.1/pybind11/__main__.py create mode 100644 vendor/pybind11-3.0.1/pybind11/_version.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/pybind11/commands.py (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/pybind11/py.typed (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/pybind11/setup_helpers.py (99%) create mode 100644 vendor/pybind11-3.0.1/pyproject.toml rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/CMakeLists.txt (79%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/conftest.py (67%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/constructor_stats.h (97%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/cross_module_gil_utils.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/cross_module_interleaved_error_already_set.cpp (100%) create mode 100644 vendor/pybind11-3.0.1/tests/custom_exceptions.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/eigen_tensor_avoid_stl_array.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/env.py (78%) create mode 100644 vendor/pybind11-3.0.1/tests/exo_planet_c_api.cpp create mode 100644 vendor/pybind11-3.0.1/tests/exo_planet_pybind11.cpp rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/extra_python_package/pytest.ini (100%) create mode 100644 vendor/pybind11-3.0.1/tests/extra_python_package/test_files.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/extra_setuptools/pytest.ini (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/extra_setuptools/test_setuphelper.py (100%) create mode 100644 vendor/pybind11-3.0.1/tests/home_planet_very_lonely_traveler.cpp rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/local_bindings.h (90%) create mode 100644 vendor/pybind11-3.0.1/tests/mod_per_interpreter_gil.cpp create mode 100644 vendor/pybind11-3.0.1/tests/mod_shared_interpreter_gil.cpp rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/object.h (100%) create mode 100644 vendor/pybind11-3.0.1/tests/pure_cpp/CMakeLists.txt create mode 100644 vendor/pybind11-3.0.1/tests/pure_cpp/smart_holder_poc.h create mode 100644 vendor/pybind11-3.0.1/tests/pure_cpp/smart_holder_poc_test.cpp rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/pybind11_cross_module_tests.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/pybind11_tests.cpp (95%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/pybind11_tests.h (81%) create mode 100644 vendor/pybind11-3.0.1/tests/pyproject.toml rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/pytest.ini (91%) create mode 100644 vendor/pybind11-3.0.1/tests/requirements.txt rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_async.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_async.py (78%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_buffers.cpp (57%) create mode 100644 vendor/pybind11-3.0.1/tests/test_buffers.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_builtin_casters.cpp (98%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_builtin_casters.py (94%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_call_policies.cpp (98%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_call_policies.py (92%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_callbacks.cpp (88%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_callbacks.py (85%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_chrono.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_chrono.py (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_class.cpp (95%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_class.py (87%) create mode 100644 vendor/pybind11-3.0.1/tests/test_class_release_gil_before_calling_cpp_dtor.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_release_gil_before_calling_cpp_dtor.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_basic.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_basic.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_disowning.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_disowning.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_disowning_mi.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_disowning_mi.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_factory_constructors.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_factory_constructors.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_inheritance.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_inheritance.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_mi_thunks.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_mi_thunks.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_property.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_property.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_property_non_owning.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_property_non_owning.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_shared_ptr_copy_move.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_shared_ptr_copy_move.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_trampoline_basic.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_trampoline_basic.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_trampoline_self_life_support.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_trampoline_self_life_support.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_trampoline_shared_from_this.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_trampoline_shared_from_this.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_trampoline_shared_ptr_cpp_arg.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_trampoline_shared_ptr_cpp_arg.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_trampoline_unique_ptr.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_trampoline_unique_ptr.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_unique_ptr_custom_deleter.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_unique_ptr_custom_deleter.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_unique_ptr_member.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_unique_ptr_member.py create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_virtual_py_cpp_mix.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_class_sh_virtual_py_cpp_mix.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_cmake_build/CMakeLists.txt (77%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_cmake_build/embed.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_cmake_build/installed_embed/CMakeLists.txt (66%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_cmake_build/installed_function/CMakeLists.txt (66%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_cmake_build/installed_target/CMakeLists.txt (76%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_cmake_build/main.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_cmake_build/subdirectory_embed/CMakeLists.txt (75%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_cmake_build/subdirectory_function/CMakeLists.txt (72%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_cmake_build/subdirectory_target/CMakeLists.txt (75%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_cmake_build/test.py (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_const_name.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_const_name.py (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_constants_and_functions.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_constants_and_functions.py (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_copy_move.cpp (99%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_copy_move.py (95%) create mode 100644 vendor/pybind11-3.0.1/tests/test_cpp_conduit.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_cpp_conduit.py create mode 100644 vendor/pybind11-3.0.1/tests/test_cpp_conduit_traveler_bindings.h create mode 100644 vendor/pybind11-3.0.1/tests/test_cpp_conduit_traveler_types.h create mode 100644 vendor/pybind11-3.0.1/tests/test_cross_module_rtti/CMakeLists.txt create mode 100644 vendor/pybind11-3.0.1/tests/test_cross_module_rtti/bindings.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_cross_module_rtti/catch.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_cross_module_rtti/lib.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_cross_module_rtti/lib.h create mode 100644 vendor/pybind11-3.0.1/tests/test_cross_module_rtti/test_cross_module_rtti.cpp rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_custom_type_casters.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_custom_type_casters.py (96%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_custom_type_setup.cpp (62%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_custom_type_setup.py (90%) create mode 100644 vendor/pybind11-3.0.1/tests/test_docs_advanced_cast_custom.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_docs_advanced_cast_custom.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_docstring_options.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_docstring_options.py (84%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_eigen_matrix.cpp (98%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_eigen_matrix.py (90%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_eigen_tensor.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_eigen_tensor.inl (94%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_eigen_tensor.py (79%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_embed/CMakeLists.txt (75%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_embed/catch.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_embed/external_module.cpp (75%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_embed/test_interpreter.cpp (85%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_embed/test_interpreter.py (100%) create mode 100644 vendor/pybind11-3.0.1/tests/test_embed/test_subinterpreter.cpp rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_embed/test_trampoline.py (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_enum.cpp (90%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_enum.py (77%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_eval.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_eval.py (94%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_eval_call.py (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_exceptions.cpp (91%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_exceptions.h (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_exceptions.py (92%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_factory_constructors.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_factory_constructors.py (93%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_gil_scoped.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_gil_scoped.py (80%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_iostream.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_iostream.py (98%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_kwargs_and_defaults.cpp (97%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_kwargs_and_defaults.py (79%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_local_bindings.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_local_bindings.py (98%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_methods_and_attributes.cpp (99%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_methods_and_attributes.py (92%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_modules.cpp (87%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_modules.py (85%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_multiple_inheritance.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_multiple_inheritance.py (94%) create mode 100644 vendor/pybind11-3.0.1/tests/test_multiple_interpreters.py create mode 100644 vendor/pybind11-3.0.1/tests/test_native_enum.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_native_enum.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_numpy_array.cpp (87%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_numpy_array.py (87%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_numpy_dtypes.cpp (83%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_numpy_dtypes.py (91%) create mode 100644 vendor/pybind11-3.0.1/tests/test_numpy_scalars.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_numpy_scalars.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_numpy_vectorize.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_numpy_vectorize.py (93%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_opaque_types.cpp (94%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_opaque_types.py (79%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_operator_overloading.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_operator_overloading.py (92%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_pickling.cpp (97%) create mode 100644 vendor/pybind11-3.0.1/tests/test_pickling.py create mode 100644 vendor/pybind11-3.0.1/tests/test_potentially_slicing_weak_ptr.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_potentially_slicing_weak_ptr.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_python_multiple_inheritance.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_python_multiple_inheritance.py (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_pytypes.cpp (75%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_pytypes.py (65%) create mode 100644 vendor/pybind11-3.0.1/tests/test_scoped_critical_section.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_scoped_critical_section.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_sequences_and_iterators.cpp (99%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_sequences_and_iterators.py (79%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_smart_ptr.cpp (81%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_smart_ptr.py (84%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_stl.cpp (81%) create mode 100644 vendor/pybind11-3.0.1/tests/test_stl.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_stl_binders.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_stl_binders.py (94%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_tagbased_polymorphic.cpp (98%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_tagbased_polymorphic.py (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_thread.cpp (91%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_thread.py (54%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_type_caster_pyobject_ptr.cpp (97%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_type_caster_pyobject_ptr.py (97%) create mode 100644 vendor/pybind11-3.0.1/tests/test_type_caster_std_function_specializations.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_type_caster_std_function_specializations.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_union.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_union.py (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_unnamed_namespace_a.cpp (91%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_unnamed_namespace_a.py (76%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_unnamed_namespace_b.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_unnamed_namespace_b.py (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_vector_unique_ptr_member.cpp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_vector_unique_ptr_member.py (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_virtual_functions.cpp (99%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/test_virtual_functions.py (97%) create mode 100644 vendor/pybind11-3.0.1/tests/test_warnings.cpp create mode 100644 vendor/pybind11-3.0.1/tests/test_warnings.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/valgrind-numpy-scipy.supp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tests/valgrind-python.supp (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/FindCatch.cmake (97%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/FindEigen3.cmake (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/FindPythonLibsNew.cmake (95%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/JoinPaths.cmake (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/check-style.sh (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/cmake_uninstall.cmake.in (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/codespell_ignore_lines_from_errors.py (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/libsize.py (100%) create mode 100755 vendor/pybind11-3.0.1/tools/make_changelog.py create mode 100755 vendor/pybind11-3.0.1/tools/make_global.py rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/pybind11.pc.in (100%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/pybind11Common.cmake (81%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/pybind11Config.cmake.in (92%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/pybind11GuessPythonExtSuffix.cmake (98%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/pybind11NewTools.cmake (91%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/pybind11Tools.cmake (82%) rename vendor/{pybind11-2.13.1 => pybind11-3.0.1}/tools/test-pybind11GuessPythonExtSuffix.cmake (99%) delete mode 100644 vendor/spdlog-1.14.1/include/spdlog/fmt/bundled/core.h delete mode 100644 vendor/spdlog-1.14.1/include/spdlog/fmt/bundled/locale.h delete mode 100644 vendor/spdlog-1.14.1/include/spdlog/fmt/bundled/ostream.h delete mode 100644 vendor/spdlog-1.14.1/include/spdlog/fmt/bundled/std.h delete mode 100644 vendor/spdlog-1.14.1/include/spdlog/fmt/bundled/xchar.h rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/.clang-format (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/.clang-tidy (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/.git-blame-ignore-revs (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/.gitattributes (100%) rename vendor/{spdlog-1.14.1/.github/workflows/ci.yml => spdlog-1.15.3/.github/workflows/linux.yml} (69%) create mode 100644 vendor/spdlog-1.15.3/.github/workflows/macos.yml create mode 100644 vendor/spdlog-1.15.3/.github/workflows/windows.yml create mode 100644 vendor/spdlog-1.15.3/.gitignore rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/CMakeLists.txt (86%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/INSTALL (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/LICENSE (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/README.md (88%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/appveyor.yml (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/bench/CMakeLists.txt (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/bench/async_bench.cpp (99%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/bench/bench.cpp (99%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/bench/formatter-bench.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/bench/latency.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/bench/utils.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/cmake/ide.cmake (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/cmake/pch.h.in (97%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/cmake/spdlog.pc.in (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/cmake/spdlogCPack.cmake (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/cmake/spdlogConfig.cmake.in (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/cmake/utils.cmake (82%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/cmake/version.rc.in (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/example/CMakeLists.txt (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/example/example.cpp (95%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/async.h (98%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/async_logger-inl.h (85%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/async_logger.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/cfg/argv.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/cfg/env.h (89%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/cfg/helpers-inl.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/cfg/helpers.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/common-inl.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/common.h (98%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/backtracer-inl.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/backtracer.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/circular_q.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/console_globals.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/file_helper-inl.h (98%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/file_helper.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/fmt_helper.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/log_msg-inl.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/log_msg.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/log_msg_buffer-inl.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/log_msg_buffer.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/mpmc_blocking_q.h (96%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/null_mutex.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/os-inl.h (94%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/os.h (95%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/periodic_worker-inl.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/periodic_worker.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/registry-inl.h (95%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/registry.h (97%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/synchronous_factory.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/tcp_client-windows.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/tcp_client.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/thread_pool-inl.h (89%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/thread_pool.h (85%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/udp_client-windows.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/udp_client.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/details/windows_include.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/bin_to_hex.h (98%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/bundled/args.h (55%) create mode 100644 vendor/spdlog-1.15.3/include/spdlog/fmt/bundled/base.h rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/bundled/chrono.h (61%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/bundled/color.h (65%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/bundled/compile.h (79%) create mode 100644 vendor/spdlog-1.15.3/include/spdlog/fmt/bundled/core.h rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/bundled/fmt.license.rst (95%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/bundled/format-inl.h (87%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/bundled/format.h (63%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/bundled/os.h (63%) create mode 100644 vendor/spdlog-1.15.3/include/spdlog/fmt/bundled/ostream.h rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/bundled/printf.h (58%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/bundled/ranges.h (53%) create mode 100644 vendor/spdlog-1.15.3/include/spdlog/fmt/bundled/std.h create mode 100644 vendor/spdlog-1.15.3/include/spdlog/fmt/bundled/xchar.h rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/chrono.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/compile.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/fmt.h (91%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/ostr.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/ranges.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/std.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fmt/xchar.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/formatter.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/fwd.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/logger-inl.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/logger.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/mdc.h (76%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/pattern_formatter-inl.h (99%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/pattern_formatter.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/android_sink.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/ansicolor_sink-inl.h (89%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/ansicolor_sink.h (94%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/base_sink-inl.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/base_sink.h (88%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/basic_file_sink-inl.h (87%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/basic_file_sink.h (99%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/callback_sink.h (98%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/daily_file_sink.h (98%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/dist_sink.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/dup_filter_sink.h (92%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/hourly_file_sink.h (97%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/kafka_sink.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/mongo_sink.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/msvc_sink.h (96%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/null_sink.h (95%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/ostream_sink.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/qt_sinks.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/ringbuffer_sink.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/rotating_file_sink-inl.h (77%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/rotating_file_sink.h (65%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/sink-inl.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/sink.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/stdout_color_sinks-inl.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/stdout_color_sinks.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/stdout_sinks-inl.h (95%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/stdout_sinks.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/syslog_sink.h (98%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/systemd_sink.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/tcp_sink.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/udp_sink.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/win_eventlog_sink.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/wincolor_sink-inl.h (93%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/sinks/wincolor_sink.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/spdlog-inl.h (95%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/spdlog.h (94%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/stopwatch.h (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/tweakme.h (96%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/include/spdlog/version.h (86%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/logos/jetbrains-variant-4.svg (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/logos/spdlog.png (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/scripts/ci_setup_clang.sh (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/scripts/extract_version.py (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/scripts/format.sh (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/src/async.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/src/bundled_fmtlib_format.cpp (93%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/src/cfg.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/src/color_sinks.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/src/file_sinks.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/src/spdlog.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/src/stdout_sinks.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/CMakeLists.txt (85%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/includes.h (91%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/main.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_async.cpp (83%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_backtrace.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_bin_to_hex.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_cfg.cpp (96%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_circular_q.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_create_dir.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_custom_callbacks.cpp (89%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_daily_logger.cpp (95%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_dup_filter.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_errors.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_eventlog.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_file_helper.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_file_logging.cpp (53%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_fmt_helper.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_macros.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_misc.cpp (74%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_mpmc_q.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_pattern_formatter.cpp (96%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_registry.cpp (89%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_sink.h (93%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_stdout_api.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_stopwatch.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_systemd.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/test_time_point.cpp (100%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/utils.cpp (97%) rename vendor/{spdlog-1.14.1 => spdlog-1.15.3}/tests/utils.h (100%) delete mode 100644 vendor/zpp-1.0.16/.gitignore delete mode 100644 vendor/zpp-1.0.16/AUTHORS delete mode 100644 vendor/zpp-1.0.16/CMakeLists.txt delete mode 100644 vendor/zpp-1.0.16/MANIFEST.in delete mode 100755 vendor/zpp-1.0.16/bin/zpp delete mode 100755 vendor/zpp-1.0.16/bin/zpp.in delete mode 100644 vendor/zpp-1.0.16/examples/cmake_find/CMakeLists.txt delete mode 100644 vendor/zpp-1.0.16/examples/cmake_subdirectory/CMakeLists.txt delete mode 100644 vendor/zpp-1.0.16/examples/makefile/Makefile delete mode 100755 vendor/zpp-1.0.16/release delete mode 100755 vendor/zpp-1.0.16/setup.py delete mode 120000 vendor/zpp-1.0.16/zpp/cmake/BppConfig.cmake delete mode 120000 vendor/zpp-1.0.16/zpp/cmake/BppConfigVersion.cmake delete mode 100644 vendor/zpp-1.0.16/zpp/cmake/ZppConfig.cmake delete mode 100644 vendor/zpp-1.0.16/zpp/cmake/ZppConfigVersion.cmake delete mode 100644 vendor/zpp-1.0.16/zpp/include/config.Gnu.zpp.sh delete mode 100644 vendor/zpp-1.0.16/zpp/include/config.Intel.zpp.sh delete mode 100644 vendor/zpp-1.0.16/zpp/include/config.PGI.zpp.sh delete mode 100644 vendor/zpp-1.0.16/zpp/include/config.XL.zpp.sh delete mode 100644 vendor/zpp-1.0.16/zpp/include/hdf5_fortran.zpp.sh delete mode 100644 vendor/zpp-1.0.16/zpp/version.py delete mode 100644 vendor/zpp-1.0.16/zpp/zpp.mk create mode 100644 vendor/zpp-1.1.0/.gitignore create mode 100644 vendor/zpp-1.1.0/AUTHORS create mode 100644 vendor/zpp-1.1.0/CMakeLists.txt create mode 100644 vendor/zpp-1.1.0/LICENSES/MIT.txt create mode 100644 vendor/zpp-1.1.0/MANIFEST.in rename vendor/{zpp-1.0.16 => zpp-1.1.0}/README.md (89%) create mode 100755 vendor/zpp-1.1.0/bin/zpp create mode 100755 vendor/zpp-1.1.0/bin/zpp.in create mode 100755 vendor/zpp-1.1.0/bin/zpp_register create mode 100644 vendor/zpp-1.1.0/examples/cmake_find/CMakeLists.txt rename vendor/{zpp-1.0.16 => zpp-1.1.0}/examples/cmake_find/example.F90.zpp (52%) create mode 100644 vendor/zpp-1.1.0/examples/cmake_subdirectory/CMakeLists.txt rename vendor/{zpp-1.0.16 => zpp-1.1.0}/examples/cmake_subdirectory/example.F90.zpp (52%) create mode 100644 vendor/zpp-1.1.0/examples/makefile/Makefile rename vendor/{zpp-1.0.16 => zpp-1.1.0}/examples/makefile/example.F90.zpp (52%) create mode 100644 vendor/zpp-1.1.0/pyproject.toml create mode 100755 vendor/zpp-1.1.0/release create mode 100755 vendor/zpp-1.1.0/setup.py rename vendor/{zpp-1.0.16 => zpp-1.1.0}/zpp/__init__.py (72%) rename vendor/{zpp-1.0.16 => zpp-1.1.0}/zpp/cmake/TestFortType.cmake (74%) rename vendor/{zpp-1.0.16 => zpp-1.1.0}/zpp/cmake/Zpp.cmake (67%) create mode 100644 vendor/zpp-1.1.0/zpp/cmake/ZppConfig.cmake create mode 100644 vendor/zpp-1.1.0/zpp/cmake/ZppConfigVersion.cmake rename vendor/{zpp-1.0.16 => zpp-1.1.0}/zpp/include/base.zpp.sh (66%) create mode 100644 vendor/zpp-1.1.0/zpp/include/config.Gnu.zpp.sh create mode 100644 vendor/zpp-1.1.0/zpp/include/config.Intel.zpp.sh create mode 100644 vendor/zpp-1.1.0/zpp/include/config.PGI.zpp.sh create mode 100644 vendor/zpp-1.1.0/zpp/include/config.XL.zpp.sh rename vendor/{zpp-1.0.16 => zpp-1.1.0}/zpp/include/fortran.zpp.sh (65%) create mode 100644 vendor/zpp-1.1.0/zpp/include/hdf5_fortran.zpp.sh create mode 100644 vendor/zpp-1.1.0/zpp/registration.py create mode 100644 vendor/zpp-1.1.0/zpp/version.py create mode 100644 vendor/zpp-1.1.0/zpp/zpp.mk diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..3b0d3c58a --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,51 @@ +#============================================================================= +# Copyright (C) 2025 Centre national de la recherche scientifique (CNRS) +# Copyright (C) 2025 Commissariat a l'énergie atomique et aux énergies alternatives (CEA) +# Copyright (C) 2025 Université Paris-Saclay +# Copyright (C) 2025 Université de Versailles Saint-Quentin-en-Yvelines (UVSQ) +# +# SPDX-License-Identifier: BSD-3-Clause +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the names of CEA, nor the names of the contributors may be used to +# endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +# Default owners, unless something else is specified +* yushan.wang@cea.fr julien.bigot@cea.fr + +# Owners of the Deisa plugin +plugins/deisa/ bmartin@cea.fr julien.bigot@cea.fr + +# Owners of the buildsystem & packaging stuff +cmake/ bmartin@cea.fr julien.bigot@cea.fr +CMakeLists.txt bmartin@cea.fr julien.bigot@cea.fr +*.cmake bmartin@cea.fr julien.bigot@cea.fr +/spack.yaml bmartin@cea.fr julien.bigot@cea.fr +/PACKAGING.md bmartin@cea.fr julien.bigot@cea.fr + +# Owners of the CI/CD stuff +/.github/ bmartin@cea.fr julien.bigot@cea.fr +/bin/ bmartin@cea.fr julien.bigot@cea.fr +/tools bmartin@cea.fr julien.bigot@cea.fr diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml index 911756d7d..577a33514 100644 --- a/.github/actions/test/action.yml +++ b/.github/actions/test/action.yml @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2024-2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -44,21 +44,22 @@ runs: JOBID="$(echo "${{github.run_id}}"|md5sum|cut -b 1)" if [[ "01234567" == *"${JOBID}"* ]]; then export PDI_PLUGIN_PATH=/tmp/pdi_plugins; fi export MAKEFLAGS='-j 4' - export CTEST_FLAGS="--output-junit /tests.xml" - export TEST_DIR="/tmp" - /src/bin/build_and_run_all_tests + export CTEST_DIR="/tmp/tests_output" + export TEST_DIR="/tmp_dir_test" + exec /src/bin/build_and_run_all_tests EOF docker run \ --cidfile='docker.cid' \ -v ${PWD}:/src:ro \ - --tmpfs /tmp:exec \ + --tmpfs /tmp_dir_test:exec,mode=1777 \ ${{inputs.image}} \ bash /src/run.sh - if docker cp "$(cat docker.cid)":/tests.xml tests.xml + if docker cp "$(cat docker.cid)":/tmp/tests_output ./ then echo "with_report=true" >> "$GITHUB_OUTPUT" else echo "with_report=false" >> "$GITHUB_OUTPUT" fi - id: Publish - uses: mikepenz/action-junit-report@v4 - if: always() && steps.test.outputs.with_report == 'true' # always run even if the previous step fails - with: { report_paths: 'tests.xml' } + uses: mikepenz/action-junit-report@v5 + if: always() && steps.test.outputs.with_report == 'true' + with: + report_paths: 'tests_output/tests_*.xml' diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index eb10fa34d..acef804c8 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -6,7 +6,8 @@ Before merging your code, please check the following: * [ ] you have added a line describing your changes to the Changelog; * [ ] you have added unit tests for any new or improved feature; -* [ ] In case you updated dependencies, you have checked pdi/docs/CheckList.md +* [ ] in case you updated dependencies, you have checked pdi/docs/CheckList.md; +* [ ] in case of a change in pdi.h, this same change must be reflected in no-pdi/include/pdi.h; * you have checked your code format: - [ ] you have checked that you respect all conventions specified in CONTRIBUTING.md; - [ ] you have checked that the indentation and formatting conforms to the `.clang-format`; diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index ae776b689..76ff027eb 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -33,7 +33,7 @@ on: branches: [ main, 'v[0-9]+\.[0-9]+' ] tags: '[0-9]+\.[0-9]+\.[0-9]+' pull_request: - types: [ready_for_review] + workflow_dispatch: jobs: pages: runs-on: ubuntu-24.04 @@ -43,6 +43,7 @@ jobs: with: { submodules: recursive } - name: Build run: | + IMG="ghcr.io/pdidev/debian/unstable/openmpi/all:v3" cat<<-'EOF' > run.sh set -xe cmake -DBUILD_DOCUMENTATION=ON -DBUILD_BENCHMARKING=OFF -DBUILD_TESTING=OFF /src/pdi @@ -55,9 +56,9 @@ jobs: docker run \ --cidfile='docker.cid' \ -v ${PWD}:/src:ro \ - ghcr.io/pdidev/debian/unstable/openmpi/all:v3 \ + "${IMG}" \ bash /src/run.sh - docker cp "$(cat docker.cid)":$(docker image inspect -f '{{.Config.WorkingDir}}' ghcr.io/pdidev/debian/unstable/openmpi/all:v3)/docs/html public + docker cp "$(cat docker.cid)":$(docker image inspect -f '{{.Config.WorkingDir}}' "${IMG}")/docs/html public - name: Archive production artifacts uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 615cc6696..9edea12d3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2024-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -30,10 +30,38 @@ name: tests on: push: { branches: [ main, 'v[0-9]+.[0-9]+' ] } - pull_request: - types: [ready_for_review] + pull_request: + workflow_dispatch: jobs: + indent: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - run: exec ./bin/test_indent + first: # do a first run so as not to needlessly use all resources for all to fail + needs: indent + runs-on: ubuntu-24.04 + steps: + - name: Checkout branch + uses: actions/checkout@v6 + with: { submodules: recursive } + - name: Test + uses: ./.github/actions/test/ + with: + image: 'ghcr.io/pdidev/spack/latest/clang/mpich/all:v4' + second: # do a second run at the opposite of the spectrum from the first + needs: first + runs-on: ubuntu-24.04 + steps: + - name: Checkout branch + uses: actions/checkout@v6 + with: { submodules: recursive } + - name: Test + uses: ./.github/actions/test/ + with: + image: 'ghcr.io/pdidev/ubuntu/jammy/openmpi/mini:v4' spack: + needs: second strategy: fail-fast: false matrix: @@ -41,28 +69,75 @@ jobs: compiler: ['gcc', 'clang'] mpi: ['openmpi', 'mpich'] variant: ['mini', 'all'] + # exclude config already done in first + exclude: [ { version: latest, compiler: clang, mpi: mpich, variant: all } ] runs-on: ubuntu-24.04 steps: - name: Checkout branch - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: { submodules: recursive } - name: Test uses: ./.github/actions/test/ with: - image: 'ghcr.io/pdidev/spack/${{matrix.version}}/${{matrix.compiler}}/${{matrix.mpi}}/${{matrix.variant}}:v3' + image: 'ghcr.io/pdidev/spack/${{matrix.version}}/${{matrix.compiler}}/${{matrix.mpi}}/${{matrix.variant}}:v4' debuntu: + needs: second strategy: fail-fast: false matrix: - base: ['ubuntu/focal', 'ubuntu/rolling', 'debian/bookworm', 'debian/unstable'] + base: ['ubuntu/jammy', 'ubuntu/rolling', 'debian/bookworm', 'debian/unstable'] mpi: ['openmpi', 'mpich'] variant: ['mini', 'all'] + # exclude config already done in second + exclude: [ { base: 'ubuntu/jammy', mpi: openmpi, variant: mini } ] runs-on: ubuntu-24.04 steps: - name: Checkout branch - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: { submodules: recursive } - name: Test uses: ./.github/actions/test/ with: - image: 'ghcr.io/pdidev/${{matrix.base}}/${{matrix.mpi}}/${{matrix.variant}}:v3' + image: 'ghcr.io/pdidev/${{matrix.base}}/${{matrix.mpi}}/${{matrix.variant}}:v4' + macos: + needs: second + strategy: + fail-fast: false + matrix: + os: [macos-14, macos-15, macos-26] + cxx_std: ['17'] + build_type: ['Debug'] + runs-on: ${{matrix.os}} + env: + MAKEFLAGS: -j4 + CC: clang + CXX: clang++ + CMAKE_BUILD_TYPE: ${{matrix.build_type}} + OMPI_MCA_rmaps_base_oversubscribe: 1 + PRTE_MCA_rmaps_default_mapping_policy: :oversubscribe + PDI_SYSTEM: macos + PDI_COMPILER: clang + PDI_MPI: openmpi + CTEST_DIR: "/tmp/tests_output" + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.14' + - name: Install MPI (macOS) + run: brew install open-mpi + - name: Install Python Dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools pyyaml numpy mpi4py + - name: Set up PDI + uses: actions/checkout@v6 + with: + submodules: recursive + - name: Build PDI + run: bin/build_and_run_all_tests + - name: Publish Test Report + uses: mikepenz/action-junit-report@v5 + if: ( success() || failure() ) # always run even if the previous step fails + with: + report_paths: '/tmp/tests_output/tests_*.xml' \ No newline at end of file diff --git a/AUTHORS b/AUTHORS index 3c80d1114..44ebc8bcb 100644 --- a/AUTHORS +++ b/AUTHORS @@ -6,24 +6,27 @@ Please note this is the list for the distribution mechanism of PDI. The list for each sub-project (including PDI itself) is located in the dedicated sub-project AUTHORS file. +Julian Auriac - CEA (julian.auriac@cea.fr) +* Add pdi deactivation option +* Fix CI bug where tests.xml file could not be written Julien Bigot - CEA (julien.bigot@cea.fr) * Maintainer (Dec. 2014 - ...) * Design and initial implementation -Amal Gueroudji - CEA (agueroudji@anl.gov) -* Deisa plugin creation - Benoit Martin - CEA (bmartin@cea.fr) * CMake maintainer (Oct. 2024 - ...) -* Deisa plugin refactoring François-Xavier Mordant - CEA (francois-xavier.mordant@cea.fr) * Fixed CMake issues, internal API enhancement * Bug fix, JSON plugin Jacques Morice - CEA (jacques.morice@cea.fr) -* fix the directory of hdf5 library for rhel +* Fix the directory of hdf5 library for rhel + +Thomas Padioleau - CEA (thomas.padioleau@cea.fr) +* Added macOS CI +* Fixed CMake issues Tomasz Paluszkiewicz - PSNC (tomaszp@man.poznan.pl) The scientific/academic work is financed from financial resources for science diff --git a/CHANGELOG.md b/CHANGELOG.md index 87c6ed5e2..324335a73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] ### Added +* Enable plugin `decl_netcdf` in macOS CI +* added a `ENABLE_BENCHMARKING` flag to cmake to enable running the benchmarks + as part of the tests (off by default) + [#679](https://github.com/pdidev/pdi/issues/679) ### Changed +* benchmarks are not run as part of the test suite by default anymore, one must + set `ENABLE_BENCHMARKING` to `ON` in Cmake to re-enable them ### Deprecated @@ -23,6 +29,51 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Security +## [1.10.1] - 2026-02-04 + +### Added +* Added tests for using an installed PDI + + +## [1.10.0] - 2026-01-31 + +### Added +* Add "mock PDI", to allow disabling PDI while keeping code syntax unchanged + [#438](https://github.com/pdidev/pdi/issues/438) +* Added macOS CI [#556](https://github.com/pdidev/pdi/issues/556) + +### Changed +* Update the version of dependencies according to our policy: oldest supported + Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: + CMake 3.22, Doxygen 1.9.1, HDF5 1.10.7, mpi4py 3.1.3, NetCDF 4.8.1, + numpy 1.21.5, pyyaml 5.4.1, pybind11 2.9.1, Python 3.10.6, and spdlog 1.9.2 + [#613](https://github.com/pdidev/pdi/issues/613) + +### Removed +* Removed the Deisa plugin that does not match any current version of Deisa + +### Fixed +* Fix an issue where github action wouldn't run due to permission issue + [#585](https://github.com/pdidev/pdi/issues/585) +* Fix a build error in libyaml with recent cmake versions + [#593](https://github.com/pdidev/pdi/issues/593) +* Fix macOS linking issue when installing via root CMakeLists.txt + [#565](https://github.com/pdidev/pdi/issues/565) +* Fix chunking test in decl_hdf5 + [#588](https://github.com/pdidev/pdi/issues/588) +* Fix data validation in decl_hdf5 test after write operation + [#587](https://github.com/pdidev/pdi/issues/587) +* Fix default CMAKE_BUILD_TYPE value + [#617](https://github.com/pdidev/pdi/issues/617) + + +## [1.9.3] - 2026-01-16 + +### Fixed +* Updated embedded versions of paraconf & pybind11 to fix a build issue with + recent cmake [#631](https://github.com/pdidev/pdi/issues/631) + + ## [1.9.2] - 2025-06-13 ### Fixed diff --git a/CMakeLists.txt b/CMakeLists.txt index cc2692a19..035504d7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -31,7 +31,7 @@ ### Project header -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(PDI_DIST LANGUAGES C CXX) @@ -59,8 +59,6 @@ endif() set(USE_DEFAULT AUTO CACHE STRING "Default version of libraries to use; this can be 1) EMBEDDED to use the provided version, 2) SYSTEM to use an already installed version (you can use CMAKE_PREFIX_PATH to specify where to look, or 3) AUTO to use SYSTEM if available and EMBEDDED otherwise") - - # Modules to build option(BUILD_BENCHMARKING "Build PDI benchmarks" ON) @@ -78,7 +76,7 @@ option(BUILD_SHARED_LIBS "Build shared libraries rather than static ones" option(BUILD_TRACE_PLUGIN "Build Trace plugin" ON) option(BUILD_USER_CODE_PLUGIN "Build User-code plugin" ON) option(BUILD_JSON_PLUGIN "Build JSON plugin" OFF) -option(BUILD_DEISA_PLUGIN "Build Deisa plug-in" OFF) +option(ENABLE_BENCHMARKING "Activate benchmarks in the test suite" OFF) option(BUILD_DAMARIS_PLUGIN "Build Damaris plug-in" ON) @@ -86,7 +84,7 @@ option(BUILD_DAMARIS_PLUGIN "Build Damaris plug-in" ON) ### Default build type -if(NOT "${CMAKE_BUILD_TYPE}") +if(NOT DEFINED CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE STRING "Choose the type of build, options are: None Debug Release(default) RelWithDebInfo MinSizeRel ..." FORCE) endif() message(STATUS " **Profile**: Distribution profile is: `${DIST_PROFILE}' (-DDIST_PROFILE=${DIST_PROFILE})") @@ -108,34 +106,19 @@ endforeach() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" - "${CMAKE_CURRENT_SOURCE_DIR}/pdi/cmake" - "${CMAKE_CURRENT_SOURCE_DIR}/plugins/trace/cmake" - "${CMAKE_CURRENT_SOURCE_DIR}/plugins/user_code/cmake") -if("${BUILD_DECL_HDF5_PLUGIN}") - list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/decl_hdf5/cmake") -endif() + "${CMAKE_CURRENT_SOURCE_DIR}/pdi/cmake") if("${BUILD_DECL_NETCDF_PLUGIN}") + # Workaround missing "Prefer h5hl compilers if HDF5_FIND_HL is enabled" in cmake pre-4.1 + if(4.1 VERSION_GREATER "${CMAKE_VERSION}") + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/decl_netcdf/cmake/4.1") + endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/decl_netcdf/cmake") endif() -if("${BUILD_DEISA_PLUGIN}") - list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/deisa/cmake") -endif() +set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" CACHE STRING "" FORCE) + if("${BUILD_DAMARIS_PLUGIN}") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/damaris/cmake") endif() -if("${BUILD_MPI_PLUGIN}") - list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/mpi/cmake") -endif() -if("${BUILD_PYCALL_PLUGIN}") - list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/pycall/cmake") -endif() -if ("${BUILD_JSON_PLUGIN}") - list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/json/cmake") -endif() -if("${BUILD_TESTING}") - list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/example/cmake") -endif() - ### Sanity check @@ -147,7 +130,6 @@ else() mark_as_advanced(CMAKE_POSITION_INDEPENDENT_CODE BUILD_SHARED_LIBS) endif() - if("${BUILD_PYCALL_PLUGIN}" AND NOT "${BUILD_PYTHON}") message(FATAL_ERROR "The Pycall plugin is enabled but Python support is disabled.\n" @@ -187,14 +169,6 @@ if("${BUILD_DECL_NETCDF_PLUGIN}" AND "${BUILD_NETCDF_PARALLEL}" AND NOT "${BUILD ) endif() -if("${BUILD_DEISA_PLUGIN}" AND NOT "${BUILD_PYTHON}") - message(FATAL_ERROR - "Deisa plugin is enabled but Python support is disabled.\n" - " you have the following options:\n" - " * enable Python support => pass `-DBUILD_PYTHON=ON' to cmake\n" - " * do not build the Deisa plugin => pass `-DBUILD_DEISA_PLUGIN=OFF' to cmake" - ) -endif() ### Dependencies @@ -217,9 +191,9 @@ endif() ## Python3 if("${BUILD_PYTHON}") - find_package(Python3Path 3.8.2 REQUIRED COMPONENTS Interpreter Development) + find_package(Python3Path 3.10 REQUIRED COMPONENTS Interpreter Development) elseif("${BUILD_FORTRAN}") - find_package(Python3Path 3.8.2 REQUIRED COMPONENTS Interpreter) + find_package(Python3Path 3.10 REQUIRED COMPONENTS Interpreter) endif() @@ -264,10 +238,11 @@ sbuild_add_dependency(yaml "${USE_DEFAULT}" EMBEDDED_PATH "vendor/libyaml-0.2.5" CMAKE_CACHE_ARGS "-DBUILD_TESTING:BOOL=OFF" - "-DINSTALL_LIB_DIR:STRING=${CMAKE_INSTALL_LIBDIR}" + "-DCMAKE_POLICY_VERSION_MINIMUM:STRING=3.10" # needed until upstream libyaml is updated (https://github.com/yaml/libyaml/pull/314) "-DINSTALL_BIN_DIR:STRING=${CMAKE_INSTALL_BINDIR}" - "-DINSTALL_INCLUDE_DIR:STRING=${CMAKE_INSTALL_INCLUDEDIR}" "-DINSTALL_CMAKE_DIR:STRING=share/yaml/cmake" + "-DINSTALL_INCLUDE_DIR:STRING=${CMAKE_INSTALL_INCLUDEDIR}" + "-DINSTALL_LIB_DIR:STRING=${CMAKE_INSTALL_LIBDIR}" VERSION 0.2.2 ) @@ -280,15 +255,14 @@ if("${BUILD_FORTRAN}") endif() # if ( PDI or ... ) sbuild_add_dependency(paraconf "${USE_DEFAULT}" - EMBEDDED_PATH "vendor/paraconf-1.0.0" + EMBEDDED_PATH "vendor/paraconf-1.0.3" COMPONENTS ${PARACONF_COMPONENTS} - SOURCE_SUBDIR "paraconf" CMAKE_CACHE_ARGS "-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=TRUE" "-DUSE_yaml:STRING=SYSTEM" "-DBUILD_TESTING:BOOL=OFF" DEPENDS "yaml" - VERSION 1.0.0 + VERSION 1.0 ) @@ -296,21 +270,21 @@ sbuild_add_dependency(paraconf "${USE_DEFAULT}" # if ( PDI or ... ) sbuild_add_dependency(spdlog "${USE_DEFAULT}" - EMBEDDED_PATH "vendor/spdlog-1.14.1" + EMBEDDED_PATH "vendor/spdlog-1.15.3" CMAKE_CACHE_ARGS "-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON" "-DSPDLOG_BUILD_BENCH:BOOL=OFF" "-DSPDLOG_BUILD_EXAMPLES:BOOL=OFF" "-DSPDLOG_BUILD_TESTS:BOOL=OFF" "-DSPDLOG_FMT_EXTERNAL:BOOL=OFF" - VERSION 1.5.0 + VERSION 1.9 ) ## Doxygen if("${BUILD_DOCUMENTATION}") - find_package(Doxygen 1.8.17 REQUIRED OPTIONAL_COMPONENTS dot) + find_package(Doxygen 1.9 REQUIRED OPTIONAL_COMPONENTS dot) endif() @@ -336,23 +310,26 @@ if("${BUILD_DECL_HDF5_PLUGIN}" OR "${BUILD_DECL_NETCDF_PLUGIN}") list(APPEND HDF5_CMAKE_CACHE_ARGS "-DHDF5_BUILD_HL_LIB:BOOL=OFF") endif() - find_package(ZLIB) - sbuild_add_dependency(HDF5 "${USE_DEFAULT}" EMBEDDED_PATH "vendor/hdf5-1.12.3" COMPONENTS ${HDF5_COMPONENTS} - MODULE_VARS HDF5_IS_PARALLEL HDF5_C_INCLUDE_DIRS HDF5_C_LIBRARIES HDF5_VERSION + MODULE_VARS HDF5_IS_PARALLEL HDF5_VERSION CMAKE_CACHE_ARGS + -DBUILD_STATIC_LIBS:BOOL=OFF -DBUILD_TESTING:BOOL=OFF -DHDF5_BUILD_EXAMPLES:BOOL=OFF -DHDF5_BUILD_TOOLS:BOOL=ON -DHDF5_BUILD_UTILS:BOOL=OFF - -DHDF5_INSTALL_LIB_DIR:STRING=${CMAKE_INSTALL_LIBDIR} + "-DHDF5_INSTALL_BIN_DIR:STRING=${CMAKE_INSTALL_BINDIR}" + "-DHDF5_INSTALL_CMAKE_DIR:STRING=${CMAKE_INSTALL_DATADIR}/cmake/hdf5" + "-DHDF5_INSTALL_DATA_DIR:STRING=${CMAKE_INSTALL_DATADIR}/hdf5" + "-DHDF5_INSTALL_LIB_DIR:STRING=${CMAKE_INSTALL_LIBDIR}" ${HDF5_CMAKE_CACHE_ARGS} + VERSION ) if("${HDF5_FOUND}") - if(1.10.4 VERSION_GREATER "${HDF5_VERSION}") - message(FATAL_ERROR "HDF5 version ${HDF5_VERSION} found less than required 1.10.4") + if("${HDF5_VERSION}" VERSION_LESS 1.10) + message(FATAL_ERROR "HDF5 version 1.10 at least required, HDF5 ${HDF5_VERSION} found.") endif() if("${BUILD_HDF5_PARALLEL}" AND NOT "${HDF5_IS_PARALLEL}") message(FATAL_ERROR @@ -384,41 +361,30 @@ if("${BUILD_DECL_NETCDF_PLUGIN}") list(APPEND NETCDF_CMAKE_CACHE_ARGS "-DENABLE_PARALLEL4:BOOL=OFF") endif() - set(NETCDF_CPATH "${SBUILD_CPATH}") - set(NETCDF_LIBRARY_PATH "${SBUILD_LIBRARY_PATH}") - - # Workaround NetCDF borken LibXML2 include path detection - find_package(LibXml2) - if("${LIBXML2_FOUND}") - foreach(INCLUDE_DIR IN LISTS LIBXML2_INCLUDE_DIRS) - set(NETCDF_CPATH "${NETCDF_CPATH}:${INCLUDE_DIR}") - get_filename_component(INCLUDE_DIR "${INCLUDE_DIR}" DIRECTORY) - set(NETCDF_CPATH "${NETCDF_CPATH}:${INCLUDE_DIR}") - endforeach() - foreach(LIB IN LISTS LIBXML2_LIBRARIES) - get_filename_component(LIB_DIR "${LIB}" DIRECTORY) - set(NETCDF_LIBRARY_PATH "${NETCDF_LIBRARY_PATH}:${LIB_DIR}") - endforeach() + # Workaround NetCDF failing to add ZLIB include path in H5Deflate plugin + find_package(ZLIB QUIET) + if("${ZLIB_FOUND}") + string(REPLACE ";" " -I" NETCDF_CFLAGS "-I ${ZLIB_INCLUDE_DIRS}") endif() sbuild_add_dependency(NetCDF "${USE_DEFAULT}" - EMBEDDED_PATH "vendor/netcdf-c-4.9.2" + EMBEDDED_PATH "vendor/netcdf-c-4.9.3" DEPENDS HDF5 MODULE_VARS NetCDF_FEATURES - ENV "CPATH=${NETCDF_CPATH}" "LIBRARY_PATH=${NETCDF_LIBRARY_PATH}" CMAKE_CACHE_ARGS "-DCMAKE_C_COMPILER:STRING=${NETCDF_CC}" -DBUILD_TESTING:BOOL=OFF -DBUILD_TESTSETS:BOOL=OFF - -DBUILD_UTILITIES:BOOL=OFF + "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} ${NETCDF_CFLAGS}" -DENABLE_BASH_SCRIPT_TESTING:BOOL=OFF - -DENABLE_BYTERANGE:BOOL=OFF - -DENABLE_DAP:BOOL=OFF - -DENABLE_DAP4:BOOL=OFF - -DENABLE_EXAMPLES:BOOL=OFF - -DENABLE_FILTER_TESTING:BOOL=OFF - -DENABLE_TESTS:BOOL=OFF - VERSION 4.7.3 + -DNETCDF_BUILD_UTILITIES:BOOL=OFF + -DNETCDF_ENABLE_BYTERANGE:BOOL=OFF + -DNETCDF_ENABLE_DAP:BOOL=OFF + -DNETCDF_ENABLE_DAP4:BOOL=OFF + -DNETCDF_ENABLE_EXAMPLES:BOOL=OFF + -DNETCDF_ENABLE_FILTER_TESTING:BOOL=OFF + -DNETCDF_ENABLE_TESTS:BOOL=OFF + VERSION 4.8 ) if("${NETCDF_FOUND}") if("${BUILD_NETCDF_PARALLEL}" AND NOT "PARALLEL4" IN_LIST NetCDF_FEATURES) @@ -440,12 +406,12 @@ if("${BUILD_PYTHON}") set(Python_ADDITIONAL_VERSIONS "${Python3_VERSION}" CACHE STRING "Python version found by FindPython3 for coherency" FORCE) set(PYBIND11_PYTHON_VERSION "${Python3_VERSION}" CACHE STRING "Python version to use for compiling modules" FORCE) sbuild_add_dependency(pybind11 "${USE_DEFAULT}" - EMBEDDED_PATH "vendor/pybind11-2.13.1" + EMBEDDED_PATH "vendor/pybind11-3.0.1" CMAKE_CACHE_ARGS "-DBUILD_TESTING:BOOL=OFF" "-DPYBIND11_TEST:BOOL=OFF" "-DPYBIND11_PYTHON_VERSION:STRING=${Python3_VERSION}" - VERSION 2.4.3 + VERSION 2.9 ) endif() @@ -455,6 +421,10 @@ endif() if("${BUILD_JSON_PLUGIN}") sbuild_add_dependency(JSON "${USE_DEFAULT}" EMBEDDED_PATH "vendor/json-3.11.4" + CMAKE_CACHE_ARGS + "-DCMAKE_POLICY_VERSION_MINIMUM:STRING=3.10" # needed until upstream is updated + "-DJSON_BuildTests:BOOL=OFF" # skip unit tests for json + VERSION 3.11 ) endif() @@ -539,12 +509,6 @@ sbuild_add_module(USER_CODE_PLUGIN SUBSTEPS test ) -sbuild_add_module(DEISA_PLUGIN - ENABLE_BUILD_FLAG BUILD_DEISA_PLUGIN - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/plugins/deisa" - DEPENDS PDI -) - sbuild_add_module(DAMARIS_PLUGIN ENABLE_BUILD_FLAG BUILD_DAMARIS_PLUGIN SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/plugins/damaris" @@ -566,3 +530,11 @@ sbuild_add_module(PDI_TESTS INSTALL_COMMAND "" SUBSTEPS test ) + +sbuild_add_module(PDI_TEST_API + ENABLE_BUILD_FLAG BUILD_TESTING + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/test_api" + DEPENDS PDI + INSTALL_COMMAND "" + SUBSTEPS test +) diff --git a/README.md b/README.md index 94fcebe71..817831b11 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,6 @@ PDI distribution is made of the following submodules: * `pdi/` : the PDI library, * `plugins/decl_hdf5/`: the Decl'HDF5 plugin, * `plugins/decl_netcdf/`: the Decl'NetCDF plugin, -* `plugins/deisa/`: the Deisa plugin, * `plugins/mpi/`: the MPI plugin, * `plugins/pycall/`: the Pycall plugin, * `plugins/serialize/`: the serialize plugin, diff --git a/bin/build_and_run_all_tests b/bin/build_and_run_all_tests index 56b9297d9..9c5b3d10f 100755 --- a/bin/build_and_run_all_tests +++ b/bin/build_and_run_all_tests @@ -1,6 +1,6 @@ #!/bin/bash #============================================================================= -# Copyright (C) 2022-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2022-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) # # All rights reserved. @@ -33,13 +33,18 @@ set -xe -# Make our work dirs +# Setup our directories + SRCDIR="${PWD}" -TEST_DIR="${TEST_DIR:-${PWD}}" -cd "${TEST_DIR}" -cd "$(mktemp -d pdibuild.XXXXX)" -TEST_DIR="${PWD}" +if [ -z "${TEST_DIR}" ] +then + cd "$(mktemp -d pdibuild.XXXXX)" + TEST_DIR="${PWD}" +else + cd "${TEST_DIR}" + TEST_DIR="${PWD}" +fi cd "${SRCDIR}" cd "$(dirname "$0")/.." @@ -69,44 +74,91 @@ fi # Various workarounds -NC_VERSION_MAJOR="$(nc-config --version | sed 's/^[a-zA-Z ]*\([0-9]*\)\.\([0-9]*\).*$/\1/')" -NC_VERSION_MINOR="$(nc-config --version | sed 's/^[a-zA-Z ]*\([0-9]*\)\.\([0-9]*\).*$/\2/')" -if (( NC_VERSION_MAJOR > 4 || ( NC_VERSION_MAJOR == 4 && NC_VERSION_MINOR > 8 ) )) || [[ "x${PDI_LIBS}" != "xprovided" ]] -then - #TODO: NetCDF error https://gitlab.maisondelasimulation.fr/pdidev/pdi/-/issues/433 - EXCLUDED_PDI_TESTS="${EXCLUDED_PDI_TESTS:+$EXCLUDED_PDI_TESTS|}test_05_C" -fi - if [[ "x${PDI_SYSTEM}" =~ ^x(ubuntu|debian) && "x${PDI_MPI}" = "xmpich" ]] then - #Workaround: mpi4py in debuntu is packaged for openmpi only + # Workaround: mpi4py in debuntu is packaged for openmpi only EXCLUDED_PDI_TESTS="${EXCLUDED_PDI_TESTS:+$EXCLUDED_PDI_TESTS|}PDI_example_trace_P|PDI_example_decl_hdf5_P" fi -if [[ "x${PDI_SYSTEM}" =~ ^xubuntu && "x${PDI_MPI}" = "xmpich" ]] && dpkg -s mpich | grep -q 4.2.0-5 +if [[ "x${PDI_SYSTEM}" =~ ^x(ubuntu|debian) && "x${PDI_LIBS}" = "xprovided" ]] then - #Workaround: mpich is broken in ubuntu noble and launches independent processes - #Due to https://bugs.launchpad.net/ubuntu/+source/mpich/+bug/2072338 - EXCLUDED_PDI_TESTS="${EXCLUDED_PDI_TESTS:+$EXCLUDED_PDI_TESTS|}mpi|decl_hdf5_02_F|decl_hdf5_03_F|decl_hdf5_04_F|PDI_example" + # Workaround: parallel NetCDF detection broken in debuntu (and absent in mpich case) + CMAKE_FLAGS="${CMAKE_FLAGS} -DBUILD_NETCDF_PARALLEL=OFF" fi -# if [[ "x${PDI_SYSTEM}" =~ ^xdebian && "x${PDI_MPI}" = "xopenmpi" ]] && dpkg -s libpmix2t64 | grep -q 5.0.3-1 -# then -# #Workaround: libpmix2t64 is broken in debian-unstable and openmpi fails to find libpmix.so.2 -# #Due to https://bugs-devel.debian.org/cgi-bin/bugreport.cgi?bug=1076148 -# EXCLUDED_PDI_TESTS="${EXCLUDED_PDI_TESTS:+$EXCLUDED_PDI_TESTS|}mpi|decl_hdf5_02_F|decl_hdf5_03_F|decl_hdf5_04_F|PDI_example" -# fi - -if [[ "x${PDI_SYSTEM}" =~ ^x(ubuntu|debian) && "x${PDI_LIBS}" = "xprovided" ]] +if [[ "x${PDI_SYSTEM}" =~ ^xmacos ]] then - #Workaround: parallel NetCDF detection broken in debuntu (and absent in mpich case) - CMAKE_FLAGS="${CMAKE_FLAGS} -DBUILD_NETCDF_PARALLEL=OFF" + # Workaround: not all plugins work on OSX yet (https://github.com/pdidev/pdi/issues/580) + CMAKE_FLAGS="${CMAKE_FLAGS} \ + -DBUILD_BENCHMARKING=OFF \ + -DBUILD_DECL_HDF5_PLUGIN=ON \ + -DBUILD_DECL_NETCDF_PLUGIN=ON \ + -DBUILD_DOCUMENTATION=OFF \ + -DBUILD_HDF5_PARALLEL=ON \ + -DBUILD_FORTRAN=OFF \ + -DBUILD_PYTHON=ON \ + -DBUILD_MPI_PLUGIN=ON \ + -DBUILD_NETCDF_PARALLEL=ON \ + -DBUILD_PYCALL_PLUGIN=ON \ + -DBUILD_SERIALIZE_PLUGIN=ON \ + -DBUILD_SET_VALUE_PLUGIN=ON \ + -DBUILD_TESTING=ON \ + -DBUILD_TRACE_PLUGIN=ON \ + -DBUILD_USER_CODE_PLUGIN=ON" fi -# Configure, build & test +# And now for the actual tests -cmake -DDIST_PROFILE=Devel ${CMAKE_FLAGS} "${SRCDIR}" -make ${MAKEFLAGS} -ctest --output-on-failure --timeout 90 ${CTEST_FLAGS} ${EXCLUDED_PDI_TESTS:+-E $EXCLUDED_PDI_TESTS} +printf "\n\n\n\e[1;36m *** Configure, build & test the whole pdi distribution\e[m\n\n" + +mkdir -p install/include install/lib # Workaround for https://github.com/pdidev/pdi/issues/644 +cmake --install-prefix "${PWD}/install" -DDIST_PROFILE=Devel ${CMAKE_FLAGS} -S "${SRCDIR}" -B tests_distribution +cmake --build tests_distribution -- ${MAKEFLAGS} +ctest --output-on-failure --timeout 90 ${CTEST_FLAGS} ${CTEST_DIR:+--output-junit "${CTEST_DIR}/tests_distribution.xml"} ${EXCLUDED_PDI_TESTS:+-E $EXCLUDED_PDI_TESTS} --test-dir tests_distribution + + +printf "\n\n\n\e[1;36m *** Install the pdi distribution & use it from an external project\e[m\n\n" + +cmake --install tests_distribution +./install/bin/pdirun cmake -DDIST_PROFILE=Devel ${CMAKE_FLAGS} -S "${SRCDIR}/cmake_test" -B test_from_install +./install/bin/pdirun cmake --build test_from_install -- ${MAKEFLAGS} +./install/bin/pdirun ctest --output-on-failure --timeout 90 ${CTEST_FLAGS} ${CTEST_DIR:+--output-junit "${CTEST_DIR}/tests_from_install.xml"} ${EXCLUDED_PDI_TESTS:+-E $EXCLUDED_PDI_TESTS} --test-dir test_from_install + + +printf "\n\n\n\e[1;36m *** Configure, build & test pdi example with SubdirMock PDI\e[m\n\n" + +cmake -DDISABLE_PDI=ON -S "${SRCDIR}/example" -B tests_example_subdirmock +cmake --build tests_example_subdirmock -- ${MAKEFLAGS} +ctest --output-on-failure --timeout 90 ${CTEST_FLAGS} ${CTEST_DIR:+--output-junit "${CTEST_DIR}/tests_example_subdirmock.xml"} ${EXCLUDED_PDI_TESTS:+-E $EXCLUDED_PDI_TESTS} --test-dir tests_example_subdirmock + + +printf "\n\n\n\e[1;36m *** Configure, build & test pdi API with SubdirMock PDI\e[m\n\n" + +cmake -DDISABLE_PDI=ON -S "${SRCDIR}/test_api" -B tests_api_subdirmock +cmake --build tests_api_subdirmock -- ${MAKEFLAGS} +ctest --output-on-failure --timeout 90 ${CTEST_FLAGS} ${CTEST_DIR:+--output-junit "${CTEST_DIR}/tests_api_subdirmock.xml"} ${EXCLUDED_PDI_TESTS:+-E $EXCLUDED_PDI_TESTS} --test-dir tests_api_subdirmock + + +if [[ "x${PDI_LIBS}" = "xprovided" ]]; then + + printf "\n\n\n\e[1;36m *** Configure, build & test pdi example with MockFind PDI\e[m\n\n" + + cd "${TEST_DIR}" + mkdir tests_example_mockfind + cd tests_example_mockfind + cmake -DPDI_ROOT="${SRCDIR}/mock_pdi" -S "${SRCDIR}/example" -B tests_example_mockfind + cmake --build tests_example_mockfind -- ${MAKEFLAGS} + ctest --output-on-failure --timeout 90 ${CTEST_FLAGS} ${CTEST_DIR:+--output-junit "${CTEST_DIR}/tests_example_mockfind.xml"} ${EXCLUDED_PDI_TESTS:+-E $EXCLUDED_PDI_TESTS} --test-dir tests_example_mockfind + + + printf "\n\n\n\e[1;36m *** Configure, build & test pdi API with MockFind PDI\e[m\n\n" + + cd "${TEST_DIR}" + mkdir tests_api_mockfind + cd tests_api_mockfind + cmake -DPDI_ROOT="${SRCDIR}/mock_pdi" -S "${SRCDIR}/test_api" -B tests_api_mockfind + cmake --build tests_api_mockfind ${MAKEFLAGS} + ctest --output-on-failure --timeout 90 ${CTEST_FLAGS} ${CTEST_DIR:+--output-junit "${CTEST_DIR}/tests_api_mockfind.xml"} ${EXCLUDED_PDI_TESTS:+-E $EXCLUDED_PDI_TESTS} --test-dir tests_api_mockfind +fi diff --git a/bin/test_indent b/bin/test_indent index 870d4c715..0951785be 100755 --- a/bin/test_indent +++ b/bin/test_indent @@ -53,16 +53,16 @@ RUN_CLANG_FORMAT='false' DOCKER="$(which docker)" if "${DOCKER}" --version >/dev/null 2>&1 then - RUN_CLANG_FORMAT="${DOCKER} run --rm -v $(pwd):/src ghcr.io/pdidev/run_clang_format:v3" + RUN_CLANG_FORMAT="${DOCKER} run --rm -v $(pwd):/src ghcr.io/pdidev/run-clang-format:v4" fi # Look for a local version if [ -f vendor/run-clang-format/run-clang-format.py ] then - for CLANG_FORMAT in clang-format-17 clang-format17 clang-format + for CLANG_FORMAT in clang-format-18 clang-format18 clang-format do CLANG_FORMAT="$(which "${CLANG_FORMAT}")" - if which "${CLANG_FORMAT}" >/dev/null && [ 17 -le "$("${CLANG_FORMAT}" --version | sed 's/.*version\s\+\([0-9]\+\)\..*/\1/')" 2>/dev/null ] + if which "${CLANG_FORMAT}" >/dev/null && [ 18 -eq "$("${CLANG_FORMAT}" --version | sed 's/.*version\s\+\([0-9]\+\)\..*/\1/')" 2>/dev/null ] then RUN_CLANG_FORMAT="python3 vendor/run-clang-format/run-clang-format.py --clang-format-executable ${CLANG_FORMAT}" break @@ -72,7 +72,7 @@ fi if [ "${RUN_CLANG_FORMAT}" = false ] then - echo "clang-format version 17 not found and docker not usable" + echo "clang-format version 18 not found and docker not usable" exit 127 fi diff --git a/cmake/Findyaml.cmake b/cmake/Findyaml.cmake index d5ec335cb..15ddcfdc8 100644 --- a/cmake/Findyaml.cmake +++ b/cmake/Findyaml.cmake @@ -1,6 +1,6 @@ #-------------------------------------------------------------------------------- # Copyright (c) 2012-2013, Lars Baehren -# Copyright (C) 2020-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -24,7 +24,8 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #-------------------------------------------------------------------------------- -cmake_minimum_required(VERSION 3.16...3.25) +cmake_policy(PUSH) +cmake_policy(VERSION 3.22...4.2) # - Check for the presence of libyaml # @@ -41,8 +42,14 @@ function(_yaml_Find_Config) get_target_property(yaml_INCLUDE_DIRS yaml INTERFACE_INCLUDE_DIRECTORIES) set(yaml_INCLUDE_DIRS "${yaml_INCLUDE_DIRS}" PARENT_SCOPE) mark_as_advanced(yaml_DIR) + if("${DEBUG_FIND_YAML}" AND NOT "${yaml_FIND_QUIETLY}") + message(DEBUG "Yaml found through config") + endif() else() unset(yaml_DIR CACHE) + if("${DEBUG_FIND_YAML}" AND NOT "${yaml_FIND_QUIETLY}") + message(DEBUG "Yaml not found through config") + endif() endif() endfunction(_yaml_Find_Config) @@ -52,6 +59,13 @@ function(_yaml_Find_Cache) set_target_properties(yaml PROPERTIES IMPORTED_LOCATION ${yaml_LIBRARIES} INTERFACE_INCLUDE_DIRECTORIES "${yaml_INCLUDE_DIRS}") + if("${DEBUG_FIND_YAML}" AND NOT "${yaml_FIND_QUIETLY}") + message(DEBUG "Yaml found through cache") + endif() + else() + if("${DEBUG_FIND_YAML}" AND NOT "${yaml_FIND_QUIETLY}") + message(DEBUG "Yaml not found through cache") + endif() endif() endfunction(_yaml_Find_Cache) @@ -72,7 +86,14 @@ function(_yaml_Find_Pkgconfig) pkg_search_module(yamlpkg QUIET ${PKGCFG_NAME}) if("${yamlpkg_FOUND}") pkg_get_variable(yamlpkg_INCLUDEDIR ${PKGCFG_NAME} includedir) + if("${DEBUG_FIND_YAML}" AND NOT "${yaml_FIND_QUIETLY}") + message(DEBUG "Yaml found as ${PKGCFG_NAME} through pkgconfig") + endif() break() + else() + if("${DEBUG_FIND_YAML}" AND NOT "${yaml_FIND_QUIETLY}") + message(DEBUG "Yaml not found as ${PKGCFG_NAME} through pkgconfig") + endif() endif() unset(yamlpkg_FOUND CACHE) unset(yamlpkg_FOUND) @@ -102,6 +123,10 @@ function(_yaml_Find_Pkgconfig) unset(yaml_VERSION PARENT_SCOPE) endif() endif() + elseif("${yamlpkg_FOUND}") + if("${DEBUG_FIND_YAML}" AND NOT "${yaml_FIND_QUIETLY}") + message(DEBUG "Yaml version invalid, yaml_FIND_VERSION=${yaml_FIND_VERSION} but yamlpkg_VERSION=${yamlpkg_VERSION}") + endif() endif() endfunction(_yaml_Find_Pkgconfig) @@ -109,6 +134,9 @@ unset(yaml_FOUND) unset(yaml_LIBRARIES) unset(yaml_INCLUDE_DIRS) unset(yaml_VERSION) +if(TARGET yaml) + set(yaml_LIBRARIES yaml) +endif() if(NOT TARGET yaml) _yaml_Find_Config() endif() @@ -133,3 +161,5 @@ find_package_handle_standard_args( REQUIRED_VARS yaml_LIBRARIES VERSION_VAR yaml_VERSION ) + +cmake_policy(POP) diff --git a/cmake/SuperBuild.cmake b/cmake/SuperBuild.cmake index fa3ead644..a3e213f82 100644 --- a/cmake/SuperBuild.cmake +++ b/cmake/SuperBuild.cmake @@ -1,5 +1,5 @@ ################################################################################ -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -22,7 +22,7 @@ # THE SOFTWARE. ################################################################################ -cmake_minimum_required(VERSION 3.16...3.25) +cmake_minimum_required(VERSION 3.22...4.2) include(GNUInstallDirs) include(ExternalProject) @@ -40,7 +40,8 @@ function(__sbuild_build_command _SBUILD_OUTVAR) set(_SBUILD_CM_TARGET --target "${ARGV1}") endif() sbuild_get_env(_SBUILD_ENV_LD_LIBRARY_PATH LD_LIBRARY_PATH) - set(_SBUILD_RESULT "${CMAKE_COMMAND}" -E env "LD_LIBRARY_PATH=${_SBUILD_ENV_LD_LIBRARY_PATH}") + sbuild_get_env(_SBUILD_ENV_DYLD_LIBRARY_PATH DYLD_LIBRARY_PATH) + set(_SBUILD_RESULT "${CMAKE_COMMAND}" -E env "LD_LIBRARY_PATH=${_SBUILD_ENV_LD_LIBRARY_PATH}" "DYLD_LIBRARY_PATH=${_SBUILD_ENV_DYLD_LIBRARY_PATH}") if("${CMAKE_GENERATOR}" MATCHES "Make") #< Use recursive make. list(APPEND _SBUILD_RESULT "\$(MAKE)" ${_SBUILD_MK_TARGET}) else() #< Drive the project with "cmake --build". @@ -98,11 +99,7 @@ endfunction() # ### function(sbuild_add_dependency _SBUILD_NAME _SBUILD_DEFAULT) - if("${CMAKE_VERSION}" VERSION_LESS "3.7") - cmake_parse_arguments(_SBUILD "BUILD_DEPENDENCY;NO_INSTALL" "EMBEDDED_PATH;BUILD_IN_SOURCE;VERSION;SOURCE_SUBDIR" "CMAKE_CACHE_ARGS;DEPENDS;CONFIGURE_COMMAND;BUILD_COMMAND;INSTALL_COMMAND;COMPONENTS;OPTIONAL_COMPONENTS;PATCH_COMMAND;MODULE_VARS;ENV" ${ARGN}) - else() - cmake_parse_arguments(PARSE_ARGV 2 _SBUILD "BUILD_DEPENDENCY;NO_INSTALL" "EMBEDDED_PATH;BUILD_IN_SOURCE;VERSION;SOURCE_SUBDIR" "CMAKE_CACHE_ARGS;DEPENDS;CONFIGURE_COMMAND;BUILD_COMMAND;INSTALL_COMMAND;COMPONENTS;OPTIONAL_COMPONENTS;PATCH_COMMAND;MODULE_VARS;ENV") - endif() + cmake_parse_arguments(PARSE_ARGV 2 _SBUILD "BUILD_DEPENDENCY;NO_INSTALL" "EMBEDDED_PATH;BUILD_IN_SOURCE;VERSION;SOURCE_SUBDIR" "CMAKE_CACHE_ARGS;DEPENDS;CONFIGURE_COMMAND;BUILD_COMMAND;INSTALL_COMMAND;COMPONENTS;OPTIONAL_COMPONENTS;PATCH_COMMAND;MODULE_VARS;ENV") if(DEFINED _SBUILD_EMBEDDED_PATH) set("USE_${_SBUILD_NAME}" "${_SBUILD_DEFAULT}" CACHE STRING "version of ${_SBUILD_NAME} to use, this can be 1) a path to the library source, 2) EMBEDDED to use the provided version, 3) SYSTEM to use an already installed version (you can use CMAKE_PREFIX_PATH to specify where to look, or 4) AUTO to use SYSTEM if available and EMBEDDED otherwise") @@ -223,7 +220,8 @@ function(sbuild_add_dependency _SBUILD_NAME _SBUILD_DEFAULT) set(_SBUILD_DEPENDS "${_SBUILD_DEPENDS_NEW}") sbuild_get_env(_SBUILD_ENV_LD_LIBRARY_PATH LD_LIBRARY_PATH) - set(_SBUILD_CMAKE_COMMAND "${CMAKE_COMMAND}" -E env "LD_LIBRARY_PATH=${_SBUILD_ENV_LD_LIBRARY_PATH}" "${CMAKE_COMMAND}") + sbuild_get_env(_SBUILD_ENV_DYLD_LIBRARY_PATH DYLD_LIBRARY_PATH) + set(_SBUILD_CMAKE_COMMAND "${CMAKE_COMMAND}" -E env "LD_LIBRARY_PATH=${_SBUILD_ENV_LD_LIBRARY_PATH}" "DYLD_LIBRARY_PATH=${_SBUILD_ENV_DYLD_LIBRARY_PATH}" "${CMAKE_COMMAND}") ExternalProject_Add("${_SBUILD_NAME}_pkg" CMAKE_COMMAND "${_SBUILD_CMAKE_COMMAND}" @@ -247,11 +245,7 @@ endfunction() # ### function(sbuild_add_module _SBUILD_NAME) - if("${CMAKE_VERSION}" VERSION_LESS "3.7") - cmake_parse_arguments(_SBUILD "NO_INSTALL" "SOURCE_DIR;ENABLE_BUILD;ENABLE_BUILD_FLAG" "CMAKE_CACHE_ARGS;DEPENDS;SUBSTEPS;INSTALL_COMMAND" ${ARGN}) - else() - cmake_parse_arguments(PARSE_ARGV 1 _SBUILD "NO_INSTALL" "SOURCE_DIR;ENABLE_BUILD;ENABLE_BUILD_FLAG" "CMAKE_CACHE_ARGS;DEPENDS;SUBSTEPS;INSTALL_COMMAND") - endif() + cmake_parse_arguments(PARSE_ARGV 1 _SBUILD "NO_INSTALL" "SOURCE_DIR;ENABLE_BUILD;ENABLE_BUILD_FLAG" "CMAKE_CACHE_ARGS;DEPENDS;SUBSTEPS;INSTALL_COMMAND") if(DEFINED _SBUILD_ENABLE_BUILD_FLAG AND NOT "${${_SBUILD_ENABLE_BUILD_FLAG}}") message(STATUS " **Module**: DISABLED ${_SBUILD_NAME} (-D${_SBUILD_ENABLE_BUILD_FLAG}=OFF)") @@ -284,7 +278,8 @@ function(sbuild_add_module _SBUILD_NAME) set(_SBUILD_DEPENDS "${_SBUILD_DEPENDS_NEW}") sbuild_get_env(_SBUILD_ENV_LD_LIBRARY_PATH LD_LIBRARY_PATH) - set(_SBUILD_CMAKE_COMMAND "${CMAKE_COMMAND}" -E env "LD_LIBRARY_PATH=${_SBUILD_ENV_LD_LIBRARY_PATH}" "${CMAKE_COMMAND}") + sbuild_get_env(_SBUILD_ENV_DYLD_LIBRARY_PATH DYLD_LIBRARY_PATH) + set(_SBUILD_CMAKE_COMMAND "${CMAKE_COMMAND}" -E env "LD_LIBRARY_PATH=${_SBUILD_ENV_LD_LIBRARY_PATH}" "DYLD_LIBRARY_PATH=${_SBUILD_ENV_DYLD_LIBRARY_PATH}" "${CMAKE_COMMAND}") ExternalProject_Add("${_SBUILD_NAME}_pkg" CMAKE_COMMAND "${_SBUILD_CMAKE_COMMAND}" @@ -323,7 +318,7 @@ endfunction() ### function(sbuild_get_env _SBUILD_VAR _SBUILD_ENV_NAME) set(_SBUILD_ENV_VAL "$ENV{${_SBUILD_ENV_NAME}}") - if("LD_LIBRARY_PATH" STREQUAL "${_SBUILD_ENV_NAME}" OR "LIBRARY_PATH" STREQUAL "${_SBUILD_ENV_NAME}") + if("LD_LIBRARY_PATH" STREQUAL "${_SBUILD_ENV_NAME}" OR "DYLD_LIBRARY_PATH" STREQUAL "${_SBUILD_ENV_NAME}" OR "LIBRARY_PATH" STREQUAL "${_SBUILD_ENV_NAME}") __sbuild_env_append(_SBUILD_ENV_VAL "${CMAKE_INSTALL_LIBDIR}") __sbuild_env_append(_SBUILD_ENV_VAL "lib") elseif("CPATH" STREQUAL "${_SBUILD_ENV_NAME}") @@ -342,11 +337,7 @@ endfunction() if("${BUILD_TESTING}") enable_testing() - if("${CMAKE_VERSION}" VERSION_LESS 3.10) - set_property(DIRECTORY "${CMAKE_SOURCE_DIR}" PROPERTY TEST_INCLUDE_FILE "${CMAKE_BINARY_DIR}/SubTests.cmake") - else() - set_property(DIRECTORY "${CMAKE_SOURCE_DIR}" APPEND PROPERTY TEST_INCLUDE_FILES "${CMAKE_BINARY_DIR}/SubTests.cmake") - endif() + set_property(DIRECTORY "${CMAKE_SOURCE_DIR}" APPEND PROPERTY TEST_INCLUDE_FILES "${CMAKE_BINARY_DIR}/SubTests.cmake") file(WRITE "${CMAKE_BINARY_DIR}/SubTests.cmake" "set(ADDPATH [=[${CMAKE_BINARY_DIR}/staging/${CMAKE_INSTALL_LIBDIR}:${CMAKE_BINARY_DIR}/staging/lib]=])\n" [===[ @@ -356,6 +347,12 @@ if("x${LD_LIBRARY_PATH}x" STREQUAL xx) else() set(ENV{LD_LIBRARY_PATH} "${ADDPATH}:${LD_LIBRARY_PATH}") endif() +set(DYLD_LIBRARY_PATH "$ENV{DYLD_LIBRARY_PATH}") +if("x${DYLD_LIBRARY_PATH}x" STREQUAL xx) + set(ENV{DYLD_LIBRARY_PATH} "${ADDPATH}") +else() + set(ENV{DYLD_LIBRARY_PATH} "${ADDPATH}:${DYLD_LIBRARY_PATH}") +endif() ]===] ) endif() diff --git a/cmake_test/AUTHORS b/cmake_test/AUTHORS new file mode 100644 index 000000000..1fbe2901a --- /dev/null +++ b/cmake_test/AUTHORS @@ -0,0 +1,10 @@ +Multiple people have contributed to the PDI cmake tests. To show our +appreciation for their public spirit, we list here in alphabetical order a +condensed list of their contributions. + + +Julien Bigot - CEA (julien.bigot@cea.fr) +* Support calling other existing tests (example, test_api, tests) + +Benoit Martin - CEA (benoit.martin2@cea.fr) +* Initial implementation diff --git a/cmake_test/CHANGELOG.md b/cmake_test/CHANGELOG.md new file mode 100644 index 000000000..0d159f355 --- /dev/null +++ b/cmake_test/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog for PDI cmake tests project +All notable changes to the cmake tests project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + + +## [1.10.1] - 2026-02-04 + +### Added +* Added cmake tests diff --git a/cmake_test/CMakeLists.txt b/cmake_test/CMakeLists.txt new file mode 100644 index 000000000..71aa6b5c8 --- /dev/null +++ b/cmake_test/CMakeLists.txt @@ -0,0 +1,129 @@ +#============================================================================= +# Copyright (C) 2025-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the names of CEA, nor the names of the contributors may be used to +# endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +cmake_minimum_required(VERSION 3.22...4.2) +project(pdi_cmake_tests) + +include(CTest) + +## Global options + +set(DIST_PROFILE "User" CACHE STRING "Profile to use for PDI distribution build. Options are: User, Devel") +set_property(CACHE DIST_PROFILE PROPERTY STRINGS User Devel) + +if(User STREQUAL "${DIST_PROFILE}") + option(BUILD_DOCUMENTATION "Build documentation" OFF) + option(BUILD_TESTING "Build tests" OFF) + option(BUILD_UNSTABLE "Build all features by default including those not stable yet" OFF) +elseif(Devel STREQUAL "${DIST_PROFILE}") + option(BUILD_DOCUMENTATION "Build documentation" ON) + option(BUILD_TESTING "Build tests" ON) + option(BUILD_UNSTABLE "Build all features by default including those not stable yet" ON) +else() + message(FATAL_ERROR "DIST_PROFILE should be set to one of: User, Devel") +endif() + +option(BUILD_BENCHMARKING "Build PDI benchmarks" ON) +option(BUILD_DECL_HDF5_PLUGIN "Build Decl'HDF5 plug-in" ON) +option(BUILD_DECL_NETCDF_PLUGIN "Build Decl'NetCDF plug-in" ON) +option(BUILD_FORTRAN "Build with Fortran support" ON) +option(BUILD_HDF5_PARALLEL "Build Decl'HDF5 in parallel mode" ON) +option(BUILD_MPI_PLUGIN "Build MPI plug-in" ON) +option(BUILD_NETCDF_PARALLEL "Build Decl'NetCDF in parallel mode" ON) +option(BUILD_PYCALL_PLUGIN "Build Pycall plug-in" "${BUILD_UNSTABLE}") +option(BUILD_PYTHON "Build with Python support" "${BUILD_UNSTABLE}") +option(BUILD_SET_VALUE_PLUGIN "Build Set_value plug-in" ON) +option(BUILD_SERIALIZE_PLUGIN "Build Serialize plug-in" ON) +option(BUILD_TRACE_PLUGIN "Build Trace plugin" ON) +option(BUILD_USER_CODE_PLUGIN "Build User-code plugin" ON) +option(BUILD_JSON_PLUGIN "Build JSON plugin" OFF) + + + +function(assert) + string(REPLACE ";" " " ASSERT_TEXT "${ARGN}") + message(STATUS "assert(${ASSERT_TEXT})") + if(NOT ( ${ARGN} )) + message(FATAL_ERROR "Assertion failed: ${ASSERT_TEXT}") + endif () +endfunction() + + +# check subdirectory scope +message(STATUS "checking subdirectory scope") + +message("++ add_subdirectory(example)") +add_subdirectory(../example example) + +message("++ add_subdirectory(test_api)") +add_subdirectory(../test_api/ test_api) + +message("++ add_subdirectory(tests)") +add_subdirectory(../tests/ tests) + +message("++ add_subdirectory(subdir)") +add_subdirectory(subdir) + +message(STATUS "Testing multiple find_package(PDI)") + +message("++ 1st find_package") +find_package(PDI REQUIRED COMPONENTS C) +assert("${PDI_FOUND}") +assert(TARGET PDI::PDI_C) + +message("++ 2nd find_package") +find_package(PDI REQUIRED COMPONENTS C) +assert("${PDI_FOUND}") +assert(TARGET PDI::PDI_C) + +if ("${BUILD_FORTRAN}") + message(STATUS "Testing Fortran component") + + message("++ find_package with component C and Fortran") + find_package(PDI REQUIRED COMPONENTS f90) + assert("${PDI_FOUND}") + assert(TARGET PDI::PDI_C) + assert(TARGET PDI::PDI_f90) + + # Only C component + message("++ find_package with component C. Previous components should remain.") + find_package(PDI REQUIRED COMPONENTS C) + assert("${PDI_FOUND}") + assert(TARGET PDI::PDI_C) + assert(TARGET PDI::PDI_f90) +endif() + +if ("${BUILD_PYTHON}") + message(STATUS "Testing pysupport component") + + message("++ find_package with component C and python") + find_package(PDI REQUIRED COMPONENTS pysupport) + assert("${PDI_FOUND}") + assert(TARGET PDI::PDI_C) +endif() diff --git a/vendor/paraconf-1.0.0/LICENSE b/cmake_test/LICENSE similarity index 100% rename from vendor/paraconf-1.0.0/LICENSE rename to cmake_test/LICENSE diff --git a/vendor/paraconf-1.0.0/paraconf/tests/CMakeLists.txt b/cmake_test/subdir/CMakeLists.txt similarity index 77% rename from vendor/paraconf-1.0.0/paraconf/tests/CMakeLists.txt rename to cmake_test/subdir/CMakeLists.txt index a24a28452..6d53b9b9a 100644 --- a/vendor/paraconf-1.0.0/paraconf/tests/CMakeLists.txt +++ b/cmake_test/subdir/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2019 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2025-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -27,15 +27,13 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.5) - -add_executable(test1 test1.c) -target_link_libraries(test1 paraconf::paraconf) -set_target_properties(test1 PROPERTIES C_STANDARD 99 C_STANDARD_REQUIRED TRUE) -add_test(NAME test1 COMMAND test1 "${CMAKE_CURRENT_SOURCE_DIR}/test_data.yml") +cmake_minimum_required(VERSION 3.22...4.2) +set(COMPONENTS) if("${BUILD_FORTRAN}") - add_executable(test2 test2.f90) - target_link_libraries(test2 paraconf::paraconf_f90) - add_test(NAME test2 COMMAND test2 "${CMAKE_CURRENT_SOURCE_DIR}/test_data.yml") + list(APPEND COMPONENTS f90) +endif() +if("${BUILD_PYTHON}") + list(APPEND COMPONENTS python pysupport) endif() +find_package(PDI REQUIRED C plugins ${COMPONENTS}) diff --git a/example/AUTHORS b/example/AUTHORS index 76a0609a4..faf0ed196 100644 --- a/example/AUTHORS +++ b/example/AUTHORS @@ -14,9 +14,6 @@ Mohamed Gaalich - CEA (mohamed.gaalich@cea.fr) * Added Fortran example * Added FTI example -Benoit Martin - CEA (bmartin@cea.fr) -* Added Deisa example - Tomasz Paluszkiewicz - PSNC (tomaszp@man.poznan.pl) The scientific/academic work is financed from financial resources for science in the years 2016 - 2018 granted for the realization of the international diff --git a/example/CHANGELOG.md b/example/CHANGELOG.md index e5327b353..be7e7bc96 100644 --- a/example/CHANGELOG.md +++ b/example/CHANGELOG.md @@ -19,6 +19,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Security +## [1.10.0] - 2026-01-31 + +### Changed +* Update the version of dependencies according to our policy: oldest supported + Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: + CMake 3.22 and Python 3.10 [#613](https://github.com/pdidev/pdi/issues/613) + + ## [1.8.1] - 2025-01-23 ### Fixed diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 11d6ee7e8..30a736faa 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,6 +1,7 @@ #============================================================================= -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) +# # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,28 +28,43 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(pdi_examples LANGUAGES C) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") set(MPI_COMPONENTS C) +set(paraconf_COMPONENTS C) set(PDI_COMPONENTS C) +option(BUILD_DECL_HDF5_PLUGIN "Build Decl'HDF5 plug-in" OFF) +option(BUILD_DECL_NETCDF_PLUGIN "Build Decl'NetCDF plug-in" OFF) +option(BUILD_FORTRAN "Build with Fortran support" OFF) +option(BUILD_PYCALL_PLUGIN "Build Pycall plug-in" OFF) +option(BUILD_PYTHON "Build with Python support" OFF) +option(BUILD_JSON_PLUGIN "Build JSON plug-in" OFF) +option(DISABLE_PDI "Disable the use of both PDI and Paraconf in the project" OFF) + if("${BUILD_FORTRAN}") enable_language(Fortran) list(APPEND MPI_COMPONENTS Fortran) + list(APPEND PARACONF_COMPONENTS "f90") list(APPEND PDI_COMPONENTS f90) endif() if("${BUILD_PYTHON}") - find_package(Python3 3.8.2 REQUIRED COMPONENTS Interpreter) + find_package(Python3 3.10 REQUIRED COMPONENTS Interpreter) list(APPEND PDI_COMPONENTS python) endif() # Includes include(CTest) find_package(MPI REQUIRED COMPONENTS ${MPI_COMPONENTS}) -find_package(PDI REQUIRED COMPONENTS ${PDI_COMPONENTS}) +if("${DISABLE_PDI}") + set(PDI_MOCK_PARACONF_TARGET TRUE) + add_subdirectory(../mock_pdi mock_pdi) +else() + find_package(paraconf REQUIRED COMPONENTS ${paraconf_COMPONENTS}) + find_package(PDI REQUIRED COMPONENTS ${PDI_COMPONENTS}) +endif() find_library(LIB_M m DOC "The math library") # Default standard in the project is C11 @@ -65,7 +81,7 @@ include "mpif.h" end module ]=]) add_library(MPI_with_mod STATIC "${CMAKE_CURRENT_BINARY_DIR}/mpi.F90") - target_link_libraries(MPI_with_mod MPI::MPI_Fortran) + target_link_libraries(MPI_with_mod PUBLIC MPI::MPI_Fortran) else() message(FATAL_ERROR "Unable to compile a MPI program either with F90 module or F77 include") endif() @@ -77,14 +93,15 @@ endif() add_executable(PDI_example_C example.c) -target_link_libraries(PDI_example_C PDI::PDI_C MPI::MPI_C m) +target_link_libraries(PDI_example_C PRIVATE PDI::PDI_C paraconf::paraconf MPI::MPI_C m) + if("${BUILD_FORTRAN}") add_executable(PDI_example_F example.F90) -target_link_libraries(PDI_example_F PDI::PDI_f90 MPI_with_mod m) -endif("${BUILD_FORTRAN}") +target_link_libraries(PDI_example_F PRIVATE PDI::PDI_f90 paraconf::paraconf_f90 MPI_with_mod m) +endif() -set(RUNTEST_DIR "${CMAKE_SOURCE_DIR}/cmake/runtest-dir") +set(RUNTEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake/runtest-dir") if("${BUILD_DECL_HDF5_PLUGIN}") add_test(NAME PDI_example_decl_hdf5_C COMMAND "${RUNTEST_DIR}" "${MPIEXEC}" "${MPIEXEC_NUMPROC_FLAG}" 3 ${MPIEXEC_PREFLAGS} "$" ${MPIEXEC_POSTFLAGS} "${CMAKE_CURRENT_SOURCE_DIR}/decl_hdf5.yml") diff --git a/example/cmake/DefaultKind.cmake b/example/cmake/DefaultKind.cmake deleted file mode 100644 index 1fd6a7d0c..000000000 --- a/example/cmake/DefaultKind.cmake +++ /dev/null @@ -1,66 +0,0 @@ -################################################################################ -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -################################################################################ - -cmake_minimum_required(VERSION 3.16...3.25) - -function(get_default_kind TYPE DEFAULT_KIND_VAR) - if(DEFINED "${DEFAULT_KIND_VAR}") - return() - endif() - message(STATUS "Checking default Fortran kind for ${TYPE}") - set(TEST_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cmake_test_kind${TYPE}.f90") - file(WRITE "${TEST_FILE}" " -program test_kind${TYPE} - ${TYPE} :: def_knd_var - print *, 'KINDOF ', kind(def_knd_var), ' ENDKINDOF' -end program test_kind${TYPE} -") - try_run(RUN_RES CMP_RES "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}" "${TEST_FILE}" - COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT - RUN_OUTPUT_VARIABLE RUN_OUTPUT - ) - if("${CMP_RES}" AND "${RUN_RES}" EQUAL 0) - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Kind detection program for ${TYPE} successfully compiled and run:\n" - " ===> Compilation\n" - "${COMPILE_OUTPUT}\n" - " ===> Execution\n" - "${RUN_OUTPUT}\n\n" - ) - string(REGEX MATCH "KINDOF *[0-9]* *ENDKINDOF" "${DEFAULT_KIND_VAR}" "${RUN_OUTPUT}") - string(REGEX MATCH "[0-9]+" "${DEFAULT_KIND_VAR}" "${${DEFAULT_KIND_VAR}}") - else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Kind detection program for ${TYPE} failed to compile or run:\n" - " ===> Compilation (${CMP_RES})\n" - "${COMPILE_OUTPUT}\n" - " ===> Execution (${RUN_RES})\n" - "${RUN_OUTPUT}\n\n" - ) - message(FATAL_ERROR "Checking default Fortran kind -- Failed") - endif() - set("${DEFAULT_KIND_VAR}" "${${DEFAULT_KIND_VAR}}" CACHE STRING "Default Fortran kind for ${TYPE} variables") - mark_as_advanced("${DEFAULT_KIND_VAR}") - message(STATUS "Checking default Fortran kind for ${TYPE} -- ${${DEFAULT_KIND_VAR}}") -endfunction() diff --git a/example/cmake/FindPackageHandleStandardArgs.cmake b/example/cmake/FindPackageHandleStandardArgs.cmake deleted file mode 100644 index 67f6bd6f2..000000000 --- a/example/cmake/FindPackageHandleStandardArgs.cmake +++ /dev/null @@ -1,386 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPackageHandleStandardArgs ------------------------------ - -This module provides a function intended to be used in :ref:`Find Modules` -implementing :command:`find_package()` calls. It handles the -``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. -It also sets the ``_FOUND`` variable. The package is -considered found if all variables listed contain valid results, e.g. -valid filepaths. - -.. command:: find_package_handle_standard_args - - There are two signatures:: - - find_package_handle_standard_args( - (DEFAULT_MSG|) - ... - ) - - find_package_handle_standard_args( - [FOUND_VAR ] - [REQUIRED_VARS ...] - [VERSION_VAR ] - [HANDLE_COMPONENTS] - [CONFIG_MODE] - [FAIL_MESSAGE ] - ) - - The ``_FOUND`` variable will be set to ``TRUE`` if all - the variables ``...`` are valid and any optional - constraints are satisfied, and ``FALSE`` otherwise. A success or - failure message may be displayed based on the results and on - whether the ``REQUIRED`` and/or ``QUIET`` option was given to - the :command:`find_package` call. - - The options are: - - ``(DEFAULT_MSG|)`` - In the simple signature this specifies the failure message. - Use ``DEFAULT_MSG`` to ask for a default message to be computed - (recommended). Not valid in the full signature. - - ``FOUND_VAR `` - Obsolete. Specifies either ``_FOUND`` or - ``_FOUND`` as the result variable. This exists only - for compatibility with older versions of CMake and is now ignored. - Result variables of both names are always set for compatibility. - - ``REQUIRED_VARS ...`` - Specify the variables which are required for this package. - These may be named in the generated failure message asking the - user to set the missing variable values. Therefore these should - typically be cache entries such as ``FOO_LIBRARY`` and not output - variables like ``FOO_LIBRARIES``. - - ``VERSION_VAR `` - Specify the name of a variable that holds the version of the package - that has been found. This version will be checked against the - (potentially) specified required version given to the - :command:`find_package` call, including its ``EXACT`` option. - The default messages include information about the required - version and the version which has been actually found, both - if the version is ok or not. - - ``HANDLE_COMPONENTS`` - Enable handling of package components. In this case, the command - will report which components have been found and which are missing, - and the ``_FOUND`` variable will be set to ``FALSE`` - if any of the required components (i.e. not the ones listed after - the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are - missing. - - ``CONFIG_MODE`` - Specify that the calling find module is a wrapper around a - call to ``find_package( NO_MODULE)``. This implies - a ``VERSION_VAR`` value of ``_VERSION``. The command - will automatically check whether the package configuration file - was found. - - ``FAIL_MESSAGE `` - Specify a custom failure message instead of using the default - generated message. Not recommended. - -Example for the simple signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibXml2 DEFAULT_MSG - LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) - -The ``LibXml2`` package is considered to be found if both -``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. -Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found -and ``REQUIRED`` was used, it fails with a -:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was -used or not. If it is found, success will be reported, including -the content of the first ````. On repeated CMake runs, -the same message will not be printed again. - -Example for the full signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibArchive - REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR - VERSION_VAR LibArchive_VERSION) - -In this case, the ``LibArchive`` package is considered to be found if -both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. -Also the version of ``LibArchive`` will be checked by using the version -contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, -the default messages will be printed. - -Another example for the full signature: - -.. code-block:: cmake - - find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) - find_package_handle_standard_args(Automoc4 CONFIG_MODE) - -In this case, a ``FindAutmoc4.cmake`` module wraps a call to -``find_package(Automoc4 NO_MODULE)`` and adds an additional search -directory for ``automoc4``. Then the call to -``find_package_handle_standard_args`` produces a proper success/failure -message. -#]=======================================================================] - -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - -# internal helper macro -macro(_FPHSA_FAILURE_MESSAGE _msg) - if (${_NAME}_FIND_REQUIRED) - message(FATAL_ERROR "${_msg}") - else () - if (NOT ${_NAME}_FIND_QUIETLY) - message(STATUS "${_msg}") - endif () - endif () -endmacro() - - -# internal helper macro to generate the failure message when used in CONFIG_MODE: -macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: - if(${_NAME}_CONFIG) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") - else() - # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. - # List them all in the error message: - if(${_NAME}_CONSIDERED_CONFIGS) - set(configsText "") - list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) - math(EXPR configsCount "${configsCount} - 1") - foreach(currentConfigIndex RANGE ${configsCount}) - list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) - list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) - string(APPEND configsText " ${filename} (version ${version})\n") - endforeach() - if (${_NAME}_NOT_FOUND_MESSAGE) - string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") - endif() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") - - else() - # Simple case: No Config-file was found at all: - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") - endif() - endif() -endmacro() - - -function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) - -# Set up the arguments for `cmake_parse_arguments`. - set(options CONFIG_MODE HANDLE_COMPONENTS) - set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) - set(multiValueArgs REQUIRED_VARS) - -# Check whether we are in 'simple' or 'extended' mode: - set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) - list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) - - if(${INDEX} EQUAL -1) - set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) - set(FPHSA_REQUIRED_VARS ${ARGN}) - set(FPHSA_VERSION_VAR) - else() - cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) - - if(FPHSA_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") - endif() - - if(NOT FPHSA_FAIL_MESSAGE) - set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") - endif() - - # In config-mode, we rely on the variable _CONFIG, which is set by find_package() - # when it successfully found the config-file, including version checking: - if(FPHSA_CONFIG_MODE) - list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) - list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) - set(FPHSA_VERSION_VAR ${_NAME}_VERSION) - endif() - - if(NOT FPHSA_REQUIRED_VARS) - message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") - endif() - endif() - -# now that we collected all arguments, process them - - if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") - set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") - endif() - - list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) - - string(TOUPPER ${_NAME} _NAME_UPPER) - string(TOLOWER ${_NAME} _NAME_LOWER) - - if(FPHSA_FOUND_VAR) - if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") - set(_FOUND_VAR ${FPHSA_FOUND_VAR}) - else() - message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") - endif() - else() - set(_FOUND_VAR ${_NAME_UPPER}_FOUND) - endif() - - # collect all variables which were not found, so they can be printed, so the - # user knows better what went wrong (#6375) - set(MISSING_VARS "") - set(DETAILS "") - # check if all passed variables are valid - set(FPHSA_FOUND_${_NAME} TRUE) - foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) - if(NOT ${_CURRENT_VAR}) - set(FPHSA_FOUND_${_NAME} FALSE) - string(APPEND MISSING_VARS " ${_CURRENT_VAR}") - else() - string(APPEND DETAILS "[${${_CURRENT_VAR}}]") - endif() - endforeach() - if(FPHSA_FOUND_${_NAME}) - set(${_NAME}_FOUND TRUE) - set(${_NAME_UPPER}_FOUND TRUE) - else() - set(${_NAME}_FOUND FALSE) - set(${_NAME_UPPER}_FOUND FALSE) - endif() - - # component handling - unset(FOUND_COMPONENTS_MSG) - unset(MISSING_COMPONENTS_MSG) - - if(FPHSA_HANDLE_COMPONENTS) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(${_NAME}_${comp}_FOUND) - - if(NOT DEFINED FOUND_COMPONENTS_MSG) - set(FOUND_COMPONENTS_MSG "found components: ") - endif() - string(APPEND FOUND_COMPONENTS_MSG " ${comp}") - - else() - - if(NOT DEFINED MISSING_COMPONENTS_MSG) - set(MISSING_COMPONENTS_MSG "missing components: ") - endif() - string(APPEND MISSING_COMPONENTS_MSG " ${comp}") - - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - string(APPEND MISSING_VARS " ${comp}") - endif() - - endif() - endforeach() - set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") - string(APPEND DETAILS "[c${COMPONENT_MSG}]") - endif() - - # version handling: - set(VERSION_MSG "") - set(VERSION_OK TRUE) - - # check with DEFINED here as the requested or found version may be "0" - if (DEFINED ${_NAME}_FIND_VERSION) - if(DEFINED ${FPHSA_VERSION_VAR}) - set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) - - if(${_NAME}_FIND_VERSION_EXACT) # exact version required - # count the dots in the version string - string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}") - # add one dot because there is one dot more than there are components - string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) - if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) - # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT - # is at most 4 here. Therefore a simple lookup table is used. - if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) - set(_VERSION_REGEX "[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) - set(_VERSION_REGEX "[^.]*\\.[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") - else () - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") - endif () - string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}") - unset(_VERSION_REGEX) - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - unset(_VERSION_HEAD) - else () - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - endif () - unset(_VERSION_DOTS) - - else() # minimum version specified: - if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") - endif () - endif() - - else() - - # if the package was not found, but a version was given, add that to the output: - if(${_NAME}_FIND_VERSION_EXACT) - set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") - else() - set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") - endif() - - endif() - else () - # Check with DEFINED as the found version may be 0. - if(DEFINED ${FPHSA_VERSION_VAR}) - set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") - endif() - endif () - - if(VERSION_OK) - string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") - else() - set(${_NAME}_FOUND FALSE) - endif() - - - # print the result: - if (${_NAME}_FOUND) - FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") - else () - - if(FPHSA_CONFIG_MODE) - _FPHSA_HANDLE_FAILURE_CONFIG_MODE() - else() - if(NOT VERSION_OK) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") - else() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") - endif() - endif() - - endif () - - set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) - set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) -endfunction() diff --git a/example/cmake/FindPackageMessage.cmake b/example/cmake/FindPackageMessage.cmake deleted file mode 100644 index 6821cee4f..000000000 --- a/example/cmake/FindPackageMessage.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# FindPackageMessage -# ------------------ -# -# -# -# FIND_PACKAGE_MESSAGE( "message for user" "find result details") -# -# This macro is intended to be used in FindXXX.cmake modules files. It -# will print a message once for each unique find result. This is useful -# for telling the user where a package was found. The first argument -# specifies the name (XXX) of the package. The second argument -# specifies the message to display. The third argument lists details -# about the find result so that if they change the message will be -# displayed again. The macro also obeys the QUIET argument to the -# find_package command. -# -# Example: -# -# :: -# -# if(X11_FOUND) -# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" -# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") -# else() -# ... -# endif() - -function(FIND_PACKAGE_MESSAGE pkg msg details) - # Avoid printing a message repeatedly for the same find result. - if(NOT ${pkg}_FIND_QUIETLY) - string(REPLACE "\n" "" details "${details}") - set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) - if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - # The message has not yet been printed. - message(STATUS "${msg}") - - # Save the find details in the cache to avoid printing the same - # message again. - set("${DETAILS_VAR}" "${details}" - CACHE INTERNAL "Details about finding ${pkg}") - endif() - endif() -endfunction() diff --git a/example/cmake/FindPython/Support.cmake b/example/cmake/FindPython/Support.cmake deleted file mode 100644 index be4c3366f..000000000 --- a/example/cmake/FindPython/Support.cmake +++ /dev/null @@ -1,1244 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -# -# This file is a "template" file used by various FindPython modules. -# - -cmake_policy (VERSION 3.16...3.25) - -# -# Initial configuration -# -if (NOT DEFINED _PYTHON_PREFIX) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 3) - set(_${_PYTHON_PREFIX}_VERSIONS 3.20 3.19 3.18 3.17 3.16 3.15 3.14 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0) -elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 2) - set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) -else() - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() - - -# -# helper commands -# -macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG) - if (${_PYTHON_PREFIX}_FIND_REQUIRED) - message (FATAL_ERROR "${_PYTHON_MSG}") - else() - if (NOT ${_PYTHON_PREFIX}_FIND_QUIETLY) - message(STATUS "${_PYTHON_MSG}") - endif () - endif() - - set (${_PYTHON_PREFIX}_FOUND FALSE) - string (TOUPPER "${_PYTHON_PREFIX}" _${_PYTHON_PREFIX}_UPPER_PREFIX) - set (${_PYTHON_UPPER_PREFIX}_FOUND FALSE) - return() -endmacro() - - -macro (_PYTHON_FIND_FRAMEWORKS) - set (${_PYTHON_PREFIX}_FRAMEWORKS) - if (APPLE) - set (_pff_frameworks ${CMAKE_FRAMEWORK_PATH} - $ENV{CMAKE_FRAMEWORK_PATH} - ~/Library/Frameworks - /usr/local/Frameworks - ${CMAKE_SYSTEM_FRAMEWORK_PATH}) - list (REMOVE_DUPLICATES _pff_frameworks) - foreach (_pff_framework IN LISTS _pff_frameworks) - if (EXISTS ${_pff_framework}/Python.framework) - list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python.framework) - endif() - endforeach() - unset (_pff_frameworks) - unset (_pff_framework) - endif() -endmacro() - -function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION) - set (_PYTHON_FRAMEWORK_PATHS) - foreach (_PYTHON_FRAMEWORK IN LISTS ${_PYTHON_PREFIX}_FRAMEWORKS) - list (APPEND _PYTHON_FRAMEWORK_PATHS - "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}") - endforeach() - set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${_PYTHON_FRAMEWORK_PATHS} PARENT_SCOPE) -endfunction() - - -function (_PYTHON_VALIDATE_INTERPRETER) - if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) - return() - endif() - - if (ARGC EQUAL 1) - set (expected_version ${ARGV0}) - else() - unset (expected_version) - endif() - - get_filename_component (python_name "${${_PYTHON_PREFIX}_EXECUTABLE}" NAME) - - if (expected_version AND NOT python_name STREQUAL "python${expected_version}${CMAKE_EXECUTABLE_SUFFIX}") - # executable found must have a specific version - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL expected_version) - # interpreter not usable or has wrong major version - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - else() - if (NOT python_name STREQUAL "python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}${CMAKE_EXECUTABLE_SUFFIX}") - # executable found do not have version in name - # ensure major version is OK - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write(str(sys.version_info[0]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - # interpreter not usable or has wrong major version - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - endif() - endif() - - if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND NOT CMAKE_CROSSCOMPILING) - # In this case, interpreter must have same architecture as environment - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))" - RESULT_VARIABLE result - OUTPUT_VARIABLE size - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P) - # interpreter not usable or has wrong architecture - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - endif() -endfunction() - - -function (_PYTHON_VALIDATE_COMPILER expected_version) - if (NOT ${_PYTHON_PREFIX}_COMPILER) - return() - endif() - - # retrieve python environment version from compiler - set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))\n") - execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${working_dir}/version.py" - WORKING_DIRECTORY "${working_dir}" - OUTPUT_QUIET - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process (COMMAND "${working_dir}/version" - WORKING_DIRECTORY "${working_dir}" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET) - file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") - - if (result OR NOT version EQUAL expected_version) - # Compiler not usable or has wrong major version - set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) - endif() -endfunction() - - -function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB) - string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}") - # look at runtime part on systems supporting it - if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR - (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN" - AND ${_PYTHON_LIB} MATCHES "${CMAKE_IMPORT_LIBRARY_SUFFIX}$")) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) - # MSYS has a special syntax for runtime libraries - if (CMAKE_SYSTEM_NAME MATCHES "MSYS") - list (APPEND CMAKE_FIND_LIBRARY_PREFIXES "msys-") - endif() - find_library (${ARGV}) - endif() -endfunction() - - -function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT) - unset (_PYTHON_DIRS) - set (_PYTHON_LIBS ${ARGV}) - list (REMOVE_AT _PYTHON_LIBS 0) - foreach (_PYTHON_LIB IN LISTS _PYTHON_LIBS) - if (${_PYTHON_LIB}) - get_filename_component (_PYTHON_DIR "${${_PYTHON_LIB}}" DIRECTORY) - list (APPEND _PYTHON_DIRS "${_PYTHON_DIR}") - endif() - endforeach() - if (_PYTHON_DIRS) - list (REMOVE_DUPLICATES _PYTHON_DIRS) - endif() - set (${_PYTHON_SLD_RESULT} ${_PYTHON_DIRS} PARENT_SCOPE) -endfunction() - - -# If major version is specified, it must be the same as internal major version -if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR - AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") -endif() - - -# handle components -if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_FIND_COMPONENTS Interpreter) - set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE) -endif() -foreach (_${_PYTHON_PREFIX}_COMPONENT IN LISTS ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE) -endforeach() -unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - -# Set versions to search -## default: search any version -set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS}) - -if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER 1) - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}) - else() - unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - # add all compatible versions - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS) - if (${_PYTHON_PREFIX}_FIND_VERSION VERSION_LESS _${_PYTHON_PREFIX}_VERSION) - list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION}) - endif() - endforeach() - endif() -endif() - -# Anaconda distribution: define which architectures can be used -if (CMAKE_SIZEOF_VOID_P) - # In this case, search only for 64bit or 32bit - math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH}) -else() - # architecture unknown, search for both 64bit and 32bit - set (_${_PYTHON_PREFIX}_ARCH 64) - set (_${_PYTHON_PREFIX}_ARCH2 32) -endif() - -# IronPython support -if (CMAKE_SIZEOF_VOID_P) - # In this case, search only for 64bit or 32bit - math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy${_${_PYTHON_PREFIX}_ARCH} ipy) -else() - # architecture unknown, search for natural interpreter - set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy) -endif() -set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40) - -# Apple frameworks handling -_python_find_frameworks () - -# Save CMAKE_FIND_APPBUNDLE -if (DEFINED CMAKE_FIND_APPBUNDLE) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE}) -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -endif() -# To avoid app bundle lookup -set (CMAKE_FIND_APPBUNDLE "NEVER") - -# Save CMAKE_FIND_FRAMEWORK -if (DEFINED CMAKE_FIND_FRAMEWORK) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) - if (CMAKE_FIND_FRAMEWORK STREQUAL "ONLY") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: CMAKE_FIND_FRAMEWORK: 'ONLY' value is not supported. 'FIRST' will be used instead.") - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) - endif() -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") -endif() -# To avoid framework lookup -set (CMAKE_FIND_FRAMEWORK "NEVER") - -# Windows Registry handling -if (DEFINED ${_PYTHON_PREFIX}_FIND_REGISTRY) - if (NOT ${_PYTHON_PREFIX}_FIND_REGISTRY MATCHES "^(FIRST|LAST|NEVER)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_REGISTRY}: invalid value for '${_PYTHON_PREFIX}_FIND_REGISTRY'. 'FIRST', 'LAST' or 'NEVER' expected.") - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY ${${_PYTHON_PREFIX}_FIND_REGISTRY}) - endif() -else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") -endif() - - -unset (_${_PYTHON_PREFIX}_REQUIRED_VARS) -unset (_${_PYTHON_PREFIX}_CACHED_VARS) - - -# first step, search for the interpreter -if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) - endif() - - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - if (DEFINED ${_PYTHON_PREFIX}_EXECUTABLE AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_EXECUTABLE}") - set (_${_PYTHON_PREFIX}_EXECUTABLE "${${_PYTHON_PREFIX}_EXECUTABLE}" CACHE INTERNAL "") - elseif (DEFINED _${_PYTHON_PREFIX}_EXECUTABLE) - # check version validity - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) - else() - _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) - endif() - endif() - - if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) - # look-up for various versions and locations - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - - # Apple frameworks handling - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # Windows registry - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # try using HINTS - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) - - # Apple frameworks handling - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_DEFAULT_PATH) - endif() - - # Windows registry - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() - - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION}) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - endforeach() - endif() - - if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) - # No specific version found. Retry with generic names - # try using HINTS - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) - - _python_validate_interpreter () - endif() - - set (${_PYTHON_PREFIX}_EXECUTABLE "${_${_PYTHON_PREFIX}_EXECUTABLE}" CACHE FILEPATH "${_PYTHON_PREFIX} Interpreter") - - # retrieve exact version of executable found - if (${_PYTHON_PREFIX}_EXECUTABLE) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_VERSION - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 ${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 ${_PYTHON_PREFIX}_VERSION_PATCH) - else() - # Interpreter is not usable - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - unset (${_PYTHON_PREFIX}_VERSION) - endif() - endif() - - if (${_PYTHON_PREFIX}_EXECUTABLE - AND ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE) - # Use interpreter version for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - endif() - - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # retrieve interpreter identity - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -V - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID - ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID) - if (NOT _${_PYTHON_PREFIX}_RESULT) - if (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Anaconda") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda") - elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy") - else() - string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}") - if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python") - # try to get a more precise ID - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.copyright)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT - ERROR_QUIET) - if (${_PYTHON_PREFIX}_COPYRIGHT MATCHES "ActiveState") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "ActivePython") - endif() - endif() - endif() - else() - set (${_PYTHON_PREFIX}_INTERPRETER_ID Python) - endif() - else() - unset (${_PYTHON_PREFIX}_INTERPRETER_ID) - endif() - - # retrieve various package installation directories - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))" - - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 2 ${_PYTHON_PREFIX}_SITELIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 3 ${_PYTHON_PREFIX}_SITEARCH) - else() - unset (${_PYTHON_PREFIX}_STDLIB) - unset (${_PYTHON_PREFIX}_STDARCH) - unset (${_PYTHON_PREFIX}_SITELIB) - unset (${_PYTHON_PREFIX}_SITEARCH) - endif() - - mark_as_advanced (${_PYTHON_PREFIX}_EXECUTABLE) -endif() - - -# second step, search for compiler (IronPython) -if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_COMPILER) - endif() - - # IronPython specific artifacts - # If IronPython interpreter is found, use its path - unset (_${_PYTHON_PREFIX}_IRON_ROOT) - if (${_PYTHON_PREFIX}_Interpreter_FOUND AND ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - get_filename_component (_${_PYTHON_PREFIX}_IRON_ROOT "${${_PYTHON_PREFIX}_EXECUTABLE}" DIRECTORY) - endif() - - # try using root dir and registry - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() - - _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION}) - if (${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endforeach() - - # no specific version found, re-try in standard paths - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}) - - if (${_PYTHON_PREFIX}_COMPILER) - # retrieve python environment version from compiler - set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n") - execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - OUTPUT_QUIET - ERROR_QUIET) - execute_process (COMMAND "${_${_PYTHON_PREFIX}_VERSION_DIR}/version" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - else() - # compiler not usable - set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) - endif() - file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") - endif() - - if (${_PYTHON_PREFIX}_COMPILER) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # Compiler must be compatible with interpreter - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - # Use compiler version for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - endif() - endif() - - if (${_PYTHON_PREFIX}_Compiler_FOUND) - set (${_PYTHON_PREFIX}_COMPILER_ID IronPython) - else() - unset (${_PYTHON_PREFIX}_COMPILER_ID) - endif() - - mark_as_advanced (${_PYTHON_PREFIX}_COMPILER) -endif() - - -# third step, search for the development artifacts -## Development environment is not compatible with IronPython interpreter -if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_INCLUDE_DIR) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_INCLUDE_DIR) - endif() - - # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - if (DEFINED ${_PYTHON_PREFIX}_USE_STATIC_LIBS AND NOT WIN32) - set(_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(${_PYTHON_PREFIX}_USE_STATIC_LIBS) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - else() - list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - endif() - else() - endif() - - # if python interpreter is found, use its location and version to ensure consistency - # between interpreter and development environment - unset (_${_PYTHON_PREFIX}_PREFIX) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.PREFIX)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - unset (_${_PYTHON_PREFIX}_PREFIX) - endif() - endif() - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - # try to use pythonX.Y-config tool - set (_${_PYTHON_PREFIX}_CONFIG_NAMES) - if (DEFINED CMAKE_LIBRARY_ARCHITECTURE) - set (_${_PYTHON_PREFIX}_CONFIG_NAMES "${CMAKE_LIBRARY_ARCHITECTURE}-python${_${_PYTHON_PREFIX}_VERSION}-config") - endif() - list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES "python${_${_PYTHON_PREFIX}_VERSION}-config") - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - unset (_${_PYTHON_PREFIX}_CONFIG_NAMES) - - if (NOT _${_PYTHON_PREFIX}_CONFIG) - continue() - endif() - - # retrieve root install directory - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --prefix - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # python-config is not usable - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - continue() - endif() - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - # retrieve library - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - # retrieve library directory - string (REGEX MATCHALL "-L[^ ]+" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-L" "" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_LIB_DIRS}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_DIRS) - # retrieve library name - string (REGEX MATCHALL "-lpython[^ ]+" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-l" "" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_LIB_NAMES}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_NAMES) - - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} ${_${_PYTHON_PREFIX}_LIB_DIRS} - PATH_SUFFIXES lib - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # retrieve runtime library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_PATH} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - endif() - - # retrieve include directory - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --includes - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - # retrieve include directory - string (REGEX MATCHALL "-I[^ ]+" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-I" "" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIRS}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_DIRS) - - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - break() - endif() - endforeach() - - # Rely on HINTS and standard paths if config tool failed to locate artifacts - if (NOT (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) OR NOT ${_PYTHON_PREFIX}_INCLUDE_DIR) - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - - set (_${_PYTHON_PREFIX}_REGISTRY_PATHS - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # search in HINTS locations - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) - endif() - - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config) - # retrieve runtime library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - - if (WIN32) - # search for debug library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - # use library location as a hint - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - NO_DEFAULT_PATH) - else() - # search first in known locations - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs) - endif() - if (${_PYTHON_PREFIX}_LIBRARY_DEBUG) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - endif() - - # Don't search for include dir until library location is known - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) - - if (${_PYTHON_PREFIX}_EXECUTABLE) - # pick up include directory from configuration - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; import sysconfig; sys.stdout.write(sysconfig.get_path('include'))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PATH - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - file (TO_CMAKE_PATH "${_${_PYTHON_PREFIX}_PATH}" _${_PYTHON_PREFIX}_PATH) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PATH}") - endif() - endif() - - foreach (_${_PYTHON_PREFIX}_LIB IN ITEMS ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - if (${_${_PYTHON_PREFIX}_LIB}) - # Use the library's install prefix as a hint - if (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - else() - # assume library is in a directory under root - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${${_${_PYTHON_PREFIX}_LIB}}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") - endif() - endif() - endforeach() - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_HINTS) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - break() - endif() - endforeach() - - # search header file in standard locations - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h) - endif() - - if (${_PYTHON_PREFIX}_INCLUDE_DIR) - # retrieve version from header file - file (STRINGS "${${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" _${_PYTHON_PREFIX}_VERSION - REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") - string (REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" - _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_VERSION}") - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_Compiler_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - endif() - - # define public variables - include (${CMAKE_CURRENT_LIST_DIR}/../SelectLibraryConfigurations.cmake) - select_library_configurations (${_PYTHON_PREFIX}) - if (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - elseif (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - else() - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "$${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND") - endif() - - _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS - ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - if (UNIX) - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$") - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS}) - endif() - else() - _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - endif() - - set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${${_PYTHON_PREFIX}_INCLUDE_DIR}") - - mark_as_advanced (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_INCLUDE_DIR) - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND) - # development environment must be compatible with interpreter/compiler - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_Development_FOUND TRUE) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Development_FOUND TRUE) - endif() - endif() - - # Restore the original find library ordering - if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() -endif() - -# final validation -if (${_PYTHON_PREFIX}_VERSION_MAJOR AND - NOT ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") -endif() - -include (${CMAKE_CURRENT_LIST_DIR}/../FindPackageHandleStandardArgs.cmake) -find_package_handle_standard_args (${_PYTHON_PREFIX} - REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS} - VERSION_VAR ${_PYTHON_PREFIX}_VERSION - HANDLE_COMPONENTS) - -# Create imported targets and helper functions -if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Interpreter_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Interpreter) - add_executable (${_PYTHON_PREFIX}::Interpreter IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Interpreter - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_EXECUTABLE}") -endif() - -if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Compiler_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Compiler) - add_executable (${_PYTHON_PREFIX}::Compiler IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Compiler - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}") -endif() - -if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Development_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::Python) - - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED) - else() - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC) - endif() - - add_library (${_PYTHON_PREFIX}::Python ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED) - - set_property (TARGET ${_PYTHON_PREFIX}::Python - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}") - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - OR (${_PYTHON_PREFIX}_LIBRARY_DEBUG AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)) - # System manage shared libraries in two parts: import and runtime - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - else() - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARY}" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY}") - endif() - else() - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}") - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}") - else() - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY}") - endif() - endif() - - function(list_filter_exclude _list_name _value) - if(CMAKE_VERSION VERSION_LESS 3.12) - list(FIND ${_list_name} ${_value} _INDEX) - if(${_INDEX} GREATER -1) - list(REMOVE_AT ${_list_name} ${_INDEX}) - endif() - else() - list(FILTER ${_list_name} EXCLUDE REGEX ${_value}) - endif() - set(${_list_name} ${${_list_name}} PARENT_SCOPE) - endfunction() - - if (_${_PYTHON_PREFIX}_CONFIG AND _${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC") - # extend link information with dependent libraries - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "-[Ll][^ ]+" _${_PYTHON_PREFIX}_LINK_LIBRARIES "${_${_PYTHON_PREFIX}_FLAGS}") - # remove elements relative to python library itself - list_filter_exclude(_${_PYTHON_PREFIX}_LINK_LIBRARIES "-lpython") - #list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-lpython") - foreach (_${_PYTHON_PREFIX}_DIR IN LISTS ${_PYTHON_PREFIX}_LIBRARY_DIRS) - list_filter_exclude(_${_PYTHON_PREFIX}_LINK_LIBRARIES "-L${${_PYTHON_PREFIX}_DIR}") - #list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-L${${_PYTHON_PREFIX}_DIR}") - endforeach() - set_property (TARGET ${_PYTHON_PREFIX}::Python - PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES}) - endif() - endif() - - # - # PYTHON_ADD_LIBRARY ( [STATIC|SHARED|MODULE] src1 src2 ... srcN) - # It is used to build modules for python. - # - function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name) - cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY - "STATIC;SHARED;MODULE" "" "") - - unset (type) - if (NOT (PYTHON_ADD_LIBRARY_STATIC - OR PYTHON_ADD_LIBRARY_SHARED - OR PYTHON_ADD_LIBRARY_MODULE)) - set (type MODULE) - endif() - add_library (${name} ${type} ${ARGN}) - target_link_libraries (${name} PRIVATE ${prefix}::Python) - - # customize library name to follow module name rules - get_property (type TARGET ${name} PROPERTY TYPE) - if (type STREQUAL "MODULE_LIBRARY") - set_property (TARGET ${name} PROPERTY PREFIX "") - if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - set_property (TARGET ${name} PROPERTY SUFFIX ".pyd") - endif() - endif() - endfunction() -endif() - -# final clean-up - -# Restore CMAKE_FIND_APPBUNDLE -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) - set (CMAKE_FIND_APPBUNDLE ${_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -else() - unset (CMAKE_FIND_APPBUNDLE) -endif() -# Restore CMAKE_FIND_FRAMEWORK -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) - set (CMAKE_FIND_FRAMEWORK ${_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) -else() - unset (CMAKE_FIND_FRAMEWORK) -endif() - -unset (_${_PYTHON_PREFIX}_CONFIG CACHE) diff --git a/example/cmake/FindPython3.cmake b/example/cmake/FindPython3.cmake deleted file mode 100644 index 370abfdb5..000000000 --- a/example/cmake/FindPython3.cmake +++ /dev/null @@ -1,174 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPython3 ------------ - -Find Python 3 interpreter, compiler and development environment (include -directories and libraries). - -Three components are supported: - -* ``Interpreter``: search for Python 3 interpreter -* ``Compiler``: search for Python 3 compiler. Only offered by IronPython. -* ``Development``: search for development artifacts (include directories and - libraries) - -If no ``COMPONENTS`` is specified, ``Interpreter`` is assumed. - -To ensure consistent versions between components ``Interpreter``, ``Compiler`` -and ``Development``, specify all components at the same time:: - - find_package (Python3 COMPONENTS Interpreter Development) - -This module looks only for version 3 of Python. This module can be used -concurrently with :module:`FindPython2` module to use both Python versions. - -The :module:`FindPython` module can be used if Python version does not matter -for you. - -Imported Targets -^^^^^^^^^^^^^^^^ - -This module defines the following :ref:`Imported Targets `: - -``Python3::Interpreter`` - Python 3 interpreter. Target defined if component ``Interpreter`` is found. -``Python3::Compiler`` - Python 3 compiler. Target defined if component ``Compiler`` is found. -``Python3::Python`` - Python 3 library. Target defined if component ``Development`` is found. - -Result Variables -^^^^^^^^^^^^^^^^ - -This module will set the following variables in your project -(see :ref:`Standard Variable Names `): - -``Python3_FOUND`` - System has the Python 3 requested components. -``Python3_Interpreter_FOUND`` - System has the Python 3 interpreter. -``Python3_EXECUTABLE`` - Path to the Python 3 interpreter. -``Python3_INTERPRETER_ID`` - A short string unique to the interpreter. Possible values include: - * Python - * ActivePython - * Anaconda - * Canopy - * IronPython -``Python3_STDLIB`` - Standard platform independent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``. -``Python3_STDARCH`` - Standard platform dependent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``. -``Python3_SITELIB`` - Third-party platform independent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``. -``Python3_SITEARCH`` - Third-party platform dependent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``. -``Python3_Compiler_FOUND`` - System has the Python 3 compiler. -``Python3_COMPILER`` - Path to the Python 3 compiler. Only offered by IronPython. -``Python3_COMPILER_ID`` - A short string unique to the compiler. Possible values include: - * IronPython -``Python3_Development_FOUND`` - System has the Python 3 development artifacts. -``Python3_INCLUDE_DIRS`` - The Python 3 include directories. -``Python3_LIBRARIES`` - The Python 3 libraries. -``Python3_LIBRARY_DIRS`` - The Python 3 library directories. -``Python3_RUNTIME_LIBRARY_DIRS`` - The Python 3 runtime library directories. -``Python3_VERSION`` - Python 3 version. -``Python3_VERSION_MAJOR`` - Python 3 major version. -``Python3_VERSION_MINOR`` - Python 3 minor version. -``Python3_VERSION_PATCH`` - Python 3 patch version. - -Hints -^^^^^ - -``Python3_ROOT_DIR`` - Define the root directory of a Python 3 installation. - -``Python3_USE_STATIC_LIBS`` - * If not defined, search for shared libraries and static libraries in that - order. - * If set to TRUE, search **only** for static libraries. - * If set to FALSE, search **only** for shared libraries. - -``Python3_FIND_REGISTRY`` - On Windows the ``Python3_FIND_REGISTRY`` variable determine the order - of preference between registry and environment variables. - the ``Python3_FIND_REGISTRY`` variable can be set to empty or one of the - following: - - * ``FIRST``: Try to use registry before environment variables. - This is the default. - * ``LAST``: Try to use registry after environment variables. - * ``NEVER``: Never try to use registry. - -``CMAKE_FIND_FRAMEWORK`` - On OS X the :variable:`CMAKE_FIND_FRAMEWORK` variable determine the order of - preference between Apple-style and unix-style package components. - - .. note:: - - Value ``ONLY`` is not supported so ``FIRST`` will be used instead. - -Artifacts Specification -^^^^^^^^^^^^^^^^^^^^^^^ - -To solve special cases, it is possible to specify directly the artifacts by -setting the following variables: - -``Python3_EXECUTABLE`` - The path to the interpreter. - -Commands -^^^^^^^^ - -This module defines the command ``Python3_add_library`` which have the same -semantic as :command:`add_library` but take care of Python module naming rules -(only applied if library is of type ``MODULE``) and add dependency to target -``Python3::Python``:: - - Python3_add_library (my_module MODULE src1.cpp) - -If library type is not specified, ``MODULE`` is assumed. -#]=======================================================================] - - -set (_PYTHON_PREFIX Python3) - -set (_Python3_REQUIRED_VERSION_MAJOR 3) - -include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) - -if (COMMAND __Python3_add_library) - macro (Python3_add_library) - __Python3_add_library (Python3 ${ARGV}) - endmacro() -endif() - -unset (_PYTHON_PREFIX) diff --git a/example/cmake/SelectLibraryConfigurations.cmake b/example/cmake/SelectLibraryConfigurations.cmake deleted file mode 100644 index fe3bb00a6..000000000 --- a/example/cmake/SelectLibraryConfigurations.cmake +++ /dev/null @@ -1,71 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# SelectLibraryConfigurations -# --------------------------- -# -# -# -# select_library_configurations( basename ) -# -# This macro takes a library base name as an argument, and will choose -# good values for basename_LIBRARY, basename_LIBRARIES, -# basename_LIBRARY_DEBUG, and basename_LIBRARY_RELEASE depending on what -# has been found and set. If only basename_LIBRARY_RELEASE is defined, -# basename_LIBRARY will be set to the release value, and -# basename_LIBRARY_DEBUG will be set to basename_LIBRARY_DEBUG-NOTFOUND. -# If only basename_LIBRARY_DEBUG is defined, then basename_LIBRARY will -# take the debug value, and basename_LIBRARY_RELEASE will be set to -# basename_LIBRARY_RELEASE-NOTFOUND. -# -# If the generator supports configuration types, then basename_LIBRARY -# and basename_LIBRARIES will be set with debug and optimized flags -# specifying the library to be used for the given configuration. If no -# build type has been set or the generator in use does not support -# configuration types, then basename_LIBRARY and basename_LIBRARIES will -# take only the release value, or the debug value if the release one is -# not set. - -# This macro was adapted from the FindQt4 CMake module and is maintained by Will -# Dicharry . - -macro( select_library_configurations basename ) - if(NOT ${basename}_LIBRARY_RELEASE) - set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.") - endif() - if(NOT ${basename}_LIBRARY_DEBUG) - set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.") - endif() - - get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND - NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND - ( _isMultiConfig OR CMAKE_BUILD_TYPE ) ) - # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for - # single-config generators, set optimized and debug libraries - set( ${basename}_LIBRARY "" ) - foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE ) - list( APPEND ${basename}_LIBRARY optimized "${_libname}" ) - endforeach() - foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG ) - list( APPEND ${basename}_LIBRARY debug "${_libname}" ) - endforeach() - elseif( ${basename}_LIBRARY_RELEASE ) - set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) - elseif( ${basename}_LIBRARY_DEBUG ) - set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} ) - else() - set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND") - endif() - - set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" ) - - if( ${basename}_LIBRARY ) - set( ${basename}_FOUND TRUE ) - endif() - - mark_as_advanced( ${basename}_LIBRARY_RELEASE - ${basename}_LIBRARY_DEBUG - ) -endmacro() diff --git a/example/deisa.yml b/example/deisa.yml deleted file mode 100644 index 75e9e9d4a..000000000 --- a/example/deisa.yml +++ /dev/null @@ -1,33 +0,0 @@ -# duration in seconds -duration: 0.75 -# global [height, width] (excluding boundary conditions or ghosts) -datasize: [60, 12] -# degree of parallelism -parallelism: { height: 3, width: 1 } - -# only the following config is passed to PDI -pdi: - metadata: # type of small values for which PDI keeps a copy - iter: int # current iteration id - dsize: { size: 2, type: array, subtype: int } # local data size including ghosts/boundary - psize: { size: 2, type: array, subtype: int } # number of processes in each dimension - pcoord: { size: 2, type: array, subtype: int } # coordinate of the process - data: # type of values for which PDI does not keep a copy - main_field: { size: [ '$dsize[0]', '$dsize[1]' ], type: array, subtype: double } - - plugins: - mpi: - deisa: - scheduler_info: /tmp/scheduler.json - init_on: main_loop - time_step: $iter - deisa_arrays: - global_t: # Name of the Deisa array - type: array - subtype: double - size: [ 10, '$psize[0]*($dsize[0]-2)', '$psize[1]*($dsize[1]-2)' ] # first dimension corresponds to time steps - subsize: [ 1, '$dsize[0]-2', '$dsize[1]-2' ] - start: [ $iter, '($dsize[0]-2)*$pcoord[0]', '($dsize[1]-2)*$pcoord[1]' ] - +timedim: 0 - map_in: - main_field: global_t # `main_field` is mapped to `global_t` diff --git a/example/deisa_client.py b/example/deisa_client.py deleted file mode 100644 index 8cba9c409..000000000 --- a/example/deisa_client.py +++ /dev/null @@ -1,26 +0,0 @@ -from deisa import Deisa - -# Scheduler file name and configuration file -scheduler_info = '/tmp/scheduler.json' - -# Initialize Deisa -deisa = Deisa(scheduler_info, nb_workers=1, use_ucx=False) - -# either: Get data descriptor as a list of Deisa arrays object -arrays = deisa.get_deisa_arrays() - -# Select data -gt = arrays["global_t"][...] - -# Check contract -arrays.check_contract() - - -########################## -# Perform analysis here -########################## - - -arrays.validate_contract() - -deisa.wait_for_last_bridge_and_shutdown() diff --git a/example/example.c b/example/example.c index 7beedfa48..1c827212b 100644 --- a/example/example.c +++ b/example/example.c @@ -25,11 +25,12 @@ #include #include #include +#ifndef WITHOUT_PARACONF #include +#endif #include #include #include -#include #include "pdi.h" @@ -159,10 +160,14 @@ int main(int argc, char* argv[]) exit(1); } +#ifndef WITHOUT_PARACONF PC_tree_t conf = PC_parse_path(argv[1]); +#endif MPI_Comm main_comm = MPI_COMM_WORLD; +#ifndef WITHOUT_PARACONF PDI_init(PC_get(conf, ".pdi")); +#endif PDI_expose("mpi_comm", &main_comm, PDI_INOUT); @@ -178,19 +183,39 @@ int main(int argc, char* argv[]) long longval; int dsize[2]; +#ifndef WITHOUT_PARACONF PC_int(PC_get(conf, ".datasize[0]"), &longval); +#else + longval = 8; // size is 8 by default because, why not +#endif dsize[0] = longval; +#ifndef WITHOUT_PARACONF PC_int(PC_get(conf, ".datasize[1]"), &longval); +#else + longval = 8 * psize_1d; // default size is 8 * psize_1d so that it's easy to parallelize over psize_1d processes +#endif dsize[1] = longval; int psize[2]; +#ifndef WITHOUT_PARACONF PC_int(PC_get(conf, ".parallelism.height"), &longval); +#else + longval = 1; +#endif psize[0] = longval; +#ifndef WITHOUT_PARACONF PC_int(PC_get(conf, ".parallelism.width"), &longval); +#else + longval = psize_1d; // all the parallelism is here by default +#endif psize[1] = longval; double duration; +#ifndef WITHOUT_PARACONF PC_double(PC_get(conf, ".duration"), &duration); +#else + duration = 0.1; +#endif // get local & add ghosts to sizes assert(dsize[0] % psize[0] == 0); @@ -249,7 +274,9 @@ int main(int argc, char* argv[]) PDI_finalize(); +#ifndef WITHOUT_PARACONF PC_tree_destroy(&conf); +#endif free(cur); free(next); diff --git a/mock_pdi/AUTHORS b/mock_pdi/AUTHORS new file mode 100644 index 000000000..e73cf3e59 --- /dev/null +++ b/mock_pdi/AUTHORS @@ -0,0 +1,5 @@ +Julian Auriac - CEA (julian.auriac@cea.fr) +* Added support for the MockFind approach + +Julien Bigot - CEA (julien.bigot@cea.fr) +* Added support for the SubdirMock approach and for Paraconf target mock diff --git a/mock_pdi/CHANGELOG.md b/mock_pdi/CHANGELOG.md new file mode 100644 index 000000000..8ba983a2e --- /dev/null +++ b/mock_pdi/CHANGELOG.md @@ -0,0 +1,25 @@ +# Changelog for the Mock PDI project +All notable changes to the mock_pdi project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + + +## [Unreleased] + +### Added + +### Changed + +### Deprecated + +### Removed + +### Fixed + +### Security + + +## [1.10.0] - 2026-01-31 + +### Added +* Add Mock PDI diff --git a/.github/workflows/indent.yml b/mock_pdi/CMakeLists.txt similarity index 85% rename from .github/workflows/indent.yml rename to mock_pdi/CMakeLists.txt index 68d546367..6faf7a639 100644 --- a/.github/workflows/indent.yml +++ b/mock_pdi/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -27,14 +27,9 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -name: indent -on: - push: { branches: [ main ] } - pull_request: - types: [ready_for_review] -jobs: - indent: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - run: exec ./bin/test_indent +cmake_minimum_required(VERSION 3.22...4.2) +project(PDI LANGUAGES C) + +option(PDI_MOCK_PARACONF_TARGET "Provide a Mock paraconf target in SubdirMock PDI" OFF) + +include("${CMAKE_CURRENT_SOURCE_DIR}/PDIConfig.cmake") diff --git a/mock_pdi/LICENSE b/mock_pdi/LICENSE new file mode 100644 index 000000000..5f4aa28fb --- /dev/null +++ b/mock_pdi/LICENSE @@ -0,0 +1,26 @@ +BSD 3-Clause License + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/mock_pdi/PDIConfig.cmake b/mock_pdi/PDIConfig.cmake new file mode 100644 index 000000000..b10baae92 --- /dev/null +++ b/mock_pdi/PDIConfig.cmake @@ -0,0 +1,65 @@ +#============================================================================= +# Copyright (C) 2025-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the names of CEA, nor the names of the contributors may be used to +# endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +cmake_policy(PUSH) +cmake_policy(VERSION 3.22...4.2) + +include(CMakeFindDependencyMacro) + +# Check for unsupported required components +if(DEFINED PDI_FIND_COMPONENTS) + foreach(component ${PDI_FIND_COMPONENTS}) + if(NOT component STREQUAL "C") + message(FATAL_ERROR "The component '${component}' is not supported by the mock PDI; only the C component is.") + endif() + endforeach() +endif() + +# Create the PDI_C target only once +if(NOT TARGET PDI_C) + add_library(PDI_C INTERFACE) + target_compile_features(PDI_C INTERFACE cxx_std_20 c_std_17) + target_include_directories(PDI_C INTERFACE "${CMAKE_CURRENT_LIST_DIR}") + target_compile_definitions(PDI_C INTERFACE "WITHOUT_PDI=1") + add_library(PDI::pdi ALIAS PDI_C) + add_library(PDI::PDI_C ALIAS PDI_C) +endif() + +if(NOT TARGET paraconf::paraconf) + if(DEFINED PDI_MOCK_PARACONF_TARGET AND "${PDI_MOCK_PARACONF_TARGET}") + add_library(paraconf INTERFACE) + target_compile_definitions(paraconf INTERFACE "WITHOUT_PARACONF=1") + add_library(paraconf::paraconf ALIAS paraconf) + else() + find_dependency(paraconf COMPONENTS C) + endif() +endif() +target_link_libraries(PDI_C INTERFACE paraconf::paraconf) + +cmake_policy(POP) diff --git a/vendor/paraconf-1.0.0/example/CMakeLists.txt b/mock_pdi/PDIConfigVersion.cmake similarity index 67% rename from vendor/paraconf-1.0.0/example/CMakeLists.txt rename to mock_pdi/PDIConfigVersion.cmake index f949c5500..96cb9085d 100644 --- a/vendor/paraconf-1.0.0/example/CMakeLists.txt +++ b/mock_pdi/PDIConfigVersion.cmake @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2019 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -27,30 +27,4 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.5) -project(paraconf_examples LANGUAGES C CXX) - -if("${BUILD_FORTRAN}") - enable_language(Fortran) -endif() - -# Includes -include(CTest) - -find_package(paraconf REQUIRED) - -# Default standard in the project is C99 & C++14 -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED TRUE) - - -add_executable(example example.c) -target_link_libraries(example paraconf::paraconf) -add_test(NAME example COMMAND example "${CMAKE_CURRENT_SOURCE_DIR}/example.yml") - - -if("${BUILD_FORTRAN}") - add_executable(example_f90 example.f90) - target_link_libraries(example_f90 paraconf::paraconf_f90) - add_test(NAME example_f90 COMMAND example_f90 "${CMAKE_CURRENT_SOURCE_DIR}/example.yml") -endif() +set(PDI_VERSION "1.10.1") diff --git a/mock_pdi/pdi.h b/mock_pdi/pdi.h new file mode 100644 index 000000000..5515ddbdf --- /dev/null +++ b/mock_pdi/pdi.h @@ -0,0 +1,156 @@ +/******************************************************************************* +* Copyright (C) 2025-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of CEA nor the names of its contributors may be used to +* endorse or promote products derived from this software without specific +* prior written permission. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +******************************************************************************/ + +#ifndef MOCK_PDI_H_ +#define MOCK_PDI_H_ + +#include + +#ifndef WITHOUT_PARACONF +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum PDI_status_e { + PDI_OK = 0, + PDI_UNAVAILABLE, + PDI_ERR_SPECTREE, + PDI_ERR_CONFIG = PDI_ERR_SPECTREE, + PDI_ERR_VALUE, + PDI_ERR_PLUGIN, + PDI_ERR_IMPL, + PDI_ERR_SYSTEM, + PDI_ERR_STATE, + PDI_ERR_PERMISSION, + PDI_ERR_RIGHT = PDI_ERR_PERMISSION, + PDI_ERR_TYPE, + PDI_NB_STATUSES_DEFINED +} PDI_status_t; + +typedef void (*PDI_errfunc_f)(PDI_status_t status, const char* message, void* context); + +typedef struct PDI_errhandler_s { + PDI_errfunc_f func; + + void* context; + +} PDI_errhandler_t; + +static const PDI_errhandler_t PDI_NULL_HANDLER = {NULL, NULL}; + +static const PDI_errhandler_t PDI_ASSERT_HANDLER = {NULL, NULL}; + +static const PDI_errhandler_t PDI_WARN_HANDLER = {NULL, NULL}; + +static inline const char* PDI_errmsg(void) +{ + return ""; +} + +static inline PDI_errhandler_t PDI_errhandler(PDI_errhandler_t handler) +{ + return PDI_NULL_HANDLER; +} + +#ifndef WITHOUT_PARACONF +static inline PDI_status_t PDI_init(PC_tree_t conf) +{ + return PDI_OK; +} +#endif + +static inline PDI_status_t PDI_finalize(void) +{ + return PDI_OK; +} + +static inline PDI_status_t PDI_version(unsigned long* provided, unsigned long expected) +{ + return PDI_OK; +} + +typedef enum PDI_inout_e { + PDI_NONE = 0, + PDI_IN = 1, + PDI_OUT = 2, + PDI_INOUT = 3 +} PDI_inout_t; + +static inline PDI_status_t PDI_share(const char* name, const void* data, PDI_inout_t access) +{ + return PDI_OK; +} + +static inline PDI_status_t PDI_access(const char* name, void** buffer, PDI_inout_t inout) +{ + return PDI_OK; +} + +static inline PDI_status_t PDI_release(const char* name) +{ + return PDI_OK; +} + +static inline PDI_status_t PDI_reclaim(const char* name) +{ + return PDI_OK; +} + +static inline PDI_status_t PDI_event(const char* event) +{ + return PDI_OK; +} + +static inline PDI_status_t PDI_expose(const char* name, const void* data, PDI_inout_t access) +{ + return PDI_OK; +} + +static inline PDI_status_t PDI_multi_expose(const char* event_name, const char* name, const void* data, PDI_inout_t access, ...) +{ + return PDI_OK; +} + +#ifdef PDI_WITH_DEPRECATED + +static inline PDI_status_t PDI_transaction_begin(const char* name) +{ + return PDI_OK; +} + +static inline PDI_status_t PDI_transaction_end(void) +{ + return PDI_OK; +} + +#endif // PDI_WITH_DEPRECATED + +#ifdef __cplusplus +} // extern C +#endif + +#endif // MOCK_PDI_H_ diff --git a/pdi/CHANGELOG.md b/pdi/CHANGELOG.md index 8096eb024..16035306e 100644 --- a/pdi/CHANGELOG.md +++ b/pdi/CHANGELOG.md @@ -16,14 +16,31 @@ and this project adheres to ### For users #### Added +* fix macOS Python support. [#656](https://github.com/pdidev/pdi/issues/656) +* added a `ENABLE_BENCHMARKING` flag to cmake to enable running the benchmarks + as part of the tests (off by default) + [#679](https://github.com/pdidev/pdi/issues/679) #### Changed +* The minimum version of C required is now C17 (ISO/IEC 9899:2018) instead of + C11. +* Fully qualify `std::move` calls to prevent a compilation warning and incorrect + usages [#675](https://github.com/pdidev/pdi/issues/675) +* benchmarks are not run as part of the test suite by default anymore, one must + set `ENABLE_BENCHMARKING` to `ON` in Cmake to re-enable them #### Deprecated +* Error names have been improved to fix + [#670](https://github.com/pdidev/pdi/issues/670): + - `PDI_ERR_CONFIG` has been renamed to `PDI_ERR_SPECTREE`, + - `PDI_ERR_RIGHT` has been renamed to `PDI_ERR_PERMISSION`, + - `PDI_UNAVAILABLE` is never used and will be removed. #### Removed #### Fixed +* Fix some incorrect uses of `{fmt}` that could lead to compilation errors in + C++ 20+ or crashes in C++ <20 [#660](https://github.com/pdidev/pdi/issues/660) #### Security @@ -31,12 +48,18 @@ and this project adheres to ### For plugin developers #### Added +* Added a new testing API (`pdi/testing.h`) to replace usage of assert in plugin + tests [#236](https://github.com/pdidev/pdi/issues/236) #### Changed +* Versions of C++ used in now C++ 20 instead of C++ 17. +* `PDI::Right_error` has been replaced by `PDI::Permission_error`. +* `PDI::Config_error` has been replaced by `PDI::Spectree_error`. #### Deprecated #### Removed +* `PDI::Unavailable_error` was never used and has been removed. #### Fixed @@ -44,6 +67,43 @@ and this project adheres to +## [1.10.1] - 2026-02-04 + +### For users + +#### Fixed +* Support multiple consecutive calls to `find_package(PDI)` + [#526](https://github.com/pdidev/pdi/issues/526) + + + +## [1.10.0] - 2026-01-31 + +### For users + +#### Added +* Added macOS CI [#556](https://github.com/pdidev/pdi/issues/556) + +#### Changed +* Update the version of dependencies according to our policy: oldest supported + Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: + CMake 3.22, Doxygen 1.9.1, pybind11 2.9.1, Python 3.10.6, and spdlog 1.9.2 + [#613](https://github.com/pdidev/pdi/issues/613) + + + +## [1.9.3] - 2026-01-16 + +### For users + +#### Fixed +* Updated embedded versions of zpp to fix a build issue with recent cmake + [#631](https://github.com/pdidev/pdi/issues/631) +* Updated doxygen files to be compatible with recent versions of Doxygen + [#629](https://github.com/pdidev/pdi/issues/629) + + + ## [1.9.1] - 2025-05-07 ### For users diff --git a/pdi/CMakeLists.txt b/pdi/CMakeLists.txt index 4348faf8c..b8590a3ad 100644 --- a/pdi/CMakeLists.txt +++ b/pdi/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -27,7 +27,7 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(PDI LANGUAGES CXX C) list(APPEND CMAKE_MODULE_PATH "${PDI_SOURCE_DIR}/cmake") @@ -56,27 +56,13 @@ option(BUILD_SHARED_LIBS "Build shared libraries rather than static ones" ON) option(BUILD_TESTING "Build tests" ON) option(BUILD_FORTRAN "Enable Fortran support" ON) option(BUILD_PYTHON "Enable Python support" "${BUILD_UNSTABLE}") +option(ENABLE_BENCHMARKING "Activate benchmarks in the test suite" OFF) -if("${BUILD_TESTING}" AND "${CMAKE_VERSION}" VERSION_LESS "3.10") - message(FATAL_ERROR "Minimum CMake version to build tests is 3.10. Please update CMake or turn off testing by adding the flag `-DBUILD_TESTING=OFF` to the cmake command line.") -endif() -if("${BUILD_DOCUMENTATION}" AND "${CMAKE_VERSION}" VERSION_LESS "3.10") - message(FATAL_ERROR "Minimum CMake version to build documentation is 3.10. Please update CMake or turn off documentation generation by adding the flag `-DBUILD_DOCUMENTATION=OFF` to the cmake command line.") -endif() if(NOT "${BUILD_SHARED_LIBS}") message(FATAL_ERROR "Building PDI as a static lib is not supported currently") endif() -# A little compatibility macro - -if("${CMAKE_VERSION}" VERSION_LESS "3.12") - set(LIBRARY_COMPONENT "COMPONENT" "Runtime") -else() - set(LIBRARY_COMPONENT "COMPONENT" "Runtime" "NAMELINK_COMPONENT" "Development") -endif() - - # Language support if("${BUILD_FORTRAN}") @@ -107,16 +93,20 @@ set(PARACONF_COMPONENTS "C") if("${BUILD_FORTRAN}") list(APPEND PARACONF_COMPONENTS "f90") endif() -find_package(paraconf 1.0.0 REQUIRED COMPONENTS ${PARACONF_COMPONENTS}) # must match PDIConfig.cmake.in -find_package(spdlog 1.5.0 REQUIRED) # must match PDIConfig.cmake.in +set(PDI_REQUIRED_PARACONF_VERSION 1.0) # used in PDIConfig too +find_package(paraconf "${PDI_REQUIRED_PARACONF_VERSION}" REQUIRED COMPONENTS ${PARACONF_COMPONENTS}) # must match PDIConfig.cmake.in +set(PDI_REQUIRED_SPDLOG_VERSION 1.9) # used in PDIConfig too +find_package(spdlog "${PDI_REQUIRED_SPDLOG_VERSION}" REQUIRED) # must match PDIConfig.cmake.in if("${BUILD_PYTHON}") - find_package(Python3Path 3.8.2 REQUIRED COMPONENTS Interpreter Development) + set(PDI_REQUIRED_PYTHON_VERSION 3.10) # used in PDIConfig too + find_package(Python3Path "${PDI_REQUIRED_PYTHON_VERSION}" REQUIRED COMPONENTS Interpreter Development) set(Python_ADDITIONAL_VERSIONS "${Python3_VERSION}" CACHE STRING "Python version found by FindPython3 for coherency" FORCE) set(PYBIND11_PYTHON_VERSION "${Python3_VERSION}" CACHE STRING "Python version to use for compiling modules" FORCE) - find_package(pybind11 2.4.3 REQUIRED) # must match PDIConfig.cmake.in + set(PDI_REQUIRED_PYBIND11_VERSION 2.9) # used in PDIConfig too + find_package(pybind11 "${PDI_REQUIRED_PYBIND11_VERSION}" REQUIRED) endif() if("${BUILD_FORTRAN}" OR "${BUILD_DOCUMENTATION}") - add_subdirectory("../vendor/zpp-1.0.16/" "zpp") + add_subdirectory("../vendor/zpp-1.1.0/" "zpp") endif() @@ -180,7 +170,7 @@ target_include_directories(PDI_C target_link_libraries(PDI_C PUBLIC paraconf::paraconf ${CMAKE_DL_LIBS} PRIVATE spdlog::spdlog) -target_compile_features(PDI_C PRIVATE cxx_std_17 c_std_11) +target_compile_features(PDI_C PUBLIC cxx_std_20 c_std_17) set_property(TARGET PDI_C PROPERTY LIBRARY_OUTPUT_NAME "pdi") set_property(TARGET PDI_C PROPERTY ENABLE_EXPORTS TRUE) set_property(TARGET PDI_C PROPERTY C_VISIBILITY_PRESET hidden) @@ -193,7 +183,7 @@ set_property(TARGET PDI_C APPEND PROPERTY COMPATIBLE_INTERFACE_STRING PDI_MAJOR_ add_library(PDI::pdi ALIAS PDI_C) add_library(PDI::PDI_C ALIAS PDI_C) install(TARGETS PDI_C EXPORT PDI_C_EXPORT - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" ${LIBRARY_COMPONENT} + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Runtime NAMELINK_COMPONENT Development ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Development INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) @@ -215,10 +205,9 @@ install(EXPORT PDI_C_EXPORT NAMESPACE "PDI::" DESTINATION "${INSTALL_CMAKEDIR}" add_library(PDI_plugins INTERFACE) target_link_libraries(PDI_plugins INTERFACE PDI::PDI_C spdlog::spdlog) -target_compile_features(PDI_plugins INTERFACE cxx_std_17 c_std_11) add_library(PDI::PDI_plugins ALIAS PDI_plugins) install(TARGETS PDI_plugins EXPORT PDI_plugins_EXPORT - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" ${LIBRARY_COMPONENT} + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Runtime NAMELINK_COMPONENT Development ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Development INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) @@ -250,15 +239,7 @@ if("${BUILD_PYTHON}") "$" PRIVATE "$" ) - # We should link to PDI::PDI_plugins, but since it imposes C++17 which fails with - # pybind11 <= 2.4.5 , we use its dependants, cross fingers and hope for C++-14 to work - if(2.4.5 VERSION_LESS_EQUAL "${pybind11_VERSION}") - target_link_libraries(PDI_pysupport PUBLIC PDI::PDI_plugins) - else() - target_link_libraries(PDI_pysupport PUBLIC PDI::PDI_C spdlog::spdlog) - endif() - target_link_libraries(PDI_pysupport PUBLIC pybind11::pybind11) - target_compile_features(PDI_pysupport PUBLIC cxx_std_14 c_std_11) + target_link_libraries(PDI_pysupport PUBLIC pybind11::pybind11 pybind11::python_link_helper PDI::PDI_plugins) set_property(TARGET PDI_pysupport PROPERTY LIBRARY_OUTPUT_NAME "pdi_pysupport") set_property(TARGET PDI_pysupport PROPERTY ENABLE_EXPORTS TRUE) set_property(TARGET PDI_pysupport PROPERTY C_VISIBILITY_PRESET hidden) @@ -270,7 +251,7 @@ if("${BUILD_PYTHON}") set_property(TARGET PDI_pysupport APPEND PROPERTY COMPATIBLE_INTERFACE_STRING PDI_MAJOR_VERSION) add_library(PDI::PDI_pysupport ALIAS PDI_pysupport) install(TARGETS PDI_pysupport EXPORT PDI_pysupport_EXPORT - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" ${LIBRARY_COMPONENT} + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Runtime NAMELINK_COMPONENT Development ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Development INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) @@ -341,7 +322,7 @@ if("${BUILD_FORTRAN}") CACHE PATH "Fortran module directory (LIBDIR/pdi/finclude/${CMAKE_Fortran_COMPILER_ID}-${Fortran_COMPILER_MINOR_VERSION})") install(TARGETS PDI_f90 EXPORT pdi_f90_EXPORT - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT ${LIBRARY_COMPONENT} + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT COMPONENT Runtime NAMELINK_COMPONENT Development ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Development INCLUDES DESTINATION "${INSTALL_FMODDIR}" ) @@ -393,9 +374,6 @@ write_basic_package_version_file("${PDI_BINARY_DIR}/PDIConfigVersion.cmake" COMPATIBILITY AnyNewerVersion ) install(FILES - cmake/CMakeFindDependencyMacro.cmake - cmake/FindPackageHandleStandardArgs.cmake - cmake/FindPackageMessage.cmake "${PDI_BINARY_DIR}/PDIConfig.cmake" "${PDI_BINARY_DIR}/PDIConfigVersion.cmake" DESTINATION "${INSTALL_CMAKEDIR}" diff --git a/pdi/CONTRIBUTING.md b/pdi/CONTRIBUTING.md index 04ee5f502..ed739602d 100644 --- a/pdi/CONTRIBUTING.md +++ b/pdi/CONTRIBUTING.md @@ -49,7 +49,10 @@ The blocks *should* be in order: ## C coding conventions -These conventions only apply to the C part of PDI (the C public application API) +These conventions only apply to the C part of PDI (the C public application API). + +PDI C public application API is C 17. +Features from more recent versions of C are not allowed. Naming: * all public elements (symbol, type, macro, ...) *must* start with the `PDI_` @@ -66,6 +69,9 @@ Prototypes: ## C++ coding conventions +PDI is C++ 20. +Features from more recent versions of C++ are not allowed. + The auto keyword should be used for types as `auto&&` and only in one of the following cases: * in iterations either in range based for or to refer to iterators diff --git a/pdi/VERSION b/pdi/VERSION index 1deaa0863..7847b831d 100644 --- a/pdi/VERSION +++ b/pdi/VERSION @@ -1 +1 @@ -1.10.0-alpha +1.11.0-alpha diff --git a/pdi/benchmarks/CMakeLists.txt b/pdi/benchmarks/CMakeLists.txt index 0c86b7fef..1c440ecf9 100644 --- a/pdi/benchmarks/CMakeLists.txt +++ b/pdi/benchmarks/CMakeLists.txt @@ -1,6 +1,6 @@ #============================================================================= # Copyright (C) 2022 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) -# Copyright (C) 2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2024-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,19 +27,19 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(PDI_benchmarks) if(NOT TARGET GTest::gtest) option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" OFF) - add_subdirectory("../../vendor/googletest-b4aaf97/" "googletest" EXCLUDE_FROM_ALL) + add_subdirectory("../../vendor/googletest-56efe39/" "googletest" EXCLUDE_FROM_ALL) endif() if(NOT TARGET benchmark::benchmark) option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." OFF) option(BENCHMARK_ENABLE_WERROR "Build Release candidates with -Werror." OFF) option(BENCHMARK_ENABLE_INSTALL "Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)" OFF) - add_subdirectory("../../vendor/benchmark-38df9da/" "benchmark" EXCLUDE_FROM_ALL) + add_subdirectory("../../vendor/benchmark-4ed29ae/" "benchmark" EXCLUDE_FROM_ALL) endif() include(CTest) @@ -57,7 +57,7 @@ set(PDI_benchmark_SRC PDI_logger.cxx) add_executable(PDI_benchmarks ${PDI_benchmark_SRC}) -target_compile_features(PDI_benchmarks PUBLIC cxx_std_17) +target_compile_features(PDI_benchmarks PUBLIC cxx_std_20) target_include_directories(PDI_benchmarks PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../src") target_link_libraries(PDI_benchmarks benchmark::benchmark @@ -68,4 +68,7 @@ target_link_libraries(PDI_benchmarks set(RUNTEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake/runtest-dir") add_test(NAME PDI_benchmarks COMMAND "${RUNTEST_DIR}" sh -c "$ --benchmark_format=json > ${BENCHMARK_RESULT_PATH}/PDI_benchmark_result.json") +if(NOT "${ENABLE_BENCHMARKING}") + set_property(TEST PDI_benchmarks PROPERTY DISABLED TRUE) +endif() set_property(TEST PDI_benchmarks PROPERTY TIMEOUT 300) diff --git a/pdi/cmake/CMakeFindDependencyMacro.cmake b/pdi/cmake/CMakeFindDependencyMacro.cmake deleted file mode 100644 index 6a89fff2a..000000000 --- a/pdi/cmake/CMakeFindDependencyMacro.cmake +++ /dev/null @@ -1,66 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -CMakeFindDependencyMacro -------------------------- - -.. command:: find_dependency - - The ``find_dependency()`` macro wraps a :command:`find_package` call for - a package dependency:: - - find_dependency( [...]) - - It is designed to be used in a - :ref:`Package Configuration File ` - (``Config.cmake``). ``find_dependency`` forwards the correct - parameters for ``QUIET`` and ``REQUIRED`` which were passed to - the original :command:`find_package` call. Any additional arguments - specified are forwarded to :command:`find_package`. - - If the dependency could not be found it sets an informative diagnostic - message and calls :command:`return` to end processing of the calling - package configuration file and return to the :command:`find_package` - command that loaded it. - - .. note:: - - The call to :command:`return` makes this macro unsuitable to call - from :ref:`Find Modules`. -#]=======================================================================] - -macro(find_dependency dep) - if (NOT ${dep}_FOUND) - set(cmake_fd_quiet_arg) - if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY) - set(cmake_fd_quiet_arg QUIET) - endif() - set(cmake_fd_required_arg) - if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED) - set(cmake_fd_required_arg REQUIRED) - endif() - - get_property(cmake_fd_alreadyTransitive GLOBAL PROPERTY - _CMAKE_${dep}_TRANSITIVE_DEPENDENCY - ) - - find_package(${dep} ${ARGN} - ${cmake_fd_quiet_arg} - ${cmake_fd_required_arg} - ) - - if(NOT DEFINED cmake_fd_alreadyTransitive OR cmake_fd_alreadyTransitive) - set_property(GLOBAL PROPERTY _CMAKE_${dep}_TRANSITIVE_DEPENDENCY TRUE) - endif() - - if (NOT ${dep}_FOUND) - set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "${CMAKE_FIND_PACKAGE_NAME} could not be found because dependency ${dep} could not be found.") - set(${CMAKE_FIND_PACKAGE_NAME}_FOUND False) - return() - endif() - set(cmake_fd_required_arg) - set(cmake_fd_quiet_arg) - set(cmake_fd_exact_arg) - endif() -endmacro() diff --git a/pdi/cmake/DefaultKind.cmake b/pdi/cmake/DefaultKind.cmake index d0ae699cc..2e1aed862 100644 --- a/pdi/cmake/DefaultKind.cmake +++ b/pdi/cmake/DefaultKind.cmake @@ -1,5 +1,5 @@ ################################################################################ -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -22,9 +22,8 @@ # THE SOFTWARE. ################################################################################ -cmake_minimum_required(VERSION 3.16...3.25) - -list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}") +cmake_policy(PUSH) +cmake_policy(VERSION 3.22...4.2) function(get_default_kind TYPE DEFAULT_KIND_VAR) if(DEFINED "${DEFAULT_KIND_VAR}") @@ -66,3 +65,5 @@ end program test_kind${TYPE} mark_as_advanced("${DEFAULT_KIND_VAR}") message(STATUS "Checking default Fortran kind for ${TYPE} -- ${${DEFAULT_KIND_VAR}}") endfunction() + +cmake_policy(POP) diff --git a/pdi/cmake/FindDoxygen.cmake b/pdi/cmake/FindDoxygen.cmake deleted file mode 100644 index f5c0b050e..000000000 --- a/pdi/cmake/FindDoxygen.cmake +++ /dev/null @@ -1,1118 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindDoxygen ------------ - -Doxygen is a documentation generation tool (see http://www.doxygen.org). -This module looks for Doxygen and some optional tools it supports. These -tools are enabled as components in the :command:`find_package` command: - -``dot`` - `Graphviz `_ ``dot`` utility used to render various - graphs. -``mscgen`` - `Message Chart Generator `_ utility used - by Doxygen's ``\msc`` and ``\mscfile`` commands. -``dia`` - `Dia `_ the diagram editor used by Doxygen's - ``\diafile`` command. - -Examples: - -.. code-block:: cmake - - # Require dot, treat the other components as optional - find_package(Doxygen - REQUIRED dot - OPTIONAL_COMPONENTS mscgen dia) - -The following variables are defined by this module: - -.. variable:: DOXYGEN_FOUND - - True if the ``doxygen`` executable was found. - -.. variable:: DOXYGEN_VERSION - - The version reported by ``doxygen --version``. - -The module defines ``IMPORTED`` targets for Doxygen and each component found. -These can be used as part of custom commands, etc. and should be preferred over -old-style (and now deprecated) variables like ``DOXYGEN_EXECUTABLE``. The -following import targets are defined if their corresponding executable could be -found (the component import targets will only be defined if that component was -requested): - -:: - - Doxygen::doxygen - Doxygen::dot - Doxygen::mscgen - Doxygen::dia - - -Functions -^^^^^^^^^ - -.. command:: doxygen_add_docs - - This function is intended as a convenience for adding a target for generating - documentation with Doxygen. It aims to provide sensible defaults so that - projects can generally just provide the input files and directories and that - will be sufficient to give sensible results. The function supports the - ability to customize the Doxygen configuration used to build the - documentation. - - :: - - doxygen_add_docs(targetName - [filesOrDirs...] - [ALL] - [WORKING_DIRECTORY dir] - [COMMENT comment]) - - The function constructs a ``Doxyfile`` and defines a custom target that runs - Doxygen on that generated file. The listed files and directories are used as - the ``INPUT`` of the generated ``Doxyfile`` and they can contain wildcards. - Any files that are listed explicitly will also be added as ``SOURCES`` of the - custom target so they will show up in an IDE project's source list. - - So that relative input paths work as expected, by default the working - directory of the Doxygen command will be the current source directory (i.e. - :variable:`CMAKE_CURRENT_SOURCE_DIR`). This can be overridden with the - ``WORKING_DIRECTORY`` option to change the directory used as the relative - base point. Note also that Doxygen's default behavior is to strip the working - directory from relative paths in the generated documentation (see the - ``STRIP_FROM_PATH`` `Doxygen config option - `_ for details). - - If provided, the optional ``comment`` will be passed as the ``COMMENT`` for - the :command:`add_custom_target` command used to create the custom target - internally. - - If ALL is set, the target will be added to the default build target. - - The contents of the generated ``Doxyfile`` can be customized by setting CMake - variables before calling ``doxygen_add_docs()``. Any variable with a name of - the form ``DOXYGEN_`` will have its value substituted for the - corresponding ```` configuration option in the ``Doxyfile``. See the - `Doxygen documentation `_ for the - full list of supported configuration options. - - Some of Doxygen's defaults are overridden to provide more appropriate - behavior for a CMake project. Each of the following will be explicitly set - unless the variable already has a value before ``doxygen_add_docs()`` is - called (with some exceptions noted): - - .. variable:: DOXYGEN_HAVE_DOT - - Set to ``YES`` if the ``dot`` component was requested and it was found, - ``NO`` otherwise. Any existing value of ``DOXYGEN_HAVE_DOT`` is ignored. - - .. variable:: DOXYGEN_DOT_MULTI_TARGETS - - Set to ``YES`` by this module (note that this requires a ``dot`` version - newer than 1.8.10). This option is only meaningful if ``DOXYGEN_HAVE_DOT`` - is also set to ``YES``. - - .. variable:: DOXYGEN_GENERATE_LATEX - - Set to ``NO`` by this module. - - .. variable:: DOXYGEN_WARN_FORMAT - - For Visual Studio based generators, this is set to the form recognized by - the Visual Studio IDE: ``$file($line) : $text``. For all other generators, - Doxygen's default value is not overridden. - - .. variable:: DOXYGEN_PROJECT_NAME - - Populated with the name of the current project (i.e. - :variable:`PROJECT_NAME`). - - .. variable:: DOXYGEN_PROJECT_NUMBER - - Populated with the version of the current project (i.e. - :variable:`PROJECT_VERSION`). - - .. variable:: DOXYGEN_PROJECT_BRIEF - - Populated with the description of the current project (i.e. - :variable:`PROJECT_DESCRIPTION`). - - .. variable:: DOXYGEN_INPUT - - Projects should not set this variable. It will be populated with the set of - files and directories passed to ``doxygen_add_docs()``, thereby providing - consistent behavior with the other built-in commands like - :command:`add_executable`, :command:`add_library` and - :command:`add_custom_target`. If a variable named ``DOXYGEN_INPUT`` is set - by the project, it will be ignored and a warning will be issued. - - .. variable:: DOXYGEN_RECURSIVE - - Set to ``YES`` by this module. - - .. variable:: DOXYGEN_EXCLUDE_PATTERNS - - If the set of inputs includes directories, this variable will specify - patterns used to exclude files from them. The following patterns are added - by ``doxygen_add_docs()`` to ensure CMake-specific files and directories - are not included in the input. If the project sets - ``DOXYGEN_EXCLUDE_PATTERNS``, those contents are merged with these - additional patterns rather than replacing them: - - :: - - */.git/* - */.svn/* - */.hg/* - */CMakeFiles/* - */_CPack_Packages/* - DartConfiguration.tcl - CMakeLists.txt - CMakeCache.txt - - .. variable:: DOXYGEN_OUTPUT_DIRECTORY - - Set to :variable:`CMAKE_CURRENT_BINARY_DIR` by this module. Note that if - the project provides its own value for this and it is a relative path, it - will be converted to an absolute path relative to the current binary - directory. This is necessary because doxygen will normally be run from a - directory within the source tree so that relative source paths work as - expected. If this directory does not exist, it will be recursively created - prior to executing the doxygen commands. - -To change any of these defaults or override any other Doxygen config option, -set relevant variables before calling ``doxygen_add_docs()``. For example: - - .. code-block:: cmake - - set(DOXYGEN_GENERATE_HTML NO) - set(DOXYGEN_GENERATE_MAN YES) - - doxygen_add_docs( - doxygen - ${PROJECT_SOURCE_DIR} - COMMENT "Generate man pages" - ) - -A number of Doxygen config options accept lists of values, but Doxygen requires -them to be separated by whitespace. CMake variables hold lists as a string with -items separated by semi-colons, so a conversion needs to be performed. The -``doxygen_add_docs()`` command specifically checks the following Doxygen config -options and will convert their associated CMake variable's contents into the -required form if set. - -:: - - ABBREVIATE_BRIEF - ALIASES - CITE_BIB_FILES - DIAFILE_DIRS - DOTFILE_DIRS - DOT_FONTPATH - ENABLED_SECTIONS - EXAMPLE_PATH - EXAMPLE_PATTERNS - EXCLUDE - EXCLUDE_PATTERNS - EXCLUDE_SYMBOLS - EXPAND_AS_DEFINED - EXTENSION_MAPPING - EXTRA_PACKAGES - EXTRA_SEARCH_MAPPINGS - FILE_PATTERNS - FILTER_PATTERNS - FILTER_SOURCE_PATTERNS - HTML_EXTRA_FILES - HTML_EXTRA_STYLESHEET - IGNORE_PREFIX - IMAGE_PATH - INCLUDE_FILE_PATTERNS - INCLUDE_PATH - INPUT - LATEX_EXTRA_FILES - LATEX_EXTRA_STYLESHEET - MATHJAX_EXTENSIONS - MSCFILE_DIRS - PLANTUML_INCLUDE_PATH - PREDEFINED - QHP_CUST_FILTER_ATTRS - QHP_SECT_FILTER_ATTRS - STRIP_FROM_INC_PATH - STRIP_FROM_PATH - TAGFILES - TCL_SUBST - -The following single value Doxygen options will be quoted automatically -if they contain at least one space: - -:: - - CHM_FILE - DIA_PATH - DOCBOOK_OUTPUT - DOCSET_FEEDNAME - DOCSET_PUBLISHER_NAME - DOT_FONTNAME - DOT_PATH - EXTERNAL_SEARCH_ID - FILE_VERSION_FILTER - GENERATE_TAGFILE - HHC_LOCATION - HTML_FOOTER - HTML_HEADER - HTML_OUTPUT - HTML_STYLESHEET - INPUT_FILTER - LATEX_FOOTER - LATEX_HEADER - LATEX_OUTPUT - LAYOUT_FILE - MAN_OUTPUT - MAN_SUBDIR - MATHJAX_CODEFILE - MSCGEN_PATH - OUTPUT_DIRECTORY - PERL_PATH - PLANTUML_JAR_PATH - PROJECT_BRIEF - PROJECT_LOGO - PROJECT_NAME - QCH_FILE - QHG_LOCATION - QHP_CUST_FILTER_NAME - QHP_VIRTUAL_FOLDER - RTF_EXTENSIONS_FILE - RTF_OUTPUT - RTF_STYLESHEET_FILE - SEARCHDATA_FILE - USE_MDFILE_AS_MAINPAGE - WARN_FORMAT - WARN_LOGFILE - XML_OUTPUT - -There are situations where it may be undesirable for a particular config option -to be automatically quoted by ``doxygen_add_docs()``, such as ``ALIASES`` which -may need to include its own embedded quoting. The ``DOXYGEN_VERBATIM_VARS`` -variable can be used to specify a list of Doxygen variables (including the -leading ``DOXYGEN_`` prefix) which should not be quoted. The project is then -responsible for ensuring that those variables' values make sense when placed -directly in the Doxygen input file. In the case of list variables, list items -are still separated by spaces, it is only the automatic quoting that is -skipped. For example, the following allows ``doxygen_add_docs()`` to apply -quoting to ``DOXYGEN_PROJECT_BRIEF``, but not each item in the -``DOXYGEN_ALIASES`` list (:ref:`bracket syntax ` can also -be used to make working with embedded quotes easier): - -.. code-block:: cmake - - set(DOXYGEN_PROJECT_BRIEF "String with spaces") - set(DOXYGEN_ALIASES - [[somealias="@some_command param"]] - "anotherAlias=@foobar" - ) - set(DOXYGEN_VERBATIM_VARS DOXYGEN_ALIASES) - -The resultant ``Doxyfile`` will contain the following lines: - -.. code-block:: text - - PROJECT_BRIEF = "String with spaces" - ALIASES = somealias="@some_command param" anotherAlias=@foobar - - -Deprecated Result Variables -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -For compatibility with previous versions of CMake, the following variables -are also defined but they are deprecated and should no longer be used: - -.. variable:: DOXYGEN_EXECUTABLE - - The path to the ``doxygen`` command. If projects need to refer to the - ``doxygen`` executable directly, they should use the ``Doxygen::doxygen`` - import target instead. - -.. variable:: DOXYGEN_DOT_FOUND - - True if the ``dot`` executable was found. - -.. variable:: DOXYGEN_DOT_EXECUTABLE - - The path to the ``dot`` command. If projects need to refer to the ``dot`` - executable directly, they should use the ``Doxygen::dot`` import target - instead. - -.. variable:: DOXYGEN_DOT_PATH - - The path to the directory containing the ``dot`` executable as reported in - ``DOXYGEN_DOT_EXECUTABLE``. The path may have forward slashes even on Windows - and is not suitable for direct substitution into a ``Doxyfile.in`` template. - If you need this value, get the :prop_tgt:`IMPORTED_LOCATION` property of the - ``Doxygen::dot`` target and use :command:`get_filename_component` to extract - the directory part of that path. You may also want to consider using - :command:`file(TO_NATIVE_PATH)` to prepare the path for a Doxygen - configuration file. - - -Deprecated Hint Variables -^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. variable:: DOXYGEN_SKIP_DOT - - This variable has no effect for the component form of ``find_package``. - In backward compatibility mode (i.e. without components list) it prevents - the finder module from searching for Graphviz's ``dot`` utility. - -#]=======================================================================] - -cmake_policy(PUSH) -cmake_policy(SET CMP0057 NEW) # if IN_LIST - -# For backwards compatibility support -if(Doxygen_FIND_QUIETLY) - set(DOXYGEN_FIND_QUIETLY TRUE) -endif() - -# ===== Rationale for OS X AppBundle mods below ===== -# With the OS X GUI version, Doxygen likes to be installed to /Applications -# and it contains the doxygen executable in the bundle. In the versions I've -# seen, it is located in Resources, but in general, more often binaries are -# located in MacOS. -# -# NOTE: The official Doxygen.app distributed for OS X uses non-standard -# conventions. Instead of the command-line "doxygen" tool being placed in -# Doxygen.app/Contents/MacOS, "Doxywizard" is placed there instead and -# "doxygen" is placed in Contents/Resources. This is most likely done -# so that something happens when people double-click on the Doxygen.app -# package. Unfortunately, CMake gets confused by this as when it sees the -# bundle it uses "Doxywizard" as the executable to use instead of -# "doxygen". Therefore to work-around this issue we temporarily disable -# the app-bundle feature, just for this CMake module: -# -if(APPLE) - # Save the old setting - set(TEMP_DOXYGEN_SAVE_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE}) - # Disable the App-bundle detection feature - set(CMAKE_FIND_APPBUNDLE "NEVER") -endif() -# FYI: -# In older versions of OS X Doxygen, dot was included with the Doxygen bundle, -# but newer versions require you to download Graphviz.app which contains "dot" -# or use something like homebrew. -# ============== End OSX stuff ================ - -# -# Find Doxygen... -# -macro(_Doxygen_find_doxygen) - find_program( - DOXYGEN_EXECUTABLE - NAMES doxygen - PATHS - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\doxygen_is1;Inno Setup: App Path]/bin" - /Applications/Doxygen.app/Contents/Resources - /Applications/Doxygen.app/Contents/MacOS - /Applications/Utilities/Doxygen.app/Contents/Resources - /Applications/Utilities/Doxygen.app/Contents/MacOS - DOC "Doxygen documentation generation tool (http://www.doxygen.org)" - ) - mark_as_advanced(DOXYGEN_EXECUTABLE) - - if(DOXYGEN_EXECUTABLE) - execute_process( - COMMAND "${DOXYGEN_EXECUTABLE}" --version - OUTPUT_VARIABLE DOXYGEN_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE _Doxygen_version_result - ) - if(_Doxygen_version_result) - message(WARNING "Unable to determine doxygen version: ${_Doxygen_version_result}") - endif() - endif() -endmacro() - -# -# Find Diagram Editor... -# -macro(_Doxygen_find_dia) - set(_x86 "(x86)") - find_program( - DOXYGEN_DIA_EXECUTABLE - NAMES dia - PATHS - "$ENV{ProgramFiles}/Dia" - "$ENV{ProgramFiles${_x86}}/Dia" - DOC "Diagram Editor tool for use with Doxygen" - ) - mark_as_advanced(DOXYGEN_DIA_EXECUTABLE) - - if(DOXYGEN_DIA_EXECUTABLE) - # The Doxyfile wants the path to the utility, not the entire path - # including file name - get_filename_component(DOXYGEN_DIA_PATH - "${DOXYGEN_DIA_EXECUTABLE}" - DIRECTORY) - if(WIN32) - file(TO_NATIVE_PATH "${DOXYGEN_DIA_PATH}" DOXYGEN_DIA_PATH) - endif() - - # Create an imported target for component - if(NOT TARGET Doxygen::dia) - add_executable(Doxygen::dia IMPORTED GLOBAL) - set_target_properties(Doxygen::dia PROPERTIES - IMPORTED_LOCATION "${DOXYGEN_DIA_EXECUTABLE}" - ) - endif() - endif() - - unset(_x86) -endmacro() - -# -# Find Graphviz Dot... -# -macro(_Doxygen_find_dot) - set(_x86 "(x86)") - file( - GLOB _Doxygen_GRAPHVIZ_BIN_DIRS - "$ENV{ProgramFiles}/Graphviz*/bin" - "$ENV{ProgramFiles${_x86}}/Graphviz*/bin" - ) - find_program( - DOXYGEN_DOT_EXECUTABLE - NAMES dot - PATHS - ${_Doxygen_GRAPHVIZ_BIN_DIRS} - "$ENV{ProgramFiles}/ATT/Graphviz/bin" - "C:/Program Files/ATT/Graphviz/bin" - [HKEY_LOCAL_MACHINE\\SOFTWARE\\ATT\\Graphviz;InstallPath]/bin - /Applications/Graphviz.app/Contents/MacOS - /Applications/Utilities/Graphviz.app/Contents/MacOS - /Applications/Doxygen.app/Contents/Resources - /Applications/Doxygen.app/Contents/MacOS - /Applications/Utilities/Doxygen.app/Contents/Resources - /Applications/Utilities/Doxygen.app/Contents/MacOS - DOC "Dot tool for use with Doxygen" - ) - mark_as_advanced(DOXYGEN_DOT_EXECUTABLE) - - if(DOXYGEN_DOT_EXECUTABLE) - # The Doxyfile wants the path to the utility, not the entire path - # including file name - get_filename_component(DOXYGEN_DOT_PATH - "${DOXYGEN_DOT_EXECUTABLE}" - DIRECTORY) - if(WIN32) - file(TO_NATIVE_PATH "${DOXYGEN_DOT_PATH}" DOXYGEN_DOT_PATH) - endif() - - # Create an imported target for component - if(NOT TARGET Doxygen::dot) - add_executable(Doxygen::dot IMPORTED GLOBAL) - set_target_properties(Doxygen::dot PROPERTIES - IMPORTED_LOCATION "${DOXYGEN_DOT_EXECUTABLE}" - ) - endif() - endif() - - unset(_Doxygen_GRAPHVIZ_BIN_DIRS) - unset(_x86) -endmacro() - -# -# Find Message Sequence Chart... -# -macro(_Doxygen_find_mscgen) - set(_x86 "(x86)") - find_program( - DOXYGEN_MSCGEN_EXECUTABLE - NAMES mscgen - PATHS - "$ENV{ProgramFiles}/Mscgen" - "$ENV{ProgramFiles${_x86}}/Mscgen" - DOC "Message sequence chart tool for use with Doxygen" - ) - mark_as_advanced(DOXYGEN_MSCGEN_EXECUTABLE) - - if(DOXYGEN_MSCGEN_EXECUTABLE) - # The Doxyfile wants the path to the utility, not the entire path - # including file name - get_filename_component(DOXYGEN_MSCGEN_PATH - "${DOXYGEN_MSCGEN_EXECUTABLE}" - DIRECTORY) - if(WIN32) - file(TO_NATIVE_PATH "${DOXYGEN_MSCGEN_PATH}" DOXYGEN_MSCGEN_PATH) - endif() - - # Create an imported target for component - if(NOT TARGET Doxygen::mscgen) - add_executable(Doxygen::mscgen IMPORTED GLOBAL) - set_target_properties(Doxygen::mscgen PROPERTIES - IMPORTED_LOCATION "${DOXYGEN_MSCGEN_EXECUTABLE}" - ) - endif() - endif() - - unset(_x86) -endmacro() - -# Make sure `doxygen` is one of the components to find -set(_Doxygen_keep_backward_compat FALSE) -if(NOT Doxygen_FIND_COMPONENTS) - # Search at least for `doxygen` executable - set(Doxygen_FIND_COMPONENTS doxygen) - # Preserve backward compatibility: - # search for `dot` also if `DOXYGEN_SKIP_DOT` is not explicitly disable this. - if(NOT DOXYGEN_SKIP_DOT) - list(APPEND Doxygen_FIND_COMPONENTS dot) - endif() - set(_Doxygen_keep_backward_compat TRUE) -elseif(NOT doxygen IN_LIST Doxygen_FIND_COMPONENTS) - list(INSERT Doxygen_FIND_COMPONENTS 0 doxygen) -endif() - -# -# Find all requested components of Doxygen... -# -foreach(_comp IN LISTS Doxygen_FIND_COMPONENTS) - if(_comp STREQUAL "doxygen") - _Doxygen_find_doxygen() - elseif(_comp STREQUAL "dia") - _Doxygen_find_dia() - elseif(_comp STREQUAL "dot") - _Doxygen_find_dot() - elseif(_comp STREQUAL "mscgen") - _Doxygen_find_mscgen() - else() - message(WARNING "${_comp} is not a valid Doxygen component") - set(Doxygen_${_comp}_FOUND FALSE) - continue() - endif() - - if(TARGET Doxygen::${_comp}) - set(Doxygen_${_comp}_FOUND TRUE) - else() - set(Doxygen_${_comp}_FOUND FALSE) - endif() -endforeach() -unset(_comp) - -# Verify find results -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -find_package_handle_standard_args( - Doxygen - REQUIRED_VARS DOXYGEN_EXECUTABLE - VERSION_VAR DOXYGEN_VERSION - HANDLE_COMPONENTS -) -if(NOT "${DOXYGEN_FOUND}") - unset(DOXYGEN_EXECUTABLE CACHE) -elseif(NOT TARGET Doxygen::doxygen) - # Create an imported target for Doxygen - add_executable(Doxygen::doxygen IMPORTED GLOBAL) - set_target_properties(Doxygen::doxygen PROPERTIES - IMPORTED_LOCATION "${DOXYGEN_EXECUTABLE}" - ) -endif() - -# -# Backwards compatibility... -# -if(APPLE) - # Restore the old app-bundle setting - set(CMAKE_FIND_APPBUNDLE ${TEMP_DOXYGEN_SAVE_CMAKE_FIND_APPBUNDLE}) -endif() - -# Maintain the _FOUND variables as "YES" or "NO" for backwards -# compatibility. This allows people to substitute them directly into -# Doxyfile with configure_file(). -if(DOXYGEN_FOUND) - set(DOXYGEN_FOUND "YES") -else() - set(DOXYGEN_FOUND "NO") -endif() -if(_Doxygen_keep_backward_compat) - if(Doxygen_dot_FOUND) - set(DOXYGEN_DOT_FOUND "YES") - else() - set(DOXYGEN_DOT_FOUND "NO") - endif() - - # For backwards compatibility support for even older CMake versions - set(DOXYGEN ${DOXYGEN_EXECUTABLE}) - set(DOT ${DOXYGEN_DOT_EXECUTABLE}) - - # No need to keep any backward compatibility for `DOXYGEN_MSCGEN_XXX` - # and `DOXYGEN_DIA_XXX` since they were not supported before component - # support was added -endif() -unset(_Doxygen_keep_backward_compat) - -# -# Allow full control of Doxygen from CMakeLists.txt -# - -# Prepare a template Doxyfile and Doxygen's default values CMake file -if(TARGET Doxygen::doxygen) - # If doxygen was found, use it to generate a minimal default Doxyfile. - # We will delete this file after we have finished using it below to - # generate the other files that doxygen_add_docs() will use. - set(_Doxygen_tpl "${CMAKE_BINARY_DIR}/CMakeDoxyfile.tpl") - execute_process( - COMMAND "${DOXYGEN_EXECUTABLE}" -s -g "${_Doxygen_tpl}" - OUTPUT_QUIET - RESULT_VARIABLE _Doxygen_tpl_result - ) - if(_Doxygen_tpl_result) - message(FATAL_ERROR - "Unable to generate Doxyfile template: ${_Doxygen_tpl_result}") - elseif(NOT EXISTS "${_Doxygen_tpl}") - message(FATAL_ERROR - "Doxygen has failed to generate a Doxyfile template") - endif() - - # Write a do-not-edit header to files we are going to generate... - set(_Doxygen_dne_header -[[ -# -# DO NOT EDIT! THIS FILE WAS GENERATED BY CMAKE! -# - -]] - ) - # We only need one copy of these across the whole build, since their - # content is only dependent on the version of Doxygen being used. Therefore - # we always put them at the top of the build tree so that they are in a - # predictable location. - set(_doxyfile_in "${CMAKE_BINARY_DIR}/CMakeDoxyfile.in") - set(_doxyfile_defaults "${CMAKE_BINARY_DIR}/CMakeDoxygenDefaults.cmake") - - file(WRITE "${_doxyfile_in}" ${_Doxygen_dne_header}) - file(WRITE "${_doxyfile_defaults}" ${_Doxygen_dne_header}) - - # Get strings containing a configuration key from the template Doxyfile - # we obtained from this version of Doxygen. Because some options are split - # across multiple lines by ending lines with backslashes, we cannot just - # use file(STRINGS...) with a REGEX. Instead, read lines without a REGEX - # so that file(STRINGS...) handles the trailing backslash as a line - # continuation. It stores multi-lines as lists, so we then have to replace - # the ";" list separator with backslashed newlines again so that we get the - # original content stored back as the value part. - file(STRINGS "${_Doxygen_tpl}" _file_lines) - unset(_Doxygen_tpl_params) - foreach(_line IN LISTS _file_lines) - if(_line MATCHES "([A-Z][A-Z0-9_]+)( *=)(.*)") - set(_key "${CMAKE_MATCH_1}") - set(_eql "${CMAKE_MATCH_2}") - set(_value "${CMAKE_MATCH_3}") - string(REPLACE "\\" "\\\\" _value "${_value}") - string(REPLACE ";" "\\\n" _value "${_value}") - list(APPEND _Doxygen_tpl_params "${_key}${_eql}${_value}") - endif() - endforeach() - - # Build up a Doxyfile that provides @configVar@ substitutions for each - # Doxygen config option as well as a separate CMake script which provides - # the default value for each of those options if the project doesn't supply - # them. Each config option will support substitution of a CMake variable - # of the same name except with DOXYGEN_ prepended. - foreach(_Doxygen_param IN LISTS _Doxygen_tpl_params) - if(_Doxygen_param MATCHES "([A-Z][A-Z0-9_]+)( *)=( (.*))?") - # Ok, this is a config key with a value - if(CMAKE_MATCH_COUNT EQUAL 4) - file(APPEND "${_doxyfile_in}" - "${CMAKE_MATCH_1}${CMAKE_MATCH_2}= @DOXYGEN_${CMAKE_MATCH_1}@\n") - # Remove the backslashes we had to preserve to handle newlines - string(REPLACE "\\\n" "\n" _value "${CMAKE_MATCH_4}") - file(APPEND "${_doxyfile_defaults}" -"if(NOT DEFINED DOXYGEN_${CMAKE_MATCH_1}) - set(DOXYGEN_${CMAKE_MATCH_1} ${_value}) -endif() -") - # Ok, this is a config key with empty default value - elseif(CMAKE_MATCH_COUNT EQUAL 2) - file(APPEND "${_doxyfile_in}" - "${CMAKE_MATCH_1}${CMAKE_MATCH_2}= @DOXYGEN_${CMAKE_MATCH_1}@\n") - else() - message(AUTHOR_WARNING -"Unexpected line format! Code review required!\nFault line: ${_Doxygen_param}") - endif() - else() - message(AUTHOR_WARNING -"Unexpected line format! Code review required!\nFault line: ${_Doxygen_param}") - endif() - endforeach() - - # Ok, dumped defaults are not needed anymore... - file(REMOVE "${_Doxygen_tpl}") - - unset(_Doxygen_param) - unset(_Doxygen_tpl_params) - unset(_Doxygen_dne_header) - unset(_Doxygen_tpl) - -endif() - -function(doxygen_quote_value VARIABLE) - # Quote a value of the given variable if: - # - VARIABLE parameter was really given - # - the variable it names is defined and is not present in the list - # specified by DOXYGEN_VERBATIM_VARS (if set) - # - the value of the named variable isn't already quoted - # - the value has spaces - if(VARIABLE AND DEFINED ${VARIABLE} AND - NOT ${VARIABLE} MATCHES "^\".* .*\"$" AND ${VARIABLE} MATCHES " " AND - NOT (DEFINED DOXYGEN_VERBATIM_VARS AND - "${VARIABLE}" IN_LIST DOXYGEN_VERBATIM_VARS)) - set(${VARIABLE} "\"${${VARIABLE}}\"" PARENT_SCOPE) - endif() -endfunction() - -function(doxygen_list_to_quoted_strings LIST_VARIABLE) - if(LIST_VARIABLE AND DEFINED ${LIST_VARIABLE}) - unset(_inputs) - unset(_sep) - unset(_verbatim) - # Have to test if list items should be treated as verbatim here - # because we lose the variable name when we pass just one list item - # to doxygen_quote_value() below - if(DEFINED DOXYGEN_VERBATIM_VARS AND - "${LIST_VARIABLE}" IN_LIST DOXYGEN_VERBATIM_VARS) - set(_verbatim True) - endif() - foreach(_in IN LISTS ${LIST_VARIABLE}) - if(NOT _verbatim) - doxygen_quote_value(_in) - endif() - string(APPEND _inputs "${_sep}${_in}") - set(_sep " ") - endforeach() - set(${LIST_VARIABLE} "${_inputs}" PARENT_SCOPE) - endif() -endfunction() - -function(doxygen_add_docs targetName) - set(_options ALL) - set(_one_value_args WORKING_DIRECTORY COMMENT) - set(_multi_value_args) - cmake_parse_arguments(_args - "${_options}" - "${_one_value_args}" - "${_multi_value_args}" - ${ARGN}) - - if(NOT _args_COMMENT) - set(_args_COMMENT "Generate API documentation for ${targetName}") - endif() - - if(NOT _args_WORKING_DIRECTORY) - set(_args_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") - endif() - - if(DEFINED DOXYGEN_INPUT) - message(WARNING -"DOXYGEN_INPUT is set but it will be ignored. Pass the files and directories \ -directly to the doxygen_add_docs() command instead.") - endif() - set(DOXYGEN_INPUT ${_args_UNPARSED_ARGUMENTS}) - - if(NOT TARGET Doxygen::doxygen) - message(FATAL_ERROR "Doxygen was not found, needed by \ -doxygen_add_docs() for target ${targetName}") - endif() - - # If not already defined, set some relevant defaults based on the - # assumption that the documentation is for the whole project. Details - # specified in the project() command will be used to populate a number of - # these defaults. - - if(NOT DEFINED DOXYGEN_PROJECT_NAME) - # The PROJECT_NAME tag is a single word (or a sequence of words - # surrounded by double-quotes, unless you are using Doxywizard) that - # should identify the project for which the documentation is generated. - # This name is used in the title of most generated pages and in a few - # other places. The default value is: My Project. - set(DOXYGEN_PROJECT_NAME ${PROJECT_NAME}) - endif() - - if(NOT DEFINED DOXYGEN_PROJECT_NUMBER) - # The PROJECT_NUMBER tag can be used to enter a project or revision - # number. This could be handy for archiving the generated documentation - # or if some version control system is used. - set(DOXYGEN_PROJECT_NUMBER ${PROJECT_VERSION}) - endif() - - if(NOT DEFINED DOXYGEN_PROJECT_BRIEF) - # Using the PROJECT_BRIEF tag one can provide an optional one line - # description for a project that appears at the top of each page and - # should give viewer a quick idea about the purpose of the project. - # Keep the description short. - set(DOXYGEN_PROJECT_BRIEF "${PROJECT_DESCRIPTION}") - endif() - - if(NOT DEFINED DOXYGEN_RECURSIVE) - # The RECURSIVE tag can be used to specify whether or not - # subdirectories should be searched for input files as well. CMake - # projects generally evolve to span multiple directories, so it makes - # more sense for this to be on by default. Doxygen's default value - # has this setting turned off, so we override it. - set(DOXYGEN_RECURSIVE YES) - endif() - - if(NOT DEFINED DOXYGEN_OUTPUT_DIRECTORY) - # The OUTPUT_DIRECTORY tag is used to specify the (relative or - # absolute) path into which the generated documentation will be - # written. If a relative path is used, Doxygen will interpret it as - # being relative to the location where doxygen was started, but we need - # to run Doxygen in the source tree so that relative input paths work - # intuitively. Therefore, we ensure that the output directory is always - # an absolute path and if the project provided a relative path, we - # treat it as relative to the current BINARY directory so that output - # is not generated inside the source tree. - set(DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - elseif(NOT IS_ABSOLUTE "${DOXYGEN_OUTPUT_DIRECTORY}") - get_filename_component(DOXYGEN_OUTPUT_DIRECTORY - "${DOXYGEN_OUTPUT_DIRECTORY}" - ABSOLUTE - BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") - endif() - - if(NOT DEFINED DOXYGEN_HAVE_DOT) - # If you set the HAVE_DOT tag to YES then doxygen will assume the dot - # tool is available from the path. This tool is part of Graphviz (see: - # http://www.graphviz.org/), a graph visualization toolkit from AT&T - # and Lucent Bell Labs. The other options in this section have no - # effect if this option is set to NO. - # Doxygen's default value is: NO. - if(Doxygen_dot_FOUND) - set(DOXYGEN_HAVE_DOT "YES") - else() - set(DOXYGEN_HAVE_DOT "NO") - endif() - endif() - - if(NOT DEFINED DOXYGEN_DOT_MULTI_TARGETS) - # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate - # multiple output files in one run (i.e. multiple -o and -T options on - # the command line). This makes dot run faster, but since only newer - # versions of dot (>1.8.10) support this, Doxygen disables this feature - # by default. - # This tag requires that the tag HAVE_DOT is set to YES. - set(DOXYGEN_DOT_MULTI_TARGETS YES) - endif() - - if(NOT DEFINED DOXYGEN_GENERATE_LATEX) - # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX - # output. We only want the HTML output enabled by default, so we turn - # this off if the project hasn't specified it. - set(DOXYGEN_GENERATE_LATEX NO) - endif() - - if(NOT DEFINED DOXYGEN_WARN_FORMAT) - if(CMAKE_VS_MSBUILD_COMMAND OR CMAKE_VS_DEVENV_COMMAND) - # The WARN_FORMAT tag determines the format of the warning messages - # that doxygen can produce. The string should contain the $file, - # $line and $text tags, which will be replaced by the file and line - # number from which the warning originated and the warning text. - # Optionally, the format may contain $version, which will be - # replaced by the version of the file (if it could be obtained via - # FILE_VERSION_FILTER). - # Doxygen's default value is: $file:$line: $text - set(DOXYGEN_WARN_FORMAT "$file($line) : $text ") - endif() - endif() - - if(DEFINED DOXYGEN_WARN_LOGFILE AND NOT IS_ABSOLUTE "${DOXYGEN_WARN_LOGFILE}") - # The WARN_LOGFILE tag can be used to specify a file to which warning and error - # messages should be written. If left blank the output is written to standard - # error (stderr). - get_filename_component(DOXYGEN_WARN_LOGFILE - "${DOXYGEN_WARN_LOGFILE}" - ABSOLUTE - BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") - endif() - - # Any files from the INPUT that match any of the EXCLUDE_PATTERNS will be - # excluded from the set of input files. We provide some additional patterns - # to prevent commonly unwanted things from CMake builds being pulled in. - # - # Note that the wildcards are matched against the file with absolute path, - # so to exclude all test directories for example use the pattern */test/* - list( - APPEND - DOXYGEN_EXCLUDE_PATTERNS - "*/.git/*" - "*/.svn/*" - "*/.hg/*" - "*/CMakeFiles/*" - "*/_CPack_Packages/*" - "DartConfiguration.tcl" - "CMakeLists.txt" - "CMakeCache.txt" - ) - - # Now bring in Doxgen's defaults for those things the project has not - # already set and we have not provided above - include("${CMAKE_BINARY_DIR}/CMakeDoxygenDefaults.cmake" OPTIONAL) - - # Cleanup built HTMLs on "make clean" - # TODO Any other dirs? - if(DOXYGEN_GENERATE_HTML) - if(IS_ABSOLUTE "${DOXYGEN_HTML_OUTPUT}") - set(_args_clean_html_dir "${DOXYGEN_HTML_OUTPUT}") - else() - set(_args_clean_html_dir - "${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_HTML_OUTPUT}") - endif() - set_property(DIRECTORY APPEND PROPERTY - ADDITIONAL_MAKE_CLEAN_FILES "${_args_clean_html_dir}") - endif() - - # Build up a list of files we can identify from the inputs so we can list - # them as SOURCES in the custom target (makes them display in IDEs). We - # must do this before we transform the various DOXYGEN_... variables below - # because we need to process DOXYGEN_INPUT as a list first. - unset(_sources) - foreach(_item IN LISTS DOXYGEN_INPUT) - get_filename_component(_abs_item "${_item}" ABSOLUTE - BASE_DIR "${_args_WORKING_DIRECTORY}") - if(EXISTS "${_abs_item}" AND - NOT IS_DIRECTORY "${_abs_item}" AND - NOT IS_SYMLINK "${_abs_item}") - list(APPEND _sources "${_abs_item}") - endif() - endforeach() - if(_sources) - list(INSERT _sources 0 SOURCES) - endif() - - # Transform known list type options into space separated strings. - set(_doxygen_list_options - ABBREVIATE_BRIEF - ALIASES - CITE_BIB_FILES - DIAFILE_DIRS - DOTFILE_DIRS - DOT_FONTPATH - ENABLED_SECTIONS - EXAMPLE_PATH - EXAMPLE_PATTERNS - EXCLUDE - EXCLUDE_PATTERNS - EXCLUDE_SYMBOLS - EXPAND_AS_DEFINED - EXTENSION_MAPPING - EXTRA_PACKAGES - EXTRA_SEARCH_MAPPINGS - FILE_PATTERNS - FILTER_PATTERNS - FILTER_SOURCE_PATTERNS - HTML_EXTRA_FILES - HTML_EXTRA_STYLESHEET - IGNORE_PREFIX - IMAGE_PATH - INCLUDE_FILE_PATTERNS - INCLUDE_PATH - INPUT - LATEX_EXTRA_FILES - LATEX_EXTRA_STYLESHEET - MATHJAX_EXTENSIONS - MSCFILE_DIRS - PLANTUML_INCLUDE_PATH - PREDEFINED - QHP_CUST_FILTER_ATTRS - QHP_SECT_FILTER_ATTRS - STRIP_FROM_INC_PATH - STRIP_FROM_PATH - TAGFILES - TCL_SUBST - ) - foreach(_item IN LISTS _doxygen_list_options) - doxygen_list_to_quoted_strings(DOXYGEN_${_item}) - endforeach() - - # Transform known single value variables which may contain spaces, such as - # paths or description strings. - set(_doxygen_quoted_options - CHM_FILE - DIA_PATH - DOCBOOK_OUTPUT - DOCSET_FEEDNAME - DOCSET_PUBLISHER_NAME - DOT_FONTNAME - DOT_PATH - EXTERNAL_SEARCH_ID - FILE_VERSION_FILTER - GENERATE_TAGFILE - HHC_LOCATION - HTML_FOOTER - HTML_HEADER - HTML_OUTPUT - HTML_STYLESHEET - INPUT_FILTER - LATEX_FOOTER - LATEX_HEADER - LATEX_OUTPUT - LAYOUT_FILE - MAN_OUTPUT - MAN_SUBDIR - MATHJAX_CODEFILE - MSCGEN_PATH - OUTPUT_DIRECTORY - PERL_PATH - PLANTUML_JAR_PATH - PROJECT_BRIEF - PROJECT_LOGO - PROJECT_NAME - QCH_FILE - QHG_LOCATION - QHP_CUST_FILTER_NAME - QHP_VIRTUAL_FOLDER - RTF_EXTENSIONS_FILE - RTF_OUTPUT - RTF_STYLESHEET_FILE - SEARCHDATA_FILE - USE_MDFILE_AS_MAINPAGE - WARN_FORMAT - WARN_LOGFILE - XML_OUTPUT - ) - - # Store the unmodified value of DOXYGEN_OUTPUT_DIRECTORY prior to invoking - # doxygen_quote_value() below. This will mutate the string specifically for - # consumption by Doxygen's config file, which we do not want when we use it - # later in the custom target's commands. - set( _original_doxygen_output_dir ${DOXYGEN_OUTPUT_DIRECTORY} ) - - foreach(_item IN LISTS _doxygen_quoted_options) - doxygen_quote_value(DOXYGEN_${_item}) - endforeach() - - # Prepare doxygen configuration file - set(_doxyfile_template "${CMAKE_BINARY_DIR}/CMakeDoxyfile.in") - set(_target_doxyfile "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.${targetName}") - configure_file("${_doxyfile_template}" "${_target_doxyfile}") - - unset(_all) - if(${_args_ALL}) - set(_all ALL) - endif() - - # Add the target - add_custom_target( ${targetName} ${_all} VERBATIM - COMMAND ${CMAKE_COMMAND} -E make_directory ${_original_doxygen_output_dir} - COMMAND "${DOXYGEN_EXECUTABLE}" "${_target_doxyfile}" - WORKING_DIRECTORY "${_args_WORKING_DIRECTORY}" - DEPENDS "${_target_doxyfile}" - COMMENT "${_args_COMMENT}" - ${_sources} - ) - -endfunction() - -cmake_policy(POP) diff --git a/pdi/cmake/FindGMock.cmake b/pdi/cmake/FindGMock.cmake deleted file mode 100644 index 534849219..000000000 --- a/pdi/cmake/FindGMock.cmake +++ /dev/null @@ -1,342 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. -# Copyright 2000-2018 Kitware, Inc. and Contributors -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# * Neither the name of Kitware, Inc. nor the names of Contributors -# may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# ------------------------------------------------------------------------------ -# -# The following individuals and institutions are among the Contributors: -# -# * Aaron C. Meadows -# * Adriaan de Groot -# * Aleksey Avdeev -# * Alexander Neundorf -# * Alexander Smorkalov -# * Alexey Sokolov -# * Alex Turbov -# * Andreas Pakulat -# * Andreas Schneider -# * André Rigland Brodtkorb -# * Axel Huebl, Helmholtz-Zentrum Dresden - Rossendorf -# * Benjamin Eikel -# * Bjoern Ricks -# * Brad Hards -# * Christopher Harvey -# * Christoph Grüninger -# * Clement Creusot -# * Daniel Blezek -# * Daniel Pfeifer -# * Enrico Scholz -# * Eran Ifrah -# * Esben Mose Hansen, Ange Optimization ApS -# * Geoffrey Viola -# * Google Inc -# * Gregor Jasny -# * Helio Chissini de Castro -# * Ilya Lavrenov -# * Insight Software Consortium -# * Jan Woetzel -# * Kelly Thompson -# * Konstantin Podsvirov -# * Mario Bensi -# * Mathieu Malaterre -# * Matthaeus G. Chajdas -# * Matthias Kretz -# * Matthias Maennich -# * Michael Stürmer -# * Miguel A. Figueroa-Villanueva -# * Mike Jackson -# * Mike McQuaid -# * Nicolas Bock -# * Nicolas Despres -# * Nikita Krupen'ko -# * NVIDIA Corporation -# * OpenGamma Ltd. -# * Per Øyvind Karlsen -# * Peter Collingbourne -# * Petr Gotthard -# * Philip Lowman -# * Philippe Proulx -# * Raffi Enficiaud, Max Planck Society -# * Raumfeld -# * Roger Leigh -# * Rolf Eike Beer -# * Roman Donchenko -# * Roman Kharitonov -# * Ruslan Baratov -# * Sebastian Holtermann -# * Stephen Kelly -# * Sylvain Joubert -# * Thomas Sondergaard -# * Tobias Hunger -# * Todd Gamblin -# * Tristan Carel -# * University of Dundee -# * Vadim Zhukov -# * Will Dicharry -# -# See version control history for details of individual contributions. -# -# The above copyright and license notice applies to distributions of -# CMake in source and binary form. Third-party software packages supplied -# with CMake under compatible licenses provide their own copyright notices -# documented in corresponding subdirectories or source files. -# -# ------------------------------------------------------------------------------ -# -# CMake was initially developed by Kitware with the following sponsorship: -# -# * National Library of Medicine at the National Institutes of Health -# as part of the Insight Segmentation and Registration Toolkit (ITK). -# -# * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel -# Visualization Initiative. -# -# * National Alliance for Medical Image Computing (NAMIC) is funded by the -# National Institutes of Health through the NIH Roadmap for Medical Research, -# Grant U54 EB005149. -# -# * Kitware, Inc. - -#.rst: -# FindGMock -# --------- -# -# Locate the Google C++ Mocking Framework. -# (This is nearly a copy of FindGTest.cmake as provided with cmake-3.10.2) -# -# Imported targets -# ^^^^^^^^^^^^^^^^ -# -# This module defines the following :prop_tgt:`IMPORTED` targets: -# -# ``GMock::GMock`` -# The Google Mock ``gmock`` library, if found -# ``GMock::Main`` -# The Google Mock ``gmock_main`` library, if found -# -# -# Result variables -# ^^^^^^^^^^^^^^^^ -# -# This module will set the following variables in your project: -# -# ``GMOCK_FOUND`` -# Found the Google Mocking framework -# ``GMOCK_INCLUDE_DIRS`` -# the directory containing the Google Mock headers -# -# The library variables below are set as normal variables. These -# contain debug/optimized keywords when a debugging library is found. -# -# ``GMOCK_LIBRARIES`` -# The Google Mock ``gmock`` library; note it also requires linking -# with an appropriate thread library -# ``GMOCK_MAIN_LIBRARIES`` -# The Google Mock ``gmock_main`` library -# ``GMOCK_BOTH_LIBRARIES`` -# Both ``gmock`` and ``gmock_main`` -# -# Cache variables -# ^^^^^^^^^^^^^^^ -# -# The following cache variables may also be set: -# -# ``GMOCK_ROOT`` -# The root directory of the Google Mock installation (may also be -# set as an environment variable) -# ``GMOCK_MSVC_SEARCH`` -# If compiling with MSVC, this variable can be set to ``MT`` or -# ``MD`` (the default) to enable searching a GMock build tree -# -# -# Example usage -# ^^^^^^^^^^^^^ -# -# :: -# -# enable_testing() -# find_package(GMock REQUIRED) -# -# add_executable(foo foo.cc) -# target_link_libraries(foo GMock::GMock GMock::Main) -# -# add_test(AllTestsInFoo foo) - -cmake_minimum_required(VERSION 3.16...3.25) - -list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}") - -function(__gmock_append_debugs _endvar _library) - if(${_library} AND ${_library}_DEBUG) - set(_output optimized ${${_library}} debug ${${_library}_DEBUG}) - else() - set(_output ${${_library}}) - endif() - set(${_endvar} ${_output} PARENT_SCOPE) -endfunction() - -function(__gmock_find_library _name) - find_library(${_name} - NAMES ${ARGN} - HINTS - ENV GMOCK_ROOT - ${GMOCK_ROOT} - PATH_SUFFIXES ${_gmock_libpath_suffixes} - ) - mark_as_advanced(${_name}) -endfunction() - -macro(__gmock_determine_windows_library_type _var) - if(EXISTS "${${_var}}") - file(TO_NATIVE_PATH "${${_var}}" _lib_path) - get_filename_component(_name "${${_var}}" NAME_WE) - file(STRINGS "${${_var}}" _match REGEX "${_name}\\.dll" LIMIT_COUNT 1) - if(NOT _match STREQUAL "") - set(${_var}_TYPE SHARED PARENT_SCOPE) - else() - set(${_var}_TYPE UNKNOWN PARENT_SCOPE) - endif() - return() - endif() -endmacro() - -function(__gmock_determine_library_type _var) - if(WIN32) - # For now, at least, only Windows really needs to know the library type - __gmock_determine_windows_library_type(${_var}) - __gmock_determine_windows_library_type(${_var}_RELEASE) - __gmock_determine_windows_library_type(${_var}_DEBUG) - endif() - # If we get here, no determination was made from the above checks - set(${_var}_TYPE UNKNOWN PARENT_SCOPE) -endfunction() - -function(__gmock_import_library _target _var _config) - if(_config) - set(_config_suffix "_${_config}") - else() - set(_config_suffix "") - endif() - - set(_lib "${${_var}${_config_suffix}}") - if(EXISTS "${_lib}") - if(_config) - set_property(TARGET ${_target} APPEND PROPERTY - IMPORTED_CONFIGURATIONS ${_config}) - endif() - set_target_properties(${_target} PROPERTIES - IMPORTED_LINK_INTERFACE_LANGUAGES${_config_suffix} "CXX") - if(WIN32 AND ${_var}_TYPE STREQUAL SHARED) - set_target_properties(${_target} PROPERTIES - IMPORTED_IMPLIB${_config_suffix} "${_lib}") - else() - set_target_properties(${_target} PROPERTIES - IMPORTED_LOCATION${_config_suffix} "${_lib}") - endif() - endif() -endfunction() - -# - -if(NOT DEFINED GMOCK_MSVC_SEARCH) - set(GMOCK_MSVC_SEARCH MD) -endif() - -set(_gmock_libpath_suffixes lib) -if(MSVC) - if(GMOCK_MSVC_SEARCH STREQUAL "MD") - list(APPEND _gmock_libpath_suffixes - msvc/gmock-md/Debug - msvc/gmock-md/Release - msvc/x64/Debug - msvc/x64/Release - ) - elseif(GMOCK_MSVC_SEARCH STREQUAL "MT") - list(APPEND _gmock_libpath_suffixes - msvc/gmock/Debug - msvc/gmock/Release - msvc/x64/Debug - msvc/x64/Release - ) - endif() -endif() - - -find_path(GMOCK_INCLUDE_DIR gmock/gmock.h - HINTS - $ENV{GMOCK_ROOT}/include - ${GMOCK_ROOT}/include -) -mark_as_advanced(GMOCK_INCLUDE_DIR) - -if(MSVC AND GMOCK_MSVC_SEARCH STREQUAL "MD") - # The provided /MD project files for Google Mock add -md suffixes to the - # library names. - __gmock_find_library(GMOCK_LIBRARY gmock-md gmock) - __gmock_find_library(GMOCK_LIBRARY_DEBUG gmock-mdd gmockd) - __gmock_find_library(GMOCK_MAIN_LIBRARY gmock_main-md gmock_main) - __gmock_find_library(GMOCK_MAIN_LIBRARY_DEBUG gmock_main-mdd gmock_maind) -else() - __gmock_find_library(GMOCK_LIBRARY gmock) - __gmock_find_library(GMOCK_LIBRARY_DEBUG gmockd) - __gmock_find_library(GMOCK_MAIN_LIBRARY gmock_main) - __gmock_find_library(GMOCK_MAIN_LIBRARY_DEBUG gmock_maind) -endif() - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(GMock DEFAULT_MSG GMOCK_LIBRARY GMOCK_INCLUDE_DIR GMOCK_MAIN_LIBRARY) - -if(GMOCK_FOUND) - set(GMOCK_INCLUDE_DIRS ${GMOCK_INCLUDE_DIR}) - __gmock_append_debugs(GMOCK_LIBRARIES GMOCK_LIBRARY) - __gmock_append_debugs(GMOCK_MAIN_LIBRARIES GMOCK_MAIN_LIBRARY) - set(GMOCK_BOTH_LIBRARIES ${GMOCK_LIBRARIES} ${GMOCK_MAIN_LIBRARIES}) - - if(NOT TARGET GMock::GMock) - __gmock_determine_library_type(GMOCK_LIBRARY) - add_library(GMock::GMock ${GMOCK_LIBRARY_TYPE} IMPORTED) - if(GMOCK_INCLUDE_DIRS) - set_target_properties(GMock::GMock PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${GMOCK_INCLUDE_DIRS}") - endif() - __gmock_import_library(GMock::GMock GMOCK_LIBRARY "") - __gmock_import_library(GMock::GMock GMOCK_LIBRARY "RELEASE") - __gmock_import_library(GMock::GMock GMOCK_LIBRARY "DEBUG") - endif() - if(NOT TARGET GMock::Main) - __gmock_determine_library_type(GMOCK_MAIN_LIBRARY) - add_library(GMock::Main ${GMOCK_MAIN_LIBRARY_TYPE} IMPORTED) - set_target_properties(GMock::Main PROPERTIES - INTERFACE_LINK_LIBRARIES "GMock::GMock") - __gmock_import_library(GMock::Main GMOCK_MAIN_LIBRARY "") - __gmock_import_library(GMock::Main GMOCK_MAIN_LIBRARY "RELEASE") - __gmock_import_library(GMock::Main GMOCK_MAIN_LIBRARY "DEBUG") - endif() -endif() diff --git a/pdi/cmake/FindPackageHandleStandardArgs.cmake b/pdi/cmake/FindPackageHandleStandardArgs.cmake deleted file mode 100644 index 67f6bd6f2..000000000 --- a/pdi/cmake/FindPackageHandleStandardArgs.cmake +++ /dev/null @@ -1,386 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPackageHandleStandardArgs ------------------------------ - -This module provides a function intended to be used in :ref:`Find Modules` -implementing :command:`find_package()` calls. It handles the -``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. -It also sets the ``_FOUND`` variable. The package is -considered found if all variables listed contain valid results, e.g. -valid filepaths. - -.. command:: find_package_handle_standard_args - - There are two signatures:: - - find_package_handle_standard_args( - (DEFAULT_MSG|) - ... - ) - - find_package_handle_standard_args( - [FOUND_VAR ] - [REQUIRED_VARS ...] - [VERSION_VAR ] - [HANDLE_COMPONENTS] - [CONFIG_MODE] - [FAIL_MESSAGE ] - ) - - The ``_FOUND`` variable will be set to ``TRUE`` if all - the variables ``...`` are valid and any optional - constraints are satisfied, and ``FALSE`` otherwise. A success or - failure message may be displayed based on the results and on - whether the ``REQUIRED`` and/or ``QUIET`` option was given to - the :command:`find_package` call. - - The options are: - - ``(DEFAULT_MSG|)`` - In the simple signature this specifies the failure message. - Use ``DEFAULT_MSG`` to ask for a default message to be computed - (recommended). Not valid in the full signature. - - ``FOUND_VAR `` - Obsolete. Specifies either ``_FOUND`` or - ``_FOUND`` as the result variable. This exists only - for compatibility with older versions of CMake and is now ignored. - Result variables of both names are always set for compatibility. - - ``REQUIRED_VARS ...`` - Specify the variables which are required for this package. - These may be named in the generated failure message asking the - user to set the missing variable values. Therefore these should - typically be cache entries such as ``FOO_LIBRARY`` and not output - variables like ``FOO_LIBRARIES``. - - ``VERSION_VAR `` - Specify the name of a variable that holds the version of the package - that has been found. This version will be checked against the - (potentially) specified required version given to the - :command:`find_package` call, including its ``EXACT`` option. - The default messages include information about the required - version and the version which has been actually found, both - if the version is ok or not. - - ``HANDLE_COMPONENTS`` - Enable handling of package components. In this case, the command - will report which components have been found and which are missing, - and the ``_FOUND`` variable will be set to ``FALSE`` - if any of the required components (i.e. not the ones listed after - the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are - missing. - - ``CONFIG_MODE`` - Specify that the calling find module is a wrapper around a - call to ``find_package( NO_MODULE)``. This implies - a ``VERSION_VAR`` value of ``_VERSION``. The command - will automatically check whether the package configuration file - was found. - - ``FAIL_MESSAGE `` - Specify a custom failure message instead of using the default - generated message. Not recommended. - -Example for the simple signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibXml2 DEFAULT_MSG - LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) - -The ``LibXml2`` package is considered to be found if both -``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. -Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found -and ``REQUIRED`` was used, it fails with a -:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was -used or not. If it is found, success will be reported, including -the content of the first ````. On repeated CMake runs, -the same message will not be printed again. - -Example for the full signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibArchive - REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR - VERSION_VAR LibArchive_VERSION) - -In this case, the ``LibArchive`` package is considered to be found if -both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. -Also the version of ``LibArchive`` will be checked by using the version -contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, -the default messages will be printed. - -Another example for the full signature: - -.. code-block:: cmake - - find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) - find_package_handle_standard_args(Automoc4 CONFIG_MODE) - -In this case, a ``FindAutmoc4.cmake`` module wraps a call to -``find_package(Automoc4 NO_MODULE)`` and adds an additional search -directory for ``automoc4``. Then the call to -``find_package_handle_standard_args`` produces a proper success/failure -message. -#]=======================================================================] - -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - -# internal helper macro -macro(_FPHSA_FAILURE_MESSAGE _msg) - if (${_NAME}_FIND_REQUIRED) - message(FATAL_ERROR "${_msg}") - else () - if (NOT ${_NAME}_FIND_QUIETLY) - message(STATUS "${_msg}") - endif () - endif () -endmacro() - - -# internal helper macro to generate the failure message when used in CONFIG_MODE: -macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: - if(${_NAME}_CONFIG) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") - else() - # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. - # List them all in the error message: - if(${_NAME}_CONSIDERED_CONFIGS) - set(configsText "") - list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) - math(EXPR configsCount "${configsCount} - 1") - foreach(currentConfigIndex RANGE ${configsCount}) - list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) - list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) - string(APPEND configsText " ${filename} (version ${version})\n") - endforeach() - if (${_NAME}_NOT_FOUND_MESSAGE) - string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") - endif() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") - - else() - # Simple case: No Config-file was found at all: - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") - endif() - endif() -endmacro() - - -function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) - -# Set up the arguments for `cmake_parse_arguments`. - set(options CONFIG_MODE HANDLE_COMPONENTS) - set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) - set(multiValueArgs REQUIRED_VARS) - -# Check whether we are in 'simple' or 'extended' mode: - set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) - list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) - - if(${INDEX} EQUAL -1) - set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) - set(FPHSA_REQUIRED_VARS ${ARGN}) - set(FPHSA_VERSION_VAR) - else() - cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) - - if(FPHSA_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") - endif() - - if(NOT FPHSA_FAIL_MESSAGE) - set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") - endif() - - # In config-mode, we rely on the variable _CONFIG, which is set by find_package() - # when it successfully found the config-file, including version checking: - if(FPHSA_CONFIG_MODE) - list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) - list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) - set(FPHSA_VERSION_VAR ${_NAME}_VERSION) - endif() - - if(NOT FPHSA_REQUIRED_VARS) - message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") - endif() - endif() - -# now that we collected all arguments, process them - - if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") - set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") - endif() - - list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) - - string(TOUPPER ${_NAME} _NAME_UPPER) - string(TOLOWER ${_NAME} _NAME_LOWER) - - if(FPHSA_FOUND_VAR) - if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") - set(_FOUND_VAR ${FPHSA_FOUND_VAR}) - else() - message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") - endif() - else() - set(_FOUND_VAR ${_NAME_UPPER}_FOUND) - endif() - - # collect all variables which were not found, so they can be printed, so the - # user knows better what went wrong (#6375) - set(MISSING_VARS "") - set(DETAILS "") - # check if all passed variables are valid - set(FPHSA_FOUND_${_NAME} TRUE) - foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) - if(NOT ${_CURRENT_VAR}) - set(FPHSA_FOUND_${_NAME} FALSE) - string(APPEND MISSING_VARS " ${_CURRENT_VAR}") - else() - string(APPEND DETAILS "[${${_CURRENT_VAR}}]") - endif() - endforeach() - if(FPHSA_FOUND_${_NAME}) - set(${_NAME}_FOUND TRUE) - set(${_NAME_UPPER}_FOUND TRUE) - else() - set(${_NAME}_FOUND FALSE) - set(${_NAME_UPPER}_FOUND FALSE) - endif() - - # component handling - unset(FOUND_COMPONENTS_MSG) - unset(MISSING_COMPONENTS_MSG) - - if(FPHSA_HANDLE_COMPONENTS) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(${_NAME}_${comp}_FOUND) - - if(NOT DEFINED FOUND_COMPONENTS_MSG) - set(FOUND_COMPONENTS_MSG "found components: ") - endif() - string(APPEND FOUND_COMPONENTS_MSG " ${comp}") - - else() - - if(NOT DEFINED MISSING_COMPONENTS_MSG) - set(MISSING_COMPONENTS_MSG "missing components: ") - endif() - string(APPEND MISSING_COMPONENTS_MSG " ${comp}") - - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - string(APPEND MISSING_VARS " ${comp}") - endif() - - endif() - endforeach() - set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") - string(APPEND DETAILS "[c${COMPONENT_MSG}]") - endif() - - # version handling: - set(VERSION_MSG "") - set(VERSION_OK TRUE) - - # check with DEFINED here as the requested or found version may be "0" - if (DEFINED ${_NAME}_FIND_VERSION) - if(DEFINED ${FPHSA_VERSION_VAR}) - set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) - - if(${_NAME}_FIND_VERSION_EXACT) # exact version required - # count the dots in the version string - string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}") - # add one dot because there is one dot more than there are components - string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) - if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) - # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT - # is at most 4 here. Therefore a simple lookup table is used. - if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) - set(_VERSION_REGEX "[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) - set(_VERSION_REGEX "[^.]*\\.[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") - else () - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") - endif () - string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}") - unset(_VERSION_REGEX) - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - unset(_VERSION_HEAD) - else () - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - endif () - unset(_VERSION_DOTS) - - else() # minimum version specified: - if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") - endif () - endif() - - else() - - # if the package was not found, but a version was given, add that to the output: - if(${_NAME}_FIND_VERSION_EXACT) - set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") - else() - set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") - endif() - - endif() - else () - # Check with DEFINED as the found version may be 0. - if(DEFINED ${FPHSA_VERSION_VAR}) - set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") - endif() - endif () - - if(VERSION_OK) - string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") - else() - set(${_NAME}_FOUND FALSE) - endif() - - - # print the result: - if (${_NAME}_FOUND) - FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") - else () - - if(FPHSA_CONFIG_MODE) - _FPHSA_HANDLE_FAILURE_CONFIG_MODE() - else() - if(NOT VERSION_OK) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") - else() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") - endif() - endif() - - endif () - - set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) - set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) -endfunction() diff --git a/pdi/cmake/FindPackageMessage.cmake b/pdi/cmake/FindPackageMessage.cmake deleted file mode 100644 index 6821cee4f..000000000 --- a/pdi/cmake/FindPackageMessage.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# FindPackageMessage -# ------------------ -# -# -# -# FIND_PACKAGE_MESSAGE( "message for user" "find result details") -# -# This macro is intended to be used in FindXXX.cmake modules files. It -# will print a message once for each unique find result. This is useful -# for telling the user where a package was found. The first argument -# specifies the name (XXX) of the package. The second argument -# specifies the message to display. The third argument lists details -# about the find result so that if they change the message will be -# displayed again. The macro also obeys the QUIET argument to the -# find_package command. -# -# Example: -# -# :: -# -# if(X11_FOUND) -# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" -# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") -# else() -# ... -# endif() - -function(FIND_PACKAGE_MESSAGE pkg msg details) - # Avoid printing a message repeatedly for the same find result. - if(NOT ${pkg}_FIND_QUIETLY) - string(REPLACE "\n" "" details "${details}") - set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) - if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - # The message has not yet been printed. - message(STATUS "${msg}") - - # Save the find details in the cache to avoid printing the same - # message again. - set("${DETAILS_VAR}" "${details}" - CACHE INTERNAL "Details about finding ${pkg}") - endif() - endif() -endfunction() diff --git a/pdi/cmake/FindPython/Support.cmake b/pdi/cmake/FindPython/Support.cmake deleted file mode 100644 index be4c3366f..000000000 --- a/pdi/cmake/FindPython/Support.cmake +++ /dev/null @@ -1,1244 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -# -# This file is a "template" file used by various FindPython modules. -# - -cmake_policy (VERSION 3.16...3.25) - -# -# Initial configuration -# -if (NOT DEFINED _PYTHON_PREFIX) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 3) - set(_${_PYTHON_PREFIX}_VERSIONS 3.20 3.19 3.18 3.17 3.16 3.15 3.14 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0) -elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 2) - set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) -else() - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() - - -# -# helper commands -# -macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG) - if (${_PYTHON_PREFIX}_FIND_REQUIRED) - message (FATAL_ERROR "${_PYTHON_MSG}") - else() - if (NOT ${_PYTHON_PREFIX}_FIND_QUIETLY) - message(STATUS "${_PYTHON_MSG}") - endif () - endif() - - set (${_PYTHON_PREFIX}_FOUND FALSE) - string (TOUPPER "${_PYTHON_PREFIX}" _${_PYTHON_PREFIX}_UPPER_PREFIX) - set (${_PYTHON_UPPER_PREFIX}_FOUND FALSE) - return() -endmacro() - - -macro (_PYTHON_FIND_FRAMEWORKS) - set (${_PYTHON_PREFIX}_FRAMEWORKS) - if (APPLE) - set (_pff_frameworks ${CMAKE_FRAMEWORK_PATH} - $ENV{CMAKE_FRAMEWORK_PATH} - ~/Library/Frameworks - /usr/local/Frameworks - ${CMAKE_SYSTEM_FRAMEWORK_PATH}) - list (REMOVE_DUPLICATES _pff_frameworks) - foreach (_pff_framework IN LISTS _pff_frameworks) - if (EXISTS ${_pff_framework}/Python.framework) - list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python.framework) - endif() - endforeach() - unset (_pff_frameworks) - unset (_pff_framework) - endif() -endmacro() - -function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION) - set (_PYTHON_FRAMEWORK_PATHS) - foreach (_PYTHON_FRAMEWORK IN LISTS ${_PYTHON_PREFIX}_FRAMEWORKS) - list (APPEND _PYTHON_FRAMEWORK_PATHS - "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}") - endforeach() - set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${_PYTHON_FRAMEWORK_PATHS} PARENT_SCOPE) -endfunction() - - -function (_PYTHON_VALIDATE_INTERPRETER) - if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) - return() - endif() - - if (ARGC EQUAL 1) - set (expected_version ${ARGV0}) - else() - unset (expected_version) - endif() - - get_filename_component (python_name "${${_PYTHON_PREFIX}_EXECUTABLE}" NAME) - - if (expected_version AND NOT python_name STREQUAL "python${expected_version}${CMAKE_EXECUTABLE_SUFFIX}") - # executable found must have a specific version - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL expected_version) - # interpreter not usable or has wrong major version - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - else() - if (NOT python_name STREQUAL "python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}${CMAKE_EXECUTABLE_SUFFIX}") - # executable found do not have version in name - # ensure major version is OK - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write(str(sys.version_info[0]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - # interpreter not usable or has wrong major version - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - endif() - endif() - - if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND NOT CMAKE_CROSSCOMPILING) - # In this case, interpreter must have same architecture as environment - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))" - RESULT_VARIABLE result - OUTPUT_VARIABLE size - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P) - # interpreter not usable or has wrong architecture - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - endif() -endfunction() - - -function (_PYTHON_VALIDATE_COMPILER expected_version) - if (NOT ${_PYTHON_PREFIX}_COMPILER) - return() - endif() - - # retrieve python environment version from compiler - set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))\n") - execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${working_dir}/version.py" - WORKING_DIRECTORY "${working_dir}" - OUTPUT_QUIET - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process (COMMAND "${working_dir}/version" - WORKING_DIRECTORY "${working_dir}" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET) - file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") - - if (result OR NOT version EQUAL expected_version) - # Compiler not usable or has wrong major version - set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) - endif() -endfunction() - - -function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB) - string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}") - # look at runtime part on systems supporting it - if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR - (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN" - AND ${_PYTHON_LIB} MATCHES "${CMAKE_IMPORT_LIBRARY_SUFFIX}$")) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) - # MSYS has a special syntax for runtime libraries - if (CMAKE_SYSTEM_NAME MATCHES "MSYS") - list (APPEND CMAKE_FIND_LIBRARY_PREFIXES "msys-") - endif() - find_library (${ARGV}) - endif() -endfunction() - - -function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT) - unset (_PYTHON_DIRS) - set (_PYTHON_LIBS ${ARGV}) - list (REMOVE_AT _PYTHON_LIBS 0) - foreach (_PYTHON_LIB IN LISTS _PYTHON_LIBS) - if (${_PYTHON_LIB}) - get_filename_component (_PYTHON_DIR "${${_PYTHON_LIB}}" DIRECTORY) - list (APPEND _PYTHON_DIRS "${_PYTHON_DIR}") - endif() - endforeach() - if (_PYTHON_DIRS) - list (REMOVE_DUPLICATES _PYTHON_DIRS) - endif() - set (${_PYTHON_SLD_RESULT} ${_PYTHON_DIRS} PARENT_SCOPE) -endfunction() - - -# If major version is specified, it must be the same as internal major version -if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR - AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") -endif() - - -# handle components -if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_FIND_COMPONENTS Interpreter) - set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE) -endif() -foreach (_${_PYTHON_PREFIX}_COMPONENT IN LISTS ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE) -endforeach() -unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - -# Set versions to search -## default: search any version -set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS}) - -if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER 1) - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}) - else() - unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - # add all compatible versions - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS) - if (${_PYTHON_PREFIX}_FIND_VERSION VERSION_LESS _${_PYTHON_PREFIX}_VERSION) - list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION}) - endif() - endforeach() - endif() -endif() - -# Anaconda distribution: define which architectures can be used -if (CMAKE_SIZEOF_VOID_P) - # In this case, search only for 64bit or 32bit - math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH}) -else() - # architecture unknown, search for both 64bit and 32bit - set (_${_PYTHON_PREFIX}_ARCH 64) - set (_${_PYTHON_PREFIX}_ARCH2 32) -endif() - -# IronPython support -if (CMAKE_SIZEOF_VOID_P) - # In this case, search only for 64bit or 32bit - math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy${_${_PYTHON_PREFIX}_ARCH} ipy) -else() - # architecture unknown, search for natural interpreter - set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy) -endif() -set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40) - -# Apple frameworks handling -_python_find_frameworks () - -# Save CMAKE_FIND_APPBUNDLE -if (DEFINED CMAKE_FIND_APPBUNDLE) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE}) -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -endif() -# To avoid app bundle lookup -set (CMAKE_FIND_APPBUNDLE "NEVER") - -# Save CMAKE_FIND_FRAMEWORK -if (DEFINED CMAKE_FIND_FRAMEWORK) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) - if (CMAKE_FIND_FRAMEWORK STREQUAL "ONLY") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: CMAKE_FIND_FRAMEWORK: 'ONLY' value is not supported. 'FIRST' will be used instead.") - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) - endif() -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") -endif() -# To avoid framework lookup -set (CMAKE_FIND_FRAMEWORK "NEVER") - -# Windows Registry handling -if (DEFINED ${_PYTHON_PREFIX}_FIND_REGISTRY) - if (NOT ${_PYTHON_PREFIX}_FIND_REGISTRY MATCHES "^(FIRST|LAST|NEVER)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_REGISTRY}: invalid value for '${_PYTHON_PREFIX}_FIND_REGISTRY'. 'FIRST', 'LAST' or 'NEVER' expected.") - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY ${${_PYTHON_PREFIX}_FIND_REGISTRY}) - endif() -else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") -endif() - - -unset (_${_PYTHON_PREFIX}_REQUIRED_VARS) -unset (_${_PYTHON_PREFIX}_CACHED_VARS) - - -# first step, search for the interpreter -if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) - endif() - - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - if (DEFINED ${_PYTHON_PREFIX}_EXECUTABLE AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_EXECUTABLE}") - set (_${_PYTHON_PREFIX}_EXECUTABLE "${${_PYTHON_PREFIX}_EXECUTABLE}" CACHE INTERNAL "") - elseif (DEFINED _${_PYTHON_PREFIX}_EXECUTABLE) - # check version validity - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) - else() - _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) - endif() - endif() - - if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) - # look-up for various versions and locations - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - - # Apple frameworks handling - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # Windows registry - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # try using HINTS - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) - - # Apple frameworks handling - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_DEFAULT_PATH) - endif() - - # Windows registry - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() - - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION}) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - endforeach() - endif() - - if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) - # No specific version found. Retry with generic names - # try using HINTS - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) - - _python_validate_interpreter () - endif() - - set (${_PYTHON_PREFIX}_EXECUTABLE "${_${_PYTHON_PREFIX}_EXECUTABLE}" CACHE FILEPATH "${_PYTHON_PREFIX} Interpreter") - - # retrieve exact version of executable found - if (${_PYTHON_PREFIX}_EXECUTABLE) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_VERSION - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 ${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 ${_PYTHON_PREFIX}_VERSION_PATCH) - else() - # Interpreter is not usable - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - unset (${_PYTHON_PREFIX}_VERSION) - endif() - endif() - - if (${_PYTHON_PREFIX}_EXECUTABLE - AND ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE) - # Use interpreter version for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - endif() - - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # retrieve interpreter identity - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -V - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID - ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID) - if (NOT _${_PYTHON_PREFIX}_RESULT) - if (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Anaconda") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda") - elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy") - else() - string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}") - if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python") - # try to get a more precise ID - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.copyright)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT - ERROR_QUIET) - if (${_PYTHON_PREFIX}_COPYRIGHT MATCHES "ActiveState") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "ActivePython") - endif() - endif() - endif() - else() - set (${_PYTHON_PREFIX}_INTERPRETER_ID Python) - endif() - else() - unset (${_PYTHON_PREFIX}_INTERPRETER_ID) - endif() - - # retrieve various package installation directories - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))" - - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 2 ${_PYTHON_PREFIX}_SITELIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 3 ${_PYTHON_PREFIX}_SITEARCH) - else() - unset (${_PYTHON_PREFIX}_STDLIB) - unset (${_PYTHON_PREFIX}_STDARCH) - unset (${_PYTHON_PREFIX}_SITELIB) - unset (${_PYTHON_PREFIX}_SITEARCH) - endif() - - mark_as_advanced (${_PYTHON_PREFIX}_EXECUTABLE) -endif() - - -# second step, search for compiler (IronPython) -if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_COMPILER) - endif() - - # IronPython specific artifacts - # If IronPython interpreter is found, use its path - unset (_${_PYTHON_PREFIX}_IRON_ROOT) - if (${_PYTHON_PREFIX}_Interpreter_FOUND AND ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - get_filename_component (_${_PYTHON_PREFIX}_IRON_ROOT "${${_PYTHON_PREFIX}_EXECUTABLE}" DIRECTORY) - endif() - - # try using root dir and registry - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() - - _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION}) - if (${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endforeach() - - # no specific version found, re-try in standard paths - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}) - - if (${_PYTHON_PREFIX}_COMPILER) - # retrieve python environment version from compiler - set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n") - execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - OUTPUT_QUIET - ERROR_QUIET) - execute_process (COMMAND "${_${_PYTHON_PREFIX}_VERSION_DIR}/version" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - else() - # compiler not usable - set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) - endif() - file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") - endif() - - if (${_PYTHON_PREFIX}_COMPILER) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # Compiler must be compatible with interpreter - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - # Use compiler version for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - endif() - endif() - - if (${_PYTHON_PREFIX}_Compiler_FOUND) - set (${_PYTHON_PREFIX}_COMPILER_ID IronPython) - else() - unset (${_PYTHON_PREFIX}_COMPILER_ID) - endif() - - mark_as_advanced (${_PYTHON_PREFIX}_COMPILER) -endif() - - -# third step, search for the development artifacts -## Development environment is not compatible with IronPython interpreter -if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_INCLUDE_DIR) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_INCLUDE_DIR) - endif() - - # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - if (DEFINED ${_PYTHON_PREFIX}_USE_STATIC_LIBS AND NOT WIN32) - set(_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(${_PYTHON_PREFIX}_USE_STATIC_LIBS) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - else() - list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - endif() - else() - endif() - - # if python interpreter is found, use its location and version to ensure consistency - # between interpreter and development environment - unset (_${_PYTHON_PREFIX}_PREFIX) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.PREFIX)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - unset (_${_PYTHON_PREFIX}_PREFIX) - endif() - endif() - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - # try to use pythonX.Y-config tool - set (_${_PYTHON_PREFIX}_CONFIG_NAMES) - if (DEFINED CMAKE_LIBRARY_ARCHITECTURE) - set (_${_PYTHON_PREFIX}_CONFIG_NAMES "${CMAKE_LIBRARY_ARCHITECTURE}-python${_${_PYTHON_PREFIX}_VERSION}-config") - endif() - list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES "python${_${_PYTHON_PREFIX}_VERSION}-config") - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - unset (_${_PYTHON_PREFIX}_CONFIG_NAMES) - - if (NOT _${_PYTHON_PREFIX}_CONFIG) - continue() - endif() - - # retrieve root install directory - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --prefix - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # python-config is not usable - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - continue() - endif() - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - # retrieve library - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - # retrieve library directory - string (REGEX MATCHALL "-L[^ ]+" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-L" "" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_LIB_DIRS}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_DIRS) - # retrieve library name - string (REGEX MATCHALL "-lpython[^ ]+" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-l" "" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_LIB_NAMES}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_NAMES) - - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} ${_${_PYTHON_PREFIX}_LIB_DIRS} - PATH_SUFFIXES lib - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # retrieve runtime library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_PATH} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - endif() - - # retrieve include directory - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --includes - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - # retrieve include directory - string (REGEX MATCHALL "-I[^ ]+" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-I" "" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIRS}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_DIRS) - - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - break() - endif() - endforeach() - - # Rely on HINTS and standard paths if config tool failed to locate artifacts - if (NOT (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) OR NOT ${_PYTHON_PREFIX}_INCLUDE_DIR) - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - - set (_${_PYTHON_PREFIX}_REGISTRY_PATHS - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # search in HINTS locations - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) - endif() - - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config) - # retrieve runtime library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - - if (WIN32) - # search for debug library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - # use library location as a hint - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - NO_DEFAULT_PATH) - else() - # search first in known locations - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs) - endif() - if (${_PYTHON_PREFIX}_LIBRARY_DEBUG) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - endif() - - # Don't search for include dir until library location is known - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) - - if (${_PYTHON_PREFIX}_EXECUTABLE) - # pick up include directory from configuration - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; import sysconfig; sys.stdout.write(sysconfig.get_path('include'))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PATH - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - file (TO_CMAKE_PATH "${_${_PYTHON_PREFIX}_PATH}" _${_PYTHON_PREFIX}_PATH) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PATH}") - endif() - endif() - - foreach (_${_PYTHON_PREFIX}_LIB IN ITEMS ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - if (${_${_PYTHON_PREFIX}_LIB}) - # Use the library's install prefix as a hint - if (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - else() - # assume library is in a directory under root - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${${_${_PYTHON_PREFIX}_LIB}}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") - endif() - endif() - endforeach() - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_HINTS) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - break() - endif() - endforeach() - - # search header file in standard locations - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h) - endif() - - if (${_PYTHON_PREFIX}_INCLUDE_DIR) - # retrieve version from header file - file (STRINGS "${${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" _${_PYTHON_PREFIX}_VERSION - REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") - string (REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" - _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_VERSION}") - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_Compiler_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - endif() - - # define public variables - include (${CMAKE_CURRENT_LIST_DIR}/../SelectLibraryConfigurations.cmake) - select_library_configurations (${_PYTHON_PREFIX}) - if (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - elseif (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - else() - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "$${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND") - endif() - - _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS - ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - if (UNIX) - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$") - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS}) - endif() - else() - _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - endif() - - set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${${_PYTHON_PREFIX}_INCLUDE_DIR}") - - mark_as_advanced (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_INCLUDE_DIR) - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND) - # development environment must be compatible with interpreter/compiler - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_Development_FOUND TRUE) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Development_FOUND TRUE) - endif() - endif() - - # Restore the original find library ordering - if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() -endif() - -# final validation -if (${_PYTHON_PREFIX}_VERSION_MAJOR AND - NOT ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") -endif() - -include (${CMAKE_CURRENT_LIST_DIR}/../FindPackageHandleStandardArgs.cmake) -find_package_handle_standard_args (${_PYTHON_PREFIX} - REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS} - VERSION_VAR ${_PYTHON_PREFIX}_VERSION - HANDLE_COMPONENTS) - -# Create imported targets and helper functions -if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Interpreter_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Interpreter) - add_executable (${_PYTHON_PREFIX}::Interpreter IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Interpreter - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_EXECUTABLE}") -endif() - -if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Compiler_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Compiler) - add_executable (${_PYTHON_PREFIX}::Compiler IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Compiler - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}") -endif() - -if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Development_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::Python) - - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED) - else() - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC) - endif() - - add_library (${_PYTHON_PREFIX}::Python ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED) - - set_property (TARGET ${_PYTHON_PREFIX}::Python - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}") - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - OR (${_PYTHON_PREFIX}_LIBRARY_DEBUG AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)) - # System manage shared libraries in two parts: import and runtime - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - else() - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARY}" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY}") - endif() - else() - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}") - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}") - else() - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY}") - endif() - endif() - - function(list_filter_exclude _list_name _value) - if(CMAKE_VERSION VERSION_LESS 3.12) - list(FIND ${_list_name} ${_value} _INDEX) - if(${_INDEX} GREATER -1) - list(REMOVE_AT ${_list_name} ${_INDEX}) - endif() - else() - list(FILTER ${_list_name} EXCLUDE REGEX ${_value}) - endif() - set(${_list_name} ${${_list_name}} PARENT_SCOPE) - endfunction() - - if (_${_PYTHON_PREFIX}_CONFIG AND _${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC") - # extend link information with dependent libraries - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "-[Ll][^ ]+" _${_PYTHON_PREFIX}_LINK_LIBRARIES "${_${_PYTHON_PREFIX}_FLAGS}") - # remove elements relative to python library itself - list_filter_exclude(_${_PYTHON_PREFIX}_LINK_LIBRARIES "-lpython") - #list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-lpython") - foreach (_${_PYTHON_PREFIX}_DIR IN LISTS ${_PYTHON_PREFIX}_LIBRARY_DIRS) - list_filter_exclude(_${_PYTHON_PREFIX}_LINK_LIBRARIES "-L${${_PYTHON_PREFIX}_DIR}") - #list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-L${${_PYTHON_PREFIX}_DIR}") - endforeach() - set_property (TARGET ${_PYTHON_PREFIX}::Python - PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES}) - endif() - endif() - - # - # PYTHON_ADD_LIBRARY ( [STATIC|SHARED|MODULE] src1 src2 ... srcN) - # It is used to build modules for python. - # - function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name) - cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY - "STATIC;SHARED;MODULE" "" "") - - unset (type) - if (NOT (PYTHON_ADD_LIBRARY_STATIC - OR PYTHON_ADD_LIBRARY_SHARED - OR PYTHON_ADD_LIBRARY_MODULE)) - set (type MODULE) - endif() - add_library (${name} ${type} ${ARGN}) - target_link_libraries (${name} PRIVATE ${prefix}::Python) - - # customize library name to follow module name rules - get_property (type TARGET ${name} PROPERTY TYPE) - if (type STREQUAL "MODULE_LIBRARY") - set_property (TARGET ${name} PROPERTY PREFIX "") - if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - set_property (TARGET ${name} PROPERTY SUFFIX ".pyd") - endif() - endif() - endfunction() -endif() - -# final clean-up - -# Restore CMAKE_FIND_APPBUNDLE -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) - set (CMAKE_FIND_APPBUNDLE ${_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -else() - unset (CMAKE_FIND_APPBUNDLE) -endif() -# Restore CMAKE_FIND_FRAMEWORK -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) - set (CMAKE_FIND_FRAMEWORK ${_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) -else() - unset (CMAKE_FIND_FRAMEWORK) -endif() - -unset (_${_PYTHON_PREFIX}_CONFIG CACHE) diff --git a/pdi/cmake/FindPython3.cmake b/pdi/cmake/FindPython3.cmake deleted file mode 100644 index 370abfdb5..000000000 --- a/pdi/cmake/FindPython3.cmake +++ /dev/null @@ -1,174 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPython3 ------------ - -Find Python 3 interpreter, compiler and development environment (include -directories and libraries). - -Three components are supported: - -* ``Interpreter``: search for Python 3 interpreter -* ``Compiler``: search for Python 3 compiler. Only offered by IronPython. -* ``Development``: search for development artifacts (include directories and - libraries) - -If no ``COMPONENTS`` is specified, ``Interpreter`` is assumed. - -To ensure consistent versions between components ``Interpreter``, ``Compiler`` -and ``Development``, specify all components at the same time:: - - find_package (Python3 COMPONENTS Interpreter Development) - -This module looks only for version 3 of Python. This module can be used -concurrently with :module:`FindPython2` module to use both Python versions. - -The :module:`FindPython` module can be used if Python version does not matter -for you. - -Imported Targets -^^^^^^^^^^^^^^^^ - -This module defines the following :ref:`Imported Targets `: - -``Python3::Interpreter`` - Python 3 interpreter. Target defined if component ``Interpreter`` is found. -``Python3::Compiler`` - Python 3 compiler. Target defined if component ``Compiler`` is found. -``Python3::Python`` - Python 3 library. Target defined if component ``Development`` is found. - -Result Variables -^^^^^^^^^^^^^^^^ - -This module will set the following variables in your project -(see :ref:`Standard Variable Names `): - -``Python3_FOUND`` - System has the Python 3 requested components. -``Python3_Interpreter_FOUND`` - System has the Python 3 interpreter. -``Python3_EXECUTABLE`` - Path to the Python 3 interpreter. -``Python3_INTERPRETER_ID`` - A short string unique to the interpreter. Possible values include: - * Python - * ActivePython - * Anaconda - * Canopy - * IronPython -``Python3_STDLIB`` - Standard platform independent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``. -``Python3_STDARCH`` - Standard platform dependent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``. -``Python3_SITELIB`` - Third-party platform independent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``. -``Python3_SITEARCH`` - Third-party platform dependent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``. -``Python3_Compiler_FOUND`` - System has the Python 3 compiler. -``Python3_COMPILER`` - Path to the Python 3 compiler. Only offered by IronPython. -``Python3_COMPILER_ID`` - A short string unique to the compiler. Possible values include: - * IronPython -``Python3_Development_FOUND`` - System has the Python 3 development artifacts. -``Python3_INCLUDE_DIRS`` - The Python 3 include directories. -``Python3_LIBRARIES`` - The Python 3 libraries. -``Python3_LIBRARY_DIRS`` - The Python 3 library directories. -``Python3_RUNTIME_LIBRARY_DIRS`` - The Python 3 runtime library directories. -``Python3_VERSION`` - Python 3 version. -``Python3_VERSION_MAJOR`` - Python 3 major version. -``Python3_VERSION_MINOR`` - Python 3 minor version. -``Python3_VERSION_PATCH`` - Python 3 patch version. - -Hints -^^^^^ - -``Python3_ROOT_DIR`` - Define the root directory of a Python 3 installation. - -``Python3_USE_STATIC_LIBS`` - * If not defined, search for shared libraries and static libraries in that - order. - * If set to TRUE, search **only** for static libraries. - * If set to FALSE, search **only** for shared libraries. - -``Python3_FIND_REGISTRY`` - On Windows the ``Python3_FIND_REGISTRY`` variable determine the order - of preference between registry and environment variables. - the ``Python3_FIND_REGISTRY`` variable can be set to empty or one of the - following: - - * ``FIRST``: Try to use registry before environment variables. - This is the default. - * ``LAST``: Try to use registry after environment variables. - * ``NEVER``: Never try to use registry. - -``CMAKE_FIND_FRAMEWORK`` - On OS X the :variable:`CMAKE_FIND_FRAMEWORK` variable determine the order of - preference between Apple-style and unix-style package components. - - .. note:: - - Value ``ONLY`` is not supported so ``FIRST`` will be used instead. - -Artifacts Specification -^^^^^^^^^^^^^^^^^^^^^^^ - -To solve special cases, it is possible to specify directly the artifacts by -setting the following variables: - -``Python3_EXECUTABLE`` - The path to the interpreter. - -Commands -^^^^^^^^ - -This module defines the command ``Python3_add_library`` which have the same -semantic as :command:`add_library` but take care of Python module naming rules -(only applied if library is of type ``MODULE``) and add dependency to target -``Python3::Python``:: - - Python3_add_library (my_module MODULE src1.cpp) - -If library type is not specified, ``MODULE`` is assumed. -#]=======================================================================] - - -set (_PYTHON_PREFIX Python3) - -set (_Python3_REQUIRED_VERSION_MAJOR 3) - -include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) - -if (COMMAND __Python3_add_library) - macro (Python3_add_library) - __Python3_add_library (Python3 ${ARGV}) - endmacro() -endif() - -unset (_PYTHON_PREFIX) diff --git a/pdi/cmake/FindPython3Path.cmake b/pdi/cmake/FindPython3Path.cmake index a048dc863..117f992f6 100644 --- a/pdi/cmake/FindPython3Path.cmake +++ b/pdi/cmake/FindPython3Path.cmake @@ -1,5 +1,5 @@ ################################################################################ -# Copyright (C) 2015-2025 Commissariat a l'energie atomique et aux energies +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies # alternatives (CEA) # All rights reserved. # @@ -23,7 +23,8 @@ # THE SOFTWARE. ################################################################################ -cmake_minimum_required(VERSION 3.16...3.25) +cmake_policy(PUSH) +cmake_policy(VERSION 3.22...4.2) include(FindPackageHandleStandardArgs) @@ -94,3 +95,5 @@ sys.stdout.write(';'.join([sysconfig.get_python_lib(prefix='',plat_specific=Fals endif() find_package_handle_standard_args(Python3Path REQUIRED_VARS Python3Path_INSTALL_SITELIBDIR Python3Path_INSTALL_SITEARCHDIR Python3Path_INSTALL_STDLIBDIR Python3Path_INSTALL_STDARCHDIR) + +cmake_policy(POP) diff --git a/pdi/cmake/PDIConfig.cmake.in b/pdi/cmake/PDIConfig.cmake.in index 7b183d563..be63409ac 100644 --- a/pdi/cmake/PDIConfig.cmake.in +++ b/pdi/cmake/PDIConfig.cmake.in @@ -1,5 +1,6 @@ ################################################################################ -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -22,71 +23,104 @@ # THE SOFTWARE. ################################################################################ -cmake_minimum_required(VERSION 3.16...3.25) +cmake_policy(PUSH) +cmake_policy(VERSION 3.22...4.2) -list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}") +include(CMakeFindDependencyMacro) -include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindDependencyMacro.cmake) +# List of Components supported by the project. -# Compute the installation prefix relative to this file. +set(_PDI_AVAILABLE_COMPONENTS C f90 Fortran plugins pysupport python) -set(_PDI_INSTALL_CMAKEDIR "@INSTALL_CMAKEDIR@") -get_filename_component(_PDI_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) -while(NOT "${_PDI_INSTALL_CMAKEDIR}" STREQUAL "") - get_filename_component(_PDI_IMPORT_PREFIX "${_PDI_IMPORT_PREFIX}" PATH) - get_filename_component(_PDI_INSTALL_CMAKEDIR "${_PDI_INSTALL_CMAKEDIR}" PATH) -endwhile() -if(_PDI_IMPORT_PREFIX STREQUAL "/") - set(_PDI_IMPORT_PREFIX "") -endif() -set(PDI_DEFAULT_PLUGINDIR "@INSTALL_PDIPLUGINDIR@" ) +# Check that all required components are valid + +foreach(_PDI_ONE_COMPONENT ${PDI_FIND_COMPONENTS}) + if(NOT "${_PDI_ONE_COMPONENT}" IN_LIST _PDI_AVAILABLE_COMPONENTS) + # We do not respect PDI_FIND_QUIETLY because we were called in an invalid way + message(FATAL_ERROR "PDI: unknown component: \"${_PDI_ONE_COMPONENT}\"") + elseif("x${_PDI_ONE_COMPONENT}" STREQUAL "xFortran" AND NOT "${_PDI_FIND_OPTIONAL_QUIETLY}") + message(WARNING "PDI: \"Fortran\" component is deprecated, please use \"f90\" instead") + endif() +endforeach() + # Normalize the component names if("Fortran" IN_LIST PDI_FIND_COMPONENTS) list(REMOVE_ITEM PDI_FIND_COMPONENTS "Fortran") list(APPEND PDI_FIND_COMPONENTS "f90") - set(PDI_FIND_REQUIRED_f90 "${PDI_FIND_REQUIRED_Fortran}") + if("${PDI_FIND_REQUIRED_Fortran}") + set(PDI_FIND_REQUIRED_f90 TRUE) + endif() endif() # by default, if no component is specified, look for all but only require C -set(_PDI_FIND_QUIETLY_OPTIONAL "${PDI_FIND_QUIETLY}") +set(_PDI_FIND_OPTIONAL_QUIETLY "${PDI_FIND_QUIETLY}") if("xx" STREQUAL "x${PDI_FIND_COMPONENTS}x") - set(PDI_FIND_COMPONENTS C f90) + set(PDI_FIND_COMPONENTS C f90 pysupport plugins) set(PDI_FIND_REQUIRED_C TRUE) set(PDI_FIND_REQUIRED_f90 FALSE) - set(PDI_FIND_REQUIRED_python FALSE) - set(_PDI_FIND_QUIETLY_OPTIONAL TRUE) + set(PDI_FIND_REQUIRED_pysupport FALSE) + set(PDI_FIND_REQUIRED_plugins FALSE) + set(_PDI_FIND_OPTIONAL_QUIETLY TRUE) endif() -# Add dependencies +# Add dependency components if("pysupport" IN_LIST PDI_FIND_COMPONENTS) list(INSERT PDI_FIND_COMPONENTS 0 "plugins") endif() + + +# Ensure C is present and remove any duplicate requested component + list(INSERT PDI_FIND_COMPONENTS 0 "C") +list(REMOVE_DUPLICATES PDI_FIND_COMPONENTS) + + +# Compute the installation prefix relative to this file. + +set(_PDI_INSTALL_CMAKEDIR "@INSTALL_CMAKEDIR@") +get_filename_component(_PDI_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) +while(NOT "${_PDI_INSTALL_CMAKEDIR}" STREQUAL "") + get_filename_component(_PDI_IMPORT_PREFIX "${_PDI_IMPORT_PREFIX}" PATH) + get_filename_component(_PDI_INSTALL_CMAKEDIR "${_PDI_INSTALL_CMAKEDIR}" PATH) +endwhile() +if(_PDI_IMPORT_PREFIX STREQUAL "/") + set(_PDI_IMPORT_PREFIX "") +endif() + +set(PDI_DEFAULT_PLUGINDIR "@INSTALL_PDIPLUGINDIR@" ) # The executable -set(PDI_pdirun_EXECUTABLE "${_PDI_IMPORT_PREFIX}/@CMAKE_INSTALL_BINDIR@/pdirun") -add_executable(PDI::pdirun IMPORTED) -set_target_properties(PDI::pdirun PROPERTIES IMPORTED_LOCATION "${PDI_pdirun_EXECUTABLE}") +if(NOT TARGET "PDI::pdirun") + add_executable(PDI::pdirun IMPORTED) + set_target_properties(PDI::pdirun PROPERTIES IMPORTED_LOCATION "${_PDI_IMPORT_PREFIX}/@CMAKE_INSTALL_BINDIR@/pdirun") +elseif("${DEBUG_PDI_FIND}" AND NOT "${PDI_FIND_QUIETLY}") + message(DEBUG "Target PDI::pdirun is already defined. Skipping defining it.") +endif() -# The other targets +# The exported library targets -foreach(_PDI_ONE_COMPONENT ${PDI_FIND_COMPONENTS}) - include("${CMAKE_CURRENT_LIST_DIR}/PDI_${_PDI_ONE_COMPONENT}.cmake" OPTIONAL) -endforeach() +include("${CMAKE_CURRENT_LIST_DIR}/PDI_C.cmake" OPTIONAL) +include("${CMAKE_CURRENT_LIST_DIR}/PDI_plugins.cmake" OPTIONAL) +if(pysupport IN_LIST PDI_FIND_COMPONENTS) + include("${CMAKE_CURRENT_LIST_DIR}/PDI_pysupport.cmake" OPTIONAL) +endif() +if(f90 IN_LIST PDI_FIND_COMPONENTS) + include("${CMAKE_CURRENT_LIST_DIR}/PDI_f90.cmake" OPTIONAL) +endif() -# Check the components +# Check that all required components were found foreach(_PDI_ONE_COMPONENT ${PDI_FIND_COMPONENTS}) if("@BUILD_PYTHON@" AND "x${_PDI_ONE_COMPONENT}" STREQUAL "xpython") @@ -95,46 +129,77 @@ foreach(_PDI_ONE_COMPONENT ${PDI_FIND_COMPONENTS}) if("${PDI_FIND_REQUIRED_${_PDI_ONE_COMPONENT}}") set(PDI_FOUND "FALSE") if(NOT "${PDI_FIND_QUIETLY}") - message(WARNING "PDI: required component \"${_PDI_ONE_COMPONENT}\" not found") - endif() - else() - if(NOT "${_PDI_FIND_QUIETLY_OPTIONAL}") - message("PDI: optional component \"${_PDI_ONE_COMPONENT}\" not found") + message(SEND_ERROR "PDI: required component \"${_PDI_ONE_COMPONENT}\" not found") endif() + elseif(NOT "${_PDI_FIND_OPTIONAL_QUIETLY}") + message(STATUS "PDI: optional component \"${_PDI_ONE_COMPONENT}\" not found") endif() endif() endforeach() -# Add aliases +# Add aliases for (deprecated) backward compatibility + +if(TARGET "PDI::PDI_C" AND NOT TARGET "PDI_C") + add_library(PDI_C INTERFACE) + target_link_libraries(PDI_C INTERFACE PDI::PDI_C) + set_target_properties(PDI_C PROPERTIES DEPRECATION + "The unnamespaced `PDI_C', and `PDI::pdi` targets are deprecated, please use `PDI::PDI_C' instead.") +elseif(TARGET "PDI::PDI_C" AND "${DEBUG_PDI_FIND}" AND NOT "${PDI_FIND_QUIETLY}") + message(DEBUG "Target PDI_C is already defined. Skipping aliasing it.") +endif() -add_library(PDI_C INTERFACE) -target_link_libraries(PDI_C INTERFACE PDI::PDI_C) -add_library(PDI::pdi ALIAS PDI_C) -if(TARGET "PDI::PDI_f90") +if(TARGET "PDI::PDI_C" AND NOT TARGET "PDI::pdi") + add_library(PDI::pdi ALIAS PDI_C) +elseif(TARGET "PDI::PDI_C" AND "${DEBUG_PDI_FIND}" AND NOT "${PDI_FIND_QUIETLY}") + message(DEBUG "Target PDI::pdi is already defined. Skipping aliasing it.") +endif() + +if(TARGET "PDI::PDI_f90" AND NOT TARGET "PDI_f90") add_library(PDI_f90 INTERFACE) target_link_libraries(PDI_f90 INTERFACE PDI::PDI_f90) + set_target_properties(PDI_f90 PROPERTIES DEPRECATION + "The unnamespaced `PDI_f90', `PDI::PDI_Fortran', and `PDI::pdi_f90' targets are deprecated, please use `PDI::PDI_f90' instead.") +elseif(TARGET "PDI::PDI_f90" AND "${DEBUG_PDI_FIND}" AND NOT "${PDI_FIND_QUIETLY}") + message(DEBUG "Target PDI_f90 is already defined. Skipping aliasing it.") +endif() + +if(TARGET "PDI::PDI_f90" AND NOT TARGET "PDI::PDI_Fortran") add_library(PDI::PDI_Fortran ALIAS PDI_f90) +elseif(TARGET "PDI::PDI_f90" AND "${DEBUG_PDI_FIND}" AND NOT "${PDI_FIND_QUIETLY}") + message(DEBUG "Target PDI::PDI_Fortran is already defined. Skipping aliasing it.") +endif() + +if(TARGET "PDI::PDI_f90" AND NOT TARGET "PDI::pdi_f90") add_library(PDI::pdi_f90 ALIAS PDI_f90) +elseif(TARGET "PDI::PDI_f90" AND "${DEBUG_PDI_FIND}" AND NOT "${PDI_FIND_QUIETLY}") + message(DEBUG "Target PDI::pdi_f90 is already defined. Skipping aliasing it.") endif() -# Import our dependencies, for Paraconf, require f90 if is was required from us +# Find our dependencies if(TARGET PDI::PDI_plugins) - find_dependency(spdlog 1.5.0) + find_dependency(spdlog "@PDI_REQUIRED_SPDLOG_VERSION@") endif() if(TARGET PDI::PDI_pysupport) - find_dependency(pybind11 2.3.0) + find_dependency(Python3 "@PDI_REQUIRED_PYTHON_VERSION@" COMPONENTS Interpreter Development) + find_dependency(pybind11 "@PDI_REQUIRED_PYBIND11_VERSION@") endif() if(TARGET PDI::PDI_f90) - find_dependency(paraconf 1.0.0 COMPONENTS C f90) + find_dependency(paraconf "@PDI_REQUIRED_PARACONF_VERSION@" COMPONENTS C f90) else() - find_dependency(paraconf 1.0.0 COMPONENTS C) + find_dependency(paraconf "@PDI_REQUIRED_PARACONF_VERSION@" COMPONENTS C) endif() -unset(_PDI_FIND_QUIETLY_OPTIONAL) + +# Cleanup after ourselves + +unset(_PDI_AVAILABLE_COMPONENTS) +unset(_PDI_FIND_OPTIONAL_QUIETLY) unset(_PDI_IMPORT_PREFIX) unset(_PDI_INCLUDE_OPTIONAL) unset(_PDI_INSTALL_CMAKEDIR) unset(_PDI_ONE_COMPONENT) + +cmake_policy(POP) diff --git a/pdi/cmake/SelectLibraryConfigurations.cmake b/pdi/cmake/SelectLibraryConfigurations.cmake deleted file mode 100644 index fe3bb00a6..000000000 --- a/pdi/cmake/SelectLibraryConfigurations.cmake +++ /dev/null @@ -1,71 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# SelectLibraryConfigurations -# --------------------------- -# -# -# -# select_library_configurations( basename ) -# -# This macro takes a library base name as an argument, and will choose -# good values for basename_LIBRARY, basename_LIBRARIES, -# basename_LIBRARY_DEBUG, and basename_LIBRARY_RELEASE depending on what -# has been found and set. If only basename_LIBRARY_RELEASE is defined, -# basename_LIBRARY will be set to the release value, and -# basename_LIBRARY_DEBUG will be set to basename_LIBRARY_DEBUG-NOTFOUND. -# If only basename_LIBRARY_DEBUG is defined, then basename_LIBRARY will -# take the debug value, and basename_LIBRARY_RELEASE will be set to -# basename_LIBRARY_RELEASE-NOTFOUND. -# -# If the generator supports configuration types, then basename_LIBRARY -# and basename_LIBRARIES will be set with debug and optimized flags -# specifying the library to be used for the given configuration. If no -# build type has been set or the generator in use does not support -# configuration types, then basename_LIBRARY and basename_LIBRARIES will -# take only the release value, or the debug value if the release one is -# not set. - -# This macro was adapted from the FindQt4 CMake module and is maintained by Will -# Dicharry . - -macro( select_library_configurations basename ) - if(NOT ${basename}_LIBRARY_RELEASE) - set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.") - endif() - if(NOT ${basename}_LIBRARY_DEBUG) - set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.") - endif() - - get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND - NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND - ( _isMultiConfig OR CMAKE_BUILD_TYPE ) ) - # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for - # single-config generators, set optimized and debug libraries - set( ${basename}_LIBRARY "" ) - foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE ) - list( APPEND ${basename}_LIBRARY optimized "${_libname}" ) - endforeach() - foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG ) - list( APPEND ${basename}_LIBRARY debug "${_libname}" ) - endforeach() - elseif( ${basename}_LIBRARY_RELEASE ) - set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) - elseif( ${basename}_LIBRARY_DEBUG ) - set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} ) - else() - set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND") - endif() - - set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" ) - - if( ${basename}_LIBRARY ) - set( ${basename}_FOUND TRUE ) - endif() - - mark_as_advanced( ${basename}_LIBRARY_RELEASE - ${basename}_LIBRARY_DEBUG - ) -endmacro() diff --git a/pdi/docs/About.md b/pdi/docs/About.md index ffb974d06..86f6cbda8 100644 --- a/pdi/docs/About.md +++ b/pdi/docs/About.md @@ -13,16 +13,16 @@ ensemble run, etc. ## User documentation -1. \ref Installation "Installation" -2. \ref PDI_usage "PDI usage" -3. \ref Concepts "Core concepts" -4. \ref First_steps "First steps" -5. \ref Hands_on "Tutorial" -6. \ref PDI_example "PDI example" -7. [C API reference](modules.html) -8. \ref Specification_tree_ref "Specification tree reference" -9. \ref Plugins "List of PDI plugins" - +1. \subpage Installation "Installation" +2. \subpage PDI_usage "PDI usage" +3. \subpage Concepts "Core concepts" +4. \subpage First_steps "First steps" +5. \subpage Hands_on "Tutorial" +6. \subpage PDI_example "PDI example" +7. [C API reference](topics.html) +8. \subpage Specification_tree_ref "Specification tree reference" +9. \subpage Plugins "List of PDI plugins" +10. \subpage FAQ "F.A.Q." ## Developer documentation diff --git a/pdi/docs/CMakeLists.txt b/pdi/docs/CMakeLists.txt index e74bde6b3..455f41b21 100644 --- a/pdi/docs/CMakeLists.txt +++ b/pdi/docs/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -27,9 +27,9 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) -find_package(Doxygen 1.8.17 REQUIRED) +find_package(Doxygen 1.9 REQUIRED) set(DOXYGEN_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/About.md" @@ -38,7 +38,6 @@ set(DOXYGEN_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/First_steps.md" "${CMAKE_CURRENT_SOURCE_DIR}/How_to_create_plugin.md" "${CMAKE_CURRENT_SOURCE_DIR}/Installation.md" - "${CMAKE_CURRENT_SOURCE_DIR}/modules.md" "${CMAKE_CURRENT_SOURCE_DIR}/Plugins.md" "${CMAKE_CURRENT_SOURCE_DIR}/Specification_tree_ref.md" "${CMAKE_CURRENT_SOURCE_DIR}/Source_installation.md" @@ -61,12 +60,21 @@ set(DOXYGEN_INPUT "${PDI_SOURCE_DIR}/../plugins/set_value/README.md" "${PDI_SOURCE_DIR}/../plugins/json/README.md") +set(DOXY_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../..") +cmake_path(NORMAL_PATH DOXY_ROOT) + +set(DOXYGEN_REL_INPUT) +foreach(INPUT_ELEMENT IN LISTS DOXYGEN_INPUT) + cmake_path(RELATIVE_PATH INPUT_ELEMENT BASE_DIRECTORY "${DOXY_ROOT}") + list(APPEND DOXYGEN_REL_INPUT "${INPUT_ELEMENT}") +endforeach() +string(REPLACE ";" " " DOXYGEN_REL_INPUT "${DOXYGEN_REL_INPUT}") + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html") -string(REPLACE ";" " " DOXYGEN_INPUT_SP "${DOXYGEN_INPUT}") configure_file(Doxyfile "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile") add_custom_target(doc ALL Doxygen::doxygen "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../../" DEPENDS ${DOXYGEN_INPUT} ) add_dependencies(doc generated_files_for_doc) diff --git a/pdi/docs/CheckList.md b/pdi/docs/CheckList.md index 55a09dc78..24b356bff 100644 --- a/pdi/docs/CheckList.md +++ b/pdi/docs/CheckList.md @@ -6,6 +6,7 @@ To publish a small fix as a patch release: * make your changes based on the version branch (`v${X}.${Y}`) * change the version in `pdi/VERSION` * change the version in `pdi/docs/Source_installation.md` +* change the version in `mock_pdi/PDIConfigVersion.cmake` * commit (or better, make a MR) in the version branch * merge the version branch into main * in the merge commit: @@ -24,6 +25,7 @@ To publish a new minor or major release: * start from the main branch * change the version in `pdi/VERSION` * change the version in `pdi/docs/Source_installation.md` +* change the version in `mock_pdi/PDIConfigVersion.cmake` * go over all `CHANGELOG.md` files and mark the just released version * commit these changes into a new version branch (`v${X}.${Y}`) * tag the new release: `git tag -m "PDI release ${X}.${Y}.0" -s "${X}.${Y}.0"` @@ -42,7 +44,11 @@ To publish a new minor or major release: When changing the list of dependencies or just the version of one dependency: * update `pdi/docs/Source_installation.md`, * update `spack.yaml`, -* update PDI distribution CMakeLists.txt as well as all CMakeLists.txt actually using it, +* update PDI distribution CMakeLists.txt as well as all CMakeLists.txt actually + using it, * update the dockerfiles used for tests, * prepare the update of the spack, deb & RPM packages for the next version, -* change `.github/workflows/*.yml` to use the new docker test images. +* change `.github/workflows/*.yml` to use the new docker test images, +* if the new minimum compiler versions support an updated version of C / C++ / + Fortran, change this info in `pdi/docs/Source_installation.md` and + `pdi/CONTRIBUTING.md` as well as every `c[xx]_std_??` in cmake. diff --git a/pdi/docs/Doxyfile b/pdi/docs/Doxyfile index 5e2307d4f..8bcc83652 100644 --- a/pdi/docs/Doxyfile +++ b/pdi/docs/Doxyfile @@ -27,298 +27,311 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = PDI -PROJECT_NUMBER = @PDI_VERSION@ -PROJECT_BRIEF = -PROJECT_ICON = ./_template/logo.png -PROJECT_LOGO = ./_template/logo.png -OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@ -CREATE_SUBDIRS = NO -CREATE_SUBDIRS_LEVEL = 8 +ABBREVIATE_BRIEF = +ALIASES = +ALLEXTERNALS = NO ALLOW_UNICODE_NAMES = NO -OUTPUT_LANGUAGE = English -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = "The $name class" "The $name widget" "The $name file" is provides specifies contains represents a an the +ALPHABETICAL_INDEX = YES ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = NO -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = YES -JAVADOC_BANNER = NO -QT_AUTOBRIEF = YES -MULTILINE_CPP_IS_BRIEF = NO -PYTHON_DOCSTRING = YES -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 4 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = NO -OPTIMIZE_OUTPUT_JAVA = NO -OPTIMIZE_FOR_FORTRAN = NO -OPTIMIZE_OUTPUT_VHDL = NO -OPTIMIZE_OUTPUT_SLICE = NO -EXTENSION_MAPPING = -MARKDOWN_SUPPORT = YES -TOC_INCLUDE_HEADINGS = 4 -MARKDOWN_ID_STYLE = DOXYGEN +AUTOLINK_IGNORE_WORDS = AUTOLINK_SUPPORT = YES -BUILTIN_STL_SUPPORT = YES +BINARY_TOC = NO +BRIEF_MEMBER_DESC = YES +BUILTIN_STL_SUPPORT = NO +CALLER_GRAPH = NO +CALL_GRAPH = NO +CASE_SENSE_NAMES = SYSTEM +CHM_FILE = +CHM_INDEX_ENCODING = +CITE_BIB_FILES = +CLANG_ADD_INC_PATHS = YES +CLANG_ASSISTED_PARSING = NO +CLANG_DATABASE_PATH = +CLANG_OPTIONS = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +COMPACT_LATEX = NO +COMPACT_RTF = NO CPP_CLI_SUPPORT = NO -SIP_SUPPORT = NO -IDL_PROPERTY_SUPPORT = YES +CREATE_SUBDIRS_LEVEL = 8 +CREATE_SUBDIRS = NO +DIAFILE_DIRS = +DIA_PATH = +DIRECTORY_GRAPH = YES +DIR_GRAPH_MAX_DEPTH = 1 +DISABLE_INDEX = YES DISTRIBUTE_GROUP_DOC = NO -GROUP_NESTED_COMPOUNDS = NO -SUBGROUPING = YES -INLINE_GROUPED_CLASSES = NO -INLINE_SIMPLE_STRUCTS = YES -TYPEDEF_HIDES_STRUCT = YES -LOOKUP_CACHE_SIZE = 0 -NUM_PROC_THREADS = 1 -TIMESTAMP = NO +DOCBOOK_OUTPUT = docbook +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_FEEDURL = +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +DOT_CLEANUP = YES +DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10" +DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10" +DOTFILE_DIRS = +DOT_FONTPATH = +DOT_GRAPH_MAX_NODES = 50 +DOT_IMAGE_FORMAT = png +DOT_MULTI_TARGETS = NO +DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" +DOT_NUM_THREADS = 0 +DOT_PATH = +DOT_UML_DETAILS = NO +DOT_WRAP_THRESHOLD = 17 +DOXYFILE_ENCODING = UTF-8 +ECLIPSE_DOC_ID = org.doxygen.Project +ENABLED_SECTIONS = +ENABLE_PREPROCESSING = YES +ENUM_VALUES_PER_LINE = 1 +EXAMPLE_PATH = example pdi/docs example/example.c +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +EXCLUDE = +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXCLUDE_SYMLINKS = NO +EXPAND_AS_DEFINED = +EXPAND_ONLY_PREDEF = YES +EXTENSION_MAPPING = +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES +EXTERNAL_SEARCH_ID = +EXTERNAL_SEARCH = NO +EXTERNAL_TOOL_PATH = +EXT_LINKS_IN_WINDOW = NO EXTRACT_ALL = YES +EXTRACT_ANON_NSPACES = NO +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +EXTRACT_PACKAGE = NO EXTRACT_PRIVATE = NO EXTRACT_PRIV_VIRTUAL = NO -EXTRACT_PACKAGE = NO EXTRACT_STATIC = NO -EXTRACT_LOCAL_CLASSES = NO -EXTRACT_LOCAL_METHODS = NO -EXTRACT_ANON_NSPACES = NO -RESOLVE_UNNAMED_PARAMS = YES -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = SYSTEM -HIDE_SCOPE_NAMES = NO -HIDE_COMPOUND_REFERENCE= NO -SHOW_HEADERFILE = YES -SHOW_INCLUDE_FILES = NO -SHOW_GROUPED_MEMB_INC = NO +EXTRA_PACKAGES = +EXTRA_SEARCH_MAPPINGS = +FILE_PATTERNS = +FILE_VERSION_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = FORCE_LOCAL_INCLUDES = NO -INLINE_INFO = YES -SORT_MEMBER_DOCS = NO -SORT_BRIEF_DOCS = NO -SORT_MEMBERS_CTORS_1ST = YES -SORT_GROUP_NAMES = NO -SORT_BY_SCOPE_NAME = NO -STRICT_PROTO_MATCHING = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES +FORMULA_FONTSIZE = 10 +FORMULA_MACROFILE = +FORTRAN_COMMENT_AFTER = 72 +FULL_PATH_NAMES = NO +FULL_SIDEBAR = NO +GENERATE_AUTOGEN_DEF = NO GENERATE_BUGLIST = YES +GENERATE_CHI = NO GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_FILES = NO -SHOW_NAMESPACES = YES -FILE_VERSION_FILTER = -LAYOUT_FILE = ./_template/layout.xml -CITE_BIB_FILES = -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_IF_INCOMPLETE_DOC = YES -WARN_NO_PARAMDOC = YES -WARN_IF_UNDOC_ENUM_VAL = NO -WARN_AS_ERROR = NO -WARN_FORMAT = "$file:$line: $text" -WARN_LINE_FORMAT = at line $line of file $file -WARN_LOGFILE = -INPUT = @DOXYGEN_INPUT_SP@ -INPUT_ENCODING = UTF-8 -INPUT_FILE_ENCODING = -FILE_PATTERNS = *.c *.cc *.cxx *.cxxm *.cpp *.cppm *.c++ *.c++m *.java *.ii *.ixx *.ipp *.i++ *.inl *.idl *.ddl *.odl *.h *.hh *.hxx *.hpp *.h++ *.ixx *.l *.cs *.d *.php *.php4 *.php5 *.phtml *.inc *.m *.markdown *.md *.mm *.dox *.py *.pyw *.f90 *.f95 *.f03 *.f08 *.f18 *.f *.for *.vhd *.vhdl *.ucf *.qsf *.ice -RECURSIVE = NO -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = */.git/* */.svn/* */.hg/* */CMakeFiles/* */_CPack_Packages/* DartConfiguration.tcl CMakeLists.txt CMakeCache.txt -EXCLUDE_SYMBOLS = -EXAMPLE_PATH = ./ ../ ../../example/ -EXAMPLE_PATTERNS = * -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = ./images -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -FILTER_SOURCE_PATTERNS = -USE_MDFILE_AS_MAINPAGE = -FORTRAN_COMMENT_AFTER = 72 -SOURCE_BROWSER = NO -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = NO -REFERENCES_RELATION = NO -REFERENCES_LINK_SOURCE = YES -SOURCE_TOOLTIPS = YES -USE_HTAGS = NO -VERBATIM_HEADERS = YES -CLANG_ASSISTED_PARSING = NO -CLANG_ADD_INC_PATHS = YES -CLANG_OPTIONS = -CLANG_DATABASE_PATH = -ALPHABETICAL_INDEX = YES -IGNORE_PREFIX = +GENERATE_DOCBOOK = NO +GENERATE_DOCSET = NO +GENERATE_ECLIPSEHELP = NO +GENERATE_HTMLHELP = NO GENERATE_HTML = YES -HTML_OUTPUT = @CMAKE_CURRENT_BINARY_DIR@/html -HTML_FILE_EXTENSION = .html -HTML_HEADER = ./_template/header.html -HTML_FOOTER = ./_template/footer.html -HTML_STYLESHEET = ./_template/style.css -HTML_EXTRA_STYLESHEET = -HTML_EXTRA_FILES = +GENERATE_LATEX = NO +GENERATE_LEGEND = YES +GENERATE_MAN = NO +GENERATE_PERLMOD = NO +GENERATE_QHP = NO +GENERATE_RTF = NO +GENERATE_SQLITE3 = NO +GENERATE_TAGFILE = +GENERATE_TESTLIST = YES +GENERATE_TODOLIST = YES +GENERATE_TREEVIEW = YES +GENERATE_XML = NO +GRAPHICAL_HIERARCHY = YES +GROUP_GRAPHS = YES +GROUP_NESTED_COMPOUNDS = NO +HAVE_DOT = NO +HHC_LOCATION = +HIDE_COMPOUND_REFERENCE= NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +HIDE_SCOPE_NAMES = NO +HIDE_UNDOC_CLASSES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_NAMESPACES = NO +HIDE_UNDOC_RELATIONS = YES +HTML_CODE_FOLDING = YES HTML_COLORSTYLE = AUTO_LIGHT +HTML_COLORSTYLE_GAMMA = 80 HTML_COLORSTYLE_HUE = 220 HTML_COLORSTYLE_SAT = 100 -HTML_COLORSTYLE_GAMMA = 80 +HTML_COPY_CLIPBOARD = YES HTML_DYNAMIC_MENUS = YES HTML_DYNAMIC_SECTIONS = NO -HTML_CODE_FOLDING = YES -HTML_INDEX_NUM_ENTRIES = 100 -GENERATE_DOCSET = NO -DOCSET_FEEDNAME = "Doxygen generated docs" -DOCSET_FEEDURL = -DOCSET_BUNDLE_ID = org.doxygen.Project -DOCSET_PUBLISHER_ID = org.doxygen.Publisher -DOCSET_PUBLISHER_NAME = Publisher -GENERATE_HTMLHELP = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -CHM_INDEX_ENCODING = -BINARY_TOC = NO -TOC_EXPAND = NO -SITEMAP_URL = -GENERATE_QHP = NO -QCH_FILE = -QHP_NAMESPACE = org.doxygen.Project -QHP_VIRTUAL_FOLDER = doc -QHP_CUST_FILTER_NAME = -QHP_CUST_FILTER_ATTRS = -QHP_SECT_FILTER_ATTRS = -QHG_LOCATION = -GENERATE_ECLIPSEHELP = NO -ECLIPSE_DOC_ID = org.doxygen.Project -DISABLE_INDEX = YES -GENERATE_TREEVIEW = YES -FULL_SIDEBAR = NO -ENUM_VALUES_PER_LINE = 1 -TREEVIEW_WIDTH = 250 -EXT_LINKS_IN_WINDOW = NO -OBFUSCATE_EMAILS = YES +HTML_EXTRA_FILES = +HTML_EXTRA_STYLESHEET = +HTML_FILE_EXTENSION = .html +HTML_FOOTER = @CMAKE_CURRENT_SOURCE_DIR@/_template/footer.html HTML_FORMULA_FORMAT = png -FORMULA_FONTSIZE = 10 -FORMULA_MACROFILE = -USE_MATHJAX = NO -MATHJAX_VERSION = MathJax_2 -MATHJAX_FORMAT = HTML-CSS -MATHJAX_RELPATH = -MATHJAX_EXTENSIONS = -MATHJAX_CODEFILE = -SEARCHENGINE = NO -SERVER_BASED_SEARCH = NO -EXTERNAL_SEARCH = NO -SEARCHENGINE_URL = -SEARCHDATA_FILE = searchdata.xml -EXTERNAL_SEARCH_ID = -EXTRA_SEARCH_MAPPINGS = -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = -MAKEINDEX_CMD_NAME = makeindex -LATEX_MAKEINDEX_CMD = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4 -EXTRA_PACKAGES = -LATEX_HEADER = -LATEX_FOOTER = -LATEX_EXTRA_STYLESHEET = -LATEX_EXTRA_FILES = -PDF_HYPERLINKS = YES -USE_PDFLATEX = YES +HTML_HEADER = @CMAKE_CURRENT_SOURCE_DIR@/_template/header.html +HTML_INDEX_NUM_ENTRIES = 100 +HTML_OUTPUT = @CMAKE_CURRENT_BINARY_DIR@/html +HTML_PROJECT_COOKIE = +HTML_STYLESHEET = @CMAKE_CURRENT_SOURCE_DIR@/_template/style.css +IDL_PROPERTY_SUPPORT = YES +IGNORE_PREFIX = +IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/images +IMPLICIT_DIR_DOCS = NO +INCLUDED_BY_GRAPH = NO +INCLUDE_FILE_PATTERNS = +INCLUDE_GRAPH = NO +INCLUDE_PATH = pdi/include/ @PDI_BINARY_DIR@ +INHERIT_DOCS = YES +INLINE_GROUPED_CLASSES = NO +INLINE_INFO = YES +INLINE_INHERITED_MEMB = NO +INLINE_SIMPLE_STRUCTS = YES +INLINE_SOURCES = NO +INPUT = @DOXYGEN_REL_INPUT@ +INPUT_ENCODING = UTF-8 +INPUT_FILE_ENCODING = +INPUT_FILTER = +INTERACTIVE_SVG = NO +INTERNAL_DOCS = NO +JAVADOC_AUTOBRIEF = YES +JAVADOC_BANNER = NO LATEX_BATCHMODE = NO +LATEX_BIB_STYLE = plainnat +LATEX_CMD_NAME = +LATEX_EMOJI_DIRECTORY = +LATEX_EXTRA_FILES = +LATEX_EXTRA_STYLESHEET = +LATEX_FOOTER = +LATEX_HEADER = LATEX_HIDE_INDICES = NO -LATEX_BIB_STYLE = plain -LATEX_EMOJI_DIRECTORY = -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -GENERATE_MAN = NO -MAN_OUTPUT = man +LATEX_MAKEINDEX_CMD = makeindex +LATEX_OUTPUT = latex +LAYOUT_FILE = @CMAKE_CURRENT_SOURCE_DIR@/_template/layout.xml +LOOKUP_CACHE_SIZE = 0 +MACRO_EXPANSION = YES +MAKEINDEX_CMD_NAME = makeindex MAN_EXTENSION = .3 -MAN_SUBDIR = MAN_LINKS = NO -GENERATE_XML = NO # YES Crashes on Gitlab CI -XML_OUTPUT = xml -XML_PROGRAMLISTING = YES -XML_NS_MEMB_FILE_SCOPE = NO -GENERATE_DOCBOOK = NO -DOCBOOK_OUTPUT = docbook -GENERATE_AUTOGEN_DEF = NO -GENERATE_SQLITE3 = NO -SQLITE3_OUTPUT = sqlite3 -SQLITE3_RECREATE_DB = YES -GENERATE_PERLMOD = NO +MAN_OUTPUT = man +MAN_SUBDIR = +MARKDOWN_ID_STYLE = GITHUB +MARKDOWN_SUPPORT = YES +MARKDOWN_STRICT = NO +MATHJAX_CODEFILE = +MATHJAX_EXTENSIONS = +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = +MATHJAX_VERSION = MathJax_2 +MAX_DOT_GRAPH_DEPTH = 0 +MAX_INITIALIZER_LINES = 30 +MSCFILE_DIRS = +MSCGEN_TOOL = +MULTILINE_CPP_IS_BRIEF = NO +NUM_PROC_THREADS = 1 +OBFUSCATE_EMAILS = YES +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_OUTPUT_SLICE = NO +OPTIMIZE_OUTPUT_VHDL = NO +OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@ +OUTPUT_LANGUAGE = English +PAGE_OUTLINE_PANEL = NO +PAPER_TYPE = a4 +PDF_HYPERLINKS = YES PERLMOD_LATEX = NO +PERLMOD_MAKEVAR_PREFIX = PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = YES -SEARCH_INCLUDES = YES -INCLUDE_PATH = ../include/ ../src/ @PDI_BINARY_DIR@ -INCLUDE_FILE_PATTERNS = +PLANTUML_CFG_FILE = +PLANTUMLFILE_DIRS = +PLANTUML_INCLUDE_PATH = +PLANTUML_JAR_PATH = PREDEFINED = PDI_EXPORT= PDI_NO_EXPORT= PDI_DEPRECATED_EXPORT= -EXPAND_AS_DEFINED = +PROJECT_BRIEF = +PROJECT_ICON = @CMAKE_CURRENT_SOURCE_DIR@/_template/logo.png +PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/_template/logo.png +PROJECT_NAME = PDI +PROJECT_NUMBER = @PDI_VERSION@ +PYTHON_DOCSTRING = YES +QCH_FILE = +QHG_LOCATION = +QHP_CUST_FILTER_ATTRS = +QHP_CUST_FILTER_NAME = +QHP_NAMESPACE = org.doxygen.Project +QHP_SECT_FILTER_ATTRS = +QHP_VIRTUAL_FOLDER = doc +QT_AUTOBRIEF = YES +QUIET = NO +RECURSIVE = YES +REFERENCED_BY_RELATION = NO +REFERENCES_LINK_SOURCE = YES +REFERENCES_RELATION = NO +REPEAT_BRIEF = YES +RESOLVE_UNNAMED_PARAMS = YES +RTF_EXTENSIONS_FILE = +RTF_EXTRA_FILES = +RTF_HYPERLINKS = NO +RTF_OUTPUT = rtf +RTF_STYLESHEET_FILE = +SEARCHDATA_FILE = searchdata.xml +SEARCHENGINE_URL = +SEARCHENGINE = NO +SEARCH_INCLUDES = YES +SEPARATE_MEMBER_PAGES = NO +SERVER_BASED_SEARCH = NO +SHORT_NAMES = NO +SHOW_ENUM_VALUES = YES +SHOW_FILES = NO +SHOW_GROUPED_MEMB_INC = NO +SHOW_HEADERFILE = YES +SHOW_INCLUDE_FILES = NO +SHOW_NAMESPACES = YES +SHOW_USED_FILES = YES +SIP_SUPPORT = NO +SITEMAP_URL = SKIP_FUNCTION_MACROS = YES -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -EXTERNAL_PAGES = YES -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = NO -DOT_NUM_THREADS = 0 -DOT_COMMON_ATTR = fontname=Helvetica,fontsize=10 -DOT_EDGE_ATTR = labelfontname=Helvetica,labelfontsize=10 -DOT_NODE_ATTR = shape=box,height=0.2,width=0.4 -DOT_FONTPATH = -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES -UML_LOOK = YES -UML_LIMIT_NUM_FIELDS = 20 -DOT_UML_DETAILS = NO -DOT_WRAP_THRESHOLD = 17 +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +SORT_GROUP_NAMES = NO +SORT_MEMBER_DOCS = NO +SORT_MEMBERS_CTORS_1ST = YES +SOURCE_BROWSER = NO +SOURCE_TOOLTIPS = YES +SQLITE3_OUTPUT = sqlite3 +SQLITE3_RECREATE_DB = YES +STRICT_PROTO_MATCHING = NO +STRIP_CODE_COMMENTS = YES +STRIP_FROM_INC_PATH = +STRIP_FROM_PATH = +SUBGROUPING = YES +TAB_SIZE = 4 +TAGFILES = TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = NO -INCLUDED_BY_GRAPH = NO -CALL_GRAPH = NO -CALLER_GRAPH = NO -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = YES -DIR_GRAPH_MAX_DEPTH = 1 -DOT_IMAGE_FORMAT = png -INTERACTIVE_SVG = NO -DOT_PATH = -DOTFILE_DIRS = -DIA_PATH = -DIAFILE_DIRS = -PLANTUML_JAR_PATH = -PLANTUML_CFG_FILE = -PLANTUML_INCLUDE_PATH = -DOT_GRAPH_MAX_NODES = 50 -MAX_DOT_GRAPH_DEPTH = 0 -DOT_MULTI_TARGETS = YES -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -MSCGEN_TOOL = -MSCFILE_DIRS = +TIMESTAMP = NO +TOC_EXPAND = NO +TOC_INCLUDE_HEADINGS = 4 +TREEVIEW_WIDTH = 250 +TYPEDEF_HIDES_STRUCT = YES +UML_LIMIT_NUM_FIELDS = 20 +UML_LOOK = YES +UML_MAX_EDGE_LABELS = 10 +USE_HTAGS = NO +USE_MATHJAX = NO +USE_MDFILE_AS_MAINPAGE = +USE_PDFLATEX = YES +VERBATIM_HEADERS = YES +WARN_AS_ERROR = NO +WARN_FORMAT = "$file:$line: $text" +WARN_IF_DOC_ERROR = YES +WARN_IF_INCOMPLETE_DOC = YES +WARN_IF_UNDOC_ENUM_VAL = NO +WARN_IF_UNDOCUMENTED = YES +WARNINGS = YES +WARN_LAYOUT_FILE = YES +WARN_LINE_FORMAT = "!!!WARNING!!! at line $line of file $file" +WARN_LOGFILE = +WARN_NO_PARAMDOC = YES +XML_NS_MEMB_FILE_SCOPE = NO +XML_OUTPUT = xml +XML_PROGRAMLISTING = YES diff --git a/pdi/docs/First_steps/CMakeLists.txt b/pdi/docs/First_steps/CMakeLists.txt index 027447138..4f6c1fe92 100644 --- a/pdi/docs/First_steps/CMakeLists.txt +++ b/pdi/docs/First_steps/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -27,7 +27,7 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) if("${BUILD_FORTRAN}") add_executable(hello_access.f90 hello_access.f90) diff --git a/pdi/docs/Plugins.md b/pdi/docs/Plugins.md index 65b349830..4d3fa3268 100644 --- a/pdi/docs/Plugins.md +++ b/pdi/docs/Plugins.md @@ -4,7 +4,6 @@ |:----------------------------------------------------|:------------------------------------------------------------------| |\subpage Decl_HDF5_plugin "Decl'HDF5 plugin" |Read and write data from HDF5 files in a declarative way. | |\subpage Decl_NetCDF_plugin "Decl'NetCDF plugin" |Read and write data from NetCDF files in a declarative way. | -|Deisa plugin |Expose data to a Dask analysis script. | |\subpage mpi_plugin "MPI plugin" |Enables MPI support in %PDI and plugins. | |\subpage pycall_plugin "Pycall plugin" |Call python scripts from C application | |\subpage JSON_plugin "JSON plugin" |Export data in JSON format. | @@ -13,4 +12,4 @@ |\subpage trace_plugin "Trace plugin" |Generate a trace of what happens in %PDI data store. | |\subpage user_code_plugin "user-code plugin" |Call your function on event or when data becomes available. | -To learn how to create your own plugin see: \subpage how_to_create_plugin "How to create a plugin" +To learn how to create your own plugin see: \ref how_to_create_plugin "How to create a plugin" diff --git a/pdi/docs/Source_installation.md b/pdi/docs/Source_installation.md index 986196e9b..e2857ac06 100644 --- a/pdi/docs/Source_installation.md +++ b/pdi/docs/Source_installation.md @@ -16,8 +16,8 @@ The %PDI source distribution includes: To download the sources, have a look at the list of all releases at https://github.com/pdidev/pdi/releases/ -For example, release 1.9.2 can be downloaded from -https://github.com/pdidev/pdi/archive/refs/tags/1.9.2.tar.gz +For example, release 1.10.1 can be downloaded from +https://github.com/pdidev/pdi/archive/refs/tags/1.10.1.tar.gz ## Default installation {#default_installation} @@ -29,29 +29,28 @@ Installing the default %PDI source distribution is fairly easy. Most dependencies are embedded in the distribution and the only required external dependencies are: * a POSIX compatible OS such as GNU/linux, -* [cmake](https://cmake.org/) version 3.16.3 or above, -* a C 99, C++ 17 and Fortran 03 compiler such as - - [gcc](https://gcc.gnu.org/) 9.3 or above, - - [clang](https://clang.llvm.org/) 10.0 or above, -* a [python](https://www.python.org/) interpreter, version 3.8.2 or above, +* [cmake](https://cmake.org/) version 3.22 or above, +* a C 17, C++ 20 and Fortran 18 compiler such as [gcc](https://gcc.gnu.org/) 11 + or above, +* a [python](https://www.python.org/) interpreter, version 3.10 or above, * a [bash](https://www.gnu.org/software/bash/) interpreter, * a [MPI](https://www.mpi-forum.org/) 2 implementation such as - - [openmpi](https://www.open-mpi.org/) 4.0 or above, - - [mpich](https://www.mpich.org/) 3.3 or above. + - [openmpi](https://www.open-mpi.org/) 4.1 or above, + - [mpich](https://www.mpich.org/) 4.0 or above. \attention This list of dependencies can be further reduced or extended by changing the set of features compiled. -For example, release 1.9.2 can be installed by following these instructions (but +For example, release 1.10.1 can be installed by following these instructions (but look for the latest release at https://github.com/pdidev/pdi/releases ): ```bash -wget https://github.com/pdidev/pdi/archive/refs/tags/1.9.2.tar.gz -tar -xjf 1.9.2.tar.bz2 -mkdir 1.9.2/build -cd 1.9.2/build +wget https://github.com/pdidev/pdi/archive/refs/tags/1.10.1.tar.gz +tar -xjf 1.10.1.tar.bz2 +mkdir 1.10.1/build +cd 1.10.1/build cmake -DCMAKE_INSTALL_PREFIX="${HOME}/.local/" .. # configuration make install # compilation and installation ``` @@ -106,10 +105,10 @@ The following flags define which features of the distribution to enable or not. |`BUILD_TESTING` |`ON` |Build the tests.| |`BUILD_TRACE_PLUGIN` |`ON` |Build the Trace plug-in.| |`BUILD_USER_CODE_PLUGIN` |`ON` |Build the User-code plug-in.| -|`BUILD_DEISA_PLUGIN` |`OFF` |Build the Deisa plug-in.| |`BUILD_DOCUMENTATION` |`OFF` |Build the documentation website. (devel profile)| |`BUILD_PYCALL_PLUGIN` |`OFF` |Build Pycall plug-in. (unstable)| |`BUILD_PYTHON` |`OFF` |Build the Python interface. (unstable)| +|`ENABLE_BENCHMARKING` |`OFF` |Run benchmarks as part of the test suite.| The following flags define whether to: @@ -138,23 +137,21 @@ The following flags define whether to: The following flags define where to install %PDI, those prefixed with `CMAKE_` are provided and documented by the -[GNUInstallDirs](https://cmake.org/cmake/help/v3.19/module/GNUInstallDirs.html) +[GNUInstallDirs](https://cmake.org/cmake/help/v3.22/module/GNUInstallDirs.html) cmake module. - - |Flag |Default |Description| |:-------------|:---------|:----------| |`INSTALL_CMAKEDIR`|`PDIDATADIR/cmake`|Cmake modules.| |`INSTALL_FMODDIR`|`LIBDIR/pdi/finclude/${COMPILER_VERSION}`|Fortran modules| |`INSTALL_PDIDATADIR`|`DATADIR/pdi`|PDI data| |`INSTALL_PDIPLUGINDIR`|`LIBDIR/pdi/plugins_${PDI_VERSION}`|PDI plugins| -|`CMAKE_INSTALL_BINDIR`|see [GNUInstallDirs](https://cmake.org/cmake/help/v3.19/module/GNUInstallDirs.html)|user executables| -|`CMAKE_INSTALL_DATADIR`|see [GNUInstallDirs](https://cmake.org/cmake/help/v3.19/module/GNUInstallDirs.html)|read-only architecture-independent data| -|`CMAKE_INSTALL_DOCDIR`|see [GNUInstallDirs](https://cmake.org/cmake/help/v3.19/module/GNUInstallDirs.html)|documentation root| -|`CMAKE_INSTALL_INCLUDEDIR`|see [GNUInstallDirs](https://cmake.org/cmake/help/v3.19/module/GNUInstallDirs.html)|C header files| -|`CMAKE_INSTALL_LIBDIR`|see [GNUInstallDirs](https://cmake.org/cmake/help/v3.19/module/GNUInstallDirs.html)|object code libraries| -|`CMAKE_INSTALL_PREFIX`|see [CMake doc](https://cmake.org/cmake/help/v3.19/variable/CMAKE_INSTALL_PREFIX.html)|Installation base| +|`CMAKE_INSTALL_BINDIR`|see [GNUInstallDirs](https://cmake.org/cmake/help/v3.22/module/GNUInstallDirs.html)|user executables| +|`CMAKE_INSTALL_DATADIR`|see [GNUInstallDirs](https://cmake.org/cmake/help/v3.22/module/GNUInstallDirs.html)|read-only architecture-independent data| +|`CMAKE_INSTALL_DOCDIR`|see [GNUInstallDirs](https://cmake.org/cmake/help/v3.22/module/GNUInstallDirs.html)|documentation root| +|`CMAKE_INSTALL_INCLUDEDIR`|see [GNUInstallDirs](https://cmake.org/cmake/help/v3.22/module/GNUInstallDirs.html)|C header files| +|`CMAKE_INSTALL_LIBDIR`|see [GNUInstallDirs](https://cmake.org/cmake/help/v3.22/module/GNUInstallDirs.html)|object code libraries| +|`CMAKE_INSTALL_PREFIX`|see [CMake doc](https://cmake.org/cmake/help/v3.22/variable/CMAKE_INSTALL_PREFIX.html)|Installation base| ## List of dependencies {#dependecies} @@ -164,52 +161,52 @@ All dependencies are provided in the distribution unless specified otherwise. Dependencies of **%PDI**: * a POSIX compatible OS such as GNU/linux, -* **[cmake](https://cmake.org/) version 3.16 or above (not provided)**, -* **a C 99 and C++ 17 compiler (not provided)** such as - - [gcc](https://gcc.gnu.org/) 9.3 or above, - - [clang](https://clang.llvm.org/) 10.0 or above, -* the [paraconf](https://github.com/pdidev/paraconf) library version 1.0.0 or above (provided), +* **[cmake](https://cmake.org/) version 3.22 or above (not provided)**, +* **a C 17 and C++ 20 compiler (not provided)** such as + - [gcc](https://gcc.gnu.org/) 11 or above, + - [clang](https://clang.llvm.org/) 14 or above, +* the [paraconf](https://github.com/pdidev/paraconf) library version 1.0 or above (provided), * the [libyaml](https://pyyaml.org/wiki/LibYAML) library version 0.2.2 or above (provided), -* the [spdlog](https://github.com/gabime/spdlog) library version 1.5.0 or above (provided). +* the [spdlog](https://github.com/gabime/spdlog) library version 1.9 or above (provided). Additional dependencies for **the Fortran API**: * the PDI library, -* **a Fortran 03 compiler (not provided)** such as - - [gcc](https://gcc.gnu.org/) 9.3 or above, -* **a [python](https://www.python.org/) interpreter, version 3.8.2 or above (not provided)**. +* **a Fortran 18 compiler (not provided)** such as + - [gcc](https://gcc.gnu.org/) 11 or above, +* **a [python](https://www.python.org/) interpreter, version 3.10 or above (not provided)**. Additional dependencies for **the Python support**: * the PDI library, -* **the [python](https://www.python.org/) development environment version 3.8.2 or above (not provided)**, -* the [pybind11](https://pybind11.readthedocs.io/en/stable) library version 2.4.3 or above. +* **the [python](https://www.python.org/) development environment version 3.10 or above (not provided)**, +* the [pybind11](https://pybind11.readthedocs.io/en/stable) library version 2.9 or above. Dependencies of **the Decl'HDF5 plugin**: * the PDI library, -* the [HDF5](https://www.hdfgroup.org/solutions/hdf5/) library version 1.10.4 or above (provided), +* the [HDF5](https://www.hdfgroup.org/solutions/hdf5/) library version 1.10 or above (provided), * **a MPI implementation for the parallel version of the plugin (not provided)**, such as - - [openmpi](https://www.open-mpi.org/) 4.0 or above, - - [mpich](https://www.mpich.org/) 3.3 or above. + - [openmpi](https://www.open-mpi.org/) 4.1 or above, + - [mpich](https://www.mpich.org/) 4.0 or above. Dependencies of **the Decl'NetCDF plugin**: * the PDI library, -* the [NetCDF](https://www.unidata.ucar.edu/software/netcdf/) library version 4.7.3 or above (provided), -* the [HDF5](https://www.hdfgroup.org/solutions/hdf5/) library version 1.10.4 or above (provided), +* the [NetCDF](https://www.unidata.ucar.edu/software/netcdf/) library version 4.8 or above (provided), +* the [HDF5](https://www.hdfgroup.org/solutions/hdf5/) library version 1.10 or above (provided), * **a MPI implementation for the parallel version of the plugin (not provided)**, such as - - [openmpi](https://www.open-mpi.org/) 4.0 or above, - - [mpich](https://www.mpich.org/) 3.3 or above. + - [openmpi](https://www.open-mpi.org/) 4.1 or above, + - [mpich](https://www.mpich.org/) 4.0 or above. Dependencies of **the JSON plugin**: * the PDI library, -* the [Json](https://github.com/nlohmann/json/) library version 3.9.1 or above (provided). +* the [Json](https://github.com/nlohmann/json/) library version 3.9 or above (provided). Dependencies of **the MPI plugin**: * the PDI library, * **a MPI-2 implementation (not provided)** such as - - [openmpi](https://www.open-mpi.org/) 4.0 or above, - - [mpich](https://www.mpich.org/) 3.3 or above. + - [openmpi](https://www.open-mpi.org/) 4.1 or above, + - [mpich](https://www.mpich.org/) 4.0 or above. diff --git a/pdi/docs/Using_PDI.md b/pdi/docs/Using_PDI.md index 000fc3865..60414b8ea 100644 --- a/pdi/docs/Using_PDI.md +++ b/pdi/docs/Using_PDI.md @@ -5,91 +5,189 @@ is written either in C/C++, Fortran or Pyhton. ## Preparing the environment {#preparing_the_environment} -### PDI was installed in default location {#pdi_in_default_location} +If you installed PDI to the system default location (such as `/usr/` under linux), the library and plugins should be found without any problem. +But you can always follow the directions for \ref pdi_not_in_default_location "installation in a custom location" to ensure everything is found. -The library and plugins should be found without any problem, but a good approach is to -make sure that all environment variables are set correctly. To do this, there are 3 options: +### %PDI was installed in custom location {#pdi_not_in_default_location} -1. `source pdirun` - sets up current environment variables -2. `pdirun bash` - creates new shell with environment variables set up -3. `pdirun command` - runs a `command` with all environment variables set up +To prepare environment in this case there are 3 options: -To have the environment always prepared for using %PDI, the first option (`source pdirun`) -can be added to `~/.bash_profile` file. After that, any new shell will have environment -variables set up. +1. `source /share/pdi/env.bash` - sets up current environment variables +2. `/bin/pdirun bash` - creates new shell with environment variables set up +3. `/bin/pdirun command` - runs a `command` with all environment variables set up -### PDI was installed in custom location {#pdi_not_in_default_location} +where `` is the root of %PDI installation. -To prepare environment in this case there are 3 options: +To have the environment always setup for %PDI, the first option (`source PDI_path/share/pdi/env.bash`) can be added to `~/.bash_profile` file. +After that, any new shell will have the environment set up. -1. `source PDI_path/share/pdi/env.bash` - sets up current environment variables -2. `PDI_path/bin/pdirun bash` - creates new shell with environment variables set up -3. `PDI_path/bin/pdirun command` - runs a `command` with all environment variables set up +## Compilation of an application {#compilation_of__app} -where `PDI_path` is the path where %PDI was installed. +For C make sure that source files that use %PDI API include the `pdi.h` header (`#include `). +For Fortran make sure that source files that use %PDI use `PDI` module (`USE PDI`). -To have the environment always prepared for using %PDI, the first option (`source PDI_path/share/pdi/env.bash`) -can be added to `~/.bash_profile` file. After that, any new shell will have environment -variables set up. +The recommended way to compile your application is based on cmake. -## Compilation of an application {#compilation_of__app} +\remark +If you have instrumented your code using %PDI but no %PDI installation is available, you can disable it using the \ref deactivate_pdi "MockPDI approach". + +### C/C++ compilation {#c_cpp_compiling_with_cmake_application} -If source files (of application that uses %PDI) and specification tree file are ready, the compilation step can be made. -For C make sure that source files that use %PDI API are including `pdi.h` header file. -For Fortran make sure that source files that use %PDI API are using `%PDI` module file (`USE %PDI`). +To compile C/C++ applications, cmake must find the `C` component from %PDI package and the `PDI::PDI_C` target must be linked to the application target: +Because in order to initialize %PDI, you also have to use Paraconf, you should do the same for Paraconf component `C` and target `paraconf::paraconf`. +```CMake +find_package(paraconf REQUIRED COMPONENTS C) +find_package(PDI REQUIRED COMPONENTS C) -### Compiling by hand {#compiling_by_hand} +add_executable(exec_file source_files.c) +target_link_libraries(exec_file PRIVATE PDI::PDI_C paraconf::paraconf) +``` -To compile application, linker flag `-lpdi` must be used. -For C it would look like this: +### Fortran compilation {#fortan_compiling_by_cmake_application} -```bash -gcc source_files.c -o exec_file -lpdi +To compile Fortran applications, cmake must find the `C` component from %PDI and the `PDI::PDI_f90` target must be linked to the application target. +Because in order to initialize %PDI, you also have to use Paraconf, you should do the same for Paraconf component `f90` and target `paraconf::paraconf_f90`. +```CMake +find_package(paraconf REQUIRED COMPONENTS f90) +find_package(PDI REQUIRED COMPONENTS f90) + +add_executable(exec_file source_files.c) +target_link_libraries(exec_file PRIVATE PDI::PDI_f90 paraconf::paraconf_f90) ``` -For Fortran it would look like this: +## Running the application {#running_app} -```bash -gfortran source_files.f90 -o exec_file -lpdi +%PDI is a shared library. +That means that all environment variables must be set not only on compilation, but also when running the program. + +Every used plugin in application needs to be found by %PDI. +%PDI will search for plugins in 4 steps (it will use the first plugin found): + +1. `PDI_PLUGIN_PATH` environment variable that is colon separated list with paths, +2. `plugin_path` subtree in specification tree: \ref plugin_path_map_node, +3. the directory relative to the installation of %PDI shared library `libpdi.so`, +4. `LD_LIBRARY_PATH` environment variable that is colon separated list. + +## Deactivating %PDI with MockPDI {#deactivate_pdi} + +You may use the `mock_pdi` directory instead of the real %PDI to compile your application. +This directory contains a [mock](https://en.wikipedia.org/wiki/Mock_object) %PDI implementation that you can use instead of the real %PDI, if you prefer not or can not to install it on your specific system. +The recommandation is to copy the `mock_pdi` dirctory into your own application directory so as to be able to use it when required. + +\remark +As of now, only the C component of %PDI is provided by the mock %PDI. +We do not provide any way to mock the Fortran or Python API of %PDI yet. + +There are two ways the mock %PDI can be used: "SubdirMock" and "MockFind". +1. The recommended way is to use "SubdirMock", as it is more robust and will also support working without Paraconf if that's an option for you. +However, "SubdirMock" requires you to modify your root `CMakeLists.txt`. +2. The "MockFind" approach is less robust, and only mocks %PDI so other libraries such as Paraconf remain required even if they were used for %PDI only, but it is non-invasive and requires zero modification to your project. + +### The recommended way: "SubdirMock" {#SubdirMock} + +\remark +This is the recommended way to mock %PDI. +It is robust and also support working without Paraconf if that's an option for you. +However, it requires you to modify your root `CMakeLists.txt`. +I you do not or can not do it, have a look at the \ref MockFind "\"MockFind\" approach" + +To use "SubdirMock", your need to introduce a new cmake option in your project. +For example, in the %PDI `example`, the option is called `DISABLE_PDI`. +```CMake +option(DISABLE_PDI "Disable the use of both PDI and Paraconf in the project" OFF) ``` -### Compiling with cmake {#compiling_with_cmake} +Then, where you used to look for %PDI, you will have to replace the call to `find_package` by a call to `add_subdirectory`. +As parameter, pass the location where you copied the `mock_pdi` directory in your project. -If source files (of application that uses %PDI) and specification tree file are ready, the compilation step can be made. +```CMake +if("${DISABLE_PDI}") + add_subdirectory(/mock_pdi mock_pdi) +else() + find_package(PDI REQUIRED) +endif() +``` -#### C/C++ compilation {#c_cpp_compiling_with_cmake_application} +With this approach, your code should be able to compile without %PDI. +Please note, that it will still require Paraconf however. -To compile C/C++ application, cmake must find `C` component from %PDI package. -Then the `PDI::PDI_C` library must be linked to the target: +\remark +In your code, you can check and handle the case where %PDI is disabled specifically by checking the `WITHOUT_PDI` macro: +```C +#ifdef WITHOUT_PDI +do_something_specific_for_mock_pdi(); +#endif +``` -```cmake -find_package(PDI REQUIRED COMPONENTS C) +#### Without Paraconf -add_executable(exec_file source_files.c) -target_link_libraries(exec_file PDI::PDI_C) +If you want to go further and make Paraconf optional too: +1. set `PDI_MOCK_PARACONF_TARGET` to true before the `add_subdirectory` call, and +2. put Paraconf `find_package` in the same place as the one for %PDI that is not called in case your disabling option is set. + +```CMake +if("${DISABLE_PDI}") + set(PDI_MOCK_PARACONF_TARGET TRUE) + add_subdirectory(/mock_pdi mock_pdi) +else() + find_package(paraconf REQUIRED) + find_package(PDI REQUIRED) +endif() +``` +\remark +Again, in your code, you can check the `WITHOUT_PDI` macro. +This time, you can also check and handle the case where Paraconf is disabled by checking the `WITHOUT_PARACONF` macro. + +This will take care of your cmake. +But while the `paraconf::paraconf` target will be provided that way, Paraconf itself will not be mocked. +You will therefore have to `#ifdef` out any use you make of Paraconf in your code. + +The two uses you most definitely make in your code are +1. the one to include Paraconf, and +2. the one to provide the `PC_tree_t` to %PDI. +These should be `#ifdef`ed out. + +```C +#ifndef WITHOUT_PARACONF +#include +#endif ``` -#### Fortran compilation {#fortan_compiling_by_cmake_application} +```C +#ifndef WITHOUT_PARACONF + PDI_init(PC_parse_path(config_file])); +#endif +``` -To compile Fortran application, cmake must find `f90` component from %PDI package. -Then the `PDI::PDI_f90` library must be linked to the target: +And if your only use of Paraconf is for %PDI, that's all you have to do. -```cmake -find_package(PDI REQUIRED COMPONENTS f90) +If you use Paraconf beyond %PDI, you will have to `#ifdef` out those usages too. +Here you are on your own to provide sensible values instead of the one read from YAML by Paraconf. -add_executable(exec_file source_files.c) -target_link_libraries(exec_file PDI::PDI_f90) +For example: +```C++ + double duration; +#ifndef WITHOUT_PARACONF + PC_double(PC_get(conf, ".duration"), &duration); +#else + // if we don't have paraconf available, we use 10 as duration, because... why not. + duration = 10; +#endif ``` -## Running an application {#running_app} +You can find a full example of this approach in the `example` directory. -%PDI is a shared library. That means that all environment variables -must be set not only on compilation, but also when running the program. +### The non-invasive way: "MockFind" {#MockFind} -Every used plugin in application needs to be found by %PDI. It will search for -plugins in 4 steps (it will use the first plugin found): +\remark +This is way to mock %PDI that is non-invasive and require zero modification to either your code or cmake files. +However, it is less robust than \ref SubdirMock "the \"SubdirMock\" approach", and does not support mocking Paraconf. +Hence the recommended approach is \ref SubdirMock \"SubdirMock\". -1. `PDI_PLUGIN_PATH` environment variable that is colon separated list with paths, -2. `plugin_path` subtree in specification tree: \ref plugin_path_map_node, -3. Relative path of used %PDI shared object `libpdi.so`, -4. `LD_LIBRARY_PATH` environment variable that is colon separated list. +The only modification you need to make is to add the `PDI_ROOT` option to your CMake command to point to `mock_pdi`: +```bash +cmake --your-usual-cmake-compile-options -DPDI_ROOT="/mock_pdi" +``` + +\warning +"MockFind" only mocks %PDI and not Paraconf, so you still need a functional Paraconf if only to pass the required parameter to `PDI_init`' diff --git a/pdi/docs/_template/header.html b/pdi/docs/_template/header.html index 2b783f9de..ec6ba28c3 100644 --- a/pdi/docs/_template/header.html +++ b/pdi/docs/_template/header.html @@ -37,7 +37,7 @@

the PDI First steps
  • Tutorial
  • PDI example -
  • C API reference +
  • C API reference
  • Specification tree
  • Plugins
  • ⭐Star us on GitHub
  • diff --git a/pdi/docs/_template/layout.xml b/pdi/docs/_template/layout.xml index 7f3b61d99..edb71dc20 100644 --- a/pdi/docs/_template/layout.xml +++ b/pdi/docs/_template/layout.xml @@ -1,68 +1,105 @@ - + + + + - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - + + + + + + + + + + + - + @@ -71,21 +108,162 @@ + - - - - + + + + + + + + + + - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pdi/docs/_template/style.css b/pdi/docs/_template/style.css index 0c31524b5..2e8a46409 100644 --- a/pdi/docs/_template/style.css +++ b/pdi/docs/_template/style.css @@ -1168,19 +1168,22 @@ a[id] position: -webkit-sticky; position: sticky; top: 0; - height: calc(100vh - 5rem); - width: 15rem; + width: 15rem !important; margin: calc(-1.5rem - 2px) 0 0 0; padding: calc(1.5rem + 2px) 0 0 0; } -#doc-content +#container { max-width: 52rem; - padding: 0; margin: 0 15rem 0 0 !important; } +#doc-content +{ + margin: 0 !important; +} + @media (max-width: 68rem) { body diff --git a/pdi/docs/modules.md b/pdi/docs/modules.md deleted file mode 100644 index 0e95dcb67..000000000 --- a/pdi/docs/modules.md +++ /dev/null @@ -1,23 +0,0 @@ -# C API Reference {#modules} - -This is the list of functions for %PDI grouped by category - -
    - - - - -
    -\ref init_final "Initialization and finalization" - -The initialization and finalization part of the API is used to setup %PDI, release its resources and check version information -
    -\ref annotation "Code annotation" - -The code annotation API is the main interface to use in the code -
    -\ref error "Error handling" - -The error handling API supports checking the error status of %PDI -
    -
    diff --git a/pdi/include/pdi.h b/pdi/include/pdi.h index 75e30db46..4e2bf5f3c 100644 --- a/pdi/include/pdi.h +++ b/pdi/include/pdi.h @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (C) 2015-2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) +* Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -62,6 +62,13 @@ #ifdef __cplusplus extern "C" { +#define PDI_UNAVAILABLE_DEPRECATED [[deprecated("PDI_UNAVAILABLE is never used")]] +#define PDI_ERR_CONFIG_DEPRECATED [[deprecated("Use PDI_ERR_SPECTREE instead")]] +#define PDI_ERR_RIGHT_DEPRECATED [[deprecated("Use PDI_ERR_PERMISSION instead")]] +#else +#define PDI_UNAVAILABLE_DEPRECATED +#define PDI_ERR_CONFIG_DEPRECATED +#define PDI_ERR_RIGHT_DEPRECATED #endif /** \addtogroup error @@ -73,27 +80,31 @@ extern "C" { typedef enum PDI_status_e { /// everything went well PDI_OK = 0, - /// on an input call, no such data is available - PDI_UNAVAILABLE, - /// The configuration file is invalid - PDI_ERR_CONFIG, + /// \deprecated PDI_UNAVAILABLE is never used in PDI + // initialize the value to workaround a bug in AppleClang 15 + PDI_UNAVAILABLE PDI_UNAVAILABLE_DEPRECATED = (PDI_OK + 1), + /// Invalid entry in the specification tree + PDI_ERR_SPECTREE, + PDI_ERR_CONFIG PDI_ERR_CONFIG_DEPRECATED = PDI_ERR_SPECTREE, /// A value expression is invalid PDI_ERR_VALUE, /// Tried to load a non-existing plugin PDI_ERR_PLUGIN, /// Implementation limitation (typically an unimplemented feature) PDI_ERR_IMPL, - /// A system error occured (OS, etc.) + /// A system error occurred (OS, etc.) PDI_ERR_SYSTEM, /** A call to a function has been made at a wrong time (e.g. closing an * unopened transaction) */ PDI_ERR_STATE, - /// A conflict of onwership over a content has been raised - PDI_ERR_RIGHT, + /// A conflict of ownership over a content has been raised + PDI_ERR_PERMISSION, + PDI_ERR_RIGHT PDI_ERR_RIGHT_DEPRECATED = PDI_ERR_PERMISSION, /// Invalid type error - PDI_ERR_TYPE - + PDI_ERR_TYPE, + /// The amount of distinct error codes defined. This should always remain last and not be used as an error code + PDI_NB_STATUSES_DEFINED } PDI_status_t; /** Type of a callback function used when an error occurs diff --git a/pdi/include/pdi/error.h b/pdi/include/pdi/error.h index 3ab0f9e5c..9e5243e42 100644 --- a/pdi/include/pdi/error.h +++ b/pdi/include/pdi/error.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2020 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -59,8 +59,8 @@ class PDI_EXPORT Error: public std::exception * \param[in] args the python-style parameters for the message * \see printf */ - template - Error(PDI_status_t errcode, const S& format_str, Args&&... args) + template + inline constexpr Error(PDI_status_t errcode, fmt::format_string format_str, Args&&... args) : m_status{errcode} , m_what{fmt::format(format_str, std::forward(args)...)} {} @@ -79,51 +79,38 @@ class PDI_EXPORT Error: public std::exception PDI_status_t status() const noexcept; }; -class PDI_EXPORT Unavailable_error: public Error +class PDI_EXPORT Spectree_error: public Error { public: - template - Unavailable_error(const S& format_str, Args&&... args) - : Error(PDI_UNAVAILABLE, std::string("Unavailable_error: ") + format_str, std::forward(args)...) - {} - - Unavailable_error(Unavailable_error&&) = default; - - Unavailable_error(const Unavailable_error&) = default; -}; - -class PDI_EXPORT Config_error: public Error -{ -public: - template - Config_error(PC_tree_t tree, const S& format_str, Args&&... args) - : Error(PDI_ERR_CONFIG) + template + Spectree_error(PC_tree_t tree, fmt::format_string format_str, Args&&... args) + : Error(PDI_ERR_SPECTREE) { std::ostringstream err_msg; if (!PC_status(tree) && tree.node) { if (tree.node->start_mark.line == tree.node->end_mark.line) { - err_msg << "Config_error in line " << tree.node->start_mark.line + 1 << ": "; + err_msg << "Spectree_error in line " << tree.node->start_mark.line + 1 << ": "; } else { - err_msg << "Config_error in lines " << tree.node->start_mark.line + 1 << " - " << tree.node->end_mark.line << ": "; + err_msg << "Spectree_error in lines " << tree.node->start_mark.line + 1 << " - " << tree.node->end_mark.line << ": "; } } else { - err_msg << "Config_error: "; + err_msg << "Spectree_error: "; } err_msg << fmt::format(format_str, std::forward(args)...); m_what = err_msg.str(); } - Config_error(Config_error&&) = default; + Spectree_error(Spectree_error&&) = default; - Config_error(const Config_error&) = default; + Spectree_error(const Spectree_error&) = default; }; class PDI_EXPORT Value_error: public Error { public: - template - Value_error(const S& format_str, Args&&... args) - : Error(PDI_ERR_VALUE, std::string("Value_error: ") + format_str, std::forward(args)...) + template + inline constexpr Value_error(fmt::format_string format_str, Args&&... args) + : Error(PDI_ERR_VALUE, "Value_error: {}", fmt::format(format_str, std::forward(args)...)) {} Value_error(Value_error&&) = default; @@ -134,9 +121,9 @@ class PDI_EXPORT Value_error: public Error class PDI_EXPORT Plugin_error: public Error { public: - template - Plugin_error(const S& format_str, Args&&... args) - : Error(PDI_ERR_PLUGIN, std::string("Plugin_error: ") + format_str, std::forward(args)...) + template + inline constexpr Plugin_error(fmt::format_string format_str, Args&&... args) + : Error(PDI_ERR_PLUGIN, "Plugin_error: {}", fmt::format(format_str, std::forward(args)...)) {} Plugin_error(Plugin_error&&) = default; @@ -147,9 +134,9 @@ class PDI_EXPORT Plugin_error: public Error class PDI_EXPORT Impl_error: public Error { public: - template - Impl_error(const S& format_str, Args&&... args) - : Error(PDI_ERR_IMPL, std::string("Impl_error: ") + format_str, std::forward(args)...) + template + inline constexpr Impl_error(fmt::format_string format_str, Args&&... args) + : Error(PDI_ERR_IMPL, "Impl_error: {}", fmt::format(format_str, std::forward(args)...)) {} Impl_error(Impl_error&&) = default; @@ -160,9 +147,9 @@ class PDI_EXPORT Impl_error: public Error class PDI_EXPORT System_error: public Error { public: - template - System_error(const S& format_str, Args&&... args) - : Error(PDI_ERR_SYSTEM, std::string("System_error: ") + format_str, std::forward(args)...) + template + inline constexpr System_error(fmt::format_string format_str, Args&&... args) + : Error(PDI_ERR_SYSTEM, "System_error: {}", fmt::format(format_str, std::forward(args)...)) {} System_error(System_error&&) = default; @@ -173,9 +160,9 @@ class PDI_EXPORT System_error: public Error class PDI_EXPORT State_error: public Error { public: - template - State_error(const S& format_str, Args&&... args) - : Error(PDI_ERR_STATE, std::string("State_error: ") + format_str, std::forward(args)...) + template + inline constexpr State_error(fmt::format_string format_str, Args&&... args) + : Error(PDI_ERR_STATE, "State_error: {}", fmt::format(format_str, std::forward(args)...)) {} State_error(State_error&&) = default; @@ -183,25 +170,25 @@ class PDI_EXPORT State_error: public Error State_error(const State_error&) = default; }; -class PDI_EXPORT Right_error: public Error +class PDI_EXPORT Permission_error: public Error { public: - template - Right_error(const S& format_str, Args&&... args) - : Error(PDI_ERR_RIGHT, std::string("Right_error: ") + format_str, std::forward(args)...) + template + inline constexpr Permission_error(fmt::format_string format_str, Args&&... args) + : Error(PDI_ERR_PERMISSION, "Permission_error: {}", fmt::format(format_str, std::forward(args)...)) {} - Right_error(Right_error&&) = default; + Permission_error(Permission_error&&) = default; - Right_error(const Right_error&) = default; + Permission_error(const Permission_error&) = default; }; class PDI_EXPORT Type_error: public Error { public: - template - Type_error(const S& format_str, Args&&... args) - : Error(PDI_ERR_TYPE, std::string("Type_error: ") + format_str, std::forward(args)...) + template + inline constexpr Type_error(fmt::format_string format_str, Args&&... args) + : Error(PDI_ERR_TYPE, "Type_error: {}", fmt::format(format_str, std::forward(args)...)) {} Type_error(Type_error&&) = default; diff --git a/pdi/include/pdi/expression.h b/pdi/include/pdi/expression.h index 1aa8f3c75..ec2da704c 100644 --- a/pdi/include/pdi/expression.h +++ b/pdi/include/pdi/expression.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -114,7 +114,7 @@ class PDI_EXPORT Expression /** Moves an expression * - * \param[in] expr the expression to move` + * \param[in] expr the expression to move * \return *this */ Expression& operator= (Expression&& expr); @@ -193,7 +193,7 @@ class PDI_EXPORT Expression */ Ref to_ref(Context& ctx, Datatype_sptr type) const; - /** Parses a string that starts with `$` and represents a reference expression + /** Parses a string that starts with `$' and represents a reference expression * * \param[in] reference_str string that represents a reference expression * diff --git a/pdi/include/pdi/logger.h b/pdi/include/pdi/logger.h index d5e87598b..2693fc0ae 100644 --- a/pdi/include/pdi/logger.h +++ b/pdi/include/pdi/logger.h @@ -1,4 +1,5 @@ /******************************************************************************* + * Copyright (C) 2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2018-2022 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -172,7 +173,7 @@ class PDI_EXPORT Logger * \param[in] args arguments for fmt string */ template - void trace(const char* fmt, Args&&... args) + void trace(fmt::format_string fmt, Args&&... args) { m_logger->trace(fmt, std::forward(args)...); } @@ -182,7 +183,7 @@ class PDI_EXPORT Logger * \param[in] args arguments for fmt string */ template - void debug(const char* fmt, Args&&... args) + void debug(fmt::format_string fmt, Args&&... args) { m_logger->debug(fmt, std::forward(args)...); } @@ -192,7 +193,7 @@ class PDI_EXPORT Logger * \param[in] args arguments for fmt string */ template - void info(const char* fmt, Args&&... args) + void info(fmt::format_string fmt, Args&&... args) { m_logger->info(fmt, std::forward(args)...); } @@ -202,7 +203,7 @@ class PDI_EXPORT Logger * \param[in] args arguments for fmt string */ template - void warn(const char* fmt, Args&&... args) + void warn(fmt::format_string fmt, Args&&... args) { m_logger->warn(fmt, std::forward(args)...); } @@ -212,7 +213,7 @@ class PDI_EXPORT Logger * \param[in] args arguments for fmt string */ template - void error(const char* fmt, Args&&... args) + void error(fmt::format_string fmt, Args&&... args) { m_logger->error(fmt, std::forward(args)...); } diff --git a/pdi/include/pdi/ref_any.h b/pdi/include/pdi/ref_any.h index e52c5f6f2..5db583c0f 100644 --- a/pdi/include/pdi/ref_any.h +++ b/pdi/include/pdi/ref_any.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -167,13 +167,13 @@ class PDI_EXPORT Reference_base */ Referenced_data(void* data, std::function freefunc, Datatype_sptr type, bool readable, bool writable) : m_buffer(std::make_shared( - [data, freefunc, type]() { - type->destroy_data(data); - freefunc(data); - }, - readable, - writable - )) + [data, freefunc, type]() { + type->destroy_data(data); + freefunc(data); + }, + readable, + writable + )) , m_data{data} , m_type{type} { @@ -343,6 +343,32 @@ class PDI_EXPORT Ref_any: public Reference_base return m_content == get_content(o); } + bool operator== (const Ref_any& o) const noexcept + { + is_null(); + return m_content == get_content(o); + } + + template + bool operator== (const Ref_any& o) const noexcept + { + is_null(); + return m_content == get_content(o); + } + + bool operator!= (const Ref_any& o) const noexcept + { + is_null(); + return m_content != get_content(o); + } + + template + bool operator!= (const Ref_any& o) const noexcept + { + is_null(); + return m_content != get_content(o); + } + bool operator!= (const Reference_base& o) const noexcept { is_null(); @@ -465,7 +491,7 @@ class PDI_EXPORT Ref_any: public Reference_base */ ref_access_t get() const { - if (is_null()) throw Right_error{"Trying to dereference a null reference"}; + if (is_null()) throw Permission_error{"Trying to dereference a null reference"}; return m_content->m_data; } diff --git a/pdi/include/pdi/testing.h b/pdi/include/pdi/testing.h new file mode 100644 index 000000000..8419dfaba --- /dev/null +++ b/pdi/include/pdi/testing.h @@ -0,0 +1,286 @@ +/******************************************************************************* + * Copyright (C) 2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#ifndef PDI_TESTING_H_ +#define PDI_TESTING_H_ + +// this is a header-only file because we don't want to depend on a given version of gtest/gmock +/** \file + * Tools to help testing %PDI plugins. + * + * To include this, you must link against both gtest & gmock. + * - Let your tests be fixtures using TEST_F and have your fixture class inherit ::PDI::PdiTest . + * - Call ::PDI::PdiTest::InitPdi() to initialize %PDI in your test. + * + * Have a look at Decl'HDF5 plugin `decl_hdf5_tests.cxx` for an example of use. + * + * It offers the following features. + * - If you need to re-init %PDI, you can re-call ::PDI::PdiTest::InitPdi() . + * - If you want to finalize Pdi before you re-initialize it, you can call + * ::PDI::PdiTest::FinalizePdi() + * - ::PDI::make_a() initialize your data to "random" but repeatable values. + * - `EXPECT_CALL(*this, PdiError(errcodeMatcher, errmsgMatcher))` if you expect an error. + * + * Each test will run in a separate directory that's cleaned up after execution, feel free to create + * any file you need there. + * In order to be able to use make_a for your own classes & structures, you'll need to define a + * matching random_init() function. + * + * Some recommendations: + * - Follow gtest naming requirements for the tests: valid C++ identifiers without _ (underscores) + * - Make each test target one feature and test it well. + * - Use standard c++ ::std::filesystem or the plugin underlying library directly to check that what + * you expected actually append. + * - Use C++ types, such as ::std::array vs. int[N]. + * - When defining your own type, make them default constructibel, give them a init_from member + * function, a default comparison operator and a stream output operator. + * - Make the data you expose for writing const as much as possible with the pattern: + * `auto const myvar = make_a()`. + * - Use a separate variable for reading as much as possible, so that you can compare it against the + * unmodified expected value, do not rely on magic constants. + * - When expecting errors, use partial or regex testers for strings to support message improvement. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace PDI { + +/** An object is initializable_from if it can be initalized using the init_from member function + * from a reference of G + */ +template < class T, class G > +concept initializable_from = requires(T t, G& gen) { + { + t.init_from(gen) + }; +}; + +/** An object is buildable_from if it can be constructed using the init_from member function + * from a reference of G + */ +template +concept buildable_from = std::constructible_from && requires(G& g) { + { + T(g) + }; + { + ::new T(g) + }; +}; + +/** initialize an integral value with uniformly distributed values from the provided generator + * \param gen the (pseudo)random generator + * \param t the value to initialize + */ +static inline void random_init(std::uniform_random_bit_generator auto& gen, std::integral auto& t) +{ + using T = std::remove_reference_t; + t = std::uniform_int_distribution(std::numeric_limits::min())(gen); +} + +/** initialize a floating-point value with normally distributed values from the provided generator + * \param gen the (pseudo)random generator + * \param t the value to initialize + */ +static inline void random_init(std::uniform_random_bit_generator auto& gen, std::floating_point auto& t) +{ + t = std::normal_distribution>{}(gen); +} + +/** initialize all elements in an iterable with the provided generator + * \param gen the (pseudo)random generator + * \param t the iterable to initialize + */ +static inline void random_init(std::uniform_random_bit_generator auto& gen, std::ranges::input_range auto& t) +{ + std::for_each(std::begin(t), std::end(t), [&](std::ranges::range_value_t& v) { random_init(gen, v); }); +} + +/** initialize an object that supports `init_from` from the provided generator + * \param gen the (pseudo)random generator + * \param t the object to initialize + */ +static inline void random_init(std::uniform_random_bit_generator auto& gen, initializable_from auto& t) +{ + t.init_from(gen); +} + +/** initialize an object that can be constructed from a generator from the provided generator + * \param gen the (pseudo)random generator + * \param t the object to initialize + */ +template +requires(!std::ranges::input_range && !initializable_from && buildable_from && std::assignable_from) +static inline void random_init(G& gen, T& t) +{ + t = T(gen); +} + +/** make a new randomly-initialized object that can be constructed from a generator + * \param gen the (pseudo)random generator + */ +template +requires buildable_from +static inline T make_random(G& gen) +{ + return T(gen); +} + +/** make a new randomly-initialized object that supports `random_init` + * \param gen the (pseudo)random generator + */ +template +requires(!buildable_from, std::default_initializable) +static inline T make_random(G& gen) +{ + T result; + random_init(gen, result); + return result; +} + +/** The fixture class for PDI plugins testing. + * + * - Each test run in its own directory. + * - offer make_a to create data + * - Takes ownership of PC_tree and handles initialization & finalization of PDI + */ +// this is a header-only class because we don't want to depend on a given version of gtest/gmock +class PdiTest: public ::testing::Test +{ + /// The workdir when the test was launched, we'll go back there after cleaning + std::filesystem::path m_workdir; + + /// The temp directory we created and moved to, we'll remove it when cleaning + std::filesystem::path m_tmpdir; + + /// The configuration provided to PDI, we'll have to destroy it + PC_tree_t m_conf = {PC_NODE_NOT_FOUND, nullptr, nullptr}; + + /// The generator used to initialize data for the test + std::mt19937_64 m_random_generator; + + /// The PDI compatible errhandler we use as an adapter for PdiError + static void s_pdi_errhandler(PDI_status_t status, const char* message, void* context) + { + static_cast(context)->PdiError(status, message); + } + +protected: + PdiTest(); + + ~PdiTest(); + + /** make a new repeatably randomly initialized object + */ + template + inline T make_a() + { + return ::PDI::make_random(m_random_generator); + } + + /** Initialize PDI with the provided PC_tree + * + * Takes ownership of the tree. + * If %PDI was already initialized, finalize it first. + * + * \param tree the tree to initialize from. + */ + inline void InitPdi(PC_tree_t tree); + + /** Finalize PDI + * + * Leaves any file created available until the end of the test + */ + inline void FinalizePdi(); + + MOCK_METHOD(void, PdiError, (PDI_status_t, char const *), (const)); +}; + +PdiTest::PdiTest() + : m_workdir(std::filesystem::canonical(std::filesystem::current_path())) +{ + static thread_local auto random_generator([]() { + if (int gseed = ::testing::UnitTest::GetInstance()->random_seed()) { + return std::mt19937_64(gseed); + } else { + std::random_device source; + std::array random_seed_data; + std::generate(std::begin(random_seed_data), std::end(random_seed_data), std::ref(source)); + std::seed_seq seed(std::begin(random_seed_data), std::end(random_seed_data)); + return std::mt19937_64(seed); + } + }()); + auto const filename = [&]() { + static constexpr char const VALID_FILE_CHARS[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-"; + std::uniform_int_distribution random(0, std::ranges::size(VALID_FILE_CHARS) - 1); + std::string filename(16, '\0'); + std::generate(filename.begin(), filename.end(), [&]() { return VALID_FILE_CHARS[random(random_generator)]; }); + auto&& test_info = *::testing::UnitTest::GetInstance()->current_test_info(); + return std::string("pdi_tst_dir.") + test_info.test_suite_name() + "." + test_info.name() + "." + filename; + }(); + m_tmpdir = m_workdir / filename; + std::filesystem::create_directory(m_tmpdir); + std::filesystem::current_path(m_tmpdir); + EXPECT_CALL(*this, PdiError(testing::_, testing::_)).Times(0); +} + +inline void PdiTest::InitPdi(PC_tree_t tree) +{ + FinalizePdi(); + m_conf = tree; + ASSERT_EQ(PC_OK, PC_status(m_conf)); + ASSERT_EQ(PDI_OK, PDI_init(m_conf)); + PDI_errhandler({s_pdi_errhandler, this}); +} + +inline void PdiTest::FinalizePdi() +{ + if (!PC_status(m_conf)) { + ASSERT_EQ(PDI_OK, PDI_finalize()); + EXPECT_EQ(PC_OK, PC_tree_destroy(&m_conf)); + m_conf = {PC_NODE_NOT_FOUND, nullptr, nullptr}; + } +} + +inline PdiTest::~PdiTest() +{ + FinalizePdi(); + std::filesystem::current_path(m_workdir); + std::filesystem::remove_all(m_tmpdir); +} + + +} // namespace PDI + +#endif diff --git a/pdi/src/array_datatype.cxx b/pdi/src/array_datatype.cxx index a534d7c81..e8f7f97f0 100644 --- a/pdi/src/array_datatype.cxx +++ b/pdi/src/array_datatype.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -46,7 +46,6 @@ using std::align; using std::endl; using std::make_shared; using std::max; -using std::move; using std::pair; using std::regex; using std::regex_replace; @@ -61,14 +60,14 @@ using std::vector; Array_datatype::Array_datatype(Datatype_sptr subtype, size_t size, size_t start, size_t subsize, const Attributes_map& attributes) : Datatype(attributes) - , m_subtype{move(subtype)} - , m_size{move(size)} - , m_start{move(start)} - , m_subsize{move(subsize)} + , m_subtype{std::move(subtype)} + , m_size{std::move(size)} + , m_start{std::move(start)} + , m_subsize{std::move(subsize)} {} Array_datatype::Array_datatype(Datatype_sptr subtype, size_t size, const Attributes_map& attributes) - : Array_datatype{move(subtype), size, 0, move(size), attributes} + : Array_datatype{std::move(subtype), size, 0, std::move(size), attributes} {} Datatype_sptr Array_datatype::subtype() const diff --git a/pdi/src/callbacks.cxx b/pdi/src/callbacks.cxx index bafc27da1..8d33606ed 100644 --- a/pdi/src/callbacks.cxx +++ b/pdi/src/callbacks.cxx @@ -1,4 +1,5 @@ /******************************************************************************* + * Copyright (C) 2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -156,7 +157,7 @@ void Callbacks::call_data_callbacks(const string& name, Ref ref) const for (auto&& err: errors) { errmsg += string(err.what()) + "\n"; } - throw System_error{errmsg.c_str()}; + throw System_error{"{}", errmsg.c_str()}; } } @@ -195,7 +196,7 @@ void Callbacks::call_data_remove_callbacks(const string& name, Ref ref) const for (auto&& err: errors) { errmsg += string(err.what()) + "\n"; } - throw System_error{errmsg.c_str()}; + throw System_error{"{}", errmsg.c_str()}; } } @@ -234,7 +235,7 @@ void Callbacks::call_event_callbacks(const string& name) const for (auto&& err: errors) { errmsg += string(err.what()) + "\n"; } - throw System_error{errmsg.c_str()}; + throw System_error{"{}", errmsg.c_str()}; } } @@ -273,7 +274,7 @@ void Callbacks::call_empty_desc_access_callbacks(const string& name) const for (auto&& err: errors) { errmsg += string(err.what()) + "\n"; } - throw System_error{errmsg.c_str()}; + throw System_error{"{}", errmsg.c_str()}; } } diff --git a/pdi/src/context.cxx b/pdi/src/context.cxx index f194048b1..56805749e 100644 --- a/pdi/src/context.cxx +++ b/pdi/src/context.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2019 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,7 +38,6 @@ namespace PDI { -using std::move; using std::string; using std::unique_ptr; using std::unordered_map; @@ -48,7 +47,7 @@ Context::Iterator::Iterator(const unordered_map>::iterator&& data) - : m_data(move(data)) + : m_data(std::move(data)) {} Data_descriptor* Context::Iterator::operator->() @@ -84,7 +83,7 @@ Context::Iterator Context::get_iterator(const std::unordered_map>::iterator&& data) { - return move(data); + return std::move(data); } Context::~Context() = default; diff --git a/pdi/src/context_proxy.cxx b/pdi/src/context_proxy.cxx index 1e6e2b5fa..c7177acd4 100644 --- a/pdi/src/context_proxy.cxx +++ b/pdi/src/context_proxy.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2019-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -27,7 +27,6 @@ #include "pdi/context_proxy.h" #include "pdi/logger.h" -using std::move; using std::string; namespace PDI { @@ -99,12 +98,12 @@ Logger& Context_proxy::pdi_core_logger() Datatype_template_sptr Context_proxy::datatype(PC_tree_t node) { - return m_real_context.datatype(move(node)); + return m_real_context.datatype(std::move(node)); } void Context_proxy::add_datatype(const string& name, Datatype_template_parser parser) { - m_real_context.add_datatype(name, move(parser)); + m_real_context.add_datatype(name, std::move(parser)); } Callbacks& Context_proxy::callbacks() diff --git a/pdi/src/data_descriptor_impl.cxx b/pdi/src/data_descriptor_impl.cxx index 8cd1d2afa..5916db179 100644 --- a/pdi/src/data_descriptor_impl.cxx +++ b/pdi/src/data_descriptor_impl.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -97,7 +97,7 @@ Data_descriptor_impl::~Data_descriptor_impl() void Data_descriptor_impl::default_type(Datatype_template_sptr type) { - m_type = move(type); + m_type = std::move(type); } Datatype_template_sptr Data_descriptor_impl::default_type() @@ -174,7 +174,7 @@ try { assert((!metadata() || !m_refs.empty()) && "metadata descriptors should always keep a placeholder"); // metadata must provide read access if (metadata() && !Ref_r(data_ref)) { - throw Right_error{"Metadata sharing must offer read access"}; + throw Permission_error{"Metadata sharing must offer read access"}; } // make a reference and put it in the store @@ -198,12 +198,12 @@ try { if (data_ref && !ref()) { m_refs.pop(); - throw Right_error{"Unable to grant requested rights"}; + throw Permission_error{"Unable to grant requested rights"}; } try { m_context.callbacks().call_data_callbacks(m_name, ref()); - } catch (const exception&) { + } catch (...) { m_refs.pop(); throw; } diff --git a/pdi/src/datatype_template.cxx b/pdi/src/datatype_template.cxx index 380f0417e..6f3ea6c00 100644 --- a/pdi/src/datatype_template.cxx +++ b/pdi/src/datatype_template.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -51,7 +51,6 @@ namespace PDI { using std::exception; using std::make_shared; using std::max; -using std::move; using std::string; using std::transform; using std::unique_ptr; @@ -116,18 +115,18 @@ class Array_template: public Datatype_template public: Array_template(Datatype_template_sptr subtype, Expression size, Expression start, Expression subsize, PC_tree_t datatype_tree) : Datatype_template(datatype_tree) - , m_subtype{move(subtype)} - , m_size{move(size)} - , m_start{move(start)} - , m_subsize{move(subsize)} + , m_subtype{std::move(subtype)} + , m_size{std::move(size)} + , m_start{std::move(start)} + , m_subsize{std::move(subsize)} {} Array_template(Datatype_template_sptr subtype, Expression size, Expression start, Expression subsize, const Attributes_map& attributes = {}) : Datatype_template(attributes) - , m_subtype{move(subtype)} - , m_size{move(size)} - , m_start{move(start)} - , m_subsize{move(subsize)} + , m_subtype{std::move(subtype)} + , m_size{std::move(size)} + , m_start{std::move(start)} + , m_subsize{std::move(subsize)} {} Datatype_sptr evaluate(Context& ctx) const override @@ -155,9 +154,9 @@ class Record_template: public Datatype_template string m_name; Member(Expression disp, Datatype_template_sptr type, string name) - : m_displacement{move(disp)} - , m_type{move(type)} - , m_name{move(name)} + : m_displacement{std::move(disp)} + , m_type{std::move(type)} + , m_name{std::move(name)} {} Member(const Member& o) @@ -177,14 +176,14 @@ class Record_template: public Datatype_template public: Record_template(vector&& members, Expression&& size, PC_tree_t datatype_tree) : Datatype_template(datatype_tree) - , m_members{move(members)} - , m_buffersize{move(size)} + , m_members{std::move(members)} + , m_buffersize{std::move(size)} {} Record_template(vector&& members, Expression&& size, const Attributes_map& attributes = {}) : Datatype_template(attributes) - , m_members{move(members)} - , m_buffersize{move(size)} + , m_members{std::move(members)} + , m_buffersize{std::move(size)} {} Datatype_sptr evaluate(Context& ctx) const override @@ -193,7 +192,7 @@ class Record_template: public Datatype_template for (auto&& member: m_members) { evaluated_members.emplace_back(member.m_displacement.to_long(ctx), member.m_type->evaluate(ctx), member.m_name); } - return Record_datatype::make(move(evaluated_members), static_cast(m_buffersize.to_long(ctx)), m_attributes); + return Record_datatype::make(std::move(evaluated_members), static_cast(m_buffersize.to_long(ctx)), m_attributes); } }; @@ -206,8 +205,8 @@ class Struct_template: public Datatype_template string m_name; Member(Datatype_template_sptr type, string name) - : m_type{move(type)} - , m_name{move(name)} + : m_type{std::move(type)} + , m_name{std::move(name)} {} Member(const Member& o) @@ -240,7 +239,7 @@ class Struct_template: public Datatype_template size_t alignment = member_type->alignment(); // align the next member as requested displacement += (alignment - (displacement % alignment)) % alignment; - evaluated_members.emplace_back(displacement, move(member_type), member.m_name); + evaluated_members.emplace_back(displacement, std::move(member_type), member.m_name); displacement += evaluated_members.back().type()->buffersize(); struct_alignment = max(struct_alignment, alignment); } @@ -249,7 +248,7 @@ class Struct_template: public Datatype_template // ensure the record size is at least 1 to have a unique address displacement = max(1, displacement); - return Record_datatype::make(move(evaluated_members), displacement, m_attributes); + return Record_datatype::make(std::move(evaluated_members), displacement, m_attributes); } }; @@ -286,7 +285,7 @@ class Tuple_template: public Datatype_template * \param[in] type type of the element */ Element(Datatype_template_sptr type) - : m_type{move(type)} + : m_type{std::move(type)} {} /** Creates new Element template with only type defined @@ -295,8 +294,8 @@ class Tuple_template: public Datatype_template * \param[in] type type of the element */ Element(Expression disp, Datatype_template_sptr type) - : m_displacement{move(disp)} - , m_type{move(type)} + : m_displacement{std::move(disp)} + , m_type{std::move(type)} {} /** Creates a copy of an element template @@ -319,19 +318,19 @@ class Tuple_template: public Datatype_template public: Tuple_template(vector&& elements, PC_tree_t datatype_tree) : Datatype_template(datatype_tree) - , m_elements{move(elements)} + , m_elements{std::move(elements)} {} Tuple_template(vector&& elements, Expression&& size, PC_tree_t datatype_tree) : Datatype_template(datatype_tree) - , m_elements{move(elements)} - , m_buffersize{move(size)} + , m_elements{std::move(elements)} + , m_buffersize{std::move(size)} {} Tuple_template(vector&& elements, Expression&& size, const Attributes_map& attributes = {}) : Datatype_template(attributes) - , m_elements{move(elements)} - , m_buffersize{move(size)} + , m_elements{std::move(elements)} + , m_buffersize{std::move(size)} {} Datatype_sptr evaluate(Context& ctx) const override @@ -353,7 +352,7 @@ class Tuple_template: public Datatype_template size_t alignment = element_type->alignment(); // align the next element as requested displacement += (alignment - (displacement % alignment)) % alignment; - evaluated_elements.emplace_back(displacement, move(element_type)); + evaluated_elements.emplace_back(displacement, std::move(element_type)); displacement += evaluated_elements.back().type()->buffersize(); tuple_alignment = max(tuple_alignment, alignment); } @@ -366,7 +365,7 @@ class Tuple_template: public Datatype_template } - return Tuple_datatype::make(move(evaluated_elements), tuple_buffersize, m_attributes); + return Tuple_datatype::make(std::move(evaluated_elements), tuple_buffersize, m_attributes); } }; @@ -391,10 +390,10 @@ vector get_array_property(PC_tree_t node, string property) void validate_array(PC_tree_t node, vector& size, vector& subsize, vector& start) { if (size.empty()) { - throw Config_error{node, "Array must have defined `size'"}; + throw Spectree_error{node, "Array must have defined `size'"}; } if (!start.empty() && subsize.empty()) { - throw Config_error{node, "Array with a `start` property must have a defined `subsize'"}; + throw Spectree_error{node, "Array with a `start` property must have a defined `subsize'"}; //TODO: handle by setting subsize to size-start } if (start.empty()) { @@ -406,10 +405,10 @@ void validate_array(PC_tree_t node, vector& size, vector //check if rank of array is correct if (size.size() != subsize.size()) { - throw Config_error{node, "`subsize' must have the same rank as `size': {} != {}", subsize.size(), size.size()}; + throw Spectree_error{node, "`subsize' must have the same rank as `size': {} != {}", subsize.size(), size.size()}; } if (size.size() != start.size()) { - throw Config_error{node, "`start' must have the same rank as `size': {} != {}", start.size(), size.size()}; + throw Spectree_error{node, "`start' must have the same rank as `size': {} != {}", start.size(), size.size()}; } } @@ -420,7 +419,7 @@ Datatype_template_sptr to_array_datatype_template(Context& ctx, PC_tree_t node) if (order_str == "c" && order_str == "C") { ctx.logger().warn("`order: C' for array is the only supported order and its specification is deprecated"); } else if (order_str != "") { - throw Config_error{node, "Incorrect array ordering: `{}', only C order is supported", order_str}; + throw Spectree_error{node, "Incorrect array ordering: `{}', only C order is supported", order_str}; } } @@ -432,13 +431,15 @@ Datatype_template_sptr to_array_datatype_template(Context& ctx, PC_tree_t node) PC_tree_t config_elem = PC_get(node, ".subtype"); if (PC_status(config_elem)) { - throw Config_error{node, "Array must have `subtype'"}; + throw Spectree_error{node, "Array must have `subtype'"}; } Datatype_template_sptr res_type = ctx.datatype(config_elem); for (ssize_t ii = array_size.size() - 1; ii >= 0; --ii) { - res_type.reset(new Array_template(move(res_type), move(array_size[ii]), move(array_start[ii]), move(array_subsize[ii]), node)); + res_type.reset( + new Array_template(std::move(res_type), std::move(array_size[ii]), std::move(array_start[ii]), std::move(array_subsize[ii]), node) + ); } return res_type; } @@ -463,22 +464,22 @@ vector get_tuple_elements(Context& ctx, PC_tree_t eleme result.emplace_back(disp, ctx.datatype(element_node)); } } else { - throw Config_error{elements_node, "Tuple elements subtree must be a seqence or ordered mapping"}; + throw Spectree_error{elements_node, "Tuple elements subtree must be a seqence or ordered mapping"}; } // check if non or all of elements have diplacement defined if (displacement_counter != 0 && displacement_counter != nb_elements) { - throw Config_error{elements_node, "None or all of tuple elements must to have `disp' defined"}; + throw Spectree_error{elements_node, "None or all of tuple elements must to have `disp' defined"}; } // buffersize defined, but no displacement in elements if (buffersize_defined && displacement_counter == 0) { - throw Config_error{elements_node, "If tuple buffersize is defined, all `disp' must be defined also"}; + throw Spectree_error{elements_node, "If tuple buffersize is defined, all `disp' must be defined also"}; } // buffersize not defined, but displacement is defined in elements if (!buffersize_defined && displacement_counter != 0) { - throw Config_error{elements_node, "If tuple buffersize is not defined, `disp' cannot be defined also"}; + throw Spectree_error{elements_node, "If tuple buffersize is not defined, `disp' cannot be defined also"}; } return result; @@ -494,11 +495,11 @@ Datatype_template_sptr to_tuple_datatype_template(Context& ctx, PC_tree_t node) PC_tree_t elements_node = PC_get(node, ".elements"); if (PC_status(elements_node)) { - throw Config_error{node, "Tuple datatype must have `elements' subtree"}; + throw Spectree_error{node, "Tuple datatype must have `elements' subtree"}; } bool tuple_buffersize_defined = static_cast(tuple_buffersize); return unique_ptr{ - new Tuple_template{get_tuple_elements(ctx, elements_node, tuple_buffersize_defined), move(tuple_buffersize), node} + new Tuple_template{get_tuple_elements(ctx, elements_node, tuple_buffersize_defined), std::move(tuple_buffersize), node} }; } @@ -516,11 +517,11 @@ vector get_members(Context& ctx, PC_tree_t member_list_ PC_tree_t disp_conf = PC_get(member_node, ".disp"); if (PC_status(disp_conf)) { - throw Config_error{member_node, "All members must have displacements"}; + throw Spectree_error{member_node, "All members must have displacements"}; } Expression disp = to_string(disp_conf); - members.emplace_back(move(disp), ctx.datatype(member_node), move(member_name)); + members.emplace_back(std::move(disp), ctx.datatype(member_node), std::move(member_name)); } return members; } @@ -529,13 +530,13 @@ Datatype_template_sptr to_record_datatype_template(Context& ctx, PC_tree_t node) { PC_tree_t buffersize_conf = PC_get(node, ".buffersize"); if (PC_status(buffersize_conf)) { - throw Config_error{node, "Record must have defined buffersize"}; + throw Spectree_error{node, "Record must have defined buffersize"}; } Expression record_buffersize = to_string(buffersize_conf); PC_tree_t member_list_node = PC_get(node, ".members"); - return unique_ptr{new Record_template{get_members(ctx, member_list_node), move(record_buffersize), node}}; + return unique_ptr{new Record_template{get_members(ctx, member_list_node), std::move(record_buffersize), node}}; } Datatype_template_sptr to_struct_datatype_template(Context& ctx, PC_tree_t node) @@ -551,7 +552,7 @@ Datatype_template_sptr to_pointer_datatype_template(Context& ctx, PC_tree_t node { PC_tree_t subtype_conf = PC_get(node, ".subtype"); if (PC_status(subtype_conf)) { - throw Config_error{node, "Pointer must have defined subtype"}; + throw Spectree_error{node, "Pointer must have defined subtype"}; } return unique_ptr{new Pointer_template{ctx.datatype(subtype_conf), node}}; } @@ -726,7 +727,7 @@ void Datatype_template::load_basic_datatypes(Context& ctx) if (kind == 0) kind = PDI_CHARACTER_DEFAULT_KIND; else if (kind < 0) - throw Config_error{PC_get(tree, ".kind"), "`kind' of the datatype cannot be less than 0"}; + throw Spectree_error{PC_get(tree, ".kind"), "`kind' of the datatype cannot be less than 0"}; return Datatype_template_sptr{new Scalar_template{Scalar_kind::UNSIGNED, kind, tree}}; }); ctx.add_datatype("integer", [](Context&, PC_tree_t tree) { @@ -734,7 +735,7 @@ void Datatype_template::load_basic_datatypes(Context& ctx) if (kind == 0) kind = PDI_INTEGER_DEFAULT_KIND; else if (kind < 0) - throw Config_error{PC_get(tree, ".kind"), "`kind' of the datatype cannot be less than 0"}; + throw Spectree_error{PC_get(tree, ".kind"), "`kind' of the datatype cannot be less than 0"}; return Datatype_template_sptr{new Scalar_template{Scalar_kind::SIGNED, kind, tree}}; }); ctx.add_datatype("logical", [](Context&, PC_tree_t tree) { @@ -742,7 +743,7 @@ void Datatype_template::load_basic_datatypes(Context& ctx) if (kind == 0) kind = PDI_LOGICAL_DEFAULT_KIND; else if (kind < 0) - throw Config_error{PC_get(tree, ".kind"), "`kind' of the datatype cannot be less than 0"}; + throw Spectree_error{PC_get(tree, ".kind"), "`kind' of the datatype cannot be less than 0"}; return Datatype_template_sptr{new Scalar_template{Scalar_kind::UNSIGNED, kind, tree}}; }); ctx.add_datatype("real", [](Context&, PC_tree_t tree) { @@ -750,7 +751,7 @@ void Datatype_template::load_basic_datatypes(Context& ctx) if (kind == 0) kind = PDI_REAL_DEFAULT_KIND; else if (kind < 0) - throw Config_error{PC_get(tree, ".kind"), "`kind' of the datatype cannot be less than 0"}; + throw Spectree_error{PC_get(tree, ".kind"), "`kind' of the datatype cannot be less than 0"}; return Datatype_template_sptr{new Scalar_template{Scalar_kind::FLOAT, kind, tree}}; }); #endif // BUILD_FORTRAN diff --git a/pdi/src/expression.cxx b/pdi/src/expression.cxx index 27b00ceaa..408d09092 100644 --- a/pdi/src/expression.cxx +++ b/pdi/src/expression.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -49,11 +49,10 @@ namespace PDI { -using std::move; using std::unique_ptr; Expression::Expression(std::unique_ptr impl) - : m_impl(move(impl)) + : m_impl(std::move(impl)) {} Expression::Expression() = default; @@ -163,7 +162,7 @@ std::pair Expression::parse_reference(const char* reference_st { const char* reference_str_to_parse = reference_str; unique_ptr reference_impl = Expression::Impl::Reference_expression::parse(&reference_str_to_parse); - return {move(reference_impl), reference_str_to_parse - reference_str}; + return {std::move(reference_impl), reference_str_to_parse - reference_str}; } } // namespace PDI diff --git a/pdi/src/expression/impl/mapping.cxx b/pdi/src/expression/impl/mapping.cxx index a152839af..476ba9487 100644 --- a/pdi/src/expression/impl/mapping.cxx +++ b/pdi/src/expression/impl/mapping.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -44,7 +44,6 @@ namespace PDI { using std::dynamic_pointer_cast; using std::make_shared; using std::max; -using std::move; using std::string; using std::unique_ptr; using std::unordered_map; @@ -104,7 +103,7 @@ Ref Expression::Impl::Mapping::to_ref(Context& ctx) const //add padding at the end of record displacement += (record_alignment - (displacement % record_alignment)) % record_alignment; - return Impl::to_ref(ctx, Record_datatype::make(move(members), displacement)); + return Impl::to_ref(ctx, Record_datatype::make(std::move(members), displacement)); } size_t Expression::Impl::Mapping::copy_value(Context& ctx, void* buffer, Datatype_sptr type) const diff --git a/pdi/src/expression/impl/operation.cxx b/pdi/src/expression/impl/operation.cxx index df6583558..9d44fc7e5 100644 --- a/pdi/src/expression/impl/operation.cxx +++ b/pdi/src/expression/impl/operation.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2020-2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -428,7 +428,7 @@ unique_ptr Expression::Impl::Operation::parse(char const ** va while (op_level(exprval) == level) { if (!expr) { expr.reset(new Operation); - expr->m_first_operand = move(result); + expr->m_first_operand = std::move(result); } Operator oper = parse_operator(&exprval, level); expr->m_operands.emplace_back(oper, Expression{parse(&exprval, level + 1)}); diff --git a/pdi/src/expression/impl/reference_expression.cxx b/pdi/src/expression/impl/reference_expression.cxx index bc93591d5..c89f9ee93 100644 --- a/pdi/src/expression/impl/reference_expression.cxx +++ b/pdi/src/expression/impl/reference_expression.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2020-2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -153,7 +153,7 @@ long Expression::Impl::Reference_expression::to_long(Context& ctx) const if (Ref_r ref = to_ref(ctx)) { return ref.scalar_value(); } - throw Right_error{"Unable to grant access for value reference"}; + throw Permission_error{"Unable to grant access for value reference"}; } catch (const Error& e) { throw Error{e.status(), "while referencing `{}': {}", m_referenced, e.what()}; } @@ -165,7 +165,7 @@ double Expression::Impl::Reference_expression::to_double(Context& ctx) const if (Ref_r ref = to_ref(ctx)) { return ref.scalar_value(); } - throw Right_error{"Unable to grant read access for value reference"}; + throw Permission_error{"Unable to grant read access for value reference"}; } catch (const Error& e) { throw Error{e.status(), "while referencing `{}': {}", m_referenced, e.what()}; } @@ -180,7 +180,7 @@ std::string Expression::Impl::Reference_expression::to_string(Context& ctx) cons if (scal_type->datasize() == 1 && (scal_type->kind() == Scalar_kind::SIGNED || scal_type->kind() == Scalar_kind::UNSIGNED)) { result = string{static_cast(raw_data.get()), referenced_type->size()}; if (!m_fmt_format.empty()) { - result = fmt::format("{" + m_fmt_format + "}", result.c_str()); + result = fmt::format(fmt::runtime("{" + m_fmt_format + "}"), result.c_str()); } } } else { @@ -195,7 +195,7 @@ std::string Expression::Impl::Reference_expression::to_string(Context& ctx) cons ss_result << lres; result = ss_result.str(); } else { - result = fmt::format("{" + m_fmt_format + "}", lres); + result = fmt::format(fmt::runtime("{" + m_fmt_format + "}"), lres); } } else { if (m_fmt_format.empty()) { @@ -203,7 +203,7 @@ std::string Expression::Impl::Reference_expression::to_string(Context& ctx) cons ss_result << setprecision(17) << dres; result = ss_result.str(); } else { - result = fmt::format("{" + m_fmt_format + "}", dres); + result = fmt::format(fmt::runtime("{" + m_fmt_format + "}"), dres); } } } diff --git a/pdi/src/expression/impl/sequence.cxx b/pdi/src/expression/impl/sequence.cxx index ec99e17af..fa4bce724 100644 --- a/pdi/src/expression/impl/sequence.cxx +++ b/pdi/src/expression/impl/sequence.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -43,7 +43,6 @@ namespace PDI { using std::dynamic_pointer_cast; using std::max; -using std::move; using std::string; using std::unique_ptr; using std::vector; @@ -129,7 +128,7 @@ Ref Expression::Impl::Sequence::to_ref(Context& ctx) const // ensure the tuple size is at least 1 to have a unique address displacement = max(1, displacement); - result_type = Tuple_datatype::make(move(tuple_elements), displacement); + result_type = Tuple_datatype::make(std::move(tuple_elements), displacement); } return Impl::to_ref(ctx, result_type); diff --git a/pdi/src/global_context.cxx b/pdi/src/global_context.cxx index 0550fd248..3e06b52a7 100644 --- a/pdi/src/global_context.cxx +++ b/pdi/src/global_context.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -206,12 +206,12 @@ Datatype_template_sptr Global_context::datatype(PC_tree_t node) if (func_it != m_datatype_parsers.end()) { return (func_it->second)(*this, node); } - throw Config_error{node, "Unknown data type: `{}'", type}; + throw Spectree_error{node, "Unknown data type: `{}'", type}; } void Global_context::add_datatype(const string& name, Datatype_template_parser parser) { - if (!m_datatype_parsers.emplace(name, move(parser)).second) { + if (!m_datatype_parsers.emplace(name, std::move(parser)).second) { //if a datatype with the given name already exists throw Type_error{"Datatype already defined `{}'", name}; } diff --git a/pdi/src/paraconf_wrapper.cxx b/pdi/src/paraconf_wrapper.cxx index b75c4c8e3..6840165a3 100644 --- a/pdi/src/paraconf_wrapper.cxx +++ b/pdi/src/paraconf_wrapper.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,7 +37,7 @@ namespace { void do_pc(PC_tree_t tree, PC_status_t status) { if (status) { - throw Config_error{tree, "Configuration error #{}: {}", static_cast(status), PC_errmsg()}; + throw Spectree_error{tree, "Configuration error #{}: {}", static_cast(status), PC_errmsg()}; } } @@ -171,19 +171,19 @@ void each_in_omap(PC_tree_t tree, std::function oper int nb_elem = len(tree); if (!is_list(tree)) { if (is_scalar(tree)) { - throw Config_error{tree, "Expected an ordered mapping, found a scalar"}; + throw Spectree_error{tree, "Expected an ordered mapping, found a scalar"}; } else if (is_map(tree)) { - throw Config_error{tree, "Expected an ordered mapping, found a (unordered) mapping"}; + throw Spectree_error{tree, "Expected an ordered mapping, found a (unordered) mapping"}; } else { - throw Config_error{tree, "Expected an ordered mapping, invalid element found"}; + throw Spectree_error{tree, "Expected an ordered mapping, invalid element found"}; } } for (int elem_id = 0; elem_id < nb_elem; ++elem_id) { PC_tree_t elem = PC_get(tree, "[%d]", elem_id); if (!is_map(elem)) { - throw Config_error{elem, "Invalid ordered mapping found (no key)"}; + throw Spectree_error{elem, "Invalid ordered mapping found (no key)"}; } else if (len(elem) != 1) { - throw Config_error{elem, "Invalid ordered mapping found (multiple keys)"}; + throw Spectree_error{elem, "Invalid ordered mapping found (multiple keys)"}; } operation(PC_get(elem, "{0}"), PC_get(elem, "<0>")); } diff --git a/pdi/src/pdi.cxx b/pdi/src/pdi.cxx index 2b9824ca4..03ed040f7 100644 --- a/pdi/src/pdi.cxx +++ b/pdi/src/pdi.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -53,7 +53,6 @@ using std::endl; using std::exception; using std::list; using std::make_shared; -using std::move; using std::setfill; using std::setw; using std::stack; @@ -126,7 +125,7 @@ void assert_status(PDI_status_t status, const char* message, void*) { if (status) { if (Global_context::initialized()) { - Global_context::context().logger().error(message); + Global_context::context().logger().error("{}", message); } else { cerr << "[PDI][NOINIT] *** Fatal error: " << message << endl; } @@ -139,7 +138,7 @@ void assert_status(PDI_status_t status, const char* message, void*) void warn_status(PDI_status_t status, const char* message, void*) { if (status && Global_context::initialized()) { - Global_context::context().logger().warn(message); + Global_context::context().logger().warn("{}", message); } } @@ -216,7 +215,7 @@ try { PDI_VERSION_PATCH }; } - Global_context::context().logger().trace("PDI API version: {}.{}.{}"); + Global_context::context().logger().trace("PDI API version: {}.{}.{}", PDI_VERSION_MAJOR, PDI_VERSION_MINOR, PDI_VERSION_PATCH); return PDI_OK; } catch (const Error& e) { return g_error_context.return_err(e); diff --git a/pdi/src/plugin_store.cxx b/pdi/src/plugin_store.cxx index c1a63f883..95cb4ea05 100644 --- a/pdi/src/plugin_store.cxx +++ b/pdi/src/plugin_store.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -167,7 +167,7 @@ void Plugin_store::initialize_path(PC_tree_t plugin_path_node) m_ctx.logger().trace("Adding plugin path from yaml: `{}'", PDI::to_string(plugin_path_node)); m_plugin_path.push_back(PDI::to_string(plugin_path_node)); } else { - throw Config_error{plugin_path_node, "plugin_path must be a single path or an array of paths"}; + throw Spectree_error{plugin_path_node, "plugin_path must be a single path or an array of paths"}; } } @@ -202,7 +202,7 @@ void* Plugin_store::plugin_dlopen(const std::string& plugin_name) } else { const string error_msg = dlerror(); m_ctx.logger().debug("Unable to load `{}' {}", libname, error_msg); - load_errors.push_back(format("\n * unable to load `{}' {}", libname, error_msg)); + load_errors.push_back(fmt::format("\n * unable to load `{}' {}", libname, error_msg)); } } @@ -217,7 +217,7 @@ void* Plugin_store::plugin_dlopen(const std::string& plugin_name) } else { const string error_msg = dlerror(); m_ctx.logger().debug("Unable to load `{}' relative to system path {}", libname, error_msg); - load_errors.push_back(format("\n * unable to load `{}' relative to system path {}", libname, error_msg)); + load_errors.push_back(fmt::format("\n * unable to load `{}' relative to system path {}", libname, error_msg)); } } @@ -231,7 +231,7 @@ void* Plugin_store::plugin_dlopen(const std::string& plugin_name) } else { const string error_msg = dlerror(); m_ctx.logger().debug("Unable to load `{}' from system path {}", libname, error_msg); - load_errors.push_back(format("\n * unable to load `{}' from system path {}", libname, error_msg)); + load_errors.push_back(fmt::format("\n * unable to load `{}' from system path {}", libname, error_msg)); } throw Plugin_error{"Unable to load plugin `{}': {}", plugin_name, join(load_errors, ", ")}; diff --git a/pdi/src/pointer_datatype.cxx b/pdi/src/pointer_datatype.cxx index 548391e31..fc0bc2189 100644 --- a/pdi/src/pointer_datatype.cxx +++ b/pdi/src/pointer_datatype.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -39,7 +39,6 @@ using std::dynamic_pointer_cast; using std::endl; using std::function; using std::make_shared; -using std::move; using std::pair; using std::shared_ptr; using std::static_pointer_cast; @@ -50,7 +49,7 @@ using std::vector; Pointer_datatype::Pointer_datatype(Datatype_sptr subtype, const Attributes_map& attributes) : Datatype(attributes) - , m_subtype{move(subtype)} + , m_subtype{std::move(subtype)} {} Pointer_datatype::Pointer_datatype( @@ -60,9 +59,9 @@ Pointer_datatype::Pointer_datatype( const Attributes_map& attributes ) : Datatype(attributes) - , m_subtype{move(subtype)} - , m_copy{move(copy)} - , m_destroy{move(destroy)} + , m_subtype{std::move(subtype)} + , m_copy{std::move(copy)} + , m_destroy{std::move(destroy)} {} Datatype_sptr Pointer_datatype::subtype() const diff --git a/pdi/src/python/pdi.cxx b/pdi/src/python/pdi.cxx index 4299f2e23..347e255e8 100644 --- a/pdi/src/python/pdi.cxx +++ b/pdi/src/python/pdi.cxx @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +* Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -60,7 +60,6 @@ using pyobj = pybind11::object; // using pystr = pybind11::str; using pytup = pybind11::tuple; using namespace pybind11::literals; -using std::move; using std::vector; /** Check API version of PDI and python diff --git a/pdi/src/python/python_ref_wrapper.cxx b/pdi/src/python/python_ref_wrapper.cxx index 3bf1dea76..d4a093f61 100644 --- a/pdi/src/python/python_ref_wrapper.cxx +++ b/pdi/src/python/python_ref_wrapper.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -135,7 +135,7 @@ void Python_ref_wrapper::setattribute(std::string member_name, const pybind11::o throw Type_error{"Setting a member ({}) of record type is unsupported", member_name}; } } else { - throw Right_error{"Cannot set member that is read only: {}", member_name}; + throw Permission_error{"Cannot set member that is read only: {}", member_name}; } } diff --git a/pdi/src/python/tools.cxx b/pdi/src/python/tools.cxx index 5da838c44..7d85f9120 100644 --- a/pdi/src/python/tools.cxx +++ b/pdi/src/python/tools.cxx @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +* Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -165,7 +165,7 @@ Datatype_sptr python_type(const pybind11::array& a) Datatype_sptr result = Scalar_datatype::make(k, static_cast(a.dtype().itemsize())); for (int ii = a.ndim() - 1; ii >= 0; --ii) { - result = Array_datatype::make(move(result), sizes[ii], 0, static_cast(a.shape(ii))); + result = Array_datatype::make(std::move(result), sizes[ii], 0, static_cast(a.shape(ii))); } return result; } diff --git a/pdi/src/record_datatype.cxx b/pdi/src/record_datatype.cxx index 7d0bfe8e0..cb9835752 100644 --- a/pdi/src/record_datatype.cxx +++ b/pdi/src/record_datatype.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -44,7 +44,6 @@ using std::align; using std::endl; using std::make_shared; using std::max; -using std::move; using std::pair; using std::regex; using std::regex_replace; @@ -57,7 +56,7 @@ using std::vector; Record_datatype::Member::Member(size_t displacement, Datatype_sptr type, const string& name) : m_displacement{displacement} - , m_type{move(type)} + , m_type{std::move(type)} , m_name{name} {} @@ -94,8 +93,8 @@ bool Record_datatype::Member::operator!= (const Member& rhs) const Record_datatype::Record_datatype(vector&& members, size_t size, const Attributes_map& attributes) : Datatype(attributes) - , m_members{move(members)} - , m_buffersize{move(size)} + , m_members{std::move(members)} + , m_buffersize{std::move(size)} {} const vector& Record_datatype::members() const @@ -112,7 +111,7 @@ Datatype_sptr Record_datatype::densify() const size_t alignment = densified_type->alignment(); // align the next member as requested displacement += (alignment - (displacement % alignment)) % alignment; - densified_members.emplace_back(displacement, move(densified_type), member.name()); + densified_members.emplace_back(displacement, std::move(densified_type), member.name()); displacement += densified_members.back().type()->buffersize(); } //add padding at the end of record @@ -121,7 +120,7 @@ Datatype_sptr Record_datatype::densify() const // ensure the record size is at least 1 to have a unique address displacement = max(1, displacement); - return unique_ptr{new Record_datatype{move(densified_members), displacement}}; + return unique_ptr{new Record_datatype{std::move(densified_members), displacement}}; } Datatype_sptr Record_datatype::evaluate(Context&) const @@ -290,13 +289,13 @@ bool Record_datatype::operator== (const Datatype& other) const struct Record_datatype::Shared_enabler: public Record_datatype { Shared_enabler(vector&& members, size_t size, const Attributes_map& attributes) - : Record_datatype(move(members), size, attributes) + : Record_datatype(std::move(members), size, attributes) {} }; shared_ptr Record_datatype::make(vector&& members, size_t size, const Attributes_map& attributes) { - return make_shared(move(members), size, attributes); + return make_shared(std::move(members), size, attributes); } } // namespace PDI diff --git a/pdi/src/scalar_datatype.cxx b/pdi/src/scalar_datatype.cxx index 7449fcd9a..dd9de9cdb 100644 --- a/pdi/src/scalar_datatype.cxx +++ b/pdi/src/scalar_datatype.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -47,7 +47,6 @@ using std::function; using std::make_shared; using std::map; using std::max; -using std::move; using std::shared_ptr; using std::static_pointer_cast; using std::string; @@ -132,8 +131,8 @@ Scalar_datatype::Scalar_datatype( , m_dense_size{dense_size} , m_align{align} , m_kind{kind} - , m_copy{move(copy)} - , m_destroy{move(destroy)} + , m_copy{std::move(copy)} + , m_destroy{std::move(destroy)} { if (!nulltype(*this) && !ispow2(m_align)) throw Value_error{"alignment should be a power of 2"}; } diff --git a/pdi/src/tuple_datatype.cxx b/pdi/src/tuple_datatype.cxx index ddbaa49ff..20d3de7aa 100644 --- a/pdi/src/tuple_datatype.cxx +++ b/pdi/src/tuple_datatype.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -44,7 +44,6 @@ using std::align; using std::endl; using std::make_shared; using std::max; -using std::move; using std::pair; using std::regex; using std::regex_replace; @@ -58,7 +57,7 @@ using std::vector; Tuple_datatype::Element::Element(size_t displacement, Datatype_sptr type) : m_offset{displacement} - , m_type{move(type)} + , m_type{std::move(type)} {} Tuple_datatype::Element::Element(const Element& o) @@ -88,7 +87,7 @@ bool Tuple_datatype::Element::operator!= (const Element& rhs) const Tuple_datatype::Tuple_datatype(vector elements, size_t buffersize, const Attributes_map& attributes) : Datatype(attributes) - , m_elements{move(elements)} + , m_elements{std::move(elements)} , m_buffersize{buffersize} {} @@ -111,7 +110,7 @@ Datatype_sptr Tuple_datatype::densify() const size_t alignment = densified_type->alignment(); // align the next element as requested displacement += (alignment - (displacement % alignment)) % alignment; - densified_elements.emplace_back(displacement, move(densified_type)); + densified_elements.emplace_back(displacement, std::move(densified_type)); displacement += densified_elements.back().type()->buffersize(); } //add padding at the end of tuple @@ -120,7 +119,7 @@ Datatype_sptr Tuple_datatype::densify() const // ensure the tuple size is at least 1 to have a unique address displacement = max(1, displacement); - return unique_ptr{new Tuple_datatype{move(densified_elements), displacement}}; + return unique_ptr{new Tuple_datatype{std::move(densified_elements), displacement}}; } Datatype_sptr Tuple_datatype::evaluate(Context&) const @@ -259,8 +258,8 @@ Datatype_sptr Tuple_datatype::slice(size_t start_index, size_t end_index) const new_buffersize = elements()[end_index + 1].offset() - elements()[start_index].offset(); } - auto&& new_tuple = Tuple_datatype::make(move(new_elements), new_buffersize); - return move(new_tuple); + auto&& new_tuple = Tuple_datatype::make(std::move(new_elements), new_buffersize); + return std::move(new_tuple); } else { throw Value_error{"Subaccess tuple slice out of range: [{}:{}] > {}", start_index, end_index, size()}; } @@ -320,7 +319,7 @@ struct Tuple_datatype::Shared_enabler: public Tuple_datatype { shared_ptr Tuple_datatype::make(vector elements, size_t buffersize, const Attributes_map& attributes) { - return make_shared(move(elements), buffersize, attributes); + return make_shared(std::move(elements), buffersize, attributes); } } // namespace PDI diff --git a/pdi/tests/CMakeLists.txt b/pdi/tests/CMakeLists.txt index 8da0e0085..1cf7cb83f 100644 --- a/pdi/tests/CMakeLists.txt +++ b/pdi/tests/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # Copyright (C) 2018 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) # All rights reserved. # @@ -27,12 +27,12 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) find_package(Threads REQUIRED) if(NOT TARGET GTest::gtest) option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" OFF) - add_subdirectory("../../vendor/googletest-b4aaf97/" "googletest" EXCLUDE_FROM_ALL) + add_subdirectory("../../vendor/googletest-56efe39/" "googletest" EXCLUDE_FROM_ALL) endif() include(GoogleTest) @@ -102,7 +102,7 @@ foreach(OPERAND1_TYPE IN LISTS MODULABLE_OPERAND_TYPES) endforeach() endforeach() -target_compile_features(PDI_unit_tests PRIVATE cxx_std_17) +target_compile_features(PDI_unit_tests PRIVATE cxx_std_20) target_link_libraries(PDI_unit_tests PDI::PDI_plugins Threads::Threads GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main) target_include_directories(PDI_unit_tests PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../src") gtest_discover_tests(PDI_unit_tests) @@ -118,7 +118,7 @@ if("${ENABLE_ZSH}" STREQUAL "AUTO") set(ENABLE_ZSH "${ZSH_PROGRAM_FOUND}") endif() -add_test(NAME PDI_test_env_zsh COMMAND bash "${CMAKE_CURRENT_SOURCE_DIR}/test_env_sh" "${CMAKE_INSTALL_PREFIX}/share/pdi/env.bash") +add_test(NAME PDI_test_env_zsh COMMAND bash "${CMAKE_CURRENT_SOURCE_DIR}/test_env_sh" "${PDI_BINARY_DIR}/env.bash") if(NOT "${ENABLE_ZSH}") set_property(TEST PDI_test_env_zsh PROPERTY DISABLED TRUE) endif() diff --git a/pdi/tests/PDI_data_descriptor.cxx b/pdi/tests/PDI_data_descriptor.cxx index e41aafc68..3cb7760c5 100644 --- a/pdi/tests/PDI_data_descriptor.cxx +++ b/pdi/tests/PDI_data_descriptor.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2018 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -210,7 +210,7 @@ TEST_F(DataDescTest, multi_write_share_data) this->m_desc_default->share(this->m_desc_default->ref(), false, true); FAIL(); } catch (const Error& err) { - ASSERT_EQ(PDI_status_t::PDI_ERR_RIGHT, err.status()); + ASSERT_EQ(PDI_status_t::PDI_ERR_PERMISSION, err.status()); } this->m_desc_default->reclaim(); @@ -236,7 +236,7 @@ TEST_F(DataDescTest, read_write_share_data) this->m_desc_default->share(this->m_desc_default->ref(), false, true); FAIL(); } catch (const Error& err) { - ASSERT_EQ(PDI_status_t::PDI_ERR_RIGHT, err.status()); + ASSERT_EQ(PDI_status_t::PDI_ERR_PERMISSION, err.status()); } this->m_desc_default->release(); @@ -246,7 +246,7 @@ TEST_F(DataDescTest, read_write_share_data) this->m_desc_default->share(this->m_desc_default->ref(), true, false); FAIL(); } catch (const Error& err) { - ASSERT_EQ(PDI_status_t::PDI_ERR_RIGHT, err.status()); + ASSERT_EQ(PDI_status_t::PDI_ERR_PERMISSION, err.status()); } this->m_desc_default->reclaim(); } @@ -285,7 +285,7 @@ TEST_F(DataDescTest, share_meta_without_read) this->m_desc_default->share(this->array, false, true); FAIL(); } catch (const Error& err) { - ASSERT_EQ(PDI_status_t::PDI_ERR_RIGHT, err.status()); + ASSERT_EQ(PDI_status_t::PDI_ERR_PERMISSION, err.status()); } } diff --git a/pdi/tests/PDI_error.cxx b/pdi/tests/PDI_error.cxx index 265414876..abe0a460d 100644 --- a/pdi/tests/PDI_error.cxx +++ b/pdi/tests/PDI_error.cxx @@ -1,4 +1,5 @@ /******************************************************************************* + * Copyright (C) 2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2018 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -59,9 +60,9 @@ TEST(ErrorTest, call_constructor_no_vargs) */ TEST(ErrorTest, call_constructor_vargs) { - Error error(PDI_UNAVAILABLE, "{} errors in {}?", 0, "ErrorTest"); + Error error(PDI_ERR_SYSTEM, "{} errors in {}?", 0, "ErrorTest"); ASSERT_STREQ("0 errors in ErrorTest?", error.what()); - ASSERT_EQ(error.status(), PDI_UNAVAILABLE); + ASSERT_EQ(error.status(), PDI_ERR_SYSTEM); } /* diff --git a/pdi/tests/PDI_python_tools.cxx b/pdi/tests/PDI_python_tools.cxx index 03813eb2b..81aef1744 100644 --- a/pdi/tests/PDI_python_tools.cxx +++ b/pdi/tests/PDI_python_tools.cxx @@ -1,4 +1,5 @@ /******************************************************************************* + * Copyright (C) 2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -63,7 +64,7 @@ TEST(Python, ref_to_python) } } - Ref test_ref{data, [](void*) {}, move(type), true, true}; + Ref test_ref{data, [](void*) {}, std::move(type), true, true}; { pybind11::dict pyscope = pybind11::module::import("__main__").attr("__dict__"); pyscope["py_data"] = to_python(test_ref); diff --git a/pdi/tests/PDI_record_datatype_empty.cxx b/pdi/tests/PDI_record_datatype_empty.cxx index c7cb92d46..e59d78b15 100644 --- a/pdi/tests/PDI_record_datatype_empty.cxx +++ b/pdi/tests/PDI_record_datatype_empty.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2018 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -43,7 +43,7 @@ struct RecordDatatypeEmptyTest: public ::testing::Test { test_size = sizeof(EmptyStructure); vector test_members; - test_record = Record_datatype::make(move(test_members), test_size); + test_record = Record_datatype::make(std::move(test_members), test_size); } //size used to create Record_datatype diff --git a/pdi/tests/PDI_ref_any.cxx b/pdi/tests/PDI_ref_any.cxx index d638d126b..d4bf3932c 100644 --- a/pdi/tests/PDI_ref_any.cxx +++ b/pdi/tests/PDI_ref_any.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021-2023 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2018-2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -119,7 +119,7 @@ TEST_F(DataRefAnyTest, copyConstructor) */ TEST_F(DataRefAnyTest, moveConstructor) { - Ref moved_ref(move(*this->m_tested_ref)); + Ref moved_ref(std::move(*this->m_tested_ref)); EXPECT_TRUE(moved_ref); EXPECT_FALSE(*this->m_tested_ref); EXPECT_EQ(nullptr, Reference_base::get_content(*this->m_tested_ref)); diff --git a/pdi/tests/expression.cxx b/pdi/tests/expression.cxx index d706d4f0b..e557240c1 100644 --- a/pdi/tests/expression.cxx +++ b/pdi/tests/expression.cxx @@ -78,22 +78,8 @@ TYPED_TEST(ExpressionU@CASE_NAME@Test, toLong) for (auto op1: ALL_VALS) { for (auto op2: ALL_VALS) { - EXPECT_CALL(o1_desc, ref()) - .WillOnce(testing::Return(Ref( - &op1, - [](void*) {}, - Scalar_datatype::type_for_v, - true, - false - ))); - EXPECT_CALL(o2_desc, ref()) - .WillOnce(testing::Return(Ref( - &op2, - [](void*) {}, - Scalar_datatype::type_for_v, - true, - false - ))); + EXPECT_CALL(o1_desc, ref()).WillOnce(testing::Return(Ref(&op1, [](void*) {}, Scalar_datatype::type_for_v, true, false))); + EXPECT_CALL(o2_desc, ref()).WillOnce(testing::Return(Ref(&op2, [](void*) {}, Scalar_datatype::type_for_v, true, false))); auto const & expr = fmt::format("${{o1}} {} ${{o2}}", operator_type::sign); auto const & expected = static_cast(operator_type::eval(op1, op2)); @@ -119,22 +105,8 @@ TYPED_TEST(ExpressionU@CASE_NAME@Test, toDouble) for (auto op1: ALL_VALS) { for (auto op2: ALL_VALS) { - EXPECT_CALL(o1_desc, ref()) - .WillOnce(testing::Return(Ref( - &op1, - [](void*) {}, - Scalar_datatype::type_for_v, - true, - false - ))); - EXPECT_CALL(o2_desc, ref()) - .WillOnce(testing::Return(Ref( - &op2, - [](void*) {}, - Scalar_datatype::type_for_v, - true, - false - ))); + EXPECT_CALL(o1_desc, ref()).WillOnce(testing::Return(Ref(&op1, [](void*) {}, Scalar_datatype::type_for_v, true, false))); + EXPECT_CALL(o2_desc, ref()).WillOnce(testing::Return(Ref(&op2, [](void*) {}, Scalar_datatype::type_for_v, true, false))); auto const & expr = fmt::format("${{o1}} {} ${{o2}}", operator_type::sign); auto const & expected = operator_type::eval(op1, op2); @@ -160,22 +132,8 @@ TYPED_TEST(ExpressionU@CASE_NAME@Test, toRef) for (auto op1: ALL_VALS) { for (auto op2: ALL_VALS) { - EXPECT_CALL(o1_desc, ref()) - .WillOnce(testing::Return(Ref( - &op1, - [](void*) {}, - Scalar_datatype::type_for_v, - true, - false - ))); - EXPECT_CALL(o2_desc, ref()) - .WillOnce(testing::Return(Ref( - &op2, - [](void*) {}, - Scalar_datatype::type_for_v, - true, - false - ))); + EXPECT_CALL(o1_desc, ref()).WillOnce(testing::Return(Ref(&op1, [](void*) {}, Scalar_datatype::type_for_v, true, false))); + EXPECT_CALL(o2_desc, ref()).WillOnce(testing::Return(Ref(&op2, [](void*) {}, Scalar_datatype::type_for_v, true, false))); auto const & expr = fmt::format("${{o1}} {} ${{o2}}", operator_type::sign); auto const & expected = operator_type::eval(op1, op2); diff --git a/pdi/tests/fortran/CMakeLists.txt b/pdi/tests/fortran/CMakeLists.txt index a93192288..a731ba981 100644 --- a/pdi/tests/fortran/CMakeLists.txt +++ b/pdi/tests/fortran/CMakeLists.txt @@ -1,6 +1,6 @@ #============================================================================= # Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) -# Copyright (C) 2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2024-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -28,7 +28,7 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) enable_language(Fortran) # Includes diff --git a/pdi/tests/modulo.cxx b/pdi/tests/modulo.cxx index 66287db26..dfc43034f 100644 --- a/pdi/tests/modulo.cxx +++ b/pdi/tests/modulo.cxx @@ -65,22 +65,8 @@ TEST(ModuloU@CASE_NAME@Test, toLong) for (auto op1: ALL_VALS) { for (auto op2: ALL_VALS) { - EXPECT_CALL(o1_desc, ref()) - .WillOnce(testing::Return(Ref( - &op1, - [](void*) {}, - Scalar_datatype::type_for_v, - true, - false - ))); - EXPECT_CALL(o2_desc, ref()) - .WillOnce(testing::Return(Ref( - &op2, - [](void*) {}, - Scalar_datatype::type_for_v, - true, - false - ))); + EXPECT_CALL(o1_desc, ref()).WillOnce(testing::Return(Ref(&op1, [](void*) {}, Scalar_datatype::type_for_v, true, false))); + EXPECT_CALL(o2_desc, ref()).WillOnce(testing::Return(Ref(&op2, [](void*) {}, Scalar_datatype::type_for_v, true, false))); auto const & expr = "${o1} % ${o2}"; auto const & expected = op1 % op2; @@ -104,22 +90,8 @@ TEST(ModuloU@CASE_NAME@Test, toDouble) for (auto op1: ALL_VALS) { for (auto op2: ALL_VALS) { - EXPECT_CALL(o1_desc, ref()) - .WillOnce(testing::Return(Ref( - &op1, - [](void*) {}, - Scalar_datatype::type_for_v, - true, - false - ))); - EXPECT_CALL(o2_desc, ref()) - .WillOnce(testing::Return(Ref( - &op2, - [](void*) {}, - Scalar_datatype::type_for_v, - true, - false - ))); + EXPECT_CALL(o1_desc, ref()).WillOnce(testing::Return(Ref(&op1, [](void*) {}, Scalar_datatype::type_for_v, true, false))); + EXPECT_CALL(o2_desc, ref()).WillOnce(testing::Return(Ref(&op2, [](void*) {}, Scalar_datatype::type_for_v, true, false))); auto const & expr = "${o1} % ${o2}"; auto const & expected = op1 % op2; @@ -143,22 +115,8 @@ TEST(ModuloU@CASE_NAME@Test, toRef) for (auto op1: ALL_VALS) { for (auto op2: ALL_VALS) { - EXPECT_CALL(o1_desc, ref()) - .WillOnce(testing::Return(Ref( - &op1, - [](void*) {}, - Scalar_datatype::type_for_v, - true, - false - ))); - EXPECT_CALL(o2_desc, ref()) - .WillOnce(testing::Return(Ref( - &op2, - [](void*) {}, - Scalar_datatype::type_for_v, - true, - false - ))); + EXPECT_CALL(o1_desc, ref()).WillOnce(testing::Return(Ref(&op1, [](void*) {}, Scalar_datatype::type_for_v, true, false))); + EXPECT_CALL(o2_desc, ref()).WillOnce(testing::Return(Ref(&op2, [](void*) {}, Scalar_datatype::type_for_v, true, false))); auto const & expr = "${o1} % ${o2}"; auto const & expected = op1 % op2; diff --git a/plugins/decl_hdf5/AUTHORS b/plugins/decl_hdf5/AUTHORS index 935bea53b..0244c9084 100644 --- a/plugins/decl_hdf5/AUTHORS +++ b/plugins/decl_hdf5/AUTHORS @@ -3,6 +3,9 @@ appreciation for their public spirit, we list here in alphabetical order a condensed list of their contributions. +Julian Auriac - CEA (julian.auriac@cea.fr) +* Improvement of a test to work on OSX + Julien Bigot - CEA (julien.bigot@cea.fr) * Maintainer (Nov. 2015 - ...) * Design and initial implementation @@ -11,9 +14,13 @@ Julien Bigot - CEA (julien.bigot@cea.fr) * Run tests that depend on the filesystem in their own temporary directory * Buildsystem +Anida Khizar - CEA (anida.khizar@cea.fr) +* fix HDF5 API version compatibility issue [#567](https://github.com/pdidev/pdi/issues/567) + Jacques Morice - CEA (jacques.morice@cea.fr) * contribution to feature improvement, validation * fix issue [#55](https://github.com/pdidev/pkgs/issues/55) +* fix issue [#582](https://github.com/pdidev/pkgs/issues/582) Yacine Ould Rouis - CNRS (yacine.ould-rouis@inria.fr) * contribution to feature design, validation @@ -51,3 +58,4 @@ Kacper Sinkiewicz - PSNC (ksinkiewicz@man.poznan.pl) Yushan Wang - CEA (yushan.wang@cea.fr) * Maintainer (Sept. 2023 - ...) +* enable HDF5 subfiling diff --git a/plugins/decl_hdf5/CHANGELOG.md b/plugins/decl_hdf5/CHANGELOG.md index 1cc634c2e..98cd690a5 100644 --- a/plugins/decl_hdf5/CHANGELOG.md +++ b/plugins/decl_hdf5/CHANGELOG.md @@ -7,18 +7,47 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] ### Added +* Add subfiling support [#602](https://github.com/pdidev/pdi/issues/602) +* added a `ENABLE_BENCHMARKING` flag to cmake to enable running the benchmarks + as part of the tests (off by default) + [#679](https://github.com/pdidev/pdi/issues/679) ### Changed +* Fully qualify `std::move` calls to prevent a compilation warning and incorrect + usages [#675](https://github.com/pdidev/pdi/issues/675) +* benchmarks are not run as part of the test suite by default anymore, one must + set `ENABLE_BENCHMARKING` to `ON` in Cmake to re-enable them ### Deprecated ### Removed ### Fixed +* Fixed a rare bug, where the plugin would crash while reporting an error with + multiple matching regexes [#668](https://github.com/pdidev/pdi/issues/668) ### Security +## [1.10.0] - 2026-01-31 + +### Added +* Added macOS CI [#556](https://github.com/pdidev/pdi/issues/556) +* Possibility to add a regex for dataset name in datasets section + [#582](https://github.com/pdidev/pdi/issues/582) +* Fix HDF5 compression test for MacOS 26 + [#627](https://github.com/pdidev/pdi/issues/627) + +### Changed +* Update the version of dependencies according to our policy: oldest supported + Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: + CMake 3.22, and HDF5 1.10.7 [#613](https://github.com/pdidev/pdi/issues/613) + +### Fixed +* fix HDF5 API version compatibility issue during error handling + [#567](https://github.com/pdidev/pdi/issues/567) + + ## [1.9.0] - 2025-03-07 ### Added diff --git a/plugins/decl_hdf5/CMakeLists.txt b/plugins/decl_hdf5/CMakeLists.txt index 4ffc07438..348f4b4e5 100644 --- a/plugins/decl_hdf5/CMakeLists.txt +++ b/plugins/decl_hdf5/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) # # All rights reserved. @@ -28,13 +28,13 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(pdi_decl_hdf5_plugin LANGUAGES C CXX) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") option(BUILD_BENCHMARKING "Build PDI benchmarks" ON) option(BUILD_FORTRAN "Enable Fortran support" ON) option(BUILD_HDF5_PARALLEL "Enable HDF5 parallel build" ON) +option(ENABLE_BENCHMARKING "Activate benchmarks in the test suite" OFF) include(CTest) @@ -49,9 +49,10 @@ include(GNUInstallDirs) set(HDF5_USE_STATIC_LIBRARIES OFF) set(HDF5_PREFER_PARALLEL "${BUILD_HDF5_PARALLEL}") find_package(HDF5 REQUIRED COMPONENTS C) -if("${HDF5_VERSION}" VERSION_LESS "1.10.0") - message(FATAL_ERROR "HDF5 version 1.10.0 at least required, HDF5 ${HDF5_VERSION} found.") +if("${HDF5_VERSION}" VERSION_LESS 1.10) + message(FATAL_ERROR "HDF5 version 1.10 at least required, HDF5 ${HDF5_VERSION} found.") endif() + if("${BUILD_HDF5_PARALLEL}" AND NOT "${HDF5_IS_PARALLEL}") message(FATAL_ERROR "Parallel HDF5 required, sequential HDF5 only found. Please set -DBUILD_HDF5_PARALLEL=OFF to disable parallel HDF5") endif() @@ -77,7 +78,8 @@ add_library(pdi_decl_hdf5_plugin MODULE collision_policy.cxx file_op.cxx hdf5_wrapper.cxx - selection.cxx) + selection.cxx + subfiling.cxx) target_link_libraries(pdi_decl_hdf5_plugin PUBLIC PDI::PDI_plugins ${HDF5_DEPS}) set_target_properties(pdi_decl_hdf5_plugin PROPERTIES CXX_VISIBILITY_PRESET hidden) diff --git a/plugins/decl_hdf5/README.md b/plugins/decl_hdf5/README.md index a46db8676..0847ee5c5 100644 --- a/plugins/decl_hdf5/README.md +++ b/plugins/decl_hdf5/README.md @@ -42,7 +42,9 @@ The possible values for the keys are as follow: can be replaced inside the `DATA_SECTION`. * `datasets`: a key-value map associating a PDI type to string keys. Each string is the name of a dataset to create in the file on first - access, with the type described in the value. + access, with the type described in the value. The string key is + a regular expression (regex), and be used to define "generic keys", + that can be used in `DATA_IO_DESC` for the keyword dataset. The regex use the Modified ECMAScript regular expression grammar. * `collision_policy`: a string identifying a \ref COLLISION_POLICY * `deflate`: an integer value (from 0 to 9) defining the default deflate (GNU gzip) compression level to use for datasets created in this file. @@ -59,6 +61,34 @@ The possible values for the keys are as follow: https://support.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetFletcher32 for more information. +* `subfiling`: a key-value map or an integer. Configures the HDF5 Subfiling Virtual File Driver (VFD). This feature is only available if the underlying HDF5 installation was compiled with `H5_HAVE_SUBFILING_VFD`. + * Configuration keys: + * `count` (integer, default: 0) : the total number of subfiles to generate. If set to -1 or other negative values, the one-subfile-per-node mode will be triggered. + * `policy` (string, default: "STOP") : Determines behavior if subfiling requirements are not met. + * `STOP`: Throw a runtime error. + * `CONTINUE`: Fall back to a standard HDF5 output file. + * `stripe_size` (non-negative integer, default: 0): The amount of data (in bytes) written to one subfile before rotating to the next. If 0, the HDF5 default (typically 32MB) is used. + * Yaml example + * full configuration: + ``` + subfiling: + count: 4 # generate 4 subfiles + policy: CONTINUE # Fallback to standard HDF5 if necessary + stripe_size: 8388608 # 8MB stripes + ``` + * shorthand configuration: + ``` + subfiling: 2 + ``` + This will set `count=2` and all other members use default values. + * Here are several important notes for using `subfiling` correctly: + * **MPI Threading Requirement**: The simulation must be initialized with `MPI_THREAD_MULTIPLE`. If this is not satisfied, the application will throw a runtime error unless policy is set to `CONTINUE`. In `CONTINUE` mode, the simulation will proceed using standard HDF5 I/O. + * **Stripe Size Configuration**: The stripe size can be set in the YAML via `stripe_size` or via the environment variable `H5FD_SUBFILING_STRIPE_SIZE`. The YAML value takes precedence if both are provided. + * **Custom File Locations**: To store subfiles in a specific directory (e.g., a high-speed scratch burst buffer), provide an absolute path to `H5FD_SUBFILING_SUBFILE_PREFIX`. **Note** : You must set the same path to `H5FD_SUBFILING_CONFIG_FILE_PREFIX` so the main .h5 file can locate its constituent subfiles. + * **Naming Convention**: Subfile names are managed internally by HDF5 and cannot be easily customized. They follow a template similar to: + `[filename].h5.subfile_[contextID]_[subfile_index]_of_[total_subfiles]` + (e.g., `output.h5.subfile_11273556_01_of_10`) + ### DATA_SECTION The `DATA_SECTION` describes a set of I/O (read or write) to execute. @@ -112,7 +142,8 @@ The possible values for the keys are as follow: It defaults to selecting the whole data. * `dataset_selection`: a `SELECTION_DESC` specifying the selection of data in the file data to write or read. - This is only valid if the + This is only valid if the dataset is explicitly defined in the `datasets` + section. * `attributes`: a key-value map specifying the set of attributes to read from (respectively, write to) the file when the associated dataset is read (respectively, written). @@ -216,6 +247,10 @@ plugins: type: array subtype: double # type of the data in the dataset size: [10, $width-2, $width-2] # size of the dataset + data_iter.*/array: # a dataset name which is a regex. This name allows to write datasets that match this regex in the h5 file + type: array + subtype: double # type of the data in the dataset + size: [$width-2, $width-2] # size of the dataset write: # a list or map of data to write (default: empty) main_field: # name of the data, it contains either a list or a single write to execute - dataset: data/array # a dataset name (default: the data name) @@ -232,6 +267,14 @@ plugins: size: ($width-2)*($width-2) width: $width-2 height: $width-2 + - dataset: data_iter${iter}/array # a dataset name with an implicit name + memory_selection: + size: [$width-2, $height-2] # number of elements to transfer in each dimension (default: size of the full data) + start: [1, 1] # coordinate of the start point in memory relative to the shared data (default: 0 in each dimensions) + dataset_selection: + size: [ $width-2, $width-2] # number of elements to transfer in each dimension, must amount to the same number as the memory selection (default: size of memory slab) + start: [ 0, 0] # coordinate of the start point in the file relative to the dataset (default: 0 in each dimensions) + read: # a list or map of data to read, similar to write (default: empty) - another_value ``` diff --git a/plugins/decl_hdf5/attribute_op.cxx b/plugins/decl_hdf5/attribute_op.cxx index 95c66ce41..4e7d820a8 100644 --- a/plugins/decl_hdf5/attribute_op.cxx +++ b/plugins/decl_hdf5/attribute_op.cxx @@ -1,4 +1,5 @@ /******************************************************************************* + * Copyright (C) 2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -32,26 +33,25 @@ namespace decl_hdf5 { -using PDI::Config_error; using PDI::Context; using PDI::each; using PDI::Expression; using PDI::Ref_r; using PDI::Ref_w; +using PDI::Spectree_error; using PDI::to_string; using PDI::Value_error; -using std::move; using std::string; using std::tie; Attribute_op::Attribute_op(Direction direction, PC_tree_t attr_path_tree, Expression when) : m_direction{direction} - , m_when{move(when)} + , m_when{std::move(when)} { string attr_path = to_string(attr_path_tree); size_t pos = attr_path.find('#'); if (pos == string::npos) { - throw Config_error{attr_path_tree, "Attribute path must contain `#' sign to separate group/dataset from attribute name"}; + throw Spectree_error{attr_path_tree, "Attribute path must contain `#' sign to separate group/dataset from attribute name"}; } m_object_path = Expression{attr_path.substr(0, pos)}; m_name = attr_path.substr(pos + 1); @@ -63,7 +63,7 @@ Attribute_op::Attribute_op(Direction direction, const string& desc, Expression w : m_desc{desc} , m_direction{direction} , m_value{"$" + desc} - , m_when{move(when)} + , m_when{std::move(when)} { each(tree, [&](PC_tree_t key_tree, PC_tree_t value) { string key = to_string(key_tree); @@ -80,7 +80,7 @@ Attribute_op::Attribute_op(Direction direction, const string& desc, Expression w } else if (key == "when") { m_when = to_string(value); } else { - throw Config_error{key_tree, "Unknown key for HDF5 attribute configuration: `{}'", key}; + throw Spectree_error{key_tree, "Unknown key for HDF5 attribute configuration: `{}'", key}; } }); } @@ -88,8 +88,8 @@ Attribute_op::Attribute_op(Direction direction, const string& desc, Expression w Attribute_op::Attribute_op(Direction direction, Expression object_path, const string& attr_name, Expression value, Expression when) : m_direction{direction} , m_name{attr_name} - , m_object_path{move(object_path)} - , m_value{move(value)} + , m_object_path{std::move(object_path)} + , m_value{std::move(value)} , m_when{when} {} diff --git a/plugins/decl_hdf5/benchmarks/CMakeLists.txt b/plugins/decl_hdf5/benchmarks/CMakeLists.txt index 26c3be8a2..0e51f70b9 100644 --- a/plugins/decl_hdf5/benchmarks/CMakeLists.txt +++ b/plugins/decl_hdf5/benchmarks/CMakeLists.txt @@ -1,6 +1,6 @@ #============================================================================= # Copyright (C) 2022 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) -# Copyright (C) 2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2024-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,19 +27,19 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(decl_hdf5_benchmarks) if(NOT TARGET GTest::gtest) option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" OFF) - add_subdirectory("../../../vendor/googletest-b4aaf97/" "googletest" EXCLUDE_FROM_ALL) + add_subdirectory("../../../vendor/googletest-56efe39/" "googletest" EXCLUDE_FROM_ALL) endif() if(NOT TARGET benchmark::benchmark) option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." OFF) option(BENCHMARK_ENABLE_WERROR "Build Release candidates with -Werror." OFF) option(BENCHMARK_ENABLE_INSTALL "Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)" OFF) - add_subdirectory("../../../vendor/benchmark-38df9da/" "benchmark" EXCLUDE_FROM_ALL) + add_subdirectory("../../../vendor/benchmark-4ed29ae/" "benchmark" EXCLUDE_FROM_ALL) endif() include(CTest) @@ -66,4 +66,7 @@ target_link_libraries(decl_hdf5_benchmarks set(RUNTEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/runtest-dir") add_test(NAME decl_hdf5_benchmarks COMMAND "${RUNTEST_DIR}" sh -c "$ --benchmark_format=json > ${BENCHMARK_RESULT_PATH}/decl_hdf5_benchmark_result.json") +if(NOT "${ENABLE_BENCHMARKING}") + set_property(TEST decl_hdf5_benchmarks PROPERTY DISABLED TRUE) +endif() set_property(TEST decl_hdf5_benchmarks PROPERTY TIMEOUT 300) diff --git a/plugins/decl_hdf5/cmake/FindHDF5.cmake b/plugins/decl_hdf5/cmake/FindHDF5.cmake deleted file mode 100644 index 6d34972d8..000000000 --- a/plugins/decl_hdf5/cmake/FindHDF5.cmake +++ /dev/null @@ -1,1206 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindHDF5 --------- - -Find Hierarchical Data Format (HDF5), a library for reading and writing -self describing array data. - - -This module invokes the ``HDF5`` wrapper compiler that should be installed -alongside ``HDF5``. Depending upon the ``HDF5`` Configuration, the wrapper -compiler is called either ``h5cc`` or ``h5pcc``. If this succeeds, the module -will then call the compiler with the show argument to see what flags -are used when compiling an ``HDF5`` client application. - -The module will optionally accept the ``COMPONENTS`` argument. If no -``COMPONENTS`` are specified, then the find module will default to finding -only the ``HDF5`` C library. If one or more ``COMPONENTS`` are specified, the -module will attempt to find the language bindings for the specified -components. The valid components are ``C``, ``CXX``, ``Fortran``, ``HL``. -``HL`` refers to the "high-level" HDF5 functions for C and Fortran. -If the ``COMPONENTS`` argument is not given, the module will -attempt to find only the C bindings. -For example, to use Fortran HDF5 and HDF5-HL functions, do: -``find_package(HDF5 COMPONENTS Fortran HL)``. - -This module will read the variable -``HDF5_USE_STATIC_LIBRARIES`` to determine whether or not to prefer a -static link to a dynamic link for ``HDF5`` and all of it's dependencies. -To use this feature, make sure that the ``HDF5_USE_STATIC_LIBRARIES`` -variable is set before the call to find_package. - -.. versionadded:: 3.10 - Support for ``HDF5_USE_STATIC_LIBRARIES`` on Windows. - -Both the serial and parallel ``HDF5`` wrappers are considered and the first -directory to contain either one will be used. In the event that both appear -in the same directory the serial version is preferentially selected. This -behavior can be reversed by setting the variable ``HDF5_PREFER_PARALLEL`` to -``TRUE``. - -In addition to finding the includes and libraries required to compile -an ``HDF5`` client application, this module also makes an effort to find -tools that come with the ``HDF5`` distribution that may be useful for -regression testing. - -Result Variables -^^^^^^^^^^^^^^^^ - -This module will set the following variables in your project: - -``HDF5_FOUND`` - HDF5 was found on the system -``HDF5_VERSION`` - .. versionadded:: 3.3 - HDF5 library version -``HDF5_INCLUDE_DIRS`` - Location of the HDF5 header files -``HDF5_DEFINITIONS`` - Required compiler definitions for HDF5 -``HDF5_LIBRARIES`` - Required libraries for all requested bindings -``HDF5_HL_LIBRARIES`` - Required libraries for the HDF5 high level API for all bindings, - if the ``HL`` component is enabled - -Available components are: ``C`` ``CXX`` ``Fortran`` and ``HL``. -For each enabled language binding, a corresponding ``HDF5_${LANG}_LIBRARIES`` -variable, and potentially ``HDF5_${LANG}_DEFINITIONS``, will be defined. -If the ``HL`` component is enabled, then an ``HDF5_${LANG}_HL_LIBRARIES`` will -also be defined. With all components enabled, the following variables will be defined: - -``HDF5_C_DEFINITIONS`` - Required compiler definitions for HDF5 C bindings -``HDF5_CXX_DEFINITIONS`` - Required compiler definitions for HDF5 C++ bindings -``HDF5_Fortran_DEFINITIONS`` - Required compiler definitions for HDF5 Fortran bindings -``HDF5_C_INCLUDE_DIRS`` - Required include directories for HDF5 C bindings -``HDF5_CXX_INCLUDE_DIRS`` - Required include directories for HDF5 C++ bindings -``HDF5_Fortran_INCLUDE_DIRS`` - Required include directories for HDF5 Fortran bindings -``HDF5_C_LIBRARIES`` - Required libraries for the HDF5 C bindings -``HDF5_CXX_LIBRARIES`` - Required libraries for the HDF5 C++ bindings -``HDF5_Fortran_LIBRARIES`` - Required libraries for the HDF5 Fortran bindings -``HDF5_C_HL_LIBRARIES`` - Required libraries for the high level C bindings -``HDF5_CXX_HL_LIBRARIES`` - Required libraries for the high level C++ bindings -``HDF5_Fortran_HL_LIBRARIES`` - Required libraries for the high level Fortran bindings. - -``HDF5_IS_PARALLEL`` - HDF5 library has parallel IO support -``HDF5_C_COMPILER_EXECUTABLE`` - path to the HDF5 C wrapper compiler -``HDF5_CXX_COMPILER_EXECUTABLE`` - path to the HDF5 C++ wrapper compiler -``HDF5_Fortran_COMPILER_EXECUTABLE`` - path to the HDF5 Fortran wrapper compiler -``HDF5_C_COMPILER_EXECUTABLE_NO_INTERROGATE`` - path to the primary C compiler which is also the HDF5 wrapper -``HDF5_CXX_COMPILER_EXECUTABLE_NO_INTERROGATE`` - path to the primary C++ compiler which is also the HDF5 wrapper -``HDF5_Fortran_COMPILER_EXECUTABLE_NO_INTERROGATE`` - path to the primary Fortran compiler which is also the HDF5 wrapper -``HDF5_DIFF_EXECUTABLE`` - path to the HDF5 dataset comparison tool - -With all components enabled, the following targets will be defined: - -``HDF5::HDF5`` - All detected ``HDF5_LIBRARIES``. -``hdf5::hdf5`` - C library. -``hdf5::hdf5_cpp`` - C++ library. -``hdf5::hdf5_fortran`` - Fortran library. -``hdf5::hdf5_hl`` - High-level C library. -``hdf5::hdf5_hl_cpp`` - High-level C++ library. -``hdf5::hdf5_hl_fortran`` - High-level Fortran library. -``hdf5::h5diff`` - ``h5diff`` executable. - -Hints -^^^^^ - -The following variables can be set to guide the search for HDF5 libraries and includes: - -``HDF5_PREFER_PARALLEL`` - .. versionadded:: 3.4 - - set ``true`` to prefer parallel HDF5 (by default, serial is preferred) - -``HDF5_FIND_DEBUG`` - .. versionadded:: 3.9 - - Set ``true`` to get extra debugging output. - -``HDF5_NO_FIND_PACKAGE_CONFIG_FILE`` - .. versionadded:: 3.8 - - Set ``true`` to skip trying to find ``hdf5-config.cmake``. -#]=======================================================================] - -include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) - -# We haven't found HDF5 yet. Clear its state in case it is set in the parent -# scope somewhere else. We can't rely on it because different components may -# have been requested for this call. -set(HDF5_FOUND OFF) - -# List of the valid HDF5 components -set(HDF5_VALID_LANGUAGE_BINDINGS C CXX Fortran) - -# Validate the list of find components. -if(NOT HDF5_FIND_COMPONENTS) - set(HDF5_LANGUAGE_BINDINGS "C") -else() - set(HDF5_LANGUAGE_BINDINGS) - # add the extra specified components, ensuring that they are valid. - set(HDF5_FIND_HL OFF) - foreach(_component IN LISTS HDF5_FIND_COMPONENTS) - list(FIND HDF5_VALID_LANGUAGE_BINDINGS ${_component} _component_location) - if(NOT _component_location EQUAL -1) - list(APPEND HDF5_LANGUAGE_BINDINGS ${_component}) - elseif(_component STREQUAL "HL") - set(HDF5_FIND_HL ON) - elseif(_component STREQUAL "Fortran_HL") # only for compatibility - list(APPEND HDF5_LANGUAGE_BINDINGS Fortran) - set(HDF5_FIND_HL ON) - set(HDF5_FIND_REQUIRED_Fortran_HL FALSE) - set(HDF5_FIND_REQUIRED_Fortran TRUE) - set(HDF5_FIND_REQUIRED_HL TRUE) - else() - message(FATAL_ERROR "${_component} is not a valid HDF5 component.") - endif() - endforeach() - unset(_component) - unset(_component_location) - if(NOT HDF5_LANGUAGE_BINDINGS) - get_property(_langs GLOBAL PROPERTY ENABLED_LANGUAGES) - foreach(_lang IN LISTS _langs) - if(_lang MATCHES "^(C|CXX|Fortran)$") - list(APPEND HDF5_LANGUAGE_BINDINGS ${_lang}) - endif() - endforeach() - endif() - list(REMOVE_ITEM HDF5_FIND_COMPONENTS Fortran_HL) # replaced by Fortran and HL - if(HDF5_LANGUAGE_BINDINGS) - list(REMOVE_DUPLICATES HDF5_LANGUAGE_BINDINGS) - endif() -endif() - -# Determine whether to search for serial or parallel executable first -if(HDF5_PREFER_PARALLEL) - set(HDF5_C_COMPILER_NAMES h5pcc h5cc) - set(HDF5_CXX_COMPILER_NAMES h5pc++ h5c++) - set(HDF5_Fortran_COMPILER_NAMES h5pfc h5fc) -else() - set(HDF5_C_COMPILER_NAMES h5cc h5pcc) - set(HDF5_CXX_COMPILER_NAMES h5c++ h5pc++) - set(HDF5_Fortran_COMPILER_NAMES h5fc h5pfc) -endif() - -# Test first if the current compilers automatically wrap HDF5 -function(_HDF5_test_regular_compiler_C success version is_parallel) - set(scratch_directory - ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) - if(NOT ${success} OR - NOT EXISTS ${scratch_directory}/compiler_has_h5_c) - set(test_file ${scratch_directory}/cmake_hdf5_test.c) - file(WRITE ${test_file} - "#include \n" - "const char* info_ver = \"INFO\" \":\" H5_VERSION;\n" - "#ifdef H5_HAVE_PARALLEL\n" - "const char* info_parallel = \"INFO\" \":\" \"PARALLEL\";\n" - "#endif\n" - "int main(int argc, char **argv) {\n" - " int require = 0;\n" - " require += info_ver[argc];\n" - "#ifdef H5_HAVE_PARALLEL\n" - " require += info_parallel[argc];\n" - "#endif\n" - " hid_t fid;\n" - " fid = H5Fcreate(\"foo.h5\",H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT);\n" - " return 0;\n" - "}") - try_compile(${success} ${scratch_directory} ${test_file} - COPY_FILE ${scratch_directory}/compiler_has_h5_c - ) - endif() - if(${success}) - file(STRINGS ${scratch_directory}/compiler_has_h5_c INFO_STRINGS - REGEX "^INFO:" - ) - string(REGEX MATCH "^INFO:([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?" - INFO_VER "${INFO_STRINGS}" - ) - set(${version} ${CMAKE_MATCH_1}) - if(CMAKE_MATCH_3) - set(${version} ${HDF5_C_VERSION}.${CMAKE_MATCH_3}) - endif() - set(${version} ${${version}} PARENT_SCOPE) - - if(INFO_STRINGS MATCHES "INFO:PARALLEL") - set(${is_parallel} TRUE PARENT_SCOPE) - else() - set(${is_parallel} FALSE PARENT_SCOPE) - endif() - endif() -endfunction() - -function(_HDF5_test_regular_compiler_CXX success version is_parallel) - set(scratch_directory ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) - if(NOT ${success} OR - NOT EXISTS ${scratch_directory}/compiler_has_h5_cxx) - set(test_file ${scratch_directory}/cmake_hdf5_test.cxx) - file(WRITE ${test_file} - "#include \n" - "#ifndef H5_NO_NAMESPACE\n" - "using namespace H5;\n" - "#endif\n" - "const char* info_ver = \"INFO\" \":\" H5_VERSION;\n" - "#ifdef H5_HAVE_PARALLEL\n" - "const char* info_parallel = \"INFO\" \":\" \"PARALLEL\";\n" - "#endif\n" - "int main(int argc, char **argv) {\n" - " int require = 0;\n" - " require += info_ver[argc];\n" - "#ifdef H5_HAVE_PARALLEL\n" - " require += info_parallel[argc];\n" - "#endif\n" - " H5File file(\"foo.h5\", H5F_ACC_TRUNC);\n" - " return 0;\n" - "}") - try_compile(${success} ${scratch_directory} ${test_file} - COPY_FILE ${scratch_directory}/compiler_has_h5_cxx - ) - endif() - if(${success}) - file(STRINGS ${scratch_directory}/compiler_has_h5_cxx INFO_STRINGS - REGEX "^INFO:" - ) - string(REGEX MATCH "^INFO:([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?" - INFO_VER "${INFO_STRINGS}" - ) - set(${version} ${CMAKE_MATCH_1}) - if(CMAKE_MATCH_3) - set(${version} ${HDF5_CXX_VERSION}.${CMAKE_MATCH_3}) - endif() - set(${version} ${${version}} PARENT_SCOPE) - - if(INFO_STRINGS MATCHES "INFO:PARALLEL") - set(${is_parallel} TRUE PARENT_SCOPE) - else() - set(${is_parallel} FALSE PARENT_SCOPE) - endif() - endif() -endfunction() - -function(_HDF5_test_regular_compiler_Fortran success is_parallel) - if(NOT ${success}) - set(scratch_directory - ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) - set(test_file ${scratch_directory}/cmake_hdf5_test.f90) - file(WRITE ${test_file} - "program hdf5_hello\n" - " use hdf5\n" - " use h5lt\n" - " use h5ds\n" - " integer error\n" - " call h5open_f(error)\n" - " call h5close_f(error)\n" - "end\n") - try_compile(${success} ${scratch_directory} ${test_file}) - if(${success}) - execute_process(COMMAND ${CMAKE_Fortran_COMPILER} -showconfig - OUTPUT_VARIABLE config_output - ERROR_VARIABLE config_error - RESULT_VARIABLE config_result - ) - if(config_output MATCHES "Parallel HDF5: yes") - set(${is_parallel} TRUE PARENT_SCOPE) - else() - set(${is_parallel} FALSE PARENT_SCOPE) - endif() - endif() - endif() -endfunction() - -# Invoke the HDF5 wrapper compiler. The compiler return value is stored to the -# return_value argument, the text output is stored to the output variable. -function( _HDF5_invoke_compiler language output_var return_value_var version_var is_parallel_var) - set(is_parallel FALSE) - if(HDF5_USE_STATIC_LIBRARIES) - set(lib_type_args -noshlib) - else() - set(lib_type_args -shlib) - endif() - set(scratch_dir ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) - if("${language}" STREQUAL "C") - set(test_file ${scratch_dir}/cmake_hdf5_test.c) - elseif("${language}" STREQUAL "CXX") - set(test_file ${scratch_dir}/cmake_hdf5_test.cxx) - elseif("${language}" STREQUAL "Fortran") - set(test_file ${scratch_dir}/cmake_hdf5_test.f90) - endif() - # Verify that the compiler wrapper can actually compile: sometimes the compiler - # wrapper exists, but not the compiler. E.g. Miniconda / Anaconda Python - execute_process( - COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} ${test_file} - WORKING_DIRECTORY ${scratch_dir} - OUTPUT_VARIABLE output - ERROR_VARIABLE output - RESULT_VARIABLE return_value - ) - if(return_value AND NOT HDF5_FIND_QUIETLY) - message(STATUS - "HDF5 ${language} compiler wrapper is unable to compile a minimal HDF5 program.") - else() - execute_process( - COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -show ${lib_type_args} ${test_file} - WORKING_DIRECTORY ${scratch_dir} - OUTPUT_VARIABLE output - ERROR_VARIABLE output - RESULT_VARIABLE return_value - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(return_value AND NOT HDF5_FIND_QUIETLY) - message(STATUS - "Unable to determine HDF5 ${language} flags from HDF5 wrapper.") - endif() - execute_process( - COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -showconfig - OUTPUT_VARIABLE config_output - ERROR_VARIABLE config_output - RESULT_VARIABLE return_value - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(return_value AND NOT HDF5_FIND_QUIETLY) - message(STATUS - "Unable to determine HDF5 ${language} version_var from HDF5 wrapper.") - endif() - string(REGEX MATCH "HDF5 Version: ([a-zA-Z0-9\\.\\-]*)" version "${config_output}") - if(version) - string(REPLACE "HDF5 Version: " "" version "${version}") - string(REPLACE "-patch" "." version "${version}") - endif() - if(config_output MATCHES "Parallel HDF5: yes") - set(is_parallel TRUE) - endif() - endif() - foreach(var output return_value version is_parallel) - set(${${var}_var} ${${var}} PARENT_SCOPE) - endforeach() -endfunction() - -# Parse a compile line for definitions, includes, library paths, and libraries. -function(_HDF5_parse_compile_line compile_line_var include_paths definitions - library_paths libraries libraries_hl) - - if(${WIN32}) - set(CM35_NATIVE_COMMAND WINDOWS_COMMAND) - else(${WIN32}) - set(CM35_NATIVE_COMMAND UNIX_COMMAND) - endif(${WIN32}) - separate_arguments(_compile_args ${CM35_NATIVE_COMMAND} "${${compile_line_var}}") - - foreach(_arg IN LISTS _compile_args) - if("${_arg}" MATCHES "^-I(.*)$") - # include directory - list(APPEND include_paths "${CMAKE_MATCH_1}") - elseif("${_arg}" MATCHES "^-D(.*)$") - # compile definition - list(APPEND definitions "-D${CMAKE_MATCH_1}") - elseif("${_arg}" MATCHES "^-L(.*)$") - # library search path - list(APPEND library_paths "${CMAKE_MATCH_1}") - elseif("${_arg}" MATCHES "^-l(hdf5.*hl.*)$") - # library name (hl) - list(APPEND libraries_hl "${CMAKE_MATCH_1}") - elseif("${_arg}" MATCHES "^-l(.*)$") - # library name - list(APPEND libraries "${CMAKE_MATCH_1}") - elseif("${_arg}" MATCHES "^(.:)?[/\\].*\\.(a|so|dylib|sl|lib)$") - # library file - if(NOT EXISTS "${_arg}") - continue() - endif() - get_filename_component(_lpath "${_arg}" DIRECTORY) - get_filename_component(_lname "${_arg}" NAME_WE) - string(REGEX REPLACE "^lib" "" _lname "${_lname}") - list(APPEND library_paths "${_lpath}") - if(_lname MATCHES "hdf5.*hl") - list(APPEND libraries_hl "${_lname}") - else() - list(APPEND libraries "${_lname}") - endif() - endif() - endforeach() - foreach(var include_paths definitions library_paths libraries libraries_hl) - set(${${var}_var} ${${var}} PARENT_SCOPE) - endforeach() -endfunction() - -# Select a preferred imported configuration from a target -function(_HDF5_select_imported_config target imported_conf) - # We will first assign the value to a local variable _imported_conf, then assign - # it to the function argument at the end. - get_target_property(_imported_conf ${target} MAP_IMPORTED_CONFIG_${CMAKE_BUILD_TYPE}) - if (NOT _imported_conf) - # Get available imported configurations by examining target properties - get_target_property(_imported_conf ${target} IMPORTED_CONFIGURATIONS) - if(HDF5_FIND_DEBUG) - message(STATUS "Found imported configurations: ${_imported_conf}") - endif() - # Find the imported configuration that we prefer. - # We do this by making list of configurations in order of preference, - # starting with ${CMAKE_BUILD_TYPE} and ending with the first imported_conf - set(_preferred_confs ${CMAKE_BUILD_TYPE}) - list(GET _imported_conf 0 _fallback_conf) - list(APPEND _preferred_confs RELWITHDEBINFO RELEASE DEBUG ${_fallback_conf}) - if(HDF5_FIND_DEBUG) - message(STATUS "Start search through imported configurations in the following order: ${_preferred_confs}") - endif() - # Now find the first of these that is present in imported_conf - cmake_policy(PUSH) - cmake_policy(SET CMP0057 NEW) # support IN_LISTS - foreach (_conf IN LISTS _preferred_confs) - if (${_conf} IN_LIST _imported_conf) - set(_imported_conf ${_conf}) - break() - endif() - endforeach() - cmake_policy(POP) - endif() - if(HDF5_FIND_DEBUG) - message(STATUS "Selected imported configuration: ${_imported_conf}") - endif() - # assign value to function argument - set(${imported_conf} ${_imported_conf} PARENT_SCOPE) -endfunction() - - -if(NOT HDF5_ROOT) - set(HDF5_ROOT $ENV{HDF5_ROOT}) -endif() -if(HDF5_ROOT) - set(_HDF5_SEARCH_OPTS NO_DEFAULT_PATH) -else() - set(_HDF5_SEARCH_OPTS) -endif() - -# Try to find HDF5 using an installed hdf5-config.cmake -if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE) - find_package(HDF5 QUIET NO_MODULE - HINTS ${HDF5_ROOT} - ${_HDF5_SEARCH_OPTS} - ) - if( HDF5_FOUND) - if(HDF5_FIND_DEBUG) - message(STATUS "Found HDF5 at ${HDF5_DIR} via NO_MODULE. Now trying to extract locations etc.") - endif() - unset(HDF5_IS_PARALLEL CACHE) - set(HDF5_IS_PARALLEL ${HDF5_ENABLE_PARALLEL}) - set(HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR}) - set(HDF5_LIBRARIES) - if (NOT TARGET hdf5 AND NOT TARGET hdf5-static AND NOT TARGET hdf5-shared) - # Some HDF5 versions (e.g. 1.8.18) used hdf5::hdf5 etc - set(_target_prefix "hdf5::") - endif() - set(HDF5_C_TARGET ${_target_prefix}hdf5) - set(HDF5_C_HL_TARGET ${_target_prefix}hdf5_hl) - set(HDF5_CXX_TARGET ${_target_prefix}hdf5_cpp) - set(HDF5_CXX_HL_TARGET ${_target_prefix}hdf5_hl_cpp) - set(HDF5_Fortran_TARGET ${_target_prefix}hdf5_fortran) - set(HDF5_Fortran_HL_TARGET ${_target_prefix}hdf5_hl_fortran) - set(HDF5_DEFINITIONS "") - if(HDF5_USE_STATIC_LIBRARIES) - set(_suffix "-static") - else() - set(_suffix "-shared") - endif() - foreach(_lang ${HDF5_LANGUAGE_BINDINGS}) - - #Older versions of hdf5 don't have a static/shared suffix so - #if we detect that occurrence clear the suffix - if(_suffix AND NOT TARGET ${HDF5_${_lang}_TARGET}${_suffix}) - if(NOT TARGET ${HDF5_${_lang}_TARGET}) - #can't find this component with or without the suffix - #so bail out, and let the following locate HDF5 - set(HDF5_FOUND FALSE) - break() - endif() - set(_suffix "") - endif() - - if(HDF5_FIND_DEBUG) - message(STATUS "Trying to get properties of target ${HDF5_${_lang}_TARGET}${_suffix}") - endif() - # Find library for this target. Complicated as on Windows with a DLL, we need to search for the import-lib. - _HDF5_select_imported_config(${HDF5_${_lang}_TARGET}${_suffix} _hdf5_imported_conf) - get_target_property(_hdf5_lang_location ${HDF5_${_lang}_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} ) - if (NOT _hdf5_lang_location) - # no import lib, just try LOCATION - get_target_property(_hdf5_lang_location ${HDF5_${_lang}_TARGET}${_suffix} LOCATION_${_hdf5_imported_conf}) - if (NOT _hdf5_lang_location) - get_target_property(_hdf5_lang_location ${HDF5_${_lang}_TARGET}${_suffix} LOCATION) - endif() - endif() - if( _hdf5_lang_location ) - set(HDF5_${_lang}_LIBRARY ${_hdf5_lang_location}) - list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix}) - set(HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_TARGET}${_suffix}) - set(HDF5_${_lang}_FOUND TRUE) - endif() - if(HDF5_FIND_HL) - get_target_property(_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} ) - if (NOT _hdf5_lang_hl_location) - get_target_property(_hdf5_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} LOCATION_${_hdf5_imported_conf}) - if (NOT _hdf5_hl_lang_location) - get_target_property(_hdf5_hl_lang_location ${HDF5_${_lang}_HL_TARGET}${_suffix} LOCATION) - endif() - endif() - if( _hdf5_lang_hl_location ) - set(HDF5_${_lang}_HL_LIBRARY ${_hdf5_lang_hl_location}) - list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix}) - set(HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_HL_TARGET}${_suffix}) - set(HDF5_HL_FOUND TRUE) - endif() - unset(_hdf5_lang_hl_location) - endif() - unset(_hdf5_imported_conf) - unset(_hdf5_lang_location) - endforeach() - endif() -endif() - -if(NOT HDF5_FOUND) - set(_HDF5_NEED_TO_SEARCH FALSE) - set(HDF5_COMPILER_NO_INTERROGATE TRUE) - unset(HDF5_IS_PARALLEL) - unset(HDF5_IS_PARALLEL CACHE) - # Only search for languages we've enabled - foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS) - # First check to see if our regular compiler is one of wrappers - if(_lang STREQUAL "C") - _HDF5_test_regular_compiler_C( - HDF5_${_lang}_COMPILER_NO_INTERROGATE - HDF5_${_lang}_VERSION - HDF5_${_lang}_IS_PARALLEL) - elseif(_lang STREQUAL "CXX") - _HDF5_test_regular_compiler_CXX( - HDF5_${_lang}_COMPILER_NO_INTERROGATE - HDF5_${_lang}_VERSION - HDF5_${_lang}_IS_PARALLEL) - elseif(_lang STREQUAL "Fortran") - _HDF5_test_regular_compiler_Fortran( - HDF5_${_lang}_COMPILER_NO_INTERROGATE - HDF5_${_lang}_IS_PARALLEL) - else() - continue() - endif() - if(HDF5_${_lang}_COMPILER_NO_INTERROGATE) - if(HDF5_FIND_DEBUG) - message(STATUS "HDF5: Using hdf5 compiler wrapper for all ${_lang} compiling") - endif() - set(HDF5_${_lang}_FOUND TRUE) - set(HDF5_${_lang}_COMPILER_EXECUTABLE_NO_INTERROGATE - "${CMAKE_${_lang}_COMPILER}" - CACHE FILEPATH "HDF5 ${_lang} compiler wrapper") - set(HDF5_${_lang}_DEFINITIONS) - set(HDF5_${_lang}_INCLUDE_DIRS) - set(HDF5_${_lang}_LIBRARIES) - set(HDF5_${_lang}_HL_LIBRARIES) - - mark_as_advanced(HDF5_${_lang}_COMPILER_EXECUTABLE_NO_INTERROGATE) - - set(HDF5_${_lang}_FOUND TRUE) - set(HDF5_HL_FOUND TRUE) - else() - set(HDF5_COMPILER_NO_INTERROGATE FALSE) - # If this language isn't using the wrapper, then try to seed the - # search options with the wrapper - find_program(HDF5_${_lang}_COMPILER_EXECUTABLE - NAMES ${HDF5_${_lang}_COMPILER_NAMES} NAMES_PER_DIR - HINTS ${HDF5_ROOT} - PATH_SUFFIXES bin Bin - DOC "HDF5 ${_lang} Wrapper compiler. Used only to detect HDF5 compile flags." - ${_HDF5_SEARCH_OPTS} - ) - mark_as_advanced( HDF5_${_lang}_COMPILER_EXECUTABLE ) - unset(HDF5_${_lang}_COMPILER_NAMES) - - if(HDF5_${_lang}_COMPILER_EXECUTABLE) - _HDF5_invoke_compiler(${_lang} HDF5_${_lang}_COMPILE_LINE - HDF5_${_lang}_RETURN_VALUE HDF5_${_lang}_VERSION HDF5_${_lang}_IS_PARALLEL) - if(HDF5_${_lang}_RETURN_VALUE EQUAL 0) - if(HDF5_FIND_DEBUG) - message(STATUS "HDF5: Using hdf5 compiler wrapper to determine ${_lang} configuration") - endif() - _HDF5_parse_compile_line( HDF5_${_lang}_COMPILE_LINE - HDF5_${_lang}_INCLUDE_DIRS - HDF5_${_lang}_DEFINITIONS - HDF5_${_lang}_LIBRARY_DIRS - HDF5_${_lang}_LIBRARY_NAMES - HDF5_${_lang}_HL_LIBRARY_NAMES - ) - set(HDF5_${_lang}_LIBRARIES) - - foreach(_lib IN LISTS HDF5_${_lang}_LIBRARY_NAMES) - set(_HDF5_SEARCH_NAMES_LOCAL) - if("x${_lib}" MATCHES "hdf5") - # hdf5 library - set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS}) - if(HDF5_USE_STATIC_LIBRARIES) - if(WIN32) - set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib}) - else() - set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib}.a) - endif() - endif() - else() - # external library - set(_HDF5_SEARCH_OPTS_LOCAL) - endif() - find_library(HDF5_${_lang}_LIBRARY_${_lib} - NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${_lib} NAMES_PER_DIR - HINTS ${HDF5_${_lang}_LIBRARY_DIRS} - ${HDF5_ROOT} - ${_HDF5_SEARCH_OPTS_LOCAL} - ) - unset(_HDF5_SEARCH_OPTS_LOCAL) - unset(_HDF5_SEARCH_NAMES_LOCAL) - if(HDF5_${_lang}_LIBRARY_${_lib}) - list(APPEND HDF5_${_lang}_LIBRARIES ${HDF5_${_lang}_LIBRARY_${_lib}}) - else() - list(APPEND HDF5_${_lang}_LIBRARIES ${_lib}) - endif() - endforeach() - if(HDF5_FIND_HL) - set(HDF5_${_lang}_HL_LIBRARIES) - foreach(_lib IN LISTS HDF5_${_lang}_HL_LIBRARY_NAMES) - set(_HDF5_SEARCH_NAMES_LOCAL) - if("x${_lib}" MATCHES "hdf5") - # hdf5 library - set(_HDF5_SEARCH_OPTS_LOCAL ${_HDF5_SEARCH_OPTS}) - if(HDF5_USE_STATIC_LIBRARIES) - if(WIN32) - set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib}) - else() - set(_HDF5_SEARCH_NAMES_LOCAL lib${_lib}.a) - endif() - endif() - else() - # external library - set(_HDF5_SEARCH_OPTS_LOCAL) - endif() - find_library(HDF5_${_lang}_LIBRARY_${_lib} - NAMES ${_HDF5_SEARCH_NAMES_LOCAL} ${_lib} NAMES_PER_DIR - HINTS ${HDF5_${_lang}_LIBRARY_DIRS} - ${HDF5_ROOT} - ${_HDF5_SEARCH_OPTS_LOCAL} - ) - unset(_HDF5_SEARCH_OPTS_LOCAL) - unset(_HDF5_SEARCH_NAMES_LOCAL) - if(HDF5_${_lang}_LIBRARY_${_lib}) - list(APPEND HDF5_${_lang}_HL_LIBRARIES ${HDF5_${_lang}_LIBRARY_${_lib}}) - else() - list(APPEND HDF5_${_lang}_HL_LIBRARIES ${_lib}) - endif() - endforeach() - set(HDF5_HL_FOUND TRUE) - endif() - - set(HDF5_${_lang}_FOUND TRUE) - if (HDF5_${_lang}_DEFINITIONS) - list(REMOVE_DUPLICATES HDF5_${_lang}_DEFINITIONS) - endif() - if(HDF5_${_lang}_INCLUDE_DIRS) - list(REMOVE_DUPLICATES HDF5_${_lang}_INCLUDE_DIRS) - endif() - else() - set(_HDF5_NEED_TO_SEARCH TRUE) - endif() - else() - set(_HDF5_NEED_TO_SEARCH TRUE) - endif() - endif() - if(HDF5_${_lang}_VERSION) - if(NOT HDF5_VERSION) - set(HDF5_VERSION ${HDF5_${_lang}_VERSION}) - elseif(NOT HDF5_VERSION VERSION_EQUAL HDF5_${_lang}_VERSION) - message(WARNING "HDF5 Version found for language ${_lang}, ${HDF5_${_lang}_VERSION} is different than previously found version ${HDF5_VERSION}") - endif() - endif() - if(DEFINED HDF5_${_lang}_IS_PARALLEL) - if(NOT DEFINED HDF5_IS_PARALLEL) - set(HDF5_IS_PARALLEL ${HDF5_${_lang}_IS_PARALLEL}) - elseif(NOT HDF5_IS_PARALLEL AND HDF5_${_lang}_IS_PARALLEL) - message(WARNING "HDF5 found for language ${_lang} is parallel but previously found language is not parallel.") - elseif(HDF5_IS_PARALLEL AND NOT HDF5_${_lang}_IS_PARALLEL) - message(WARNING "HDF5 found for language ${_lang} is not parallel but previously found language is parallel.") - endif() - endif() - endforeach() - unset(_lib) -else() - set(_HDF5_NEED_TO_SEARCH TRUE) -endif() - -if(NOT HDF5_FOUND AND HDF5_COMPILER_NO_INTERROGATE) - # No arguments necessary, all languages can use the compiler wrappers - set(HDF5_FOUND TRUE) - set(HDF5_METHOD "Included by compiler wrappers") - set(HDF5_REQUIRED_VARS HDF5_METHOD) -elseif(NOT HDF5_FOUND AND NOT _HDF5_NEED_TO_SEARCH) - # Compiler wrappers aren't being used by the build but were found and used - # to determine necessary include and library flags - set(HDF5_INCLUDE_DIRS) - set(HDF5_LIBRARIES) - set(HDF5_HL_LIBRARIES) - foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS) - if(HDF5_${_lang}_FOUND) - if(NOT HDF5_${_lang}_COMPILER_NO_INTERROGATE) - list(APPEND HDF5_DEFINITIONS ${HDF5_${_lang}_DEFINITIONS}) - list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIRS}) - list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_LIBRARIES}) - if(HDF5_FIND_HL) - list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARIES}) - endif() - endif() - endif() - endforeach() - if(HDF5_DEFINITIONS) - list(REMOVE_DUPLICATES HDF5_DEFINITIONS) - endif() - if(HDF5_INCLUDE_DIRS) - list(REMOVE_DUPLICATES HDF5_INCLUDE_DIRS) - endif() - set(HDF5_FOUND TRUE) - set(HDF5_REQUIRED_VARS HDF5_LIBRARIES) - if(HDF5_FIND_HL) - list(APPEND HDF5_REQUIRED_VARS HDF5_HL_LIBRARIES) - endif() -endif() - -find_program( HDF5_DIFF_EXECUTABLE - NAMES h5diff - HINTS ${HDF5_ROOT} - PATH_SUFFIXES bin Bin - ${_HDF5_SEARCH_OPTS} - DOC "HDF5 file differencing tool." ) -mark_as_advanced( HDF5_DIFF_EXECUTABLE ) - -if( NOT HDF5_FOUND ) - # seed the initial lists of libraries to find with items we know we need - set(HDF5_C_LIBRARY_NAMES hdf5) - set(HDF5_C_HL_LIBRARY_NAMES hdf5_hl ${HDF5_C_LIBRARY_NAMES} ) - - set(HDF5_CXX_LIBRARY_NAMES hdf5_cpp ${HDF5_C_LIBRARY_NAMES}) - set(HDF5_CXX_HL_LIBRARY_NAMES hdf5_hl_cpp ${HDF5_C_HL_LIBRARY_NAMES} ${HDF5_CXX_LIBRARY_NAMES}) - - set(HDF5_Fortran_LIBRARY_NAMES hdf5_fortran ${HDF5_C_LIBRARY_NAMES}) - set(HDF5_Fortran_HL_LIBRARY_NAMES hdf5_hl_fortran hdf5hl_fortran ${HDF5_C_HL_LIBRARY_NAMES} ${HDF5_Fortran_LIBRARY_NAMES}) - - # suffixes as seen on Linux, MSYS2, ... - set(_lib_suffixes hdf5) - if(NOT HDF5_PREFER_PARALLEL) - list(APPEND _lib_suffixes hdf5/serial) - endif() - if(HDF5_USE_STATIC_LIBRARIES) - set(_inc_suffixes include/static) - else() - set(_inc_suffixes include/shared) - endif() - - foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS) - # The "main" library. - set(_hdf5_main_library "") - - # find the HDF5 libraries - foreach(LIB IN LISTS HDF5_${_lang}_LIBRARY_NAMES) - if(HDF5_USE_STATIC_LIBRARIES) - # According to bug 1643 on the CMake bug tracker, this is the - # preferred method for searching for a static library. - # See https://gitlab.kitware.com/cmake/cmake/-/issues/1643. We search - # first for the full static library name, but fall back to a - # generic search on the name if the static search fails. - set( THIS_LIBRARY_SEARCH_DEBUG - lib${LIB}d.a lib${LIB}_debug.a lib${LIB}d lib${LIB}_D lib${LIB}_debug - lib${LIB}d-static.a lib${LIB}_debug-static.a ${LIB}d-static ${LIB}_D-static ${LIB}_debug-static ) - set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a lib${LIB} lib${LIB}-static.a ${LIB}-static) - else() - set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ${LIB}_D ${LIB}_debug ${LIB}d-shared ${LIB}_D-shared ${LIB}_debug-shared) - set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} ${LIB}-shared) - if(WIN32) - list(APPEND HDF5_DEFINITIONS "-DH5_BUILT_AS_DYNAMIC_LIB") - endif() - endif() - find_library(HDF5_${LIB}_LIBRARY_DEBUG - NAMES ${THIS_LIBRARY_SEARCH_DEBUG} - HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes} - ${_HDF5_SEARCH_OPTS} - ) - find_library(HDF5_${LIB}_LIBRARY_RELEASE - NAMES ${THIS_LIBRARY_SEARCH_RELEASE} - HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes} - ${_HDF5_SEARCH_OPTS} - ) - - # Set the "main" library if not already set. - if (NOT _hdf5_main_library) - if (HDF5_${LIB}_LIBRARY_RELEASE) - set(_hdf5_main_library "${HDF5_${LIB}_LIBRARY_RELEASE}") - elseif (HDF5_${LIB}_LIBRARY_DEBUG) - set(_hdf5_main_library "${HDF5_${LIB}_LIBRARY_DEBUG}") - endif () - endif () - - select_library_configurations( HDF5_${LIB} ) - list(APPEND HDF5_${_lang}_LIBRARIES ${HDF5_${LIB}_LIBRARY}) - endforeach() - if(HDF5_${_lang}_LIBRARIES) - set(HDF5_${_lang}_FOUND TRUE) - endif() - - # Append the libraries for this language binding to the list of all - # required libraries. - list(APPEND HDF5_LIBRARIES ${HDF5_${_lang}_LIBRARIES}) - - # find the HDF5 include directories - set(_hdf5_inc_extra_paths) - set(_hdf5_inc_extra_suffixes) - if("${_lang}" STREQUAL "Fortran") - set(HDF5_INCLUDE_FILENAME hdf5.mod HDF5.mod) - - # Add library-based search paths for Fortran modules. - if (NOT _hdf5_main_library STREQUAL "") - # gfortran module directory - if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - get_filename_component(_hdf5_library_dir "${_hdf5_main_library}" DIRECTORY) - list(APPEND _hdf5_inc_extra_paths "${_hdf5_library_dir}") - unset(_hdf5_library_dir) - list(APPEND _hdf5_inc_extra_suffixes gfortran/modules) - endif () - endif () - elseif("${_lang}" STREQUAL "CXX") - set(HDF5_INCLUDE_FILENAME H5Cpp.h) - else() - set(HDF5_INCLUDE_FILENAME hdf5.h) - endif() - - unset(_hdf5_main_library) - - find_path(HDF5_${_lang}_INCLUDE_DIR ${HDF5_INCLUDE_FILENAME} - HINTS ${HDF5_ROOT} - PATHS $ENV{HOME}/.local/include ${_hdf5_inc_extra_paths} - PATH_SUFFIXES include Include ${_inc_suffixes} ${_lib_suffixes} ${_hdf5_inc_extra_suffixes} - ${_HDF5_SEARCH_OPTS} - ) - mark_as_advanced(HDF5_${_lang}_INCLUDE_DIR) - unset(_hdf5_inc_extra_paths) - unset(_hdf5_inc_extra_suffixes) - # set the _DIRS variable as this is what the user will normally use - set(HDF5_${_lang}_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIR}) - list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${_lang}_INCLUDE_DIR}) - - if(HDF5_FIND_HL) - foreach(LIB IN LISTS HDF5_${_lang}_HL_LIBRARY_NAMES) - if(HDF5_USE_STATIC_LIBRARIES) - # According to bug 1643 on the CMake bug tracker, this is the - # preferred method for searching for a static library. - # See https://gitlab.kitware.com/cmake/cmake/-/issues/1643. We search - # first for the full static library name, but fall back to a - # generic search on the name if the static search fails. - set( THIS_LIBRARY_SEARCH_DEBUG - lib${LIB}d.a lib${LIB}_debug.a lib${LIB}d lib${LIB}_D lib${LIB}_debug - lib${LIB}d-static.a lib${LIB}_debug-static.a lib${LIB}d-static lib${LIB}_D-static lib${LIB}_debug-static ) - set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a lib${LIB} lib${LIB}-static.a lib${LIB}-static) - else() - set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ${LIB}_D ${LIB}_debug ${LIB}d-shared ${LIB}_D-shared ${LIB}_debug-shared) - set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} ${LIB}-shared) - endif() - find_library(HDF5_${LIB}_LIBRARY_DEBUG - NAMES ${THIS_LIBRARY_SEARCH_DEBUG} - HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes} - ${_HDF5_SEARCH_OPTS} - ) - find_library(HDF5_${LIB}_LIBRARY_RELEASE - NAMES ${THIS_LIBRARY_SEARCH_RELEASE} - HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes} - ${_HDF5_SEARCH_OPTS} - ) - - select_library_configurations( HDF5_${LIB} ) - list(APPEND HDF5_${_lang}_HL_LIBRARIES ${HDF5_${LIB}_LIBRARY}) - endforeach() - - # Append the libraries for this language binding to the list of all - # required libraries. - list(APPEND HDF5_HL_LIBRARIES ${HDF5_${_lang}_HL_LIBRARIES}) - endif() - endforeach() - if(HDF5_FIND_HL AND HDF5_HL_LIBRARIES) - set(HDF5_HL_FOUND TRUE) - endif() - - if(HDF5_DEFINITIONS) - list(REMOVE_DUPLICATES HDF5_DEFINITIONS) - endif() - if(HDF5_INCLUDE_DIRS) - list(REMOVE_DUPLICATES HDF5_INCLUDE_DIRS) - endif() - - # If the HDF5 include directory was found, open H5pubconf.h to determine if - # HDF5 was compiled with parallel IO support - unset(HDF5_IS_PARALLEL CACHE) - set( HDF5_IS_PARALLEL FALSE ) - set( HDF5_VERSION "" ) - foreach( _dir IN LISTS HDF5_INCLUDE_DIRS ) - foreach(_hdr "${_dir}/H5pubconf.h" "${_dir}/H5pubconf-64.h" "${_dir}/H5pubconf-32.h") - if( EXISTS "${_hdr}" ) - file( STRINGS "${_hdr}" - HDF5_HAVE_PARALLEL_DEFINE - REGEX "HAVE_PARALLEL 1" ) - if( HDF5_HAVE_PARALLEL_DEFINE ) - set( HDF5_IS_PARALLEL TRUE ) - endif() - unset(HDF5_HAVE_PARALLEL_DEFINE) - - file( STRINGS "${_hdr}" - HDF5_VERSION_DEFINE - REGEX "^[ \t]*#[ \t]*define[ \t]+H5_VERSION[ \t]+" ) - if( "${HDF5_VERSION_DEFINE}" MATCHES - "H5_VERSION[ \t]+\"([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?\"" ) - set( HDF5_VERSION "${CMAKE_MATCH_1}" ) - if( CMAKE_MATCH_3 ) - set( HDF5_VERSION ${HDF5_VERSION}.${CMAKE_MATCH_3}) - endif() - endif() - unset(HDF5_VERSION_DEFINE) - endif() - endforeach() - endforeach() - unset(_hdr) - unset(_dir) - set( HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL - "HDF5 library compiled with parallel IO support" ) - mark_as_advanced( HDF5_IS_PARALLEL ) - - set(HDF5_REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS) - if(HDF5_FIND_HL) - list(APPEND HDF5_REQUIRED_VARS HDF5_HL_LIBRARIES) - endif() -endif() - -# For backwards compatibility we set HDF5_INCLUDE_DIR to the value of -# HDF5_INCLUDE_DIRS -if( HDF5_INCLUDE_DIRS ) - set( HDF5_INCLUDE_DIR "${HDF5_INCLUDE_DIRS}" ) -endif() - -# If HDF5_REQUIRED_VARS is empty at this point, then it's likely that -# something external is trying to explicitly pass already found -# locations -if(NOT HDF5_REQUIRED_VARS) - set(HDF5_REQUIRED_VARS HDF5_LIBRARIES HDF5_INCLUDE_DIRS) -endif() - -find_package_handle_standard_args(HDF5 - REQUIRED_VARS ${HDF5_REQUIRED_VARS} - VERSION_VAR HDF5_VERSION - HANDLE_COMPONENTS -) - -unset(_HDF5_SEARCH_OPTS) - -if( HDF5_FOUND AND NOT HDF5_DIR) - # hide HDF5_DIR for the non-advanced user to avoid confusion with - # HDF5_DIR-NOT_FOUND while HDF5 was found. - mark_as_advanced(HDF5_DIR) -endif() - -if (HDF5_FOUND) - #if (NOT TARGET HDF5::HDF5) - #add_library(HDF5::HDF5 INTERFACE IMPORTED) - #string(REPLACE "-D" "" _hdf5_definitions "${HDF5_DEFINITIONS}") - #set_target_properties(HDF5::HDF5 PROPERTIES - #INTERFACE_INCLUDE_DIRECTORIES "${HDF5_INCLUDE_DIRS}" - #INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}") - #unset(_hdf5_definitions) - #target_link_libraries(HDF5::HDF5 INTERFACE ${HDF5_LIBRARIES}) - #endif () - - foreach (hdf5_lang IN LISTS HDF5_LANGUAGE_BINDINGS) - if (hdf5_lang STREQUAL "C") - set(hdf5_target_name "hdf5") - elseif (hdf5_lang STREQUAL "CXX") - set(hdf5_target_name "hdf5_cpp") - elseif (hdf5_lang STREQUAL "Fortran") - set(hdf5_target_name "hdf5_fortran") - else () - continue () - endif () - - if (NOT TARGET "hdf5::${hdf5_target_name}") - if (HDF5_COMPILER_NO_INTERROGATE) - add_library("hdf5::${hdf5_target_name}" INTERFACE IMPORTED) - string(REPLACE "-D" "" _hdf5_definitions "${HDF5_${hdf5_lang}_DEFINITIONS}") - set_target_properties("hdf5::${hdf5_target_name}" PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${HDF5_${hdf5_lang}_INCLUDE_DIRS}" - INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}") - else() - if (DEFINED "HDF5_${hdf5_target_name}_LIBRARY") - set(_hdf5_location "${HDF5_${hdf5_target_name}_LIBRARY}") - elseif (DEFINED "HDF5_${hdf5_lang}_LIBRARY") - set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY}") - elseif (DEFINED "HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}") - set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}}") - else () - # Error if we still don't have the location. - message(SEND_ERROR - "HDF5 was found, but a different variable was set which contains " - "the location of the `hdf5::${hdf5_target_name}` library.") - endif () - add_library("hdf5::${hdf5_target_name}" UNKNOWN IMPORTED) - string(REPLACE "-D" "" _hdf5_definitions "${HDF5_${hdf5_lang}_DEFINITIONS}") - if (NOT HDF5_${hdf5_lang}_INCLUDE_DIRS) - set(HDF5_${hdf5_lang}_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS}) - endif () - set_target_properties("hdf5::${hdf5_target_name}" PROPERTIES - IMPORTED_LOCATION "${_hdf5_location}" - IMPORTED_IMPLIB "${_hdf5_location}" - INTERFACE_INCLUDE_DIRECTORIES "${HDF5_${hdf5_lang}_INCLUDE_DIRS}" - INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}") - if (_hdf5_libtype STREQUAL "SHARED") - set_property(TARGET "hdf5::${hdf5_target_name}" APPEND - PROPERTY - INTERFACE_COMPILE_DEFINITIONS H5_BUILT_AS_DYNAMIC_LIB) - elseif (_hdf5_libtype STREQUAL "STATIC") - set_property(TARGET "hdf5::${hdf5_target_name}" APPEND - PROPERTY - INTERFACE_COMPILE_DEFINITIONS H5_BUILT_AS_STATIC_LIB) - endif () - unset(_hdf5_definitions) - unset(_hdf5_libtype) - unset(_hdf5_location) - endif () - endif () - - if (NOT HDF5_FIND_HL) - continue () - endif () - - set(hdf5_alt_target_name "") - if (hdf5_lang STREQUAL "C") - set(hdf5_target_name "hdf5_hl") - elseif (hdf5_lang STREQUAL "CXX") - set(hdf5_target_name "hdf5_hl_cpp") - elseif (hdf5_lang STREQUAL "Fortran") - set(hdf5_target_name "hdf5_hl_fortran") - set(hdf5_alt_target_name "hdf5hl_fortran") - else () - continue () - endif () - - if (NOT TARGET "hdf5::${hdf5_target_name}") - if (HDF5_COMPILER_NO_INTERROGATE) - add_library("hdf5::${hdf5_target_name}" INTERFACE IMPORTED) - string(REPLACE "-D" "" _hdf5_definitions "${HDF5_${hdf5_lang}_HL_DEFINITIONS}") - set_target_properties("hdf5::${hdf5_target_name}" PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${HDF5_${hdf5_lang}_HL_INCLUDE_DIRS}" - INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}") - else() - if (DEFINED "HDF5_${hdf5_target_name}_LIBRARY") - set(_hdf5_location "${HDF5_${hdf5_target_name}_LIBRARY}") - elseif (DEFINED "HDF5_${hdf5_lang}_HL_LIBRARY") - set(_hdf5_location "${HDF5_${hdf5_lang}_HL_LIBRARY}") - elseif (DEFINED "HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}") - set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}}") - elseif (hdf5_alt_target_name AND DEFINED "HDF5_${hdf5_lang}_LIBRARY_${hdf5_alt_target_name}") - set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY_${hdf5_alt_target_name}}") - else () - # Error if we still don't have the location. - message(SEND_ERROR - "HDF5 was found, but a different variable was set which contains " - "the location of the `hdf5::${hdf5_target_name}` library.") - endif () - add_library("hdf5::${hdf5_target_name}" UNKNOWN IMPORTED) - string(REPLACE "-D" "" _hdf5_definitions "${HDF5_${hdf5_lang}_HL_DEFINITIONS}") - set_target_properties("hdf5::${hdf5_target_name}" PROPERTIES - IMPORTED_LOCATION "${_hdf5_location}" - IMPORTED_IMPLIB "${_hdf5_location}" - INTERFACE_INCLUDE_DIRECTORIES "${HDF5_${hdf5_lang}_HL_INCLUDE_DIRS}" - INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}") - if (_hdf5_libtype STREQUAL "SHARED") - set_property(TARGET "hdf5::${hdf5_target_name}" APPEND - PROPERTY - INTERFACE_COMPILE_DEFINITIONS H5_BUILT_AS_DYNAMIC_LIB) - elseif (_hdf5_libtype STREQUAL "STATIC") - set_property(TARGET "hdf5::${hdf5_target_name}" APPEND - PROPERTY - INTERFACE_COMPILE_DEFINITIONS H5_BUILT_AS_STATIC_LIB) - endif () - unset(_hdf5_definitions) - unset(_hdf5_libtype) - unset(_hdf5_location) - endif () - endif () - endforeach () - unset(hdf5_lang) - - if (HDF5_DIFF_EXECUTABLE AND NOT TARGET hdf5::h5diff) - add_executable(hdf5::h5diff IMPORTED) - set_target_properties(hdf5::h5diff PROPERTIES - IMPORTED_LOCATION "${HDF5_DIFF_EXECUTABLE}") - endif () -endif () - -if (HDF5_FIND_DEBUG) - message(STATUS "HDF5_DIR: ${HDF5_DIR}") - message(STATUS "HDF5_DEFINITIONS: ${HDF5_DEFINITIONS}") - message(STATUS "HDF5_INCLUDE_DIRS: ${HDF5_INCLUDE_DIRS}") - message(STATUS "HDF5_LIBRARIES: ${HDF5_LIBRARIES}") - message(STATUS "HDF5_HL_LIBRARIES: ${HDF5_HL_LIBRARIES}") - foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS) - message(STATUS "HDF5_${_lang}_DEFINITIONS: ${HDF5_${_lang}_DEFINITIONS}") - message(STATUS "HDF5_${_lang}_INCLUDE_DIR: ${HDF5_${_lang}_INCLUDE_DIR}") - message(STATUS "HDF5_${_lang}_INCLUDE_DIRS: ${HDF5_${_lang}_INCLUDE_DIRS}") - message(STATUS "HDF5_${_lang}_LIBRARY: ${HDF5_${_lang}_LIBRARY}") - message(STATUS "HDF5_${_lang}_LIBRARIES: ${HDF5_${_lang}_LIBRARIES}") - message(STATUS "HDF5_${_lang}_HL_LIBRARY: ${HDF5_${_lang}_HL_LIBRARY}") - message(STATUS "HDF5_${_lang}_HL_LIBRARIES: ${HDF5_${_lang}_HL_LIBRARIES}") - endforeach() - message(STATUS "Defined targets (if any):") - foreach(_lang IN ITEMS "" "_cpp" "_fortran") - foreach(_hl IN ITEMS "" "_hl") - foreach(_prefix IN ITEMS "hdf5::" "") - foreach(_suffix IN ITEMS "-static" "-shared" "") - set (_target ${_prefix}hdf5${_hl}${_lang}${_suffix}) - if (TARGET ${_target}) - message(STATUS "... ${_target}") - else() - #message(STATUS "... ${_target} does not exist") - endif() - endforeach() - endforeach() - endforeach() - endforeach() -endif() -unset(_lang) -unset(_HDF5_NEED_TO_SEARCH) diff --git a/plugins/decl_hdf5/cmake/FindPackageHandleStandardArgs.cmake b/plugins/decl_hdf5/cmake/FindPackageHandleStandardArgs.cmake deleted file mode 100644 index 4fb08259a..000000000 --- a/plugins/decl_hdf5/cmake/FindPackageHandleStandardArgs.cmake +++ /dev/null @@ -1,466 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPackageHandleStandardArgs ------------------------------ - -This module provides a function intended to be used in :ref:`Find Modules` -implementing :command:`find_package()` calls. It handles the -``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. -It also sets the ``_FOUND`` variable. The package is -considered found if all variables listed contain valid results, e.g. -valid filepaths. - -.. command:: find_package_handle_standard_args - - There are two signatures:: - - find_package_handle_standard_args( - (DEFAULT_MSG|) - ... - ) - - find_package_handle_standard_args( - [FOUND_VAR ] - [REQUIRED_VARS ...] - [VERSION_VAR ] - [HANDLE_COMPONENTS] - [CONFIG_MODE] - [NAME_MISMATCHED] - [REASON_FAILURE_MESSAGE ] - [FAIL_MESSAGE ] - ) - - The ``_FOUND`` variable will be set to ``TRUE`` if all - the variables ``...`` are valid and any optional - constraints are satisfied, and ``FALSE`` otherwise. A success or - failure message may be displayed based on the results and on - whether the ``REQUIRED`` and/or ``QUIET`` option was given to - the :command:`find_package` call. - - The options are: - - ``(DEFAULT_MSG|)`` - In the simple signature this specifies the failure message. - Use ``DEFAULT_MSG`` to ask for a default message to be computed - (recommended). Not valid in the full signature. - - ``FOUND_VAR `` - Obsolete. Specifies either ``_FOUND`` or - ``_FOUND`` as the result variable. This exists only - for compatibility with older versions of CMake and is now ignored. - Result variables of both names are always set for compatibility. - - ``REQUIRED_VARS ...`` - Specify the variables which are required for this package. - These may be named in the generated failure message asking the - user to set the missing variable values. Therefore these should - typically be cache entries such as ``FOO_LIBRARY`` and not output - variables like ``FOO_LIBRARIES``. This option is mandatory if - ``HANDLE_COMPONENTS`` is not specified. - - ``VERSION_VAR `` - Specify the name of a variable that holds the version of the package - that has been found. This version will be checked against the - (potentially) specified required version given to the - :command:`find_package` call, including its ``EXACT`` option. - The default messages include information about the required - version and the version which has been actually found, both - if the version is ok or not. - - ``HANDLE_COMPONENTS`` - Enable handling of package components. In this case, the command - will report which components have been found and which are missing, - and the ``_FOUND`` variable will be set to ``FALSE`` - if any of the required components (i.e. not the ones listed after - the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are - missing. - - ``CONFIG_MODE`` - Specify that the calling find module is a wrapper around a - call to ``find_package( NO_MODULE)``. This implies - a ``VERSION_VAR`` value of ``_VERSION``. The command - will automatically check whether the package configuration file - was found. - - ``REASON_FAILURE_MESSAGE `` - Specify a custom message of the reason for the failure which will be - appended to the default generated message. - - ``FAIL_MESSAGE `` - Specify a custom failure message instead of using the default - generated message. Not recommended. - - ``NAME_MISMATCHED`` - Indicate that the ```` does not match - ``${CMAKE_FIND_PACKAGE_NAME}``. This is usually a mistake and raises a - warning, but it may be intentional for usage of the command for components - of a larger package. - -Example for the simple signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibXml2 DEFAULT_MSG - LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) - -The ``LibXml2`` package is considered to be found if both -``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. -Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found -and ``REQUIRED`` was used, it fails with a -:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was -used or not. If it is found, success will be reported, including -the content of the first ````. On repeated CMake runs, -the same message will not be printed again. - -.. note:: - - If ```` does not match ``CMAKE_FIND_PACKAGE_NAME`` for the - calling module, a warning that there is a mismatch is given. The - ``FPHSA_NAME_MISMATCHED`` variable may be set to bypass the warning if using - the old signature and the ``NAME_MISMATCHED`` argument using the new - signature. To avoid forcing the caller to require newer versions of CMake for - usage, the variable's value will be used if defined when the - ``NAME_MISMATCHED`` argument is not passed for the new signature (but using - both is an error).. - -Example for the full signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibArchive - REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR - VERSION_VAR LibArchive_VERSION) - -In this case, the ``LibArchive`` package is considered to be found if -both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. -Also the version of ``LibArchive`` will be checked by using the version -contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, -the default messages will be printed. - -Another example for the full signature: - -.. code-block:: cmake - - find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) - find_package_handle_standard_args(Automoc4 CONFIG_MODE) - -In this case, a ``FindAutmoc4.cmake`` module wraps a call to -``find_package(Automoc4 NO_MODULE)`` and adds an additional search -directory for ``automoc4``. Then the call to -``find_package_handle_standard_args`` produces a proper success/failure -message. -#]=======================================================================] - -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - -# internal helper macro -macro(_FPHSA_FAILURE_MESSAGE _msg) - set (__msg "${_msg}") - if (FPHSA_REASON_FAILURE_MESSAGE) - string(APPEND __msg "\n Reason given by package: ${FPHSA_REASON_FAILURE_MESSAGE}\n") - endif() - if (${_NAME}_FIND_REQUIRED) - message(FATAL_ERROR "${__msg}") - else () - if (NOT ${_NAME}_FIND_QUIETLY) - message(STATUS "${__msg}") - endif () - endif () -endmacro() - - -# internal helper macro to generate the failure message when used in CONFIG_MODE: -macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: - if(${_NAME}_CONFIG) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") - else() - # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. - # List them all in the error message: - if(${_NAME}_CONSIDERED_CONFIGS) - set(configsText "") - list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) - math(EXPR configsCount "${configsCount} - 1") - foreach(currentConfigIndex RANGE ${configsCount}) - list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) - list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) - string(APPEND configsText "\n ${filename} (version ${version})") - endforeach() - if (${_NAME}_NOT_FOUND_MESSAGE) - if (FPHSA_REASON_FAILURE_MESSAGE) - string(PREPEND FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}\n ") - else() - set(FPHSA_REASON_FAILURE_MESSAGE "${${_NAME}_NOT_FOUND_MESSAGE}") - endif() - else() - string(APPEND configsText "\n") - endif() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:${configsText}") - - else() - # Simple case: No Config-file was found at all: - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") - endif() - endif() -endmacro() - - -function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) - - # Set up the arguments for `cmake_parse_arguments`. - set(options CONFIG_MODE HANDLE_COMPONENTS NAME_MISMATCHED) - set(oneValueArgs FAIL_MESSAGE REASON_FAILURE_MESSAGE VERSION_VAR FOUND_VAR) - set(multiValueArgs REQUIRED_VARS) - - # Check whether we are in 'simple' or 'extended' mode: - set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) - list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) - - unset(FPHSA_NAME_MISMATCHED_override) - if (DEFINED FPHSA_NAME_MISMATCHED) - # If the variable NAME_MISMATCHED variable is set, error if it is passed as - # an argument. The former is for old signatures, the latter is for new - # signatures. - list(FIND ARGN "NAME_MISMATCHED" name_mismatched_idx) - if (NOT name_mismatched_idx EQUAL "-1") - message(FATAL_ERROR - "The `NAME_MISMATCHED` argument may only be specified by the argument or " - "the variable, not both.") - endif () - - # But use the variable if it is not an argument to avoid forcing minimum - # CMake version bumps for calling modules. - set(FPHSA_NAME_MISMATCHED_override "${FPHSA_NAME_MISMATCHED}") - endif () - - if(${INDEX} EQUAL -1) - set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) - set(FPHSA_REQUIRED_VARS ${ARGN}) - set(FPHSA_VERSION_VAR) - else() - cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) - - if(FPHSA_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") - endif() - - if(NOT FPHSA_FAIL_MESSAGE) - set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") - endif() - - # In config-mode, we rely on the variable _CONFIG, which is set by find_package() - # when it successfully found the config-file, including version checking: - if(FPHSA_CONFIG_MODE) - list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) - list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) - set(FPHSA_VERSION_VAR ${_NAME}_VERSION) - endif() - - if(NOT FPHSA_REQUIRED_VARS AND NOT FPHSA_HANDLE_COMPONENTS) - message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") - endif() - endif() - - if (DEFINED FPHSA_NAME_MISMATCHED_override) - set(FPHSA_NAME_MISMATCHED "${FPHSA_NAME_MISMATCHED_override}") - endif () - - if (DEFINED CMAKE_FIND_PACKAGE_NAME - AND NOT FPHSA_NAME_MISMATCHED - AND NOT _NAME STREQUAL CMAKE_FIND_PACKAGE_NAME) - message(AUTHOR_WARNING - "The package name passed to `find_package_handle_standard_args` " - "(${_NAME}) does not match the name of the calling package " - "(${CMAKE_FIND_PACKAGE_NAME}). This can lead to problems in calling " - "code that expects `find_package` result variables (e.g., `_FOUND`) " - "to follow a certain pattern.") - endif () - -# now that we collected all arguments, process them - - if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") - set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") - endif() - - if (FPHSA_REQUIRED_VARS) - list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) - endif() - - string(TOUPPER ${_NAME} _NAME_UPPER) - string(TOLOWER ${_NAME} _NAME_LOWER) - - if(FPHSA_FOUND_VAR) - set(_FOUND_VAR_UPPER ${_NAME_UPPER}_FOUND) - set(_FOUND_VAR_MIXED ${_NAME}_FOUND) - if(FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_MIXED OR FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_UPPER) - set(_FOUND_VAR ${FPHSA_FOUND_VAR}) - else() - message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_FOUND_VAR_MIXED}\" and \"${_FOUND_VAR_UPPER}\" are valid names.") - endif() - else() - set(_FOUND_VAR ${_NAME_UPPER}_FOUND) - endif() - - # collect all variables which were not found, so they can be printed, so the - # user knows better what went wrong (#6375) - set(MISSING_VARS "") - set(DETAILS "") - # check if all passed variables are valid - set(FPHSA_FOUND_${_NAME} TRUE) - foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) - if(NOT ${_CURRENT_VAR}) - set(FPHSA_FOUND_${_NAME} FALSE) - string(APPEND MISSING_VARS " ${_CURRENT_VAR}") - else() - string(APPEND DETAILS "[${${_CURRENT_VAR}}]") - endif() - endforeach() - if(FPHSA_FOUND_${_NAME}) - set(${_NAME}_FOUND TRUE) - set(${_NAME_UPPER}_FOUND TRUE) - else() - set(${_NAME}_FOUND FALSE) - set(${_NAME_UPPER}_FOUND FALSE) - endif() - - # component handling - unset(FOUND_COMPONENTS_MSG) - unset(MISSING_COMPONENTS_MSG) - - if(FPHSA_HANDLE_COMPONENTS) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(${_NAME}_${comp}_FOUND) - - if(NOT DEFINED FOUND_COMPONENTS_MSG) - set(FOUND_COMPONENTS_MSG "found components:") - endif() - string(APPEND FOUND_COMPONENTS_MSG " ${comp}") - - else() - - if(NOT DEFINED MISSING_COMPONENTS_MSG) - set(MISSING_COMPONENTS_MSG "missing components:") - endif() - string(APPEND MISSING_COMPONENTS_MSG " ${comp}") - - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - string(APPEND MISSING_VARS " ${comp}") - endif() - - endif() - endforeach() - set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") - string(APPEND DETAILS "[c${COMPONENT_MSG}]") - endif() - - # version handling: - set(VERSION_MSG "") - set(VERSION_OK TRUE) - - # check with DEFINED here as the requested or found version may be "0" - if (DEFINED ${_NAME}_FIND_VERSION) - if(DEFINED ${FPHSA_VERSION_VAR}) - set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) - - if(${_NAME}_FIND_VERSION_EXACT) # exact version required - # count the dots in the version string - string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}") - # add one dot because there is one dot more than there are components - string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) - if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) - # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT - # is at most 4 here. Therefore a simple lookup table is used. - if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) - set(_VERSION_REGEX "[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) - set(_VERSION_REGEX "[^.]*\\.[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") - else () - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") - endif () - string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}") - unset(_VERSION_REGEX) - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - unset(_VERSION_HEAD) - else () - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - endif () - unset(_VERSION_DOTS) - - else() # minimum version specified: - if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") - endif () - endif() - - else() - - # if the package was not found, but a version was given, add that to the output: - if(${_NAME}_FIND_VERSION_EXACT) - set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") - else() - set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") - endif() - - endif() - else () - # Check with DEFINED as the found version may be 0. - if(DEFINED ${FPHSA_VERSION_VAR}) - set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") - endif() - endif () - - if(VERSION_OK) - string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") - else() - set(${_NAME}_FOUND FALSE) - endif() - - - # print the result: - if (${_NAME}_FOUND) - FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") - else () - - if(FPHSA_CONFIG_MODE) - _FPHSA_HANDLE_FAILURE_CONFIG_MODE() - else() - if(NOT VERSION_OK) - set(RESULT_MSG) - if (_FIRST_REQUIRED_VAR) - string (APPEND RESULT_MSG "found ${${_FIRST_REQUIRED_VAR}}") - endif() - if (COMPONENT_MSG) - if (RESULT_MSG) - string (APPEND RESULT_MSG ", ") - endif() - string (APPEND RESULT_MSG "${FOUND_COMPONENTS_MSG}") - endif() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (${RESULT_MSG})") - else() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") - endif() - endif() - - endif () - - set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) - set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) -endfunction() diff --git a/plugins/decl_hdf5/cmake/FindPackageMessage.cmake b/plugins/decl_hdf5/cmake/FindPackageMessage.cmake deleted file mode 100644 index 0628b9816..000000000 --- a/plugins/decl_hdf5/cmake/FindPackageMessage.cmake +++ /dev/null @@ -1,48 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPackageMessage ------------------- - -.. code-block:: cmake - - find_package_message( "message for user" "find result details") - -This function is intended to be used in FindXXX.cmake modules files. -It will print a message once for each unique find result. This is -useful for telling the user where a package was found. The first -argument specifies the name (XXX) of the package. The second argument -specifies the message to display. The third argument lists details -about the find result so that if they change the message will be -displayed again. The macro also obeys the QUIET argument to the -find_package command. - -Example: - -.. code-block:: cmake - - if(X11_FOUND) - find_package_message(X11 "Found X11: ${X11_X11_LIB}" - "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") - else() - ... - endif() -#]=======================================================================] - -function(find_package_message pkg msg details) - # Avoid printing a message repeatedly for the same find result. - if(NOT ${pkg}_FIND_QUIETLY) - string(REPLACE "\n" "" details "${details}") - set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) - if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - # The message has not yet been printed. - message(STATUS "${msg}") - - # Save the find details in the cache to avoid printing the same - # message again. - set("${DETAILS_VAR}" "${details}" - CACHE INTERNAL "Details about finding ${pkg}") - endif() - endif() -endfunction() diff --git a/plugins/decl_hdf5/cmake/SelectLibraryConfigurations.cmake b/plugins/decl_hdf5/cmake/SelectLibraryConfigurations.cmake deleted file mode 100644 index 4c0e9a8c0..000000000 --- a/plugins/decl_hdf5/cmake/SelectLibraryConfigurations.cmake +++ /dev/null @@ -1,80 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -SelectLibraryConfigurations ---------------------------- - -.. code-block:: cmake - - select_library_configurations(basename) - -This macro takes a library base name as an argument, and will choose -good values for the variables - -:: - - basename_LIBRARY - basename_LIBRARIES - basename_LIBRARY_DEBUG - basename_LIBRARY_RELEASE - -depending on what has been found and set. - -If only ``basename_LIBRARY_RELEASE`` is defined, ``basename_LIBRARY`` will -be set to the release value, and ``basename_LIBRARY_DEBUG`` will be set -to ``basename_LIBRARY_DEBUG-NOTFOUND``. If only ``basename_LIBRARY_DEBUG`` -is defined, then ``basename_LIBRARY`` will take the debug value, and -``basename_LIBRARY_RELEASE`` will be set to ``basename_LIBRARY_RELEASE-NOTFOUND``. - -If the generator supports configuration types, then ``basename_LIBRARY`` -and ``basename_LIBRARIES`` will be set with debug and optimized flags -specifying the library to be used for the given configuration. If no -build type has been set or the generator in use does not support -configuration types, then ``basename_LIBRARY`` and ``basename_LIBRARIES`` -will take only the release value, or the debug value if the release one -is not set. -#]=======================================================================] - -# This macro was adapted from the FindQt4 CMake module and is maintained by Will -# Dicharry . - -macro(select_library_configurations basename) - if(NOT ${basename}_LIBRARY_RELEASE) - set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.") - endif() - if(NOT ${basename}_LIBRARY_DEBUG) - set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.") - endif() - - get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND - NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND - ( _isMultiConfig OR CMAKE_BUILD_TYPE ) ) - # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for - # single-config generators, set optimized and debug libraries - set( ${basename}_LIBRARY "" ) - foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE ) - list( APPEND ${basename}_LIBRARY optimized "${_libname}" ) - endforeach() - foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG ) - list( APPEND ${basename}_LIBRARY debug "${_libname}" ) - endforeach() - elseif( ${basename}_LIBRARY_RELEASE ) - set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) - elseif( ${basename}_LIBRARY_DEBUG ) - set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} ) - else() - set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND") - endif() - - set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" ) - - if( ${basename}_LIBRARY ) - set( ${basename}_FOUND TRUE ) - endif() - - mark_as_advanced( ${basename}_LIBRARY_RELEASE - ${basename}_LIBRARY_DEBUG - ) -endmacro() diff --git a/plugins/decl_hdf5/dataset_explicit_type.h b/plugins/decl_hdf5/dataset_explicit_type.h new file mode 100644 index 000000000..6cf3cbf48 --- /dev/null +++ b/plugins/decl_hdf5/dataset_explicit_type.h @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (C) 2025-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#ifndef DECL_HDF5_DATASET_EXPLICIT_TYPE_H_ +#define DECL_HDF5_DATASET_EXPLICIT_TYPE_H_ + +#include +#include + +#include + +#include + +namespace decl_hdf5 { + +/// Information about the types that should be used to create datasets as provided in the Yaml file +class Dataset_explicit_type +{ + /// definition from the YAML as a string for debugging purpose + std::string m_definition; + + /// the parsed regex that determines if the provided type applies (depend only on m_definition and regex grammar) + std::regex m_regex; + + /// begin line number in the YAML for debugging purposes + int m_begin_line; + + /// end line number in the YAML for debugging purposes + int m_end_line; + + /// the type to use for the dataset in case the regex matches + PDI::Datatype_template_sptr m_type; + +public: + /** Constructor of Dataset_explicit_type + * + * \param def the definition or generic name of the dataset in the Yaml file + * \param b_line first line in the Yaml file where the dataset is defined + * \param e_line last line in the Yaml file where the dataset is defined + * \param regex the regex that correspond to the string contains in def + * \param type the type to use for the dataset in case the regex matches + */ + Dataset_explicit_type(std::string def, int b_line, int e_line, std::regex regex, PDI::Datatype_template_sptr type) + : m_definition(def) + , m_begin_line(b_line) + , m_regex(regex) + , m_end_line(e_line) + , m_type(type) + {} + + /// function to get the line where the dataset is defined in Yaml file + std::string get_msg_err_line() const + { + std::string result; + if (m_begin_line == m_end_line) { + result = " defined in line " + std::to_string(m_begin_line + 1); + } else { + result = " defined in lines " + std::to_string(m_begin_line + 1) + " - " + std::to_string(m_end_line); + } + return result; + } + + /** Accesses the name given in Yaml file to define the dataset + * + * \return the name given in Yaml file to define the dataset + */ + std::string definition() const { return m_definition; } + + /** Accesses the regex corresponding to this dataset + * + * \return the regex corresponding to this dataset + */ + std::regex regex() const { return m_regex; } + + /** Accesses the type to use for the dataset + * + * \return the type to use for the dataset + */ + PDI::Datatype_template_sptr type() const { return m_type; } +}; + +} // namespace decl_hdf5 + +#endif // DECL_HDF5_DATASET_EXPLICIT_TYPE_H_ diff --git a/plugins/decl_hdf5/dataset_op.cxx b/plugins/decl_hdf5/dataset_op.cxx index 5058a2715..66aba7f0b 100644 --- a/plugins/decl_hdf5/dataset_op.cxx +++ b/plugins/decl_hdf5/dataset_op.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021-2022 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -29,6 +29,8 @@ #endif #include +#include +#include #include #include #include @@ -41,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -52,7 +55,6 @@ #include "dataset_op.h" using PDI::Array_datatype; -using PDI::Config_error; using PDI::Context; using PDI::Datatype; using PDI::Datatype_sptr; @@ -62,6 +64,7 @@ using PDI::Expression; using PDI::Ref_r; using PDI::Ref_w; using PDI::Scalar_datatype; +using PDI::Spectree_error; using PDI::System_error; using PDI::to_string; using PDI::Tuple_datatype; @@ -69,6 +72,8 @@ using PDI::Type_error; using PDI::Value_error; using std::dynamic_pointer_cast; using std::function; +using std::pair; +using std::regex; using std::string; using std::stringstream; using std::tie; @@ -91,7 +96,7 @@ tuple, vector, vector> get_selection(hid_t sel vector subsize(rank); if (0 > H5Sget_select_bounds(selection, &start[0], &subsize[0])) handle_hdf5_err(); transform(start.begin(), start.end(), subsize.begin(), subsize.begin(), [](hsize_t start, hsize_t end) { return end - start + 1; }); - return make_tuple(move(size), move(start), move(subsize)); + return make_tuple(std::move(size), std::move(start), std::move(subsize)); } /** Validates that memory space and dataset space number of elements match @@ -120,7 +125,7 @@ void validate_dataspaces(PC_tree_t selectree, hid_t h5_mem_space, hid_t h5_file_ file_desc << " (" << pr_start[ii] << "-" << (pr_start[ii] + pr_subsize[ii] - 1) << "/0-" << (pr_size[ii] - 1) << ")"; - throw Config_error{selectree, "Incompatible selections while writing `{}': [{} ] -> [{} ]", dataset_name, mem_desc.str(), file_desc.str()}; + throw Spectree_error{selectree, "Incompatible selections while writing `{}': [{} ] -> [{} ]", dataset_name, mem_desc.str(), file_desc.str()}; } } @@ -150,7 +155,7 @@ Dataset_op::Dataset_op(Direction dir, string name, Expression default_when, PC_t #ifdef H5_HAVE_PARALLEL m_communicator = to_string(value); #else - throw Config_error {value, "Used HDF5 is not parallel. Invalid communicator: `{}'", to_string(value)}; + throw Spectree_error {value, "Used HDF5 is not parallel. Invalid communicator: `{}'", to_string(value)}; #endif } else if (key == "memory_selection") { m_memory_selection = value; @@ -170,12 +175,12 @@ Dataset_op::Dataset_op(Direction dir, string name, Expression default_when, PC_t } else if (to_string(value) == "COLLECTIVE") { m_mpio = H5FD_MPIO_COLLECTIVE; } else { - throw Config_error{key_tree, "Not valid mpio value: `{}'. Expecting INDEPENDENT or COLLECTIVE.", to_string(value)}; + throw Spectree_error{key_tree, "Not valid mpio value: `{}'. Expecting INDEPENDENT or COLLECTIVE.", to_string(value)}; } } else if (key == "collision_policy") { m_collision_policy = to_collision_policy(to_string(value)); } else { - throw Config_error{key_tree, "Unknown key for HDF5 dataset configuration: `{}'", key}; + throw Spectree_error{key_tree, "Unknown key for HDF5 dataset configuration: `{}'", key}; } } }); @@ -211,7 +216,7 @@ void Dataset_op::fletcher(Context& ctx, Expression value) } } -void Dataset_op::execute(Context& ctx, hid_t h5_file, bool use_mpio, const unordered_map& dsets) +void Dataset_op::execute(Context& ctx, hid_t h5_file, bool use_mpio, const std::vector& dsets) { Raii_hid xfer_lst = make_raii_hid(H5Pcreate(H5P_DATASET_XFER), H5Pclose); #ifdef H5_HAVE_PARALLEL @@ -345,7 +350,7 @@ hid_t Dataset_op::dataset_creation_plist(Context& ctx, const Datatype* dataset_t return dset_plist; } -void Dataset_op::do_write(Context& ctx, hid_t h5_file, hid_t write_lst, const unordered_map& dsets) +void Dataset_op::do_write(Context& ctx, hid_t h5_file, hid_t write_lst, const std::vector& dsets) { string dataset_name = m_dataset.to_string(ctx); ctx.logger().trace("Preparing for writing `{}' dataset", dataset_name); @@ -360,17 +365,61 @@ void Dataset_op::do_write(Context& ctx, hid_t h5_file, hid_t write_lst, const un ctx.logger().trace("Applying `{}' memory selection", dataset_name); m_memory_selection.apply(ctx, h5_mem_space); - auto&& dataset_type_iter = dsets.find(dataset_name); Datatype_sptr dataset_type; Raii_hid h5_file_type, h5_file_space; - if (dataset_type_iter != dsets.end()) { - dataset_type = dataset_type_iter->second->evaluate(ctx); + + std::optional dset_found; + ctx.logger().trace("search `{}' in the list of datasets section", dataset_name); + + for (auto&& dsets_elem = dsets.begin(); dsets_elem != dsets.end(); ++dsets_elem) { + if (std::regex_match(dataset_name, dsets_elem->regex())) { + if (!dset_found.has_value()) { + ctx.logger() + .trace(" `{}' matches an element of datasets(defined as regex) with value := `{}'", dataset_name, dsets_elem->definition()); + dset_found = *dsets_elem; + } else { + // if we found an other element in the list of datasets, we can't choose the right dataset + // (if the elements found have different size, subsize, type, ...) + // send a error a message to the user + std::vector list_dataset_found; + list_dataset_found.emplace_back(dset_found->definition() + dset_found->get_msg_err_line()); + list_dataset_found.emplace_back(dsets_elem->definition() + dsets_elem->get_msg_err_line()); + ++dsets_elem; // get the next element in the iterator on dsets + // loop over the rest of the elements in the iterator on dsets + for (; dsets_elem != dsets.end(); ++dsets_elem) { + if (std::regex_match(dataset_name, dsets_elem->regex())) { + list_dataset_found.emplace_back(dsets_elem->definition() + dsets_elem->get_msg_err_line()); + } + } + + // Remark: message error is defined outside Config_error because is too long. + static constexpr char const * const msg_config_error + = "Found `{0}' match(es) in the list of datasets section for `{1}'." + " Cannot choose the right element in datasets.\n" + "The elements that match `{1}' are:\n" + " - {2}\n" + "Attention: The elements are considered as a regex."; + + throw Spectree_error{ + m_dataset_selection.selection_tree(), + msg_config_error, + list_dataset_found.size(), + dataset_name, + fmt::join(list_dataset_found, "\n - ") + }; + } + } + } + + if (dset_found.has_value()) { + ctx.logger().trace("Get the regex in the list of datasets section := `{}'", dset_found->definition()); + dataset_type = dset_found->type()->evaluate(ctx); tie(h5_file_space, h5_file_type) = space(dataset_type); ctx.logger().trace("Applying `{}' dataset selection", dataset_name); m_dataset_selection.apply(ctx, h5_file_space, h5_mem_space); } else { if (!m_dataset_selection.size().empty()) { - throw Config_error{m_dataset_selection.selection_tree(), "Dataset selection is invalid in implicit dataset `{}'", dataset_name}; + throw Spectree_error{m_dataset_selection.selection_tree(), "Dataset selection is invalid for implicit dataset `{}'", dataset_name}; } dataset_type = ref.type(); tie(h5_file_space, h5_file_type) = space(dataset_type, true); diff --git a/plugins/decl_hdf5/dataset_op.h b/plugins/decl_hdf5/dataset_op.h index aaa63bec8..8d58df0da 100644 --- a/plugins/decl_hdf5/dataset_op.h +++ b/plugins/decl_hdf5/dataset_op.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021-2022 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -43,6 +43,7 @@ #include "attribute_op.h" #include "collision_policy.h" +#include "dataset_explicit_type.h" #include "selection.h" namespace decl_hdf5 { @@ -186,14 +187,14 @@ class Dataset_op * \param ctx the context in which to operate * \param h5_file the already opened HDF5 file id * \param use_mpio whether the hdf5 read/write is parallel - * \param dsets the type of the explicitly typed datasets + * \param dsets the vector of the explicitly typed datasets defined in Yaml file. */ - void execute(PDI::Context& ctx, hid_t h5_file, bool use_mpio, const std::unordered_map& dsets); + void execute(PDI::Context& ctx, hid_t h5_file, bool use_mpio, const std::vector& dsets); private: void do_read(PDI::Context& ctx, hid_t h5_file, hid_t read_lst); - void do_write(PDI::Context& ctx, hid_t h5_file, hid_t xfer_lst, const std::unordered_map& dsets); + void do_write(PDI::Context& ctx, hid_t h5_file, hid_t xfer_lst, const std::vector& dsets); }; } // namespace decl_hdf5 diff --git a/plugins/decl_hdf5/file_op.cxx b/plugins/decl_hdf5/file_op.cxx index 61f296823..1d0b61586 100644 --- a/plugins/decl_hdf5/file_op.cxx +++ b/plugins/decl_hdf5/file_op.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021-2022 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -26,7 +26,11 @@ #include #ifdef H5_HAVE_PARALLEL #include +#ifdef H5_HAVE_SUBFILING_VFD +#include #endif +#endif + #include #include @@ -41,7 +45,6 @@ #include "file_op.h" -using PDI::Config_error; using PDI::Context; using PDI::each; using PDI::Error; @@ -49,10 +52,10 @@ using PDI::Expression; using PDI::opt_each; using PDI::Ref_r; using PDI::Ref_w; +using PDI::Spectree_error; using PDI::System_error; using PDI::to_string; using std::function; -using std::move; using std::string; using std::unique_ptr; using std::unordered_map; @@ -85,16 +88,30 @@ vector File_op::parse(Context& ctx, PC_tree_t tree) #ifdef H5_HAVE_PARALLEL template_op.m_communicator = to_string(value); #else - throw Config_error {key_tree, "Used HDF5 is not parallel. Invalid communicator: `{}'", to_string(value)}; + throw Spectree_error {key_tree, "Used HDF5 is not parallel. Invalid communicator: `{}'", to_string(value)}; #endif } else if (key == "datasets") { each(value, [&](PC_tree_t dset_name, PC_tree_t dset_type) { - template_op.m_datasets.emplace(to_string(dset_name), ctx.datatype(dset_type)); + std::string dset_name_value = to_string(dset_name); + std::regex dset_regex(dset_name_value, std::regex::ECMAScript); + if (dset_type.node && dset_name.node) { + template_op.m_datasets.emplace_back( + dset_name_value, + dset_name.node->start_mark.line, + dset_type.node->end_mark.line, + dset_regex, + ctx.datatype(dset_type) + ); + } else { + Spectree_error{key_tree, "Error in the definiion of dataset `{}' in datasets section.", dset_name_value}; + } }); } else if (key == "deflate") { deflate = value; } else if (key == "fletcher") { fletcher = value; + } else if (key == "subfiling") { + template_op.m_subfiling = value; } else if (key == "write") { // will read in pass 2 } else if (key == "read") { @@ -102,7 +119,7 @@ vector File_op::parse(Context& ctx, PC_tree_t tree) } else if (key == "logging") { // pass } else { - throw Config_error{key_tree, "Unknown key in HDF5 file configuration: `{}'", key}; + throw Spectree_error{key_tree, "Unknown key in HDF5 file configuration: `{}'", key}; } }); @@ -186,31 +203,31 @@ vector File_op::parse(Context& ctx, PC_tree_t tree) } #endif one_op.m_dset_ops.emplace_back(one_dset_op); - result.emplace_back(move(one_op)); + result.emplace_back(std::move(one_op)); } for (auto&& one_attr_op: attr_ops) { File_op one_op = template_op; one_op.m_attr_ops.emplace_back(one_attr_op); - result.emplace_back(move(one_op)); + result.emplace_back(std::move(one_op)); } for (auto&& one_dset_size_op: dset_size_ops) { File_op one_op = template_op; one_op.m_dset_size_ops.emplace(one_dset_size_op.first, one_dset_size_op.second); - result.emplace_back(move(one_op)); + result.emplace_back(std::move(one_op)); } } else { #ifdef H5_HAVE_PARALLEL // check the dataset ops don't have specific communicators set for (auto&& one_dset_op: dset_ops) { if (one_dset_op.communicator()) { - throw Config_error{tree, "Communicator can not be set at the dataset level for event triggered I/O"}; + throw Spectree_error{tree, "Communicator can not be set at the dataset level for event triggered I/O"}; } } #endif - template_op.m_dset_ops = move(dset_ops); - template_op.m_attr_ops = move(attr_ops); - template_op.m_dset_size_ops = move(dset_size_ops); - result.emplace_back(move(template_op)); + template_op.m_dset_ops = std::move(dset_ops); + template_op.m_attr_ops = std::move(attr_ops); + template_op.m_dset_size_ops = std::move(dset_size_ops); + result.emplace_back(std::move(template_op)); } return result; @@ -223,6 +240,9 @@ File_op::File_op(const File_op& other) , #ifdef H5_HAVE_PARALLEL m_communicator{other.m_communicator} +#ifdef H5_HAVE_SUBFILING_VFD + , m_subfiling{other.m_subfiling} +#endif , #endif m_dset_ops{other.m_dset_ops} @@ -230,13 +250,13 @@ File_op::File_op(const File_op& other) , m_dset_size_ops{other.m_dset_size_ops} { for (auto&& dataset: other.m_datasets) { - m_datasets.emplace(dataset.first, dataset.second); + m_datasets.emplace_back(dataset); } } File_op::File_op(Expression&& file, Collision_policy collision_policy) : m_collision_policy{collision_policy} - , m_file{move(file)} + , m_file{std::move(file)} {} void File_op::execute(Context& ctx) @@ -254,8 +274,9 @@ void File_op::execute(Context& ctx) dset_writes.push_back(one_dset_op); } } - } catch (const Error& e) { - ctx.logger().warn("Unable to evaluate when close while executing transfer for {}: `{}'", one_dset_op.value(), e.what()); + } catch (PDI::Value_error const & e) { + //TODO: explain why we only warn here + ctx.logger().warn("Unable to evaluate \"when\" close while executing transfer for {}: `{}'", one_dset_op.value(), e.what()); } } @@ -271,8 +292,9 @@ void File_op::execute(Context& ctx) attr_writes.push_back(one_attr_op); } } - } catch (const Error& e) { - ctx.logger().warn("Unable to evaluate when close while executing transfer for {}: `{}'", one_attr_op.name(), e.what()); + } catch (PDI::Value_error const & e) { + //TODO: explain why we only warn here + ctx.logger().warn("Unable to evaluate \"when\" close while executing transfer for {}: `{}'", one_attr_op.name(), e.what()); } } // nothing to do if no op is selected @@ -290,6 +312,44 @@ void File_op::execute(Context& ctx) if (0 > H5Pset_fapl_mpio(file_lst, comm, MPI_INFO_NULL)) handle_hdf5_err(); use_mpio = true; ctx.logger().debug("Opening `{}' file in parallel mode", filename); + + if (auto subfiling_stripe_count = subfiling().count().to_long(ctx)) { +#ifndef H5_HAVE_SUBFILING_VFD + if (subfiling().policy().to_string(ctx) == "CONTINUE") { + ctx.logger().warn("Used HDF5 does not support subfiling. HDF5 subfiling is ignored"); + } else { + throw System_error{"Used HDF5 does not support subfiling. Please set subfiling to 0."}; + } +#endif + int provided; + MPI_Query_thread(&provided); + if (provided < MPI_THREAD_MULTIPLE) { + if (subfiling().policy().to_string(ctx) == "CONTINUE") { + subfiling_stripe_count = 0; + ctx.logger().warn("MPI is not initialized with MPI_THREAD_MULTIPLE. HDF5 subfiling is ignored"); + } else { + throw System_error{"HDF5 subfiling requires MPI_THREAD_MULTIPLE (3). The provided level of thread support is {}", provided}; + } + } +#ifdef H5_HAVE_SUBFILING_VFD + if (subfiling_stripe_count != 0) { + ctx.logger().info("HDF5 subfiling enabled for file {}", filename); + H5FD_subfiling_config_t subf_config; + H5Pget_fapl_subfiling(file_lst, &subf_config); + subf_config.shared_cfg.stripe_count = subfiling_stripe_count; + if (auto stripe_size = subfiling().stripe_size().to_long(ctx)) { + if (stripe_size > 0) { + subf_config.shared_cfg.stripe_size = stripe_size; + } else if (stripe_size < 0) { + throw System_error{"Negative stripe_size is provided. Please set stripe_size > 0."}; + } else { + ctx.logger().warn("Using default stripe_size"); + } + } + H5Pset_fapl_subfiling(file_lst, &subf_config); + } +#endif + } } #endif diff --git a/plugins/decl_hdf5/file_op.h b/plugins/decl_hdf5/file_op.h index ab2126b17..b722c9a21 100644 --- a/plugins/decl_hdf5/file_op.h +++ b/plugins/decl_hdf5/file_op.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -32,6 +32,7 @@ #include #endif +#include #include #include #include @@ -43,7 +44,9 @@ #include "attribute_op.h" #include "collision_policy.h" +#include "dataset_explicit_type.h" #include "dataset_op.h" +#include "subfiling.h" namespace decl_hdf5 { @@ -61,13 +64,15 @@ class File_op /// a list of events that trigger this operation std::vector m_event; + Subfiling m_subfiling; + #ifdef H5_HAVE_PARALLEL /// a communicator for parallel HDF5 (null if no comm is specified) PDI::Expression m_communicator; #endif - /// type of the datasets for which an explicit type is specified - std::unordered_map m_datasets; + /// type information for the datasets for which an explicit type is specified + std::vector m_datasets; /// the dataset operations std::vector m_dset_ops; @@ -120,6 +125,8 @@ class File_op PDI::Expression communicator() const { return m_communicator; } #endif + Subfiling const & subfiling() const { return m_subfiling; } + /** Executes the requested operation. * * \param ctx the context in which to operate diff --git a/plugins/decl_hdf5/hdf5_wrapper.cxx b/plugins/decl_hdf5/hdf5_wrapper.cxx index 71b3809fa..88aa7d432 100644 --- a/plugins/decl_hdf5/hdf5_wrapper.cxx +++ b/plugins/decl_hdf5/hdf5_wrapper.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,7 +49,6 @@ using PDI::System_error; using PDI::Type_error; using std::dynamic_pointer_cast; using std::make_tuple; -using std::move; using std::string; using std::tie; using std::tuple; @@ -175,7 +174,7 @@ tuple space(Datatype_sptr type, bool dense) Raii_hid h5_space = make_raii_hid(H5Screate_simple(rank, &h5_size[0], NULL), H5Sclose); if (0 > H5Sselect_hyperslab(h5_space, H5S_SELECT_SET, &h5_start[0], NULL, &h5_subsize[0], NULL)) handle_hdf5_err(); - return make_tuple(move(h5_space), Raii_hid{get_h5_type(subtype), H5Tclose}); + return make_tuple(std::move(h5_space), Raii_hid{get_h5_type(subtype), H5Tclose}); } else { if (!type->dense()) { throw Type_error{"The top array datatype is the only one that can be sparse in dataset"}; diff --git a/plugins/decl_hdf5/hdf5_wrapper.h b/plugins/decl_hdf5/hdf5_wrapper.h index 4caf5e48e..a5e764149 100644 --- a/plugins/decl_hdf5/hdf5_wrapper.h +++ b/plugins/decl_hdf5/hdf5_wrapper.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,36 +48,6 @@ namespace decl_hdf5 { */ [[noreturn]] void handle_hdf5_err(const char* message = NULL); -/** A RAII-style HDF5 error handler. - * - * Creating an instance of this class removes any HDF5 error handler. - * The original handler is reinstalled when the instance is destroyed. - */ -class Hdf5_error_handler -{ - /// The original handler - H5E_auto2_t m_old_func; - - /// The original handler data - void* m_old_data; - -public: - /** The default (and only) constructor, installs the handler - */ - Hdf5_error_handler() - { - if (0 > H5Eget_auto2(H5E_DEFAULT, &m_old_func, &m_old_data)) handle_hdf5_err(); - if (0 > H5Eset_auto2(H5E_DEFAULT, NULL, NULL)) handle_hdf5_err(); - } - - /** The destructor - */ - ~Hdf5_error_handler() - { - if (0 > H5Eset_auto2(H5E_DEFAULT, m_old_func, m_old_data)) handle_hdf5_err(); - } -}; - /** A RAII-style wrapper for HDF5 hid_t. * * This calls the provided destroyer function when the hid_t goes out of scope. @@ -143,12 +113,11 @@ class Raii_hid */ Raii_hid& operator= (Raii_hid&& moved_from) { - using std::move; // destroy ourselves first if (m_destroyer) m_destroyer(m_value); // then move the parameter into ourselves m_value = moved_from.m_value; - m_destroyer = move(moved_from.m_destroyer); + m_destroyer = std::move(moved_from.m_destroyer); moved_from.m_destroyer = NULL; return *this; } @@ -170,9 +139,8 @@ class Raii_hid template Raii_hid make_raii_hid(hid_t value, Destroyer&& dst, const char* message = NULL) { - using std::move; if (0 > value) handle_hdf5_err(message); - return Raii_hid{value, move(dst)}; + return Raii_hid{value, std::move(dst)}; } /** builds a HDF5 dataspace that represents a PDI Datatype @@ -183,6 +151,64 @@ Raii_hid make_raii_hid(hid_t value, Destroyer&& dst, const char* message = NULL) */ std::tuple space(PDI::Datatype_sptr type, bool dense = false); +/** A RAII-style HDF5 error handler. + * + * Creating an instance of this class removes any HDF5 error handler. + * The original handler is reinstalled when the instance is destroyed. + */ +class Hdf5_error_handler +{ + /// The original handler + union { + // handler to use with the HDF5 API version 2 + H5E_auto2_t m_old_func; + ///handler to use with old HDF5 API + H5E_auto1_t m_old_func_V16; + }; + + /// The original handler data + void* m_old_data; + + /** Retrieves the HDF5 API version that is being used by the current error stack + * + * \return 1 if the error stack conforms to the API version 2, 0 otherwise + */ + static unsigned get_api_version() + { + Raii_hid stack = make_raii_hid(H5Eget_current_stack(), H5Eclose_stack, "unable to retrieve HDF5 stack to check API version"); + unsigned result; + if (0 > H5Eauto_is_v2(stack, &result)) handle_hdf5_err("unable to retrieve HDF5 stack to check API version"); + return result; + } + +public: + /** The default (and only) constructor, installs the handler + */ + Hdf5_error_handler() + { + static unsigned is_v2 = get_api_version(); + if (is_v2) { + if (0 > H5Eget_auto2(H5E_DEFAULT, &m_old_func, &m_old_data)) handle_hdf5_err(); + if (0 > H5Eset_auto2(H5E_DEFAULT, NULL, NULL)) handle_hdf5_err(); + } else { + if (0 > H5Eget_auto1(&m_old_func_V16, &m_old_data)) handle_hdf5_err(); + if (0 > H5Eset_auto1(NULL, NULL)) handle_hdf5_err(); + } + } + + /** The destructor + */ + ~Hdf5_error_handler() + { + static unsigned is_v2 = get_api_version(); + if (is_v2) { + if (0 > H5Eset_auto2(H5E_DEFAULT, m_old_func, m_old_data)) handle_hdf5_err(); + } else { + if (0 > H5Eset_auto1(m_old_func_V16, m_old_data)) handle_hdf5_err(); + } + } +}; + } // namespace decl_hdf5 #endif // DECL_HDF5_HDF5_WRAPPER_H_ diff --git a/plugins/decl_hdf5/selection.cxx b/plugins/decl_hdf5/selection.cxx index db6a9dadf..5c4d812e2 100644 --- a/plugins/decl_hdf5/selection.cxx +++ b/plugins/decl_hdf5/selection.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2019 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,10 +38,10 @@ #include "selection.h" -using PDI::Config_error; using PDI::Context; using PDI::each; using PDI::opt_each; +using PDI::Spectree_error; using PDI::to_string; using std::string; using std::transform; @@ -59,7 +59,7 @@ Selection::Selection(PC_tree_t tree) } else if (key == "start") { opt_each(value, [&](PC_tree_t start) { m_start.emplace_back(to_string(start)); }); } else { - throw Config_error{key_tree, "Invalid configuration key in selection: `{}'", key}; + throw Spectree_error{key_tree, "Invalid configuration key in selection: `{}'", key}; } }); } @@ -77,7 +77,7 @@ void Selection::apply(Context& ctx, hid_t h5_space, hid_t dflt_space) const if (!m_size.empty()) { if (m_size.size() != static_cast(rank)) { - throw Config_error{PC_get(m_selection_tree, ".size"), "Invalid selection: {} selection in {} array", m_size.size(), rank}; + throw Spectree_error{PC_get(m_selection_tree, ".size"), "Invalid selection: {} selection in {} array", m_size.size(), rank}; } for (int size_id = 0; size_id < rank; ++size_id) { h5_subsize[size_id] = m_size[size_id].to_long(ctx); @@ -88,7 +88,7 @@ void Selection::apply(Context& ctx, hid_t h5_space, hid_t dflt_space) const if (H5Sget_select_npoints(h5_space) == H5Sget_select_npoints(dflt_space)) { // if ranks differ but number of elements are the same, select whole dataset } else { - throw Config_error{m_selection_tree, "Invalid default selection: {} selection in {} array", dflt_rank, rank}; + throw Spectree_error{m_selection_tree, "Invalid default selection: {} selection in {} array", dflt_rank, rank}; } } else { // ranks match, get memory size selection as dataset size selection @@ -102,7 +102,7 @@ void Selection::apply(Context& ctx, hid_t h5_space, hid_t dflt_space) const if (!m_start.empty()) { if (m_start.size() != static_cast(rank)) { - throw Config_error{PC_get(m_selection_tree, ".start"), "Invalid selection: {} start in {} array", m_size.size(), rank}; + throw Spectree_error{PC_get(m_selection_tree, ".start"), "Invalid selection: {} start in {} array", m_size.size(), rank}; } for (int size_id = 0; size_id < rank; ++size_id) { h5_start[size_id] += m_start[size_id].to_long(ctx); diff --git a/plugins/decl_hdf5/selection.h b/plugins/decl_hdf5/selection.h index a70b3753a..7d8dacc97 100644 --- a/plugins/decl_hdf5/selection.h +++ b/plugins/decl_hdf5/selection.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2019 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,7 +40,7 @@ namespace decl_hdf5 { class Selection { /// The tree representing the selection - PC_tree_t m_selection_tree; + PC_tree_t m_selection_tree = {PC_NODE_NOT_FOUND, nullptr, nullptr}; /// The size of the selection in each dimension or empty for default std::vector m_size; diff --git a/vendor/paraconf-1.0.0/paraconf/src/status.h b/plugins/decl_hdf5/subfiling.cxx similarity index 57% rename from vendor/paraconf-1.0.0/paraconf/src/status.h rename to plugins/decl_hdf5/subfiling.cxx index 9f782f411..5309c9578 100644 --- a/vendor/paraconf-1.0.0/paraconf/src/status.h +++ b/plugins/decl_hdf5/subfiling.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2019 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,7 +10,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of CEA nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific + * endorse or promote products derived from this software without specific * prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR @@ -22,34 +22,43 @@ * THE SOFTWARE. ******************************************************************************/ -#ifndef STATUS_H__ -#define STATUS_H__ +#include +#include +#include -#include "paraconf.h" +#include +#include -#define PC_handle_err(callstatus, free_stamp)\ -do { \ - status = callstatus; \ - if ( status ) goto free_stamp; \ -} while( 0 ) +#include "subfiling.h" -#define PC_handle_tree(free_stamp)\ -do { \ - if ( PC_status(restree) ) goto free_stamp; \ -} while( 0 ) +using PDI::each; +using PDI::opt_each; +using PDI::Spectree_error; +using PDI::to_string; +using std::string; -#define PC_handle_err_tree(callstatus, free_stamp)\ -do { \ - restree.status = callstatus; \ - if ( PC_status(restree) ) goto free_stamp; \ -} while( 0 ) +namespace decl_hdf5 { -#define PC_handle_tree_err(calltree, free_stamp)\ -do { \ - status = calltree.status; \ - if ( status ) goto free_stamp; \ -} while( 0 ) +Subfiling::Subfiling(PC_tree_t sf_tree) +{ + if (PDI::is_scalar(sf_tree)) { + m_sf_count = PDI::to_string(sf_tree); + } else if (PDI::is_map(sf_tree)) { + PDI::each(sf_tree, [&](PC_tree_t key_tree, PC_tree_t value) { + string key = to_string(key_tree); + if (key == "policy") { + m_sf_policy = value; + } else if (key == "count") { + m_sf_count = value; + } else if (key == "stripe_size") { + m_sf_stripe_size = value; + } else { + throw Spectree_error{key_tree, "Invalid configuration key in subfiling: `{}'", key}; + } + }); + } else { + throw Spectree_error{sf_tree, "subfiling node is not parsed correctly"}; + } +} -PC_status_t PC_make_err(PC_status_t status, const char* message, ...); - -#endif // STATUS_H__ +} // namespace decl_hdf5 diff --git a/plugins/decl_hdf5/subfiling.h b/plugins/decl_hdf5/subfiling.h new file mode 100644 index 000000000..09bcf10ac --- /dev/null +++ b/plugins/decl_hdf5/subfiling.h @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (C) 2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + + +#ifndef DECL_HDF5_SUBFILING_H_ +#define DECL_HDF5_SUBFILING_H_ + +#include + +#include +#include + +namespace decl_hdf5 { + +/** This identifies a selection in an (array) Datatype + */ +class Subfiling +{ + /// The number of subfiles + PDI::Expression m_sf_count = 0L; + + /// The stripe size for subfiling + PDI::Expression m_sf_stripe_size = 0L; + + /// The policy for subfiling when problem + PDI::Expression m_sf_policy = "STOP"; + +public: + /** The default constructor for an empty selection (everything selected) + */ + Subfiling() = default; + + /** Builds a subfiling from a yaml tree. + * + * The tree should be a mapping with two optional keys: + * - count: an expressions, or an integer value + * - stripe_size: an expressions, or an integer value + * - policy: an expression representing either CONTINUE or STOP + * + * \param tree the tree representing the subfiling. + */ + Subfiling(PC_tree_t tree); + + /** Accesses the number of subfiles that will be generated. + * + * \return the number of subfiles + */ + const PDI::Expression& count() const { return m_sf_count; } + + /** Accesses the stripe size of the subfiling configuration. + * + * \return The stripe size of the subfiling configuration + */ + const PDI::Expression& stripe_size() const { return m_sf_stripe_size; } + + /** Accesses the policy of subfiling configuration if problem + * default. + * + * \return The the policy of subfiling configuration if problem + */ + const PDI::Expression& policy() const { return m_sf_policy; } +}; + +} // namespace decl_hdf5 + +#endif // DECL_HDF5_SELECTION_H_ diff --git a/plugins/decl_hdf5/tests/CMakeLists.txt b/plugins/decl_hdf5/tests/CMakeLists.txt index d67503cb6..db7a8f259 100644 --- a/plugins/decl_hdf5/tests/CMakeLists.txt +++ b/plugins/decl_hdf5/tests/CMakeLists.txt @@ -1,7 +1,7 @@ #============================================================================= -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) -# Copyright (C) 2022 Centre National de Recherche Scientifique (CNRS) +# Copyright (C) 2022-2026 Centre National de Recherche Scientifique (CNRS) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,11 +28,11 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) if(NOT TARGET GTest::gtest) option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" OFF) - add_subdirectory("../../../vendor/googletest-b4aaf97/" "googletest" EXCLUDE_FROM_ALL) + add_subdirectory("../../../vendor/googletest-56efe39/" "googletest" EXCLUDE_FROM_ALL) endif() include(GoogleTest) @@ -52,7 +52,7 @@ endif() ) add_executable(decl_hdf5_tests decl_hdf5_tests.cxx) -target_link_libraries(decl_hdf5_tests PDI::PDI_C GTest::gtest GTest::gtest_main) +target_link_libraries(decl_hdf5_tests PDI::PDI_C GTest::gmock GTest::gmock_main GTest::gtest GTest::gtest_main) gtest_discover_tests(decl_hdf5_tests) # compression test @@ -122,11 +122,32 @@ if("${BUILD_HDF5_PARALLEL}") set_property(TEST decl_hdf5_mpi_07_C PROPERTY PROCESSORS 4) endif() +# case datasets is defined as a regex. +# The data is writing in //. This data is defined with a dataset_selection and a dataset that depends on a regex +if("${BUILD_HDF5_PARALLEL}") + add_executable(decl_hdf5_mpi_08_C decl_hdf5_mpi_test_08.c) + target_link_libraries(decl_hdf5_mpi_08_C PDI::PDI_C MPI::MPI_C) + add_test(NAME decl_hdf5_mpi_08_C COMMAND "${RUNTEST_DIR}" "${MPIEXEC}" "${MPIEXEC_NUMPROC_FLAG}" 4 ${MPIEXEC_PREFLAGS} "$" ${MPIEXEC_POSTFLAGS}) + set_property(TEST decl_hdf5_mpi_08_C PROPERTY TIMEOUT 15) + set_property(TEST decl_hdf5_mpi_08_C PROPERTY PROCESSORS 4) +endif() + + add_executable(decl_hdf5_IO_options_C decl_hdf5_test_IO_options.c) target_link_libraries(decl_hdf5_IO_options_C PDI::PDI_C ${HDF5_DEPS}) add_test(NAME decl_hdf5_IO_options_C COMMAND "${RUNTEST_DIR}" "$") set_property(TEST decl_hdf5_IO_options_C PROPERTY TIMEOUT 15) +if("${BUILD_HDF5_PARALLEL}") + add_executable(decl_hdf5_mpi_subfiling decl_hdf5_mpi_subfiling.cxx) + target_link_libraries(decl_hdf5_mpi_subfiling PDI::PDI_C MPI::MPI_C ${HDF5_DEPS}) + target_compile_features(decl_hdf5_mpi_subfiling PUBLIC cxx_std_17) + add_test(NAME decl_hdf5_mpi_subfiling COMMAND "${RUNTEST_DIR}" "${MPIEXEC}" "${MPIEXEC_NUMPROC_FLAG}" 4 ${MPIEXEC_PREFLAGS} "$" ${MPIEXEC_POSTFLAGS}) + set_property(TEST decl_hdf5_mpi_subfiling PROPERTY TIMEOUT 15) + set_property(TEST decl_hdf5_mpi_subfiling PROPERTY PROCESSORS 4) + +endif() + if("${BUILD_FORTRAN}") add_subdirectory(fortran/) endif("${BUILD_FORTRAN}") diff --git a/plugins/decl_hdf5/tests/compatibility_tests/CMakeLists.txt b/plugins/decl_hdf5/tests/compatibility_tests/CMakeLists.txt index a390af759..7b18f57d1 100644 --- a/plugins/decl_hdf5/tests/compatibility_tests/CMakeLists.txt +++ b/plugins/decl_hdf5/tests/compatibility_tests/CMakeLists.txt @@ -1,6 +1,6 @@ #============================================================================= # Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) -# Copyright (C) 2020-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -23,7 +23,7 @@ # THE SOFTWARE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) set(RUNTEST_DIR "${CMAKE_CURRENT_LIST_DIR}/../../cmake/runtest-dir") diff --git a/plugins/decl_hdf5/tests/decl_hdf5_mpi_subfiling.cxx b/plugins/decl_hdf5/tests/decl_hdf5_mpi_subfiling.cxx new file mode 100644 index 000000000..6d8420053 --- /dev/null +++ b/plugins/decl_hdf5/tests/decl_hdf5_mpi_subfiling.cxx @@ -0,0 +1,181 @@ +/******************************************************************************* + * Copyright (C) 2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * forcumentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * enforrse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include +#include +#include + +#define IMX 50 +#define JMX 40 +#define NI_GHOST 1 +#define NJ_GHOST 2 +#define DIM 2 + +constexpr char CONFIG_YAML[] = R"( +logging: trace +metadata: + input: int + ni: int + nj: int + nig: int + njg: int + nit: int + njt: int + istart: int + jstart: int +data: + reals: + type: array + subtype: double + size: [$nj + 2*$njg, $ni + 2*$nig] + subsize: [$nj, $ni] + start: [$njg, $nig] + values: + type: array + subtype: int + size: [$nj + 2*$njg, $ni + 2*$nig] + subsize: [$nj, $ni] + start: [$njg, $nig] +plugins: + mpi: + decl_hdf5: + - file: subfiling_reals.h5 + communicator: $MPI_COMM_WORLD + subfiling: + stripe_size: 4096 + count: 4 + datasets: + reals: {type: array, subtype: double, size: [$njt, $nit]} + write: + reals: + dataset_selection: {start: [$jstart, $istart]} + - file: subfiling_values.h5 + communicator: $MPI_COMM_WORLD + subfiling: 2 + datasets: + values: {type: array, subtype: int, size: [$njt, $nit]} + write: + values: + dataset_selection: {start: [$jstart, $istart]} +)"; + +int main(int argc, char* argv[]) +{ + const int icst = -1; /// constants values in the ghost nodes + const double rcst = -1.01; + + int nig = NI_GHOST, njg = NJ_GHOST; + int ni = IMX, nj = JMX; + int values[JMX + 2 * NJ_GHOST][IMX + NI_GHOST * 2] = {{0}}, cp_values[JMX + 2 * NJ_GHOST][IMX + NI_GHOST * 2] = {{0}}; + double reals[JMX + 2 * NJ_GHOST][IMX + NI_GHOST * 2] = {{0}}, cp_reals[JMX + 2 * NJ_GHOST][IMX + NI_GHOST * 2] = {{0}}; + int i, j, input; + int nit, njt; + + /// MPI and parallel data or info + int dims[DIM], coord[DIM], periodic[DIM]; + int istart, jstart; + MPI_Comm comm2D; + periodic[0] = 0; + periodic[1] = 0; + dims[0] = 2; + dims[1] = 2; + + int provided; + MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); + + if (provided != MPI_THREAD_MULTIPLE) { + printf("provided level = %d, required level = %d\n", provided, MPI_THREAD_MULTIPLE); + return -1; + } + PC_tree_t conf = PC_parse_string(CONFIG_YAML); + MPI_Comm world = MPI_COMM_WORLD; + PDI_init(conf); + int rank; + MPI_Comm_rank(world, &rank); + + int size; + MPI_Comm_size(world, &size); + if (size != 4) { + printf("Run on 4 procs only."); + MPI_Abort(MPI_COMM_WORLD, -1); + } + PDI_expose("nproc", &size, PDI_OUT); + + + MPI_Cart_create(world, DIM, dims, periodic, 0, &comm2D); + MPI_Cart_coords(comm2D, rank, DIM, coord); + + istart = coord[1] * ni; + jstart = coord[0] * nj; + + nit = 2 * ni; + njt = 2 * nj; + + PDI_expose("nig", &nig, PDI_OUT); /// Ghost cells + PDI_expose("njg", &njg, PDI_OUT); + + PDI_expose("ni", &ni, PDI_OUT); /// Size of the portion of the array for a given MPI task + PDI_expose("nj", &nj, PDI_OUT); + + PDI_expose("nit", &nit, PDI_OUT); /// size of the distributed array + PDI_expose("njt", &njt, PDI_OUT); + + PDI_expose("istart", &istart, PDI_OUT); /// offset + PDI_expose("jstart", &jstart, PDI_OUT); + + // Fill arrays + for (j = 0; j < nj + 2 * njg; ++j) { + for (i = 0; i < ni + 2 * nig; ++i) { + cp_values[j][i] = icst; + cp_reals[j][i] = rcst; /// array initialized with const values + } + } + /// Values and reals == 0 in the ghost. + double cst = -rcst; + for (j = njg; j < nj + njg; ++j) { + for (i = nig; i < ni + nig; ++i) { + values[j][i] = (i + coord[1] * ni - nig) + (j + coord[0] * nj - njg) * 10; + reals[j][i] = (i + coord[1] * ni - nig) * cst + (j + coord[0] * nj - njg) * 10 * cst; + } + } + + PDI_expose("rank", &rank, PDI_OUT); + PDI_expose("input", &input, PDI_OUT); + + /// Test that export/exchange works + PDI_multi_expose("", "reals", &reals, PDI_OUT, "values", &values, PDI_INOUT, NULL); + + PDI_finalize(); + PC_tree_destroy(&conf); + MPI_Finalize(); + + if (!std::system("h5cc -showconfig | grep -q 'Subfiling VFD: ON' > /dev/null 2>&1")) { + if (std::system("grep \"subfile_count=4\" subfiling_reals.h5.subfile_*.config > /dev/null 2>&1")) { + return EXIT_FAILURE; + } + if (std::system("grep \"subfile_count=2\" subfiling_values.h5.subfile_*.config > /dev/null 2>&1")) { + return EXIT_FAILURE; + } + } +} diff --git a/plugins/decl_hdf5/tests/decl_hdf5_mpi_test_08.c b/plugins/decl_hdf5/tests/decl_hdf5_mpi_test_08.c new file mode 100644 index 000000000..483c3243c --- /dev/null +++ b/plugins/decl_hdf5/tests/decl_hdf5_mpi_test_08.c @@ -0,0 +1,224 @@ +/******************************************************************************* + * Copyright (C) 2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * forcumentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * enforrse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +/* +* +* description: +* +* In this test, we check that an element of datasets define as a regex +* allow to write a global data that verify these conditions: +* - The global data is writting in one hdf5 file. +* - The local data of a given mpi rank is writting in the global data using 'dataset_selection' +* - The global data is saved in a datagroup that depends on 'iter_saved': +* - dataset: timestep${iter_saved:05}/reals +*/ + + +#include +#include +#include +#include +#include + +#define IMX 5 +#define JMX 4 +#define DIM 2 + + +const char* CONFIG_YAML + = "logging: trace \n" + "metadata: \n" + " input: int \n" + " ni: int \n" + " nj: int \n" + " nit: int \n" + " njt: int \n" + " istart: int \n" + " jstart: int \n" + " rank: int \n" + " nproc: int \n" + " iter_saved: int \n" + "data: \n" + " reals: \n" + " type: array \n" + " subtype: double \n" + " size: [$nj , $ni] \n" + " values: \n" + " type: array \n" + " subtype: int \n" + " size: [$nj , $ni] \n" + "plugins: \n" + " mpi: \n" + " decl_hdf5: \n" + " - file: decl_hdf5_mpi_test_08_C.h5 \n" + " communicator: $MPI_COMM_WORLD \n" + " collision_policy: replace_and_warn \n" + " on_event: write \n" + " datasets: \n" + " timestep.*/reals: {type: array, subtype: double, size: [$njt, $nit]} \n" + " timestep[0-9]+/values: {type: array, subtype: int, size: [$njt, $nit]} \n" + " write: \n" + " reals: \n" + " when: $input=0 \n" + " dataset_selection: {start: [$jstart, $istart]} \n" + " dataset: timestep${iter_saved:05}/reals \n" + " values: \n" + " when: $input=0 \n" + " dataset_selection: {start: [$jstart, $istart]} \n" + " dataset: timestep${iter_saved:05}/values \n" + " - file: decl_hdf5_mpi_test_08_C.h5 \n" + " communicator: $MPI_COMM_WORLD \n" + " on_event: read \n" + " datasets: \n" + " timestep.*/reals: {type: array, subtype: double, size: [$njt, $nit]} \n" + " timestep[0-9]+values: {type: array, subtype: int, size: [$njt, $nit]} \n" + " read: \n" + " reals: \n" + " when: $input=1 \n" + " dataset_selection: {start: [$jstart, $istart]} \n" + " dataset: timestep${iter_saved:05}/reals \n" + " values: \n" + " when: $input=1 \n" + " dataset_selection: {start: [$jstart, $istart]} \n" + " dataset: timestep${iter_saved:05}/values \n"; + +int main(int argc, char* argv[]) +{ + const int icst = -1; /// constants values in the ghost nodes + const double rcst = -1.1; + + int ni = IMX, nj = JMX; + int values[JMX][IMX] = {{0}}, cp_values[JMX][IMX] = {{0}}; + double reals[JMX][IMX] = {{0}}, cp_reals[JMX][IMX] = {{0}}; + int i, j, input; + int nit, njt; + int niterations = 4; + + /// MPI and parallel data or info + int dims[DIM], coord[DIM], periodic[DIM]; + int istart, jstart; + MPI_Comm comm2D; + periodic[0] = 0; + periodic[1] = 0; + dims[0] = 2; + dims[1] = 2; + + + MPI_Init(&argc, &argv); + PC_tree_t conf = PC_parse_string(CONFIG_YAML); + MPI_Comm world = MPI_COMM_WORLD; + PDI_init(conf); + int rank; + MPI_Comm_rank(world, &rank); + + { + /// setting nb of procs. + int size; + MPI_Comm_size(world, &size); + if (size != 4) { + printf("Run on 4 procs only."); + MPI_Abort(MPI_COMM_WORLD, -1); + } + PDI_expose("nproc", &size, PDI_OUT); + } + PDI_expose("rank", &rank, PDI_OUT); + input = 0; + PDI_expose("input", &input, PDI_OUT); + + MPI_Cart_create(world, DIM, dims, periodic, 0, &comm2D); + MPI_Cart_coords(comm2D, rank, DIM, coord); + + istart = coord[1] * ni; + jstart = coord[0] * nj; + + nit = 2 * ni; + njt = 2 * nj; + + PDI_expose("ni", &ni, PDI_OUT); /// Size of the portion of the array for a given MPI task + PDI_expose("nj", &nj, PDI_OUT); + + PDI_expose("nit", &nit, PDI_OUT); /// size of the distributed array + PDI_expose("njt", &njt, PDI_OUT); + + PDI_expose("istart", &istart, PDI_OUT); /// offset + PDI_expose("jstart", &jstart, PDI_OUT); + + for (int iteration = 0; iteration < niterations; ++iteration) { + PDI_expose("iter_saved", &iteration, PDI_INOUT); // save all iteration + // Fill arrays + for (j = 0; j < nj; ++j) { + for (i = 0; i < ni; ++i) { + cp_values[j][i] = icst; + cp_reals[j][i] = rcst; /// array initialized with const values + values[j][i] = iteration; + reals[j][i] = (double)iteration; + } + } + + input = 0; + /// Test that export/exchange works + PDI_expose("input", &input, PDI_OUT); + PDI_multi_expose( + "write", + "reals", + &reals, + PDI_OUT, // output real + "values", + &values, + PDI_OUT, // output integers + NULL + ); + + input = 1; + /// Import should also work + PDI_expose("input", &input, PDI_OUT); // update metadata => HDF5 now import only + PDI_multi_expose( + "read", + "reals", + &cp_reals, + PDI_INOUT, // input real + "values", + &cp_values, + PDI_INOUT, // input integers + NULL + ); + + /// So the data should be the same + fprintf(stderr, "Data exported | Data imported\n"); + + for (int j = 0; j < nj; ++j) { // Should be the same inside + for (int i = 0; i < ni; i++) { + if ((values[j][i] != cp_values[j][i]) || (reals[j][i] != cp_reals[j][i])) { + fprintf(stderr, "integer (export) / integer(imported) :: %3d %3d\n", values[j][i], cp_values[j][i]); + fprintf(stderr, "reals (export) / reals (imported) :: %6f %6f\n", reals[j][i], cp_reals[j][i]); + MPI_Abort(MPI_COMM_WORLD, -1); + } + } + } + } + + PDI_finalize(); + PC_tree_destroy(&conf); + MPI_Finalize(); +} diff --git a/plugins/decl_hdf5/tests/decl_hdf5_test_IO_options.c b/plugins/decl_hdf5/tests/decl_hdf5_test_IO_options.c index 2d1304420..f6fdf617f 100644 --- a/plugins/decl_hdf5/tests/decl_hdf5_test_IO_options.c +++ b/plugins/decl_hdf5/tests/decl_hdf5_test_IO_options.c @@ -1,4 +1,5 @@ /******************************************************************************* + * Copyright (C) 2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -25,7 +26,7 @@ #include #include -int PDI_write_pure() +int PDI_write_pure(int array_data[100], float matrix_data[100][100]) { const char* CONFIG_YAML = "logging: trace \n" @@ -43,18 +44,8 @@ int PDI_write_pure() PC_tree_t conf = PC_parse_string(CONFIG_YAML); PDI_init(conf); - int array_data[100]; - for (int i = 0; i < 100; i++) { - array_data[i] = i; - } PDI_expose("array_data", array_data, PDI_OUT); - float matrix_data[100][100]; - for (int i = 0; i < 100; i++) { - for (int j = 0; j < 100; j++) { - matrix_data[i][j] = 100 * i + j * 0.95f; - } - } PDI_expose("matrix_data", matrix_data, PDI_OUT); PDI_finalize(); @@ -63,7 +54,7 @@ int PDI_write_pure() return 0; } -int PDI_read_pure() +int PDI_read_pure(int array_ref[100], float matrix_ref[100][100]) { hid_t file_id = H5Fopen("decl_hdf5_test_16_pure.h5", H5F_ACC_RDONLY, H5P_DEFAULT); if (file_id < 0) { @@ -97,9 +88,7 @@ int PDI_read_pure() // check chunking hid_t array_plist = H5Dget_create_plist(array_data_id); - hsize_t array_dims[2]; - int chunk_dim = H5Pget_chunk(array_plist, 2, array_dims); - if (chunk_dim >= 0) { + if (H5Pget_layout(array_plist) == H5D_CHUNKED) { printf("Array dataset has chunking in pure file\n"); return 1; } @@ -118,8 +107,8 @@ int PDI_read_pure() } for (int i = 0; i < 100; i++) { - if (array_data[i] != i) { - printf("array_size[%d] invalid value: %d (should be: %d)\n", i, array_data[i], i); + if (array_data[i] != array_ref[i]) { + printf("array_size[%d] invalid value: %d (should be: %d)\n", i, array_data[i], array_ref[i]); return 1; } } @@ -140,13 +129,10 @@ int PDI_read_pure() // check chunking hid_t matrix_plist = H5Dget_create_plist(matrix_data_id); - hsize_t matrix_dims[2]; - chunk_dim = H5Pget_chunk(matrix_plist, 2, matrix_dims); - if (chunk_dim >= 0) { + if (H5Pget_layout(matrix_plist) == H5D_CHUNKED) { printf("Matrix dataset has chunking in pure file\n"); return 1; } - printf("Above errors are expected and correct\n"); // check deflate and fletcher filters_count = H5Pget_nfilters(matrix_plist); @@ -163,8 +149,8 @@ int PDI_read_pure() for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { - if (matrix_data[i][j] != i * 100 + j * 0.95f) { - printf("matrix_size[%d, %d] invalid value: %f (should be: %f)\n", i, j, matrix_data[i][j], i * 100 + j * 0.95f); + if (matrix_data[i][j] != matrix_ref[i][j]) { + printf("matrix_size[%d, %d] invalid value: %f (should be: %f)\n", i, j, matrix_data[i][j], matrix_ref[i][j]); return 1; } } @@ -178,7 +164,7 @@ int PDI_read_pure() return 0; } -int PDI_write_chunked() +int PDI_write_chunked(int array_data[100], float matrix_data[100][100]) { const char* CONFIG_YAML = "logging: trace \n" @@ -203,18 +189,8 @@ int PDI_write_chunked() PDI_expose("x", &x, PDI_OUT); PDI_expose("y", &y, PDI_OUT); - int array_data[100]; - for (int i = 0; i < 100; i++) { - array_data[i] = i; - } PDI_expose("array_data", array_data, PDI_OUT); - float matrix_data[100][100]; - for (int i = 0; i < 100; i++) { - for (int j = 0; j < 100; j++) { - matrix_data[i][j] = 100 * i + j * 0.95f; - } - } PDI_expose("matrix_data", matrix_data, PDI_OUT); PDI_finalize(); @@ -223,7 +199,7 @@ int PDI_write_chunked() return 0; } -int PDI_read_chunked() +int PDI_read_chunked(int array_ref[100], float matrix_ref[100][100]) { hid_t file_id = H5Fopen("decl_hdf5_test_16_chunked.h5", H5F_ACC_RDONLY, H5P_DEFAULT); if (file_id < 0) { @@ -264,7 +240,7 @@ int PDI_read_chunked() return 1; } if (array_dims[0] != 10) { - printf("Array dataset invalid chunking: %d (should be: 10)\n", array_dims[0]); + printf("Array dataset invalid chunking: %d (should be: 10)\n", (int)array_dims[0]); return 1; } @@ -282,8 +258,8 @@ int PDI_read_chunked() } for (int i = 0; i < 100; i++) { - if (array_data[i] != i) { - printf("array_size[%d] invalid value: %d (should be: %d)\n", i, array_data[i], i); + if (array_data[i] != array_ref[i]) { + printf("array_size[%d] invalid value: %d (should be: %d)\n", i, array_data[i], array_ref[i]); return 1; } } @@ -309,7 +285,7 @@ int PDI_read_chunked() return 1; } if (matrix_dims[0] != 10 || matrix_dims[1] != 10) { - printf("Matrix dataset invalid chunking: [%d, %d] (should be: [10, 10])\n", matrix_dims[0], matrix_dims[1]); + printf("Matrix dataset invalid chunking: [%d, %d] (should be: [10, 10])\n", (int)matrix_dims[0], (int)matrix_dims[1]); return 1; } @@ -328,8 +304,8 @@ int PDI_read_chunked() for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { - if (matrix_data[i][j] != i * 100 + j * 0.95f) { - printf("matrix_size[%d, %d] invalid value: %f (should be: %f)\n", i, j, matrix_data[i][j], i * 100 + j * 0.95f); + if (matrix_data[i][j] != matrix_ref[i][j]) { + printf("matrix_size[%d, %d] invalid value: %f (should be: %f)\n", i, j, matrix_data[i][j], matrix_ref[i][j]); return 1; } } @@ -343,7 +319,7 @@ int PDI_read_chunked() return 0; } -int PDI_write_deflated() +int PDI_write_deflated(int array_data[100], float matrix_data[100][100]) { const char* CONFIG_YAML = "logging: trace \n" @@ -361,18 +337,8 @@ int PDI_write_deflated() PC_tree_t conf = PC_parse_string(CONFIG_YAML); PDI_init(conf); - int array_data[100]; - for (int i = 0; i < 100; i++) { - array_data[i] = i; - } PDI_expose("array_data", array_data, PDI_OUT); - float matrix_data[100][100]; - for (int i = 0; i < 100; i++) { - for (int j = 0; j < 100; j++) { - matrix_data[i][j] = 100 * i + j * 0.95f; - } - } PDI_expose("matrix_data", matrix_data, PDI_OUT); PDI_finalize(); @@ -381,7 +347,7 @@ int PDI_write_deflated() return 0; } -int PDI_read_deflated() +int PDI_read_deflated(int array_ref[100], float matrix_ref[100][100]) { hid_t file_id = H5Fopen("decl_hdf5_test_16_deflated.h5", H5F_ACC_RDONLY, H5P_DEFAULT); if (file_id < 0) { @@ -428,8 +394,8 @@ int PDI_read_deflated() } for (int i = 0; i < 100; i++) { - if (array_data[i] != i) { - printf("array_size[%d] invalid value: %d (should be: %d)\n", i, array_data[i], i); + if (array_data[i] != array_ref[i]) { + printf("array_size[%d] invalid value: %d (should be: %d)\n", i, array_data[i], array_ref[i]); return 1; } } @@ -462,8 +428,8 @@ int PDI_read_deflated() for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { - if (matrix_data[i][j] != i * 100 + j * 0.95f) { - printf("matrix_size[%d, %d] invalid value: %f (should be: %f)\n", i, j, matrix_data[i][j], i * 100 + j * 0.95f); + if (matrix_data[i][j] != matrix_ref[i][j]) { + printf("matrix_size[%d, %d] invalid value: %f (should be: %f)\n", i, j, matrix_data[i][j], matrix_ref[i][j]); return 1; } } @@ -477,7 +443,7 @@ int PDI_read_deflated() return 0; } -int PDI_write_fletcher() +int PDI_write_fletcher(int array_data[100], float matrix_data[100][100]) { const char* CONFIG_YAML = "logging: trace \n" @@ -495,18 +461,8 @@ int PDI_write_fletcher() PC_tree_t conf = PC_parse_string(CONFIG_YAML); PDI_init(conf); - int array_data[100]; - for (int i = 0; i < 100; i++) { - array_data[i] = i; - } PDI_expose("array_data", array_data, PDI_OUT); - float matrix_data[100][100]; - for (int i = 0; i < 100; i++) { - for (int j = 0; j < 100; j++) { - matrix_data[i][j] = 100 * i + j * 0.95f; - } - } PDI_expose("matrix_data", matrix_data, PDI_OUT); PDI_finalize(); @@ -515,7 +471,7 @@ int PDI_write_fletcher() return 0; } -int PDI_read_fletcher() +int PDI_read_fletcher(int array_ref[100], float matrix_ref[100][100]) { hid_t file_id = H5Fopen("decl_hdf5_test_16_fletcher.h5", H5F_ACC_RDONLY, H5P_DEFAULT); if (file_id < 0) { @@ -562,8 +518,8 @@ int PDI_read_fletcher() } for (int i = 0; i < 100; i++) { - if (array_data[i] != i) { - printf("array_size[%d] invalid value: %d (should be: %d)\n", i, array_data[i], i); + if (array_data[i] != array_ref[i]) { + printf("array_size[%d] invalid value: %d (should be: %d)\n", i, array_data[i], array_ref[i]); return 1; } } @@ -596,8 +552,8 @@ int PDI_read_fletcher() for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { - if (matrix_data[i][j] != i * 100 + j * 0.95f) { - printf("matrix_size[%d, %d] invalid value: %f (should be: %f)\n", i, j, matrix_data[i][j], i * 100 + j * 0.95f); + if (matrix_data[i][j] != matrix_ref[i][j]) { + printf("matrix_size[%d, %d] invalid value: %f (should be: %f)\n", i, j, matrix_data[i][j], matrix_ref[i][j]); return 1; } } @@ -611,7 +567,7 @@ int PDI_read_fletcher() return 0; } -int PDI_write_defletcher() +int PDI_write_defletcher(int array_data[100], float matrix_data[100][100]) { const char* CONFIG_YAML = "logging: trace \n" @@ -630,18 +586,8 @@ int PDI_write_defletcher() PC_tree_t conf = PC_parse_string(CONFIG_YAML); PDI_init(conf); - int array_data[100]; - for (int i = 0; i < 100; i++) { - array_data[i] = i; - } PDI_expose("array_data", array_data, PDI_OUT); - float matrix_data[100][100]; - for (int i = 0; i < 100; i++) { - for (int j = 0; j < 100; j++) { - matrix_data[i][j] = 100 * i + j * 0.95f; - } - } PDI_expose("matrix_data", matrix_data, PDI_OUT); PDI_finalize(); @@ -650,7 +596,7 @@ int PDI_write_defletcher() return 0; } -int PDI_read_defletcher() +int PDI_read_defletcher(int array_ref[100], float matrix_ref[100][100]) { hid_t file_id = H5Fopen("decl_hdf5_test_16_defletcher.h5", H5F_ACC_RDONLY, H5P_DEFAULT); if (file_id < 0) { @@ -697,8 +643,8 @@ int PDI_read_defletcher() } for (int i = 0; i < 100; i++) { - if (array_data[i] != i) { - printf("array_size[%d] invalid value: %d (should be: %d)\n", i, array_data[i], i); + if (array_data[i] != array_ref[i]) { + printf("array_size[%d] invalid value: %d (should be: %d)\n", i, array_data[i], array_ref[i]); return 1; } } @@ -731,8 +677,8 @@ int PDI_read_defletcher() for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { - if (matrix_data[i][j] != i * 100 + j * 0.95f) { - printf("matrix_size[%d, %d] invalid value: %f (should be: %f)\n", i, j, matrix_data[i][j], i * 100 + j * 0.95f); + if (matrix_data[i][j] != matrix_ref[i][j]) { + printf("matrix_size[%d, %d] invalid value: %f (should be: %f)\n", i, j, matrix_data[i][j], matrix_ref[i][j]); return 1; } } @@ -748,52 +694,64 @@ int PDI_read_defletcher() int main() { + int array_data[100]; + for (int i = 0; i < 100; i++) { + array_data[i] = i; + } + + float matrix_data[100][100]; + for (int i = 0; i < 100; i++) { + for (int j = 0; j < 100; j++) { + matrix_data[i][j] = 100 * i + j * 0.95f; + } + } + // pure - int status = PDI_write_pure(); + int status = PDI_write_pure(array_data, matrix_data); if (status != 0) { return status; } - status = PDI_read_pure(); + status = PDI_read_pure(array_data, matrix_data); if (status != 0) { return status; } // chunked - status = PDI_write_chunked(); + status = PDI_write_chunked(array_data, matrix_data); if (status != 0) { return status; } - status = PDI_read_chunked(); + status = PDI_read_chunked(array_data, matrix_data); if (status != 0) { return status; } // deflated - status = PDI_write_deflated(); + status = PDI_write_deflated(array_data, matrix_data); if (status != 0) { return status; } - status = PDI_read_deflated(); + status = PDI_read_deflated(array_data, matrix_data); if (status != 0) { return status; } // fletcher - status = PDI_write_fletcher(); + status = PDI_write_fletcher(array_data, matrix_data); if (status != 0) { return status; } - status = PDI_read_fletcher(); + status = PDI_read_fletcher(array_data, matrix_data); if (status != 0) { return status; } // deflate and fletcher - status = PDI_write_defletcher(); + status = PDI_write_defletcher(array_data, matrix_data); if (status != 0) { return status; } - status = PDI_read_defletcher(); + status = PDI_read_defletcher(array_data, matrix_data); if (status != 0) { return status; } diff --git a/plugins/decl_hdf5/tests/decl_hdf5_test_deflate.cxx b/plugins/decl_hdf5/tests/decl_hdf5_test_deflate.cxx index 1d8d1722d..a8dcdc5b7 100644 --- a/plugins/decl_hdf5/tests/decl_hdf5_test_deflate.cxx +++ b/plugins/decl_hdf5/tests/decl_hdf5_test_deflate.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,6 +29,31 @@ #include #include +/** check the deflate level set in a HDF5 plist + * + * \param plist_id the plist identifier + * \param[out] level set to the deflate level in the plist + * \return whether deflate is set in the plist + */ +bool get_deflate_level(hid_t plist_id, unsigned int& level) +{ + int nfilters = H5Pget_nfilters(plist_id); + for (int i = 0; i < nfilters; i++) { + size_t nelmts = 1; + unsigned int cd_value = 0; + + H5Z_filter_t filter = H5Pget_filter2(plist_id, i, nullptr, &nelmts, &cd_value, 0, nullptr, nullptr); + + if (filter == H5Z_FILTER_DEFLATE) { + if (nelmts == 1) { + level = cd_value; + return true; + } + } + } + return false; +} + TEST(decl_hdf5_deflate, no_deflate) { const char* CONFIG_YAML @@ -52,22 +77,17 @@ TEST(decl_hdf5_deflate, no_deflate) size_t N = 1000; PDI_expose("pb_size", &N, PDI_OUT); - double** matrix_data = new double*[N]; - for (int i = 0; i < N; i++) { - matrix_data[i] = new double[N]; - for (int j = 0; j < N; j++) { - matrix_data[i][j] = N * i + j; + std::vector matrix_data(N * N); + for (size_t i = 0; i < N; i++) { + for (size_t j = 0; j < N; j++) { + matrix_data[i * N + j] = N * i + j; } } - PDI_expose("matrix_data", matrix_data, PDI_OUT); + PDI_expose("matrix_data", matrix_data.data(), PDI_OUT); PDI_finalize(); PC_tree_destroy(&conf); - for (int i = 0; i < N; i++) - delete[] matrix_data[i]; - delete[] matrix_data; - hid_t file_id, dataset_id, plist_id; herr_t status; unsigned int compression_level; @@ -78,9 +98,10 @@ TEST(decl_hdf5_deflate, no_deflate) dataset_id = H5Dopen2(file_id, "matrix_data", H5P_DEFAULT); plist_id = H5Dget_create_plist(dataset_id); - status = H5Pget_filter_by_id2(plist_id, H5Z_FILTER_DEFLATE, NULL, &cd_nelmts, &compression_level, 0, NULL, NULL); + unsigned int level = 0; + bool has_deflate = get_deflate_level(plist_id, level); - ASSERT_LT(status, 0); + ASSERT_FALSE(has_deflate); H5Pclose(plist_id); H5Dclose(dataset_id); @@ -112,22 +133,17 @@ TEST(decl_hdf5_deflate, deflate_level1) size_t N = 1000; PDI_expose("pb_size", &N, PDI_OUT); - double** matrix_data = new double*[N]; - for (int i = 0; i < N; i++) { - matrix_data[i] = new double[N]; - for (int j = 0; j < N; j++) { - matrix_data[i][j] = N * i + j; + std::vector matrix_data(N * N); + for (size_t i = 0; i < N; i++) { + for (size_t j = 0; j < N; j++) { + matrix_data[i * N + j] = N * i + j; } } - PDI_expose("matrix_data", matrix_data, PDI_OUT); + PDI_expose("matrix_data", matrix_data.data(), PDI_OUT); PDI_finalize(); PC_tree_destroy(&conf); - for (int i = 0; i < N; i++) - delete[] matrix_data[i]; - delete[] matrix_data; - hid_t file_id, dataset_id, plist_id; herr_t status; unsigned int compression_level; @@ -138,9 +154,11 @@ TEST(decl_hdf5_deflate, deflate_level1) dataset_id = H5Dopen2(file_id, "matrix_data", H5P_DEFAULT); plist_id = H5Dget_create_plist(dataset_id); - status = H5Pget_filter_by_id2(plist_id, H5Z_FILTER_DEFLATE, NULL, &cd_nelmts, &compression_level, 0, NULL, NULL); + unsigned int level = 0; + bool has_deflate = get_deflate_level(plist_id, level); - ASSERT_EQ(compression_level, 1); + ASSERT_TRUE(has_deflate); + ASSERT_EQ(level, 1); H5Pclose(plist_id); H5Dclose(dataset_id); @@ -172,22 +190,17 @@ TEST(decl_hdf5_deflate, deflate_level2) size_t N = 1000; PDI_expose("pb_size", &N, PDI_OUT); - double** matrix_data = new double*[N]; - for (int i = 0; i < N; i++) { - matrix_data[i] = new double[N]; - for (int j = 0; j < N; j++) { - matrix_data[i][j] = N * i + j; + std::vector matrix_data(N * N); + for (size_t i = 0; i < N; i++) { + for (size_t j = 0; j < N; j++) { + matrix_data[i * N + j] = N * i + j; } } - PDI_expose("matrix_data", matrix_data, PDI_OUT); + PDI_expose("matrix_data", matrix_data.data(), PDI_OUT); PDI_finalize(); PC_tree_destroy(&conf); - for (int i = 0; i < N; i++) - delete[] matrix_data[i]; - delete[] matrix_data; - hid_t file_id, dataset_id, plist_id; herr_t status; unsigned int compression_level; @@ -198,9 +211,11 @@ TEST(decl_hdf5_deflate, deflate_level2) dataset_id = H5Dopen2(file_id, "matrix_data", H5P_DEFAULT); plist_id = H5Dget_create_plist(dataset_id); - status = H5Pget_filter_by_id2(plist_id, H5Z_FILTER_DEFLATE, NULL, &cd_nelmts, &compression_level, 0, NULL, NULL); + unsigned int level = 0; + bool has_deflate = get_deflate_level(plist_id, level); - ASSERT_EQ(compression_level, 2); + ASSERT_TRUE(has_deflate); + ASSERT_EQ(level, 2); H5Pclose(plist_id); H5Dclose(dataset_id); @@ -232,22 +247,17 @@ TEST(decl_hdf5_deflate, deflate_level9) size_t N = 1000; PDI_expose("pb_size", &N, PDI_OUT); - double** matrix_data = new double*[N]; - for (int i = 0; i < N; i++) { - matrix_data[i] = new double[N]; - for (int j = 0; j < N; j++) { - matrix_data[i][j] = N * i + j; + std::vector matrix_data(N * N); + for (size_t i = 0; i < N; i++) { + for (size_t j = 0; j < N; j++) { + matrix_data[i * N + j] = N * i + j; } } - PDI_expose("matrix_data", matrix_data, PDI_OUT); + PDI_expose("matrix_data", matrix_data.data(), PDI_OUT); PDI_finalize(); PC_tree_destroy(&conf); - for (int i = 0; i < N; i++) - delete[] matrix_data[i]; - delete[] matrix_data; - hid_t file_id, dataset_id, plist_id; herr_t status; unsigned int compression_level; @@ -258,9 +268,11 @@ TEST(decl_hdf5_deflate, deflate_level9) dataset_id = H5Dopen2(file_id, "matrix_data", H5P_DEFAULT); plist_id = H5Dget_create_plist(dataset_id); - status = H5Pget_filter_by_id2(plist_id, H5Z_FILTER_DEFLATE, NULL, &cd_nelmts, &compression_level, 0, NULL, NULL); + unsigned int level = 0; + bool has_deflate = get_deflate_level(plist_id, level); - ASSERT_EQ(compression_level, 9); + ASSERT_TRUE(has_deflate); + ASSERT_EQ(level, 9); H5Pclose(plist_id); H5Dclose(dataset_id); diff --git a/plugins/decl_hdf5/tests/decl_hdf5_tests.cxx b/plugins/decl_hdf5/tests/decl_hdf5_tests.cxx index 4e3717c78..73d270acf 100644 --- a/plugins/decl_hdf5/tests/decl_hdf5_tests.cxx +++ b/plugins/decl_hdf5/tests/decl_hdf5_tests.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -23,930 +23,827 @@ * THE SOFTWARE. ******************************************************************************/ -#include -#include -#include +#include +#include +#include +#include -/* - * Name: decl_hdf5_test.01 - * - * Description: Metatadata export using filename - */ -TEST(decl_hdf5_test, 01) -{ - const char* CONFIG_YAML - = "logging: trace \n" - "metadata: \n" - " meta0: int \n" - " meta1: int \n" - " meta2: int \n" - " meta3: int \n" - " meta4: int \n" - "data: \n" - " test_var: double \n" - "plugins: \n" - " decl_hdf5: \n" - " file: ${meta1}.h5 \n" - " write: \n" - " test_var: ~ \n" - " meta2: ~ \n"; - - int value[5] = {5, 4, 3, 2, 1}; - double test_var = 0; - - remove("5.h5"); - - PC_tree_t conf = PC_parse_string(CONFIG_YAML); - PDI_init(conf); +#include - PDI_multi_expose( - "testing", - "meta0", - &value[0], - PDI_OUT, - "meta1", - &value[0], - PDI_OUT, - "meta2", - &value[1], - PDI_OUT, - "meta3", - &value[2], - PDI_OUT, - "meta4", - &value[3], - PDI_OUT, - "test_var", - &test_var, - PDI_OUT, - NULL - ); +using PDI::make_random; +using PDI::random_init; +using testing::Eq; +using testing::StartsWith; +using testing::StrEq; - PDI_finalize(); - PC_tree_destroy(&conf); +struct Simple_record { + int x; + int y; + int z; + bool operator== (const Simple_record&) const = default; - FILE* fp = fopen("5.h5", "r"); - EXPECT_NE(fp, nullptr) << "File not found. \n"; - fclose(fp); -} + void init_from(std::uniform_random_bit_generator auto& gen) + { + random_init(gen, x); + random_init(gen, y); + random_init(gen, z); + } +}; -/* - * Name: decl_hdf5_test.02 - * - * Description: outer record - */ -TEST(decl_hdf5_test, 02) +std::ostream& operator<< (std::ostream& out, Simple_record const & r) { - const char* CONFIG_YAML - = "logging: trace \n" - "metadata: \n" - " input: int \n" - "data: \n" - " outer_record: \n" - " type: struct \n" - " members: \n" - " - id: int \n" - " - value: \n" - " type: array \n" - " size: [2, 2] \n" - " subtype: \n" - " type: struct \n" - " members: \n" - " - x: int \n" - " - y: int \n" - " - z: int \n" - "plugins: \n" - " decl_hdf5: \n" - " - file: test_02.h5 \n" - " write: [outer_record] \n" - " when: $input=0 \n" - " - file: test_02.h5 \n" - " read: [outer_record] \n" - " when: $input=1 \n"; - - struct XYZ { - int x; - int y; - int z; - }; - - struct Record { - int id; - struct XYZ value[4]; // 2 x 2 - }; - - struct Record outer_record; - - // init data - outer_record.id = 24; - for (int i = 0; i < 4; i++) { - outer_record.value[i].x = -1 * i; - outer_record.value[i].y = 2 * i; - outer_record.value[i].z = 3 * i; - } + return out << "Simple_record(x=" << r.x << ", y=" << r.y << ", z=" << r.z << ")"; +} - PC_tree_t conf = PC_parse_string(CONFIG_YAML); - PDI_init(conf); - int input = 0; - PDI_expose("input", &input, PDI_OUT); - PDI_expose("outer_record", &outer_record, PDI_OUT); - - // reset record - outer_record.id = 0; - for (int i = 0; i < 4; i++) { - outer_record.value[i].x = 0; - outer_record.value[i].y = 0; - outer_record.value[i].z = 0; - } +struct Complex_record { + int id; + Simple_record value[4]; + bool operator== (const Complex_record&) const = default; - // load record from file - input = 1; - PDI_expose("input", &input, PDI_OUT); - PDI_expose("outer_record", &outer_record, PDI_IN); - - // check values - printf("%d != %d\n", outer_record.id, 24); - ASSERT_EQ(outer_record.id, 24); - for (int i = 0; i < 4; i++) { - EXPECT_EQ(outer_record.value[i].x, -1 * i); - EXPECT_EQ(outer_record.value[i].y, 2 * i); - EXPECT_EQ(outer_record.value[i].z, 3 * i); + void init_from(std::uniform_random_bit_generator auto& gen) + { + random_init(gen, id); + random_init(gen, value); } - PDI_finalize(); - PC_tree_destroy(&conf); +}; + +std::ostream& operator<< (std::ostream& out, Complex_record const & r) +{ + return out << "Complex_record(id=" << r.id << ", value=" << r.value << ")"; } -/* - * Name: decl_hdf5_test.03 - * - * Description: record with dataset_selection and memory_selection +class DeclHdf5: public ::PDI::PdiTest +{}; + +/* Metatadata use in filename expression & write on data */ -TEST(decl_hdf5_test, 03) +TEST_F(DeclHdf5, FilenameFromMetaList) { - const char* CONFIG_YAML - = "logging: trace \n" - "metadata: \n" - " input: int \n" - "data: \n" - " array_of_record: \n" - " type: array \n" - " size: 4 \n" - " subtype: \n" - " type: struct \n" - " members: \n" - " - id: int \n" - " - value: \n" - " type: array \n" - " subtype: int \n" - " size: [4, 4] \n" - " array_of_record_read: \n" - " type: array \n" - " size: 2 \n" - " subtype: \n" - " type: struct \n" - " members: \n" - " - id: int \n" - " - value: \n" - " type: array \n" - " subtype: int \n" - " size: [4, 4] \n" - "plugins: \n" - " decl_hdf5: \n" - " - file: test_03.h5 \n" - " when: $input=0 \n" - " datasets: \n" - " data_array: \n" - " type: array \n" - " size: 2 \n" - " subtype: \n" - " type: struct \n" - " members: \n" - " - id: int \n" - " - value: \n" - " type: array \n" - " subtype: int \n" - " size: [4, 4] \n" - " write: \n" - " array_of_record: \n" - " dataset: data_array \n" - " memory_selection: \n" - " size: 2 \n" - " start: 1 \n" - " dataset_selection: \n" - " size: 2 \n" - " - file: test_03.h5 \n" - " when: $input=1 \n" - " read: [array_of_record_read] \n"; - - struct Record { - int id; - int value[16]; - }; - - struct Record rec[4]; - // init data - for (int i = 0; i < 4; i++) { - rec[i].id = i; - for (int j = 0; j < 16; j++) { - rec[i].value[j] = j + i * 16; - } - } - PC_tree_t conf = PC_parse_string(CONFIG_YAML); - PDI_init(conf); - int input = 0; - PDI_expose("input", &input, PDI_OUT); - - // write record to file - PDI_expose("array_of_record", rec, PDI_OUT); - - // load record from file - input = 1; - PDI_expose("input", &input, PDI_OUT); - struct Record rec_read[2]; - PDI_expose("array_of_record", rec_read, PDI_IN); - - // check values - for (int i = 1; i < 3; i++) { - EXPECT_EQ(rec[i].id, i); - for (int j = 0; j < 16; j++) { - EXPECT_EQ(rec[i].value[j], j + i * 16); - } - } - PDI_finalize(); - PC_tree_destroy(&conf); + InitPdi(PC_parse_string(R"==( +logging: trace +metadata: { meta_var: int } +data: { test_var: double } +plugins: + decl_hdf5: + file: "file${meta_var}.h5" + write: [ test_var ] +)==")); + + int const meta_var = 1; + PDI_expose("meta_var", &meta_var, PDI_OUT); + + auto const test_var = make_a(); + PDI_expose("test_var", &test_var, PDI_OUT); + EXPECT_TRUE(std::filesystem::exists("file1.h5")); } -/* - * Name: decl_hdf5_test.04 - * - * Description: attribute +/* Metatadata use in filename expression & write on data (from mapping) */ -TEST(decl_hdf5_test, 04) +TEST_F(DeclHdf5, FilenameFromMetaMapping) { - //PDI_write + InitPdi(PC_parse_string(R"==( +logging: trace +metadata: { meta_var: int } +data: { test_var: double } +plugins: + decl_hdf5: + file: file${meta_var}.h5 + write: { test_var: ~ } +)==")); + + int const meta_var = 2; + PDI_expose("meta_var", &meta_var, PDI_OUT); + + auto const test_var = make_a(); + PDI_expose("test_var", &test_var, PDI_OUT); + EXPECT_TRUE(std::filesystem::exists("file2.h5")); +} - const char* CONFIG_YAML - = "logging: trace \n" - "metadata: \n" - " array_size: int \n" - "data: \n" - " array_data: { size: $array_size, type: array, subtype: int } \n" - " group_attr: float \n" - " dset_attr: {type: array, subtype: int, size: 4} \n" - "plugins: \n" - " decl_hdf5: \n" - " file: decl_hdf5_test_04.h5 \n" - " datasets: \n" - " data/array_data: { size: $array_size, type: array, subtype: int } \n" - " write: \n" - " array_data: \n" - " dataset: data/array_data \n" - " attributes: \n" - " expr_attr: $array_size \n" - " dset_attr: \n" - " attribute: data/array_data#dset_attr_name \n" - " group_attr: \n" - " attribute: data#group_attr_name \n"; - - PC_tree_t conf = PC_parse_string(CONFIG_YAML); - PDI_init(conf); - - int array_size = 10; - int test_array[array_size]; - for (int i = 0; i < 10; i++) { - test_array[i] = i; - } - PDI_expose("array_size", &array_size, PDI_OUT); - PDI_expose("array_data", test_array, PDI_OUT); +/* Metatadata use in filename expression & write on event + */ +TEST_F(DeclHdf5, FilenameFromMetaEvent) +{ + InitPdi(PC_parse_string(R"==( +logging: trace +metadata: { meta_var: int } +data: { test_var: double } +plugins: + decl_hdf5: + file: file${meta_var}.h5 + on_event: "event" + write: { test_var: ~ } +)==")); + + int const meta_var = 3; + PDI_expose("meta_var", &meta_var, PDI_OUT); + + auto const test_var = make_a(); + PDI_expose("test_var", &test_var, PDI_OUT); + EXPECT_FALSE(std::filesystem::exists("file3.h5")); + + PDI_multi_expose("wrong_event", "test_var", &test_var, PDI_OUT, nullptr); + EXPECT_FALSE(std::filesystem::exists("file3.h5")); + + PDI_multi_expose("event", "test_var", &test_var, PDI_OUT, nullptr); + EXPECT_TRUE(std::filesystem::exists("file3.h5")); +} - float group_attr = 1.2345f; - PDI_expose("group_attr", &group_attr, PDI_OUT); +/* Write then read complex structures (record of array of record) + */ +TEST_F(DeclHdf5, RecordOfArrayOfRecord) +{ + InitPdi(PC_parse_string(R"==( +logging: trace +metadata: + step: int +data: + complex_record: + type: struct + members: + - id: int + - value: + type: array + size: 4 + subtype: + type: struct + members: + - x: int + - y: int + - z: int +plugins: + decl_hdf5: + - file: decl_hdf5_test_outer_record.h5 + write: [complex_record] + when: $step=0 + - file: decl_hdf5_test_outer_record.h5 + read: [complex_record] + when: $step=1 +)==")); + + // write to file + int step = 0; + PDI_expose("step", &step, PDI_OUT); + + auto const complex_record = make_a(); + PDI_expose("complex_record", &complex_record, PDI_OUT); + + // read from file + step = 1; + PDI_expose("step", &step, PDI_OUT); + + Complex_record complex_record_read; + PDI_expose("complex_record", &complex_record_read, PDI_IN); + EXPECT_EQ(complex_record, complex_record_read); +} - int dset_attr[4]; - for (int i = 0; i < 4; i++) { - dset_attr[i] = i; - } - PDI_expose("dset_attr", dset_attr, PDI_OUT); +/* Write then read a selection of dataset of records + */ +TEST_F(DeclHdf5, ArrayOfRecordSelection) +{ + InitPdi(PC_parse_string(R"==( +logging: trace +metadata: + step: int +types: + Complex_record: + type: struct + members: + - id: int + - value: + type: array + size: 4 + subtype: + type: struct + members: + - x: int + - y: int + - z: int +data: + array_of_record: + type: array + size: 4 + subtype: Complex_record + array_of_record_read: Complex_record +plugins: + decl_hdf5: + - file: decl_hdf5_test_record_and_selection.h5 + datasets: + array_of_record: + type: array + size: 2 + subtype: Complex_record + write: + array_of_record: + dataset: array_of_record + # select a subset of the data in memory to write + memory_selection: { start: 1, size: 2 } + read: + array_of_record_read: + dataset: array_of_record + # select a subset of the data in file to read + dataset_selection: { start: 1, size: 1 } +)==")); + + // write to file + auto const array_of_record = make_a>(); + PDI_expose("array_of_record", array_of_record.data(), PDI_OUT); + + // load from file + Complex_record array_of_record_read; + PDI_expose("array_of_record_read", &array_of_record_read, PDI_IN); + // we excluded 1 element on write and 1 on read, so we lost 2 + EXPECT_EQ(array_of_record[2], array_of_record_read); +} - PDI_finalize(); - PC_tree_destroy(&conf); +/* attribute depend on group + */ +TEST_F(DeclHdf5, AttributesGroup) +{ + InitPdi(PC_parse_string(R"==( +logging: trace +metadata: + array_size: int +data: + array_data: { size: $array_size, type: array, subtype: int } + group_attr: float + dset_attr: {type: array, subtype: int, size: 4} + array_data_read: { size: $array_size, type: array, subtype: int } + group_attr_read: float + dset_attr_read: {type: array, subtype: int, size: 4} + expr_attr: int +plugins: + decl_hdf5: + - file: decl_hdf5_test_attribute_group.h5 + datasets: + data/array_data: { size: $array_size, type: array, subtype: int } + write: + array_data: + dataset: data/array_data + attributes: + expr_attr: $array_size + dset_attr: + attribute: data/array_data#dset_attr_name + group_attr: + attribute: data#group_attr_name + read: + array_data_read: + dataset: data/array_data + attributes: + expr_attr: $expr_attr + dset_attr_read: + attribute: data/array_data#dset_attr_name + group_attr_read: + attribute: data#group_attr_name +)==")); + + static constexpr int const array_size = 10; + PDI_expose("array_size", &array_size, PDI_OUT); - //PDI_read + auto const array_data = make_a>(); + PDI_expose("array_data", array_data.data(), PDI_OUT); - CONFIG_YAML - = "logging: trace \n" - "metadata: \n" - " array_size: int \n" - "data: \n" - " array_data: { size: 10, type: array, subtype: int } \n" - " dset_attr: {type: array, subtype: int, size: 4} \n" - " group_attr: float \n" - " expr_attr: int \n" - "plugins: \n" - " decl_hdf5: \n" - " file: decl_hdf5_test_04.h5 \n" - " datasets: \n" - " data/array_data: { size: 10, type: array, subtype: int } \n" - " read: \n" - " array_data: \n" - " dataset: data/array_data \n" - " attributes: \n" - " expr_attr: $expr_attr \n" - " dset_attr: \n" - " attribute: data/array_data#dset_attr_name \n" - " group_attr: \n" - " attribute: data#group_attr_name \n"; - - conf = PC_parse_string(CONFIG_YAML); - PDI_init(conf); - - array_size = 10; - for (int i = 0; i < 10; i++) { - test_array[i] = 0; - } - PDI_expose("array_size", &array_size, PDI_OUT); + auto const group_attr = make_a(); + PDI_expose("group_attr", &group_attr, PDI_OUT); - group_attr = 0.0f; - for (int i = 0; i < 4; i++) { - dset_attr[i] = 0; - } + auto const dset_attr = make_a>(); + PDI_expose("dset_attr", dset_attr.data(), PDI_OUT); - PDI_expose("group_attr", &group_attr, PDI_IN); - EXPECT_EQ(group_attr, 1.2345f) << "group_attr invalid value: " << group_attr << " (should be: 1.2345)"; + float group_attr_read = 0; + PDI_expose("group_attr_read", &group_attr_read, PDI_IN); + EXPECT_EQ(group_attr, group_attr_read); - PDI_expose("dset_attr", dset_attr, PDI_IN); - for (int i = 0; i < 4; i++) { - EXPECT_EQ(dset_attr[i], i) << "dset_attr[" << i << "] invalid value: " << dset_attr[i] << " (should be: " << i << ")"; - } + std::array dset_attr_read; + PDI_expose("dset_attr_read", dset_attr_read.data(), PDI_IN); + EXPECT_EQ(dset_attr, dset_attr_read); int expr_attr = 0; + std::array array_data_read; PDI_share("expr_attr", &expr_attr, PDI_IN); - PDI_expose("array_data", test_array, PDI_IN); - for (int i = 0; i < 10; i++) { - EXPECT_EQ(test_array[i], i) << "test_array[" << i << "] invalid value: " << test_array[i] << "(should be: " << i << ")"; - } - EXPECT_EQ(expr_attr, 10) << "expr_attr invalid value: " << expr_attr << " (should be: 10)"; + PDI_expose("array_data_read", array_data_read.data(), PDI_IN); + EXPECT_EQ(array_data, array_data_read); PDI_reclaim("expr_attr"); - - PDI_finalize(); - PC_tree_destroy(&conf); + EXPECT_EQ(array_size, expr_attr); } -/* - * Name: decl_hdf5_test.05 - * - * Description: attribute testing +/* attribute depend on data */ -TEST(decl_hdf5_test, 05) +TEST_F(DeclHdf5, AttributesData) { //PDI_write - const char* CONFIG_YAML - = "logging: trace \n" - "metadata: \n" - " array_size: int \n" - "data: \n" - " array_data: { size: $array_size, type: array, subtype: int } \n" - " dset_attr: {type: array, subtype: int, size: 4} \n" - " size_attr: int \n" - "plugins: \n" - " decl_hdf5: \n" - " file: decl_hdf5_test_05.h5 \n" - " on_event: \"write\" \n" - " write: [array_data, array_data#dset_attr, array_data#size_attr] \n"; - - PC_tree_t conf = PC_parse_string(CONFIG_YAML); - PDI_init(conf); - - int array_size = 10; - int test_array[array_size]; - for (int i = 0; i < 10; i++) { - test_array[i] = i; - } + InitPdi(PC_parse_string(R"==( +logging: trace +metadata: + array_size: int +data: + array_data: { size: $array_size, type: array, subtype: int } + dset_attr: {type: array, subtype: int, size: 4} + size_attr: int +plugins: + decl_hdf5: + - file: decl_hdf5_test_attribute_data.h55 + on_event: "write" + write: [array_data, array_data#dset_attr, array_data#size_attr] + - file: decl_hdf5_test_attribute_data.h55 + on_event: "read" + read: [array_data, array_data#dset_attr, array_data#size_attr] +)==")); + + static constexpr int const array_size = 10; PDI_expose("array_size", &array_size, PDI_OUT); - PDI_expose("array_data", test_array, PDI_OUT); - - int dset_attr[4]; - for (int i = 0; i < 4; i++) { - dset_attr[i] = i; - } - PDI_multi_expose("write", "size_attr", &array_size, PDI_OUT, "array_data", test_array, PDI_OUT, "dset_attr", dset_attr, PDI_OUT, NULL); - PDI_finalize(); - PC_tree_destroy(&conf); + auto const array_data = make_a>(); + PDI_expose("array_data", array_data.data(), PDI_OUT); - //PDI_read - CONFIG_YAML - = "logging: trace \n" - "metadata: \n" - " array_size: int \n" - "data: \n" - " array_data: { size: $array_size, type: array, subtype: int } \n" - " dset_attr: {type: array, subtype: int, size: 4} \n" - " size_attr: int \n" - "plugins: \n" - " decl_hdf5: \n" - " file: decl_hdf5_test_05.h5 \n" - " on_event: \"read\" \n" - " read: [array_data, array_data#dset_attr, array_data#size_attr] \n"; - - conf = PC_parse_string(CONFIG_YAML); - PDI_init(conf); - - array_size = 10; - for (int i = 0; i < 10; i++) { - test_array[i] = 0; - } - PDI_expose("array_size", &array_size, PDI_OUT); - - float group_attr = 0.0f; - for (int i = 0; i < 4; i++) { - dset_attr[i] = 0; - } + auto const dset_attr = make_a>(); + PDI_multi_expose( + "write", + "size_attr", + &array_size, + PDI_OUT, + "array_data", + array_data.data(), + PDI_OUT, + "dset_attr", + dset_attr.data(), + PDI_OUT, + NULL + ); int size_attr = 0; - PDI_multi_expose("read", "size_attr", &size_attr, PDI_IN, "array_data", test_array, PDI_IN, "dset_attr", dset_attr, PDI_IN, NULL); - - EXPECT_EQ(size_attr, 10) << "size_attr invalid value: " << size_attr << " (should be: 10)"; - - for (int i = 0; i < 4; i++) { - EXPECT_EQ(dset_attr[i], i) << "dset_attr[" << i << "] invalid value: " << dset_attr[i] << " (should be: " << i << ")"; - } - - for (int i = 0; i < 10; i++) { - EXPECT_EQ(test_array[i], i) << "test_array[" << i << "] invalid value: " << test_array[i] << " (should be: " << i << ")"; - } - - PDI_finalize(); - PC_tree_destroy(&conf); + std::array dset_attr_read; + std::array array_data_read; + PDI_multi_expose( + "read", + "size_attr", + &size_attr, + PDI_IN, + "array_data", + array_data_read.data(), + PDI_IN, + "dset_attr", + dset_attr_read.data(), + PDI_IN, + NULL + ); + EXPECT_EQ(array_size, size_attr); + EXPECT_EQ(dset_attr, dset_attr_read); + EXPECT_EQ(array_data, array_data_read); } -/* - * Name: decl_hdf5_test.06 - * - * Description: read dataset size before dataset itself +/* read dataset size before dataset itself */ -TEST(decl_hdf5_test, 06) +TEST_F(DeclHdf5, SizeOf) { //PDI_write - const char* CONFIG_YAML - = "logging: trace \n" - "data: \n" - " array_data: { size: 10, type: array, subtype: int } \n" - " matrix_data: { size: [10, 10], type: array, subtype: float } \n" - "plugins: \n" - " decl_hdf5: \n" - " file: decl_hdf5_test_06.h5 \n" - " write: [array_data, matrix_data] \n"; - - PC_tree_t conf = PC_parse_string(CONFIG_YAML); - PDI_init(conf); - - int array_data[10]; - for (int i = 0; i < 10; i++) { - array_data[i] = i; - } - PDI_expose("array_data", array_data, PDI_OUT); - - int matrix_data[10][10]; - for (int i = 0; i < 10; i++) { - for (int j = 0; j < 10; j++) { - matrix_data[i][j] = 10 * i + j; - } - } - PDI_expose("matrix_data", matrix_data, PDI_OUT); - - PDI_finalize(); - PC_tree_destroy(&conf); - - //PDI_read - CONFIG_YAML - = "logging: trace \n" - "metadata: \n" - " input: int \n" - "data: \n" - " array_data_size: int64 \n" - " matrix_data_size: { size: 2, type: array, subtype: int64 } \n" - "plugins: \n" - " decl_hdf5: \n" - " - file: decl_hdf5_test_06.h5 \n" - " when: $input \n" - " read: \n" - " array_data_size: \n" - " size_of: array_data \n" - " matrix_data_size: \n" - " size_of: matrix_data \n" - " - file: decl_hdf5_test_06.h5 \n" - " on_event: \"read_size\" \n" - " read: \n" - " array_data_size: \n" - " size_of: array_data \n" - " matrix_data_size: \n" - " size_of: matrix_data \n"; - - conf = PC_parse_string(CONFIG_YAML); - PDI_init(conf); - - int input = 1; - PDI_expose("input", &input, PDI_OUT); + InitPdi(PC_parse_string(R"==( +logging: trace +metadata: + step: int +data: + array_data_size: int64 + array_data: { size: 10, type: array, subtype: int } + matrix_data_size: { size: 2, type: array, subtype: int64 } + matrix_data: { size: [10, 10], type: array, subtype: float } +plugins: + decl_hdf5: + - file: decl_hdf5_test_read_dataset_size_before_dataset_itself.h5 + when: $step=0 + write: [array_data, matrix_data] + - file: decl_hdf5_test_read_dataset_size_before_dataset_itself.h5 + when: $step + read: + array_data_size: + size_of: array_data + matrix_data_size: + size_of: matrix_data + - file: decl_hdf5_test_read_dataset_size_before_dataset_itself.h5 + on_event: "read_size" + read: + array_data_size: + size_of: array_data + matrix_data_size: + size_of: matrix_data)==")); + + int step = 0; + PDI_expose("step", &step, PDI_OUT); + + auto const array_data = make_a>(); + PDI_expose("array_data", array_data.data(), PDI_OUT); + + auto const matrix_data = make_a>(); + PDI_expose("matrix_data", matrix_data.data(), PDI_OUT); + + step = 1; + PDI_expose("step", &step, PDI_OUT); long array_size = 0; - long matrix_size[2] = {0, 0}; PDI_expose("array_data_size", &array_size, PDI_IN); - PDI_expose("matrix_data_size", matrix_size, PDI_IN); + EXPECT_EQ(10, array_size); - EXPECT_EQ(array_size, 10) << "array_size invalid value: " << array_size << " (should be: 10)"; - EXPECT_TRUE(matrix_size[0] == 10 || matrix_size[1] == 10) - << "matrix_size invalid value: [" << matrix_size[0] << ", " << matrix_size[1] << "] (should be: [10, 10]"; + std::array matrix_size = {}; + PDI_expose("matrix_data_size", matrix_size.data(), PDI_IN); + EXPECT_EQ(10, matrix_size[0]); + EXPECT_EQ(10, matrix_size[1]); // now with event - input = 0; - PDI_expose("input", &input, PDI_OUT); - - array_size = 0; - matrix_size[0] = 0; - matrix_size[1] = 0; - PDI_multi_expose("read_size", "array_data_size", &array_size, PDI_IN, "matrix_data_size", matrix_size, PDI_IN, NULL); - - EXPECT_EQ(array_size, 10) << "array_size invalid value: " << array_size << " (should be: 10)"; - EXPECT_TRUE(matrix_size[0] == 10 || matrix_size[1] == 10) - << "matrix_size invalid value: [" << matrix_size[0] << ", " << matrix_size[1] << "] (should be: [10, 10]"; - - PDI_finalize(); - PC_tree_destroy(&conf); + step = 2; + PDI_expose("step", &step, PDI_OUT); + + long array_size_event = 0; + std::array matrix_size_event; + PDI_multi_expose("read_size", "array_data_size", &array_size_event, PDI_IN, "matrix_data_size", matrix_size_event.data(), PDI_IN, nullptr); + EXPECT_EQ(10, array_size_event); + EXPECT_EQ(10, matrix_size_event[0]); + EXPECT_EQ(10, matrix_size_event[1]); } -/* - * Name: decl_hdf5_test.07 - * - * Description: different dimension of data and dataset +/* different dimension of data and dataset */ -TEST(decl_hdf5_test, 07) +TEST_F(DeclHdf5, DifferentDim) { //PDI_write - const char* CONFIG_YAML - = "logging: trace \n" - "data: \n" - " scalar_data: double \n" - " array_data: { size: [8, 8], type: array, subtype: int } \n" - "plugins: \n" - " decl_hdf5: \n" - " file: decl_hdf5_test_07.h5 \n" - " datasets: \n" - " scalar_data: {type: array, subtype: double, size: 1} \n" - " array_data: {type: array, subtype: int, size: [4, 4, 4]} \n" - " write: [scalar_data, array_data] \n"; - - PC_tree_t conf = PC_parse_string(CONFIG_YAML); - PDI_init(conf); - - double scalar_data = 1.2345; + InitPdi(PC_parse_string(R"==( +logging: trace +data: + scalar_data: double + array_data: { size: [8, 8], type: array, subtype: int } +plugins: + decl_hdf5: + file: decl_hdf5_test_different_dim_of_data_and_dataset.h5 + datasets: + scalar_data: {type: array, subtype: double, size: 1} + array_data: {type: array, subtype: int, size: [4, 4, 4]} + write: [scalar_data, array_data] +)==")); + + auto const scalar_data = make_a(); PDI_expose("scalar_data", &scalar_data, PDI_OUT); - int array_data[8][8]; - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 8; j++) { - array_data[i][j] = i * 8 + j; - } - } - - PDI_expose("array_data", array_data, PDI_OUT); + auto const array_data = make_a, 8>>(); + PDI_expose("array_data", array_data.data(), PDI_OUT); - PDI_finalize(); - PC_tree_destroy(&conf); + FinalizePdi(); //PDI_read - CONFIG_YAML - = "logging: trace \n" - "data: \n" - " scalar_data: double \n" - " array_data: { size: [8, 8], type: array, subtype: int } \n" - "plugins: \n" - " decl_hdf5: \n" - " file: decl_hdf5_test_07.h5 \n" - " datasets: \n" - " scalar_data: {type: array, subtype: double, size: 1} \n" - " array_data: {type: array, subtype: int, size: [4, 4, 4]} \n" - " read: [scalar_data, array_data] \n"; - - conf = PC_parse_string(CONFIG_YAML); - PDI_init(conf); - - scalar_data = 0; - PDI_expose("scalar_data", &scalar_data, PDI_IN); - EXPECT_EQ(scalar_data, 1.2345) << "Wrong value of scalar_data: " << scalar_data << " != 1.2345"; - - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 8; j++) { - array_data[i][j] = 0; - } - } - - PDI_expose("array_data", array_data, PDI_IN); - - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 8; j++) { - EXPECT_EQ(array_data[i][j], i * 8 + j) << "Wrong value of array_data[" << i << "][" << j << "]: " << array_data[i][j] - << " != " << i * 8 + j; - } - } - - PDI_finalize(); - PC_tree_destroy(&conf); + InitPdi(PC_parse_string(R"==( +logging: trace +data: + scalar_data: double + array_data: { size: [8, 8], type: array, subtype: int } +plugins: + decl_hdf5: + file: decl_hdf5_test_different_dim_of_data_and_dataset.h5 + datasets: + scalar_data: {type: array, subtype: double, size: 1} + array_data: {type: array, subtype: int, size: [4, 4, 4]} + read: [scalar_data, array_data] +)==")); + + double scalar_data_read = 0; + PDI_expose("scalar_data", &scalar_data_read, PDI_IN); + EXPECT_EQ(scalar_data, scalar_data_read); + + std::array, 8> array_data_read = {}; + PDI_expose("array_data", array_data_read.data(), PDI_IN); + EXPECT_EQ(array_data, array_data_read); } -/* - * Name: decl_hdf5_test.08 - * - * Description: - */ -// TEST(decl_hdf5_test, 08) { - -// //PDI write -// const char* CONFIG_YAML = -// "logging: trace \n" -// "data: \n" -// " array_data: { size: 10, type: array, subtype: int } \n" -// "plugins: \n" -// " decl_hdf5: \n" -// " file: decl_hdf5_test_10.h5 \n" -// // " datasets: \n" -// // " array_data: {type: array, subtype: int, size: 10} \n" -// " write: \n" -// " array_data: \n" -// " - memory_selection: \n" -// " size: 10 \n" -// " dataset_selection: \n" -// " size: 10 \n" -// ; - -// PC_tree_t conf = PC_parse_string(CONFIG_YAML); -// PDI_init(conf); - -// int test_array[10]; -// for (int i = 0; i < 10; i++) { -// test_array[i] = i; -// } - -// PDI_expose("array_data", test_array, PDI_OUT); - -// PDI_finalize(); -// PC_tree_destroy(&conf); - -// //PDI read -// CONFIG_YAML = -// "logging: trace \n" -// "data: \n" -// " array_data: { size: 10, type: array, subtype: int } \n" -// "plugins: \n" -// " decl_hdf5: \n" -// " file: decl_hdf5_test_10.h5 \n" -// " read: [array_data] \n" -// ; - -// PC_tree_t conf = PC_parse_string(CONFIG_YAML); -// PDI_init(conf); - -// test_array[10]; -// for (int i = 0; i < 10; i++) { -// test_array[i] = 0; -// } -// PDI_expose("array_data", test_array, PDI_IN); - -// for (int i = 0; i < 10; i++) { -// if (test_array[i] != i) { -// fprintf(stderr, "[%d] %d != %d\n ", i, test_array[i], i); -// return 1; -// } -// } - -// PDI_finalize(); -// PC_tree_destroy(&conf); - -// int status = PDI_write(); -// ASSERT_EQ (status, 0) << "Status Error - PDI_write" << status; - -// status = PDI_read(); -// ASSERT_EQ (status, 0) << "Status Error - PDI_write" << status; -// } - - - -/* - * Name: decl_hdf5_test.09 - * - * Description: colission policy +/* Test of the various collision policies */ -TEST(decl_hdf5_test, 08) +TEST_F(DeclHdf5, Collision) { - const char* CONFIG_YAML - = "logging: trace \n" - "data: \n" - " scalar_data: int \n" - " array_data: { size: [4, 4], type: array, subtype: int } \n" - "plugins: \n" - " decl_hdf5: \n" - " - file: decl_hdf5_test_08.h5 \n" - " on_event: init \n" - " datasets: \n" - " array_data: {type: array, subtype: int, size: [4, 4]} \n" - " write: [array_data] \n" - " - file: decl_hdf5_test_08.h5 \n" - " collision_policy: skip \n" - " on_event: skip \n" - " datasets: \n" - " array_data: {type: array, subtype: int, size: [4, 4]} \n" - " write: [array_data] \n" - " - file: decl_hdf5_test_08.h5 \n" - " collision_policy: write_into \n" - " on_event: write_into \n" - " datasets: \n" - " scalar_data: int \n" - " array_data: {type: array, subtype: int, size: [4, 4]} \n" - " write: [scalar_data, array_data] \n" - " - file: decl_hdf5_test_08.h5 \n" - " collision_policy: replace \n" - " on_event: replace \n" - " datasets: \n" - " array_data: {type: array, subtype: int, size: [4, 4]} \n" - " write: [array_data] \n" - " - file: decl_hdf5_test_08.h5 \n" - " collision_policy: write_into \n" - " on_event: append \n" - " datasets: \n" - " scalar_data: int \n" - " write: \n" - " scalar_data: \n" - " collision_policy: error \n" - " - file: decl_hdf5_test_08.h5 \n" - " collision_policy: error \n" - " on_event: error \n" - " datasets: \n" - " array_data: {type: array, subtype: int, size: [4, 4]} \n" - " write: [array_data] \n" - " - file: decl_hdf5_test_08.h5 \n" - " on_event: read \n" - " datasets: \n" - " array_data: {type: array, subtype: int, size: [4, 4]} \n" - " read: [array_data] \n" - " - file: decl_hdf5_test_08.h5 \n" - " on_event: read_scalar \n" - " datasets: \n" - " scalar_data: int \n" - " read: [scalar_data] \n"; - - PC_tree_t conf = PC_parse_string(CONFIG_YAML); - PDI_init(conf); - - // INIT - int array_data[4][4]; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - array_data[i][j] = 0; - } - } - - PDI_multi_expose("init", "array_data", array_data, PDI_OUT, NULL); + InitPdi(PC_parse_string(R"==( +logging: trace +data: + scalar_data: int + array_data: { size: [4, 4], type: array, subtype: int } +plugins: + decl_hdf5: + - file: decl_hdf5_test_collision_policy.h5 + on_event: init + write: [array_data] + - file: decl_hdf5_test_collision_policy.h5 + collision_policy: skip + on_event: skip + write: [array_data] + - file: decl_hdf5_test_collision_policy.h5 + collision_policy: write_into + on_event: write_into + write: [scalar_data, array_data] + - file: decl_hdf5_test_collision_policy.h5 + collision_policy: replace + on_event: replace + write: [array_data] + - file: decl_hdf5_test_collision_policy.h5 + collision_policy: write_into + on_event: append + write: + scalar_data: + collision_policy: error + - file: decl_hdf5_test_collision_policy.h5 + collision_policy: error + on_event: error + write: [array_data] + - file: decl_hdf5_test_collision_policy.h5 + on_event: read + read: [array_data] + - file: decl_hdf5_test_collision_policy.h5 + on_event: read_scalar + read: [scalar_data] +)==")); + + // INIT => array_data = array_data_1 + auto const array_data_1 = make_a, 4>>(); + PDI_multi_expose("init", "array_data", array_data_1.data(), PDI_OUT, nullptr); + + // SKIP => array_data already present, do nothing + auto const array_data_2 = make_a, 4>>(); + PDI_multi_expose("skip", "array_data", array_data_2.data(), PDI_OUT, nullptr); + + { // check that array_data == array_data_pos + std::array, 4> array_data_read; + PDI_multi_expose("read", "array_data", array_data_read.data(), PDI_IN, nullptr); + EXPECT_EQ(array_data_1, array_data_read); + } + + // WRITE_INTO => scalar_data = scalar_data_val; array_data = array_data_3 + auto const scalar_data_val = make_a(); + auto const array_data_3 = make_a, 4>>(); + PDI_multi_expose("write_into", "scalar_data", &scalar_data_val, PDI_OUT, "array_data", array_data_3.data(), PDI_OUT, nullptr); + + { // check that scalar_data == scalar_data_val + int scalar_data_read = 0; + PDI_multi_expose("read_scalar", "scalar_data", &scalar_data_read, PDI_IN, nullptr); + EXPECT_EQ(scalar_data_val, scalar_data_read); + } + + { // check that array_data == array_data_3 + std::array, 4> array_data_read; + PDI_multi_expose("read", "array_data", array_data_read.data(), PDI_IN, nullptr); + EXPECT_EQ(array_data_3, array_data_read); + } + + // REPLACE => array_data = array_data_4; removes scalar_data + auto const array_data_4 = make_a, 4>>(); + PDI_multi_expose("replace", "array_data", array_data_4.data(), PDI_OUT, nullptr); + + { // check that array_data == array_data_4 + std::array, 4> array_data_read; + PDI_multi_expose("read", "array_data", array_data_read.data(), PDI_IN, nullptr); + EXPECT_EQ(array_data_4, array_data_read); + } + + { // check that scalar_data is missing + int scalar_data_read = 0; + EXPECT_CALL( + *this, + PdiError( + Eq(PDI_ERR_SYSTEM), + StartsWith("Error while triggering event `read_scalar': " + "System_error: Cannot open `scalar_data' dataset object 'scalar_data' doesn't exist") + ) + ); + PDI_multi_expose("read_scalar", "scalar_data", &scalar_data_read, PDI_IN, nullptr); + } + + // APPEND => scalar_data = scalar_data_val + PDI_multi_expose("append", "scalar_data", &scalar_data_val, PDI_OUT, nullptr); + + { // check that scalar_data == scalar_data_val + int scalar_data_read = 0; + PDI_multi_expose("read_scalar", "scalar_data", &scalar_data_read, PDI_IN, nullptr); + EXPECT_EQ(scalar_data_val, scalar_data_read); + } + + { // check that array_data == array_data_4 + std::array, 4> array_data_read; + PDI_multi_expose("read", "array_data", array_data_read.data(), PDI_IN, nullptr); + EXPECT_EQ(array_data_4, array_data_read); + } + + // APPEND => error (scalar_data already exists) + EXPECT_CALL( + *this, + PdiError( + Eq(PDI_ERR_SYSTEM), + StrEq("Error while triggering event `append': System_error: Dataset collision `scalar_data': Dataset already exists") + ) + ); + auto const scalar_data_2 = make_a(); + PDI_multi_expose("append", "scalar_data", &scalar_data_2, PDI_OUT, nullptr); + + // ERROR => error (file already exists) + EXPECT_CALL( + *this, + PdiError( + Eq(PDI_ERR_SYSTEM), + StrEq("Error while triggering event `error': System_error: Filename collision `decl_hdf5_test_collision_policy.h5': File already exists") + ) + ); + auto const array_data_5 = make_a, 4>>(); + PDI_multi_expose("error", "array_data", array_data_5.data(), PDI_OUT, nullptr); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - array_data[i][j] = 1; - } + { // check that scalar_data == scalar_data_val + int scalar_data_read = 0; + PDI_multi_expose("read_scalar", "scalar_data", &scalar_data_read, PDI_IN, nullptr); + EXPECT_EQ(scalar_data_val, scalar_data_read); } - // SKIP - PDI_multi_expose("skip", "array_data", array_data, PDI_OUT, NULL); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - array_data[i][j] = -1; - } - } - PDI_multi_expose("read", "array_data", array_data, PDI_IN, NULL); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - if (array_data[i][j] != 0) { - printf("array_data[%d][%d] = %d, should be: 0", i, j, array_data[i][j]); - PDI_finalize(); - PC_tree_destroy(&conf); - FAIL(); - } - } + { // check that array_data == array_data_4 + std::array, 4> array_data_read; + PDI_multi_expose("read", "array_data", array_data_read.data(), PDI_IN, nullptr); + EXPECT_EQ(array_data_4, array_data_read); } +} - // WRITE_INTO - int scalar_data = 42; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - array_data[i][j] = 2; - } - } - PDI_multi_expose("write_into", "scalar_data", &scalar_data, PDI_OUT, "array_data", array_data, PDI_OUT, NULL); - scalar_data = -1; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - array_data[i][j] = -1; - } - } - PDI_multi_expose("read_scalar", "scalar_data", &scalar_data, PDI_IN, NULL); - if (scalar_data != 42) { - printf("scalar_data = %d, should be: 42", scalar_data); - PDI_finalize(); - PC_tree_destroy(&conf); - FAIL(); - } - PDI_multi_expose("read", "array_data", array_data, PDI_IN, NULL); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - if (array_data[i][j] != 2) { - printf("array_data[%d][%d] = %d, should be: 2", i, j, array_data[i][j]); - PDI_finalize(); - PC_tree_destroy(&conf); - FAIL(); - } - } - } +/* test the creation of groups define by differents regex + */ +TEST_F(DeclHdf5, CreateGroupsWithRegexes) +{ + InitPdi(PC_parse_string(R"==( +logging: trace +data: + array_01: { type: array, size: 3, subtype: int } + array_02: { type: array, size: 3, subtype: int } + array_03: { type: array, size: 3, subtype: int } + array_01_read: { type: array, size: 3, subtype: int } + array_02_read: { type: array, size: 3, subtype: int } + array_03_read: { type: array, size: 3, subtype: int } +metadata: + index: int +plugins: + decl_hdf5: + - file: decl_hdf5_test_create_different_groups_with_regex.h5 + datasets: + group/lion_array_data: { type: array, size: 5, subtype: int } + group[0-9]+/dog_array_data: { type: array, size: 5, subtype: int } + group_second.*/cat_array_data: { type: array, size: 5, subtype: int } + write: + array_01: + dataset: 'group${index}/dog_array_data' + dataset_selection: { start: 1, size: 3 } + array_02: + dataset: group_second_TRY/cat_array_data + dataset_selection: { start: 1, size: 3 } + array_03: + dataset: group/lion_array_data + dataset_selection: { start: 1, size: 3 } + read: + array_01_read: + dataset: 'group${index}/dog_array_data' + dataset_selection: { start: 1, size: 3 } + array_02_read: + dataset: group_second_TRY/cat_array_data + dataset_selection: { start: 1, size: 3 } + array_03_read: + dataset: group/lion_array_data + dataset_selection: { start: 1, size: 3 } +)==")); + + int index = 123; + PDI_expose("index", &index, PDI_OUT); + + auto const array_01 = make_a>(); + PDI_expose("array_01", array_01.data(), PDI_OUT); + + auto const array_02 = make_a>(); + PDI_expose("array_02", array_02.data(), PDI_OUT); + + auto const array_03 = make_a>(); + PDI_expose("array_03", array_03.data(), PDI_OUT); + + std::array array_01_read; + PDI_expose("array_01_read", array_01_read.data(), PDI_IN); + EXPECT_EQ(array_01, array_01_read); + + std::array array_02_read; + PDI_expose("array_02_read", array_02_read.data(), PDI_IN); + EXPECT_EQ(array_02, array_02_read); + + std::array array_03_read; + PDI_expose("array_03_read", array_03_read.data(), PDI_IN); + EXPECT_EQ(array_03, array_03_read); +} - // REPLACE - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - array_data[i][j] = 3; - } - } - PDI_multi_expose("replace", "array_data", array_data, PDI_OUT, NULL); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - array_data[i][j] = -1; - } - } - PDI_multi_expose("read", "array_data", array_data, PDI_IN, NULL); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - if (array_data[i][j] != 3) { - printf("array_data[%d][%d] = %d, should be: 3", i, j, array_data[i][j]); - PDI_finalize(); - PC_tree_destroy(&conf); - FAIL(); - } - } - } - PDI_errhandler(PDI_NULL_HANDLER); - PDI_status_t status = PDI_multi_expose("read_scalar", "scalar_data", &scalar_data, PDI_IN, NULL); - if (status == PDI_OK) { - printf("replace: status = %d, should not be: 0 (PDI_OK)", status); - PDI_finalize(); - PC_tree_destroy(&conf); - FAIL(); - } - PDI_errhandler(PDI_ASSERT_HANDLER); - - // APPEND - scalar_data = 42; - PDI_multi_expose("append", "scalar_data", &scalar_data, PDI_OUT, NULL); - scalar_data = -1; - PDI_multi_expose("read_scalar", "scalar_data", &scalar_data, PDI_IN, NULL); - if (scalar_data != 42) { - printf("scalar_data = %d, should be: 42", scalar_data); - PDI_finalize(); - PC_tree_destroy(&conf); - FAIL(); - } - PDI_errhandler(PDI_NULL_HANDLER); - status = PDI_multi_expose("append", "scalar_data", &scalar_data, PDI_OUT, NULL); - if (status == PDI_OK) { - printf("append: status = %d, should not be: 0 (PDI_OK)", status); - PDI_finalize(); - PC_tree_destroy(&conf); - FAIL(); +/* creating different groups defined by the same regex and depended on an index + */ +TEST_F(DeclHdf5, CreateMultipleGroupsFromOneRegex) +{ + InitPdi(PC_parse_string(R"==( +logging: trace +metadata: + index: int +data: + array_data: { type: array, size: 3, subtype: int } + array_data_read: { type: array, size: 3, subtype: int } +plugins: + decl_hdf5: + file: decl_hdf5_test_create_groups_that_depend_on_index.h5 + datasets: + group[0-9]+/array_data: { type: array, size: 5, subtype: int } + write: + array_data: + dataset: 'group${index}/array_data' + dataset_selection: { start: 1, size: 3 } + read: + array_data_read: + dataset: 'group${index}/array_data' + dataset_selection: { start: 1, size: 3 } +)==")); + + auto const array_data = make_a, 3>>(); + for (int index = 0; index < std::size(array_data); ++index) { + PDI_expose("index", &index, PDI_OUT); + PDI_expose("array_data", array_data[index].data(), PDI_OUT); + } + + for (int index = 0; index < std::size(array_data); ++index) { + PDI_expose("index", &index, PDI_OUT); + std::array array_data_read = {}; + PDI_expose("array_data_read", array_data_read.data(), PDI_IN); + EXPECT_EQ(array_data[index], array_data_read) << "index = " << index; } - PDI_errhandler(PDI_ASSERT_HANDLER); +} - // ERROR - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - array_data[i][j] = 4; - } - } - PDI_errhandler(PDI_NULL_HANDLER); - status = PDI_multi_expose("error", "array_data", array_data, PDI_OUT, NULL); - if (status == PDI_OK) { - printf("error: status = %d, should not be: 0 (PDI_OK)", status); - PDI_finalize(); - PC_tree_destroy(&conf); - FAIL(); - } +/* check error message generated with a dataset where 4 regex are found + */ - PDI_multi_expose("read", "array_data", array_data, PDI_IN, NULL); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - if (array_data[i][j] != 3) { - printf("array_data[%d][%d] = %d, should be: 4", i, j, array_data[i][j]); - PDI_finalize(); - PC_tree_destroy(&conf); - FAIL(); - } - } - } - PDI_errhandler(PDI_ASSERT_HANDLER); +TEST_F(DeclHdf5, ConfigErrorForMultipleRegexes) +{ + InitPdi(PC_parse_string(R"==( +logging: + level: trace +data: + array_data: { type: array, subtype: int, size: 3 } +metadata: + index: int +plugins: + decl_hdf5: + file: decl_hdf5_test_four_regex_found.h5 + on_event: write_event + datasets: + group[0-9]+/array_data: { type: array, subtype: int, size: 3 } + group.*/array_data: { type: array, subtype: int, size: 3 } + group1.*/array_data: { type: array, subtype: int, size: 3 } + group/.*/array_data: { type: array, subtype: int, size: 3 } + group12.*/array_data: { type: array, subtype: int, size: 3 } + write: + array_data: + dataset: 'group${index}/array_data' +)==")); + + int const index = 123; + PDI_expose("index", &index, PDI_OUT); + + auto const array_data = make_a>(); + EXPECT_CALL( + *this, + PdiError( + Eq(PDI_ERR_SPECTREE), + StrEq("Error while triggering event `write_event': Spectree_error: " + "Found `4' match(es) in the list of datasets section for `group123/array_data'. " + "Cannot choose the right element in datasets.\n" + "The elements that match `group123/array_data' are:\n" + " - group[0-9]+/array_data defined in line 13\n" + " - group.*/array_data defined in line 14\n" + " - group1.*/array_data defined in line 15\n" + " - group12.*/array_data defined in line 17\n" + "Attention: The elements are considered as a regex.") + ) + ); + PDI_multi_expose("write_event", "array_data", array_data.data(), PDI_OUT, nullptr); +} - PDI_finalize(); - PC_tree_destroy(&conf); +/* check error when dataset_selection is given and no datasets is found + */ +TEST_F(DeclHdf5, DatasetMissing) +{ + InitPdi(PC_parse_string(R"==( +logging: trace +metadata: + index: int +data: + array_data: { type: array, subtype: int, size: 3 } +plugins: + decl_hdf5: + file: decl_hdf5_test_no_regex.h5 + write: + array_data: + dataset: 'group${index}/array_data' + dataset_selection: { start: 1, size: 3 } +)==")); + + int const index = 123; + PDI_expose("index", &index, PDI_OUT); + + auto const array_data = make_a>(); + EXPECT_CALL( + *this, + PdiError( + Eq(PDI_ERR_SPECTREE), + StrEq("Unable to share `array_data', Unable to share `array_data', Error while triggering data share `array_data': " + "Spectree_error in line 13: Dataset selection is invalid for implicit dataset `group123/array_data'") + ) + ); + PDI_expose("array_data", array_data.data(), PDI_OUT); } diff --git a/plugins/decl_hdf5/tests/fortran/CMakeLists.txt b/plugins/decl_hdf5/tests/fortran/CMakeLists.txt index 6aba57b20..5c5e30334 100644 --- a/plugins/decl_hdf5/tests/fortran/CMakeLists.txt +++ b/plugins/decl_hdf5/tests/fortran/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2021-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) # # All rights reserved. @@ -28,7 +28,7 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) enable_language(Fortran) # Includes diff --git a/plugins/decl_netcdf/AUTHORS b/plugins/decl_netcdf/AUTHORS index ea2dea372..691aed764 100644 --- a/plugins/decl_netcdf/AUTHORS +++ b/plugins/decl_netcdf/AUTHORS @@ -27,4 +27,5 @@ Kacper Sinkiewicz - PSNC (ksinkiewicz@man.poznan.pl) * Test refactoring using GTEST Yushan Wang - CEA (yushan.wang@cea.fr) +* Add native compression support * Maintainer (Sept. 2023 - ...) diff --git a/plugins/decl_netcdf/CHANGELOG.md b/plugins/decl_netcdf/CHANGELOG.md index ffa0df3c3..f5b709732 100644 --- a/plugins/decl_netcdf/CHANGELOG.md +++ b/plugins/decl_netcdf/CHANGELOG.md @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] ### Added +* Add native netcdf deflate support with chunking + [[#603](https://github.com/pdidev/pdi/issues/603)] +* Add type check when reading scalar variable from file + [[#647](https://github.com/pdidev/pdi/issues/647)] ### Changed @@ -19,6 +23,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Security +## [1.10.0] - 2026-01-31 + +### Changed +* Update the version of dependencies according to our policy: oldest supported + Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: + CMake 3.22, and NetCDF 4.8.1 [#613](https://github.com/pdidev/pdi/issues/613) + +### Fixed +* Fixed a error incorrectly raised when using the scalar format in yaml write + configuration [#636](https://github.com/pdidev/pdi/issues/636) + + ## [1.8.1] - 2025-01-23 ### Fixed diff --git a/plugins/decl_netcdf/CMakeLists.txt b/plugins/decl_netcdf/CMakeLists.txt index 7d195b866..96e14ed4d 100644 --- a/plugins/decl_netcdf/CMakeLists.txt +++ b/plugins/decl_netcdf/CMakeLists.txt @@ -1,6 +1,6 @@ #============================================================================= # Copyright (C) 2019 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) -# Copyright (C) 2020-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -28,9 +28,13 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(pdi_decl_netcdf_plugin LANGUAGES C CXX) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") +if("${CMAKE_VERSION}" VERSION_LESS 4.1) + # Workaround missing "Prefer h5hl compilers if HDF5_FIND_HL is enabled" in cmake pre-4.1 + list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}/4.1") +endif() option(BUILD_NETCDF_PARALLEL "Build Decl'NetCDF in parallel mode" ON) @@ -44,7 +48,7 @@ if("${BUILD_NETCDF_PARALLEL}") endif() # NetCDF -find_package(NetCDF 4.7.3 REQUIRED) +find_package(NetCDF 4.8 REQUIRED) if("${BUILD_NETCDF_PARALLEL}" AND NOT "PARALLEL4" IN_LIST NetCDF_FEATURES) message(FATAL_ERROR "Parallel NetCDF required, sequential NetCDF only found. Please set -DBUILD_NETCDF_PARALLEL=OFF to disable parallel NetCDF") endif() diff --git a/plugins/decl_netcdf/README.md b/plugins/decl_netcdf/README.md index 5d8f2b732..a394256f8 100644 --- a/plugins/decl_netcdf/README.md +++ b/plugins/decl_netcdf/README.md @@ -154,6 +154,21 @@ plugins: |:------------------------|:--------------------------------------------------------------------------| |name (path) of the group |Map with `attribute` key with value as map of \ref decl_netcdf_attr | +#### deflate subtree {#decl_netcdf_deflate} + +|key |value | | +|:-------|:-------------------------------------------------------|-----| +|deflate | Compression level (0-9) for all variables of the file (defalut=0). Can be overwritten by the content of `variables definition` | *optional* | + +See \ref decl_netcdf_variables for more information about the `deflate` attribut. +Configuration example: +```yaml +plugins: + decl_netcdf: + - file: "compressed_file.nc" + deflate: 6 +``` + ### variables subtree {#decl_netcdf_variables} Defines variables in the NetCDF file. Mainly used to define dimensions names and read/write attributes of the variable. @@ -181,6 +196,8 @@ plugins: subtype: double size: [0, $value, $value] # 0 -> UNLIMITED dimension dimensions: ["time", "height", "width"] + deflate: 6 + chunking: [10, 100, 100] attributes: attr1: $value ``` @@ -193,7 +210,11 @@ plugins: |type |type of variable (defined the same way as other types in %PDI)|*optional* | |dimensions |array of dimensions names of variable |*optional* | |attributes |Map of \ref decl_netcdf_attr |*optional* | +|deflate |Compression level (0-9) of the variable (defalut=0) |*optional* | +|chunking |Chunk size of the variable for chunked storage |*optional* | +`deflate` allows you to set the compression level of a variable. It uses the native netCDF compression. Using `deflate: 0` means no compression and it is the default setting. +When compression is enabled, you can also set the variable's chunk size by `chunking`. If you do not specify the `chunking`, an automatic chunking will be used. The `chunking` must have the same dimension as the variable. #### attribute subtree {#decl_netcdf_attr} diff --git a/plugins/decl_netcdf/cmake/FindHDF5.cmake b/plugins/decl_netcdf/cmake/4.1/FindHDF5.cmake similarity index 73% rename from plugins/decl_netcdf/cmake/FindHDF5.cmake rename to plugins/decl_netcdf/cmake/4.1/FindHDF5.cmake index 6d34972d8..958b29496 100644 --- a/plugins/decl_netcdf/cmake/FindHDF5.cmake +++ b/plugins/decl_netcdf/cmake/4.1/FindHDF5.cmake @@ -1,166 +1,333 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. +# file LICENSE.rst or https://cmake.org/licensing for details. #[=======================================================================[.rst: FindHDF5 -------- -Find Hierarchical Data Format (HDF5), a library for reading and writing -self describing array data. - - -This module invokes the ``HDF5`` wrapper compiler that should be installed -alongside ``HDF5``. Depending upon the ``HDF5`` Configuration, the wrapper -compiler is called either ``h5cc`` or ``h5pcc``. If this succeeds, the module -will then call the compiler with the show argument to see what flags -are used when compiling an ``HDF5`` client application. - -The module will optionally accept the ``COMPONENTS`` argument. If no -``COMPONENTS`` are specified, then the find module will default to finding -only the ``HDF5`` C library. If one or more ``COMPONENTS`` are specified, the -module will attempt to find the language bindings for the specified -components. The valid components are ``C``, ``CXX``, ``Fortran``, ``HL``. -``HL`` refers to the "high-level" HDF5 functions for C and Fortran. -If the ``COMPONENTS`` argument is not given, the module will -attempt to find only the C bindings. -For example, to use Fortran HDF5 and HDF5-HL functions, do: -``find_package(HDF5 COMPONENTS Fortran HL)``. - -This module will read the variable -``HDF5_USE_STATIC_LIBRARIES`` to determine whether or not to prefer a -static link to a dynamic link for ``HDF5`` and all of it's dependencies. -To use this feature, make sure that the ``HDF5_USE_STATIC_LIBRARIES`` -variable is set before the call to find_package. - -.. versionadded:: 3.10 - Support for ``HDF5_USE_STATIC_LIBRARIES`` on Windows. - -Both the serial and parallel ``HDF5`` wrappers are considered and the first -directory to contain either one will be used. In the event that both appear -in the same directory the serial version is preferentially selected. This -behavior can be reversed by setting the variable ``HDF5_PREFER_PARALLEL`` to -``TRUE``. - -In addition to finding the includes and libraries required to compile -an ``HDF5`` client application, this module also makes an effort to find -tools that come with the ``HDF5`` distribution that may be useful for -regression testing. +Finds Hierarchical Data Format (HDF5), a library for reading and writing +self-describing array data: + +.. code-block:: cmake + + find_package(HDF5 [] ... [COMPONENTS ...] ...) + +If the HDF5 library is built using its CMake-based build system, it will as +of HDF5 version 1.8.15 provide its own CMake Package Configuration file +(``hdf5-config.cmake``) for use with the :command:`find_package` command in +*config mode*. By default, this module searches for this file and, if found, +returns the results based on the found configuration. + +If the upstream configuration file is not found, this module falls back to +*module mode* and invokes the HDF5 wrapper compiler typically installed +with the HDF5 library. Depending on the configuration, this wrapper +compiler is named either ``h5cc`` (serial) or ``h5pcc`` (parallel). If +found, the wrapper is queried with the ``-show`` argument to determine the +compiler and linker flags required for building an HDF5 client application. +Both serial and parallel versions of the HDF5 wrapper are considered. The +first directory containing either is used. If both versions are found in the +same directory, the serial version is preferred by default. To change this +behavior, set the variable ``HDF5_PREFER_PARALLEL`` to ``TRUE``. + +In addition to finding the include directories and libraries needed to compile +an HDF5 application, this module also attempts to find additional tools +provided by the HDF5 distribution, which can be useful for regression testing +or development workflows. + +Components +^^^^^^^^^^ + +This module supports optional components, which can be specified with the +:command:`find_package` command: + +.. code-block:: cmake + + find_package(HDF5 [COMPONENTS ...]) + +Supported components include: + +``C`` + Finds the ``HDF5`` C library (C bindings). + +``CXX`` + Finds the ``HDF5`` C++ library (C++ bindings). + +``Fortran`` + Finds the ``HDF5`` Fortran library (Fortran bindings). + +``HL`` + This component can be used in combination with other components to find the + high-level (HL) HDF5 library variants for C, CXX, and/or Fortran, which + provide high-level functions. + +If no components are specified, then this module will by default search for the +``C`` component. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module provides the following :ref:`Imported Targets`: + +``HDF5::HDF5`` + .. versionadded:: 3.19 + + Target encapsulating the usage requirements for all found HDF5 libraries + (``HDF5_LIBRARIES``), available if HDF5 and all required components are found. + +``hdf5::hdf5`` + .. versionadded:: 3.19 + + Target encapsulating the usage requirements for the HDF5 C library, available + if HDF5 library and its ``C`` component are found. + +``hdf5::hdf5_cpp`` + .. versionadded:: 3.19 + + Target encapsulating the usage requirements for the HDF5 C and C++ libraries, + available if HDF5 library, and its ``C`` and ``CXX`` components are found. + +``hdf5::hdf5_fortran`` + .. versionadded:: 3.19 + + Target encapsulating the usage requirements for the HDF5 Fortran library, + available if HDF5 library and its ``Fortran`` component are found. + +``hdf5::hdf5_hl`` + .. versionadded:: 3.19 + + Target encapsulating the usage requirements for the HDF5 high-level C library, + available if HDF5 library and its ``C``, and ``HL`` components are found. + +``hdf5::hdf5_hl_cpp`` + .. versionadded:: 3.19 + + High-level C++ library. + + Target encapsulating the usage requirements for the HDF5 high-level C and + high-level C++ libraries, available if HDF5 library and its ``C``, ``CXX``, + and ``HL`` components are found. + +``hdf5::hdf5_hl_fortran`` + .. versionadded:: 3.19 + + Target encapsulating the usage requirements for the HDF5 high-level Fortran + library, available if HDF5 library and its ``Fortran``, and ``HL`` components + are found. + +``hdf5::h5diff`` + .. versionadded:: 3.19 + + Imported executable target encapsulating the usage requirements for the + ``h5diff`` executable, available if ``h5diff`` is found. Result Variables ^^^^^^^^^^^^^^^^ -This module will set the following variables in your project: +This module defines the following variables: ``HDF5_FOUND`` - HDF5 was found on the system + Boolean indicating whether (the requested version of) HDF5 is found. + ``HDF5_VERSION`` .. versionadded:: 3.3 - HDF5 library version + + The version of HDF5 library found. + ``HDF5_INCLUDE_DIRS`` - Location of the HDF5 header files + Include directories containing header files needed to use HDF5. + ``HDF5_DEFINITIONS`` - Required compiler definitions for HDF5 + Required compiler definitions for using HDF5. + ``HDF5_LIBRARIES`` - Required libraries for all requested bindings + Libraries of all requested bindings needed to link against to use HDF5. + ``HDF5_HL_LIBRARIES`` - Required libraries for the HDF5 high level API for all bindings, - if the ``HL`` component is enabled + Required libraries for the HDF5 high-level API for all bindings, + if the ``HL`` component is enabled. -Available components are: ``C`` ``CXX`` ``Fortran`` and ``HL``. -For each enabled language binding, a corresponding ``HDF5_${LANG}_LIBRARIES`` -variable, and potentially ``HDF5_${LANG}_DEFINITIONS``, will be defined. -If the ``HL`` component is enabled, then an ``HDF5_${LANG}_HL_LIBRARIES`` will -also be defined. With all components enabled, the following variables will be defined: +``HDF5_IS_PARALLEL`` + Boolean indicating whether the HDF5 library has parallel IO support. + +For each enabled language binding component, a corresponding +``HDF5__LIBRARIES`` variable, and potentially +``HDF5__DEFINITIONS``, will be defined. If the ``HL`` component is +enabled, then ``HDF5__HL_LIBRARIES`` variables will also be defined: ``HDF5_C_DEFINITIONS`` - Required compiler definitions for HDF5 C bindings + Required compiler definitions for HDF5 C bindings. + ``HDF5_CXX_DEFINITIONS`` - Required compiler definitions for HDF5 C++ bindings + Required compiler definitions for HDF5 C++ bindings. + ``HDF5_Fortran_DEFINITIONS`` - Required compiler definitions for HDF5 Fortran bindings + Required compiler definitions for HDF5 Fortran bindings. + ``HDF5_C_INCLUDE_DIRS`` - Required include directories for HDF5 C bindings + Required include directories for HDF5 C bindings. + ``HDF5_CXX_INCLUDE_DIRS`` - Required include directories for HDF5 C++ bindings + Required include directories for HDF5 C++ bindings. + ``HDF5_Fortran_INCLUDE_DIRS`` - Required include directories for HDF5 Fortran bindings + Required include directories for HDF5 Fortran bindings. + ``HDF5_C_LIBRARIES`` - Required libraries for the HDF5 C bindings + Required libraries for the HDF5 C bindings. + ``HDF5_CXX_LIBRARIES`` - Required libraries for the HDF5 C++ bindings + Required libraries for the HDF5 C++ bindings. + ``HDF5_Fortran_LIBRARIES`` - Required libraries for the HDF5 Fortran bindings + Required libraries for the HDF5 Fortran bindings. + ``HDF5_C_HL_LIBRARIES`` - Required libraries for the high level C bindings + Required libraries for the high-level C bindings, if the ``HL`` component + is enabled. + ``HDF5_CXX_HL_LIBRARIES`` - Required libraries for the high level C++ bindings + Required libraries for the high-level C++ bindings, if the ``HL`` + component is enabled. + ``HDF5_Fortran_HL_LIBRARIES`` - Required libraries for the high level Fortran bindings. + Required libraries for the high-level Fortran bindings, if the ``HL`` + component is enabled. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: -``HDF5_IS_PARALLEL`` - HDF5 library has parallel IO support ``HDF5_C_COMPILER_EXECUTABLE`` - path to the HDF5 C wrapper compiler + The path to the HDF5 C wrapper compiler. + ``HDF5_CXX_COMPILER_EXECUTABLE`` - path to the HDF5 C++ wrapper compiler + The path to the HDF5 C++ wrapper compiler. + ``HDF5_Fortran_COMPILER_EXECUTABLE`` - path to the HDF5 Fortran wrapper compiler + The path to the HDF5 Fortran wrapper compiler. + ``HDF5_C_COMPILER_EXECUTABLE_NO_INTERROGATE`` - path to the primary C compiler which is also the HDF5 wrapper + .. versionadded:: 3.6 + + The path to the primary C compiler which is also the HDF5 wrapper. + This variable is used only in *module mode*. + ``HDF5_CXX_COMPILER_EXECUTABLE_NO_INTERROGATE`` - path to the primary C++ compiler which is also the HDF5 wrapper + .. versionadded:: 3.6 + + The path to the primary C++ compiler which is also the HDF5 wrapper. + This variable is used only in *module mode*. + ``HDF5_Fortran_COMPILER_EXECUTABLE_NO_INTERROGATE`` - path to the primary Fortran compiler which is also the HDF5 wrapper -``HDF5_DIFF_EXECUTABLE`` - path to the HDF5 dataset comparison tool + .. versionadded:: 3.6 -With all components enabled, the following targets will be defined: + The path to the primary Fortran compiler which is also the HDF5 wrapper. + This variable is used only in *module mode*. -``HDF5::HDF5`` - All detected ``HDF5_LIBRARIES``. -``hdf5::hdf5`` - C library. -``hdf5::hdf5_cpp`` - C++ library. -``hdf5::hdf5_fortran`` - Fortran library. -``hdf5::hdf5_hl`` - High-level C library. -``hdf5::hdf5_hl_cpp`` - High-level C++ library. -``hdf5::hdf5_hl_fortran`` - High-level Fortran library. -``hdf5::h5diff`` - ``h5diff`` executable. +``HDF5_DIFF_EXECUTABLE`` + The path to the HDF5 dataset comparison tool (``h5diff``). Hints ^^^^^ -The following variables can be set to guide the search for HDF5 libraries and includes: +The following variables can be set before calling the ``find_package(HDF5)`` +to guide the search for HDF5 library: ``HDF5_PREFER_PARALLEL`` .. versionadded:: 3.4 - set ``true`` to prefer parallel HDF5 (by default, serial is preferred) + Set this to boolean true to prefer parallel HDF5 (by default, serial is + preferred). This variable is used only in *module mode*. ``HDF5_FIND_DEBUG`` .. versionadded:: 3.9 - Set ``true`` to get extra debugging output. + Set this to boolean true to get extra debugging output by this module. ``HDF5_NO_FIND_PACKAGE_CONFIG_FILE`` .. versionadded:: 3.8 - Set ``true`` to skip trying to find ``hdf5-config.cmake``. + Set this to boolean true to skip finding and using CMake package configuration + file (``hdf5-config.cmake``). + +``HDF5_USE_STATIC_LIBRARIES`` + Set this to boolean value to determine whether or not to prefer a + static link to a dynamic link for ``HDF5`` and all of its dependencies. + + .. versionadded:: 3.10 + Support for ``HDF5_USE_STATIC_LIBRARIES`` on Windows. + +Examples +^^^^^^^^ + +Examples: Finding HDF5 +"""""""""""""""""""""" + +Finding HDF5: + +.. code-block:: cmake + + find_package(HDF5) + +Specifying a minimum required version of HDF5 to find: + +.. code-block:: cmake + + find_package(HDF5 1.8.15) + +Finding HDF5 and making it required (if HDF5 is not found, processing stops with +an error message): + +.. code-block:: cmake + + find_package(HDF5 1.8.15 REQUIRED) + +Searching for static HDF5 libraries: + +.. code-block:: cmake + + set(HDF5_USE_STATIC_LIBRARIES TRUE) + find_package(HDF5) + +Specifying components to find high-level C and C++ functions: + +.. code-block:: cmake + + find_package(HDF5 COMPONENTS C CXX HL) + +Examples: Using HDF5 +"""""""""""""""""""" + +Finding HDF5 and linking it to a project target: + +.. code-block:: cmake + + find_package(HDF5) + target_link_libraries(project_target PRIVATE HDF5::HDF5) + +Using Fortran HDF5 and HDF5-HL functions: + +.. code-block:: cmake + + find_package(HDF5 COMPONENTS Fortran HL) + target_link_libraries(project_target PRIVATE HDF5::HDF5) #]=======================================================================] include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +include(FindPackageHandleStandardArgs) + +cmake_policy(PUSH) +if(POLICY CMP0159) + cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_ +endif() # We haven't found HDF5 yet. Clear its state in case it is set in the parent # scope somewhere else. We can't rely on it because different components may # have been requested for this call. set(HDF5_FOUND OFF) +set(HDF5_LIBRARIES) +set(HDF5_HL_LIBRARIES) # List of the valid HDF5 components set(HDF5_VALID_LANGUAGE_BINDINGS C CXX Fortran) @@ -199,9 +366,7 @@ else() endforeach() endif() list(REMOVE_ITEM HDF5_FIND_COMPONENTS Fortran_HL) # replaced by Fortran and HL - if(HDF5_LANGUAGE_BINDINGS) - list(REMOVE_DUPLICATES HDF5_LANGUAGE_BINDINGS) - endif() + list(REMOVE_DUPLICATES HDF5_LANGUAGE_BINDINGS) endif() # Determine whether to search for serial or parallel executable first @@ -215,14 +380,18 @@ else() set(HDF5_Fortran_COMPILER_NAMES h5fc h5pfc) endif() +# Prefer h5hl compilers if HDF5_FIND_HL is enabled +if(HDF5_FIND_HL) + list(PREPEND HDF5_C_COMPILER_NAMES h5hlcc) + list(PREPEND HDF5_CXX_COMPILER_NAMES h5hlc++) + list(PREPEND HDF5_Fortran_COMPILER_NAMES h5hlfc) +endif() + # Test first if the current compilers automatically wrap HDF5 function(_HDF5_test_regular_compiler_C success version is_parallel) - set(scratch_directory - ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) if(NOT ${success} OR - NOT EXISTS ${scratch_directory}/compiler_has_h5_c) - set(test_file ${scratch_directory}/cmake_hdf5_test.c) - file(WRITE ${test_file} + NOT EXISTS ${_HDF5_TEST_DIR}/compiler_has_h5_c) + file(WRITE "${_HDF5_TEST_DIR}/${_HDF5_TEST_SRC}" "#include \n" "const char* info_ver = \"INFO\" \":\" H5_VERSION;\n" "#ifdef H5_HAVE_PARALLEL\n" @@ -238,12 +407,12 @@ function(_HDF5_test_regular_compiler_C success version is_parallel) " fid = H5Fcreate(\"foo.h5\",H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT);\n" " return 0;\n" "}") - try_compile(${success} ${scratch_directory} ${test_file} - COPY_FILE ${scratch_directory}/compiler_has_h5_c + try_compile(${success} "${_HDF5_TEST_DIR}" "${_HDF5_TEST_DIR}/${_HDF5_TEST_SRC}" + COPY_FILE ${_HDF5_TEST_DIR}/compiler_has_h5_c ) endif() - if(${success}) - file(STRINGS ${scratch_directory}/compiler_has_h5_c INFO_STRINGS + if(${success} AND EXISTS ${_HDF5_TEST_DIR}/compiler_has_h5_c) + file(STRINGS ${_HDF5_TEST_DIR}/compiler_has_h5_c INFO_STRINGS REGEX "^INFO:" ) string(REGEX MATCH "^INFO:([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?" @@ -264,11 +433,9 @@ function(_HDF5_test_regular_compiler_C success version is_parallel) endfunction() function(_HDF5_test_regular_compiler_CXX success version is_parallel) - set(scratch_directory ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) if(NOT ${success} OR - NOT EXISTS ${scratch_directory}/compiler_has_h5_cxx) - set(test_file ${scratch_directory}/cmake_hdf5_test.cxx) - file(WRITE ${test_file} + NOT EXISTS ${_HDF5_TEST_DIR}/compiler_has_h5_cxx) + file(WRITE "${_HDF5_TEST_DIR}/${_HDF5_TEST_SRC}" "#include \n" "#ifndef H5_NO_NAMESPACE\n" "using namespace H5;\n" @@ -286,12 +453,12 @@ function(_HDF5_test_regular_compiler_CXX success version is_parallel) " H5File file(\"foo.h5\", H5F_ACC_TRUNC);\n" " return 0;\n" "}") - try_compile(${success} ${scratch_directory} ${test_file} - COPY_FILE ${scratch_directory}/compiler_has_h5_cxx + try_compile(${success} "${_HDF5_TEST_DIR}" "${_HDF5_TEST_DIR}/${_HDF5_TEST_SRC}" + COPY_FILE ${_HDF5_TEST_DIR}/compiler_has_h5_cxx ) endif() - if(${success}) - file(STRINGS ${scratch_directory}/compiler_has_h5_cxx INFO_STRINGS + if(${success} AND EXISTS ${_HDF5_TEST_DIR}/compiler_has_h5_cxx) + file(STRINGS ${_HDF5_TEST_DIR}/compiler_has_h5_cxx INFO_STRINGS REGEX "^INFO:" ) string(REGEX MATCH "^INFO:([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?" @@ -313,27 +480,29 @@ endfunction() function(_HDF5_test_regular_compiler_Fortran success is_parallel) if(NOT ${success}) - set(scratch_directory - ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) - set(test_file ${scratch_directory}/cmake_hdf5_test.f90) - file(WRITE ${test_file} + file(WRITE "${_HDF5_TEST_DIR}/${_HDF5_TEST_SRC}" "program hdf5_hello\n" " use hdf5\n" - " use h5lt\n" - " use h5ds\n" " integer error\n" " call h5open_f(error)\n" " call h5close_f(error)\n" "end\n") - try_compile(${success} ${scratch_directory} ${test_file}) + try_compile(${success} "${_HDF5_TEST_DIR}" "${_HDF5_TEST_DIR}/${_HDF5_TEST_SRC}") if(${success}) execute_process(COMMAND ${CMAKE_Fortran_COMPILER} -showconfig OUTPUT_VARIABLE config_output ERROR_VARIABLE config_error RESULT_VARIABLE config_result ) - if(config_output MATCHES "Parallel HDF5: yes") - set(${is_parallel} TRUE PARENT_SCOPE) + if(config_output MATCHES "Parallel HDF5: ([A-Za-z0-9]+)") + # The value may be anything used when HDF5 was configured, + # so see if CMake interprets it as "true". + set(parallelHDF5 "${CMAKE_MATCH_1}") + if(parallelHDF5) + set(${is_parallel} TRUE PARENT_SCOPE) + else() + set(${is_parallel} FALSE PARENT_SCOPE) + endif() else() set(${is_parallel} FALSE PARENT_SCOPE) endif() @@ -350,38 +519,38 @@ function( _HDF5_invoke_compiler language output_var return_value_var version_var else() set(lib_type_args -shlib) endif() - set(scratch_dir ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) - if("${language}" STREQUAL "C") - set(test_file ${scratch_dir}/cmake_hdf5_test.c) - elseif("${language}" STREQUAL "CXX") - set(test_file ${scratch_dir}/cmake_hdf5_test.cxx) - elseif("${language}" STREQUAL "Fortran") - set(test_file ${scratch_dir}/cmake_hdf5_test.f90) - endif() # Verify that the compiler wrapper can actually compile: sometimes the compiler # wrapper exists, but not the compiler. E.g. Miniconda / Anaconda Python execute_process( - COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} ${test_file} - WORKING_DIRECTORY ${scratch_dir} + COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} "${_HDF5_TEST_SRC}" + WORKING_DIRECTORY ${_HDF5_TEST_DIR} OUTPUT_VARIABLE output ERROR_VARIABLE output RESULT_VARIABLE return_value ) - if(return_value AND NOT HDF5_FIND_QUIETLY) - message(STATUS - "HDF5 ${language} compiler wrapper is unable to compile a minimal HDF5 program.") + if(NOT return_value EQUAL 0) + message(CONFIGURE_LOG + "HDF5 ${language} compiler wrapper is unable to compile a minimal HDF5 program.\n\n${output}") + if(NOT HDF5_FIND_QUIETLY) + message(STATUS + "HDF5 ${language} compiler wrapper is unable to compile a minimal HDF5 program.") + endif() else() execute_process( - COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -show ${lib_type_args} ${test_file} - WORKING_DIRECTORY ${scratch_dir} + COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -show ${lib_type_args} "${_HDF5_TEST_SRC}" + WORKING_DIRECTORY ${_HDF5_TEST_DIR} OUTPUT_VARIABLE output ERROR_VARIABLE output RESULT_VARIABLE return_value OUTPUT_STRIP_TRAILING_WHITESPACE ) - if(return_value AND NOT HDF5_FIND_QUIETLY) - message(STATUS - "Unable to determine HDF5 ${language} flags from HDF5 wrapper.") + if(NOT return_value EQUAL 0) + message(CONFIGURE_LOG + "Unable to determine HDF5 ${language} flags from HDF5 wrapper.\n\n${output}") + if(NOT HDF5_FIND_QUIETLY) + message(STATUS + "Unable to determine HDF5 ${language} flags from HDF5 wrapper.") + endif() endif() execute_process( COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -showconfig @@ -390,17 +559,26 @@ function( _HDF5_invoke_compiler language output_var return_value_var version_var RESULT_VARIABLE return_value OUTPUT_STRIP_TRAILING_WHITESPACE ) - if(return_value AND NOT HDF5_FIND_QUIETLY) - message(STATUS - "Unable to determine HDF5 ${language} version_var from HDF5 wrapper.") + if(NOT return_value EQUAL 0) + message(CONFIGURE_LOG + "Unable to determine HDF5 ${language} version_var from HDF5 wrapper.\n\n${output}") + if(NOT HDF5_FIND_QUIETLY) + message(STATUS + "Unable to determine HDF5 ${language} version_var from HDF5 wrapper.") + endif() endif() string(REGEX MATCH "HDF5 Version: ([a-zA-Z0-9\\.\\-]*)" version "${config_output}") if(version) string(REPLACE "HDF5 Version: " "" version "${version}") string(REPLACE "-patch" "." version "${version}") endif() - if(config_output MATCHES "Parallel HDF5: yes") - set(is_parallel TRUE) + if(config_output MATCHES "Parallel HDF5: ([A-Za-z0-9]+)") + # The value may be anything used when HDF5 was configured, + # so see if CMake interprets it as "true". + set(parallelHDF5 "${CMAKE_MATCH_1}") + if(parallelHDF5) + set(is_parallel TRUE) + endif() endif() endif() foreach(var output return_value version is_parallel) @@ -412,12 +590,7 @@ endfunction() function(_HDF5_parse_compile_line compile_line_var include_paths definitions library_paths libraries libraries_hl) - if(${WIN32}) - set(CM35_NATIVE_COMMAND WINDOWS_COMMAND) - else(${WIN32}) - set(CM35_NATIVE_COMMAND UNIX_COMMAND) - endif(${WIN32}) - separate_arguments(_compile_args ${CM35_NATIVE_COMMAND} "${${compile_line_var}}") + separate_arguments(_compile_args NATIVE_COMMAND "${${compile_line_var}}") foreach(_arg IN LISTS _compile_args) if("${_arg}" MATCHES "^-I(.*)$") @@ -477,15 +650,12 @@ function(_HDF5_select_imported_config target imported_conf) message(STATUS "Start search through imported configurations in the following order: ${_preferred_confs}") endif() # Now find the first of these that is present in imported_conf - cmake_policy(PUSH) - cmake_policy(SET CMP0057 NEW) # support IN_LISTS foreach (_conf IN LISTS _preferred_confs) if (${_conf} IN_LIST _imported_conf) set(_imported_conf ${_conf}) break() endif() endforeach() - cmake_policy(POP) endif() if(HDF5_FIND_DEBUG) message(STATUS "Selected imported configuration: ${_imported_conf}") @@ -514,7 +684,6 @@ if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE) if(HDF5_FIND_DEBUG) message(STATUS "Found HDF5 at ${HDF5_DIR} via NO_MODULE. Now trying to extract locations etc.") endif() - unset(HDF5_IS_PARALLEL CACHE) set(HDF5_IS_PARALLEL ${HDF5_ENABLE_PARALLEL}) set(HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR}) set(HDF5_LIBRARIES) @@ -568,7 +737,7 @@ if(NOT HDF5_FOUND AND NOT HDF5_NO_FIND_PACKAGE_CONFIG_FILE) set(HDF5_${_lang}_FOUND TRUE) endif() if(HDF5_FIND_HL) - get_target_property(_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} ) + get_target_property(_hdf5_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} IMPORTED_IMPLIB_${_hdf5_imported_conf} ) if (NOT _hdf5_lang_hl_location) get_target_property(_hdf5_lang_hl_location ${HDF5_${_lang}_HL_TARGET}${_suffix} LOCATION_${_hdf5_imported_conf}) if (NOT _hdf5_hl_lang_location) @@ -591,23 +760,32 @@ endif() if(NOT HDF5_FOUND) set(_HDF5_NEED_TO_SEARCH FALSE) + set(_HDF5_TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hdf5) set(HDF5_COMPILER_NO_INTERROGATE TRUE) - unset(HDF5_IS_PARALLEL) - unset(HDF5_IS_PARALLEL CACHE) # Only search for languages we've enabled foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS) + set(HDF5_${_lang}_LIBRARIES) + set(HDF5_${_lang}_HL_LIBRARIES) + # First check to see if our regular compiler is one of wrappers if(_lang STREQUAL "C") + set(_HDF5_TEST_SRC cmake_hdf5_test.c) + if(CMAKE_CXX_COMPILER_LOADED AND NOT CMAKE_C_COMPILER_LOADED) + # CXX project without C enabled + set(_HDF5_TEST_SRC cmake_hdf5_test.cxx) + endif() _HDF5_test_regular_compiler_C( HDF5_${_lang}_COMPILER_NO_INTERROGATE HDF5_${_lang}_VERSION HDF5_${_lang}_IS_PARALLEL) elseif(_lang STREQUAL "CXX") + set(_HDF5_TEST_SRC cmake_hdf5_test.cxx) _HDF5_test_regular_compiler_CXX( HDF5_${_lang}_COMPILER_NO_INTERROGATE HDF5_${_lang}_VERSION HDF5_${_lang}_IS_PARALLEL) elseif(_lang STREQUAL "Fortran") + set(_HDF5_TEST_SRC cmake_hdf5_test.f90) _HDF5_test_regular_compiler_Fortran( HDF5_${_lang}_COMPILER_NO_INTERROGATE HDF5_${_lang}_IS_PARALLEL) @@ -727,12 +905,8 @@ if(NOT HDF5_FOUND) endif() set(HDF5_${_lang}_FOUND TRUE) - if (HDF5_${_lang}_DEFINITIONS) - list(REMOVE_DUPLICATES HDF5_${_lang}_DEFINITIONS) - endif() - if(HDF5_${_lang}_INCLUDE_DIRS) - list(REMOVE_DUPLICATES HDF5_${_lang}_INCLUDE_DIRS) - endif() + list(REMOVE_DUPLICATES HDF5_${_lang}_DEFINITIONS) + list(REMOVE_DUPLICATES HDF5_${_lang}_INCLUDE_DIRS) else() set(_HDF5_NEED_TO_SEARCH TRUE) endif() @@ -757,6 +931,8 @@ if(NOT HDF5_FOUND) endif() endif() endforeach() + unset(_HDF5_TEST_DIR) + unset(_HDF5_TEST_SRC) unset(_lib) else() set(_HDF5_NEED_TO_SEARCH TRUE) @@ -785,12 +961,8 @@ elseif(NOT HDF5_FOUND AND NOT _HDF5_NEED_TO_SEARCH) endif() endif() endforeach() - if(HDF5_DEFINITIONS) - list(REMOVE_DUPLICATES HDF5_DEFINITIONS) - endif() - if(HDF5_INCLUDE_DIRS) - list(REMOVE_DUPLICATES HDF5_INCLUDE_DIRS) - endif() + list(REMOVE_DUPLICATES HDF5_DEFINITIONS) + list(REMOVE_DUPLICATES HDF5_INCLUDE_DIRS) set(HDF5_FOUND TRUE) set(HDF5_REQUIRED_VARS HDF5_LIBRARIES) if(HDF5_FIND_HL) @@ -829,6 +1001,9 @@ if( NOT HDF5_FOUND ) endif() foreach(_lang IN LISTS HDF5_LANGUAGE_BINDINGS) + set(HDF5_${_lang}_LIBRARIES) + set(HDF5_${_lang}_HL_LIBRARIES) + # The "main" library. set(_hdf5_main_library "") @@ -891,7 +1066,7 @@ if( NOT HDF5_FOUND ) # Add library-based search paths for Fortran modules. if (NOT _hdf5_main_library STREQUAL "") # gfortran module directory - if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "LCC") get_filename_component(_hdf5_library_dir "${_hdf5_main_library}" DIRECTORY) list(APPEND _hdf5_inc_extra_paths "${_hdf5_library_dir}") unset(_hdf5_library_dir) @@ -959,18 +1134,12 @@ if( NOT HDF5_FOUND ) set(HDF5_HL_FOUND TRUE) endif() - if(HDF5_DEFINITIONS) - list(REMOVE_DUPLICATES HDF5_DEFINITIONS) - endif() - if(HDF5_INCLUDE_DIRS) - list(REMOVE_DUPLICATES HDF5_INCLUDE_DIRS) - endif() + list(REMOVE_DUPLICATES HDF5_DEFINITIONS) + list(REMOVE_DUPLICATES HDF5_INCLUDE_DIRS) # If the HDF5 include directory was found, open H5pubconf.h to determine if # HDF5 was compiled with parallel IO support - unset(HDF5_IS_PARALLEL CACHE) set( HDF5_IS_PARALLEL FALSE ) - set( HDF5_VERSION "" ) foreach( _dir IN LISTS HDF5_INCLUDE_DIRS ) foreach(_hdr "${_dir}/H5pubconf.h" "${_dir}/H5pubconf-64.h" "${_dir}/H5pubconf-32.h") if( EXISTS "${_hdr}" ) @@ -986,7 +1155,7 @@ if( NOT HDF5_FOUND ) HDF5_VERSION_DEFINE REGEX "^[ \t]*#[ \t]*define[ \t]+H5_VERSION[ \t]+" ) if( "${HDF5_VERSION_DEFINE}" MATCHES - "H5_VERSION[ \t]+\"([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?\"" ) + "H5_VERSION[ \t]+\"([0-9\\.]+)(-patch([0-9]+))?\"" ) set( HDF5_VERSION "${CMAKE_MATCH_1}" ) if( CMAKE_MATCH_3 ) set( HDF5_VERSION ${HDF5_VERSION}.${CMAKE_MATCH_3}) @@ -1036,15 +1205,15 @@ if( HDF5_FOUND AND NOT HDF5_DIR) endif() if (HDF5_FOUND) - #if (NOT TARGET HDF5::HDF5) - #add_library(HDF5::HDF5 INTERFACE IMPORTED) - #string(REPLACE "-D" "" _hdf5_definitions "${HDF5_DEFINITIONS}") - #set_target_properties(HDF5::HDF5 PROPERTIES - #INTERFACE_INCLUDE_DIRECTORIES "${HDF5_INCLUDE_DIRS}" - #INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}") - #unset(_hdf5_definitions) - #target_link_libraries(HDF5::HDF5 INTERFACE ${HDF5_LIBRARIES}) - #endif () + if (NOT TARGET HDF5::HDF5) + add_library(HDF5::HDF5 INTERFACE IMPORTED) + string(REPLACE "-D" "" _hdf5_definitions "${HDF5_DEFINITIONS}") + set_target_properties(HDF5::HDF5 PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${HDF5_INCLUDE_DIRS}" + INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}") + unset(_hdf5_definitions) + target_link_libraries(HDF5::HDF5 INTERFACE ${HDF5_LIBRARIES}) + endif () foreach (hdf5_lang IN LISTS HDF5_LANGUAGE_BINDINGS) if (hdf5_lang STREQUAL "C") @@ -1067,8 +1236,12 @@ if (HDF5_FOUND) else() if (DEFINED "HDF5_${hdf5_target_name}_LIBRARY") set(_hdf5_location "${HDF5_${hdf5_target_name}_LIBRARY}") + set(_hdf5_location_release "${HDF5_${hdf5_target_name}_LIBRARY_RELEASE}") + set(_hdf5_location_debug "${HDF5_${hdf5_target_name}_LIBRARY_DEBUG}") elseif (DEFINED "HDF5_${hdf5_lang}_LIBRARY") set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY}") + set(_hdf5_location_release "${HDF5_${hdf5_lang}_LIBRARY_RELEASE}") + set(_hdf5_location_debug "${HDF5_${hdf5_lang}_LIBRARY_DEBUG}") elseif (DEFINED "HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}") set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}}") else () @@ -1083,10 +1256,24 @@ if (HDF5_FOUND) set(HDF5_${hdf5_lang}_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS}) endif () set_target_properties("hdf5::${hdf5_target_name}" PROPERTIES - IMPORTED_LOCATION "${_hdf5_location}" - IMPORTED_IMPLIB "${_hdf5_location}" INTERFACE_INCLUDE_DIRECTORIES "${HDF5_${hdf5_lang}_INCLUDE_DIRS}" INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}") + if (_hdf5_location_release) + set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY + IMPORTED_LOCATION_RELEASE "${_hdf5_location_release}") + endif() + if (_hdf5_location_debug) + set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY + IMPORTED_LOCATION_DEBUG "${_hdf5_location_debug}") + endif() + if (NOT _hdf5_location_release AND NOT _hdf5_location_debug) + set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY + IMPORTED_LOCATION "${_hdf5_location}") + endif() if (_hdf5_libtype STREQUAL "SHARED") set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY @@ -1099,6 +1286,8 @@ if (HDF5_FOUND) unset(_hdf5_definitions) unset(_hdf5_libtype) unset(_hdf5_location) + unset(_hdf5_location_release) + unset(_hdf5_location_debug) endif () endif () @@ -1128,8 +1317,12 @@ if (HDF5_FOUND) else() if (DEFINED "HDF5_${hdf5_target_name}_LIBRARY") set(_hdf5_location "${HDF5_${hdf5_target_name}_LIBRARY}") + set(_hdf5_location_release "${HDF5_${hdf5_target_name}_LIBRARY_RELEASE}") + set(_hdf5_location_debug "${HDF5_${hdf5_target_name}_LIBRARY_DEBUG}") elseif (DEFINED "HDF5_${hdf5_lang}_HL_LIBRARY") set(_hdf5_location "${HDF5_${hdf5_lang}_HL_LIBRARY}") + set(_hdf5_location_release "${HDF5_${hdf5_lang}_HL_LIBRARY_RELEASE}") + set(_hdf5_location_debug "${HDF5_${hdf5_lang}_HL_LIBRARY_DEBUG}") elseif (DEFINED "HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}") set(_hdf5_location "${HDF5_${hdf5_lang}_LIBRARY_${hdf5_target_name}}") elseif (hdf5_alt_target_name AND DEFINED "HDF5_${hdf5_lang}_LIBRARY_${hdf5_alt_target_name}") @@ -1143,10 +1336,24 @@ if (HDF5_FOUND) add_library("hdf5::${hdf5_target_name}" UNKNOWN IMPORTED) string(REPLACE "-D" "" _hdf5_definitions "${HDF5_${hdf5_lang}_HL_DEFINITIONS}") set_target_properties("hdf5::${hdf5_target_name}" PROPERTIES - IMPORTED_LOCATION "${_hdf5_location}" - IMPORTED_IMPLIB "${_hdf5_location}" INTERFACE_INCLUDE_DIRECTORIES "${HDF5_${hdf5_lang}_HL_INCLUDE_DIRS}" INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}") + if (_hdf5_location_release) + set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY + IMPORTED_LOCATION_RELEASE "${_hdf5_location_release}") + endif() + if (_hdf5_location_debug) + set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY + IMPORTED_LOCATION_DEBUG "${_hdf5_location_debug}") + endif() + if (NOT _hdf5_location_release AND NOT _hdf5_location_debug) + set_property(TARGET "hdf5::${hdf5_target_name}" PROPERTY + IMPORTED_LOCATION "${_hdf5_location}") + endif() if (_hdf5_libtype STREQUAL "SHARED") set_property(TARGET "hdf5::${hdf5_target_name}" APPEND PROPERTY @@ -1204,3 +1411,5 @@ if (HDF5_FIND_DEBUG) endif() unset(_lang) unset(_HDF5_NEED_TO_SEARCH) + +cmake_policy(POP) diff --git a/plugins/decl_netcdf/cmake/4.1/SelectLibraryConfigurations.cmake b/plugins/decl_netcdf/cmake/4.1/SelectLibraryConfigurations.cmake new file mode 100644 index 000000000..e26c9080a --- /dev/null +++ b/plugins/decl_netcdf/cmake/4.1/SelectLibraryConfigurations.cmake @@ -0,0 +1,185 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file LICENSE.rst or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +SelectLibraryConfigurations +--------------------------- + +This module is intended for use in :ref:`Find Modules` and provides a +command to automatically set library variables when package is available +with multiple :ref:`Build Configurations`. + +Load it in a CMake find module with: + +.. code-block:: cmake + + include(SelectLibraryConfigurations) + +Supported build configurations are ``Release`` and ``Debug`` as these are +the most common ones in such packages. + +.. note:: + + This module has been available since early versions of CMake, when the + ``_LIBRARIES`` result variable was used for linking found + packages. When writing standard find modules, :ref:`Imported Targets` should + be preferred. In addition to or as an alternative to this module, imported + targets provide finer control over linking through the + :prop_tgt:`IMPORTED_CONFIGURATIONS` property. + +Commands +^^^^^^^^ + +This module provides the following command: + +.. command:: select_library_configurations + + Sets and adjusts library variables based on debug and release build + configurations: + + .. code-block:: cmake + + select_library_configurations() + + This command is a helper for setting the ``_LIBRARY`` and + ``_LIBRARIES`` result variables when a library might be provided + with multiple build configurations. + + The argument is: + + ```` + The base name of the library, used as a prefix for variable names. This is + the name of the package as used in the ``Find.cmake`` module + filename, or the component name, when find module provides them. + + Prior to calling this command the following cache variables should be set + in the find module (for example, by the :command:`find_library` command): + + ``_LIBRARY_RELEASE`` + A cache variable storing the full path to the ``Release`` build of the + library. If not set or found, this command will set its value to + ``_LIBRARY_RELEASE-NOTFOUND``. + + ``_LIBRARY_DEBUG`` + A cache variable storing the full path to the ``Debug`` build of the + library. If not set or found, this command will set its value to + ``_LIBRARY_DEBUG-NOTFOUND``. + + This command then sets the following local result variables: + + ``_LIBRARY`` + A result variable that is set to the value of + ``_LIBRARY_RELEASE`` variable if found, otherwise it is set to the + value of ``_LIBRARY_DEBUG`` variable if found. If both are found, + the release library value takes precedence. If both are not found, it is set + to value ``_LIBRARY-NOTFOUND``. + + If the :manual:`CMake Generator ` in use supports + build configurations, then this variable will be a list of found libraries + each prepended with the ``optimized`` or ``debug`` keywords specifying which + library should be linked for the given configuration. These keywords are + used by the :command:`target_link_libraries` command. If a build + configuration has not been set or the generator in use does not support + build configurations, then this variable value will not contain these + keywords. + + ``_LIBRARIES`` + A result variable that is set to the same value as the + ``_LIBRARY`` variable. + + .. note:: + + The ``select_library_configurations()`` command should be called before + handling standard find module arguments with + :command:`find_package_handle_standard_args` to ensure that the + ``_FOUND`` result variable is correctly set based on + ``_LIBRARY`` or other related variables. + +Examples +^^^^^^^^ + +Setting library variables based on the build configuration inside a find module +file: + +.. code-block:: cmake + :caption: ``FindFoo.cmake`` + + # Find release and debug build of the library + find_library(Foo_LIBRARY_RELEASE ...) + find_library(Foo_LIBRARY_DEBUG ...) + + # Set Foo_LIBRARY and Foo_LIBRARIES result variables + include(SelectLibraryConfigurations) + select_library_configurations(Foo) + + # Set Foo_FOUND variable and print result message. + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args( + Foo + REQUIRED_VARS Foo_LIBRARY ... + ) + +When find module provides components with multiple build configurations: + +.. code-block:: cmake + :caption: ``FindFoo.cmake`` + + include(SelectLibraryConfigurations) + foreach(component IN LISTS Foo_FIND_COMPONENTS) + # ... + select_library_configurations(Foo_${component}) + # ... + endforeach() + +A project can then use this find module as follows: + +.. code-block:: cmake + :caption: ``CMakeLists.txt`` + + find_package(Foo) + target_link_libraries(project_target PRIVATE ${Foo_LIBRARIES}) + # ... +#]=======================================================================] + +# This macro was adapted from the FindQt4 CMake module and is maintained by Will +# Dicharry . + +macro(select_library_configurations basename) + if(NOT ${basename}_LIBRARY_RELEASE) + set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.") + endif() + if(NOT ${basename}_LIBRARY_DEBUG) + set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.") + endif() + + get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND + NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND + ( _isMultiConfig OR CMAKE_BUILD_TYPE ) ) + # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for + # single-config generators, set optimized and debug libraries + set( ${basename}_LIBRARY "" ) + foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE ) + list( APPEND ${basename}_LIBRARY optimized "${_libname}" ) + endforeach() + foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG ) + list( APPEND ${basename}_LIBRARY debug "${_libname}" ) + endforeach() + elseif( ${basename}_LIBRARY_RELEASE ) + set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) + elseif( ${basename}_LIBRARY_DEBUG ) + set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} ) + else() + set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND") + endif() + + set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" ) + + if( ${basename}_LIBRARY ) + set( ${basename}_FOUND TRUE ) + endif() + + mark_as_advanced( ${basename}_LIBRARY_RELEASE + ${basename}_LIBRARY_DEBUG + ) +endmacro() diff --git a/plugins/decl_netcdf/cmake/FindNetCDF.cmake b/plugins/decl_netcdf/cmake/FindNetCDF.cmake index fa8e907ab..0cdd109d5 100644 --- a/plugins/decl_netcdf/cmake/FindNetCDF.cmake +++ b/plugins/decl_netcdf/cmake/FindNetCDF.cmake @@ -1,5 +1,5 @@ ################################################################################ -# Copyright (C) 2020-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -40,9 +40,6 @@ This module will define the following variables: :NetCDF_FOUND: Whether NetCDF was found or not. :NetCDF_VERSION: The version of NetCDF found. -:NetCDF_INCLUDE_DIRECTORIES: . -:NetCDF_COMPILE_DEFINITIONS: . -:NetCDF_LINK_LIBRARIES: . :NetCDF_FEATURES: the features supported amongst CDF5, DAP, DAP2, DAP4, DISKLESS, HDF4, HDF5, JNA, MMAP, NC2, NC4, PARALLEL, PARALLEL4, PNETCDF @@ -54,7 +51,7 @@ In addition, the module provides the following target to link against: The following variable can be set to guide the search for NetCDF libraries and includes: -:NetCDF_CFGSCRIPT: The config script to use. +:NetCDF_CFGSCRIPT: The config script (nc-config) to use. :NetCDF_FIND_DEBUG: Set to true to get extra debugging output. @@ -63,7 +60,7 @@ includes: #]==] -cmake_minimum_required(VERSION 3.16...3.25) +cmake_minimum_required(VERSION 3.22...4.2) set(_NetCDF_features_list CDF5 DAP DAP2 DAP4 DISKLESS HDF4 HDF5 JNA MMAP NC2 NC4 PARALLEL PARALLEL4 PNETCDF) @@ -205,7 +202,7 @@ function(_NetCDF_find_CMAKE) set(NetCDF_FOUND TRUE) set(NetCDF_VERSION "${netCDF_VERSION}") if(TARGET "${netCDF_LIBRARIES}") - if(NetCDF_FIND_DEBUG) + if("${NetCDF_FIND_DEBUG}" AND NOT "${NetCDF_FIND_QUIETLY}") message(STATUS "Found NetCDF CMAKE target ${netCDF_LIBRARIES}") endif() set(NetCDF_LINK_LIBRARIES ${netCDF_LIBRARIES}) @@ -275,7 +272,7 @@ function(_NetCDF_find_CFGSCRIPT CFGSCRIPT) set(NetCDF_FOUND "FALSE" PARENT_SCOPE) return() endif() - if(NetCDF_FIND_DEBUG) + if("${NetCDF_FIND_DEBUG}" AND NOT "${NetCDF_FIND_QUIETLY}") message(STATUS "${CFGSCRIPT} ${${INFO}_OPT} returns ${${INFO}}") endif() endforeach() @@ -290,7 +287,9 @@ function(_NetCDF_find_CFGSCRIPT CFGSCRIPT) OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT "${CFGSCRIPT_RETURN}" EQUAL "0") - message(WARNING "Error running ${CFGSCRIPT} ${FEATURE_OPT}") + if(NOT "${NetCDF_FIND_QUIETLY}") + message(VERBOSE "Error running ${CFGSCRIPT} ${FEATURE_OPT}") + endif() continue() endif() if("x${FEATURE_${FEATURE}}" MATCHES "yes") @@ -366,9 +365,9 @@ if("${NetCDF_FOUND}") if("PARALLEL4" IN_LIST NetCDF_FEATURES) set(HDF5_PREFER_PARALLEL ON) endif() - find_package(HDF5 REQUIRED COMPONENTS C) - if("${HDF5_VERSION}" VERSION_LESS "1.8.0") - message(ERROR "HDF5 version 1.8.0 at least required by NetCDF, HDF5 ${HDF5_VERSION} found.") + find_package(HDF5 REQUIRED COMPONENTS C HL) + if("${HDF5_VERSION}" VERSION_LESS 1.10) + message(FATAL_ERROR "HDF5 version 1.10 at least required, HDF5 ${HDF5_VERSION} found.") endif() if("PARALLEL4" IN_LIST NetCDF_FEATURES AND NOT "${HDF5_IS_PARALLEL}") message(ERROR "Parallel HDF5 required by NetCDF, sequential HDF5 only found.") diff --git a/plugins/decl_netcdf/cmake/FindPackageHandleStandardArgs.cmake b/plugins/decl_netcdf/cmake/FindPackageHandleStandardArgs.cmake deleted file mode 100644 index 67f6bd6f2..000000000 --- a/plugins/decl_netcdf/cmake/FindPackageHandleStandardArgs.cmake +++ /dev/null @@ -1,386 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPackageHandleStandardArgs ------------------------------ - -This module provides a function intended to be used in :ref:`Find Modules` -implementing :command:`find_package()` calls. It handles the -``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. -It also sets the ``_FOUND`` variable. The package is -considered found if all variables listed contain valid results, e.g. -valid filepaths. - -.. command:: find_package_handle_standard_args - - There are two signatures:: - - find_package_handle_standard_args( - (DEFAULT_MSG|) - ... - ) - - find_package_handle_standard_args( - [FOUND_VAR ] - [REQUIRED_VARS ...] - [VERSION_VAR ] - [HANDLE_COMPONENTS] - [CONFIG_MODE] - [FAIL_MESSAGE ] - ) - - The ``_FOUND`` variable will be set to ``TRUE`` if all - the variables ``...`` are valid and any optional - constraints are satisfied, and ``FALSE`` otherwise. A success or - failure message may be displayed based on the results and on - whether the ``REQUIRED`` and/or ``QUIET`` option was given to - the :command:`find_package` call. - - The options are: - - ``(DEFAULT_MSG|)`` - In the simple signature this specifies the failure message. - Use ``DEFAULT_MSG`` to ask for a default message to be computed - (recommended). Not valid in the full signature. - - ``FOUND_VAR `` - Obsolete. Specifies either ``_FOUND`` or - ``_FOUND`` as the result variable. This exists only - for compatibility with older versions of CMake and is now ignored. - Result variables of both names are always set for compatibility. - - ``REQUIRED_VARS ...`` - Specify the variables which are required for this package. - These may be named in the generated failure message asking the - user to set the missing variable values. Therefore these should - typically be cache entries such as ``FOO_LIBRARY`` and not output - variables like ``FOO_LIBRARIES``. - - ``VERSION_VAR `` - Specify the name of a variable that holds the version of the package - that has been found. This version will be checked against the - (potentially) specified required version given to the - :command:`find_package` call, including its ``EXACT`` option. - The default messages include information about the required - version and the version which has been actually found, both - if the version is ok or not. - - ``HANDLE_COMPONENTS`` - Enable handling of package components. In this case, the command - will report which components have been found and which are missing, - and the ``_FOUND`` variable will be set to ``FALSE`` - if any of the required components (i.e. not the ones listed after - the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are - missing. - - ``CONFIG_MODE`` - Specify that the calling find module is a wrapper around a - call to ``find_package( NO_MODULE)``. This implies - a ``VERSION_VAR`` value of ``_VERSION``. The command - will automatically check whether the package configuration file - was found. - - ``FAIL_MESSAGE `` - Specify a custom failure message instead of using the default - generated message. Not recommended. - -Example for the simple signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibXml2 DEFAULT_MSG - LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) - -The ``LibXml2`` package is considered to be found if both -``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. -Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found -and ``REQUIRED`` was used, it fails with a -:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was -used or not. If it is found, success will be reported, including -the content of the first ````. On repeated CMake runs, -the same message will not be printed again. - -Example for the full signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibArchive - REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR - VERSION_VAR LibArchive_VERSION) - -In this case, the ``LibArchive`` package is considered to be found if -both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. -Also the version of ``LibArchive`` will be checked by using the version -contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, -the default messages will be printed. - -Another example for the full signature: - -.. code-block:: cmake - - find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) - find_package_handle_standard_args(Automoc4 CONFIG_MODE) - -In this case, a ``FindAutmoc4.cmake`` module wraps a call to -``find_package(Automoc4 NO_MODULE)`` and adds an additional search -directory for ``automoc4``. Then the call to -``find_package_handle_standard_args`` produces a proper success/failure -message. -#]=======================================================================] - -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - -# internal helper macro -macro(_FPHSA_FAILURE_MESSAGE _msg) - if (${_NAME}_FIND_REQUIRED) - message(FATAL_ERROR "${_msg}") - else () - if (NOT ${_NAME}_FIND_QUIETLY) - message(STATUS "${_msg}") - endif () - endif () -endmacro() - - -# internal helper macro to generate the failure message when used in CONFIG_MODE: -macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: - if(${_NAME}_CONFIG) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") - else() - # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. - # List them all in the error message: - if(${_NAME}_CONSIDERED_CONFIGS) - set(configsText "") - list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) - math(EXPR configsCount "${configsCount} - 1") - foreach(currentConfigIndex RANGE ${configsCount}) - list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) - list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) - string(APPEND configsText " ${filename} (version ${version})\n") - endforeach() - if (${_NAME}_NOT_FOUND_MESSAGE) - string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") - endif() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") - - else() - # Simple case: No Config-file was found at all: - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") - endif() - endif() -endmacro() - - -function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) - -# Set up the arguments for `cmake_parse_arguments`. - set(options CONFIG_MODE HANDLE_COMPONENTS) - set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) - set(multiValueArgs REQUIRED_VARS) - -# Check whether we are in 'simple' or 'extended' mode: - set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) - list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) - - if(${INDEX} EQUAL -1) - set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) - set(FPHSA_REQUIRED_VARS ${ARGN}) - set(FPHSA_VERSION_VAR) - else() - cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) - - if(FPHSA_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") - endif() - - if(NOT FPHSA_FAIL_MESSAGE) - set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") - endif() - - # In config-mode, we rely on the variable _CONFIG, which is set by find_package() - # when it successfully found the config-file, including version checking: - if(FPHSA_CONFIG_MODE) - list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) - list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) - set(FPHSA_VERSION_VAR ${_NAME}_VERSION) - endif() - - if(NOT FPHSA_REQUIRED_VARS) - message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") - endif() - endif() - -# now that we collected all arguments, process them - - if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") - set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") - endif() - - list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) - - string(TOUPPER ${_NAME} _NAME_UPPER) - string(TOLOWER ${_NAME} _NAME_LOWER) - - if(FPHSA_FOUND_VAR) - if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") - set(_FOUND_VAR ${FPHSA_FOUND_VAR}) - else() - message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") - endif() - else() - set(_FOUND_VAR ${_NAME_UPPER}_FOUND) - endif() - - # collect all variables which were not found, so they can be printed, so the - # user knows better what went wrong (#6375) - set(MISSING_VARS "") - set(DETAILS "") - # check if all passed variables are valid - set(FPHSA_FOUND_${_NAME} TRUE) - foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) - if(NOT ${_CURRENT_VAR}) - set(FPHSA_FOUND_${_NAME} FALSE) - string(APPEND MISSING_VARS " ${_CURRENT_VAR}") - else() - string(APPEND DETAILS "[${${_CURRENT_VAR}}]") - endif() - endforeach() - if(FPHSA_FOUND_${_NAME}) - set(${_NAME}_FOUND TRUE) - set(${_NAME_UPPER}_FOUND TRUE) - else() - set(${_NAME}_FOUND FALSE) - set(${_NAME_UPPER}_FOUND FALSE) - endif() - - # component handling - unset(FOUND_COMPONENTS_MSG) - unset(MISSING_COMPONENTS_MSG) - - if(FPHSA_HANDLE_COMPONENTS) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(${_NAME}_${comp}_FOUND) - - if(NOT DEFINED FOUND_COMPONENTS_MSG) - set(FOUND_COMPONENTS_MSG "found components: ") - endif() - string(APPEND FOUND_COMPONENTS_MSG " ${comp}") - - else() - - if(NOT DEFINED MISSING_COMPONENTS_MSG) - set(MISSING_COMPONENTS_MSG "missing components: ") - endif() - string(APPEND MISSING_COMPONENTS_MSG " ${comp}") - - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - string(APPEND MISSING_VARS " ${comp}") - endif() - - endif() - endforeach() - set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") - string(APPEND DETAILS "[c${COMPONENT_MSG}]") - endif() - - # version handling: - set(VERSION_MSG "") - set(VERSION_OK TRUE) - - # check with DEFINED here as the requested or found version may be "0" - if (DEFINED ${_NAME}_FIND_VERSION) - if(DEFINED ${FPHSA_VERSION_VAR}) - set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) - - if(${_NAME}_FIND_VERSION_EXACT) # exact version required - # count the dots in the version string - string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}") - # add one dot because there is one dot more than there are components - string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) - if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) - # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT - # is at most 4 here. Therefore a simple lookup table is used. - if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) - set(_VERSION_REGEX "[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) - set(_VERSION_REGEX "[^.]*\\.[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") - else () - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") - endif () - string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}") - unset(_VERSION_REGEX) - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - unset(_VERSION_HEAD) - else () - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - endif () - unset(_VERSION_DOTS) - - else() # minimum version specified: - if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") - endif () - endif() - - else() - - # if the package was not found, but a version was given, add that to the output: - if(${_NAME}_FIND_VERSION_EXACT) - set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") - else() - set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") - endif() - - endif() - else () - # Check with DEFINED as the found version may be 0. - if(DEFINED ${FPHSA_VERSION_VAR}) - set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") - endif() - endif () - - if(VERSION_OK) - string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") - else() - set(${_NAME}_FOUND FALSE) - endif() - - - # print the result: - if (${_NAME}_FOUND) - FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") - else () - - if(FPHSA_CONFIG_MODE) - _FPHSA_HANDLE_FAILURE_CONFIG_MODE() - else() - if(NOT VERSION_OK) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") - else() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") - endif() - endif() - - endif () - - set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) - set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) -endfunction() diff --git a/plugins/decl_netcdf/cmake/FindPackageMessage.cmake b/plugins/decl_netcdf/cmake/FindPackageMessage.cmake deleted file mode 100644 index 6821cee4f..000000000 --- a/plugins/decl_netcdf/cmake/FindPackageMessage.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# FindPackageMessage -# ------------------ -# -# -# -# FIND_PACKAGE_MESSAGE( "message for user" "find result details") -# -# This macro is intended to be used in FindXXX.cmake modules files. It -# will print a message once for each unique find result. This is useful -# for telling the user where a package was found. The first argument -# specifies the name (XXX) of the package. The second argument -# specifies the message to display. The third argument lists details -# about the find result so that if they change the message will be -# displayed again. The macro also obeys the QUIET argument to the -# find_package command. -# -# Example: -# -# :: -# -# if(X11_FOUND) -# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" -# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") -# else() -# ... -# endif() - -function(FIND_PACKAGE_MESSAGE pkg msg details) - # Avoid printing a message repeatedly for the same find result. - if(NOT ${pkg}_FIND_QUIETLY) - string(REPLACE "\n" "" details "${details}") - set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) - if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - # The message has not yet been printed. - message(STATUS "${msg}") - - # Save the find details in the cache to avoid printing the same - # message again. - set("${DETAILS_VAR}" "${details}" - CACHE INTERNAL "Details about finding ${pkg}") - endif() - endif() -endfunction() diff --git a/plugins/decl_netcdf/cmake/SelectLibraryConfigurations.cmake b/plugins/decl_netcdf/cmake/SelectLibraryConfigurations.cmake deleted file mode 100644 index fe3bb00a6..000000000 --- a/plugins/decl_netcdf/cmake/SelectLibraryConfigurations.cmake +++ /dev/null @@ -1,71 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# SelectLibraryConfigurations -# --------------------------- -# -# -# -# select_library_configurations( basename ) -# -# This macro takes a library base name as an argument, and will choose -# good values for basename_LIBRARY, basename_LIBRARIES, -# basename_LIBRARY_DEBUG, and basename_LIBRARY_RELEASE depending on what -# has been found and set. If only basename_LIBRARY_RELEASE is defined, -# basename_LIBRARY will be set to the release value, and -# basename_LIBRARY_DEBUG will be set to basename_LIBRARY_DEBUG-NOTFOUND. -# If only basename_LIBRARY_DEBUG is defined, then basename_LIBRARY will -# take the debug value, and basename_LIBRARY_RELEASE will be set to -# basename_LIBRARY_RELEASE-NOTFOUND. -# -# If the generator supports configuration types, then basename_LIBRARY -# and basename_LIBRARIES will be set with debug and optimized flags -# specifying the library to be used for the given configuration. If no -# build type has been set or the generator in use does not support -# configuration types, then basename_LIBRARY and basename_LIBRARIES will -# take only the release value, or the debug value if the release one is -# not set. - -# This macro was adapted from the FindQt4 CMake module and is maintained by Will -# Dicharry . - -macro( select_library_configurations basename ) - if(NOT ${basename}_LIBRARY_RELEASE) - set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.") - endif() - if(NOT ${basename}_LIBRARY_DEBUG) - set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.") - endif() - - get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND - NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND - ( _isMultiConfig OR CMAKE_BUILD_TYPE ) ) - # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for - # single-config generators, set optimized and debug libraries - set( ${basename}_LIBRARY "" ) - foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE ) - list( APPEND ${basename}_LIBRARY optimized "${_libname}" ) - endforeach() - foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG ) - list( APPEND ${basename}_LIBRARY debug "${_libname}" ) - endforeach() - elseif( ${basename}_LIBRARY_RELEASE ) - set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) - elseif( ${basename}_LIBRARY_DEBUG ) - set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} ) - else() - set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND") - endif() - - set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" ) - - if( ${basename}_LIBRARY ) - set( ${basename}_FOUND TRUE ) - endif() - - mark_as_advanced( ${basename}_LIBRARY_RELEASE - ${basename}_LIBRARY_DEBUG - ) -endmacro() diff --git a/plugins/decl_netcdf/dnc_file_context.cxx b/plugins/decl_netcdf/dnc_file_context.cxx index b0d9fc441..fb8efb0b8 100644 --- a/plugins/decl_netcdf/dnc_file_context.cxx +++ b/plugins/decl_netcdf/dnc_file_context.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2019-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -37,7 +37,7 @@ Dnc_file_context::Dnc_file_context(PDI::Context& ctx, PC_tree_t config) { PC_tree_t file_node = PC_get(config, ".file"); if (PC_status(file_node)) { - throw PDI::Error{PDI_ERR_CONFIG, "Decl_netcdf plugin: `file' node is mandatory"}; + throw PDI::Spectree_error{file_node, "Decl_netcdf plugin: `file' node is mandatory"}; } m_file_path = PDI::Expression{PDI::to_string(file_node)}; m_ctx.logger().trace("Creating file info"); @@ -73,6 +73,12 @@ Dnc_file_context::Dnc_file_context(PDI::Context& ctx, PC_tree_t config) m_when = PDI::Expression{1L}; // if when not defined -> always true } + PDI::Expression file_deflate; + PC_tree_t deflate_node = PC_get(config, ".deflate"); + if (!PC_status(deflate_node)) { + file_deflate = deflate_node; + } + PC_tree_t groups_node = PC_get(config, ".groups"); if (!PC_status(groups_node)) { PDI::each(groups_node, [this](PC_tree_t group_path_node, PC_tree_t group_value) { @@ -86,10 +92,10 @@ Dnc_file_context::Dnc_file_context(PDI::Context& ctx, PC_tree_t config) PC_tree_t variables_node = PC_get(config, ".variables"); if (!PC_status(variables_node)) { - PDI::each(variables_node, [this](PC_tree_t variable_path_node, PC_tree_t variable_value) { + PDI::each(variables_node, [&](PC_tree_t variable_path_node, PC_tree_t variable_value) { std::string variable_path = PDI::to_string(variable_path_node); this->m_ctx.logger().trace("Creating new variable info: {}", variable_path); - this->m_variables.emplace(variable_path, Dnc_variable{this->m_ctx, variable_path, variable_value}); + this->m_variables.emplace(variable_path, Dnc_variable{this->m_ctx, variable_path, variable_value, file_deflate}); }); } else { m_ctx.logger().trace("No variable defined"); @@ -127,7 +133,7 @@ Dnc_file_context::Dnc_file_context(PDI::Context& ctx, PC_tree_t config) PC_tree_t write_node = PC_get(config, ".write"); if (!PC_status(write_node)) { - if (PDI::is_scalar(read_node)) { + if (PDI::is_scalar(write_node)) { std::string write_desc = PDI::to_string(write_node); m_ctx.logger().trace("Creating new empty write info for: {}", write_desc); m_write.emplace(write_desc, Dnc_io{this->m_ctx, PC_tree_t{}}); @@ -138,12 +144,14 @@ Dnc_file_context::Dnc_file_context(PDI::Context& ctx, PC_tree_t config) m_ctx.logger().trace("Creating new empty write info for: {}", write_desc); m_write.emplace(write_desc, Dnc_io{this->m_ctx, PC_tree_t{}}); } - } else { + } else if (PDI::is_map(write_node)) { PDI::each(write_node, [this](PC_tree_t desc_name, PC_tree_t write_value) { std::string write_desc = PDI::to_string(desc_name); m_ctx.logger().trace("Creating new write info for: {}", write_desc); this->m_write.emplace(PDI::to_string(desc_name), Dnc_io{this->m_ctx, write_value}); }); + } else { + throw PDI::Spectree_error{write_node, "write node is not parsed correctly"}; } } diff --git a/plugins/decl_netcdf/dnc_io.cxx b/plugins/decl_netcdf/dnc_io.cxx index 7c3487fd8..0b3323727 100644 --- a/plugins/decl_netcdf/dnc_io.cxx +++ b/plugins/decl_netcdf/dnc_io.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2024-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -92,7 +92,7 @@ std::vector Dnc_io::get_dims_start(const std::vector& var_stride } } else { if (m_start.size() != var_stride.size()) { - throw PDI::Error{PDI_ERR_RIGHT, "Decl_netcdf plugin: Dimensions of stride and start differ: {} != {}", m_start.size(), var_stride.size()}; + throw PDI::Permission_error{"Decl_netcdf plugin: Dimensions of stride and start differ: {} != {}", m_start.size(), var_stride.size()}; } for (auto&& start: m_start) { var_start.emplace_back(start.to_long(m_ctx)); @@ -110,12 +110,7 @@ std::vector Dnc_io::get_dims_count(const std::vector& var_stride } } else { if (m_subsize.size() != var_stride.size()) { - throw PDI::Error{ - PDI_ERR_RIGHT, - "Decl_netcdf plugin: Dimensions of stride and subsize differ: {} != {}", - m_subsize.size(), - var_stride.size() - }; + throw PDI::Permission_error{"Decl_netcdf plugin: Dimensions of stride and subsize differ: {} != {}", m_subsize.size(), var_stride.size()}; } for (auto&& subsize: m_subsize) { var_count.emplace_back(subsize.to_long(m_ctx)); diff --git a/plugins/decl_netcdf/dnc_netcdf_file.cxx b/plugins/decl_netcdf/dnc_netcdf_file.cxx index faa9f4520..f3789cf58 100644 --- a/plugins/decl_netcdf/dnc_netcdf_file.cxx +++ b/plugins/decl_netcdf/dnc_netcdf_file.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2020-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -101,13 +101,13 @@ const PDI::Datatype_sptr get_variable_stride(PDI::Datatype_sptr type, std::vecto /** Wraps the calling of netcdf call with status checking * * \param status status returned from netcdf call - * \param message a context message to use in case of error + * \param format_str a context message to use in case of error */ template -void nc_try(int status, const char* message_if_error, const Args&... args) +void nc_try(int status, fmt::format_string format_str, Args&&... args) { if (status != NC_NOERR) { - throw PDI::Error{PDI_ERR_VALUE, "Decl_netcdf plugin: {} : ({}) {}", fmt::format(message_if_error, args...), status, nc_strerror(status)}; + throw PDI::Value_error{"in NetCDF, {}: {}", fmt::format(format_str, std::forward(args)...), nc_strerror(status)}; } } @@ -125,14 +125,14 @@ nc_type nc_scalar_type(const PDI::Scalar_datatype& scalar_type) case 8L: return NC_INT64; default: - throw PDI::Error{PDI_ERR_TYPE, "Decl_netcdf plugin: Unsupported signed scalar datatype"}; + throw PDI::Type_error{"Decl_netcdf plugin: Unsupported signed scalar datatype"}; } case PDI::Scalar_kind::UNSIGNED: switch (scalar_type.buffersize()) { case 1L: return NC_CHAR; default: - throw PDI::Error{PDI_ERR_TYPE, "Decl_netcdf plugin: Unsupported unsigned scalar datatype"}; + throw PDI::Type_error{"Decl_netcdf plugin: Unsupported unsigned scalar datatype"}; } case PDI::Scalar_kind::FLOAT: switch (scalar_type.buffersize()) { @@ -141,11 +141,11 @@ nc_type nc_scalar_type(const PDI::Scalar_datatype& scalar_type) case 8L: return NC_DOUBLE; default: - throw PDI::Error{PDI_ERR_TYPE, "Decl_netcdf plugin: Unsupported float scalar datatype"}; + throw PDI::Type_error{"Decl_netcdf plugin: Unsupported float scalar datatype"}; } break; default: - throw PDI::Error{PDI_ERR_TYPE, "Decl_netcdf plugin: Unsupported unknown scalar datatype: {}", scalar_type.debug_string()}; + throw PDI::Type_error{"Decl_netcdf plugin: Unsupported unknown scalar datatype: {}", scalar_type.debug_string()}; } } @@ -166,25 +166,25 @@ Dnc_netcdf_file::Dnc_netcdf_file(PDI::Context& ctx, const std::string& filename, m_ctx.logger().trace("Cannot open file, creating", m_filename); nc_try( nc_create_par(m_filename.c_str(), rights_flag | NC_NETCDF4, *communicator, mpi_info, &m_file_id), - "Cannot open or create file: {}", + "cannot open or create file: {}", m_filename ); } else { if (rights_flag == NC_WRITE) { - nc_try(nc_redef(m_file_id), "File opened to write, but cannot get define mode"); + nc_try(nc_redef(m_file_id), "file opened for writing, cannot get define mode"); } } #else - throw PDI::Error{PDI_ERR_SYSTEM, "Decl_netcdf plugin: MPI communicator defined, but NetCDF is not parallel"}; + throw PDI::System_error{"Decl_netcdf plugin: MPI communicator defined, but NetCDF is not parallel"}; #endif } else { m_ctx.logger().debug("Openning `{}' file in serial mode", m_filename); if (nc_open(m_filename.c_str(), rights_flag | NC_NETCDF4, &m_file_id) != NC_NOERR) { m_ctx.logger().trace("Cannot open `{}' file, creating", m_filename); - nc_try(nc_create(m_filename.c_str(), rights_flag | NC_NETCDF4 | NC_NOCLOBBER, &m_file_id), "Cannot open or create file: {}", m_filename); + nc_try(nc_create(m_filename.c_str(), rights_flag | NC_NETCDF4 | NC_NOCLOBBER, &m_file_id), "cannot open or create file `{}'", m_filename); } else { if (rights_flag == NC_WRITE) { - nc_try(nc_redef(m_file_id), "File opened to write, but cannot get define mode"); + nc_try(nc_redef(m_file_id), "file opened for writing, cannot get define mode"); } } } @@ -210,7 +210,7 @@ void Dnc_netcdf_file::read_group(const Dnc_group& group) std::vector groups_names = split_to_groups(group.path()); int group_id = m_file_id; for (auto&& group_name: groups_names) { - nc_try(nc_inq_grp_ncid(dest_id, group_name.c_str(), &group_id), "Cannot read {} group from (nc_id = {})", group_name, dest_id); + nc_try(nc_inq_grp_ncid(dest_id, group_name.c_str(), &group_id), "cannot read `{}' group from (nc_id = {})", group_name, dest_id); m_ctx.logger().trace("Read `{}' group (nc_id = {}) in (nc_id = {})", dest_path + "/" + group_name, group_id, dest_id); @@ -232,7 +232,7 @@ void Dnc_netcdf_file::define_group(const Dnc_group& group) int group_id = m_file_id; for (auto&& group_name: groups_names) { if (nc_inq_grp_ncid(dest_id, group_name.c_str(), &group_id) != NC_NOERR) { - nc_try(nc_def_grp(dest_id, group_name.c_str(), &group_id), "Cannot define group {} in nc_id = {}", group_name, dest_id); + nc_try(nc_def_grp(dest_id, group_name.c_str(), &group_id), "cannot define group {} in (nc_id = {})", group_name, dest_id); m_ctx.logger().trace("Defined `{}' group (nc_id = {}) in (nc_id = {})", dest_path + "/" + group_name, group_id, dest_id); } @@ -262,7 +262,7 @@ void Dnc_netcdf_file::read_variable(const Dnc_variable& variable) std::vector groups_names = split_to_groups(group_path); int group_id = m_file_id; for (auto&& group_name: groups_names) { - nc_try(nc_inq_grp_ncid(dest_id, group_name.c_str(), &group_id), "Cannot read {} group from (nc_id = {})", group_name, dest_id); + nc_try(nc_inq_grp_ncid(dest_id, group_name.c_str(), &group_id), "cannot read `{}' group from (nc_id = {})", group_name, dest_id); m_ctx.logger().trace("Read `{}' group (nc_id = {}) in (nc_id = {})", dest_path + "/" + group_name, group_id, dest_id); @@ -275,7 +275,7 @@ void Dnc_netcdf_file::read_variable(const Dnc_variable& variable) int src_id = group_it->second; int nc_var_id; - nc_try(nc_inq_varid(src_id, variable_name.c_str(), &nc_var_id), "Cannot inquire variable {} from (nc_id = {})", variable_name, src_id); + nc_try(nc_inq_varid(src_id, variable_name.c_str(), &nc_var_id), "cannot inquire variable `{}' from (nc_id = {})", variable_name, src_id); m_ctx.logger().trace("Inquired `{}' variable (nc_id = {}) from (nc_id = {})", variable.path(), nc_var_id, src_id); m_variables.emplace(variable.path(), nc_var_id); @@ -295,10 +295,10 @@ int get_dimension_id(PDI::Context& ctx, int nc_dest_id, const std::string& dim_n if (nc_inq_dimid(nc_dest_id, dim_name.c_str(), &dim_id) == NC_NOERR) { ctx.logger().debug("`{}' dimension is already defined", dim_name); size_t dim_len; - nc_try(nc_inq_dimlen(nc_dest_id, dim_id, &dim_len), "Cannot inquire dimension length"); + nc_try(nc_inq_dimlen(nc_dest_id, dim_id, &dim_len), "cannot inquire dimension length"); } else { ctx.logger().debug("Defining `{}' dimension", dim_name); - nc_try(nc_def_dim(nc_dest_id, dim_name.c_str(), type_dim, &dim_id), "Cannot define {} dimension", dim_name); + nc_try(nc_def_dim(nc_dest_id, dim_name.c_str(), type_dim, &dim_id), "cannot define dimension `{}'", dim_name); } return dim_id; } @@ -346,7 +346,7 @@ nc_type Dnc_netcdf_file::define_compound_type(std::shared_ptrbuffersize()); - nc_try(nc_def_compound(m_file_id, record_type->buffersize(), compound_type_name.c_str(), &type_id), "Cannot define record type"); + nc_try(nc_def_compound(m_file_id, record_type->buffersize(), compound_type_name.c_str(), &type_id), "cannot define record type"); for (auto&& member: record_type->members()) { if (auto&& array_type = std::dynamic_pointer_cast(member.type())) { @@ -364,7 +364,7 @@ nc_type Dnc_netcdf_file::define_compound_type(std::shared_ptr(type)) { member_type_id = define_compound_type(member_record_type); } else { - throw PDI::Error{PDI_ERR_RIGHT, "Decl_netcdf plugin: Not supported datatype: {}", type->debug_string()}; + throw PDI::Permission_error{"Decl_netcdf plugin: Not supported datatype: {}", type->debug_string()}; } nc_insert_array_compound(m_file_id, type_id, member.name().c_str(), member.displacement(), member_type_id, sizes.size(), sizes.data()); } else if (auto&& member_record_type = std::dynamic_pointer_cast(member.type())) { @@ -376,7 +376,7 @@ nc_type Dnc_netcdf_file::define_compound_type(std::shared_ptrdebug_string()}; + throw PDI::Permission_error{"Decl_netcdf plugin: Not supported datatype: {}", member.type()->debug_string()}; } } m_ctx.logger().trace("Complete defining new compound type: {} (nc_type = {}): ", compound_type_name, type_id, record_type->debug_string()); @@ -414,10 +414,10 @@ void Dnc_netcdf_file::define_variable(const Dnc_variable& variable) // get variable type PDI::Datatype_sptr variable_type = variable.type(); if (!variable_type) { - throw PDI::Error{PDI_ERR_RIGHT, "Decl_netcdf plugin: Variable {}: No type defined", variable.path()}; + throw PDI::Permission_error{"Decl_netcdf plugin: Variable {}: No type defined", variable.path()}; } if (!variable_type->dense()) { - throw PDI::Error{PDI_ERR_RIGHT, "Decl_netcdf plugin: Variable {}: Data must be dense (continuous memory)", variable.path()}; + throw PDI::Permission_error{"Decl_netcdf plugin: Variable {}: Data must be dense (continuous memory)", variable.path()}; } m_ctx.logger().trace("Preparing variable `{}'", variable_name); @@ -433,7 +433,7 @@ void Dnc_netcdf_file::define_variable(const Dnc_variable& variable) } else if (auto&& record_type = std::dynamic_pointer_cast(type)) { type_id = define_compound_type(record_type); } else { - throw PDI::Error{PDI_ERR_RIGHT, "Decl_netcdf plugin: Not supported datatype: {}", type->debug_string()}; + throw PDI::Permission_error{"Decl_netcdf plugin: Unsupported datatype: {}", type->debug_string()}; } // get variable dimensions @@ -450,8 +450,7 @@ void Dnc_netcdf_file::define_variable(const Dnc_variable& variable) } } else { if (sizes.size() != dimensions_names.size()) { - throw PDI::Error{ - PDI_ERR_VALUE, + throw PDI::Value_error{ "Decl_netcdf plugin: Variable type dimension ({}) != defined variable dimensions ({})", sizes.size(), dimensions_names.size() @@ -468,10 +467,58 @@ void Dnc_netcdf_file::define_variable(const Dnc_variable& variable) m_ctx.logger().trace("Defining variable `{}' in (nc_id = {}) of type (nc_id = {})", variable.path(), dest_id, type_id); nc_try( nc_def_var(dest_id, variable_name.c_str(), type_id, dimensions_ids.size(), dimensions_ids.data(), &var_id), - "Cannot define `{}' variable in (nc_id = {})", + "cannot define variable `{}' in (nc_id = {})", variable_name, dest_id ); + + int deflate_level = 0; + if (variable.deflate()) { + deflate_level = variable.deflate().to_long(m_ctx); + } + // if a deflate level is set on a scalar variable, reset the level to 0 + if (auto&& scalar_type = std::dynamic_pointer_cast(variable_type) && deflate_level != 0) { + m_ctx.logger().warn("\t var {} is of type scalar, reset deflate level to {} (no deflate)", variable_name, deflate_level); + deflate_level = 0; + } + if (deflate_level) { + m_ctx.logger().trace("\t var {} deflate = [{}]", variable_name, deflate_level); + if (variable.chunking()) { + PDI::Ref_r chunking_ref = variable.chunking().to_ref(m_ctx); + if (chunking_ref) { + m_ctx.logger().trace("Setting `{}' dataset chunking:", variable_name); + std::vector sizes; + PDI::Datatype_sptr ref_type = chunking_ref.type(); + if (auto&& scalar_type = std::dynamic_pointer_cast(ref_type)) { + sizes.emplace_back(chunking_ref.scalar_value()); + } else if (auto&& array_type = std::dynamic_pointer_cast(ref_type)) { + for (size_t i = 0; i < array_type->size(); i++) { + sizes.emplace_back(PDI::Ref_r{chunking_ref[i]}.scalar_value()); + } + } else if (auto&& tuple_type = std::dynamic_pointer_cast(ref_type)) { + for (size_t i = 0; i < tuple_type->size(); i++) { + sizes.emplace_back(PDI::Ref_r{chunking_ref[i]}.scalar_value()); + } + } else { + throw PDI::Type_error{"Chunking must be a scalar, an array or a tuple"}; + } + nc_try( + nc_def_var_chunking(dest_id, var_id, NC_CHUNKED, sizes.data()), + "cannot define chunking of variable `{}' in (nc_id = {})", + variable_name, + dest_id + ); + } + } + + // if no chunking is defined, automatic chunking will be used + nc_try( + nc_def_var_deflate(dest_id, var_id, NC_SHUFFLE, 1, deflate_level), + "cannot define deflate level of variable `{}' in (nc_id = {})", + variable_name, + dest_id + ); + } m_ctx.logger().trace("Variable `{}' defined (var_id = {})", variable.path(), var_id); } @@ -479,7 +526,7 @@ void Dnc_netcdf_file::define_variable(const Dnc_variable& variable) #if NC_HAS_PARALLEL4 if (m_communicator) { - nc_try(nc_var_par_access(dest_id, var_id, NC_COLLECTIVE), "Cannot change the access of `{}' variable to parallel", variable_name); + nc_try(nc_var_par_access(dest_id, var_id, NC_COLLECTIVE), "cannot change the access of variable `{}' to parallel", variable_name); } #endif @@ -499,7 +546,7 @@ void Dnc_netcdf_file::get_attribute(nc_id src_id, nc_id var_id, const Dnc_attrib // get scalar attribute nc_try( nc_get_att(src_id, var_id, attribute.name().c_str(), ref_w.get()), - "Cannot get attribute `{}' from (nc_id = {}/{})", + "cannot get attribute `{}' from (nc_id = {}/{})", attribute.name(), src_id, var_id @@ -508,22 +555,16 @@ void Dnc_netcdf_file::get_attribute(nc_id src_id, nc_id var_id, const Dnc_attrib // get array attribute if (auto&& scalar_type = std::dynamic_pointer_cast(array_type->subtype())) { if (!array_type->dense()) { - throw PDI::Error{PDI_ERR_TYPE, "Decl_netcdf plugin: Attribute type must be dense (continuous memory)"}; + throw PDI::Type_error{"Decl_netcdf plugin: Attribute type must be dense (continuous memory)"}; } if (nc_get_att(src_id, var_id, attribute.name().c_str(), ref_w.get())) { - throw PDI::Error{ - PDI_ERR_SYSTEM, - "Decl_netcdf plugin: Cannot get attribute `{}' from (nc_id = {}/{})", - attribute.name(), - src_id, - var_id - }; + throw PDI::System_error{"Decl_netcdf plugin: Cannot get attribute `{}' from (nc_id = {}/{})", attribute.name(), src_id, var_id}; } } else { - throw PDI::Error{PDI_ERR_TYPE, "Decl_netcdf plugin: Multi dimensional array for attribute not supported"}; + throw PDI::Type_error{"Decl_netcdf plugin: Multi dimensional array for attribute not supported"}; } } else { - throw PDI::Error{PDI_ERR_TYPE, "Decl_netcdf plugin: Record datatype for attribute not supported"}; + throw PDI::Type_error{"Decl_netcdf plugin: Record datatype for attribute not supported"}; } } else { m_ctx.logger().debug("Decl_netcdf plugin: No write access to read data from file attribute: {}", attribute.name()); @@ -539,7 +580,7 @@ void Dnc_netcdf_file::put_attribute(nc_id dest_id, nc_id var_id, const Dnc_attri // set scalar attribute nc_try( nc_put_att(dest_id, var_id, attribute.name().c_str(), nc_scalar_type(*scalar_type), 1, ref_r.get()), - "Cannot put attribute `{}' to (nc_id = {}/{})", + "cannot set attribute `{}' in (nc_id = {}/{})", attribute.name(), dest_id, var_id @@ -548,21 +589,21 @@ void Dnc_netcdf_file::put_attribute(nc_id dest_id, nc_id var_id, const Dnc_attri // set array attribute if (auto&& scalar_type = std::dynamic_pointer_cast(array_type->subtype())) { if (!array_type->dense()) { - throw PDI::Error{PDI_ERR_TYPE, "Decl_netcdf plugin: Attribute type must be dense (continuous memory)"}; + throw PDI::Type_error{"Decl_netcdf plugin: Attribute type must be dense (continuous memory)"}; } else { nc_try( nc_put_att(dest_id, var_id, attribute.name().c_str(), nc_scalar_type(*scalar_type), array_type->size(), ref_r.get()), - "Cannot put attribute `{}' to (nc_id = {}/{})", + "cannot set attribute `{}' in (nc_id = {}/{})", attribute.name(), dest_id, var_id ); } } else { - throw PDI::Error{PDI_ERR_TYPE, "Decl_netcdf plugin: Multi dimensional array for attribute not supported"}; + throw PDI::Type_error{"Decl_netcdf plugin: Multi dimensional array for attribute not supported"}; } } else { - throw PDI::Error{PDI_ERR_TYPE, "Decl_netcdf plugin: Record datatype for attribute not supported"}; + throw PDI::Type_error{"Decl_netcdf plugin: Record datatype for attribute not supported"}; } } else { m_ctx.logger().debug("Decl_netcdf plugin: No read access to write data to attribute: {}", attribute.name()); @@ -571,7 +612,7 @@ void Dnc_netcdf_file::put_attribute(nc_id dest_id, nc_id var_id, const Dnc_attri void Dnc_netcdf_file::enddef() const { - nc_try(nc_enddef(m_file_id), "Cannot end define mode"); + nc_try(nc_enddef(m_file_id), "cannot end define mode"); m_ctx.logger().debug("Define mode end in file {} (nc_id = {})", m_filename, m_file_id); } @@ -579,7 +620,7 @@ void Dnc_netcdf_file::put_variable(const Dnc_variable& variable, const Dnc_io& w { // check access if (!ref_r) { - throw PDI::Error{PDI_ERR_RIGHT, "Decl_netcdf plugin: Cannot write `{}'. Need read access to write it to file", variable.path()}; + throw PDI::Permission_error{"Decl_netcdf plugin: Cannot write `{}'. Need read access to write it to file", variable.path()}; } // get group path and variable name @@ -587,14 +628,14 @@ void Dnc_netcdf_file::put_variable(const Dnc_variable& variable, const Dnc_io& w // get dest_id auto group_it = m_groups.find(group_path); if (group_it == m_groups.end()) { - throw PDI::Error{PDI_ERR_VALUE, "Decl_netcdf plugin: Cannot find group that should be created: {}", group_path}; + throw PDI::Value_error{"Decl_netcdf plugin: Cannot find group that should be created: {}", group_path}; } nc_id dest_id = group_it->second; // get var_id auto var_it = m_variables.find(variable.path()); if (var_it == m_variables.end()) { - throw PDI::Error{PDI_ERR_VALUE, "Decl_netcdf plugin: Cannot find variable that should be created: {}", variable.path()}; + throw PDI::Value_error{"Decl_netcdf plugin: Cannot find variable that should be created: {}", variable.path()}; } nc_id var_id = var_it->second; @@ -608,11 +649,12 @@ void Dnc_netcdf_file::put_variable(const Dnc_variable& variable, const Dnc_io& w m_ctx.logger().trace("Putting variable `{}' (var_id = {})", variable_name, var_id); if (var_stride.empty()) { - nc_try(nc_put_var(dest_id, var_id, ref_r.get()), "Decl_netcdf plugin: Cannot write `{}' to (nc_id = {})", dest_id); + nc_try(nc_put_var(dest_id, var_id, ref_r.get()), "Decl_netcdf plugin: Cannot write `{}' to (nc_id = {})", variable_name, dest_id); } else { nc_try( nc_put_vara(dest_id, var_id, var_start.data(), var_count.data(), ref_r.get()), - "Decl_netcdf plugin: Cannot write `{}' to (nc_id = {})", + "cannot write `{}' to (nc_id = {})", + variable_name, dest_id ); } @@ -622,7 +664,7 @@ void Dnc_netcdf_file::put_variable(const Dnc_variable& variable, const Dnc_io& w void Dnc_netcdf_file::get_variable(const Dnc_variable& variable, const Dnc_io& read, PDI::Ref_w ref_w) { if (!ref_w) { - throw PDI::Error{PDI_ERR_RIGHT, "Decl_netcdf plugin: Cannot read `{}'. Need write access to read it from file", variable.path()}; + throw PDI::Permission_error{"Decl_netcdf plugin: Cannot read `{}'. Need write access to read it from file", variable.path()}; } // get variable stride to calculate start and count @@ -637,30 +679,93 @@ void Dnc_netcdf_file::get_variable(const Dnc_variable& variable, const Dnc_io& r // get src_id auto group_it = m_groups.find(group_path); if (group_it == m_groups.end()) { - throw PDI::Error{PDI_ERR_VALUE, "Decl_netcdf plugin: Cannot find group that should be created: {}", group_path}; + throw PDI::Value_error{"Decl_netcdf plugin: Cannot find group that should be created: {}", group_path}; } nc_id src_id = group_it->second; // get var_id auto var_it = m_variables.find(variable.path()); if (var_it == m_variables.end()) { - throw PDI::Error{PDI_ERR_VALUE, "Decl_netcdf plugin: Cannot find variable that should be created: {}", variable.path()}; + throw PDI::Value_error{"Decl_netcdf plugin: Cannot find variable that should be created: {}", variable.path()}; } nc_id var_id = var_it->second; - // read variable + // read variable and check for scalar type match + if (auto&& scalar_type = std::dynamic_pointer_cast(ref_w.type())) { + nc_type var_nc_type; + size_t var_nc_type_size; + nc_try(nc_inq_vartype(src_id, var_id, &var_nc_type), "cannot get type of `{}' from file", variable.path()); + nc_try(nc_inq_type(0, var_nc_type, NULL, &var_nc_type_size), "can not inquire the size of `{}'", var_nc_type); + if (scalar_type->kind() == PDI::Scalar_kind::SIGNED) { + switch (var_nc_type) { + case NC_BYTE: + case NC_SHORT: + case NC_INT: + case NC_INT64: + if (scalar_type->datasize() != var_nc_type_size) { + throw PDI::Type_error{ + "Decl_netcdf plugin: Datatype mismatch (with size): read '{}' of size {} for a buffer of size {}", + variable_name, + var_nc_type_size, + scalar_type->datasize() + }; + } + break; + default: + throw PDI::Type_error{ + "Decl_netcdf plugin: Datatype mismatch (with sign): buffer is of signed scalar type while read '{}' is neither NC_BYTE, " + "NC_SHORT, NC_INT, nor NC_INT64.", + variable_name, + }; + } + } else if (scalar_type->kind() == PDI::Scalar_kind::UNSIGNED) { + switch (var_nc_type) { + case NC_UBYTE: + case NC_USHORT: + case NC_UINT: + case NC_UINT64: + if (scalar_type->datasize() != var_nc_type_size) { + throw PDI::Type_error{ + "Decl_netcdf plugin: Datatype mismatch: read '{}' of size {} for a buffer of size {}", + variable_name, + var_nc_type_size, + scalar_type->datasize() + }; + } + break; + default: + throw PDI::Type_error{ + "Decl_netcdf plugin: Datatype mismatch (with sign): buffer is of unsigned scalar type while read '{}' is neither NC_UBYTE, " + "NC_USHORT, NC_UINT, nor NC_UINT64.", + variable_name, + }; + } + } else if (scalar_type->kind() == PDI::Scalar_kind::FLOAT) { + if (scalar_type->datasize() != var_nc_type_size) { + throw PDI::Type_error{ + "Decl_netcdf plugin: Datatype mismatch (with size): read '{}' of size {} for a buffer of size {}", + variable_name, + var_nc_type_size, + scalar_type->datasize() + }; + } + } else { + throw PDI::Type_error{"Can not read `{}' : buffer has unknown type", variable_name}; + } + } + m_ctx.logger().trace("Getting variable `{}'", variable.path()); if (var_stride.empty()) { - nc_try(nc_get_var(src_id, var_id, ref_w.get()), "Cannot read `{}' from file", variable.path()); + nc_try(nc_get_var(src_id, var_id, ref_w.get()), "cannot read `{}' from file", variable.path()); } else { - nc_try(nc_get_vara(src_id, var_id, var_start.data(), var_count.data(), ref_w.get()), "Cannot read `{}' from file", variable.path()); + nc_try(nc_get_vara(src_id, var_id, var_start.data(), var_count.data(), ref_w.get()), "cannot read `{}' from file", variable.path()); } } void Dnc_netcdf_file::get_sizeof_variable(const std::string& variable, const std::string& sizeof_var, PDI::Ref ref) { if (!PDI::Ref_w(ref)) { - throw PDI::Error{PDI_ERR_RIGHT, "Decl_netcdf plugin: Cannot read `{}'. Need write access to read it from file", sizeof_var}; + throw PDI::Permission_error{"Decl_netcdf plugin: Cannot read `{}'. Need write access to read it from file", sizeof_var}; } // get group path and variable name @@ -669,15 +774,15 @@ void Dnc_netcdf_file::get_sizeof_variable(const std::string& variable, const std // get src_id auto group_it = m_groups.find(group_path); if (group_it == m_groups.end()) { - throw PDI::Error{PDI_ERR_VALUE, "Decl_netcdf plugin: Cannot find group that should be created: {}", group_path}; + throw PDI::Value_error{"Decl_netcdf plugin: Cannot find group that should be created: {}", group_path}; } nc_id src_id = group_it->second; nc_id var_id; - nc_try(nc_inq_varid(src_id, variable_name.c_str(), &var_id), "Cannot inquire variable {} from (nc_id = {})", variable_name, src_id); + nc_try(nc_inq_varid(src_id, variable_name.c_str(), &var_id), "cannot inquire variable `{}' from (nc_id = {})", variable_name, src_id); int var_dim; - nc_try(nc_inq_varndims(src_id, var_id, &var_dim), "Cannot inquire variable dimension counts from (var_id= {}, nc_id = {})", sizeof_var, src_id); + nc_try(nc_inq_varndims(src_id, var_id, &var_dim), "cannot inquire variable dimension counts from (var_id={}, nc_id={})", sizeof_var, src_id); std::vector dimid(var_dim); std::vector dimlen(var_dim); @@ -686,15 +791,14 @@ void Dnc_netcdf_file::get_sizeof_variable(const std::string& variable, const std if (auto&& scalar_type = std::dynamic_pointer_cast(ref.type())) { if (var_dim != 1) { - throw PDI::Error{ - PDI_ERR_VALUE, + throw PDI::Value_error{ "Decl_netcdf plugin: Incoherent data size. Data {} defined with size=1 , but {} has size {}", variable, sizeof_var, var_dim }; } - nc_try(nc_inq_dimlen(src_id, dimid[0], &dimlen[0]), "Cannot inquire dimension length"); + nc_try(nc_inq_dimlen(src_id, dimid[0], &dimlen[0]), "cannot inquire dimension length"); PDI::Ref_w(ref).scalar_assign(dimlen[0]); } @@ -702,8 +806,7 @@ void Dnc_netcdf_file::get_sizeof_variable(const std::string& variable, const std else if (auto&& array_type = std::dynamic_pointer_cast(ref.type())) { if (var_dim != array_type->size()) { - throw PDI::Error{ - PDI_ERR_VALUE, + throw PDI::Value_error{ "Decl_netcdf plugin: Incoherent data size. Data {} defined with size {}, but provided with {}", variable, array_type->size(), @@ -711,19 +814,19 @@ void Dnc_netcdf_file::get_sizeof_variable(const std::string& variable, const std }; } for (int i = 0; i < var_dim; i++) { - nc_try(nc_inq_dimlen(src_id, dimid[i], &dimlen[i]), "Cannot inquire dimension length"); + nc_try(nc_inq_dimlen(src_id, dimid[i], &dimlen[i]), "cannot inquire dimension length"); PDI::Ref_w(ref[i]).scalar_assign(dimlen[i]); } } else { - throw PDI::Error{PDI_ERR_VALUE, "Decl_netcdf plugin: Incompatible data type for {}. Expecting scalar or array", sizeof_var}; + throw PDI::Value_error{"Decl_netcdf plugin: Incompatible data type for {}. Expecting scalar or array", sizeof_var}; } } Dnc_netcdf_file::~Dnc_netcdf_file() { m_ctx.logger().debug("Closing file {} (nc_id = {})", m_filename, m_file_id); - nc_try(nc_close(m_file_id), "Cannot close the file {}", m_filename); + nc_try(nc_close(m_file_id), "cannot close the file {}", m_filename); } } // namespace decl_netcdf diff --git a/plugins/decl_netcdf/dnc_variable.cxx b/plugins/decl_netcdf/dnc_variable.cxx index fd170a901..e70083414 100644 --- a/plugins/decl_netcdf/dnc_variable.cxx +++ b/plugins/decl_netcdf/dnc_variable.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -27,9 +27,10 @@ namespace decl_netcdf { -Dnc_variable::Dnc_variable(PDI::Context& ctx, const std::string& path, PC_tree_t config) +Dnc_variable::Dnc_variable(PDI::Context& ctx, const std::string& path, PC_tree_t config, PDI::Expression deflate) : m_ctx{ctx} , m_path{path} + , m_deflate{std::move(deflate)} { PC_tree_t attributes_node = PC_get(config, ".attributes"); if (!PC_status(attributes_node)) { @@ -52,6 +53,16 @@ Dnc_variable::Dnc_variable(PDI::Context& ctx, const std::string& path, PC_tree_t if (!PC_status(type_node)) { m_type = m_ctx.datatype(config); } + + PC_tree_t deflate_node = PC_get(config, ".deflate"); + if (!PC_status(deflate_node)) { + m_deflate = deflate_node; // overwrite file_deflate level by variable deflate + } + + PC_tree_t chunking_node = PC_get(config, ".chunking"); + if (!PC_status(chunking_node)) { + m_chunking = chunking_node; + } } const std::string& Dnc_variable::path() const @@ -87,5 +98,14 @@ const std::vector& Dnc_variable::attributes() const return m_attributes; } +const PDI::Expression& Dnc_variable::deflate() const +{ + return m_deflate; +} + +const PDI::Expression& Dnc_variable::chunking() const +{ + return m_chunking; +} } // namespace decl_netcdf diff --git a/plugins/decl_netcdf/dnc_variable.h b/plugins/decl_netcdf/dnc_variable.h index 18307d277..360f57050 100644 --- a/plugins/decl_netcdf/dnc_variable.h +++ b/plugins/decl_netcdf/dnc_variable.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -56,13 +56,20 @@ class Dnc_variable /// Attributes of the variable std::vector m_attributes; + /// Compression level of this variable + PDI::Expression m_deflate; + + /// Chunking property set from yaml + PDI::Expression m_chunking; + public: /** Creates NetCDF variable information from yaml * * \param ctx Context of this variable * \param config Configuration node of this variable + * \param deflate Deflate level of the file */ - Dnc_variable(PDI::Context& ctx, const std::string& path, PC_tree_t config); + Dnc_variable(PDI::Context& ctx, const std::string& path, PC_tree_t config, PDI::Expression deflate = PDI::Expression(0L)); /** Getter for variable name * @@ -93,6 +100,18 @@ class Dnc_variable * \return attributes of the variable */ const std::vector& attributes() const; + + /** Getter for variable deflate level + * + * \return deflate level of the variable + */ + const PDI::Expression& deflate() const; + + /** Getter for variable chunk size + * + * \return chunk size of the variable + */ + const PDI::Expression& chunking() const; }; } // namespace decl_netcdf diff --git a/plugins/decl_netcdf/tests/CMakeLists.txt b/plugins/decl_netcdf/tests/CMakeLists.txt index 06296f4ba..5de3ac569 100644 --- a/plugins/decl_netcdf/tests/CMakeLists.txt +++ b/plugins/decl_netcdf/tests/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2020-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) # All rights reserved. # @@ -24,11 +24,11 @@ #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) if(NOT TARGET GTest::gtest) option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" OFF) - add_subdirectory("../../../vendor/googletest-b4aaf97/" "googletest" EXCLUDE_FROM_ALL) + add_subdirectory("../../../vendor/googletest-56efe39/" "googletest" EXCLUDE_FROM_ALL) endif() include(GoogleTest) @@ -50,14 +50,14 @@ endif() add_executable(decl_netcdf_tests decl_netcdf_tests.cxx) target_link_libraries(decl_netcdf_tests PDI::PDI_plugins Threads::Threads GTest::gtest GTest::gtest_main) -target_compile_features(decl_netcdf_tests PUBLIC cxx_std_17) +target_compile_features(decl_netcdf_tests PUBLIC cxx_std_20) gtest_discover_tests(decl_netcdf_tests) if("${BUILD_NETCDF_PARALLEL}") find_package(MPI REQUIRED COMPONENTS C) add_executable(netcdf_mpi_tests decl_netcdf_mpi_tests.c) target_link_libraries(netcdf_mpi_tests PDI::PDI_C MPI::MPI_C) - target_compile_features(netcdf_mpi_tests PUBLIC cxx_std_17) + target_compile_features(netcdf_mpi_tests PUBLIC cxx_std_20) add_test(NAME netcdf_mpi_tests COMMAND "${RUNTEST_DIR}" "${MPIEXEC}" "${MPIEXEC_NUMPROC_FLAG}" 4 ${MPIEXEC_PREFLAGS} "$" ${MPIEXEC_POSTFLAGS}) set_property(TEST netcdf_mpi_tests PROPERTY TIMEOUT 15) set_property(TEST netcdf_mpi_tests PROPERTY PROCESSORS 4) @@ -65,12 +65,12 @@ endif() add_executable(decl_netcdf_08_C decl_netcdf_test_08.c) target_link_libraries(decl_netcdf_08_C PDI::PDI_C) -target_compile_features(decl_netcdf_08_C PUBLIC cxx_std_17) +target_compile_features(decl_netcdf_08_C PUBLIC cxx_std_20) add_test(NAME decl_netcdf_08_C COMMAND "${RUNTEST_DIR}" "$" "${CMAKE_CURRENT_SOURCE_DIR}/decl_netcdf_test_08.yml") set_property(TEST decl_netcdf_08_C PROPERTY TIMEOUT 15) add_executable(decl_netcdf_09_C decl_netcdf_test_09.c) target_link_libraries(decl_netcdf_09_C PDI::PDI_C) -target_compile_features(decl_netcdf_09_C PUBLIC cxx_std_17) +target_compile_features(decl_netcdf_09_C PUBLIC cxx_std_20) add_test(NAME decl_netcdf_09_C COMMAND "${RUNTEST_DIR}" "$" "${CMAKE_CURRENT_SOURCE_DIR}/decl_netcdf_test_09.yml") set_property(TEST decl_netcdf_09_C PROPERTY TIMEOUT 15) diff --git a/plugins/decl_netcdf/tests/decl_netcdf_tests.cxx b/plugins/decl_netcdf/tests/decl_netcdf_tests.cxx index e77246f19..b796069b7 100644 --- a/plugins/decl_netcdf/tests/decl_netcdf_tests.cxx +++ b/plugins/decl_netcdf/tests/decl_netcdf_tests.cxx @@ -1,6 +1,6 @@ /******************************************************************************* * Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) - * Copyright (C) 2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2024-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -680,7 +680,7 @@ TEST(decl_netcdf_test, 06) " \n" "plugins: \n" " decl_netcdf: \n" - " - file: 'test_07.nc' \n" + " - file: 'test_06.nc' \n" " on_event: 'write' \n" " variables: \n" " int_matrix_var: \n" @@ -694,7 +694,7 @@ TEST(decl_netcdf_test, 06) " variable_selection: \n" " start: ['$iter', 0, 0] \n" " subsize: [1, 8, 8] \n" - " - file: 'test_07.nc' \n" + " - file: 'test_06.nc' \n" " on_event: 'read' \n" " variables: \n" " int_matrix_var: \n" @@ -739,6 +739,48 @@ TEST(decl_netcdf_test, 06) PDI_finalize(); } +/* + * Name: decl_netcdf_test.07 + * + * Description: Tests yaml syntaxe with `write: data` + */ +TEST(decl_netcdf_test, 07) +{ + const char* CONFIG_YAML + = "logging: trace \n" + "data: \n" + " int_matrix: \n" + " type: array \n" + " subtype: int \n" + " size: [8, 8] \n" + " \n" + "plugins: \n" + " decl_netcdf: \n" + " - file: 'test_07.nc' \n" + " on_event: 'write' \n" + " write: int_matrix \n"; + + // Use the null error handle explicitly. Otherwise, the error is not captured. + // Need further investigation + PDI_errhandler(PDI_NULL_HANDLER); + + ASSERT_EQ(PDI_OK, PDI_init(PC_parse_string(CONFIG_YAML))); + + int int_matrix[8][8]; + + // init data + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 8; j++) { + int_matrix[i][j] = 100 + i * 8 + j; + } + } + + // write data + ASSERT_EQ(PDI_OK, PDI_multi_expose("write", "int_matrix", int_matrix, PDI_OUT, NULL)); + + PDI_finalize(); +} + /* * Name: decl_netcdf_test.size_of * @@ -808,3 +850,263 @@ TEST(decl_netcdf_test, size_of) PDI_finalize(); } + +/* + * Name: decl_netcdf_test.defalte + * + * Description: Tests simple write and read of compressed variables +*/ +TEST(decl_netcdf_test, deflate) +{ + constexpr char CONFIG_YAML[] = R"( + logging: trace + metadata: + pb_size: int + input: int + chunk: int + data: + int_scalar: int + int_array: {type: array, subtype: int, size: $pb_size} + int_matrix: + type: array + subtype: int + size: ['$pb_size', '$pb_size'] + plugins: + decl_netcdf: + - file: 'test_deflate_0.nc' + variables: + int_scalar: int + int_array: + type: array + subtype: int + size: $pb_size + dimensions: ['time'] + int_matrix: + type: array + subtype: int + size: ['$pb_size', '$pb_size'] + dimensions: ['col', 'row'] + when: '${input}=0' + write: [int_scalar, int_array, int_matrix] + - file: 'test_deflate_6.nc' + variables: + int_scalar: int + int_array: + type: array + subtype: int + size: $pb_size + dimensions: ['time'] + deflate: 6 + int_matrix: + type: array + subtype: int + size: ['$pb_size', '$pb_size'] + dimensions: ['col', 'row'] + deflate: 6 + when: '${input}=0' + write: [int_scalar, int_array, int_matrix] + - file: 'test_deflate_9.nc' + deflate: 9 + variables: + int_scalar: int + int_array: + type: array + subtype: int + size: $pb_size + dimensions: ['time'] + chunking: $chunk + int_matrix: + type: array + subtype: int + size: ['$pb_size', '$pb_size'] + dimensions: ['col', 'row'] + chunking: ['$chunk', '$chunk'] + when: '${input}=0' + write: [int_scalar, int_array, int_matrix] + - file: 'test_deflate_mix.nc' + deflate: 6 + variables: + int_scalar: int + int_array: + type: array + subtype: int + size: $pb_size + dimensions: ['time'] + deflate: 9 + chunking: $chunk + int_matrix: + type: array + subtype: int + size: ['$pb_size', '$pb_size'] + dimensions: ['col', 'row'] + chunking: ['$chunk', '$chunk'] + when: '${input}=0' + write: [int_scalar, int_array, int_matrix] + - file: 'test_deflate_6.nc' + when: '${input}=1' + read: [int_scalar, int_array, int_matrix] + )"; + + PDI_init(PC_parse_string(CONFIG_YAML)); + + // init data + int input = 0; + int int_scalar = 42; + int N = 1000; + int chunk = 1000; + int* int_array = new int[N]; + int* int_matrix = new int[N * N]; + + // write data + for (int i = 0; i < N; i++) { + int_array[i] = i; + } + + for (int i = 0; i < N * N; i++) { + int_matrix[i] = i; + } + + PDI_expose("input", &input, PDI_OUT); + PDI_expose("pb_size", &N, PDI_OUT); + PDI_expose("chunk", &chunk, PDI_OUT); + + PDI_expose("int_scalar", &int_scalar, PDI_OUT); + PDI_expose("int_array", int_array, PDI_OUT); + PDI_expose("int_matrix", int_matrix, PDI_OUT); + + // check the deflate level of output files + int result; + result = std::system("which ncdump > /dev/null 2>&1"); + // check the deflate level only if ncdump is available + if (result == 0) { + result = std::system("ncdump -hs test_deflate_6.nc | grep -q '_DeflateLevel = 6'"); + EXPECT_EQ(result, 0) << "Deflate level for test_deflate_6.nc is not 6"; + result = std::system("ncdump -hs test_deflate_9.nc | grep -q '_DeflateLevel = 9'"); + EXPECT_EQ(result, 0) << "Deflate level for test_deflate_9.nc is not 9"; + result = std::system("ncdump -hs test_deflate_mix.nc | grep -q 'int_array:_DeflateLevel = 9'"); + EXPECT_EQ(result, 0) << "Deflate level of int_array in test_deflate_mix.nc is not 9"; + result = std::system("ncdump -hs test_deflate_mix.nc | grep -q 'int_matrix:_DeflateLevel = 6'"); + EXPECT_EQ(result, 0) << "Deflate level of int_matrix in test_deflate_mix.nc is not 6"; + } + + + // read data + input = 1; + int_scalar = 0; + for (int i = 0; i < N; i++) { + int_array[i] = 0; + } + for (int i = 0; i < N * N; i++) { + int_matrix[i] = 0; + } + + PDI_expose("input", &input, PDI_OUT); + + PDI_expose("int_scalar", &int_scalar, PDI_IN); + PDI_expose("int_array", int_array, PDI_IN); + PDI_expose("int_matrix", int_matrix, PDI_IN); + + // verify + ASSERT_EQ(int_scalar, 42); + + for (int i = 0; i < N; i++) { + ASSERT_EQ(int_array[i], i); + } + + for (int i = 0; i < N * N; i++) { + ASSERT_EQ(int_matrix[i], i); + } + + delete[] int_array; + delete[] int_matrix; + + PDI_finalize(); +} + +/* + * Name: decl_netcdf_test.read + * + * Description: Tests write and read of int with type mismatch + */ +TEST(decl_netcdf_test, int_read) +{ + constexpr char CONFIG_YAML[] = R"( + logging: trace + data: + int_in: int32 + int_out: int64 + plugins: + decl_netcdf: + - file: 'test_int_read.nc' + variable: + scalar_int32: int32 + on_event: write_data + write: + int_in: + variable: scalar_int32 + - file: 'test_int_read.nc' + variable: + scalar_int32: int32 + on_event: read_data + read: + int_out: + variable: + scalar_int32 + )"; + + PDI_init(PC_parse_string(CONFIG_YAML)); + PDI_errhandler(PDI_NULL_HANDLER); + + // write data + int32_t int_in = 42; + PDI_multi_expose("write_data", "int_in", &int_in, PDI_OUT, NULL); + + // read data + int64_t int_out = -1; + EXPECT_NE(PDI_OK, PDI_multi_expose("read_data", "int_out", &int_out, PDI_IN, NULL)); + PDI_finalize(); +} + +/* + * Name: decl_netcdf_test.read + * + * Description: Tests write and read of float/double with type mismatch + */ +TEST(decl_netcdf_test, float_read) +{ + constexpr char CONFIG_YAML[] = R"( + logging: trace + data: + var_in: float + var_out: double + plugins: + decl_netcdf: + - file: 'test_float_read.nc' + variable: + nc_var: float + on_event: write_data + write: + var_in: + variable: nc_var + - file: 'test_float_read.nc' + variable: + nc_var: float + on_event: read_data + read: + var_out: + variable: nc_var + )"; + + PDI_init(PC_parse_string(CONFIG_YAML)); + PDI_errhandler(PDI_NULL_HANDLER); + + // write data + float var_in = 12.34; + PDI_multi_expose("write_data", "var_in", &var_in, PDI_OUT, NULL); + + // read data + double var_out = -1.0; + EXPECT_NE(PDI_OK, PDI_multi_expose("read_data", "var_out", &var_out, PDI_IN, NULL)); + + PDI_finalize(); +} diff --git a/plugins/deisa/AUTHORS b/plugins/deisa/AUTHORS deleted file mode 100644 index 160217a5a..000000000 --- a/plugins/deisa/AUTHORS +++ /dev/null @@ -1,18 +0,0 @@ -Multiple people have contributed to the PDI Deisa plugin. To show our -appreciation for their public spirit, we list here in alphabetical order a -condensed list of their contributions. - - -Julien Bigot - CEA (julien.bigot@cea.fr) -* Supervision of the initial design -* Minor CMake improvements - -Amal Gueroudji - CEA (amal.gueroudji@cea.fr) -* Initial design - -Benoit Martin - CEA (bmartin@cea.fr) -* Major initial cleanup -* Maintainer - -Bruno Raffin - Inria (bruno.raffin@inria.fr) -* Supervision of the initial design diff --git a/plugins/deisa/CHANGELOG.md b/plugins/deisa/CHANGELOG.md deleted file mode 100644 index 05d896c8b..000000000 --- a/plugins/deisa/CHANGELOG.md +++ /dev/null @@ -1,40 +0,0 @@ -# Changelog for PDI Deisa plugin -All notable changes to the Deisa plugin will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - - -## [Unreleased] - -### Added - -### Changed - -### Deprecated - -### Removed - -### Fixed - -### Security - - -## [1.8.3] - 2025-02-25 - -#### Fixed -* Fixed a bug where the plugin would not call the bridge's release method. - [#534](https://github.com/pdidev/pdi/issues/534) - - -## [1.8.1] - 2025-01-23 - -### Fixed -* Fixed a bug where the plugin would send an incorrect array name to Deisa - `publish_data` [#512](https://github.com/pdidev/pdi/issues/512) -* Stop claiming to support old cmake versions we do not - [#507](https://github.com/pdidev/pdi/issues/507) - - -## [1.8.0] - 2024-11-28 - -Initial release diff --git a/plugins/deisa/CMakeLists.txt b/plugins/deisa/CMakeLists.txt deleted file mode 100644 index b6d720267..000000000 --- a/plugins/deisa/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -#============================================================================= -# Copyright (c) 2020-2025 Centre national de la recherche scientifique (CNRS) -# Copyright (c) 2020-2025 Commissariat a l'énergie atomique et aux énergies alternatives (CEA) -# Copyright (c) 2020-2023 Institut national de recherche en informatique et en automatique (Inria) -# Copyright (c) 2020-2025 Université Paris-Saclay -# Copyright (c) 2020-2025 Université de Versailles Saint-Quentin-en-Yvelines -# -# SPDX-License-Identifier: MIT -#============================================================================= - -cmake_minimum_required(VERSION 3.16...3.29) -project(pdi_deisa_plugin LANGUAGES C CXX) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") - -include(GNUInstallDirs) - -find_package(Python3 3.8.2 REQUIRED COMPONENTS Interpreter Development) - -# PyBind11 -set(Python_ADDITIONAL_VERSIONS "${Python3_VERSION}" CACHE STRING "Python version found by FindPython3 for coherency" FORCE) -set(PYBIND11_PYTHON_VERSION "${Python3_VERSION}" CACHE STRING "Python version to use for compiling modules" FORCE) -find_package(pybind11 2.4.3 REQUIRED) - -# PDI -find_package(PDI REQUIRED COMPONENTS plugins pysupport) -find_package(MPI REQUIRED COMPONENTS CXX) - -# The plugin -add_library(pdi_deisa_plugin MODULE deisa.cxx) -target_link_libraries(pdi_deisa_plugin PUBLIC PDI::PDI_plugins PDI::PDI_pysupport pybind11::embed MPI::MPI_CXX) -set_target_properties(pdi_deisa_plugin PROPERTIES - CXX_STANDARD_REQUIRED TRUE - CXX_VISIBILITY_PRESET hidden) - -# installation -set(INSTALL_PDIPLUGINDIR "${PDI_DEFAULT_PLUGINDIR}" CACHE PATH "PDI plugins (${PDI_DEFAULT_PLUGINDIR})") -install(TARGETS pdi_deisa_plugin - LIBRARY DESTINATION "${INSTALL_PDIPLUGINDIR}" -) diff --git a/plugins/deisa/README.md b/plugins/deisa/README.md deleted file mode 100644 index 74d0b64c3..000000000 --- a/plugins/deisa/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# The DEISA plugin {#deisa_plugin} - -**WARNING** This documentation is a work in progress and does not reflect the full DEISA plugin potential. - -The DEISA plugin is used to expose data to [Dask](https://www.dask.org/). -This mechanism decouples analytics code from simulation code by providing an asynchronous pipeline for analytics. - -The DEISA plugin uses the following configuration: -- `scheduler_info`: File name defined by the dask scheduler. This file contains information on how to connect to the dask cluster. -- `init_on`: Name of the PDI event called after sharing all metadata. -- `time_step`: Timestep variable. -- `deisa_arrays`: List of Deisa virtual arrays. - - `type`: Type of the Deisa array. Usually: `array`. - - `subtype`: Type stored in the `Deisa array. - - `size`: Size of the Deisa array. - - `subsize`: How the Deisa array is chunked. In other words, the size of each chunk. - - `start`: How to find the start of each chunk. - - `+timedim`: Define where the time dimension is. Currently, only dimension 0 is supported. -- `map_in`: Define how a local data is mapped to a Deisa array. - - ---- - - -# Example: A 2D MPI space with ghost cells. - -```yaml -metadata: - nx: int # Domain size per proc - ny: int # Domain size per proc - mpi_max_coords_x: int # MPI decomposition - mpi_max_coords_y: int # MPI decomposition - mpi_coords_x: int # MPI coordinate of the current process - mpi_coords_y: int # MPI coordinate of the current process - nstep: int # Time step - max_iterations: int # max number of iterations -data: - main_field: { size: [ '$nx+2', '$ny+2' ], type: array, subtype: double } # Field of the current subdomain. +2 for ghost cells. -plugins: - mpi: - deisa: - scheduler_info: scheduler.json - init_on: init_PDI - time_step: $nstep - deisa_arrays: - global_t: # Name of the Deisa array - type: array - subtype: double - size: [$max_iterations, '($nx+2)*$mpi_max_coords_x', '($ny+2)*$mpi_max_coords_y'] # first dimension corresponds to time steps - subsize: [1, '$nx+2', '$ny+2'] - start: [$nstep, '$mpi_coords_x*($nx+2)', '$mpi_coords_y*($ny+2)'] - +timedim: 0 - map_in: - main_field: global_t # `main_field` is mapped to `global_t` -``` diff --git a/plugins/deisa/cmake/FindPackageHandleStandardArgs.cmake b/plugins/deisa/cmake/FindPackageHandleStandardArgs.cmake deleted file mode 100644 index 67f6bd6f2..000000000 --- a/plugins/deisa/cmake/FindPackageHandleStandardArgs.cmake +++ /dev/null @@ -1,386 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPackageHandleStandardArgs ------------------------------ - -This module provides a function intended to be used in :ref:`Find Modules` -implementing :command:`find_package()` calls. It handles the -``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. -It also sets the ``_FOUND`` variable. The package is -considered found if all variables listed contain valid results, e.g. -valid filepaths. - -.. command:: find_package_handle_standard_args - - There are two signatures:: - - find_package_handle_standard_args( - (DEFAULT_MSG|) - ... - ) - - find_package_handle_standard_args( - [FOUND_VAR ] - [REQUIRED_VARS ...] - [VERSION_VAR ] - [HANDLE_COMPONENTS] - [CONFIG_MODE] - [FAIL_MESSAGE ] - ) - - The ``_FOUND`` variable will be set to ``TRUE`` if all - the variables ``...`` are valid and any optional - constraints are satisfied, and ``FALSE`` otherwise. A success or - failure message may be displayed based on the results and on - whether the ``REQUIRED`` and/or ``QUIET`` option was given to - the :command:`find_package` call. - - The options are: - - ``(DEFAULT_MSG|)`` - In the simple signature this specifies the failure message. - Use ``DEFAULT_MSG`` to ask for a default message to be computed - (recommended). Not valid in the full signature. - - ``FOUND_VAR `` - Obsolete. Specifies either ``_FOUND`` or - ``_FOUND`` as the result variable. This exists only - for compatibility with older versions of CMake and is now ignored. - Result variables of both names are always set for compatibility. - - ``REQUIRED_VARS ...`` - Specify the variables which are required for this package. - These may be named in the generated failure message asking the - user to set the missing variable values. Therefore these should - typically be cache entries such as ``FOO_LIBRARY`` and not output - variables like ``FOO_LIBRARIES``. - - ``VERSION_VAR `` - Specify the name of a variable that holds the version of the package - that has been found. This version will be checked against the - (potentially) specified required version given to the - :command:`find_package` call, including its ``EXACT`` option. - The default messages include information about the required - version and the version which has been actually found, both - if the version is ok or not. - - ``HANDLE_COMPONENTS`` - Enable handling of package components. In this case, the command - will report which components have been found and which are missing, - and the ``_FOUND`` variable will be set to ``FALSE`` - if any of the required components (i.e. not the ones listed after - the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are - missing. - - ``CONFIG_MODE`` - Specify that the calling find module is a wrapper around a - call to ``find_package( NO_MODULE)``. This implies - a ``VERSION_VAR`` value of ``_VERSION``. The command - will automatically check whether the package configuration file - was found. - - ``FAIL_MESSAGE `` - Specify a custom failure message instead of using the default - generated message. Not recommended. - -Example for the simple signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibXml2 DEFAULT_MSG - LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) - -The ``LibXml2`` package is considered to be found if both -``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. -Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found -and ``REQUIRED`` was used, it fails with a -:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was -used or not. If it is found, success will be reported, including -the content of the first ````. On repeated CMake runs, -the same message will not be printed again. - -Example for the full signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibArchive - REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR - VERSION_VAR LibArchive_VERSION) - -In this case, the ``LibArchive`` package is considered to be found if -both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. -Also the version of ``LibArchive`` will be checked by using the version -contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, -the default messages will be printed. - -Another example for the full signature: - -.. code-block:: cmake - - find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) - find_package_handle_standard_args(Automoc4 CONFIG_MODE) - -In this case, a ``FindAutmoc4.cmake`` module wraps a call to -``find_package(Automoc4 NO_MODULE)`` and adds an additional search -directory for ``automoc4``. Then the call to -``find_package_handle_standard_args`` produces a proper success/failure -message. -#]=======================================================================] - -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - -# internal helper macro -macro(_FPHSA_FAILURE_MESSAGE _msg) - if (${_NAME}_FIND_REQUIRED) - message(FATAL_ERROR "${_msg}") - else () - if (NOT ${_NAME}_FIND_QUIETLY) - message(STATUS "${_msg}") - endif () - endif () -endmacro() - - -# internal helper macro to generate the failure message when used in CONFIG_MODE: -macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: - if(${_NAME}_CONFIG) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") - else() - # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. - # List them all in the error message: - if(${_NAME}_CONSIDERED_CONFIGS) - set(configsText "") - list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) - math(EXPR configsCount "${configsCount} - 1") - foreach(currentConfigIndex RANGE ${configsCount}) - list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) - list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) - string(APPEND configsText " ${filename} (version ${version})\n") - endforeach() - if (${_NAME}_NOT_FOUND_MESSAGE) - string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") - endif() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") - - else() - # Simple case: No Config-file was found at all: - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") - endif() - endif() -endmacro() - - -function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) - -# Set up the arguments for `cmake_parse_arguments`. - set(options CONFIG_MODE HANDLE_COMPONENTS) - set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) - set(multiValueArgs REQUIRED_VARS) - -# Check whether we are in 'simple' or 'extended' mode: - set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) - list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) - - if(${INDEX} EQUAL -1) - set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) - set(FPHSA_REQUIRED_VARS ${ARGN}) - set(FPHSA_VERSION_VAR) - else() - cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) - - if(FPHSA_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") - endif() - - if(NOT FPHSA_FAIL_MESSAGE) - set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") - endif() - - # In config-mode, we rely on the variable _CONFIG, which is set by find_package() - # when it successfully found the config-file, including version checking: - if(FPHSA_CONFIG_MODE) - list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) - list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) - set(FPHSA_VERSION_VAR ${_NAME}_VERSION) - endif() - - if(NOT FPHSA_REQUIRED_VARS) - message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") - endif() - endif() - -# now that we collected all arguments, process them - - if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") - set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") - endif() - - list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) - - string(TOUPPER ${_NAME} _NAME_UPPER) - string(TOLOWER ${_NAME} _NAME_LOWER) - - if(FPHSA_FOUND_VAR) - if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") - set(_FOUND_VAR ${FPHSA_FOUND_VAR}) - else() - message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") - endif() - else() - set(_FOUND_VAR ${_NAME_UPPER}_FOUND) - endif() - - # collect all variables which were not found, so they can be printed, so the - # user knows better what went wrong (#6375) - set(MISSING_VARS "") - set(DETAILS "") - # check if all passed variables are valid - set(FPHSA_FOUND_${_NAME} TRUE) - foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) - if(NOT ${_CURRENT_VAR}) - set(FPHSA_FOUND_${_NAME} FALSE) - string(APPEND MISSING_VARS " ${_CURRENT_VAR}") - else() - string(APPEND DETAILS "[${${_CURRENT_VAR}}]") - endif() - endforeach() - if(FPHSA_FOUND_${_NAME}) - set(${_NAME}_FOUND TRUE) - set(${_NAME_UPPER}_FOUND TRUE) - else() - set(${_NAME}_FOUND FALSE) - set(${_NAME_UPPER}_FOUND FALSE) - endif() - - # component handling - unset(FOUND_COMPONENTS_MSG) - unset(MISSING_COMPONENTS_MSG) - - if(FPHSA_HANDLE_COMPONENTS) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(${_NAME}_${comp}_FOUND) - - if(NOT DEFINED FOUND_COMPONENTS_MSG) - set(FOUND_COMPONENTS_MSG "found components: ") - endif() - string(APPEND FOUND_COMPONENTS_MSG " ${comp}") - - else() - - if(NOT DEFINED MISSING_COMPONENTS_MSG) - set(MISSING_COMPONENTS_MSG "missing components: ") - endif() - string(APPEND MISSING_COMPONENTS_MSG " ${comp}") - - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - string(APPEND MISSING_VARS " ${comp}") - endif() - - endif() - endforeach() - set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") - string(APPEND DETAILS "[c${COMPONENT_MSG}]") - endif() - - # version handling: - set(VERSION_MSG "") - set(VERSION_OK TRUE) - - # check with DEFINED here as the requested or found version may be "0" - if (DEFINED ${_NAME}_FIND_VERSION) - if(DEFINED ${FPHSA_VERSION_VAR}) - set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) - - if(${_NAME}_FIND_VERSION_EXACT) # exact version required - # count the dots in the version string - string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}") - # add one dot because there is one dot more than there are components - string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) - if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) - # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT - # is at most 4 here. Therefore a simple lookup table is used. - if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) - set(_VERSION_REGEX "[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) - set(_VERSION_REGEX "[^.]*\\.[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") - else () - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") - endif () - string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}") - unset(_VERSION_REGEX) - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - unset(_VERSION_HEAD) - else () - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - endif () - unset(_VERSION_DOTS) - - else() # minimum version specified: - if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") - endif () - endif() - - else() - - # if the package was not found, but a version was given, add that to the output: - if(${_NAME}_FIND_VERSION_EXACT) - set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") - else() - set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") - endif() - - endif() - else () - # Check with DEFINED as the found version may be 0. - if(DEFINED ${FPHSA_VERSION_VAR}) - set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") - endif() - endif () - - if(VERSION_OK) - string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") - else() - set(${_NAME}_FOUND FALSE) - endif() - - - # print the result: - if (${_NAME}_FOUND) - FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") - else () - - if(FPHSA_CONFIG_MODE) - _FPHSA_HANDLE_FAILURE_CONFIG_MODE() - else() - if(NOT VERSION_OK) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") - else() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") - endif() - endif() - - endif () - - set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) - set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) -endfunction() diff --git a/plugins/deisa/cmake/FindPackageMessage.cmake b/plugins/deisa/cmake/FindPackageMessage.cmake deleted file mode 100644 index 6821cee4f..000000000 --- a/plugins/deisa/cmake/FindPackageMessage.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# FindPackageMessage -# ------------------ -# -# -# -# FIND_PACKAGE_MESSAGE( "message for user" "find result details") -# -# This macro is intended to be used in FindXXX.cmake modules files. It -# will print a message once for each unique find result. This is useful -# for telling the user where a package was found. The first argument -# specifies the name (XXX) of the package. The second argument -# specifies the message to display. The third argument lists details -# about the find result so that if they change the message will be -# displayed again. The macro also obeys the QUIET argument to the -# find_package command. -# -# Example: -# -# :: -# -# if(X11_FOUND) -# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" -# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") -# else() -# ... -# endif() - -function(FIND_PACKAGE_MESSAGE pkg msg details) - # Avoid printing a message repeatedly for the same find result. - if(NOT ${pkg}_FIND_QUIETLY) - string(REPLACE "\n" "" details "${details}") - set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) - if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - # The message has not yet been printed. - message(STATUS "${msg}") - - # Save the find details in the cache to avoid printing the same - # message again. - set("${DETAILS_VAR}" "${details}" - CACHE INTERNAL "Details about finding ${pkg}") - endif() - endif() -endfunction() diff --git a/plugins/deisa/cmake/FindPython/Support.cmake b/plugins/deisa/cmake/FindPython/Support.cmake deleted file mode 100644 index 209231919..000000000 --- a/plugins/deisa/cmake/FindPython/Support.cmake +++ /dev/null @@ -1,1244 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -# -# This file is a "template" file used by various FindPython modules. -# - -cmake_policy (VERSION 3.16...3.25) - -# -# Initial configuration -# -if (NOT DEFINED _PYTHON_PREFIX) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 3) - set(_${_PYTHON_PREFIX}_VERSIONS 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0) -elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 2) - set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) -else() - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() - - -# -# helper commands -# -macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG) - if (${_PYTHON_PREFIX}_FIND_REQUIRED) - message (FATAL_ERROR "${_PYTHON_MSG}") - else() - if (NOT ${_PYTHON_PREFIX}_FIND_QUIETLY) - message(STATUS "${_PYTHON_MSG}") - endif () - endif() - - set (${_PYTHON_PREFIX}_FOUND FALSE) - string (TOUPPER "${_PYTHON_PREFIX}" _${_PYTHON_PREFIX}_UPPER_PREFIX) - set (${_PYTHON_UPPER_PREFIX}_FOUND FALSE) - return() -endmacro() - - -macro (_PYTHON_FIND_FRAMEWORKS) - set (${_PYTHON_PREFIX}_FRAMEWORKS) - if (APPLE) - set (_pff_frameworks ${CMAKE_FRAMEWORK_PATH} - $ENV{CMAKE_FRAMEWORK_PATH} - ~/Library/Frameworks - /usr/local/Frameworks - ${CMAKE_SYSTEM_FRAMEWORK_PATH}) - list (REMOVE_DUPLICATES _pff_frameworks) - foreach (_pff_framework IN LISTS _pff_frameworks) - if (EXISTS ${_pff_framework}/Python.framework) - list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python.framework) - endif() - endforeach() - unset (_pff_frameworks) - unset (_pff_framework) - endif() -endmacro() - -function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION) - set (_PYTHON_FRAMEWORK_PATHS) - foreach (_PYTHON_FRAMEWORK IN LISTS ${_PYTHON_PREFIX}_FRAMEWORKS) - list (APPEND _PYTHON_FRAMEWORK_PATHS - "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}") - endforeach() - set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${_PYTHON_FRAMEWORK_PATHS} PARENT_SCOPE) -endfunction() - - -function (_PYTHON_VALIDATE_INTERPRETER) - if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) - return() - endif() - - if (ARGC EQUAL 1) - set (expected_version ${ARGV0}) - else() - unset (expected_version) - endif() - - get_filename_component (python_name "${${_PYTHON_PREFIX}_EXECUTABLE}" NAME) - - if (expected_version AND NOT python_name STREQUAL "python${expected_version}${CMAKE_EXECUTABLE_SUFFIX}") - # executable found must have a specific version - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL expected_version) - # interpreter not usable or has wrong major version - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - else() - if (NOT python_name STREQUAL "python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}${CMAKE_EXECUTABLE_SUFFIX}") - # executable found do not have version in name - # ensure major version is OK - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write(str(sys.version_info[0]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - # interpreter not usable or has wrong major version - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - endif() - endif() - - if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND NOT CMAKE_CROSSCOMPILING) - # In this case, interpreter must have same architecture as environment - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))" - RESULT_VARIABLE result - OUTPUT_VARIABLE size - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P) - # interpreter not usable or has wrong architecture - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - endif() -endfunction() - - -function (_PYTHON_VALIDATE_COMPILER expected_version) - if (NOT ${_PYTHON_PREFIX}_COMPILER) - return() - endif() - - # retrieve python environment version from compiler - set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))\n") - execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${working_dir}/version.py" - WORKING_DIRECTORY "${working_dir}" - OUTPUT_QUIET - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process (COMMAND "${working_dir}/version" - WORKING_DIRECTORY "${working_dir}" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET) - file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") - - if (result OR NOT version EQUAL expected_version) - # Compiler not usable or has wrong major version - set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) - endif() -endfunction() - - -function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB) - string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}") - # look at runtime part on systems supporting it - if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR - (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN" - AND ${_PYTHON_LIB} MATCHES "${CMAKE_IMPORT_LIBRARY_SUFFIX}$")) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) - # MSYS has a special syntax for runtime libraries - if (CMAKE_SYSTEM_NAME MATCHES "MSYS") - list (APPEND CMAKE_FIND_LIBRARY_PREFIXES "msys-") - endif() - find_library (${ARGV}) - endif() -endfunction() - - -function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT) - unset (_PYTHON_DIRS) - set (_PYTHON_LIBS ${ARGV}) - list (REMOVE_AT _PYTHON_LIBS 0) - foreach (_PYTHON_LIB IN LISTS _PYTHON_LIBS) - if (${_PYTHON_LIB}) - get_filename_component (_PYTHON_DIR "${${_PYTHON_LIB}}" DIRECTORY) - list (APPEND _PYTHON_DIRS "${_PYTHON_DIR}") - endif() - endforeach() - if (_PYTHON_DIRS) - list (REMOVE_DUPLICATES _PYTHON_DIRS) - endif() - set (${_PYTHON_SLD_RESULT} ${_PYTHON_DIRS} PARENT_SCOPE) -endfunction() - - -# If major version is specified, it must be the same as internal major version -if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR - AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") -endif() - - -# handle components -if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_FIND_COMPONENTS Interpreter) - set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE) -endif() -foreach (_${_PYTHON_PREFIX}_COMPONENT IN LISTS ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE) -endforeach() -unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - -# Set versions to search -## default: search any version -set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS}) - -if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER 1) - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}) - else() - unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - # add all compatible versions - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS) - if (${_PYTHON_PREFIX}_FIND_VERSION VERSION_LESS _${_PYTHON_PREFIX}_VERSION) - list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION}) - endif() - endforeach() - endif() -endif() - -# Anaconda distribution: define which architectures can be used -if (CMAKE_SIZEOF_VOID_P) - # In this case, search only for 64bit or 32bit - math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH}) -else() - # architecture unknown, search for both 64bit and 32bit - set (_${_PYTHON_PREFIX}_ARCH 64) - set (_${_PYTHON_PREFIX}_ARCH2 32) -endif() - -# IronPython support -if (CMAKE_SIZEOF_VOID_P) - # In this case, search only for 64bit or 32bit - math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy${_${_PYTHON_PREFIX}_ARCH} ipy) -else() - # architecture unknown, search for natural interpreter - set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy) -endif() -set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40) - -# Apple frameworks handling -_python_find_frameworks () - -# Save CMAKE_FIND_APPBUNDLE -if (DEFINED CMAKE_FIND_APPBUNDLE) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE}) -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -endif() -# To avoid app bundle lookup -set (CMAKE_FIND_APPBUNDLE "NEVER") - -# Save CMAKE_FIND_FRAMEWORK -if (DEFINED CMAKE_FIND_FRAMEWORK) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) - if (CMAKE_FIND_FRAMEWORK STREQUAL "ONLY") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: CMAKE_FIND_FRAMEWORK: 'ONLY' value is not supported. 'FIRST' will be used instead.") - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) - endif() -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") -endif() -# To avoid framework lookup -set (CMAKE_FIND_FRAMEWORK "NEVER") - -# Windows Registry handling -if (DEFINED ${_PYTHON_PREFIX}_FIND_REGISTRY) - if (NOT ${_PYTHON_PREFIX}_FIND_REGISTRY MATCHES "^(FIRST|LAST|NEVER)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_REGISTRY}: invalid value for '${_PYTHON_PREFIX}_FIND_REGISTRY'. 'FIRST', 'LAST' or 'NEVER' expected.") - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY ${${_PYTHON_PREFIX}_FIND_REGISTRY}) - endif() -else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") -endif() - - -unset (_${_PYTHON_PREFIX}_REQUIRED_VARS) -unset (_${_PYTHON_PREFIX}_CACHED_VARS) - - -# first step, search for the interpreter -if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) - endif() - - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - if (DEFINED ${_PYTHON_PREFIX}_EXECUTABLE AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_EXECUTABLE}") - set (_${_PYTHON_PREFIX}_EXECUTABLE "${${_PYTHON_PREFIX}_EXECUTABLE}" CACHE INTERNAL "") - elseif (DEFINED _${_PYTHON_PREFIX}_EXECUTABLE) - # check version validity - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) - else() - _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) - endif() - endif() - - if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) - # look-up for various versions and locations - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - - # Apple frameworks handling - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # Windows registry - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # try using HINTS - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) - - # Apple frameworks handling - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_DEFAULT_PATH) - endif() - - # Windows registry - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() - - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION}) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - endforeach() - endif() - - if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) - # No specific version found. Retry with generic names - # try using HINTS - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) - - _python_validate_interpreter () - endif() - - set (${_PYTHON_PREFIX}_EXECUTABLE "${_${_PYTHON_PREFIX}_EXECUTABLE}" CACHE FILEPATH "${_PYTHON_PREFIX} Interpreter") - - # retrieve exact version of executable found - if (${_PYTHON_PREFIX}_EXECUTABLE) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_VERSION - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 ${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 ${_PYTHON_PREFIX}_VERSION_PATCH) - else() - # Interpreter is not usable - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - unset (${_PYTHON_PREFIX}_VERSION) - endif() - endif() - - if (${_PYTHON_PREFIX}_EXECUTABLE - AND ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE) - # Use interpreter version for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - endif() - - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # retrieve interpreter identity - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -V - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID - ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID) - if (NOT _${_PYTHON_PREFIX}_RESULT) - if (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Anaconda") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda") - elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy") - else() - string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}") - if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python") - # try to get a more precise ID - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.copyright)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT - ERROR_QUIET) - if (${_PYTHON_PREFIX}_COPYRIGHT MATCHES "ActiveState") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "ActivePython") - endif() - endif() - endif() - else() - set (${_PYTHON_PREFIX}_INTERPRETER_ID Python) - endif() - else() - unset (${_PYTHON_PREFIX}_INTERPRETER_ID) - endif() - - # retrieve various package installation directories - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))" - - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 2 ${_PYTHON_PREFIX}_SITELIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 3 ${_PYTHON_PREFIX}_SITEARCH) - else() - unset (${_PYTHON_PREFIX}_STDLIB) - unset (${_PYTHON_PREFIX}_STDARCH) - unset (${_PYTHON_PREFIX}_SITELIB) - unset (${_PYTHON_PREFIX}_SITEARCH) - endif() - - mark_as_advanced (${_PYTHON_PREFIX}_EXECUTABLE) -endif() - - -# second step, search for compiler (IronPython) -if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_COMPILER) - endif() - - # IronPython specific artifacts - # If IronPython interpreter is found, use its path - unset (_${_PYTHON_PREFIX}_IRON_ROOT) - if (${_PYTHON_PREFIX}_Interpreter_FOUND AND ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - get_filename_component (_${_PYTHON_PREFIX}_IRON_ROOT "${${_PYTHON_PREFIX}_EXECUTABLE}" DIRECTORY) - endif() - - # try using root dir and registry - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() - - _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION}) - if (${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endforeach() - - # no specific version found, re-try in standard paths - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}) - - if (${_PYTHON_PREFIX}_COMPILER) - # retrieve python environment version from compiler - set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n") - execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - OUTPUT_QUIET - ERROR_QUIET) - execute_process (COMMAND "${_${_PYTHON_PREFIX}_VERSION_DIR}/version" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - else() - # compiler not usable - set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) - endif() - file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") - endif() - - if (${_PYTHON_PREFIX}_COMPILER) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # Compiler must be compatible with interpreter - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - # Use compiler version for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - endif() - endif() - - if (${_PYTHON_PREFIX}_Compiler_FOUND) - set (${_PYTHON_PREFIX}_COMPILER_ID IronPython) - else() - unset (${_PYTHON_PREFIX}_COMPILER_ID) - endif() - - mark_as_advanced (${_PYTHON_PREFIX}_COMPILER) -endif() - - -# third step, search for the development artifacts -## Development environment is not compatible with IronPython interpreter -if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_INCLUDE_DIR) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_INCLUDE_DIR) - endif() - - # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - if (DEFINED ${_PYTHON_PREFIX}_USE_STATIC_LIBS AND NOT WIN32) - set(_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(${_PYTHON_PREFIX}_USE_STATIC_LIBS) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - else() - list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - endif() - else() - endif() - - # if python interpreter is found, use its location and version to ensure consistency - # between interpreter and development environment - unset (_${_PYTHON_PREFIX}_PREFIX) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.PREFIX)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - unset (_${_PYTHON_PREFIX}_PREFIX) - endif() - endif() - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - # try to use pythonX.Y-config tool - set (_${_PYTHON_PREFIX}_CONFIG_NAMES) - if (DEFINED CMAKE_LIBRARY_ARCHITECTURE) - set (_${_PYTHON_PREFIX}_CONFIG_NAMES "${CMAKE_LIBRARY_ARCHITECTURE}-python${_${_PYTHON_PREFIX}_VERSION}-config") - endif() - list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES "python${_${_PYTHON_PREFIX}_VERSION}-config") - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - unset (_${_PYTHON_PREFIX}_CONFIG_NAMES) - - if (NOT _${_PYTHON_PREFIX}_CONFIG) - continue() - endif() - - # retrieve root install directory - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --prefix - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # python-config is not usable - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - continue() - endif() - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - # retrieve library - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - # retrieve library directory - string (REGEX MATCHALL "-L[^ ]+" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-L" "" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_LIB_DIRS}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_DIRS) - # retrieve library name - string (REGEX MATCHALL "-lpython[^ ]+" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-l" "" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_LIB_NAMES}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_NAMES) - - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} ${_${_PYTHON_PREFIX}_LIB_DIRS} - PATH_SUFFIXES lib - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # retrieve runtime library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_PATH} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - endif() - - # retrieve include directory - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --includes - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - # retrieve include directory - string (REGEX MATCHALL "-I[^ ]+" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-I" "" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIRS}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_DIRS) - - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - break() - endif() - endforeach() - - # Rely on HINTS and standard paths if config tool failed to locate artifacts - if (NOT (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) OR NOT ${_PYTHON_PREFIX}_INCLUDE_DIR) - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - - set (_${_PYTHON_PREFIX}_REGISTRY_PATHS - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # search in HINTS locations - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) - endif() - - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config) - # retrieve runtime library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - - if (WIN32) - # search for debug library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - # use library location as a hint - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - NO_DEFAULT_PATH) - else() - # search first in known locations - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs) - endif() - if (${_PYTHON_PREFIX}_LIBRARY_DEBUG) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - endif() - - # Don't search for include dir until library location is known - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) - - if (${_PYTHON_PREFIX}_EXECUTABLE) - # pick up include directory from configuration - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; import sysconfig; sys.stdout.write(sysconfig.get_path('include'))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PATH - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - file (TO_CMAKE_PATH "${_${_PYTHON_PREFIX}_PATH}" _${_PYTHON_PREFIX}_PATH) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PATH}") - endif() - endif() - - foreach (_${_PYTHON_PREFIX}_LIB IN ITEMS ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - if (${_${_PYTHON_PREFIX}_LIB}) - # Use the library's install prefix as a hint - if (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - else() - # assume library is in a directory under root - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${${_${_PYTHON_PREFIX}_LIB}}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") - endif() - endif() - endforeach() - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_HINTS) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - break() - endif() - endforeach() - - # search header file in standard locations - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h) - endif() - - if (${_PYTHON_PREFIX}_INCLUDE_DIR) - # retrieve version from header file - file (STRINGS "${${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" _${_PYTHON_PREFIX}_VERSION - REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") - string (REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" - _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_VERSION}") - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_Compiler_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - endif() - - # define public variables - include (${CMAKE_CURRENT_LIST_DIR}/../SelectLibraryConfigurations.cmake) - select_library_configurations (${_PYTHON_PREFIX}) - if (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - elseif (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - else() - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "$${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND") - endif() - - _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS - ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - if (UNIX) - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$") - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS}) - endif() - else() - _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - endif() - - set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${${_PYTHON_PREFIX}_INCLUDE_DIR}") - - mark_as_advanced (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_INCLUDE_DIR) - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND) - # development environment must be compatible with interpreter/compiler - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_Development_FOUND TRUE) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Development_FOUND TRUE) - endif() - endif() - - # Restore the original find library ordering - if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() -endif() - -# final validation -if (${_PYTHON_PREFIX}_VERSION_MAJOR AND - NOT ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") -endif() - -include (${CMAKE_CURRENT_LIST_DIR}/../FindPackageHandleStandardArgs.cmake) -find_package_handle_standard_args (${_PYTHON_PREFIX} - REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS} - VERSION_VAR ${_PYTHON_PREFIX}_VERSION - HANDLE_COMPONENTS) - -# Create imported targets and helper functions -if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Interpreter_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Interpreter) - add_executable (${_PYTHON_PREFIX}::Interpreter IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Interpreter - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_EXECUTABLE}") -endif() - -if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Compiler_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Compiler) - add_executable (${_PYTHON_PREFIX}::Compiler IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Compiler - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}") -endif() - -if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Development_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::Python) - - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED) - else() - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC) - endif() - - add_library (${_PYTHON_PREFIX}::Python ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED) - - set_property (TARGET ${_PYTHON_PREFIX}::Python - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}") - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - OR (${_PYTHON_PREFIX}_LIBRARY_DEBUG AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)) - # System manage shared libraries in two parts: import and runtime - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - else() - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARY}" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY}") - endif() - else() - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}") - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}") - else() - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY}") - endif() - endif() - - function(list_filter_exclude _list_name _value) - if(CMAKE_VERSION VERSION_LESS 3.12) - list(FIND ${_list_name} ${_value} _INDEX) - if(${_INDEX} GREATER -1) - list(REMOVE_AT ${_list_name} ${_INDEX}) - endif() - else() - list(FILTER ${_list_name} EXCLUDE REGEX ${_value}) - endif() - set(${_list_name} ${${_list_name}} PARENT_SCOPE) - endfunction() - - if (_${_PYTHON_PREFIX}_CONFIG AND _${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC") - # extend link information with dependent libraries - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "-[Ll][^ ]+" _${_PYTHON_PREFIX}_LINK_LIBRARIES "${_${_PYTHON_PREFIX}_FLAGS}") - # remove elements relative to python library itself - list_filter_exclude(_${_PYTHON_PREFIX}_LINK_LIBRARIES "-lpython") - #list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-lpython") - foreach (_${_PYTHON_PREFIX}_DIR IN LISTS ${_PYTHON_PREFIX}_LIBRARY_DIRS) - list_filter_exclude(_${_PYTHON_PREFIX}_LINK_LIBRARIES "-L${${_PYTHON_PREFIX}_DIR}") - #list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-L${${_PYTHON_PREFIX}_DIR}") - endforeach() - set_property (TARGET ${_PYTHON_PREFIX}::Python - PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES}) - endif() - endif() - - # - # PYTHON_ADD_LIBRARY ( [STATIC|SHARED|MODULE] src1 src2 ... srcN) - # It is used to build modules for python. - # - function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name) - cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY - "STATIC;SHARED;MODULE" "" "") - - unset (type) - if (NOT (PYTHON_ADD_LIBRARY_STATIC - OR PYTHON_ADD_LIBRARY_SHARED - OR PYTHON_ADD_LIBRARY_MODULE)) - set (type MODULE) - endif() - add_library (${name} ${type} ${ARGN}) - target_link_libraries (${name} PRIVATE ${prefix}::Python) - - # customize library name to follow module name rules - get_property (type TARGET ${name} PROPERTY TYPE) - if (type STREQUAL "MODULE_LIBRARY") - set_property (TARGET ${name} PROPERTY PREFIX "") - if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - set_property (TARGET ${name} PROPERTY SUFFIX ".pyd") - endif() - endif() - endfunction() -endif() - -# final clean-up - -# Restore CMAKE_FIND_APPBUNDLE -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) - set (CMAKE_FIND_APPBUNDLE ${_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -else() - unset (CMAKE_FIND_APPBUNDLE) -endif() -# Restore CMAKE_FIND_FRAMEWORK -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) - set (CMAKE_FIND_FRAMEWORK ${_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) -else() - unset (CMAKE_FIND_FRAMEWORK) -endif() - -unset (_${_PYTHON_PREFIX}_CONFIG CACHE) diff --git a/plugins/deisa/cmake/FindPython3.cmake b/plugins/deisa/cmake/FindPython3.cmake deleted file mode 100644 index 370abfdb5..000000000 --- a/plugins/deisa/cmake/FindPython3.cmake +++ /dev/null @@ -1,174 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPython3 ------------ - -Find Python 3 interpreter, compiler and development environment (include -directories and libraries). - -Three components are supported: - -* ``Interpreter``: search for Python 3 interpreter -* ``Compiler``: search for Python 3 compiler. Only offered by IronPython. -* ``Development``: search for development artifacts (include directories and - libraries) - -If no ``COMPONENTS`` is specified, ``Interpreter`` is assumed. - -To ensure consistent versions between components ``Interpreter``, ``Compiler`` -and ``Development``, specify all components at the same time:: - - find_package (Python3 COMPONENTS Interpreter Development) - -This module looks only for version 3 of Python. This module can be used -concurrently with :module:`FindPython2` module to use both Python versions. - -The :module:`FindPython` module can be used if Python version does not matter -for you. - -Imported Targets -^^^^^^^^^^^^^^^^ - -This module defines the following :ref:`Imported Targets `: - -``Python3::Interpreter`` - Python 3 interpreter. Target defined if component ``Interpreter`` is found. -``Python3::Compiler`` - Python 3 compiler. Target defined if component ``Compiler`` is found. -``Python3::Python`` - Python 3 library. Target defined if component ``Development`` is found. - -Result Variables -^^^^^^^^^^^^^^^^ - -This module will set the following variables in your project -(see :ref:`Standard Variable Names `): - -``Python3_FOUND`` - System has the Python 3 requested components. -``Python3_Interpreter_FOUND`` - System has the Python 3 interpreter. -``Python3_EXECUTABLE`` - Path to the Python 3 interpreter. -``Python3_INTERPRETER_ID`` - A short string unique to the interpreter. Possible values include: - * Python - * ActivePython - * Anaconda - * Canopy - * IronPython -``Python3_STDLIB`` - Standard platform independent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``. -``Python3_STDARCH`` - Standard platform dependent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``. -``Python3_SITELIB`` - Third-party platform independent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``. -``Python3_SITEARCH`` - Third-party platform dependent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``. -``Python3_Compiler_FOUND`` - System has the Python 3 compiler. -``Python3_COMPILER`` - Path to the Python 3 compiler. Only offered by IronPython. -``Python3_COMPILER_ID`` - A short string unique to the compiler. Possible values include: - * IronPython -``Python3_Development_FOUND`` - System has the Python 3 development artifacts. -``Python3_INCLUDE_DIRS`` - The Python 3 include directories. -``Python3_LIBRARIES`` - The Python 3 libraries. -``Python3_LIBRARY_DIRS`` - The Python 3 library directories. -``Python3_RUNTIME_LIBRARY_DIRS`` - The Python 3 runtime library directories. -``Python3_VERSION`` - Python 3 version. -``Python3_VERSION_MAJOR`` - Python 3 major version. -``Python3_VERSION_MINOR`` - Python 3 minor version. -``Python3_VERSION_PATCH`` - Python 3 patch version. - -Hints -^^^^^ - -``Python3_ROOT_DIR`` - Define the root directory of a Python 3 installation. - -``Python3_USE_STATIC_LIBS`` - * If not defined, search for shared libraries and static libraries in that - order. - * If set to TRUE, search **only** for static libraries. - * If set to FALSE, search **only** for shared libraries. - -``Python3_FIND_REGISTRY`` - On Windows the ``Python3_FIND_REGISTRY`` variable determine the order - of preference between registry and environment variables. - the ``Python3_FIND_REGISTRY`` variable can be set to empty or one of the - following: - - * ``FIRST``: Try to use registry before environment variables. - This is the default. - * ``LAST``: Try to use registry after environment variables. - * ``NEVER``: Never try to use registry. - -``CMAKE_FIND_FRAMEWORK`` - On OS X the :variable:`CMAKE_FIND_FRAMEWORK` variable determine the order of - preference between Apple-style and unix-style package components. - - .. note:: - - Value ``ONLY`` is not supported so ``FIRST`` will be used instead. - -Artifacts Specification -^^^^^^^^^^^^^^^^^^^^^^^ - -To solve special cases, it is possible to specify directly the artifacts by -setting the following variables: - -``Python3_EXECUTABLE`` - The path to the interpreter. - -Commands -^^^^^^^^ - -This module defines the command ``Python3_add_library`` which have the same -semantic as :command:`add_library` but take care of Python module naming rules -(only applied if library is of type ``MODULE``) and add dependency to target -``Python3::Python``:: - - Python3_add_library (my_module MODULE src1.cpp) - -If library type is not specified, ``MODULE`` is assumed. -#]=======================================================================] - - -set (_PYTHON_PREFIX Python3) - -set (_Python3_REQUIRED_VERSION_MAJOR 3) - -include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) - -if (COMMAND __Python3_add_library) - macro (Python3_add_library) - __Python3_add_library (Python3 ${ARGV}) - endmacro() -endif() - -unset (_PYTHON_PREFIX) diff --git a/plugins/deisa/cmake/SelectLibraryConfigurations.cmake b/plugins/deisa/cmake/SelectLibraryConfigurations.cmake deleted file mode 100644 index fe3bb00a6..000000000 --- a/plugins/deisa/cmake/SelectLibraryConfigurations.cmake +++ /dev/null @@ -1,71 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# SelectLibraryConfigurations -# --------------------------- -# -# -# -# select_library_configurations( basename ) -# -# This macro takes a library base name as an argument, and will choose -# good values for basename_LIBRARY, basename_LIBRARIES, -# basename_LIBRARY_DEBUG, and basename_LIBRARY_RELEASE depending on what -# has been found and set. If only basename_LIBRARY_RELEASE is defined, -# basename_LIBRARY will be set to the release value, and -# basename_LIBRARY_DEBUG will be set to basename_LIBRARY_DEBUG-NOTFOUND. -# If only basename_LIBRARY_DEBUG is defined, then basename_LIBRARY will -# take the debug value, and basename_LIBRARY_RELEASE will be set to -# basename_LIBRARY_RELEASE-NOTFOUND. -# -# If the generator supports configuration types, then basename_LIBRARY -# and basename_LIBRARIES will be set with debug and optimized flags -# specifying the library to be used for the given configuration. If no -# build type has been set or the generator in use does not support -# configuration types, then basename_LIBRARY and basename_LIBRARIES will -# take only the release value, or the debug value if the release one is -# not set. - -# This macro was adapted from the FindQt4 CMake module and is maintained by Will -# Dicharry . - -macro( select_library_configurations basename ) - if(NOT ${basename}_LIBRARY_RELEASE) - set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.") - endif() - if(NOT ${basename}_LIBRARY_DEBUG) - set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.") - endif() - - get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND - NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND - ( _isMultiConfig OR CMAKE_BUILD_TYPE ) ) - # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for - # single-config generators, set optimized and debug libraries - set( ${basename}_LIBRARY "" ) - foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE ) - list( APPEND ${basename}_LIBRARY optimized "${_libname}" ) - endforeach() - foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG ) - list( APPEND ${basename}_LIBRARY debug "${_libname}" ) - endforeach() - elseif( ${basename}_LIBRARY_RELEASE ) - set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) - elseif( ${basename}_LIBRARY_DEBUG ) - set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} ) - else() - set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND") - endif() - - set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" ) - - if( ${basename}_LIBRARY ) - set( ${basename}_FOUND TRUE ) - endif() - - mark_as_advanced( ${basename}_LIBRARY_RELEASE - ${basename}_LIBRARY_DEBUG - ) -endmacro() diff --git a/plugins/deisa/deisa.cxx b/plugins/deisa/deisa.cxx deleted file mode 100644 index 18d42c50a..000000000 --- a/plugins/deisa/deisa.cxx +++ /dev/null @@ -1,220 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2020-2025 Centre national de la recherche scientifique (CNRS) - * Copyright (c) 2020-2025 Commissariat a l'énergie atomique et aux énergies alternatives (CEA) - * Copyright (c) 2020-2023 Institut national de recherche en informatique et en automatique (Inria) - * Copyright (c) 2020-2025 Université Paris-Saclay - * Copyright (c) 2020-2025 Université de Versailles Saint-Quentin-en-Yvelines - * - * SPDX-License-Identifier: MIT - * - *****************************************************************************/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace { - -namespace py = pybind11; - -using namespace PDI; -using namespace py::literals; - -/** The deisa plugin - */ -class deisa_plugin: public Plugin -{ - static constexpr char DEISA_COMPATIBLE_VERSION[] = "0.3.2"; // Used to check compatibility with Deisa's python library - - Expression m_scheduler_info; - std::unordered_map m_deisa_arrays; - Expression m_time_step; - py::object m_bridge = py::none(); - bool m_interpreter_initialized_in_plugin = false; // Determine if python interpreter is initialized by the plugin - -public: - static std::pair, std::unordered_set> dependencies() { return {{"mpi"}, {"mpi"}}; } - - deisa_plugin(Context& ctx, PC_tree_t conf) - : Plugin{ctx} - { - if (!Py_IsInitialized()) { - py::initialize_interpreter(); - m_interpreter_initialized_in_plugin = true; - } - assert(Py_IsInitialized()); - - // init params - each(conf, [&](PC_tree_t key_tree, PC_tree_t value) { - std::string key = to_string(key_tree); - if (key == "scheduler_info") { - m_scheduler_info = to_string(value); - } else if (key == "deisa_arrays") { - each(value, [&](PC_tree_t key_map, PC_tree_t value_map) { m_deisa_arrays.emplace(to_string(key_map), ctx.datatype(value_map)); }); - } else if (key == "time_step") { - m_time_step = to_string(value); - } else if (key == "map_in") { - // - } else if (key == "logging" || key == "init_on") { - // - } else { - throw Config_error{key_tree, "Unknown key in Deisa file configuration: '{}'", key}; - } - }); - - // plugin init - PC_tree_t init_tree = PC_get(conf, ".init_on"); - if (!PC_status(init_tree)) { - ctx.callbacks().add_event_callback( - [&](const std::string&) { m_bridge = on_init_event(ctx, m_scheduler_info, m_deisa_arrays); }, - to_string(init_tree) - ); - } else { - throw Config_error{conf, "Deisa plugin requires init_on key "}; - } // TODO: replace with try/catch when #480 is fixed. - - // map_in - PC_tree_t map_in = PC_get(conf, ".map_in"); - if (!PC_status(map_in)) { - each(map_in, [&](PC_tree_t key_map, PC_tree_t value_map) { // TODO: when #481 is fixed, use `or_none` variant. - ctx.callbacks().add_data_callback( - [&, deisa_array_name = to_string(value_map)](const std::string&, const Ref& data_ref) { on_data(deisa_array_name, data_ref); }, - to_string(key_map) - ); - }); - } - } - - ~deisa_plugin() noexcept override - { - context().logger().info("Closing plugin"); - try { - // call bridge release() so that we can clear things before destructor is called (if it is ever called !). - assert(m_bridge != py::none()); - assert(hasattr(m_bridge, "release")); - m_bridge.attr("release")(); - m_bridge = py::none(); - if (m_interpreter_initialized_in_plugin) { - py::finalize_interpreter(); - } - } catch (const std::exception& e) { - context().logger().error("Exception in destructor, caught exception {}", e.what()); - } catch (...) { - context().logger().error("Exception in destructor"); - } - } - -private: - void on_data(const std::string& deisa_array_name, const Ref& data_ref) - { - try { - assert(m_bridge != py::none()); - assert(hasattr(m_bridge, "publish_data")); - py::object publish_data = m_bridge.attr("publish_data"); -#ifdef NDEBUG - publish_data(to_python(data_ref), deisa_array_name.c_str(), m_time_step.to_long(context()), "debug"_a = false); -#else - publish_data(to_python(data_ref), deisa_array_name.c_str(), m_time_step.to_long(context()), "debug"_a = true); -#endif - } catch (const std::exception& e) { - throw Plugin_error("While publishing data. Caught exception: {}", std::string(e.what())); - } catch (...) { - throw Plugin_error("While publishing data."); - } - } - - /** - * Check that the PDI plugin is compatible with Deisa's python Bridge (i.e, that the python API is what it should be). - * The plugin is compatible if DEISA_COMPATIBLE_VERSION == deisa.__version__.__version__ (python) - */ - static void check_compatibility() - { - py::module deisa = py::module::import("deisa.__version__"); - const auto python_library_version = py::str(deisa.attr("__version__")).cast(); - if (python_library_version != DEISA_COMPATIBLE_VERSION) { - throw Plugin_error( - "Deisa PDI plugin is expecting Deisa python version {} but found version {}", - DEISA_COMPATIBLE_VERSION, - python_library_version - ); - } - } - - static py::object - on_init_event(Context& ctx, const Expression& scheduler_info, const std::unordered_map& deisa_arrays) - { - std::unordered_map>> darrs; - std::unordered_map darrs_dtype; - for (auto&& [deisa_array_name, type_tpl]: deisa_arrays) { - std::unordered_map> darr; - std::vector sizes; - std::vector starts; - std::vector subsizes; - std::vector timedim; - - Datatype_sptr type_sptr = type_tpl->evaluate(ctx); - timedim.emplace_back(type_tpl->attribute("timedim").to_long(ctx)); - // get info from datatype - while (auto&& array_type = std::dynamic_pointer_cast(type_sptr)) { - sizes.emplace_back(array_type->size()); - starts.emplace_back(array_type->start()); - subsizes.emplace_back(array_type->subsize()); - type_sptr = array_type->subtype(); - } - darr["sizes"] = sizes; - darr["starts"] = starts; - darr["subsizes"] = subsizes; - darr["timedim"] = timedim; - darrs[deisa_array_name] = darr; - darrs_dtype[deisa_array_name] = to_python(std::dynamic_pointer_cast(type_sptr)); - } - - try { - int mpi_size; - long rank = Ref_r{ctx.desc("MPI_COMM_WORLD_rank").ref()}.scalar_value(); - MPI_Comm comm = *static_cast(Ref_r{ctx.desc("MPI_COMM_WORLD").ref()}.get()); - MPI_Comm_size(comm, &mpi_size); - long size = static_cast(mpi_size); - - // instantiate bridge - py::module deisa = py::module::import("deisa"); - py::object get_bridge_instance = deisa.attr("get_bridge_instance"); - - check_compatibility(); - - // TODO: use_ucx - return get_bridge_instance(to_python(scheduler_info.to_ref(ctx)), rank, size, darrs, darrs_dtype); - } catch (const std::exception& e) { - throw Plugin_error("Could not initialize Deisa plugin. Caught exception: {}", e.what()); - } catch (...) { - throw Plugin_error("Could not initialize Deisa plugin. Unknown exception."); - } - } - -}; // class deisa_plugin - -} // namespace - - -PDI_PLUGIN(deisa) diff --git a/plugins/json/AUTHORS b/plugins/json/AUTHORS index 169e4e032..8fe351f53 100644 --- a/plugins/json/AUTHORS +++ b/plugins/json/AUTHORS @@ -3,6 +3,9 @@ for their public spirit, we list here in alphabetical order a condensed list of their contributions. +Julien Bigot - CEA (julien.bigot@cea.fr) +* Update dependencies for 1.10 release + François-Xavier Mordant - CEA (francois-xavier.mordant@cea.fr) * Design and initial implementation * Plugin documentation diff --git a/plugins/json/CHANGELOG.md b/plugins/json/CHANGELOG.md new file mode 100644 index 000000000..7ba27716b --- /dev/null +++ b/plugins/json/CHANGELOG.md @@ -0,0 +1,27 @@ +# Changelog for PDI JSON plugin +All notable changes to the JSON plugin will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + + +## [Unreleased] + +### Added + +### Changed + +### Deprecated + +### Removed + +### Fixed + +### Security + + +## [1.10.0] - 2026-01-31 + +### Changed +* Update the version of dependencies according to our policy: oldest supported + Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: + CMake 3.22 [#613](https://github.com/pdidev/pdi/issues/613) diff --git a/plugins/json/CMakeLists.txt b/plugins/json/CMakeLists.txt index 974c4ea7e..7ca193ae5 100644 --- a/plugins/json/CMakeLists.txt +++ b/plugins/json/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2023-2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2023-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -22,9 +22,8 @@ # THE SOFTWARE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(pdi_json_plugin LANGUAGES C CXX) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") # Includes include(CTest) @@ -32,7 +31,7 @@ include(GNUInstallDirs) # PDI find_package(PDI REQUIRED COMPONENTS plugins) -find_package(nlohmann_json 3.9.1 REQUIRED) +find_package(nlohmann_json 3.9 REQUIRED) # The plugin add_library(pdi_json_plugin MODULE json.cxx) @@ -47,4 +46,4 @@ install(TARGETS pdi_json_plugin # Tests if("${BUILD_TESTING}") add_subdirectory(tests/) -endif() \ No newline at end of file +endif() diff --git a/plugins/json/cmake/FindPackageHandleStandardArgs.cmake b/plugins/json/cmake/FindPackageHandleStandardArgs.cmake deleted file mode 100644 index 67f6bd6f2..000000000 --- a/plugins/json/cmake/FindPackageHandleStandardArgs.cmake +++ /dev/null @@ -1,386 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPackageHandleStandardArgs ------------------------------ - -This module provides a function intended to be used in :ref:`Find Modules` -implementing :command:`find_package()` calls. It handles the -``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. -It also sets the ``_FOUND`` variable. The package is -considered found if all variables listed contain valid results, e.g. -valid filepaths. - -.. command:: find_package_handle_standard_args - - There are two signatures:: - - find_package_handle_standard_args( - (DEFAULT_MSG|) - ... - ) - - find_package_handle_standard_args( - [FOUND_VAR ] - [REQUIRED_VARS ...] - [VERSION_VAR ] - [HANDLE_COMPONENTS] - [CONFIG_MODE] - [FAIL_MESSAGE ] - ) - - The ``_FOUND`` variable will be set to ``TRUE`` if all - the variables ``...`` are valid and any optional - constraints are satisfied, and ``FALSE`` otherwise. A success or - failure message may be displayed based on the results and on - whether the ``REQUIRED`` and/or ``QUIET`` option was given to - the :command:`find_package` call. - - The options are: - - ``(DEFAULT_MSG|)`` - In the simple signature this specifies the failure message. - Use ``DEFAULT_MSG`` to ask for a default message to be computed - (recommended). Not valid in the full signature. - - ``FOUND_VAR `` - Obsolete. Specifies either ``_FOUND`` or - ``_FOUND`` as the result variable. This exists only - for compatibility with older versions of CMake and is now ignored. - Result variables of both names are always set for compatibility. - - ``REQUIRED_VARS ...`` - Specify the variables which are required for this package. - These may be named in the generated failure message asking the - user to set the missing variable values. Therefore these should - typically be cache entries such as ``FOO_LIBRARY`` and not output - variables like ``FOO_LIBRARIES``. - - ``VERSION_VAR `` - Specify the name of a variable that holds the version of the package - that has been found. This version will be checked against the - (potentially) specified required version given to the - :command:`find_package` call, including its ``EXACT`` option. - The default messages include information about the required - version and the version which has been actually found, both - if the version is ok or not. - - ``HANDLE_COMPONENTS`` - Enable handling of package components. In this case, the command - will report which components have been found and which are missing, - and the ``_FOUND`` variable will be set to ``FALSE`` - if any of the required components (i.e. not the ones listed after - the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are - missing. - - ``CONFIG_MODE`` - Specify that the calling find module is a wrapper around a - call to ``find_package( NO_MODULE)``. This implies - a ``VERSION_VAR`` value of ``_VERSION``. The command - will automatically check whether the package configuration file - was found. - - ``FAIL_MESSAGE `` - Specify a custom failure message instead of using the default - generated message. Not recommended. - -Example for the simple signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibXml2 DEFAULT_MSG - LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) - -The ``LibXml2`` package is considered to be found if both -``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. -Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found -and ``REQUIRED`` was used, it fails with a -:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was -used or not. If it is found, success will be reported, including -the content of the first ````. On repeated CMake runs, -the same message will not be printed again. - -Example for the full signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibArchive - REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR - VERSION_VAR LibArchive_VERSION) - -In this case, the ``LibArchive`` package is considered to be found if -both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. -Also the version of ``LibArchive`` will be checked by using the version -contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, -the default messages will be printed. - -Another example for the full signature: - -.. code-block:: cmake - - find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) - find_package_handle_standard_args(Automoc4 CONFIG_MODE) - -In this case, a ``FindAutmoc4.cmake`` module wraps a call to -``find_package(Automoc4 NO_MODULE)`` and adds an additional search -directory for ``automoc4``. Then the call to -``find_package_handle_standard_args`` produces a proper success/failure -message. -#]=======================================================================] - -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - -# internal helper macro -macro(_FPHSA_FAILURE_MESSAGE _msg) - if (${_NAME}_FIND_REQUIRED) - message(FATAL_ERROR "${_msg}") - else () - if (NOT ${_NAME}_FIND_QUIETLY) - message(STATUS "${_msg}") - endif () - endif () -endmacro() - - -# internal helper macro to generate the failure message when used in CONFIG_MODE: -macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: - if(${_NAME}_CONFIG) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") - else() - # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. - # List them all in the error message: - if(${_NAME}_CONSIDERED_CONFIGS) - set(configsText "") - list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) - math(EXPR configsCount "${configsCount} - 1") - foreach(currentConfigIndex RANGE ${configsCount}) - list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) - list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) - string(APPEND configsText " ${filename} (version ${version})\n") - endforeach() - if (${_NAME}_NOT_FOUND_MESSAGE) - string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") - endif() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") - - else() - # Simple case: No Config-file was found at all: - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") - endif() - endif() -endmacro() - - -function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) - -# Set up the arguments for `cmake_parse_arguments`. - set(options CONFIG_MODE HANDLE_COMPONENTS) - set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) - set(multiValueArgs REQUIRED_VARS) - -# Check whether we are in 'simple' or 'extended' mode: - set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) - list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) - - if(${INDEX} EQUAL -1) - set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) - set(FPHSA_REQUIRED_VARS ${ARGN}) - set(FPHSA_VERSION_VAR) - else() - cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) - - if(FPHSA_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") - endif() - - if(NOT FPHSA_FAIL_MESSAGE) - set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") - endif() - - # In config-mode, we rely on the variable _CONFIG, which is set by find_package() - # when it successfully found the config-file, including version checking: - if(FPHSA_CONFIG_MODE) - list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) - list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) - set(FPHSA_VERSION_VAR ${_NAME}_VERSION) - endif() - - if(NOT FPHSA_REQUIRED_VARS) - message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") - endif() - endif() - -# now that we collected all arguments, process them - - if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") - set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") - endif() - - list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) - - string(TOUPPER ${_NAME} _NAME_UPPER) - string(TOLOWER ${_NAME} _NAME_LOWER) - - if(FPHSA_FOUND_VAR) - if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") - set(_FOUND_VAR ${FPHSA_FOUND_VAR}) - else() - message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") - endif() - else() - set(_FOUND_VAR ${_NAME_UPPER}_FOUND) - endif() - - # collect all variables which were not found, so they can be printed, so the - # user knows better what went wrong (#6375) - set(MISSING_VARS "") - set(DETAILS "") - # check if all passed variables are valid - set(FPHSA_FOUND_${_NAME} TRUE) - foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) - if(NOT ${_CURRENT_VAR}) - set(FPHSA_FOUND_${_NAME} FALSE) - string(APPEND MISSING_VARS " ${_CURRENT_VAR}") - else() - string(APPEND DETAILS "[${${_CURRENT_VAR}}]") - endif() - endforeach() - if(FPHSA_FOUND_${_NAME}) - set(${_NAME}_FOUND TRUE) - set(${_NAME_UPPER}_FOUND TRUE) - else() - set(${_NAME}_FOUND FALSE) - set(${_NAME_UPPER}_FOUND FALSE) - endif() - - # component handling - unset(FOUND_COMPONENTS_MSG) - unset(MISSING_COMPONENTS_MSG) - - if(FPHSA_HANDLE_COMPONENTS) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(${_NAME}_${comp}_FOUND) - - if(NOT DEFINED FOUND_COMPONENTS_MSG) - set(FOUND_COMPONENTS_MSG "found components: ") - endif() - string(APPEND FOUND_COMPONENTS_MSG " ${comp}") - - else() - - if(NOT DEFINED MISSING_COMPONENTS_MSG) - set(MISSING_COMPONENTS_MSG "missing components: ") - endif() - string(APPEND MISSING_COMPONENTS_MSG " ${comp}") - - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - string(APPEND MISSING_VARS " ${comp}") - endif() - - endif() - endforeach() - set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") - string(APPEND DETAILS "[c${COMPONENT_MSG}]") - endif() - - # version handling: - set(VERSION_MSG "") - set(VERSION_OK TRUE) - - # check with DEFINED here as the requested or found version may be "0" - if (DEFINED ${_NAME}_FIND_VERSION) - if(DEFINED ${FPHSA_VERSION_VAR}) - set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) - - if(${_NAME}_FIND_VERSION_EXACT) # exact version required - # count the dots in the version string - string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}") - # add one dot because there is one dot more than there are components - string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) - if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) - # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT - # is at most 4 here. Therefore a simple lookup table is used. - if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) - set(_VERSION_REGEX "[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) - set(_VERSION_REGEX "[^.]*\\.[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") - else () - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") - endif () - string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}") - unset(_VERSION_REGEX) - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - unset(_VERSION_HEAD) - else () - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - endif () - unset(_VERSION_DOTS) - - else() # minimum version specified: - if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") - endif () - endif() - - else() - - # if the package was not found, but a version was given, add that to the output: - if(${_NAME}_FIND_VERSION_EXACT) - set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") - else() - set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") - endif() - - endif() - else () - # Check with DEFINED as the found version may be 0. - if(DEFINED ${FPHSA_VERSION_VAR}) - set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") - endif() - endif () - - if(VERSION_OK) - string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") - else() - set(${_NAME}_FOUND FALSE) - endif() - - - # print the result: - if (${_NAME}_FOUND) - FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") - else () - - if(FPHSA_CONFIG_MODE) - _FPHSA_HANDLE_FAILURE_CONFIG_MODE() - else() - if(NOT VERSION_OK) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") - else() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") - endif() - endif() - - endif () - - set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) - set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) -endfunction() diff --git a/plugins/json/cmake/FindPackageMessage.cmake b/plugins/json/cmake/FindPackageMessage.cmake deleted file mode 100644 index 6821cee4f..000000000 --- a/plugins/json/cmake/FindPackageMessage.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# FindPackageMessage -# ------------------ -# -# -# -# FIND_PACKAGE_MESSAGE( "message for user" "find result details") -# -# This macro is intended to be used in FindXXX.cmake modules files. It -# will print a message once for each unique find result. This is useful -# for telling the user where a package was found. The first argument -# specifies the name (XXX) of the package. The second argument -# specifies the message to display. The third argument lists details -# about the find result so that if they change the message will be -# displayed again. The macro also obeys the QUIET argument to the -# find_package command. -# -# Example: -# -# :: -# -# if(X11_FOUND) -# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" -# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") -# else() -# ... -# endif() - -function(FIND_PACKAGE_MESSAGE pkg msg details) - # Avoid printing a message repeatedly for the same find result. - if(NOT ${pkg}_FIND_QUIETLY) - string(REPLACE "\n" "" details "${details}") - set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) - if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - # The message has not yet been printed. - message(STATUS "${msg}") - - # Save the find details in the cache to avoid printing the same - # message again. - set("${DETAILS_VAR}" "${details}" - CACHE INTERNAL "Details about finding ${pkg}") - endif() - endif() -endfunction() diff --git a/plugins/json/json.cxx b/plugins/json/json.cxx index f2b1b94f6..e4c9ab9f9 100644 --- a/plugins/json/json.cxx +++ b/plugins/json/json.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2023-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2023-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -95,7 +95,7 @@ class json_plugin: public PDI::Plugin if (key == "when") { default_when = to_string(value_tree); } else if (key != "file" && key != "write") { - throw Config_error{key_tree, "Unknown keyword '{}' encountered while expecting file, when, or write", key}; + throw Spectree_error{key_tree, "Unknown keyword '{}' encountered while expecting file, when, or write", key}; } }); @@ -121,7 +121,7 @@ class json_plugin: public PDI::Plugin } }); } else { - throw Config_error{key_tree, "Unknown write method. Please use [var1, var2, ...]"}; + throw Spectree_error{key_tree, "Unknown write method. Please use [var1, var2, ...]"}; } } }); diff --git a/plugins/json/tests/CMakeLists.txt b/plugins/json/tests/CMakeLists.txt index 96e73cb49..761e559a5 100644 --- a/plugins/json/tests/CMakeLists.txt +++ b/plugins/json/tests/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2023-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2023-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -22,7 +22,7 @@ # THE SOFTWARE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) # Add the plugin path to PDI_PLUGIN_PATH set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" PROPERTY TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/TestPath.cmake") @@ -49,11 +49,10 @@ function(build_test_compare TEST_NAME) # Compare content add_test(NAME verify_content_${TEST_NAME} - COMMAND ${CMAKE_COMMAND} -DTEST_NAME=${TEST_NAME} - -DEXPECTED_OUTPUT_PATH=${EXPECTED_OUTPUT_PATH} - -DACTUAL_OUTPUT_PATH=${ACTUAL_OUTPUT_PATH} - -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compare_content.cmake) - + COMMAND ${CMAKE_COMMAND} -DTEST_NAME=${TEST_NAME} + -DEXPECTED_OUTPUT_PATH=${EXPECTED_OUTPUT_PATH} + -DACTUAL_OUTPUT_PATH=${ACTUAL_OUTPUT_PATH} + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compare_content.cmake) set_tests_properties(verify_content_${TEST_NAME} PROPERTIES FIXTURES_REQUIRED ${TEST_NAME}) endfunction() diff --git a/plugins/json/tests/cmake/compare_content.cmake b/plugins/json/tests/cmake/compare_content.cmake index 0de914893..3da1534b2 100644 --- a/plugins/json/tests/cmake/compare_content.cmake +++ b/plugins/json/tests/cmake/compare_content.cmake @@ -1,5 +1,5 @@ #-------------------------------------------------------------------------------- -# Copyright (C) 2023 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2023-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -41,7 +41,5 @@ if (ACTUAL_CONTENT STREQUAL EXPECTED_CONTENT) message(STATUS "${TEST_NAME} : Produced and expected contents corresponds\nTest verify_content_${TEST_NAME} passed.") else () message(FATAL_ERROR "${TEST_NAME} : Produced and expected contents does not corresponds\nTest verify_content_${TEST_NAME} failed." - # "Actual output:\n${ACTUAL_CONTENT}\n" - # "Expected output:\n${EXPECTED_CONTENT}" ) -endif () \ No newline at end of file +endif () diff --git a/plugins/mpi/CHANGELOG.md b/plugins/mpi/CHANGELOG.md index c65670ee6..ae27c42cb 100644 --- a/plugins/mpi/CHANGELOG.md +++ b/plugins/mpi/CHANGELOG.md @@ -9,6 +9,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added ### Changed +* Fully qualify `std::move` calls to prevent a compilation warning and incorrect + usages [#675](https://github.com/pdidev/pdi/issues/675) ### Deprecated @@ -19,6 +21,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Security +## [1.10.0] - 2026-01-31 + +### Added +* Added macOS CI [#556](https://github.com/pdidev/pdi/issues/556) + +### Changed +* Update the version of dependencies according to our policy: oldest supported + Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: + CMake 3.22 [#613](https://github.com/pdidev/pdi/issues/613) + + ## [1.8.0] - 2024-11-28 ### Changed diff --git a/plugins/mpi/CMakeLists.txt b/plugins/mpi/CMakeLists.txt index 7a6a8435d..947e549c9 100644 --- a/plugins/mpi/CMakeLists.txt +++ b/plugins/mpi/CMakeLists.txt @@ -1,6 +1,6 @@ #============================================================================= # Copyright (C) 2018 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) -# Copyright (C) 2020-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -23,9 +23,8 @@ # THE SOFTWARE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(pdi_mpi_plugin LANGUAGES C CXX) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") option(BUILD_FORTRAN "Enable Fortran support" ON) diff --git a/plugins/mpi/cmake/FindPackageHandleStandardArgs.cmake b/plugins/mpi/cmake/FindPackageHandleStandardArgs.cmake deleted file mode 100644 index 67f6bd6f2..000000000 --- a/plugins/mpi/cmake/FindPackageHandleStandardArgs.cmake +++ /dev/null @@ -1,386 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPackageHandleStandardArgs ------------------------------ - -This module provides a function intended to be used in :ref:`Find Modules` -implementing :command:`find_package()` calls. It handles the -``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. -It also sets the ``_FOUND`` variable. The package is -considered found if all variables listed contain valid results, e.g. -valid filepaths. - -.. command:: find_package_handle_standard_args - - There are two signatures:: - - find_package_handle_standard_args( - (DEFAULT_MSG|) - ... - ) - - find_package_handle_standard_args( - [FOUND_VAR ] - [REQUIRED_VARS ...] - [VERSION_VAR ] - [HANDLE_COMPONENTS] - [CONFIG_MODE] - [FAIL_MESSAGE ] - ) - - The ``_FOUND`` variable will be set to ``TRUE`` if all - the variables ``...`` are valid and any optional - constraints are satisfied, and ``FALSE`` otherwise. A success or - failure message may be displayed based on the results and on - whether the ``REQUIRED`` and/or ``QUIET`` option was given to - the :command:`find_package` call. - - The options are: - - ``(DEFAULT_MSG|)`` - In the simple signature this specifies the failure message. - Use ``DEFAULT_MSG`` to ask for a default message to be computed - (recommended). Not valid in the full signature. - - ``FOUND_VAR `` - Obsolete. Specifies either ``_FOUND`` or - ``_FOUND`` as the result variable. This exists only - for compatibility with older versions of CMake and is now ignored. - Result variables of both names are always set for compatibility. - - ``REQUIRED_VARS ...`` - Specify the variables which are required for this package. - These may be named in the generated failure message asking the - user to set the missing variable values. Therefore these should - typically be cache entries such as ``FOO_LIBRARY`` and not output - variables like ``FOO_LIBRARIES``. - - ``VERSION_VAR `` - Specify the name of a variable that holds the version of the package - that has been found. This version will be checked against the - (potentially) specified required version given to the - :command:`find_package` call, including its ``EXACT`` option. - The default messages include information about the required - version and the version which has been actually found, both - if the version is ok or not. - - ``HANDLE_COMPONENTS`` - Enable handling of package components. In this case, the command - will report which components have been found and which are missing, - and the ``_FOUND`` variable will be set to ``FALSE`` - if any of the required components (i.e. not the ones listed after - the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are - missing. - - ``CONFIG_MODE`` - Specify that the calling find module is a wrapper around a - call to ``find_package( NO_MODULE)``. This implies - a ``VERSION_VAR`` value of ``_VERSION``. The command - will automatically check whether the package configuration file - was found. - - ``FAIL_MESSAGE `` - Specify a custom failure message instead of using the default - generated message. Not recommended. - -Example for the simple signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibXml2 DEFAULT_MSG - LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) - -The ``LibXml2`` package is considered to be found if both -``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. -Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found -and ``REQUIRED`` was used, it fails with a -:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was -used or not. If it is found, success will be reported, including -the content of the first ````. On repeated CMake runs, -the same message will not be printed again. - -Example for the full signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibArchive - REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR - VERSION_VAR LibArchive_VERSION) - -In this case, the ``LibArchive`` package is considered to be found if -both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. -Also the version of ``LibArchive`` will be checked by using the version -contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, -the default messages will be printed. - -Another example for the full signature: - -.. code-block:: cmake - - find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) - find_package_handle_standard_args(Automoc4 CONFIG_MODE) - -In this case, a ``FindAutmoc4.cmake`` module wraps a call to -``find_package(Automoc4 NO_MODULE)`` and adds an additional search -directory for ``automoc4``. Then the call to -``find_package_handle_standard_args`` produces a proper success/failure -message. -#]=======================================================================] - -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - -# internal helper macro -macro(_FPHSA_FAILURE_MESSAGE _msg) - if (${_NAME}_FIND_REQUIRED) - message(FATAL_ERROR "${_msg}") - else () - if (NOT ${_NAME}_FIND_QUIETLY) - message(STATUS "${_msg}") - endif () - endif () -endmacro() - - -# internal helper macro to generate the failure message when used in CONFIG_MODE: -macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: - if(${_NAME}_CONFIG) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") - else() - # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. - # List them all in the error message: - if(${_NAME}_CONSIDERED_CONFIGS) - set(configsText "") - list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) - math(EXPR configsCount "${configsCount} - 1") - foreach(currentConfigIndex RANGE ${configsCount}) - list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) - list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) - string(APPEND configsText " ${filename} (version ${version})\n") - endforeach() - if (${_NAME}_NOT_FOUND_MESSAGE) - string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") - endif() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") - - else() - # Simple case: No Config-file was found at all: - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") - endif() - endif() -endmacro() - - -function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) - -# Set up the arguments for `cmake_parse_arguments`. - set(options CONFIG_MODE HANDLE_COMPONENTS) - set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) - set(multiValueArgs REQUIRED_VARS) - -# Check whether we are in 'simple' or 'extended' mode: - set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) - list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) - - if(${INDEX} EQUAL -1) - set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) - set(FPHSA_REQUIRED_VARS ${ARGN}) - set(FPHSA_VERSION_VAR) - else() - cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) - - if(FPHSA_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") - endif() - - if(NOT FPHSA_FAIL_MESSAGE) - set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") - endif() - - # In config-mode, we rely on the variable _CONFIG, which is set by find_package() - # when it successfully found the config-file, including version checking: - if(FPHSA_CONFIG_MODE) - list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) - list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) - set(FPHSA_VERSION_VAR ${_NAME}_VERSION) - endif() - - if(NOT FPHSA_REQUIRED_VARS) - message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") - endif() - endif() - -# now that we collected all arguments, process them - - if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") - set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") - endif() - - list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) - - string(TOUPPER ${_NAME} _NAME_UPPER) - string(TOLOWER ${_NAME} _NAME_LOWER) - - if(FPHSA_FOUND_VAR) - if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") - set(_FOUND_VAR ${FPHSA_FOUND_VAR}) - else() - message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") - endif() - else() - set(_FOUND_VAR ${_NAME_UPPER}_FOUND) - endif() - - # collect all variables which were not found, so they can be printed, so the - # user knows better what went wrong (#6375) - set(MISSING_VARS "") - set(DETAILS "") - # check if all passed variables are valid - set(FPHSA_FOUND_${_NAME} TRUE) - foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) - if(NOT ${_CURRENT_VAR}) - set(FPHSA_FOUND_${_NAME} FALSE) - string(APPEND MISSING_VARS " ${_CURRENT_VAR}") - else() - string(APPEND DETAILS "[${${_CURRENT_VAR}}]") - endif() - endforeach() - if(FPHSA_FOUND_${_NAME}) - set(${_NAME}_FOUND TRUE) - set(${_NAME_UPPER}_FOUND TRUE) - else() - set(${_NAME}_FOUND FALSE) - set(${_NAME_UPPER}_FOUND FALSE) - endif() - - # component handling - unset(FOUND_COMPONENTS_MSG) - unset(MISSING_COMPONENTS_MSG) - - if(FPHSA_HANDLE_COMPONENTS) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(${_NAME}_${comp}_FOUND) - - if(NOT DEFINED FOUND_COMPONENTS_MSG) - set(FOUND_COMPONENTS_MSG "found components: ") - endif() - string(APPEND FOUND_COMPONENTS_MSG " ${comp}") - - else() - - if(NOT DEFINED MISSING_COMPONENTS_MSG) - set(MISSING_COMPONENTS_MSG "missing components: ") - endif() - string(APPEND MISSING_COMPONENTS_MSG " ${comp}") - - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - string(APPEND MISSING_VARS " ${comp}") - endif() - - endif() - endforeach() - set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") - string(APPEND DETAILS "[c${COMPONENT_MSG}]") - endif() - - # version handling: - set(VERSION_MSG "") - set(VERSION_OK TRUE) - - # check with DEFINED here as the requested or found version may be "0" - if (DEFINED ${_NAME}_FIND_VERSION) - if(DEFINED ${FPHSA_VERSION_VAR}) - set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) - - if(${_NAME}_FIND_VERSION_EXACT) # exact version required - # count the dots in the version string - string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}") - # add one dot because there is one dot more than there are components - string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) - if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) - # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT - # is at most 4 here. Therefore a simple lookup table is used. - if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) - set(_VERSION_REGEX "[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) - set(_VERSION_REGEX "[^.]*\\.[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") - else () - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") - endif () - string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}") - unset(_VERSION_REGEX) - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - unset(_VERSION_HEAD) - else () - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - endif () - unset(_VERSION_DOTS) - - else() # minimum version specified: - if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") - endif () - endif() - - else() - - # if the package was not found, but a version was given, add that to the output: - if(${_NAME}_FIND_VERSION_EXACT) - set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") - else() - set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") - endif() - - endif() - else () - # Check with DEFINED as the found version may be 0. - if(DEFINED ${FPHSA_VERSION_VAR}) - set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") - endif() - endif () - - if(VERSION_OK) - string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") - else() - set(${_NAME}_FOUND FALSE) - endif() - - - # print the result: - if (${_NAME}_FOUND) - FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") - else () - - if(FPHSA_CONFIG_MODE) - _FPHSA_HANDLE_FAILURE_CONFIG_MODE() - else() - if(NOT VERSION_OK) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") - else() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") - endif() - endif() - - endif () - - set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) - set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) -endfunction() diff --git a/plugins/mpi/cmake/FindPackageMessage.cmake b/plugins/mpi/cmake/FindPackageMessage.cmake deleted file mode 100644 index 6821cee4f..000000000 --- a/plugins/mpi/cmake/FindPackageMessage.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# FindPackageMessage -# ------------------ -# -# -# -# FIND_PACKAGE_MESSAGE( "message for user" "find result details") -# -# This macro is intended to be used in FindXXX.cmake modules files. It -# will print a message once for each unique find result. This is useful -# for telling the user where a package was found. The first argument -# specifies the name (XXX) of the package. The second argument -# specifies the message to display. The third argument lists details -# about the find result so that if they change the message will be -# displayed again. The macro also obeys the QUIET argument to the -# find_package command. -# -# Example: -# -# :: -# -# if(X11_FOUND) -# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" -# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") -# else() -# ... -# endif() - -function(FIND_PACKAGE_MESSAGE pkg msg details) - # Avoid printing a message repeatedly for the same find result. - if(NOT ${pkg}_FIND_QUIETLY) - string(REPLACE "\n" "" details "${details}") - set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) - if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - # The message has not yet been printed. - message(STATUS "${msg}") - - # Save the find details in the cache to avoid printing the same - # message again. - set("${DETAILS_VAR}" "${details}" - CACHE INTERNAL "Details about finding ${pkg}") - endif() - endif() -endfunction() diff --git a/plugins/mpi/mpi.cxx b/plugins/mpi/mpi.cxx index 8f07604cd..a1886694c 100644 --- a/plugins/mpi/mpi.cxx +++ b/plugins/mpi/mpi.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2020-2022 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2018-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -37,7 +37,6 @@ namespace { -using PDI::Config_error; using PDI::Context; using PDI::Context_proxy; using PDI::Data_descriptor; @@ -46,11 +45,11 @@ using PDI::Datatype_sptr; using PDI::Error; using PDI::Impl_error; using PDI::len; +using PDI::Permission_error; using PDI::Plugin; using PDI::Ref; using PDI::Ref_r; using PDI::Ref_w; -using PDI::Right_error; using PDI::Scalar_datatype; using PDI::Scalar_kind; using PDI::to_long; @@ -256,7 +255,7 @@ struct mpi_plugin: Plugin { predef_desc.metadata(true); // share a RO reference on comm_self with no memory destruction function (local variable) - predef_desc.share({data, nullptr, move(type), true, false}, true, false); + predef_desc.share({data, nullptr, std::move(type), true, false}, true, false); predef_desc.reclaim(); // reclaim the reference and let PDI keep a copy (metadata) } @@ -333,7 +332,7 @@ struct mpi_plugin: Plugin { *static_cast(Ref_w{fortran_comm_ref}.get()) = MPI_Comm_c2f(*static_cast(ref_r.get())); ctx.desc(fortran_comm_desc).share(fortran_comm_ref, false, false); } else { - throw Right_error{"Cannot read `{}' data to transtype to fortran communicator", c_comm_desc}; + throw Permission_error{"Cannot read `{}' data to transtype to fortran communicator", c_comm_desc}; } }, c_comm_desc @@ -347,7 +346,7 @@ struct mpi_plugin: Plugin { if (Ref_r fortran_comm_ref_r = ctx.desc(fortran_comm_desc).ref()) { *static_cast(c_comm_ref_w.get()) = MPI_Comm_f2c(*static_cast(fortran_comm_ref_r.get())); } else { - throw Right_error{"Cannot read `{}' data", c_comm_desc}; + throw Permission_error{"Cannot read `{}' data", c_comm_desc}; } } ctx.desc(fortran_comm_desc).release(); @@ -369,14 +368,14 @@ struct mpi_plugin: Plugin { ctx.callbacks().add_data_callback( [&ctx, c_comm_desc, mpi_comm_type](const string& fortran_comm_desc, Ref ref) { ctx.logger().debug("Transtype `{}' to `{}` (F->C)", fortran_comm_desc, c_comm_desc); - Ref c_comm_ref{new MPI_Comm, [](void* p) { delete static_cast(p); }, move(mpi_comm_type), true, true}; + Ref c_comm_ref{new MPI_Comm, [](void* p) { delete static_cast(p); }, std::move(mpi_comm_type), true, true}; if (Ref_r ref_r{ref}) { MPI_Fint f_comm; set_val(f_comm, ref_r); *static_cast(Ref_w{c_comm_ref}.get()) = MPI_Comm_f2c(f_comm); ctx.desc(c_comm_desc).share(c_comm_ref, false, false); } else { - throw Right_error{"Cannot read `{}' data to transtype to C communicator", fortran_comm_desc}; + throw Permission_error{"Cannot read `{}' data to transtype to C communicator", fortran_comm_desc}; } }, fortran_comm_desc @@ -391,7 +390,7 @@ struct mpi_plugin: Plugin { if (Ref_r c_comm_ref_r = ctx.desc(c_comm_desc).ref()) { set_val(fortran_comm_ref_w, MPI_Comm_c2f(*static_cast(c_comm_ref_r.get()))); } else { - throw Right_error{"Cannot read `{}' data", c_comm_desc}; + throw Permission_error{"Cannot read `{}' data", c_comm_desc}; } } else { ctx.logger().error("Cannot write `{}' communicator back", fortran_comm_desc); diff --git a/plugins/mpi/tests/CMakeLists.txt b/plugins/mpi/tests/CMakeLists.txt index 2ddb6a29d..9742ae7f8 100644 --- a/plugins/mpi/tests/CMakeLists.txt +++ b/plugins/mpi/tests/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) # # All rights reserved. @@ -28,7 +28,7 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) set(RUNTEST_DIR "${CMAKE_CURRENT_LIST_DIR}/../cmake/runtest-dir") diff --git a/plugins/pycall/CHANGELOG.md b/plugins/pycall/CHANGELOG.md index 6d8b91a81..bde3e9616 100644 --- a/plugins/pycall/CHANGELOG.md +++ b/plugins/pycall/CHANGELOG.md @@ -9,6 +9,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added ### Changed +* Fully qualify `std::move` calls to prevent a compilation warning and incorrect + usages [#675](https://github.com/pdidev/pdi/issues/675) ### Deprecated @@ -19,6 +21,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Security +## [1.10.0] - 2026-01-31 + +### Changed +* Update the version of dependencies according to our policy: oldest supported + Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: + CMake 3.22, pybind11 2.9.1, and Python 3.10.6 + [#613](https://github.com/pdidev/pdi/issues/613) + + ## [1.8.1] - 2025-01-23 ### Fixed diff --git a/plugins/pycall/CMakeLists.txt b/plugins/pycall/CMakeLists.txt index ac46c31c8..a3e2db624 100644 --- a/plugins/pycall/CMakeLists.txt +++ b/plugins/pycall/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -27,20 +27,19 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(pdi_pycall_plugin LANGUAGES C CXX) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") include(CTest) include(GNUInstallDirs) -find_package(Python3 3.8.2 REQUIRED COMPONENTS Interpreter Development) +find_package(Python3 3.10 REQUIRED COMPONENTS Interpreter Development) # PyBind11 set(Python_ADDITIONAL_VERSIONS "${Python3_VERSION}" CACHE STRING "Python version found by FindPython3 for coherency" FORCE) set(PYBIND11_PYTHON_VERSION "${Python3_VERSION}" CACHE STRING "Python version to use for compiling modules" FORCE) -find_package(pybind11 2.4.3 REQUIRED) +find_package(pybind11 2.9 REQUIRED) # PDI find_package(PDI REQUIRED COMPONENTS pysupport) diff --git a/plugins/pycall/cmake/FindPackageHandleStandardArgs.cmake b/plugins/pycall/cmake/FindPackageHandleStandardArgs.cmake deleted file mode 100644 index 67f6bd6f2..000000000 --- a/plugins/pycall/cmake/FindPackageHandleStandardArgs.cmake +++ /dev/null @@ -1,386 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPackageHandleStandardArgs ------------------------------ - -This module provides a function intended to be used in :ref:`Find Modules` -implementing :command:`find_package()` calls. It handles the -``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. -It also sets the ``_FOUND`` variable. The package is -considered found if all variables listed contain valid results, e.g. -valid filepaths. - -.. command:: find_package_handle_standard_args - - There are two signatures:: - - find_package_handle_standard_args( - (DEFAULT_MSG|) - ... - ) - - find_package_handle_standard_args( - [FOUND_VAR ] - [REQUIRED_VARS ...] - [VERSION_VAR ] - [HANDLE_COMPONENTS] - [CONFIG_MODE] - [FAIL_MESSAGE ] - ) - - The ``_FOUND`` variable will be set to ``TRUE`` if all - the variables ``...`` are valid and any optional - constraints are satisfied, and ``FALSE`` otherwise. A success or - failure message may be displayed based on the results and on - whether the ``REQUIRED`` and/or ``QUIET`` option was given to - the :command:`find_package` call. - - The options are: - - ``(DEFAULT_MSG|)`` - In the simple signature this specifies the failure message. - Use ``DEFAULT_MSG`` to ask for a default message to be computed - (recommended). Not valid in the full signature. - - ``FOUND_VAR `` - Obsolete. Specifies either ``_FOUND`` or - ``_FOUND`` as the result variable. This exists only - for compatibility with older versions of CMake and is now ignored. - Result variables of both names are always set for compatibility. - - ``REQUIRED_VARS ...`` - Specify the variables which are required for this package. - These may be named in the generated failure message asking the - user to set the missing variable values. Therefore these should - typically be cache entries such as ``FOO_LIBRARY`` and not output - variables like ``FOO_LIBRARIES``. - - ``VERSION_VAR `` - Specify the name of a variable that holds the version of the package - that has been found. This version will be checked against the - (potentially) specified required version given to the - :command:`find_package` call, including its ``EXACT`` option. - The default messages include information about the required - version and the version which has been actually found, both - if the version is ok or not. - - ``HANDLE_COMPONENTS`` - Enable handling of package components. In this case, the command - will report which components have been found and which are missing, - and the ``_FOUND`` variable will be set to ``FALSE`` - if any of the required components (i.e. not the ones listed after - the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are - missing. - - ``CONFIG_MODE`` - Specify that the calling find module is a wrapper around a - call to ``find_package( NO_MODULE)``. This implies - a ``VERSION_VAR`` value of ``_VERSION``. The command - will automatically check whether the package configuration file - was found. - - ``FAIL_MESSAGE `` - Specify a custom failure message instead of using the default - generated message. Not recommended. - -Example for the simple signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibXml2 DEFAULT_MSG - LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) - -The ``LibXml2`` package is considered to be found if both -``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. -Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found -and ``REQUIRED`` was used, it fails with a -:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was -used or not. If it is found, success will be reported, including -the content of the first ````. On repeated CMake runs, -the same message will not be printed again. - -Example for the full signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibArchive - REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR - VERSION_VAR LibArchive_VERSION) - -In this case, the ``LibArchive`` package is considered to be found if -both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. -Also the version of ``LibArchive`` will be checked by using the version -contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, -the default messages will be printed. - -Another example for the full signature: - -.. code-block:: cmake - - find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) - find_package_handle_standard_args(Automoc4 CONFIG_MODE) - -In this case, a ``FindAutmoc4.cmake`` module wraps a call to -``find_package(Automoc4 NO_MODULE)`` and adds an additional search -directory for ``automoc4``. Then the call to -``find_package_handle_standard_args`` produces a proper success/failure -message. -#]=======================================================================] - -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - -# internal helper macro -macro(_FPHSA_FAILURE_MESSAGE _msg) - if (${_NAME}_FIND_REQUIRED) - message(FATAL_ERROR "${_msg}") - else () - if (NOT ${_NAME}_FIND_QUIETLY) - message(STATUS "${_msg}") - endif () - endif () -endmacro() - - -# internal helper macro to generate the failure message when used in CONFIG_MODE: -macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: - if(${_NAME}_CONFIG) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") - else() - # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. - # List them all in the error message: - if(${_NAME}_CONSIDERED_CONFIGS) - set(configsText "") - list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) - math(EXPR configsCount "${configsCount} - 1") - foreach(currentConfigIndex RANGE ${configsCount}) - list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) - list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) - string(APPEND configsText " ${filename} (version ${version})\n") - endforeach() - if (${_NAME}_NOT_FOUND_MESSAGE) - string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") - endif() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") - - else() - # Simple case: No Config-file was found at all: - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") - endif() - endif() -endmacro() - - -function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) - -# Set up the arguments for `cmake_parse_arguments`. - set(options CONFIG_MODE HANDLE_COMPONENTS) - set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) - set(multiValueArgs REQUIRED_VARS) - -# Check whether we are in 'simple' or 'extended' mode: - set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) - list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) - - if(${INDEX} EQUAL -1) - set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) - set(FPHSA_REQUIRED_VARS ${ARGN}) - set(FPHSA_VERSION_VAR) - else() - cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) - - if(FPHSA_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") - endif() - - if(NOT FPHSA_FAIL_MESSAGE) - set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") - endif() - - # In config-mode, we rely on the variable _CONFIG, which is set by find_package() - # when it successfully found the config-file, including version checking: - if(FPHSA_CONFIG_MODE) - list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) - list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) - set(FPHSA_VERSION_VAR ${_NAME}_VERSION) - endif() - - if(NOT FPHSA_REQUIRED_VARS) - message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") - endif() - endif() - -# now that we collected all arguments, process them - - if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") - set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") - endif() - - list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) - - string(TOUPPER ${_NAME} _NAME_UPPER) - string(TOLOWER ${_NAME} _NAME_LOWER) - - if(FPHSA_FOUND_VAR) - if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") - set(_FOUND_VAR ${FPHSA_FOUND_VAR}) - else() - message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") - endif() - else() - set(_FOUND_VAR ${_NAME_UPPER}_FOUND) - endif() - - # collect all variables which were not found, so they can be printed, so the - # user knows better what went wrong (#6375) - set(MISSING_VARS "") - set(DETAILS "") - # check if all passed variables are valid - set(FPHSA_FOUND_${_NAME} TRUE) - foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) - if(NOT ${_CURRENT_VAR}) - set(FPHSA_FOUND_${_NAME} FALSE) - string(APPEND MISSING_VARS " ${_CURRENT_VAR}") - else() - string(APPEND DETAILS "[${${_CURRENT_VAR}}]") - endif() - endforeach() - if(FPHSA_FOUND_${_NAME}) - set(${_NAME}_FOUND TRUE) - set(${_NAME_UPPER}_FOUND TRUE) - else() - set(${_NAME}_FOUND FALSE) - set(${_NAME_UPPER}_FOUND FALSE) - endif() - - # component handling - unset(FOUND_COMPONENTS_MSG) - unset(MISSING_COMPONENTS_MSG) - - if(FPHSA_HANDLE_COMPONENTS) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(${_NAME}_${comp}_FOUND) - - if(NOT DEFINED FOUND_COMPONENTS_MSG) - set(FOUND_COMPONENTS_MSG "found components: ") - endif() - string(APPEND FOUND_COMPONENTS_MSG " ${comp}") - - else() - - if(NOT DEFINED MISSING_COMPONENTS_MSG) - set(MISSING_COMPONENTS_MSG "missing components: ") - endif() - string(APPEND MISSING_COMPONENTS_MSG " ${comp}") - - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - string(APPEND MISSING_VARS " ${comp}") - endif() - - endif() - endforeach() - set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") - string(APPEND DETAILS "[c${COMPONENT_MSG}]") - endif() - - # version handling: - set(VERSION_MSG "") - set(VERSION_OK TRUE) - - # check with DEFINED here as the requested or found version may be "0" - if (DEFINED ${_NAME}_FIND_VERSION) - if(DEFINED ${FPHSA_VERSION_VAR}) - set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) - - if(${_NAME}_FIND_VERSION_EXACT) # exact version required - # count the dots in the version string - string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}") - # add one dot because there is one dot more than there are components - string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) - if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) - # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT - # is at most 4 here. Therefore a simple lookup table is used. - if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) - set(_VERSION_REGEX "[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) - set(_VERSION_REGEX "[^.]*\\.[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") - else () - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") - endif () - string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}") - unset(_VERSION_REGEX) - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - unset(_VERSION_HEAD) - else () - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - endif () - unset(_VERSION_DOTS) - - else() # minimum version specified: - if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") - endif () - endif() - - else() - - # if the package was not found, but a version was given, add that to the output: - if(${_NAME}_FIND_VERSION_EXACT) - set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") - else() - set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") - endif() - - endif() - else () - # Check with DEFINED as the found version may be 0. - if(DEFINED ${FPHSA_VERSION_VAR}) - set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") - endif() - endif () - - if(VERSION_OK) - string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") - else() - set(${_NAME}_FOUND FALSE) - endif() - - - # print the result: - if (${_NAME}_FOUND) - FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") - else () - - if(FPHSA_CONFIG_MODE) - _FPHSA_HANDLE_FAILURE_CONFIG_MODE() - else() - if(NOT VERSION_OK) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") - else() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") - endif() - endif() - - endif () - - set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) - set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) -endfunction() diff --git a/plugins/pycall/cmake/FindPackageMessage.cmake b/plugins/pycall/cmake/FindPackageMessage.cmake deleted file mode 100644 index 6821cee4f..000000000 --- a/plugins/pycall/cmake/FindPackageMessage.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# FindPackageMessage -# ------------------ -# -# -# -# FIND_PACKAGE_MESSAGE( "message for user" "find result details") -# -# This macro is intended to be used in FindXXX.cmake modules files. It -# will print a message once for each unique find result. This is useful -# for telling the user where a package was found. The first argument -# specifies the name (XXX) of the package. The second argument -# specifies the message to display. The third argument lists details -# about the find result so that if they change the message will be -# displayed again. The macro also obeys the QUIET argument to the -# find_package command. -# -# Example: -# -# :: -# -# if(X11_FOUND) -# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" -# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") -# else() -# ... -# endif() - -function(FIND_PACKAGE_MESSAGE pkg msg details) - # Avoid printing a message repeatedly for the same find result. - if(NOT ${pkg}_FIND_QUIETLY) - string(REPLACE "\n" "" details "${details}") - set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) - if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - # The message has not yet been printed. - message(STATUS "${msg}") - - # Save the find details in the cache to avoid printing the same - # message again. - set("${DETAILS_VAR}" "${details}" - CACHE INTERNAL "Details about finding ${pkg}") - endif() - endif() -endfunction() diff --git a/plugins/pycall/cmake/FindPython/Support.cmake b/plugins/pycall/cmake/FindPython/Support.cmake deleted file mode 100644 index be4c3366f..000000000 --- a/plugins/pycall/cmake/FindPython/Support.cmake +++ /dev/null @@ -1,1244 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -# -# This file is a "template" file used by various FindPython modules. -# - -cmake_policy (VERSION 3.16...3.25) - -# -# Initial configuration -# -if (NOT DEFINED _PYTHON_PREFIX) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 3) - set(_${_PYTHON_PREFIX}_VERSIONS 3.20 3.19 3.18 3.17 3.16 3.15 3.14 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0) -elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 2) - set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) -else() - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() - - -# -# helper commands -# -macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG) - if (${_PYTHON_PREFIX}_FIND_REQUIRED) - message (FATAL_ERROR "${_PYTHON_MSG}") - else() - if (NOT ${_PYTHON_PREFIX}_FIND_QUIETLY) - message(STATUS "${_PYTHON_MSG}") - endif () - endif() - - set (${_PYTHON_PREFIX}_FOUND FALSE) - string (TOUPPER "${_PYTHON_PREFIX}" _${_PYTHON_PREFIX}_UPPER_PREFIX) - set (${_PYTHON_UPPER_PREFIX}_FOUND FALSE) - return() -endmacro() - - -macro (_PYTHON_FIND_FRAMEWORKS) - set (${_PYTHON_PREFIX}_FRAMEWORKS) - if (APPLE) - set (_pff_frameworks ${CMAKE_FRAMEWORK_PATH} - $ENV{CMAKE_FRAMEWORK_PATH} - ~/Library/Frameworks - /usr/local/Frameworks - ${CMAKE_SYSTEM_FRAMEWORK_PATH}) - list (REMOVE_DUPLICATES _pff_frameworks) - foreach (_pff_framework IN LISTS _pff_frameworks) - if (EXISTS ${_pff_framework}/Python.framework) - list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python.framework) - endif() - endforeach() - unset (_pff_frameworks) - unset (_pff_framework) - endif() -endmacro() - -function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION) - set (_PYTHON_FRAMEWORK_PATHS) - foreach (_PYTHON_FRAMEWORK IN LISTS ${_PYTHON_PREFIX}_FRAMEWORKS) - list (APPEND _PYTHON_FRAMEWORK_PATHS - "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}") - endforeach() - set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${_PYTHON_FRAMEWORK_PATHS} PARENT_SCOPE) -endfunction() - - -function (_PYTHON_VALIDATE_INTERPRETER) - if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) - return() - endif() - - if (ARGC EQUAL 1) - set (expected_version ${ARGV0}) - else() - unset (expected_version) - endif() - - get_filename_component (python_name "${${_PYTHON_PREFIX}_EXECUTABLE}" NAME) - - if (expected_version AND NOT python_name STREQUAL "python${expected_version}${CMAKE_EXECUTABLE_SUFFIX}") - # executable found must have a specific version - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL expected_version) - # interpreter not usable or has wrong major version - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - else() - if (NOT python_name STREQUAL "python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}${CMAKE_EXECUTABLE_SUFFIX}") - # executable found do not have version in name - # ensure major version is OK - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write(str(sys.version_info[0]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - # interpreter not usable or has wrong major version - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - endif() - endif() - - if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND NOT CMAKE_CROSSCOMPILING) - # In this case, interpreter must have same architecture as environment - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))" - RESULT_VARIABLE result - OUTPUT_VARIABLE size - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P) - # interpreter not usable or has wrong architecture - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - endif() -endfunction() - - -function (_PYTHON_VALIDATE_COMPILER expected_version) - if (NOT ${_PYTHON_PREFIX}_COMPILER) - return() - endif() - - # retrieve python environment version from compiler - set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))\n") - execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${working_dir}/version.py" - WORKING_DIRECTORY "${working_dir}" - OUTPUT_QUIET - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process (COMMAND "${working_dir}/version" - WORKING_DIRECTORY "${working_dir}" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET) - file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") - - if (result OR NOT version EQUAL expected_version) - # Compiler not usable or has wrong major version - set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) - endif() -endfunction() - - -function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB) - string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}") - # look at runtime part on systems supporting it - if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR - (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN" - AND ${_PYTHON_LIB} MATCHES "${CMAKE_IMPORT_LIBRARY_SUFFIX}$")) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) - # MSYS has a special syntax for runtime libraries - if (CMAKE_SYSTEM_NAME MATCHES "MSYS") - list (APPEND CMAKE_FIND_LIBRARY_PREFIXES "msys-") - endif() - find_library (${ARGV}) - endif() -endfunction() - - -function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT) - unset (_PYTHON_DIRS) - set (_PYTHON_LIBS ${ARGV}) - list (REMOVE_AT _PYTHON_LIBS 0) - foreach (_PYTHON_LIB IN LISTS _PYTHON_LIBS) - if (${_PYTHON_LIB}) - get_filename_component (_PYTHON_DIR "${${_PYTHON_LIB}}" DIRECTORY) - list (APPEND _PYTHON_DIRS "${_PYTHON_DIR}") - endif() - endforeach() - if (_PYTHON_DIRS) - list (REMOVE_DUPLICATES _PYTHON_DIRS) - endif() - set (${_PYTHON_SLD_RESULT} ${_PYTHON_DIRS} PARENT_SCOPE) -endfunction() - - -# If major version is specified, it must be the same as internal major version -if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR - AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") -endif() - - -# handle components -if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_FIND_COMPONENTS Interpreter) - set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE) -endif() -foreach (_${_PYTHON_PREFIX}_COMPONENT IN LISTS ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE) -endforeach() -unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - -# Set versions to search -## default: search any version -set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS}) - -if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER 1) - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}) - else() - unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - # add all compatible versions - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS) - if (${_PYTHON_PREFIX}_FIND_VERSION VERSION_LESS _${_PYTHON_PREFIX}_VERSION) - list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION}) - endif() - endforeach() - endif() -endif() - -# Anaconda distribution: define which architectures can be used -if (CMAKE_SIZEOF_VOID_P) - # In this case, search only for 64bit or 32bit - math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH}) -else() - # architecture unknown, search for both 64bit and 32bit - set (_${_PYTHON_PREFIX}_ARCH 64) - set (_${_PYTHON_PREFIX}_ARCH2 32) -endif() - -# IronPython support -if (CMAKE_SIZEOF_VOID_P) - # In this case, search only for 64bit or 32bit - math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy${_${_PYTHON_PREFIX}_ARCH} ipy) -else() - # architecture unknown, search for natural interpreter - set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy) -endif() -set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40) - -# Apple frameworks handling -_python_find_frameworks () - -# Save CMAKE_FIND_APPBUNDLE -if (DEFINED CMAKE_FIND_APPBUNDLE) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE}) -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -endif() -# To avoid app bundle lookup -set (CMAKE_FIND_APPBUNDLE "NEVER") - -# Save CMAKE_FIND_FRAMEWORK -if (DEFINED CMAKE_FIND_FRAMEWORK) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) - if (CMAKE_FIND_FRAMEWORK STREQUAL "ONLY") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: CMAKE_FIND_FRAMEWORK: 'ONLY' value is not supported. 'FIRST' will be used instead.") - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) - endif() -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") -endif() -# To avoid framework lookup -set (CMAKE_FIND_FRAMEWORK "NEVER") - -# Windows Registry handling -if (DEFINED ${_PYTHON_PREFIX}_FIND_REGISTRY) - if (NOT ${_PYTHON_PREFIX}_FIND_REGISTRY MATCHES "^(FIRST|LAST|NEVER)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_REGISTRY}: invalid value for '${_PYTHON_PREFIX}_FIND_REGISTRY'. 'FIRST', 'LAST' or 'NEVER' expected.") - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY ${${_PYTHON_PREFIX}_FIND_REGISTRY}) - endif() -else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") -endif() - - -unset (_${_PYTHON_PREFIX}_REQUIRED_VARS) -unset (_${_PYTHON_PREFIX}_CACHED_VARS) - - -# first step, search for the interpreter -if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) - endif() - - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - if (DEFINED ${_PYTHON_PREFIX}_EXECUTABLE AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_EXECUTABLE}") - set (_${_PYTHON_PREFIX}_EXECUTABLE "${${_PYTHON_PREFIX}_EXECUTABLE}" CACHE INTERNAL "") - elseif (DEFINED _${_PYTHON_PREFIX}_EXECUTABLE) - # check version validity - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS) - else() - _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS) - endif() - endif() - - if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) - # look-up for various versions and locations - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - - # Apple frameworks handling - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # Windows registry - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # try using HINTS - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) - - # Apple frameworks handling - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_DEFAULT_PATH) - endif() - - # Windows registry - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() - - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION}) - if (_${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - endforeach() - endif() - - if (NOT _${_PYTHON_PREFIX}_EXECUTABLE) - # No specific version found. Retry with generic names - # try using HINTS - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - find_program (_${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) - - _python_validate_interpreter () - endif() - - set (${_PYTHON_PREFIX}_EXECUTABLE "${_${_PYTHON_PREFIX}_EXECUTABLE}" CACHE FILEPATH "${_PYTHON_PREFIX} Interpreter") - - # retrieve exact version of executable found - if (${_PYTHON_PREFIX}_EXECUTABLE) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_VERSION - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 ${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 ${_PYTHON_PREFIX}_VERSION_PATCH) - else() - # Interpreter is not usable - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - unset (${_PYTHON_PREFIX}_VERSION) - endif() - endif() - - if (${_PYTHON_PREFIX}_EXECUTABLE - AND ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE) - # Use interpreter version for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - endif() - - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # retrieve interpreter identity - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -V - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID - ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID) - if (NOT _${_PYTHON_PREFIX}_RESULT) - if (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Anaconda") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda") - elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy") - else() - string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}") - if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python") - # try to get a more precise ID - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.copyright)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT - ERROR_QUIET) - if (${_PYTHON_PREFIX}_COPYRIGHT MATCHES "ActiveState") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "ActivePython") - endif() - endif() - endif() - else() - set (${_PYTHON_PREFIX}_INTERPRETER_ID Python) - endif() - else() - unset (${_PYTHON_PREFIX}_INTERPRETER_ID) - endif() - - # retrieve various package installation directories - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))" - - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 2 ${_PYTHON_PREFIX}_SITELIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 3 ${_PYTHON_PREFIX}_SITEARCH) - else() - unset (${_PYTHON_PREFIX}_STDLIB) - unset (${_PYTHON_PREFIX}_STDARCH) - unset (${_PYTHON_PREFIX}_SITELIB) - unset (${_PYTHON_PREFIX}_SITEARCH) - endif() - - mark_as_advanced (${_PYTHON_PREFIX}_EXECUTABLE) -endif() - - -# second step, search for compiler (IronPython) -if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_COMPILER) - endif() - - # IronPython specific artifacts - # If IronPython interpreter is found, use its path - unset (_${_PYTHON_PREFIX}_IRON_ROOT) - if (${_PYTHON_PREFIX}_Interpreter_FOUND AND ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - get_filename_component (_${_PYTHON_PREFIX}_IRON_ROOT "${${_PYTHON_PREFIX}_EXECUTABLE}" DIRECTORY) - endif() - - # try using root dir and registry - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() - - _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION}) - if (${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endforeach() - - # no specific version found, re-try in standard paths - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}) - - if (${_PYTHON_PREFIX}_COMPILER) - # retrieve python environment version from compiler - set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n") - execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - OUTPUT_QUIET - ERROR_QUIET) - execute_process (COMMAND "${_${_PYTHON_PREFIX}_VERSION_DIR}/version" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - else() - # compiler not usable - set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) - endif() - file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") - endif() - - if (${_PYTHON_PREFIX}_COMPILER) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # Compiler must be compatible with interpreter - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - # Use compiler version for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - endif() - endif() - - if (${_PYTHON_PREFIX}_Compiler_FOUND) - set (${_PYTHON_PREFIX}_COMPILER_ID IronPython) - else() - unset (${_PYTHON_PREFIX}_COMPILER_ID) - endif() - - mark_as_advanced (${_PYTHON_PREFIX}_COMPILER) -endif() - - -# third step, search for the development artifacts -## Development environment is not compatible with IronPython interpreter -if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_INCLUDE_DIR) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_INCLUDE_DIR) - endif() - - # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - if (DEFINED ${_PYTHON_PREFIX}_USE_STATIC_LIBS AND NOT WIN32) - set(_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(${_PYTHON_PREFIX}_USE_STATIC_LIBS) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - else() - list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - endif() - else() - endif() - - # if python interpreter is found, use its location and version to ensure consistency - # between interpreter and development environment - unset (_${_PYTHON_PREFIX}_PREFIX) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.PREFIX)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - unset (_${_PYTHON_PREFIX}_PREFIX) - endif() - endif() - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - # try to use pythonX.Y-config tool - set (_${_PYTHON_PREFIX}_CONFIG_NAMES) - if (DEFINED CMAKE_LIBRARY_ARCHITECTURE) - set (_${_PYTHON_PREFIX}_CONFIG_NAMES "${CMAKE_LIBRARY_ARCHITECTURE}-python${_${_PYTHON_PREFIX}_VERSION}-config") - endif() - list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES "python${_${_PYTHON_PREFIX}_VERSION}-config") - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - unset (_${_PYTHON_PREFIX}_CONFIG_NAMES) - - if (NOT _${_PYTHON_PREFIX}_CONFIG) - continue() - endif() - - # retrieve root install directory - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --prefix - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # python-config is not usable - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - continue() - endif() - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - # retrieve library - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - # retrieve library directory - string (REGEX MATCHALL "-L[^ ]+" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-L" "" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_LIB_DIRS}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_DIRS) - # retrieve library name - string (REGEX MATCHALL "-lpython[^ ]+" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-l" "" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_LIB_NAMES}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_NAMES) - - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} ${_${_PYTHON_PREFIX}_LIB_DIRS} - PATH_SUFFIXES lib - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # retrieve runtime library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_PATH} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - endif() - - # retrieve include directory - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --includes - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - # retrieve include directory - string (REGEX MATCHALL "-I[^ ]+" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-I" "" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIRS}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_DIRS) - - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - break() - endif() - endforeach() - - # Rely on HINTS and standard paths if config tool failed to locate artifacts - if (NOT (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) OR NOT ${_PYTHON_PREFIX}_INCLUDE_DIR) - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - - set (_${_PYTHON_PREFIX}_REGISTRY_PATHS - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # search in HINTS locations - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) - endif() - - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config) - # retrieve runtime library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - - if (WIN32) - # search for debug library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - # use library location as a hint - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - NO_DEFAULT_PATH) - else() - # search first in known locations - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs) - endif() - if (${_PYTHON_PREFIX}_LIBRARY_DEBUG) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - endif() - - # Don't search for include dir until library location is known - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) - - if (${_PYTHON_PREFIX}_EXECUTABLE) - # pick up include directory from configuration - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; import sysconfig; sys.stdout.write(sysconfig.get_path('include'))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PATH - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - file (TO_CMAKE_PATH "${_${_PYTHON_PREFIX}_PATH}" _${_PYTHON_PREFIX}_PATH) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PATH}") - endif() - endif() - - foreach (_${_PYTHON_PREFIX}_LIB IN ITEMS ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - if (${_${_PYTHON_PREFIX}_LIB}) - # Use the library's install prefix as a hint - if (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - else() - # assume library is in a directory under root - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${${_${_PYTHON_PREFIX}_LIB}}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") - endif() - endif() - endforeach() - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_HINTS) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - break() - endif() - endforeach() - - # search header file in standard locations - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h) - endif() - - if (${_PYTHON_PREFIX}_INCLUDE_DIR) - # retrieve version from header file - file (STRINGS "${${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" _${_PYTHON_PREFIX}_VERSION - REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") - string (REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" - _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_VERSION}") - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_Compiler_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - endif() - - # define public variables - include (${CMAKE_CURRENT_LIST_DIR}/../SelectLibraryConfigurations.cmake) - select_library_configurations (${_PYTHON_PREFIX}) - if (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - elseif (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - else() - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "$${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND") - endif() - - _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS - ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - if (UNIX) - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$") - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS}) - endif() - else() - _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - endif() - - set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${${_PYTHON_PREFIX}_INCLUDE_DIR}") - - mark_as_advanced (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_INCLUDE_DIR) - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND) - # development environment must be compatible with interpreter/compiler - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_Development_FOUND TRUE) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Development_FOUND TRUE) - endif() - endif() - - # Restore the original find library ordering - if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() -endif() - -# final validation -if (${_PYTHON_PREFIX}_VERSION_MAJOR AND - NOT ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") -endif() - -include (${CMAKE_CURRENT_LIST_DIR}/../FindPackageHandleStandardArgs.cmake) -find_package_handle_standard_args (${_PYTHON_PREFIX} - REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS} - VERSION_VAR ${_PYTHON_PREFIX}_VERSION - HANDLE_COMPONENTS) - -# Create imported targets and helper functions -if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Interpreter_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Interpreter) - add_executable (${_PYTHON_PREFIX}::Interpreter IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Interpreter - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_EXECUTABLE}") -endif() - -if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Compiler_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Compiler) - add_executable (${_PYTHON_PREFIX}::Compiler IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Compiler - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}") -endif() - -if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Development_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::Python) - - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED) - else() - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC) - endif() - - add_library (${_PYTHON_PREFIX}::Python ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED) - - set_property (TARGET ${_PYTHON_PREFIX}::Python - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}") - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - OR (${_PYTHON_PREFIX}_LIBRARY_DEBUG AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)) - # System manage shared libraries in two parts: import and runtime - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - else() - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARY}" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY}") - endif() - else() - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}") - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}") - else() - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY}") - endif() - endif() - - function(list_filter_exclude _list_name _value) - if(CMAKE_VERSION VERSION_LESS 3.12) - list(FIND ${_list_name} ${_value} _INDEX) - if(${_INDEX} GREATER -1) - list(REMOVE_AT ${_list_name} ${_INDEX}) - endif() - else() - list(FILTER ${_list_name} EXCLUDE REGEX ${_value}) - endif() - set(${_list_name} ${${_list_name}} PARENT_SCOPE) - endfunction() - - if (_${_PYTHON_PREFIX}_CONFIG AND _${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC") - # extend link information with dependent libraries - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "-[Ll][^ ]+" _${_PYTHON_PREFIX}_LINK_LIBRARIES "${_${_PYTHON_PREFIX}_FLAGS}") - # remove elements relative to python library itself - list_filter_exclude(_${_PYTHON_PREFIX}_LINK_LIBRARIES "-lpython") - #list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-lpython") - foreach (_${_PYTHON_PREFIX}_DIR IN LISTS ${_PYTHON_PREFIX}_LIBRARY_DIRS) - list_filter_exclude(_${_PYTHON_PREFIX}_LINK_LIBRARIES "-L${${_PYTHON_PREFIX}_DIR}") - #list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-L${${_PYTHON_PREFIX}_DIR}") - endforeach() - set_property (TARGET ${_PYTHON_PREFIX}::Python - PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES}) - endif() - endif() - - # - # PYTHON_ADD_LIBRARY ( [STATIC|SHARED|MODULE] src1 src2 ... srcN) - # It is used to build modules for python. - # - function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name) - cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY - "STATIC;SHARED;MODULE" "" "") - - unset (type) - if (NOT (PYTHON_ADD_LIBRARY_STATIC - OR PYTHON_ADD_LIBRARY_SHARED - OR PYTHON_ADD_LIBRARY_MODULE)) - set (type MODULE) - endif() - add_library (${name} ${type} ${ARGN}) - target_link_libraries (${name} PRIVATE ${prefix}::Python) - - # customize library name to follow module name rules - get_property (type TARGET ${name} PROPERTY TYPE) - if (type STREQUAL "MODULE_LIBRARY") - set_property (TARGET ${name} PROPERTY PREFIX "") - if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - set_property (TARGET ${name} PROPERTY SUFFIX ".pyd") - endif() - endif() - endfunction() -endif() - -# final clean-up - -# Restore CMAKE_FIND_APPBUNDLE -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) - set (CMAKE_FIND_APPBUNDLE ${_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -else() - unset (CMAKE_FIND_APPBUNDLE) -endif() -# Restore CMAKE_FIND_FRAMEWORK -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) - set (CMAKE_FIND_FRAMEWORK ${_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) -else() - unset (CMAKE_FIND_FRAMEWORK) -endif() - -unset (_${_PYTHON_PREFIX}_CONFIG CACHE) diff --git a/plugins/pycall/cmake/FindPython3.cmake b/plugins/pycall/cmake/FindPython3.cmake deleted file mode 100644 index 370abfdb5..000000000 --- a/plugins/pycall/cmake/FindPython3.cmake +++ /dev/null @@ -1,174 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPython3 ------------ - -Find Python 3 interpreter, compiler and development environment (include -directories and libraries). - -Three components are supported: - -* ``Interpreter``: search for Python 3 interpreter -* ``Compiler``: search for Python 3 compiler. Only offered by IronPython. -* ``Development``: search for development artifacts (include directories and - libraries) - -If no ``COMPONENTS`` is specified, ``Interpreter`` is assumed. - -To ensure consistent versions between components ``Interpreter``, ``Compiler`` -and ``Development``, specify all components at the same time:: - - find_package (Python3 COMPONENTS Interpreter Development) - -This module looks only for version 3 of Python. This module can be used -concurrently with :module:`FindPython2` module to use both Python versions. - -The :module:`FindPython` module can be used if Python version does not matter -for you. - -Imported Targets -^^^^^^^^^^^^^^^^ - -This module defines the following :ref:`Imported Targets `: - -``Python3::Interpreter`` - Python 3 interpreter. Target defined if component ``Interpreter`` is found. -``Python3::Compiler`` - Python 3 compiler. Target defined if component ``Compiler`` is found. -``Python3::Python`` - Python 3 library. Target defined if component ``Development`` is found. - -Result Variables -^^^^^^^^^^^^^^^^ - -This module will set the following variables in your project -(see :ref:`Standard Variable Names `): - -``Python3_FOUND`` - System has the Python 3 requested components. -``Python3_Interpreter_FOUND`` - System has the Python 3 interpreter. -``Python3_EXECUTABLE`` - Path to the Python 3 interpreter. -``Python3_INTERPRETER_ID`` - A short string unique to the interpreter. Possible values include: - * Python - * ActivePython - * Anaconda - * Canopy - * IronPython -``Python3_STDLIB`` - Standard platform independent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``. -``Python3_STDARCH`` - Standard platform dependent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``. -``Python3_SITELIB`` - Third-party platform independent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``. -``Python3_SITEARCH`` - Third-party platform dependent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``. -``Python3_Compiler_FOUND`` - System has the Python 3 compiler. -``Python3_COMPILER`` - Path to the Python 3 compiler. Only offered by IronPython. -``Python3_COMPILER_ID`` - A short string unique to the compiler. Possible values include: - * IronPython -``Python3_Development_FOUND`` - System has the Python 3 development artifacts. -``Python3_INCLUDE_DIRS`` - The Python 3 include directories. -``Python3_LIBRARIES`` - The Python 3 libraries. -``Python3_LIBRARY_DIRS`` - The Python 3 library directories. -``Python3_RUNTIME_LIBRARY_DIRS`` - The Python 3 runtime library directories. -``Python3_VERSION`` - Python 3 version. -``Python3_VERSION_MAJOR`` - Python 3 major version. -``Python3_VERSION_MINOR`` - Python 3 minor version. -``Python3_VERSION_PATCH`` - Python 3 patch version. - -Hints -^^^^^ - -``Python3_ROOT_DIR`` - Define the root directory of a Python 3 installation. - -``Python3_USE_STATIC_LIBS`` - * If not defined, search for shared libraries and static libraries in that - order. - * If set to TRUE, search **only** for static libraries. - * If set to FALSE, search **only** for shared libraries. - -``Python3_FIND_REGISTRY`` - On Windows the ``Python3_FIND_REGISTRY`` variable determine the order - of preference between registry and environment variables. - the ``Python3_FIND_REGISTRY`` variable can be set to empty or one of the - following: - - * ``FIRST``: Try to use registry before environment variables. - This is the default. - * ``LAST``: Try to use registry after environment variables. - * ``NEVER``: Never try to use registry. - -``CMAKE_FIND_FRAMEWORK`` - On OS X the :variable:`CMAKE_FIND_FRAMEWORK` variable determine the order of - preference between Apple-style and unix-style package components. - - .. note:: - - Value ``ONLY`` is not supported so ``FIRST`` will be used instead. - -Artifacts Specification -^^^^^^^^^^^^^^^^^^^^^^^ - -To solve special cases, it is possible to specify directly the artifacts by -setting the following variables: - -``Python3_EXECUTABLE`` - The path to the interpreter. - -Commands -^^^^^^^^ - -This module defines the command ``Python3_add_library`` which have the same -semantic as :command:`add_library` but take care of Python module naming rules -(only applied if library is of type ``MODULE``) and add dependency to target -``Python3::Python``:: - - Python3_add_library (my_module MODULE src1.cpp) - -If library type is not specified, ``MODULE`` is assumed. -#]=======================================================================] - - -set (_PYTHON_PREFIX Python3) - -set (_Python3_REQUIRED_VERSION_MAJOR 3) - -include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) - -if (COMMAND __Python3_add_library) - macro (Python3_add_library) - __Python3_add_library (Python3 ${ARGV}) - endmacro() -endif() - -unset (_PYTHON_PREFIX) diff --git a/plugins/pycall/cmake/SelectLibraryConfigurations.cmake b/plugins/pycall/cmake/SelectLibraryConfigurations.cmake deleted file mode 100644 index fe3bb00a6..000000000 --- a/plugins/pycall/cmake/SelectLibraryConfigurations.cmake +++ /dev/null @@ -1,71 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# SelectLibraryConfigurations -# --------------------------- -# -# -# -# select_library_configurations( basename ) -# -# This macro takes a library base name as an argument, and will choose -# good values for basename_LIBRARY, basename_LIBRARIES, -# basename_LIBRARY_DEBUG, and basename_LIBRARY_RELEASE depending on what -# has been found and set. If only basename_LIBRARY_RELEASE is defined, -# basename_LIBRARY will be set to the release value, and -# basename_LIBRARY_DEBUG will be set to basename_LIBRARY_DEBUG-NOTFOUND. -# If only basename_LIBRARY_DEBUG is defined, then basename_LIBRARY will -# take the debug value, and basename_LIBRARY_RELEASE will be set to -# basename_LIBRARY_RELEASE-NOTFOUND. -# -# If the generator supports configuration types, then basename_LIBRARY -# and basename_LIBRARIES will be set with debug and optimized flags -# specifying the library to be used for the given configuration. If no -# build type has been set or the generator in use does not support -# configuration types, then basename_LIBRARY and basename_LIBRARIES will -# take only the release value, or the debug value if the release one is -# not set. - -# This macro was adapted from the FindQt4 CMake module and is maintained by Will -# Dicharry . - -macro( select_library_configurations basename ) - if(NOT ${basename}_LIBRARY_RELEASE) - set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.") - endif() - if(NOT ${basename}_LIBRARY_DEBUG) - set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.") - endif() - - get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND - NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND - ( _isMultiConfig OR CMAKE_BUILD_TYPE ) ) - # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for - # single-config generators, set optimized and debug libraries - set( ${basename}_LIBRARY "" ) - foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE ) - list( APPEND ${basename}_LIBRARY optimized "${_libname}" ) - endforeach() - foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG ) - list( APPEND ${basename}_LIBRARY debug "${_libname}" ) - endforeach() - elseif( ${basename}_LIBRARY_RELEASE ) - set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) - elseif( ${basename}_LIBRARY_DEBUG ) - set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} ) - else() - set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND") - endif() - - set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" ) - - if( ${basename}_LIBRARY ) - set( ${basename}_FOUND TRUE ) - endif() - - mark_as_advanced( ${basename}_LIBRARY_RELEASE - ${basename}_LIBRARY_DEBUG - ) -endmacro() diff --git a/plugins/pycall/pycall.cxx b/plugins/pycall/pycall.cxx index 10539cb68..84a91eb7e 100644 --- a/plugins/pycall/pycall.cxx +++ b/plugins/pycall/pycall.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2019 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -116,7 +116,7 @@ class Trigger * \param with aliases of descriptors for python code */ Trigger(string code, PC_tree_t with) - : m_code{move(code)} + : m_code{std::move(code)} { if (!PC_status(PC_get(with, "{0}"))) { // parameters int nwith = len(with); @@ -133,7 +133,7 @@ class Trigger * \param with alias of descriptor for python code */ Trigger(string code, string with) - : m_code{move(code)} + : m_code{std::move(code)} { string var = string("$") + with; m_aliases.emplace_back(with, var); diff --git a/plugins/pycall/tests/CMakeLists.txt b/plugins/pycall/tests/CMakeLists.txt index 7a2eface9..60e119cfa 100644 --- a/plugins/pycall/tests/CMakeLists.txt +++ b/plugins/pycall/tests/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2020 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -27,8 +27,6 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -set(RUNTEST_DIR "${CMAKE_SOURCE_DIR}/cmake/runtest-dir") - # Add the plugin path to PDI_PLUGIN_PATH set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" PROPERTY TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/TestPath.cmake") file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/TestPath.cmake" diff --git a/plugins/serialize/CHANGELOG.md b/plugins/serialize/CHANGELOG.md index 7908d8188..d1a685cef 100644 --- a/plugins/serialize/CHANGELOG.md +++ b/plugins/serialize/CHANGELOG.md @@ -9,6 +9,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added ### Changed +* Fully qualify `std::move` calls to prevent a compilation warning and incorrect + usages [#675](https://github.com/pdidev/pdi/issues/675) ### Deprecated @@ -19,6 +21,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Security +## [1.10.0] - 2026-01-31 + +### Added +* Added macOS CI [#556](https://github.com/pdidev/pdi/issues/556) + +### Changed +* Update the version of dependencies according to our policy: oldest supported + Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: + CMake 3.22 [#613](https://github.com/pdidev/pdi/issues/613) + + ## [1.8.0] - 2024-11-28 ### Changed diff --git a/plugins/serialize/CMakeLists.txt b/plugins/serialize/CMakeLists.txt index ebef61664..512c55c28 100644 --- a/plugins/serialize/CMakeLists.txt +++ b/plugins/serialize/CMakeLists.txt @@ -1,6 +1,6 @@ #============================================================================= # Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) -# Copyright (C) 2020-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -23,9 +23,8 @@ # THE SOFTWARE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(pdi_serialize_plugin LANGUAGES C CXX) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") include(CTest) include(GNUInstallDirs) diff --git a/plugins/serialize/cmake/FindPackageHandleStandardArgs.cmake b/plugins/serialize/cmake/FindPackageHandleStandardArgs.cmake deleted file mode 100644 index 67f6bd6f2..000000000 --- a/plugins/serialize/cmake/FindPackageHandleStandardArgs.cmake +++ /dev/null @@ -1,386 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPackageHandleStandardArgs ------------------------------ - -This module provides a function intended to be used in :ref:`Find Modules` -implementing :command:`find_package()` calls. It handles the -``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. -It also sets the ``_FOUND`` variable. The package is -considered found if all variables listed contain valid results, e.g. -valid filepaths. - -.. command:: find_package_handle_standard_args - - There are two signatures:: - - find_package_handle_standard_args( - (DEFAULT_MSG|) - ... - ) - - find_package_handle_standard_args( - [FOUND_VAR ] - [REQUIRED_VARS ...] - [VERSION_VAR ] - [HANDLE_COMPONENTS] - [CONFIG_MODE] - [FAIL_MESSAGE ] - ) - - The ``_FOUND`` variable will be set to ``TRUE`` if all - the variables ``...`` are valid and any optional - constraints are satisfied, and ``FALSE`` otherwise. A success or - failure message may be displayed based on the results and on - whether the ``REQUIRED`` and/or ``QUIET`` option was given to - the :command:`find_package` call. - - The options are: - - ``(DEFAULT_MSG|)`` - In the simple signature this specifies the failure message. - Use ``DEFAULT_MSG`` to ask for a default message to be computed - (recommended). Not valid in the full signature. - - ``FOUND_VAR `` - Obsolete. Specifies either ``_FOUND`` or - ``_FOUND`` as the result variable. This exists only - for compatibility with older versions of CMake and is now ignored. - Result variables of both names are always set for compatibility. - - ``REQUIRED_VARS ...`` - Specify the variables which are required for this package. - These may be named in the generated failure message asking the - user to set the missing variable values. Therefore these should - typically be cache entries such as ``FOO_LIBRARY`` and not output - variables like ``FOO_LIBRARIES``. - - ``VERSION_VAR `` - Specify the name of a variable that holds the version of the package - that has been found. This version will be checked against the - (potentially) specified required version given to the - :command:`find_package` call, including its ``EXACT`` option. - The default messages include information about the required - version and the version which has been actually found, both - if the version is ok or not. - - ``HANDLE_COMPONENTS`` - Enable handling of package components. In this case, the command - will report which components have been found and which are missing, - and the ``_FOUND`` variable will be set to ``FALSE`` - if any of the required components (i.e. not the ones listed after - the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are - missing. - - ``CONFIG_MODE`` - Specify that the calling find module is a wrapper around a - call to ``find_package( NO_MODULE)``. This implies - a ``VERSION_VAR`` value of ``_VERSION``. The command - will automatically check whether the package configuration file - was found. - - ``FAIL_MESSAGE `` - Specify a custom failure message instead of using the default - generated message. Not recommended. - -Example for the simple signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibXml2 DEFAULT_MSG - LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) - -The ``LibXml2`` package is considered to be found if both -``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. -Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found -and ``REQUIRED`` was used, it fails with a -:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was -used or not. If it is found, success will be reported, including -the content of the first ````. On repeated CMake runs, -the same message will not be printed again. - -Example for the full signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibArchive - REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR - VERSION_VAR LibArchive_VERSION) - -In this case, the ``LibArchive`` package is considered to be found if -both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. -Also the version of ``LibArchive`` will be checked by using the version -contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, -the default messages will be printed. - -Another example for the full signature: - -.. code-block:: cmake - - find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) - find_package_handle_standard_args(Automoc4 CONFIG_MODE) - -In this case, a ``FindAutmoc4.cmake`` module wraps a call to -``find_package(Automoc4 NO_MODULE)`` and adds an additional search -directory for ``automoc4``. Then the call to -``find_package_handle_standard_args`` produces a proper success/failure -message. -#]=======================================================================] - -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - -# internal helper macro -macro(_FPHSA_FAILURE_MESSAGE _msg) - if (${_NAME}_FIND_REQUIRED) - message(FATAL_ERROR "${_msg}") - else () - if (NOT ${_NAME}_FIND_QUIETLY) - message(STATUS "${_msg}") - endif () - endif () -endmacro() - - -# internal helper macro to generate the failure message when used in CONFIG_MODE: -macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: - if(${_NAME}_CONFIG) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") - else() - # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. - # List them all in the error message: - if(${_NAME}_CONSIDERED_CONFIGS) - set(configsText "") - list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) - math(EXPR configsCount "${configsCount} - 1") - foreach(currentConfigIndex RANGE ${configsCount}) - list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) - list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) - string(APPEND configsText " ${filename} (version ${version})\n") - endforeach() - if (${_NAME}_NOT_FOUND_MESSAGE) - string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") - endif() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") - - else() - # Simple case: No Config-file was found at all: - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") - endif() - endif() -endmacro() - - -function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) - -# Set up the arguments for `cmake_parse_arguments`. - set(options CONFIG_MODE HANDLE_COMPONENTS) - set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) - set(multiValueArgs REQUIRED_VARS) - -# Check whether we are in 'simple' or 'extended' mode: - set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) - list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) - - if(${INDEX} EQUAL -1) - set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) - set(FPHSA_REQUIRED_VARS ${ARGN}) - set(FPHSA_VERSION_VAR) - else() - cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) - - if(FPHSA_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") - endif() - - if(NOT FPHSA_FAIL_MESSAGE) - set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") - endif() - - # In config-mode, we rely on the variable _CONFIG, which is set by find_package() - # when it successfully found the config-file, including version checking: - if(FPHSA_CONFIG_MODE) - list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) - list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) - set(FPHSA_VERSION_VAR ${_NAME}_VERSION) - endif() - - if(NOT FPHSA_REQUIRED_VARS) - message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") - endif() - endif() - -# now that we collected all arguments, process them - - if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") - set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") - endif() - - list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) - - string(TOUPPER ${_NAME} _NAME_UPPER) - string(TOLOWER ${_NAME} _NAME_LOWER) - - if(FPHSA_FOUND_VAR) - if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") - set(_FOUND_VAR ${FPHSA_FOUND_VAR}) - else() - message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") - endif() - else() - set(_FOUND_VAR ${_NAME_UPPER}_FOUND) - endif() - - # collect all variables which were not found, so they can be printed, so the - # user knows better what went wrong (#6375) - set(MISSING_VARS "") - set(DETAILS "") - # check if all passed variables are valid - set(FPHSA_FOUND_${_NAME} TRUE) - foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) - if(NOT ${_CURRENT_VAR}) - set(FPHSA_FOUND_${_NAME} FALSE) - string(APPEND MISSING_VARS " ${_CURRENT_VAR}") - else() - string(APPEND DETAILS "[${${_CURRENT_VAR}}]") - endif() - endforeach() - if(FPHSA_FOUND_${_NAME}) - set(${_NAME}_FOUND TRUE) - set(${_NAME_UPPER}_FOUND TRUE) - else() - set(${_NAME}_FOUND FALSE) - set(${_NAME_UPPER}_FOUND FALSE) - endif() - - # component handling - unset(FOUND_COMPONENTS_MSG) - unset(MISSING_COMPONENTS_MSG) - - if(FPHSA_HANDLE_COMPONENTS) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(${_NAME}_${comp}_FOUND) - - if(NOT DEFINED FOUND_COMPONENTS_MSG) - set(FOUND_COMPONENTS_MSG "found components: ") - endif() - string(APPEND FOUND_COMPONENTS_MSG " ${comp}") - - else() - - if(NOT DEFINED MISSING_COMPONENTS_MSG) - set(MISSING_COMPONENTS_MSG "missing components: ") - endif() - string(APPEND MISSING_COMPONENTS_MSG " ${comp}") - - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - string(APPEND MISSING_VARS " ${comp}") - endif() - - endif() - endforeach() - set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") - string(APPEND DETAILS "[c${COMPONENT_MSG}]") - endif() - - # version handling: - set(VERSION_MSG "") - set(VERSION_OK TRUE) - - # check with DEFINED here as the requested or found version may be "0" - if (DEFINED ${_NAME}_FIND_VERSION) - if(DEFINED ${FPHSA_VERSION_VAR}) - set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) - - if(${_NAME}_FIND_VERSION_EXACT) # exact version required - # count the dots in the version string - string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}") - # add one dot because there is one dot more than there are components - string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) - if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) - # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT - # is at most 4 here. Therefore a simple lookup table is used. - if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) - set(_VERSION_REGEX "[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) - set(_VERSION_REGEX "[^.]*\\.[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") - else () - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") - endif () - string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}") - unset(_VERSION_REGEX) - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - unset(_VERSION_HEAD) - else () - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - endif () - unset(_VERSION_DOTS) - - else() # minimum version specified: - if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") - endif () - endif() - - else() - - # if the package was not found, but a version was given, add that to the output: - if(${_NAME}_FIND_VERSION_EXACT) - set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") - else() - set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") - endif() - - endif() - else () - # Check with DEFINED as the found version may be 0. - if(DEFINED ${FPHSA_VERSION_VAR}) - set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") - endif() - endif () - - if(VERSION_OK) - string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") - else() - set(${_NAME}_FOUND FALSE) - endif() - - - # print the result: - if (${_NAME}_FOUND) - FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") - else () - - if(FPHSA_CONFIG_MODE) - _FPHSA_HANDLE_FAILURE_CONFIG_MODE() - else() - if(NOT VERSION_OK) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") - else() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") - endif() - endif() - - endif () - - set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) - set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) -endfunction() diff --git a/plugins/serialize/cmake/FindPackageMessage.cmake b/plugins/serialize/cmake/FindPackageMessage.cmake deleted file mode 100644 index 6821cee4f..000000000 --- a/plugins/serialize/cmake/FindPackageMessage.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# FindPackageMessage -# ------------------ -# -# -# -# FIND_PACKAGE_MESSAGE( "message for user" "find result details") -# -# This macro is intended to be used in FindXXX.cmake modules files. It -# will print a message once for each unique find result. This is useful -# for telling the user where a package was found. The first argument -# specifies the name (XXX) of the package. The second argument -# specifies the message to display. The third argument lists details -# about the find result so that if they change the message will be -# displayed again. The macro also obeys the QUIET argument to the -# find_package command. -# -# Example: -# -# :: -# -# if(X11_FOUND) -# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" -# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") -# else() -# ... -# endif() - -function(FIND_PACKAGE_MESSAGE pkg msg details) - # Avoid printing a message repeatedly for the same find result. - if(NOT ${pkg}_FIND_QUIETLY) - string(REPLACE "\n" "" details "${details}") - set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) - if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - # The message has not yet been printed. - message(STATUS "${msg}") - - # Save the find details in the cache to avoid printing the same - # message again. - set("${DETAILS_VAR}" "${details}" - CACHE INTERNAL "Details about finding ${pkg}") - endif() - endif() -endfunction() diff --git a/plugins/serialize/serialize.cxx b/plugins/serialize/serialize.cxx index 57b07e0cf..7cfd575fb 100644 --- a/plugins/serialize/serialize.cxx +++ b/plugins/serialize/serialize.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -98,7 +98,7 @@ struct serialize_plugin: PDI::Plugin { size_t spacing = (alignment - (offset % alignment)) % alignment; serialized_buffersize += spacing; - return PDI::Record_datatype::make(move(serialized_members), serialized_buffersize, record_type->attributes()); + return PDI::Record_datatype::make(std::move(serialized_members), serialized_buffersize, record_type->attributes()); } else if (auto&& pointer_type = dynamic_pointer_cast(type)) { return serialize_type(pointer_type->subtype()); } else if (auto&& tuple_type = dynamic_pointer_cast(type)) { @@ -130,7 +130,7 @@ struct serialize_plugin: PDI::Plugin { size_t spacing = (alignment - (offset % alignment)) % alignment; serialized_buffersize += spacing; - return PDI::Tuple_datatype::make(move(serialized_elements), serialized_buffersize, tuple_type->attributes()); + return PDI::Tuple_datatype::make(std::move(serialized_elements), serialized_buffersize, tuple_type->attributes()); } else { throw PDI::Type_error{"Serialize plugin: Unsupported type: {}", type->debug_string()}; } @@ -354,13 +354,13 @@ struct serialize_plugin: PDI::Plugin { // need to make a deserialize copy PDI::Ref_w ref_w{ref}; if (!ref_w) { - throw PDI::Right_error{"Serialize plugin: Cannot get write access to data: {}", desc_name}; + throw PDI::Permission_error{"Serialize plugin: Cannot get write access to data: {}", desc_name}; } // get write access, because it's for sure PDI_IN PDI::Ref_w serialized_ref{context().desc(serialized_name).ref()}; if (!serialized_ref) { - throw PDI::Right_error{"Serialize plugin: Cannot get write access to serialized data: {}", serialized_name}; + throw PDI::Permission_error{"Serialize plugin: Cannot get write access to serialized data: {}", serialized_name}; } size_t bytes_copied = deserialize_copy(ref.type(), ref_w.get(), serialized_ref.get()); diff --git a/plugins/serialize/tests/CMakeLists.txt b/plugins/serialize/tests/CMakeLists.txt index d8ad6e564..c22b811b8 100644 --- a/plugins/serialize/tests/CMakeLists.txt +++ b/plugins/serialize/tests/CMakeLists.txt @@ -1,6 +1,6 @@ #============================================================================= # Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) -# Copyright (C) 2020-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -23,11 +23,11 @@ # THE SOFTWARE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) if(NOT TARGET GTest::gtest) option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" OFF) - add_subdirectory("../../../vendor/googletest-b4aaf97/" "googletest" EXCLUDE_FROM_ALL) + add_subdirectory("../../../vendor/googletest-56efe39/" "googletest" EXCLUDE_FROM_ALL) endif() include(GoogleTest) @@ -47,6 +47,6 @@ endif() ) add_executable(serialize_tests serialize_tests.cxx) -target_compile_features(serialize_tests PUBLIC cxx_std_17) +target_compile_features(serialize_tests PUBLIC cxx_std_20) target_link_libraries(serialize_tests PDI::PDI_C GTest::gtest GTest::gtest_main) gtest_discover_tests(serialize_tests) diff --git a/plugins/set_value/CHANGELOG.md b/plugins/set_value/CHANGELOG.md index 6572bfcab..4f78a12d4 100644 --- a/plugins/set_value/CHANGELOG.md +++ b/plugins/set_value/CHANGELOG.md @@ -15,12 +15,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Removed ### Fixed -* Correct some tests that would incorrectly compare floats with abs instead of - fabs, rounding down to zero and hence never failing, even in the case of error ### Security +## [1.10.0] - 2026-01-31 + +### Added +* Added macOS CI [#556](https://github.com/pdidev/pdi/issues/556) + +### Changed +* Update the version of dependencies according to our policy: oldest supported + Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: + CMake 3.22, and spdlog 1.9.2 [#613](https://github.com/pdidev/pdi/issues/613) + +### Fixed +* Correct some tests that would incorrectly compare floats with abs instead of + fabs, rounding down to zero and hence never failing, even in the case of error + + ## [1.8.1] - 2025-01-23 ### Fixed diff --git a/plugins/set_value/CMakeLists.txt b/plugins/set_value/CMakeLists.txt index 7c4aaeab5..3595c47c2 100644 --- a/plugins/set_value/CMakeLists.txt +++ b/plugins/set_value/CMakeLists.txt @@ -1,6 +1,6 @@ #============================================================================= # Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) -# Copyright (C) 2020-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -23,16 +23,15 @@ # THE SOFTWARE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(pdi_set_value_plugin LANGUAGES C CXX) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") # Includes include(CTest) include(GNUInstallDirs) # spdlog -find_package(spdlog 1.5.0 REQUIRED) +find_package(spdlog 1.9 REQUIRED) # PDI find_package(PDI REQUIRED plugins) diff --git a/plugins/set_value/cmake/FindPackageHandleStandardArgs.cmake b/plugins/set_value/cmake/FindPackageHandleStandardArgs.cmake deleted file mode 100644 index 67f6bd6f2..000000000 --- a/plugins/set_value/cmake/FindPackageHandleStandardArgs.cmake +++ /dev/null @@ -1,386 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPackageHandleStandardArgs ------------------------------ - -This module provides a function intended to be used in :ref:`Find Modules` -implementing :command:`find_package()` calls. It handles the -``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. -It also sets the ``_FOUND`` variable. The package is -considered found if all variables listed contain valid results, e.g. -valid filepaths. - -.. command:: find_package_handle_standard_args - - There are two signatures:: - - find_package_handle_standard_args( - (DEFAULT_MSG|) - ... - ) - - find_package_handle_standard_args( - [FOUND_VAR ] - [REQUIRED_VARS ...] - [VERSION_VAR ] - [HANDLE_COMPONENTS] - [CONFIG_MODE] - [FAIL_MESSAGE ] - ) - - The ``_FOUND`` variable will be set to ``TRUE`` if all - the variables ``...`` are valid and any optional - constraints are satisfied, and ``FALSE`` otherwise. A success or - failure message may be displayed based on the results and on - whether the ``REQUIRED`` and/or ``QUIET`` option was given to - the :command:`find_package` call. - - The options are: - - ``(DEFAULT_MSG|)`` - In the simple signature this specifies the failure message. - Use ``DEFAULT_MSG`` to ask for a default message to be computed - (recommended). Not valid in the full signature. - - ``FOUND_VAR `` - Obsolete. Specifies either ``_FOUND`` or - ``_FOUND`` as the result variable. This exists only - for compatibility with older versions of CMake and is now ignored. - Result variables of both names are always set for compatibility. - - ``REQUIRED_VARS ...`` - Specify the variables which are required for this package. - These may be named in the generated failure message asking the - user to set the missing variable values. Therefore these should - typically be cache entries such as ``FOO_LIBRARY`` and not output - variables like ``FOO_LIBRARIES``. - - ``VERSION_VAR `` - Specify the name of a variable that holds the version of the package - that has been found. This version will be checked against the - (potentially) specified required version given to the - :command:`find_package` call, including its ``EXACT`` option. - The default messages include information about the required - version and the version which has been actually found, both - if the version is ok or not. - - ``HANDLE_COMPONENTS`` - Enable handling of package components. In this case, the command - will report which components have been found and which are missing, - and the ``_FOUND`` variable will be set to ``FALSE`` - if any of the required components (i.e. not the ones listed after - the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are - missing. - - ``CONFIG_MODE`` - Specify that the calling find module is a wrapper around a - call to ``find_package( NO_MODULE)``. This implies - a ``VERSION_VAR`` value of ``_VERSION``. The command - will automatically check whether the package configuration file - was found. - - ``FAIL_MESSAGE `` - Specify a custom failure message instead of using the default - generated message. Not recommended. - -Example for the simple signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibXml2 DEFAULT_MSG - LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) - -The ``LibXml2`` package is considered to be found if both -``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. -Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found -and ``REQUIRED`` was used, it fails with a -:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was -used or not. If it is found, success will be reported, including -the content of the first ````. On repeated CMake runs, -the same message will not be printed again. - -Example for the full signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibArchive - REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR - VERSION_VAR LibArchive_VERSION) - -In this case, the ``LibArchive`` package is considered to be found if -both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. -Also the version of ``LibArchive`` will be checked by using the version -contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, -the default messages will be printed. - -Another example for the full signature: - -.. code-block:: cmake - - find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) - find_package_handle_standard_args(Automoc4 CONFIG_MODE) - -In this case, a ``FindAutmoc4.cmake`` module wraps a call to -``find_package(Automoc4 NO_MODULE)`` and adds an additional search -directory for ``automoc4``. Then the call to -``find_package_handle_standard_args`` produces a proper success/failure -message. -#]=======================================================================] - -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - -# internal helper macro -macro(_FPHSA_FAILURE_MESSAGE _msg) - if (${_NAME}_FIND_REQUIRED) - message(FATAL_ERROR "${_msg}") - else () - if (NOT ${_NAME}_FIND_QUIETLY) - message(STATUS "${_msg}") - endif () - endif () -endmacro() - - -# internal helper macro to generate the failure message when used in CONFIG_MODE: -macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: - if(${_NAME}_CONFIG) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") - else() - # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. - # List them all in the error message: - if(${_NAME}_CONSIDERED_CONFIGS) - set(configsText "") - list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) - math(EXPR configsCount "${configsCount} - 1") - foreach(currentConfigIndex RANGE ${configsCount}) - list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) - list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) - string(APPEND configsText " ${filename} (version ${version})\n") - endforeach() - if (${_NAME}_NOT_FOUND_MESSAGE) - string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") - endif() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") - - else() - # Simple case: No Config-file was found at all: - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") - endif() - endif() -endmacro() - - -function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) - -# Set up the arguments for `cmake_parse_arguments`. - set(options CONFIG_MODE HANDLE_COMPONENTS) - set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) - set(multiValueArgs REQUIRED_VARS) - -# Check whether we are in 'simple' or 'extended' mode: - set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) - list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) - - if(${INDEX} EQUAL -1) - set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) - set(FPHSA_REQUIRED_VARS ${ARGN}) - set(FPHSA_VERSION_VAR) - else() - cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) - - if(FPHSA_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") - endif() - - if(NOT FPHSA_FAIL_MESSAGE) - set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") - endif() - - # In config-mode, we rely on the variable _CONFIG, which is set by find_package() - # when it successfully found the config-file, including version checking: - if(FPHSA_CONFIG_MODE) - list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) - list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) - set(FPHSA_VERSION_VAR ${_NAME}_VERSION) - endif() - - if(NOT FPHSA_REQUIRED_VARS) - message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") - endif() - endif() - -# now that we collected all arguments, process them - - if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") - set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") - endif() - - list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) - - string(TOUPPER ${_NAME} _NAME_UPPER) - string(TOLOWER ${_NAME} _NAME_LOWER) - - if(FPHSA_FOUND_VAR) - if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") - set(_FOUND_VAR ${FPHSA_FOUND_VAR}) - else() - message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") - endif() - else() - set(_FOUND_VAR ${_NAME_UPPER}_FOUND) - endif() - - # collect all variables which were not found, so they can be printed, so the - # user knows better what went wrong (#6375) - set(MISSING_VARS "") - set(DETAILS "") - # check if all passed variables are valid - set(FPHSA_FOUND_${_NAME} TRUE) - foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) - if(NOT ${_CURRENT_VAR}) - set(FPHSA_FOUND_${_NAME} FALSE) - string(APPEND MISSING_VARS " ${_CURRENT_VAR}") - else() - string(APPEND DETAILS "[${${_CURRENT_VAR}}]") - endif() - endforeach() - if(FPHSA_FOUND_${_NAME}) - set(${_NAME}_FOUND TRUE) - set(${_NAME_UPPER}_FOUND TRUE) - else() - set(${_NAME}_FOUND FALSE) - set(${_NAME_UPPER}_FOUND FALSE) - endif() - - # component handling - unset(FOUND_COMPONENTS_MSG) - unset(MISSING_COMPONENTS_MSG) - - if(FPHSA_HANDLE_COMPONENTS) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(${_NAME}_${comp}_FOUND) - - if(NOT DEFINED FOUND_COMPONENTS_MSG) - set(FOUND_COMPONENTS_MSG "found components: ") - endif() - string(APPEND FOUND_COMPONENTS_MSG " ${comp}") - - else() - - if(NOT DEFINED MISSING_COMPONENTS_MSG) - set(MISSING_COMPONENTS_MSG "missing components: ") - endif() - string(APPEND MISSING_COMPONENTS_MSG " ${comp}") - - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - string(APPEND MISSING_VARS " ${comp}") - endif() - - endif() - endforeach() - set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") - string(APPEND DETAILS "[c${COMPONENT_MSG}]") - endif() - - # version handling: - set(VERSION_MSG "") - set(VERSION_OK TRUE) - - # check with DEFINED here as the requested or found version may be "0" - if (DEFINED ${_NAME}_FIND_VERSION) - if(DEFINED ${FPHSA_VERSION_VAR}) - set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) - - if(${_NAME}_FIND_VERSION_EXACT) # exact version required - # count the dots in the version string - string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}") - # add one dot because there is one dot more than there are components - string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) - if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) - # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT - # is at most 4 here. Therefore a simple lookup table is used. - if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) - set(_VERSION_REGEX "[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) - set(_VERSION_REGEX "[^.]*\\.[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") - else () - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") - endif () - string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}") - unset(_VERSION_REGEX) - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - unset(_VERSION_HEAD) - else () - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - endif () - unset(_VERSION_DOTS) - - else() # minimum version specified: - if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") - endif () - endif() - - else() - - # if the package was not found, but a version was given, add that to the output: - if(${_NAME}_FIND_VERSION_EXACT) - set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") - else() - set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") - endif() - - endif() - else () - # Check with DEFINED as the found version may be 0. - if(DEFINED ${FPHSA_VERSION_VAR}) - set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") - endif() - endif () - - if(VERSION_OK) - string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") - else() - set(${_NAME}_FOUND FALSE) - endif() - - - # print the result: - if (${_NAME}_FOUND) - FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") - else () - - if(FPHSA_CONFIG_MODE) - _FPHSA_HANDLE_FAILURE_CONFIG_MODE() - else() - if(NOT VERSION_OK) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") - else() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") - endif() - endif() - - endif () - - set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) - set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) -endfunction() diff --git a/plugins/set_value/cmake/FindPackageMessage.cmake b/plugins/set_value/cmake/FindPackageMessage.cmake deleted file mode 100644 index 6821cee4f..000000000 --- a/plugins/set_value/cmake/FindPackageMessage.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# FindPackageMessage -# ------------------ -# -# -# -# FIND_PACKAGE_MESSAGE( "message for user" "find result details") -# -# This macro is intended to be used in FindXXX.cmake modules files. It -# will print a message once for each unique find result. This is useful -# for telling the user where a package was found. The first argument -# specifies the name (XXX) of the package. The second argument -# specifies the message to display. The third argument lists details -# about the find result so that if they change the message will be -# displayed again. The macro also obeys the QUIET argument to the -# find_package command. -# -# Example: -# -# :: -# -# if(X11_FOUND) -# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" -# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") -# else() -# ... -# endif() - -function(FIND_PACKAGE_MESSAGE pkg msg details) - # Avoid printing a message repeatedly for the same find result. - if(NOT ${pkg}_FIND_QUIETLY) - string(REPLACE "\n" "" details "${details}") - set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) - if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - # The message has not yet been printed. - message(STATUS "${msg}") - - # Save the find details in the cache to avoid printing the same - # message again. - set("${DETAILS_VAR}" "${details}" - CACHE INTERNAL "Details about finding ${pkg}") - endif() - endif() -endfunction() diff --git a/plugins/set_value/cmake/FindPython/Support.cmake b/plugins/set_value/cmake/FindPython/Support.cmake deleted file mode 100644 index 375a4afc5..000000000 --- a/plugins/set_value/cmake/FindPython/Support.cmake +++ /dev/null @@ -1,1229 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -# -# This file is a "template" file used by various FindPython modules. -# - -cmake_policy (VERSION 3.16...3.25) - -# -# Initial configuration -# -if (NOT DEFINED _PYTHON_PREFIX) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() -if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 3) - set(_${_PYTHON_PREFIX}_VERSIONS 3.20 3.19 3.18 3.17 3.16 3.15 3.14 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0) -elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 2) - set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) -else() - message (FATAL_ERROR "FindPython: INTERNAL ERROR") -endif() - - -# -# helper commands -# -macro (_PYTHON_DISPLAY_FAILURE _PYTHON_MSG) - if (${_PYTHON_PREFIX}_FIND_REQUIRED) - message (FATAL_ERROR "${_PYTHON_MSG}") - else() - if (NOT ${_PYTHON_PREFIX}_FIND_QUIETLY) - message(STATUS "${_PYTHON_MSG}") - endif () - endif() - - set (${_PYTHON_PREFIX}_FOUND FALSE) - string (TOUPPER "${_PYTHON_PREFIX}" _${_PYTHON_PREFIX}_UPPER_PREFIX) - set (${_PYTHON_UPPER_PREFIX}_FOUND FALSE) - return() -endmacro() - - -macro (_PYTHON_FIND_FRAMEWORKS) - set (${_PYTHON_PREFIX}_FRAMEWORKS) - if (APPLE) - set (_pff_frameworks ${CMAKE_FRAMEWORK_PATH} - $ENV{CMAKE_FRAMEWORK_PATH} - ~/Library/Frameworks - /usr/local/Frameworks - ${CMAKE_SYSTEM_FRAMEWORK_PATH}) - list (REMOVE_DUPLICATES _pff_frameworks) - foreach (_pff_framework IN LISTS _pff_frameworks) - if (EXISTS ${_pff_framework}/Python.framework) - list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python.framework) - endif() - endforeach() - unset (_pff_frameworks) - unset (_pff_framework) - endif() -endmacro() - -function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION) - set (_PYTHON_FRAMEWORK_PATHS) - foreach (_PYTHON_FRAMEWORK IN LISTS ${_PYTHON_PREFIX}_FRAMEWORKS) - list (APPEND _PYTHON_FRAMEWORK_PATHS - "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}") - endforeach() - set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${_PYTHON_FRAMEWORK_PATHS} PARENT_SCOPE) -endfunction() - - -function (_PYTHON_VALIDATE_INTERPRETER) - if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) - return() - endif() - - if (ARGC EQUAL 1) - set (expected_version ${ARGV0}) - else() - unset (expected_version) - endif() - - get_filename_component (python_name "${${_PYTHON_PREFIX}_EXECUTABLE}" NAME) - - if (expected_version AND NOT python_name STREQUAL "python${expected_version}${CMAKE_EXECUTABLE_SUFFIX}") - # executable found must have a specific version - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL expected_version) - # interpreter not usable or has wrong major version - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - else() - if (NOT python_name STREQUAL "python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}${CMAKE_EXECUTABLE_SUFFIX}") - # executable found do not have version in name - # ensure major version is OK - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write(str(sys.version_info[0]))" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - # interpreter not usable or has wrong major version - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - endif() - endif() - - if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND NOT CMAKE_CROSSCOMPILING) - # In this case, interpreter must have same architecture as environment - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))" - RESULT_VARIABLE result - OUTPUT_VARIABLE size - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P) - # interpreter not usable or has wrong architecture - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - return() - endif() - endif() -endfunction() - - -function (_PYTHON_VALIDATE_COMPILER expected_version) - if (NOT ${_PYTHON_PREFIX}_COMPILER) - return() - endif() - - # retrieve python environment version from compiler - set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))\n") - execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${working_dir}/version.py" - WORKING_DIRECTORY "${working_dir}" - OUTPUT_QUIET - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process (COMMAND "${working_dir}/version" - WORKING_DIRECTORY "${working_dir}" - RESULT_VARIABLE result - OUTPUT_VARIABLE version - ERROR_QUIET) - file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") - - if (result OR NOT version EQUAL expected_version) - # Compiler not usable or has wrong major version - set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) - endif() -endfunction() - - -function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB) - string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}") - # look at runtime part on systems supporting it - if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR - (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN" - AND ${_PYTHON_LIB} MATCHES "${CMAKE_IMPORT_LIBRARY_SUFFIX}$")) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) - # MSYS has a special syntax for runtime libraries - if (CMAKE_SYSTEM_NAME MATCHES "MSYS") - list (APPEND CMAKE_FIND_LIBRARY_PREFIXES "msys-") - endif() - find_library (${ARGV}) - endif() -endfunction() - - -function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT) - unset (_PYTHON_DIRS) - set (_PYTHON_LIBS ${ARGV}) - list (REMOVE_AT _PYTHON_LIBS 0) - foreach (_PYTHON_LIB IN LISTS _PYTHON_LIBS) - if (${_PYTHON_LIB}) - get_filename_component (_PYTHON_DIR "${${_PYTHON_LIB}}" DIRECTORY) - list (APPEND _PYTHON_DIRS "${_PYTHON_DIR}") - endif() - endforeach() - if (_PYTHON_DIRS) - list (REMOVE_DUPLICATES _PYTHON_DIRS) - endif() - set (${_PYTHON_SLD_RESULT} ${_PYTHON_DIRS} PARENT_SCOPE) -endfunction() - - -# If major version is specified, it must be the same as internal major version -if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR - AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Wrong major version specified is \"${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}\", but expected major version is \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") -endif() - - -# handle components -if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_FIND_COMPONENTS Interpreter) - set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE) -endif() -foreach (_${_PYTHON_PREFIX}_COMPONENT IN LISTS ${_PYTHON_PREFIX}_FIND_COMPONENTS) - set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE) -endforeach() -unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - -# Set versions to search -## default: search any version -set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS}) - -if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER 1) - if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT) - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}) - else() - unset (_${_PYTHON_PREFIX}_FIND_VERSIONS) - # add all compatible versions - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS) - if (${_PYTHON_PREFIX}_FIND_VERSION VERSION_LESS _${_PYTHON_PREFIX}_VERSION) - list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION}) - endif() - endforeach() - endif() -endif() - -# Anaconda distribution: define which architectures can be used -if (CMAKE_SIZEOF_VOID_P) - # In this case, search only for 64bit or 32bit - math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH}) -else() - # architecture unknown, search for both 64bit and 32bit - set (_${_PYTHON_PREFIX}_ARCH 64) - set (_${_PYTHON_PREFIX}_ARCH2 32) -endif() - -# IronPython support -if (CMAKE_SIZEOF_VOID_P) - # In this case, search only for 64bit or 32bit - math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8") - set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy${_${_PYTHON_PREFIX}_ARCH} ipy) -else() - # architecture unknown, search for natural interpreter - set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy) -endif() -set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40) - -# Apple frameworks handling -_python_find_frameworks () - -# Save CMAKE_FIND_APPBUNDLE -if (DEFINED CMAKE_FIND_APPBUNDLE) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE}) -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -endif() -# To avoid app bundle lookup -set (CMAKE_FIND_APPBUNDLE "NEVER") - -# Save CMAKE_FIND_FRAMEWORK -if (DEFINED CMAKE_FIND_FRAMEWORK) - set (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) - if (CMAKE_FIND_FRAMEWORK STREQUAL "ONLY") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: CMAKE_FIND_FRAMEWORK: 'ONLY' value is not supported. 'FIRST' will be used instead.") - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) - endif() -else() - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) - set (_${_PYTHON_PREFIX}_FIND_FRAMEWORK "FIRST") -endif() -# To avoid framework lookup -set (CMAKE_FIND_FRAMEWORK "NEVER") - -# Windows Registry handling -if (DEFINED ${_PYTHON_PREFIX}_FIND_REGISTRY) - if (NOT ${_PYTHON_PREFIX}_FIND_REGISTRY MATCHES "^(FIRST|LAST|NEVER)$") - message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_REGISTRY}: invalid value for '${_PYTHON_PREFIX}_FIND_REGISTRY'. 'FIRST', 'LAST' or 'NEVER' expected.") - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") - else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY ${${_PYTHON_PREFIX}_FIND_REGISTRY}) - endif() -else() - set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST") -endif() - - -unset (_${_PYTHON_PREFIX}_REQUIRED_VARS) -unset (_${_PYTHON_PREFIX}_CACHED_VARS) - - -# first step, search for the interpreter -if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_EXECUTABLE) - endif() - - set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - # look-up for various versions and locations - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - - # Apple frameworks handling - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # Windows registry - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # try using HINTS - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) - - # Apple frameworks handling - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES bin - NO_DEFAULT_PATH) - endif() - - # Windows registry - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_VERSION} - python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - NAMES_PER_DIR - PATHS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() - - _python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION}) - if (${_PYTHON_PREFIX}_EXECUTABLE) - break() - endif() - endforeach() - - if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) - # No specific version found. Retry with generic names - # try using HINTS - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # try using standard paths. - # NAMES_PER_DIR is not defined on purpose to have a chance to find - # expected version. - # For example, typical systems have 'python' for version 2.* and 'python3' - # for version 3.*. So looking for names per dir will find, potentially, - # systematically 'python' (i.e. version 2) even if version 3 is searched. - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} - python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}) - - _python_validate_interpreter () - endif() - - # retrieve exact version of executable found - if (${_PYTHON_PREFIX}_EXECUTABLE) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_VERSION - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 ${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 ${_PYTHON_PREFIX}_VERSION_PATCH) - else() - # Interpreter is not usable - set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) - unset (${_PYTHON_PREFIX}_VERSION) - endif() - endif() - - if (${_PYTHON_PREFIX}_EXECUTABLE - AND ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE) - # Use interpreter version for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - endif() - - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # retrieve interpreter identity - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -V - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID - ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID) - if (NOT _${_PYTHON_PREFIX}_RESULT) - if (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Anaconda") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda") - elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy") - else() - string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}") - if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python") - # try to get a more precise ID - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.copyright)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT - ERROR_QUIET) - if (${_PYTHON_PREFIX}_COPYRIGHT MATCHES "ActiveState") - set (${_PYTHON_PREFIX}_INTERPRETER_ID "ActivePython") - endif() - endif() - endif() - else() - set (${_PYTHON_PREFIX}_INTERPRETER_ID Python) - endif() - else() - unset (${_PYTHON_PREFIX}_INTERPRETER_ID) - endif() - - # retrieve various package installation directories - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))" - - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 2 ${_PYTHON_PREFIX}_SITELIB) - list (GET _${_PYTHON_PREFIX}_LIBPATHS 3 ${_PYTHON_PREFIX}_SITEARCH) - else() - unset (${_PYTHON_PREFIX}_STDLIB) - unset (${_PYTHON_PREFIX}_STDARCH) - unset (${_PYTHON_PREFIX}_SITELIB) - unset (${_PYTHON_PREFIX}_SITEARCH) - endif() - - mark_as_advanced (${_PYTHON_PREFIX}_EXECUTABLE) -endif() - - -# second step, search for compiler (IronPython) -if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Compiler) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_COMPILER) - endif() - - # IronPython specific artifacts - # If IronPython interpreter is found, use its path - unset (_${_PYTHON_PREFIX}_IRON_ROOT) - if (${_PYTHON_PREFIX}_Interpreter_FOUND AND ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - get_filename_component (_${_PYTHON_PREFIX}_IRON_ROOT "${${_PYTHON_PREFIX}_EXECUTABLE}" DIRECTORY) - endif() - - # try using root dir and registry - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES} - NO_DEFAULT_PATH) - endif() - - _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION}) - if (${_PYTHON_PREFIX}_COMPILER) - break() - endif() - endforeach() - - # no specific version found, re-try in standard paths - find_program (${_PYTHON_PREFIX}_COMPILER - NAMES ipyc - HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}) - - if (${_PYTHON_PREFIX}_COMPILER) - # retrieve python environment version from compiler - set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir") - file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n") - execute_process (COMMAND "${${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - OUTPUT_QUIET - ERROR_QUIET) - execute_process (COMMAND "${_${_PYTHON_PREFIX}_VERSION_DIR}/version" - WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION - ERROR_QUIET) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - else() - # compiler not usable - set (${_PYTHON_PREFIX}_COMPILER ${_PYTHON_PREFIX}_COMPILER-NOTFOUND CACHE INTERNAL "" FORCE) - endif() - file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}") - endif() - - if (${_PYTHON_PREFIX}_COMPILER) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - # Compiler must be compatible with interpreter - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE) - # Use compiler version for future searches to ensure consistency - set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - endif() - endif() - - if (${_PYTHON_PREFIX}_Compiler_FOUND) - set (${_PYTHON_PREFIX}_COMPILER_ID IronPython) - else() - unset (${_PYTHON_PREFIX}_COMPILER_ID) - endif() - - mark_as_advanced (${_PYTHON_PREFIX}_COMPILER) -endif() - - -# third step, search for the development artifacts -## Development environment is not compatible with IronPython interpreter -if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython") - if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development) - list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_INCLUDE_DIR) - list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS ${_PYTHON_PREFIX}_LIBRARY - ${_PYTHON_PREFIX}_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_INCLUDE_DIR) - endif() - - # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - if (DEFINED ${_PYTHON_PREFIX}_USE_STATIC_LIBS AND NOT WIN32) - set(_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(${_PYTHON_PREFIX}_USE_STATIC_LIBS) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - else() - list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) - endif() - else() - endif() - - # if python interpreter is found, use its location and version to ensure consistency - # between interpreter and development environment - unset (_${_PYTHON_PREFIX}_PREFIX) - if (${_PYTHON_PREFIX}_Interpreter_FOUND) - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.PREFIX)" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - unset (_${_PYTHON_PREFIX}_PREFIX) - endif() - endif() - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - # try to use pythonX.Y-config tool - set (_${_PYTHON_PREFIX}_CONFIG_NAMES) - if (DEFINED CMAKE_LIBRARY_ARCHITECTURE) - set (_${_PYTHON_PREFIX}_CONFIG_NAMES "${CMAKE_LIBRARY_ARCHITECTURE}-python${_${_PYTHON_PREFIX}_VERSION}-config") - endif() - list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES "python${_${_PYTHON_PREFIX}_VERSION}-config") - find_program (_${_PYTHON_PREFIX}_CONFIG - NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - unset (_${_PYTHON_PREFIX}_CONFIG_NAMES) - - if (NOT _${_PYTHON_PREFIX}_CONFIG) - continue() - endif() - - # retrieve root install directory - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --prefix - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (_${_PYTHON_PREFIX}_RESULT) - # python-config is not usable - unset (_${_PYTHON_PREFIX}_CONFIG CACHE) - continue() - endif() - set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR) - - # retrieve library - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - # retrieve library directory - string (REGEX MATCHALL "-L[^ ]+" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-L" "" _${_PYTHON_PREFIX}_LIB_DIRS "${_${_PYTHON_PREFIX}_LIB_DIRS}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_DIRS) - # retrieve library name - string (REGEX MATCHALL "-lpython[^ ]+" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-l" "" _${_PYTHON_PREFIX}_LIB_NAMES "${_${_PYTHON_PREFIX}_LIB_NAMES}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_LIB_NAMES) - - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} ${_${_PYTHON_PREFIX}_LIB_DIRS} - PATH_SUFFIXES lib - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - # retrieve runtime library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_PATH} ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - endif() - - # retrieve include directory - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --includes - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - # retrieve include directory - string (REGEX MATCHALL "-I[^ ]+" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_FLAGS}") - string (REPLACE "-I" "" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIRS}") - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_DIRS) - - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS} - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - break() - endif() - endforeach() - - # Rely on HINTS and standard paths if config tool failed to locate artifacts - if (NOT (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) OR NOT ${_PYTHON_PREFIX}_INCLUDE_DIR) - foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS) - string (REPLACE "." "" _${_PYTHON_PREFIX}_VERSION_NO_DOTS ${_${_PYTHON_PREFIX}_VERSION}) - - _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) - - set (_${_PYTHON_PREFIX}_REGISTRY_PATHS - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - # search in HINTS locations - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST") - set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}) - else() - unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS) - endif() - - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u - lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} - lib/python${_${_PYTHON_PREFIX}_VERSION}/config) - # retrieve runtime library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} - python${_${_PYTHON_PREFIX}_VERSION}mu - python${_${_PYTHON_PREFIX}_VERSION}m - python${_${_PYTHON_PREFIX}_VERSION}u - python${_${_PYTHON_PREFIX}_VERSION} - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - - if (WIN32) - # search for debug library - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) - # use library location as a hint - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY) - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - NO_DEFAULT_PATH) - else() - # search first in known locations - if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - # search in all default paths - find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES lib libs) - endif() - if (${_PYTHON_PREFIX}_LIBRARY_DEBUG) - get_filename_component (_${_PYTHON_PREFIX}_PATH "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY) - _python_find_runtime_library (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d - NAMES_PER_DIR - HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) - endif() - endif() - - # Don't search for include dir until library location is known - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS) - - if (${_PYTHON_PREFIX}_EXECUTABLE) - # pick up include directory from configuration - execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c - "import sys; import sysconfig; sys.stdout.write(sysconfig.get_path('include'))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PATH - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - file (TO_CMAKE_PATH "${_${_PYTHON_PREFIX}_PATH}" _${_PYTHON_PREFIX}_PATH) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PATH}") - endif() - endif() - - foreach (_${_PYTHON_PREFIX}_LIB IN ITEMS ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - if (${_${_PYTHON_PREFIX}_LIB}) - # Use the library's install prefix as a hint - if (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIB} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}") - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}") - else() - # assume library is in a directory under root - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${${_${_PYTHON_PREFIX}_LIB}}" DIRECTORY) - get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY) - list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}") - endif() - endif() - endforeach() - list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_HINTS) - - if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST") - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h - HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS} - PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS} - ${__${_PYTHON_PREFIX}_REGISTRY_PATHS} - PATH_SUFFIXES include/python${_${_PYTHON_PREFIX}_VERSION}mu - include/python${_${_PYTHON_PREFIX}_VERSION}m - include/python${_${_PYTHON_PREFIX}_VERSION}u - include/python${_${_PYTHON_PREFIX}_VERSION} - include - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_SYSTEM_PATH) - endif() - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - break() - endif() - endforeach() - - # search header file in standard locations - find_path (${_PYTHON_PREFIX}_INCLUDE_DIR - NAMES Python.h) - endif() - - if (${_PYTHON_PREFIX}_INCLUDE_DIR) - # retrieve version from header file - file (STRINGS "${${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" _${_PYTHON_PREFIX}_VERSION - REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") - string (REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" - _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_VERSION}") - string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${_${_PYTHON_PREFIX}_VERSION}") - list (GET _${_PYTHON_PREFIX}_VERSIONS 0 _${_PYTHON_PREFIX}_VERSION_MAJOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 1 _${_PYTHON_PREFIX}_VERSION_MINOR) - list (GET _${_PYTHON_PREFIX}_VERSIONS 2 _${_PYTHON_PREFIX}_VERSION_PATCH) - - if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT ${_PYTHON_PREFIX}_Compiler_FOUND) - # set public version information - set (${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_VERSION}) - set (${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_VERSION_MAJOR}) - set (${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_VERSION_PATCH}) - endif() - endif() - - # define public variables - include (${CMAKE_CURRENT_LIST_DIR}/../SelectLibraryConfigurations.cmake) - select_library_configurations (${_PYTHON_PREFIX}) - if (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - elseif (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - else() - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "$${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND") - endif() - - _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS - ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - if (UNIX) - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$") - set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS}) - endif() - else() - _python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - endif() - - set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${${_PYTHON_PREFIX}_INCLUDE_DIR}") - - mark_as_advanced (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE - ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG - ${_PYTHON_PREFIX}_INCLUDE_DIR) - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - AND ${_PYTHON_PREFIX}_INCLUDE_DIR) - if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND) - # development environment must be compatible with interpreter/compiler - if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}) - set (${_PYTHON_PREFIX}_Development_FOUND TRUE) - endif() - elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - set (${_PYTHON_PREFIX}_Development_FOUND TRUE) - endif() - endif() - - # Restore the original find library ordering - if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES) - set (CMAKE_FIND_LIBRARY_SUFFIXES ${_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() -endif() - -# final validation -if (${_PYTHON_PREFIX}_VERSION_MAJOR AND - NOT ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) - _python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"") -endif() - -include (${CMAKE_CURRENT_LIST_DIR}/../FindPackageHandleStandardArgs.cmake) -find_package_handle_standard_args (${_PYTHON_PREFIX} - REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS} - VERSION_VAR ${_PYTHON_PREFIX}_VERSION - HANDLE_COMPONENTS) - -# Create imported targets and helper functions -if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Interpreter_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Interpreter) - add_executable (${_PYTHON_PREFIX}::Interpreter IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Interpreter - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_EXECUTABLE}") -endif() - -if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Compiler_FOUND - AND NOT TARGET ${_PYTHON_PREFIX}::Compiler) - add_executable (${_PYTHON_PREFIX}::Compiler IMPORTED) - set_property (TARGET ${_PYTHON_PREFIX}::Compiler - PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}") -endif() - -if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS - AND ${_PYTHON_PREFIX}_Development_FOUND AND NOT TARGET ${_PYTHON_PREFIX}::Python) - - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$" - OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG) - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE SHARED) - else() - set (_${_PYTHON_PREFIX}_LIBRARY_TYPE STATIC) - endif() - - add_library (${_PYTHON_PREFIX}::Python ${_${_PYTHON_PREFIX}_LIBRARY_TYPE} IMPORTED) - - set_property (TARGET ${_PYTHON_PREFIX}::Python - PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIR}") - - if ((${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE) - OR (${_PYTHON_PREFIX}_LIBRARY_DEBUG AND ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)) - # System manage shared libraries in two parts: import and runtime - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_IMPLIB_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}") - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_IMPLIB_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}") - else() - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARY}" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY}") - endif() - else() - if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG) - set_property (TARGET ${_PYTHON_PREFIX}::Python PROPERTY IMPORTED_CONFIGURATIONS RELEASE DEBUG) - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" - IMPORTED_LOCATION_RELEASE "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}") - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" - IMPORTED_LOCATION_DEBUG "${${_PYTHON_PREFIX}_LIBRARY_DEBUG}") - else() - set_target_properties (${_PYTHON_PREFIX}::Python - PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" - IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY}") - endif() - endif() - - function(list_filter_exclude _list_name _value) - if(CMAKE_VERSION VERSION_LESS 3.12) - list(FIND ${_list_name} ${_value} _INDEX) - if(${_INDEX} GREATER -1) - list(REMOVE_AT ${_list_name} ${_INDEX}) - endif() - else() - list(FILTER ${_list_name} EXCLUDE REGEX ${_value}) - endif() - set(${_list_name} ${${_list_name}} PARENT_SCOPE) - endfunction() - - if (_${_PYTHON_PREFIX}_CONFIG AND _${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC") - # extend link information with dependent libraries - execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT - OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT _${_PYTHON_PREFIX}_RESULT) - string (REGEX MATCHALL "-[Ll][^ ]+" _${_PYTHON_PREFIX}_LINK_LIBRARIES "${_${_PYTHON_PREFIX}_FLAGS}") - # remove elements relative to python library itself - list_filter_exclude(_${_PYTHON_PREFIX}_LINK_LIBRARIES "-lpython") - #list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-lpython") - foreach (_${_PYTHON_PREFIX}_DIR IN LISTS ${_PYTHON_PREFIX}_LIBRARY_DIRS) - list_filter_exclude(_${_PYTHON_PREFIX}_LINK_LIBRARIES "-L${${_PYTHON_PREFIX}_DIR}") - #list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-L${${_PYTHON_PREFIX}_DIR}") - endforeach() - set_property (TARGET ${_PYTHON_PREFIX}::Python - PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES}) - endif() - endif() - - # - # PYTHON_ADD_LIBRARY ( [STATIC|SHARED|MODULE] src1 src2 ... srcN) - # It is used to build modules for python. - # - function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name) - cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY - "STATIC;SHARED;MODULE" "" "") - - unset (type) - if (NOT (PYTHON_ADD_LIBRARY_STATIC - OR PYTHON_ADD_LIBRARY_SHARED - OR PYTHON_ADD_LIBRARY_MODULE)) - set (type MODULE) - endif() - add_library (${name} ${type} ${ARGN}) - target_link_libraries (${name} PRIVATE ${prefix}::Python) - - # customize library name to follow module name rules - get_property (type TARGET ${name} PROPERTY TYPE) - if (type STREQUAL "MODULE_LIBRARY") - set_property (TARGET ${name} PROPERTY PREFIX "") - if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - set_property (TARGET ${name} PROPERTY SUFFIX ".pyd") - endif() - endif() - endfunction() -endif() - -# final clean-up - -# Restore CMAKE_FIND_APPBUNDLE -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) - set (CMAKE_FIND_APPBUNDLE ${_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_APPBUNDLE) -else() - unset (CMAKE_FIND_APPBUNDLE) -endif() -# Restore CMAKE_FIND_FRAMEWORK -if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) - set (CMAKE_FIND_FRAMEWORK ${_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK}) - unset (_${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) -else() - unset (CMAKE_FIND_FRAMEWORK) -endif() - -unset (_${_PYTHON_PREFIX}_CONFIG CACHE) diff --git a/plugins/set_value/cmake/FindPython3.cmake b/plugins/set_value/cmake/FindPython3.cmake deleted file mode 100644 index ed7e1a31b..000000000 --- a/plugins/set_value/cmake/FindPython3.cmake +++ /dev/null @@ -1,165 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPython3 ------------ - -Find Python 3 interpreter, compiler and development environment (include -directories and libraries). - -Three components are supported: - -* ``Interpreter``: search for Python 3 interpreter -* ``Compiler``: search for Python 3 compiler. Only offered by IronPython. -* ``Development``: search for development artifacts (include directories and - libraries) - -If no ``COMPONENTS`` is specified, ``Interpreter`` is assumed. - -To ensure consistent versions between components ``Interpreter``, ``Compiler`` -and ``Development``, specify all components at the same time:: - - find_package (Python3 COMPONENTS Interpreter Development) - -This module looks only for version 3 of Python. This module can be used -concurrently with :module:`FindPython2` module to use both Python versions. - -The :module:`FindPython` module can be used if Python version does not matter -for you. - -Imported Targets -^^^^^^^^^^^^^^^^ - -This module defines the following :ref:`Imported Targets `: - -``Python3::Interpreter`` - Python 3 interpreter. Target defined if component ``Interpreter`` is found. -``Python3::Compiler`` - Python 3 compiler. Target defined if component ``Compiler`` is found. -``Python3::Python`` - Python 3 library. Target defined if component ``Development`` is found. - -Result Variables -^^^^^^^^^^^^^^^^ - -This module will set the following variables in your project -(see :ref:`Standard Variable Names `): - -``Python3_FOUND`` - System has the Python 3 requested components. -``Python3_Interpreter_FOUND`` - System has the Python 3 interpreter. -``Python3_EXECUTABLE`` - Path to the Python 3 interpreter. -``Python3_INTERPRETER_ID`` - A short string unique to the interpreter. Possible values include: - * Python - * ActivePython - * Anaconda - * Canopy - * IronPython -``Python3_STDLIB`` - Standard platform independent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``. -``Python3_STDARCH`` - Standard platform dependent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``. -``Python3_SITELIB`` - Third-party platform independent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``. -``Python3_SITEARCH`` - Third-party platform dependent installation directory. - - Information returned by - ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``. -``Python3_Compiler_FOUND`` - System has the Python 3 compiler. -``Python3_COMPILER`` - Path to the Python 3 compiler. Only offered by IronPython. -``Python3_COMPILER_ID`` - A short string unique to the compiler. Possible values include: - * IronPython -``Python3_Development_FOUND`` - System has the Python 3 development artifacts. -``Python3_INCLUDE_DIRS`` - The Python 3 include directories. -``Python3_LIBRARIES`` - The Python 3 libraries. -``Python3_LIBRARY_DIRS`` - The Python 3 library directories. -``Python3_RUNTIME_LIBRARY_DIRS`` - The Python 3 runtime library directories. -``Python3_VERSION`` - Python 3 version. -``Python3_VERSION_MAJOR`` - Python 3 major version. -``Python3_VERSION_MINOR`` - Python 3 minor version. -``Python3_VERSION_PATCH`` - Python 3 patch version. - -Hints -^^^^^ - -``Python3_ROOT_DIR`` - Define the root directory of a Python 3 installation. - -``Python3_USE_STATIC_LIBS`` - * If not defined, search for shared libraries and static libraries in that - order. - * If set to TRUE, search **only** for static libraries. - * If set to FALSE, search **only** for shared libraries. - -``Python3_FIND_REGISTRY`` - On Windows the ``Python3_FIND_REGISTRY`` variable determine the order - of preference between registry and environment variables. - the ``Python3_FIND_REGISTRY`` variable can be set to empty or one of the - following: - - * ``FIRST``: Try to use registry before environment variables. - This is the default. - * ``LAST``: Try to use registry after environment variables. - * ``NEVER``: Never try to use registry. - -``CMAKE_FIND_FRAMEWORK`` - On OS X the :variable:`CMAKE_FIND_FRAMEWORK` variable determine the order of - preference between Apple-style and unix-style package components. - - .. note:: - - Value ``ONLY`` is not supported so ``FIRST`` will be used instead. - -Commands -^^^^^^^^ - -This module defines the command ``Python3_add_library`` which have the same -semantic as :command:`add_library` but take care of Python module naming rules -(only applied if library is of type ``MODULE``) and add dependency to target -``Python3::Python``:: - - Python3_add_library (my_module MODULE src1.cpp) - -If library type is not specified, ``MODULE`` is assumed. -#]=======================================================================] - - -set (_PYTHON_PREFIX Python3) - -set (_Python3_REQUIRED_VERSION_MAJOR 3) - -include (${CMAKE_CURRENT_LIST_DIR}/FindPython/Support.cmake) - -if (COMMAND __Python3_add_library) - macro (Python3_add_library) - __Python3_add_library (Python3 ${ARGV}) - endmacro() -endif() - -unset (_PYTHON_PREFIX) diff --git a/plugins/set_value/set_operation.cxx b/plugins/set_value/set_operation.cxx index 56a4a8771..bc56d07de 100644 --- a/plugins/set_value/set_operation.cxx +++ b/plugins/set_value/set_operation.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2021-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -61,7 +61,7 @@ void Set_operation::execute() context().logger().trace("Copy value to {} with size {} B", data_to_set.first, value_ref.type()->buffersize()); memcpy(existing_ref_w.get(), value_ref.get(), existing_ref_w.type()->buffersize()); } else { - throw PDI::Right_error{"Cannot get write access for `{}' to set values", data_to_set.first}; + throw PDI::Permission_error{"Cannot get write access for `{}' to set values", data_to_set.first}; } } } diff --git a/plugins/set_value/tests/CMakeLists.txt b/plugins/set_value/tests/CMakeLists.txt index 5e2e10472..98fd2d47e 100644 --- a/plugins/set_value/tests/CMakeLists.txt +++ b/plugins/set_value/tests/CMakeLists.txt @@ -1,6 +1,6 @@ #============================================================================= # Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) -# Copyright (C) 2020-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -23,7 +23,7 @@ # THE SOFTWARE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) set(RUNTEST_DIR "${CMAKE_CURRENT_LIST_DIR}/../cmake/runtest-dir") diff --git a/plugins/set_value/tests/Python/CMakeLists.txt b/plugins/set_value/tests/Python/CMakeLists.txt index 0a1bb156c..55f2e6b1b 100644 --- a/plugins/set_value/tests/Python/CMakeLists.txt +++ b/plugins/set_value/tests/Python/CMakeLists.txt @@ -1,6 +1,6 @@ #============================================================================= # Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) -# Copyright (C) 2020-2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -23,9 +23,9 @@ # THE SOFTWARE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) -find_package(Python3 3.8.2 REQUIRED COMPONENTS Interpreter) +find_package(Python3 3.10 REQUIRED COMPONENTS Interpreter) set(Python_ADDITIONAL_VERSIONS "${Python3_VERSION}" CACHE STRING "Python version found by FindPython3 for coherency") set(RUNTEST_DIR "${CMAKE_CURRENT_LIST_DIR}/../../cmake/runtest-dir") diff --git a/plugins/set_value/trigger.cxx b/plugins/set_value/trigger.cxx index 64b978467..2b0248683 100644 --- a/plugins/set_value/trigger.cxx +++ b/plugins/set_value/trigger.cxx @@ -1,4 +1,5 @@ /******************************************************************************* + * Copyright (C) 2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2020-2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -39,7 +40,7 @@ Trigger::Trigger(PDI::Context& ctx, PC_tree_t operation_list_node) : m_ctx{ctx} { if (!PDI::is_list(operation_list_node)) { - throw PDI::Config_error{operation_list_node, "Operations must be defined as a list"}; + throw PDI::Spectree_error{operation_list_node, "Operations must be defined as a list"}; } size_t operations_count = PDI::len(operation_list_node); @@ -61,7 +62,7 @@ Trigger::Trigger(PDI::Context& ctx, PC_tree_t operation_list_node) } else if (operation == "logger") { m_operations.emplace_back(new Logger_operation{m_ctx, operation_value}); } else { - throw PDI::Config_error{PC_get(value_map, "{0}"), "Unknown operation: {}", operation}; + throw PDI::Spectree_error{PC_get(value_map, "{0}"), "Unknown operation: {}", operation}; } } } diff --git a/plugins/trace/CHANGELOG.md b/plugins/trace/CHANGELOG.md index 1b8b64561..bad9280ea 100644 --- a/plugins/trace/CHANGELOG.md +++ b/plugins/trace/CHANGELOG.md @@ -19,6 +19,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Security +## [1.10.0] - 2026-01-31 + +### Added +* Added macOS CI [#556](https://github.com/pdidev/pdi/issues/556) + +### Changed +* Update the version of dependencies according to our policy: oldest supported + Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: + CMake 3.22 [#613](https://github.com/pdidev/pdi/issues/613) + + ## [1.8.0] - 2024-11-28 ### Changed diff --git a/plugins/trace/CMakeLists.txt b/plugins/trace/CMakeLists.txt index 85b91457e..a55320184 100644 --- a/plugins/trace/CMakeLists.txt +++ b/plugins/trace/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -22,9 +22,8 @@ # THE SOFTWARE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(pdi_trace_plugin LANGUAGES C CXX) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") # Includes include(GNUInstallDirs) diff --git a/plugins/trace/cmake/FindPackageHandleStandardArgs.cmake b/plugins/trace/cmake/FindPackageHandleStandardArgs.cmake deleted file mode 100644 index 67f6bd6f2..000000000 --- a/plugins/trace/cmake/FindPackageHandleStandardArgs.cmake +++ /dev/null @@ -1,386 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPackageHandleStandardArgs ------------------------------ - -This module provides a function intended to be used in :ref:`Find Modules` -implementing :command:`find_package()` calls. It handles the -``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. -It also sets the ``_FOUND`` variable. The package is -considered found if all variables listed contain valid results, e.g. -valid filepaths. - -.. command:: find_package_handle_standard_args - - There are two signatures:: - - find_package_handle_standard_args( - (DEFAULT_MSG|) - ... - ) - - find_package_handle_standard_args( - [FOUND_VAR ] - [REQUIRED_VARS ...] - [VERSION_VAR ] - [HANDLE_COMPONENTS] - [CONFIG_MODE] - [FAIL_MESSAGE ] - ) - - The ``_FOUND`` variable will be set to ``TRUE`` if all - the variables ``...`` are valid and any optional - constraints are satisfied, and ``FALSE`` otherwise. A success or - failure message may be displayed based on the results and on - whether the ``REQUIRED`` and/or ``QUIET`` option was given to - the :command:`find_package` call. - - The options are: - - ``(DEFAULT_MSG|)`` - In the simple signature this specifies the failure message. - Use ``DEFAULT_MSG`` to ask for a default message to be computed - (recommended). Not valid in the full signature. - - ``FOUND_VAR `` - Obsolete. Specifies either ``_FOUND`` or - ``_FOUND`` as the result variable. This exists only - for compatibility with older versions of CMake and is now ignored. - Result variables of both names are always set for compatibility. - - ``REQUIRED_VARS ...`` - Specify the variables which are required for this package. - These may be named in the generated failure message asking the - user to set the missing variable values. Therefore these should - typically be cache entries such as ``FOO_LIBRARY`` and not output - variables like ``FOO_LIBRARIES``. - - ``VERSION_VAR `` - Specify the name of a variable that holds the version of the package - that has been found. This version will be checked against the - (potentially) specified required version given to the - :command:`find_package` call, including its ``EXACT`` option. - The default messages include information about the required - version and the version which has been actually found, both - if the version is ok or not. - - ``HANDLE_COMPONENTS`` - Enable handling of package components. In this case, the command - will report which components have been found and which are missing, - and the ``_FOUND`` variable will be set to ``FALSE`` - if any of the required components (i.e. not the ones listed after - the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are - missing. - - ``CONFIG_MODE`` - Specify that the calling find module is a wrapper around a - call to ``find_package( NO_MODULE)``. This implies - a ``VERSION_VAR`` value of ``_VERSION``. The command - will automatically check whether the package configuration file - was found. - - ``FAIL_MESSAGE `` - Specify a custom failure message instead of using the default - generated message. Not recommended. - -Example for the simple signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibXml2 DEFAULT_MSG - LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) - -The ``LibXml2`` package is considered to be found if both -``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. -Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found -and ``REQUIRED`` was used, it fails with a -:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was -used or not. If it is found, success will be reported, including -the content of the first ````. On repeated CMake runs, -the same message will not be printed again. - -Example for the full signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibArchive - REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR - VERSION_VAR LibArchive_VERSION) - -In this case, the ``LibArchive`` package is considered to be found if -both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. -Also the version of ``LibArchive`` will be checked by using the version -contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, -the default messages will be printed. - -Another example for the full signature: - -.. code-block:: cmake - - find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) - find_package_handle_standard_args(Automoc4 CONFIG_MODE) - -In this case, a ``FindAutmoc4.cmake`` module wraps a call to -``find_package(Automoc4 NO_MODULE)`` and adds an additional search -directory for ``automoc4``. Then the call to -``find_package_handle_standard_args`` produces a proper success/failure -message. -#]=======================================================================] - -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - -# internal helper macro -macro(_FPHSA_FAILURE_MESSAGE _msg) - if (${_NAME}_FIND_REQUIRED) - message(FATAL_ERROR "${_msg}") - else () - if (NOT ${_NAME}_FIND_QUIETLY) - message(STATUS "${_msg}") - endif () - endif () -endmacro() - - -# internal helper macro to generate the failure message when used in CONFIG_MODE: -macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: - if(${_NAME}_CONFIG) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") - else() - # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. - # List them all in the error message: - if(${_NAME}_CONSIDERED_CONFIGS) - set(configsText "") - list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) - math(EXPR configsCount "${configsCount} - 1") - foreach(currentConfigIndex RANGE ${configsCount}) - list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) - list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) - string(APPEND configsText " ${filename} (version ${version})\n") - endforeach() - if (${_NAME}_NOT_FOUND_MESSAGE) - string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") - endif() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") - - else() - # Simple case: No Config-file was found at all: - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") - endif() - endif() -endmacro() - - -function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) - -# Set up the arguments for `cmake_parse_arguments`. - set(options CONFIG_MODE HANDLE_COMPONENTS) - set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) - set(multiValueArgs REQUIRED_VARS) - -# Check whether we are in 'simple' or 'extended' mode: - set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) - list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) - - if(${INDEX} EQUAL -1) - set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) - set(FPHSA_REQUIRED_VARS ${ARGN}) - set(FPHSA_VERSION_VAR) - else() - cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) - - if(FPHSA_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") - endif() - - if(NOT FPHSA_FAIL_MESSAGE) - set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") - endif() - - # In config-mode, we rely on the variable _CONFIG, which is set by find_package() - # when it successfully found the config-file, including version checking: - if(FPHSA_CONFIG_MODE) - list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) - list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) - set(FPHSA_VERSION_VAR ${_NAME}_VERSION) - endif() - - if(NOT FPHSA_REQUIRED_VARS) - message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") - endif() - endif() - -# now that we collected all arguments, process them - - if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") - set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") - endif() - - list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) - - string(TOUPPER ${_NAME} _NAME_UPPER) - string(TOLOWER ${_NAME} _NAME_LOWER) - - if(FPHSA_FOUND_VAR) - if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") - set(_FOUND_VAR ${FPHSA_FOUND_VAR}) - else() - message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") - endif() - else() - set(_FOUND_VAR ${_NAME_UPPER}_FOUND) - endif() - - # collect all variables which were not found, so they can be printed, so the - # user knows better what went wrong (#6375) - set(MISSING_VARS "") - set(DETAILS "") - # check if all passed variables are valid - set(FPHSA_FOUND_${_NAME} TRUE) - foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) - if(NOT ${_CURRENT_VAR}) - set(FPHSA_FOUND_${_NAME} FALSE) - string(APPEND MISSING_VARS " ${_CURRENT_VAR}") - else() - string(APPEND DETAILS "[${${_CURRENT_VAR}}]") - endif() - endforeach() - if(FPHSA_FOUND_${_NAME}) - set(${_NAME}_FOUND TRUE) - set(${_NAME_UPPER}_FOUND TRUE) - else() - set(${_NAME}_FOUND FALSE) - set(${_NAME_UPPER}_FOUND FALSE) - endif() - - # component handling - unset(FOUND_COMPONENTS_MSG) - unset(MISSING_COMPONENTS_MSG) - - if(FPHSA_HANDLE_COMPONENTS) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(${_NAME}_${comp}_FOUND) - - if(NOT DEFINED FOUND_COMPONENTS_MSG) - set(FOUND_COMPONENTS_MSG "found components: ") - endif() - string(APPEND FOUND_COMPONENTS_MSG " ${comp}") - - else() - - if(NOT DEFINED MISSING_COMPONENTS_MSG) - set(MISSING_COMPONENTS_MSG "missing components: ") - endif() - string(APPEND MISSING_COMPONENTS_MSG " ${comp}") - - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - string(APPEND MISSING_VARS " ${comp}") - endif() - - endif() - endforeach() - set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") - string(APPEND DETAILS "[c${COMPONENT_MSG}]") - endif() - - # version handling: - set(VERSION_MSG "") - set(VERSION_OK TRUE) - - # check with DEFINED here as the requested or found version may be "0" - if (DEFINED ${_NAME}_FIND_VERSION) - if(DEFINED ${FPHSA_VERSION_VAR}) - set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) - - if(${_NAME}_FIND_VERSION_EXACT) # exact version required - # count the dots in the version string - string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}") - # add one dot because there is one dot more than there are components - string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) - if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) - # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT - # is at most 4 here. Therefore a simple lookup table is used. - if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) - set(_VERSION_REGEX "[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) - set(_VERSION_REGEX "[^.]*\\.[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") - else () - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") - endif () - string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}") - unset(_VERSION_REGEX) - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - unset(_VERSION_HEAD) - else () - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - endif () - unset(_VERSION_DOTS) - - else() # minimum version specified: - if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") - endif () - endif() - - else() - - # if the package was not found, but a version was given, add that to the output: - if(${_NAME}_FIND_VERSION_EXACT) - set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") - else() - set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") - endif() - - endif() - else () - # Check with DEFINED as the found version may be 0. - if(DEFINED ${FPHSA_VERSION_VAR}) - set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") - endif() - endif () - - if(VERSION_OK) - string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") - else() - set(${_NAME}_FOUND FALSE) - endif() - - - # print the result: - if (${_NAME}_FOUND) - FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") - else () - - if(FPHSA_CONFIG_MODE) - _FPHSA_HANDLE_FAILURE_CONFIG_MODE() - else() - if(NOT VERSION_OK) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") - else() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") - endif() - endif() - - endif () - - set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) - set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) -endfunction() diff --git a/plugins/trace/cmake/FindPackageMessage.cmake b/plugins/trace/cmake/FindPackageMessage.cmake deleted file mode 100644 index 6821cee4f..000000000 --- a/plugins/trace/cmake/FindPackageMessage.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# FindPackageMessage -# ------------------ -# -# -# -# FIND_PACKAGE_MESSAGE( "message for user" "find result details") -# -# This macro is intended to be used in FindXXX.cmake modules files. It -# will print a message once for each unique find result. This is useful -# for telling the user where a package was found. The first argument -# specifies the name (XXX) of the package. The second argument -# specifies the message to display. The third argument lists details -# about the find result so that if they change the message will be -# displayed again. The macro also obeys the QUIET argument to the -# find_package command. -# -# Example: -# -# :: -# -# if(X11_FOUND) -# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" -# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") -# else() -# ... -# endif() - -function(FIND_PACKAGE_MESSAGE pkg msg details) - # Avoid printing a message repeatedly for the same find result. - if(NOT ${pkg}_FIND_QUIETLY) - string(REPLACE "\n" "" details "${details}") - set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) - if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - # The message has not yet been printed. - message(STATUS "${msg}") - - # Save the find details in the cache to avoid printing the same - # message again. - set("${DETAILS_VAR}" "${details}" - CACHE INTERNAL "Details about finding ${pkg}") - endif() - endif() -endfunction() diff --git a/plugins/user_code/CHANGELOG.md b/plugins/user_code/CHANGELOG.md index 101cdf53b..3ad17abd8 100644 --- a/plugins/user_code/CHANGELOG.md +++ b/plugins/user_code/CHANGELOG.md @@ -19,6 +19,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Security +## [1.10.0] - 2026-01-31 + +### Added +* Added macOS CI [#556](https://github.com/pdidev/pdi/issues/556) + +### Changed +* Update the version of dependencies according to our policy: oldest supported + Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: + CMake 3.22 [#613](https://github.com/pdidev/pdi/issues/613) + + ## [1.9.0] - 2025-03-07 ### Fixed diff --git a/plugins/user_code/CMakeLists.txt b/plugins/user_code/CMakeLists.txt index 29455406a..1444fdb50 100644 --- a/plugins/user_code/CMakeLists.txt +++ b/plugins/user_code/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -27,9 +27,8 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(pdi_user_code_plugin LANGUAGES C CXX) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") include(CTest) diff --git a/plugins/user_code/cmake/FindPackageHandleStandardArgs.cmake b/plugins/user_code/cmake/FindPackageHandleStandardArgs.cmake deleted file mode 100644 index 67f6bd6f2..000000000 --- a/plugins/user_code/cmake/FindPackageHandleStandardArgs.cmake +++ /dev/null @@ -1,386 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -FindPackageHandleStandardArgs ------------------------------ - -This module provides a function intended to be used in :ref:`Find Modules` -implementing :command:`find_package()` calls. It handles the -``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. -It also sets the ``_FOUND`` variable. The package is -considered found if all variables listed contain valid results, e.g. -valid filepaths. - -.. command:: find_package_handle_standard_args - - There are two signatures:: - - find_package_handle_standard_args( - (DEFAULT_MSG|) - ... - ) - - find_package_handle_standard_args( - [FOUND_VAR ] - [REQUIRED_VARS ...] - [VERSION_VAR ] - [HANDLE_COMPONENTS] - [CONFIG_MODE] - [FAIL_MESSAGE ] - ) - - The ``_FOUND`` variable will be set to ``TRUE`` if all - the variables ``...`` are valid and any optional - constraints are satisfied, and ``FALSE`` otherwise. A success or - failure message may be displayed based on the results and on - whether the ``REQUIRED`` and/or ``QUIET`` option was given to - the :command:`find_package` call. - - The options are: - - ``(DEFAULT_MSG|)`` - In the simple signature this specifies the failure message. - Use ``DEFAULT_MSG`` to ask for a default message to be computed - (recommended). Not valid in the full signature. - - ``FOUND_VAR `` - Obsolete. Specifies either ``_FOUND`` or - ``_FOUND`` as the result variable. This exists only - for compatibility with older versions of CMake and is now ignored. - Result variables of both names are always set for compatibility. - - ``REQUIRED_VARS ...`` - Specify the variables which are required for this package. - These may be named in the generated failure message asking the - user to set the missing variable values. Therefore these should - typically be cache entries such as ``FOO_LIBRARY`` and not output - variables like ``FOO_LIBRARIES``. - - ``VERSION_VAR `` - Specify the name of a variable that holds the version of the package - that has been found. This version will be checked against the - (potentially) specified required version given to the - :command:`find_package` call, including its ``EXACT`` option. - The default messages include information about the required - version and the version which has been actually found, both - if the version is ok or not. - - ``HANDLE_COMPONENTS`` - Enable handling of package components. In this case, the command - will report which components have been found and which are missing, - and the ``_FOUND`` variable will be set to ``FALSE`` - if any of the required components (i.e. not the ones listed after - the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are - missing. - - ``CONFIG_MODE`` - Specify that the calling find module is a wrapper around a - call to ``find_package( NO_MODULE)``. This implies - a ``VERSION_VAR`` value of ``_VERSION``. The command - will automatically check whether the package configuration file - was found. - - ``FAIL_MESSAGE `` - Specify a custom failure message instead of using the default - generated message. Not recommended. - -Example for the simple signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibXml2 DEFAULT_MSG - LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) - -The ``LibXml2`` package is considered to be found if both -``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. -Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found -and ``REQUIRED`` was used, it fails with a -:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was -used or not. If it is found, success will be reported, including -the content of the first ````. On repeated CMake runs, -the same message will not be printed again. - -Example for the full signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibArchive - REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR - VERSION_VAR LibArchive_VERSION) - -In this case, the ``LibArchive`` package is considered to be found if -both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. -Also the version of ``LibArchive`` will be checked by using the version -contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, -the default messages will be printed. - -Another example for the full signature: - -.. code-block:: cmake - - find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) - find_package_handle_standard_args(Automoc4 CONFIG_MODE) - -In this case, a ``FindAutmoc4.cmake`` module wraps a call to -``find_package(Automoc4 NO_MODULE)`` and adds an additional search -directory for ``automoc4``. Then the call to -``find_package_handle_standard_args`` produces a proper success/failure -message. -#]=======================================================================] - -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) - -# internal helper macro -macro(_FPHSA_FAILURE_MESSAGE _msg) - if (${_NAME}_FIND_REQUIRED) - message(FATAL_ERROR "${_msg}") - else () - if (NOT ${_NAME}_FIND_QUIETLY) - message(STATUS "${_msg}") - endif () - endif () -endmacro() - - -# internal helper macro to generate the failure message when used in CONFIG_MODE: -macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) - # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: - if(${_NAME}_CONFIG) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") - else() - # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. - # List them all in the error message: - if(${_NAME}_CONSIDERED_CONFIGS) - set(configsText "") - list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) - math(EXPR configsCount "${configsCount} - 1") - foreach(currentConfigIndex RANGE ${configsCount}) - list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) - list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) - string(APPEND configsText " ${filename} (version ${version})\n") - endforeach() - if (${_NAME}_NOT_FOUND_MESSAGE) - string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") - endif() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") - - else() - # Simple case: No Config-file was found at all: - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") - endif() - endif() -endmacro() - - -function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) - -# Set up the arguments for `cmake_parse_arguments`. - set(options CONFIG_MODE HANDLE_COMPONENTS) - set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) - set(multiValueArgs REQUIRED_VARS) - -# Check whether we are in 'simple' or 'extended' mode: - set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) - list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) - - if(${INDEX} EQUAL -1) - set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) - set(FPHSA_REQUIRED_VARS ${ARGN}) - set(FPHSA_VERSION_VAR) - else() - cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) - - if(FPHSA_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") - endif() - - if(NOT FPHSA_FAIL_MESSAGE) - set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") - endif() - - # In config-mode, we rely on the variable _CONFIG, which is set by find_package() - # when it successfully found the config-file, including version checking: - if(FPHSA_CONFIG_MODE) - list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) - list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) - set(FPHSA_VERSION_VAR ${_NAME}_VERSION) - endif() - - if(NOT FPHSA_REQUIRED_VARS) - message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") - endif() - endif() - -# now that we collected all arguments, process them - - if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") - set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") - endif() - - list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) - - string(TOUPPER ${_NAME} _NAME_UPPER) - string(TOLOWER ${_NAME} _NAME_LOWER) - - if(FPHSA_FOUND_VAR) - if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") - set(_FOUND_VAR ${FPHSA_FOUND_VAR}) - else() - message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") - endif() - else() - set(_FOUND_VAR ${_NAME_UPPER}_FOUND) - endif() - - # collect all variables which were not found, so they can be printed, so the - # user knows better what went wrong (#6375) - set(MISSING_VARS "") - set(DETAILS "") - # check if all passed variables are valid - set(FPHSA_FOUND_${_NAME} TRUE) - foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) - if(NOT ${_CURRENT_VAR}) - set(FPHSA_FOUND_${_NAME} FALSE) - string(APPEND MISSING_VARS " ${_CURRENT_VAR}") - else() - string(APPEND DETAILS "[${${_CURRENT_VAR}}]") - endif() - endforeach() - if(FPHSA_FOUND_${_NAME}) - set(${_NAME}_FOUND TRUE) - set(${_NAME_UPPER}_FOUND TRUE) - else() - set(${_NAME}_FOUND FALSE) - set(${_NAME_UPPER}_FOUND FALSE) - endif() - - # component handling - unset(FOUND_COMPONENTS_MSG) - unset(MISSING_COMPONENTS_MSG) - - if(FPHSA_HANDLE_COMPONENTS) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(${_NAME}_${comp}_FOUND) - - if(NOT DEFINED FOUND_COMPONENTS_MSG) - set(FOUND_COMPONENTS_MSG "found components: ") - endif() - string(APPEND FOUND_COMPONENTS_MSG " ${comp}") - - else() - - if(NOT DEFINED MISSING_COMPONENTS_MSG) - set(MISSING_COMPONENTS_MSG "missing components: ") - endif() - string(APPEND MISSING_COMPONENTS_MSG " ${comp}") - - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - string(APPEND MISSING_VARS " ${comp}") - endif() - - endif() - endforeach() - set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") - string(APPEND DETAILS "[c${COMPONENT_MSG}]") - endif() - - # version handling: - set(VERSION_MSG "") - set(VERSION_OK TRUE) - - # check with DEFINED here as the requested or found version may be "0" - if (DEFINED ${_NAME}_FIND_VERSION) - if(DEFINED ${FPHSA_VERSION_VAR}) - set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}}) - - if(${_NAME}_FIND_VERSION_EXACT) # exact version required - # count the dots in the version string - string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}") - # add one dot because there is one dot more than there are components - string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) - if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) - # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT - # is at most 4 here. Therefore a simple lookup table is used. - if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) - set(_VERSION_REGEX "[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) - set(_VERSION_REGEX "[^.]*\\.[^.]*") - elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") - else () - set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") - endif () - string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}") - unset(_VERSION_REGEX) - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - unset(_VERSION_HEAD) - else () - if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")") - endif () - endif () - unset(_VERSION_DOTS) - - else() # minimum version specified: - if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION) - set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") - set(VERSION_OK FALSE) - else () - set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") - endif () - endif() - - else() - - # if the package was not found, but a version was given, add that to the output: - if(${_NAME}_FIND_VERSION_EXACT) - set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") - else() - set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") - endif() - - endif() - else () - # Check with DEFINED as the found version may be 0. - if(DEFINED ${FPHSA_VERSION_VAR}) - set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")") - endif() - endif () - - if(VERSION_OK) - string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]") - else() - set(${_NAME}_FOUND FALSE) - endif() - - - # print the result: - if (${_NAME}_FOUND) - FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") - else () - - if(FPHSA_CONFIG_MODE) - _FPHSA_HANDLE_FAILURE_CONFIG_MODE() - else() - if(NOT VERSION_OK) - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") - else() - _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") - endif() - endif() - - endif () - - set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) - set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) -endfunction() diff --git a/plugins/user_code/cmake/FindPackageMessage.cmake b/plugins/user_code/cmake/FindPackageMessage.cmake deleted file mode 100644 index 6821cee4f..000000000 --- a/plugins/user_code/cmake/FindPackageMessage.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#.rst: -# FindPackageMessage -# ------------------ -# -# -# -# FIND_PACKAGE_MESSAGE( "message for user" "find result details") -# -# This macro is intended to be used in FindXXX.cmake modules files. It -# will print a message once for each unique find result. This is useful -# for telling the user where a package was found. The first argument -# specifies the name (XXX) of the package. The second argument -# specifies the message to display. The third argument lists details -# about the find result so that if they change the message will be -# displayed again. The macro also obeys the QUIET argument to the -# find_package command. -# -# Example: -# -# :: -# -# if(X11_FOUND) -# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" -# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") -# else() -# ... -# endif() - -function(FIND_PACKAGE_MESSAGE pkg msg details) - # Avoid printing a message repeatedly for the same find result. - if(NOT ${pkg}_FIND_QUIETLY) - string(REPLACE "\n" "" details "${details}") - set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) - if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") - # The message has not yet been printed. - message(STATUS "${msg}") - - # Save the find details in the cache to avoid printing the same - # message again. - set("${DETAILS_VAR}" "${details}" - CACHE INTERNAL "Details about finding ${pkg}") - endif() - endif() -endfunction() diff --git a/plugins/user_code/tests/CMakeLists.txt b/plugins/user_code/tests/CMakeLists.txt index 2729f1b5f..a725dd380 100644 --- a/plugins/user_code/tests/CMakeLists.txt +++ b/plugins/user_code/tests/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2015-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -27,7 +27,7 @@ # POSSIBILITY OF SUCH DAMAGE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) # Add the plugin path to PDI_PLUGIN_PATH set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" PROPERTY TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/TestPath.cmake") diff --git a/plugins/user_code/user_code.cxx b/plugins/user_code/user_code.cxx index 3c2b25daf..d438f29ad 100644 --- a/plugins/user_code/user_code.cxx +++ b/plugins/user_code/user_code.cxx @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * Copyright (C) 2021 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) * All rights reserved. * @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/spack.yaml b/spack.yaml index ded772028..f9f18a2b2 100644 --- a/spack.yaml +++ b/spack.yaml @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (C) 2023-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2023-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # # All rights reserved. # @@ -29,16 +29,17 @@ spack: concretization: together specs: - - 'cmake@3.16.3:3' - - 'doxygen@1.8.17:1' - - 'hdf5@1.10.4:1' + - 'cmake@3.22.1:4' + - 'doxygen@1.9.1:1' + - 'hdf5@1.10.7:1' + - 'libyaml@0.2.2:' - 'mpi' - - 'netcdf-c@4.7.3:4' + - 'netcdf-c@4.8.1:4' - 'paraconf@1.0.0:1' - - 'pkgconfig' - - 'py-mpi4py@3.0.3:3' - - 'py-numpy@1.17.4:1' - - 'py-pyyaml@5.3.1:5' - - 'py-pybind11@2.4.3:2' - - 'python@3.8.2:3' - - 'spdlog@1.5.0:1' + - 'pkgconfig@1.8.0:2' + - 'py-mpi4py@3.1.3:4' + - 'py-numpy@1.21.5:2' + - 'py-pyyaml@5.4.1:6' + - 'py-pybind11@2.9.1:3' + - 'python@3.10.6:3' + - 'spdlog@1.9.2:1' diff --git a/test_api/AUTHORS b/test_api/AUTHORS new file mode 100644 index 000000000..9b2592577 --- /dev/null +++ b/test_api/AUTHORS @@ -0,0 +1,2 @@ +Julian Auriac - CEA (julian.auriac@cea.fr) +* Add API test diff --git a/test_api/CHANGELOG.md b/test_api/CHANGELOG.md new file mode 100644 index 000000000..053df9fbf --- /dev/null +++ b/test_api/CHANGELOG.md @@ -0,0 +1,25 @@ +# Changelog for PDI API tests project +All notable changes to the test_api project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + + +## [Unreleased] + +### Added + +### Changed + +### Deprecated + +### Removed + +### Fixed + +### Security + + +## [1.10.0] - 2026-01-31 + +### Added +* Add API tests diff --git a/test_api/CMakeLists.txt b/test_api/CMakeLists.txt new file mode 100644 index 000000000..200fefc3f --- /dev/null +++ b/test_api/CMakeLists.txt @@ -0,0 +1,49 @@ +#============================================================================= +# Copyright (C) 2025-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of CEA nor the names of its contributors may be used to +# endorse or promote products derived from this software without specific +# prior written permission. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +#============================================================================= + +cmake_minimum_required(VERSION 3.22...4.2) +project(pdi_test_api LANGUAGES C CXX) + +option(DISABLE_PDI "Disable the use of both PDI and Paraconf in the project" OFF) + +include(CTest) + + +if("${DISABLE_PDI}") + set(PDI_MOCK_PARACONF_TARGET TRUE) + add_subdirectory(../mock_pdi mock_pdi) +else() + find_package(paraconf REQUIRED COMPONENTS C) + find_package(PDI REQUIRED COMPONENTS C) +endif() + + +add_executable(test_api_C test_api.c) +target_link_libraries(test_api_C PRIVATE PDI::PDI_C paraconf::paraconf) +add_test(NAME test_api_C COMMAND "$") + + +add_executable(test_api_CXX test_api.cpp) +target_link_libraries(test_api_CXX PRIVATE PDI::PDI_C paraconf::paraconf) +add_test(NAME test_api_CXX COMMAND "$") diff --git a/test_api/LICENSE b/test_api/LICENSE new file mode 100644 index 000000000..5f4aa28fb --- /dev/null +++ b/test_api/LICENSE @@ -0,0 +1,26 @@ +BSD 3-Clause License + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/test_api/cmake/runtest-dir b/test_api/cmake/runtest-dir new file mode 100755 index 000000000..e617dbc92 --- /dev/null +++ b/test_api/cmake/runtest-dir @@ -0,0 +1,18 @@ +#!/bin/bash + +WKDIR="$(mktemp -p "${PWD}" -d run-XXXXXXXXXX)" +function finish { + rm -rf "${WKDIR}" +} +trap finish EXIT + +while [ '--runtest-dir-copy-file' = "$1" ] +do + shift + cp "$1" "${WKDIR}/" + shift +done + +cd "${WKDIR}" + +"$@" diff --git a/vendor/paraconf-1.0.0/paraconf/src/ypath.h b/test_api/test_api.c similarity index 85% rename from vendor/paraconf-1.0.0/paraconf/src/ypath.h rename to test_api/test_api.c index 3f370c085..b90b41bdd 100644 --- a/vendor/paraconf-1.0.0/paraconf/src/ypath.h +++ b/test_api/test_api.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2019 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2025-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,7 +10,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of CEA nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific + * endorse or promote products derived from this software without specific * prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR @@ -22,11 +22,10 @@ * THE SOFTWARE. ******************************************************************************/ -#ifndef YPATH_H__ -#define YPATH_H__ +#include "test_api.h" -#include "paraconf.h" - -PC_tree_t PARACONF_EXPORT PC_sget(PC_tree_t tree, const char *index); - -#endif // YPATH_H__ +int main(int argc, char* argv[]) +{ + tests(argc, argv); + printf("Disabled PDI ok for C.\n"); +} diff --git a/vendor/paraconf-1.0.0/paraconf/src/tools.h b/test_api/test_api.cpp similarity index 70% rename from vendor/paraconf-1.0.0/paraconf/src/tools.h rename to test_api/test_api.cpp index 842f730f6..ca8ed3b06 100644 --- a/vendor/paraconf-1.0.0/paraconf/src/tools.h +++ b/test_api/test_api.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2019 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2025-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,7 +10,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of CEA nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific + * endorse or promote products derived from this software without specific * prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR @@ -22,28 +22,12 @@ * THE SOFTWARE. ******************************************************************************/ -#ifndef TOOLS_H__ -#define TOOLS_H__ +#include "test_api.h" -#include -#include -#include +#include -#include "paraconf.h" - -static inline PC_tree_t subtree(PC_tree_t tree, int key) +int main(int argc, char* argv[]) { - tree.node = yaml_document_get_node(tree.document, key); - assert(tree.node); - return tree; + tests(argc, argv); + std::cout << "Disabled PDI ok for C++." << std::endl; } - -static inline int strlzcmp(const char *lstr, const char *zstr, size_t lstr_size) -{ - int res = strncmp(lstr, zstr, lstr_size); - if ( res ) return res; - if ( zstr[lstr_size] ) return -1; - return res; -} - -#endif // TOOLS_H__ diff --git a/test_api/test_api.h b/test_api/test_api.h new file mode 100644 index 000000000..13d1878b3 --- /dev/null +++ b/test_api/test_api.h @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (C) 2025-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of CEA nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include +#ifdef __cplusplus +#include +#include +#include +#else +#include +#include +#include +#endif +#ifndef WITHOUT_PARACONF +#include +#endif + +void share() //share +{ + int to_share[2] = {1, 1}; + if (PDI_OK != PDI_share("to_share", to_share, PDI_OUT)) { + fprintf(stderr, "*** Error in PDI_share\n"); + exit(EXIT_FAILURE); + } +} + +void access() //share/access +{ + int to_access[2] = {1, 1}; + PDI_share("to_access", to_access, PDI_OUT); + if (PDI_OK != PDI_access("to_access", (void**)&to_access, PDI_IN)) { + fprintf(stderr, "*** Error in PDI_access\n"); + exit(EXIT_FAILURE); + } +} + +void release() //share/release +{ + int to_release[2] = {1, 1}; + PDI_share("to_release", to_release, PDI_OUT); + PDI_access("to_release", (void**)&to_release, PDI_IN); + if (PDI_OK != PDI_release("to_release")) { + fprintf(stderr, "*** Error in PDI_release\n"); + exit(EXIT_FAILURE); + } +} + +void reclaim() //share/reclaim +{ + int to_reclaim[2] = {1, 1}; + PDI_share("to_reclaim", to_reclaim, PDI_OUT); + if (PDI_OK != PDI_reclaim("to_reclaim")) { + fprintf(stderr, "*** Error in PDI_reclaim\n"); + exit(EXIT_FAILURE); + } +} + +void event() +{ + if (PDI_OK != PDI_event("event_one")) { + fprintf(stderr, "*** Error in PDI_event\n"); + exit(EXIT_FAILURE); + } +} + +void expose() +{ + int to_expose[2] = {1, 1}; + if (PDI_OK != PDI_expose("to_expose", to_expose, PDI_OUT)) { + fprintf(stderr, "*** Error in PDI_expose\n"); + exit(EXIT_FAILURE); + } +} + +void multi_expose() +{ + int to_multi_expose[2] = {1, 1}; + int to_multi_expose_two[2] = {2, 2}; + if (PDI_OK + != PDI_multi_expose("event_two", "to_multi_expose", &to_multi_expose, PDI_OUT, "to_multi_expose_two", to_multi_expose_two, PDI_OUT, NULL)) + { + fprintf(stderr, "*** Error in PDI_multi_expose\n"); + exit(EXIT_FAILURE); + } +} + +void errhandler() +{ + PDI_errhandler_t current_handler = PDI_errhandler(PDI_NULL_HANDLER); + if (NULL != current_handler.context) { + fprintf(stderr, "*** Error in PDI_errhandler\n"); + exit(EXIT_FAILURE); + } +} + +int tests(int argc, char* argv[]) +{ + static const char* CONFIG_YAML + = "logging: trace \n" + "data: \n" + " to_share: {type: array, subtype: int, size: 2} \n" + " to_access: {type: array, subtype: int, size: 2} \n" + " to_release: {type: array, subtype: int, size: 2} \n" + " to_reclaim: {type: array, subtype: int, size: 2} \n" + " to_expose: {type: array, subtype: int, size: 2} \n" + " to_multi_expose: {type: array, subtype: int, size: 2} \n" + " to_multi_expose_two: {type: array, subtype: int, size: 2} \n"; + +#ifndef WITHOUT_PARACONF + if (PDI_OK != PDI_init(PC_parse_string(CONFIG_YAML))) { + fprintf(stderr, "*** Error in PDI_initialisation\n"); + exit(EXIT_FAILURE); + } +#endif // WITHOUT_PARACONF + + const char* errmsg = PDI_errmsg(); + if (strcmp(errmsg, "") != 0) { + fprintf(stderr, "*** Error in PDI_errmsg\n"); + exit(EXIT_FAILURE); + } + + errhandler(); + + share(); + access(); + release(); + reclaim(); + event(); + expose(); + multi_expose(); + + if (PDI_OK != PDI_finalize()) { + fprintf(stderr, "*** Error in PDI_finalisation\n"); + exit(EXIT_FAILURE); + } + + return EXIT_SUCCESS; +} diff --git a/tests/CHANGELOG.md b/tests/CHANGELOG.md index 7b2870a78..a92149161 100644 --- a/tests/CHANGELOG.md +++ b/tests/CHANGELOG.md @@ -19,6 +19,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Security +## [1.10.0] - 2026-01-31 + +### Changed +* Update the version of dependencies according to our policy: oldest supported + Debian, Fedora & Ubuntu, as well as spack 0.19. The new requirements are: + CMake 3.22 [#613](https://github.com/pdidev/pdi/issues/613) + + ## [1.8.0] - 2024-11-28 ### Changed diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1706d200b..887f0fc97 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,6 +1,6 @@ #============================================================================= # Copyright (C) 2020 Institute of Bioorganic Chemistry Polish Academy of Science (PSNC) -# Copyright (C) 2020-2024 Commissariat a l'energie atomique et aux energies alternatives (CEA) +# Copyright (C) 2020-2026 Commissariat a l'energie atomique et aux energies alternatives (CEA) # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -23,44 +23,44 @@ # THE SOFTWARE. #============================================================================= -cmake_minimum_required(VERSION 3.16...3.29) +cmake_minimum_required(VERSION 3.22...4.2) project(pdi_tests LANGUAGES C) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") set(RUNTEST_DIR "${CMAKE_CURRENT_LIST_DIR}/../cmake/runtest-dir") option(BUILD_DECL_HDF5_PLUGIN "Build Decl'HDF5 plug-in" ON) option(BUILD_SERIALIZE_PLUGIN "Build Serialize plug-in" ON) -# Includes include(CTest) -# PDI +find_package(paraconf REQUIRED COMPONENTS C) find_package(PDI REQUIRED COMPONENTS C) if("${BUILD_DECL_HDF5_PLUGIN}" AND "${BUILD_SERIALIZE_PLUGIN}") add_executable(test_01_C test_01.c) -target_link_libraries(test_01_C PDI::PDI_C) +target_link_libraries(test_01_C paraconf::paraconf PDI::PDI_C) add_test(NAME test_01_C COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/test_01.yml") add_executable(test_02_C test_02.c) -target_link_libraries(test_02_C PDI::PDI_C) +target_link_libraries(test_02_C paraconf::paraconf PDI::PDI_C) add_test(NAME test_02_C COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/test_02.yml") add_executable(test_03_C test_03.c) -target_link_libraries(test_03_C PDI::PDI_C) +target_link_libraries(test_03_C paraconf::paraconf PDI::PDI_C) add_test(NAME test_03_C COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/test_03.yml") add_executable(test_04_C test_04.c) -target_link_libraries(test_04_C PDI::PDI_C) +target_link_libraries(test_04_C paraconf::paraconf PDI::PDI_C) add_test(NAME test_04_C COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/test_04.yml") endif("${BUILD_DECL_HDF5_PLUGIN}" AND "${BUILD_SERIALIZE_PLUGIN}") if("${BUILD_DECL_NETCDF_PLUGIN}" AND "${BUILD_SERIALIZE_PLUGIN}") add_executable(test_05_C test_05.c) -target_link_libraries(test_05_C PDI::PDI_C) +target_link_libraries(test_05_C paraconf::paraconf PDI::PDI_C) add_test(NAME test_05_C COMMAND "$" "${CMAKE_CURRENT_SOURCE_DIR}/test_05.yml") +#TODO: NetCDF error https://gitlab.maisondelasimulation.fr/pdidev/pdi/-/issues/433 +set_tests_properties(test_05_C PROPERTIES DISABLED TRUE) endif("${BUILD_DECL_NETCDF_PLUGIN}" AND "${BUILD_SERIALIZE_PLUGIN}") diff --git a/vendor/benchmark-38df9da/.clang-tidy b/vendor/benchmark-38df9da/.clang-tidy deleted file mode 100644 index 1e229e582..000000000 --- a/vendor/benchmark-38df9da/.clang-tidy +++ /dev/null @@ -1,6 +0,0 @@ ---- -Checks: 'clang-analyzer-*,readability-redundant-*,performance-*' -WarningsAsErrors: 'clang-analyzer-*,readability-redundant-*,performance-*' -HeaderFilterRegex: '.*' -FormatStyle: none -User: user diff --git a/vendor/benchmark-38df9da/.github/libcxx-setup.sh b/vendor/benchmark-38df9da/.github/libcxx-setup.sh deleted file mode 100755 index 9aaf96af4..000000000 --- a/vendor/benchmark-38df9da/.github/libcxx-setup.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -set -e - -# Checkout LLVM sources -git clone --depth=1 --branch llvmorg-16.0.6 https://github.com/llvm/llvm-project.git llvm-project - -## Setup libc++ options -if [ -z "$BUILD_32_BITS" ]; then - export BUILD_32_BITS=OFF && echo disabling 32 bit build -fi - -## Build and install libc++ (Use unstable ABI for better sanitizer coverage) -mkdir llvm-build && cd llvm-build -cmake -DCMAKE_C_COMPILER=${CC} \ - -DCMAKE_CXX_COMPILER=${CXX} \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_INSTALL_PREFIX=/usr \ - -DLIBCXX_ABI_UNSTABLE=OFF \ - -DLLVM_USE_SANITIZER=${LIBCXX_SANITIZER} \ - -DLLVM_BUILD_32_BITS=${BUILD_32_BITS} \ - -DLLVM_ENABLE_RUNTIMES='libcxx;libcxxabi;libunwind' \ - -G "Unix Makefiles" \ - ../llvm-project/runtimes/ -make -j cxx cxxabi unwind -cd .. diff --git a/vendor/benchmark-38df9da/.github/workflows/clang-format-lint.yml b/vendor/benchmark-38df9da/.github/workflows/clang-format-lint.yml deleted file mode 100644 index 328fe36cc..000000000 --- a/vendor/benchmark-38df9da/.github/workflows/clang-format-lint.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: clang-format-lint -on: - push: {} - pull_request: {} - -jobs: - job: - name: check-clang-format - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - uses: DoozyX/clang-format-lint-action@v0.13 - with: - source: './include/benchmark ./src ./test' - extensions: 'h,cc' - clangFormatVersion: 12 - style: Google diff --git a/vendor/benchmark-38df9da/.github/workflows/pre-commit.yml b/vendor/benchmark-38df9da/.github/workflows/pre-commit.yml deleted file mode 100644 index 5d65b9948..000000000 --- a/vendor/benchmark-38df9da/.github/workflows/pre-commit.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: python + Bazel pre-commit checks - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - pre-commit: - runs-on: ubuntu-latest - env: - MYPY_CACHE_DIR: "${{ github.workspace }}/.cache/mypy" - RUFF_CACHE_DIR: "${{ github.workspace }}/.cache/ruff" - PRE_COMMIT_HOME: "${{ github.workspace }}/.cache/pre-commit" - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: 3.11 - cache: pip - cache-dependency-path: pyproject.toml - - name: Install dependencies - run: python -m pip install ".[dev]" - - name: Cache pre-commit tools - uses: actions/cache@v3 - with: - path: | - ${{ env.MYPY_CACHE_DIR }} - ${{ env.RUFF_CACHE_DIR }} - ${{ env.PRE_COMMIT_HOME }} - key: ${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}-linter-cache - - name: Run pre-commit checks - run: pre-commit run --all-files --verbose --show-diff-on-failure diff --git a/vendor/benchmark-38df9da/.github/workflows/test_bindings.yml b/vendor/benchmark-38df9da/.github/workflows/test_bindings.yml deleted file mode 100644 index 436a8f90e..000000000 --- a/vendor/benchmark-38df9da/.github/workflows/test_bindings.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: test-bindings - -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - python_bindings: - name: Test GBM Python bindings on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ ubuntu-latest, macos-latest, windows-latest ] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Set up Python 3.11 - uses: actions/setup-python@v5 - with: - python-version: 3.11 - - name: Install GBM Python bindings on ${{ matrix.os }} - run: python -m pip install . - - name: Run bindings example on ${{ matrix.os }} - run: - python bindings/python/google_benchmark/example.py diff --git a/vendor/benchmark-38df9da/.github/workflows/wheels.yml b/vendor/benchmark-38df9da/.github/workflows/wheels.yml deleted file mode 100644 index 591d709fb..000000000 --- a/vendor/benchmark-38df9da/.github/workflows/wheels.yml +++ /dev/null @@ -1,90 +0,0 @@ -name: Build and upload Python wheels - -on: - workflow_dispatch: - release: - types: - - published - -jobs: - build_sdist: - name: Build source distribution - runs-on: ubuntu-latest - steps: - - name: Check out repo - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Install Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: 3.12 - - run: python -m pip install build - - name: Build sdist - run: python -m build --sdist - - uses: actions/upload-artifact@v4 - with: - name: dist-sdist - path: dist/*.tar.gz - - build_wheels: - name: Build Google Benchmark wheels on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-13, macos-14, windows-latest] - - steps: - - name: Check out Google Benchmark - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up QEMU - if: runner.os == 'Linux' - uses: docker/setup-qemu-action@v3 - with: - platforms: all - - - name: Build wheels on ${{ matrix.os }} using cibuildwheel - uses: pypa/cibuildwheel@v2.17 - env: - CIBW_BUILD: "cp38-* cp39-* cp310-* cp311-* cp312-*" - CIBW_SKIP: "*-musllinux_*" - CIBW_TEST_SKIP: "cp38-macosx_*:arm64" - CIBW_ARCHS_LINUX: auto64 aarch64 - CIBW_ARCHS_WINDOWS: auto64 - CIBW_BEFORE_ALL_LINUX: bash .github/install_bazel.sh - # Grab the rootless Bazel installation inside the container. - CIBW_ENVIRONMENT_LINUX: PATH=$PATH:$HOME/bin - CIBW_TEST_COMMAND: python {project}/bindings/python/google_benchmark/example.py - - - name: Upload Google Benchmark ${{ matrix.os }} wheels - uses: actions/upload-artifact@v4 - with: - name: dist-${{ matrix.os }} - path: wheelhouse/*.whl - - merge_wheels: - name: Merge all built wheels into one artifact - runs-on: ubuntu-latest - needs: build_wheels - steps: - - name: Merge wheels - uses: actions/upload-artifact/merge@v4 - with: - name: dist - pattern: dist-* - delete-merged: true - - pypi_upload: - name: Publish google-benchmark wheels to PyPI - needs: [merge_wheels] - runs-on: ubuntu-latest - permissions: - id-token: write - steps: - - uses: actions/download-artifact@v4 - with: - path: dist - - uses: pypa/gh-action-pypi-publish@v1.8.14 diff --git a/vendor/benchmark-38df9da/.travis.yml b/vendor/benchmark-38df9da/.travis.yml deleted file mode 100644 index 8cfed3d10..000000000 --- a/vendor/benchmark-38df9da/.travis.yml +++ /dev/null @@ -1,208 +0,0 @@ -sudo: required -dist: trusty -language: cpp - -matrix: - include: - - compiler: gcc - addons: - apt: - packages: - - lcov - env: COMPILER=g++ C_COMPILER=gcc BUILD_TYPE=Coverage - - compiler: gcc - addons: - apt: - packages: - - g++-multilib - - libc6:i386 - env: - - COMPILER=g++ - - C_COMPILER=gcc - - BUILD_TYPE=Debug - - BUILD_32_BITS=ON - - EXTRA_FLAGS="-m32" - - compiler: gcc - addons: - apt: - packages: - - g++-multilib - - libc6:i386 - env: - - COMPILER=g++ - - C_COMPILER=gcc - - BUILD_TYPE=Release - - BUILD_32_BITS=ON - - EXTRA_FLAGS="-m32" - - compiler: gcc - env: - - INSTALL_GCC6_FROM_PPA=1 - - COMPILER=g++-6 C_COMPILER=gcc-6 BUILD_TYPE=Debug - - ENABLE_SANITIZER=1 - - EXTRA_FLAGS="-fno-omit-frame-pointer -g -O2 -fsanitize=undefined,address -fuse-ld=gold" - # Clang w/ libc++ - - compiler: clang - dist: xenial - addons: - apt: - packages: - clang-3.8 - env: - - INSTALL_GCC6_FROM_PPA=1 - - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug - - LIBCXX_BUILD=1 - - EXTRA_CXX_FLAGS="-stdlib=libc++" - - compiler: clang - dist: xenial - addons: - apt: - packages: - clang-3.8 - env: - - INSTALL_GCC6_FROM_PPA=1 - - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Release - - LIBCXX_BUILD=1 - - EXTRA_CXX_FLAGS="-stdlib=libc++" - # Clang w/ 32bit libc++ - - compiler: clang - dist: xenial - addons: - apt: - packages: - - clang-3.8 - - g++-multilib - - libc6:i386 - env: - - INSTALL_GCC6_FROM_PPA=1 - - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug - - LIBCXX_BUILD=1 - - BUILD_32_BITS=ON - - EXTRA_FLAGS="-m32" - - EXTRA_CXX_FLAGS="-stdlib=libc++" - # Clang w/ 32bit libc++ - - compiler: clang - dist: xenial - addons: - apt: - packages: - - clang-3.8 - - g++-multilib - - libc6:i386 - env: - - INSTALL_GCC6_FROM_PPA=1 - - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Release - - LIBCXX_BUILD=1 - - BUILD_32_BITS=ON - - EXTRA_FLAGS="-m32" - - EXTRA_CXX_FLAGS="-stdlib=libc++" - # Clang w/ libc++, ASAN, UBSAN - - compiler: clang - dist: xenial - addons: - apt: - packages: - clang-3.8 - env: - - INSTALL_GCC6_FROM_PPA=1 - - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug - - LIBCXX_BUILD=1 LIBCXX_SANITIZER="Undefined;Address" - - ENABLE_SANITIZER=1 - - EXTRA_FLAGS="-g -O2 -fno-omit-frame-pointer -fsanitize=undefined,address -fno-sanitize-recover=all" - - EXTRA_CXX_FLAGS="-stdlib=libc++" - - UBSAN_OPTIONS=print_stacktrace=1 - # Clang w/ libc++ and MSAN - - compiler: clang - dist: xenial - addons: - apt: - packages: - clang-3.8 - env: - - INSTALL_GCC6_FROM_PPA=1 - - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=Debug - - LIBCXX_BUILD=1 LIBCXX_SANITIZER=MemoryWithOrigins - - ENABLE_SANITIZER=1 - - EXTRA_FLAGS="-g -O2 -fno-omit-frame-pointer -fsanitize=memory -fsanitize-memory-track-origins" - - EXTRA_CXX_FLAGS="-stdlib=libc++" - # Clang w/ libc++ and MSAN - - compiler: clang - dist: xenial - addons: - apt: - packages: - clang-3.8 - env: - - INSTALL_GCC6_FROM_PPA=1 - - COMPILER=clang++-3.8 C_COMPILER=clang-3.8 BUILD_TYPE=RelWithDebInfo - - LIBCXX_BUILD=1 LIBCXX_SANITIZER=Thread - - ENABLE_SANITIZER=1 - - EXTRA_FLAGS="-g -O2 -fno-omit-frame-pointer -fsanitize=thread -fno-sanitize-recover=all" - - EXTRA_CXX_FLAGS="-stdlib=libc++" - - os: osx - osx_image: xcode8.3 - compiler: clang - env: - - COMPILER=clang++ - - BUILD_TYPE=Release - - BUILD_32_BITS=ON - - EXTRA_FLAGS="-m32" - -before_script: - - if [ -n "${LIBCXX_BUILD}" ]; then - source .libcxx-setup.sh; - fi - - if [ -n "${ENABLE_SANITIZER}" ]; then - export EXTRA_OPTIONS="-DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF"; - else - export EXTRA_OPTIONS=""; - fi - - mkdir -p build && cd build - -before_install: - - if [ -z "$BUILD_32_BITS" ]; then - export BUILD_32_BITS=OFF && echo disabling 32 bit build; - fi - - if [ -n "${INSTALL_GCC6_FROM_PPA}" ]; then - sudo add-apt-repository -y "ppa:ubuntu-toolchain-r/test"; - sudo apt-get update --option Acquire::Retries=100 --option Acquire::http::Timeout="60"; - fi - -install: - - if [ -n "${INSTALL_GCC6_FROM_PPA}" ]; then - travis_wait sudo -E apt-get -yq --no-install-suggests --no-install-recommends install g++-6; - fi - - if [ "${TRAVIS_OS_NAME}" == "linux" -a "${BUILD_32_BITS}" == "OFF" ]; then - travis_wait sudo -E apt-get -y --no-install-suggests --no-install-recommends install llvm-3.9-tools; - sudo cp /usr/lib/llvm-3.9/bin/FileCheck /usr/local/bin/; - fi - - if [ "${BUILD_TYPE}" == "Coverage" -a "${TRAVIS_OS_NAME}" == "linux" ]; then - PATH=~/.local/bin:${PATH}; - pip install --user --upgrade pip; - travis_wait pip install --user cpp-coveralls; - fi - - if [ "${C_COMPILER}" == "gcc-7" -a "${TRAVIS_OS_NAME}" == "osx" ]; then - rm -f /usr/local/include/c++; - brew update; - travis_wait brew install gcc@7; - fi - - if [ "${TRAVIS_OS_NAME}" == "linux" ]; then - sudo apt-get update -qq; - sudo apt-get install -qq unzip cmake3; - wget https://github.com/bazelbuild/bazel/releases/download/3.2.0/bazel-3.2.0-installer-linux-x86_64.sh --output-document bazel-installer.sh; - travis_wait sudo bash bazel-installer.sh; - fi - - if [ "${TRAVIS_OS_NAME}" == "osx" ]; then - curl -L -o bazel-installer.sh https://github.com/bazelbuild/bazel/releases/download/3.2.0/bazel-3.2.0-installer-darwin-x86_64.sh; - travis_wait sudo bash bazel-installer.sh; - fi - -script: - - cmake -DCMAKE_C_COMPILER=${C_COMPILER} -DCMAKE_CXX_COMPILER=${COMPILER} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_C_FLAGS="${EXTRA_FLAGS}" -DCMAKE_CXX_FLAGS="${EXTRA_FLAGS} ${EXTRA_CXX_FLAGS}" -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON -DBENCHMARK_BUILD_32_BITS=${BUILD_32_BITS} ${EXTRA_OPTIONS} .. - - make - - ctest -C ${BUILD_TYPE} --output-on-failure - - bazel test -c dbg --define google_benchmark.have_regex=posix --announce_rc --verbose_failures --test_output=errors --keep_going //test/... - -after_success: - - if [ "${BUILD_TYPE}" == "Coverage" -a "${TRAVIS_OS_NAME}" == "linux" ]; then - coveralls --include src --include include --gcov-options '\-lp' --root .. --build-root .; - fi diff --git a/vendor/benchmark-38df9da/bindings/python/google_benchmark/version.py b/vendor/benchmark-38df9da/bindings/python/google_benchmark/version.py deleted file mode 100644 index a324693e2..000000000 --- a/vendor/benchmark-38df9da/bindings/python/google_benchmark/version.py +++ /dev/null @@ -1,7 +0,0 @@ -from importlib.metadata import PackageNotFoundError, version - -try: - __version__ = version("google-benchmark") -except PackageNotFoundError: - # package is not installed - pass diff --git a/vendor/benchmark-38df9da/cmake/CXXFeatureCheck.cmake b/vendor/benchmark-38df9da/cmake/CXXFeatureCheck.cmake deleted file mode 100644 index e51482659..000000000 --- a/vendor/benchmark-38df9da/cmake/CXXFeatureCheck.cmake +++ /dev/null @@ -1,82 +0,0 @@ -# - Compile and run code to check for C++ features -# -# This functions compiles a source file under the `cmake` folder -# and adds the corresponding `HAVE_[FILENAME]` flag to the CMake -# environment -# -# cxx_feature_check( []) -# -# - Example -# -# include(CXXFeatureCheck) -# cxx_feature_check(STD_REGEX) -# Requires CMake 2.8.12+ - -if(__cxx_feature_check) - return() -endif() -set(__cxx_feature_check INCLUDED) - -option(CXXFEATURECHECK_DEBUG OFF) - -function(cxx_feature_check FILE) - string(TOLOWER ${FILE} FILE) - string(TOUPPER ${FILE} VAR) - string(TOUPPER "HAVE_${VAR}" FEATURE) - if (DEFINED HAVE_${VAR}) - set(HAVE_${VAR} 1 PARENT_SCOPE) - add_definitions(-DHAVE_${VAR}) - return() - endif() - - set(FEATURE_CHECK_CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS}) - if (ARGC GREATER 1) - message(STATUS "Enabling additional flags: ${ARGV1}") - list(APPEND FEATURE_CHECK_CMAKE_FLAGS ${ARGV1}) - endif() - - if (NOT DEFINED COMPILE_${FEATURE}) - if(CMAKE_CROSSCOMPILING) - message(STATUS "Cross-compiling to test ${FEATURE}") - try_compile(COMPILE_${FEATURE} - ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp - CXX_STANDARD 11 - CXX_STANDARD_REQUIRED ON - CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS} - LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES} - OUTPUT_VARIABLE COMPILE_OUTPUT_VAR) - if(COMPILE_${FEATURE}) - message(WARNING - "If you see build failures due to cross compilation, try setting HAVE_${VAR} to 0") - set(RUN_${FEATURE} 0 CACHE INTERNAL "") - else() - set(RUN_${FEATURE} 1 CACHE INTERNAL "") - endif() - else() - message(STATUS "Compiling and running to test ${FEATURE}") - try_run(RUN_${FEATURE} COMPILE_${FEATURE} - ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp - CXX_STANDARD 11 - CXX_STANDARD_REQUIRED ON - CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS} - LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES} - COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT_VAR) - endif() - endif() - - if(RUN_${FEATURE} EQUAL 0) - message(STATUS "Performing Test ${FEATURE} -- success") - set(HAVE_${VAR} 1 PARENT_SCOPE) - add_definitions(-DHAVE_${VAR}) - else() - if(NOT COMPILE_${FEATURE}) - if(CXXFEATURECHECK_DEBUG) - message(STATUS "Performing Test ${FEATURE} -- failed to compile: ${COMPILE_OUTPUT_VAR}") - else() - message(STATUS "Performing Test ${FEATURE} -- failed to compile") - endif() - else() - message(STATUS "Performing Test ${FEATURE} -- compiled but failed to run") - endif() - endif() -endfunction() diff --git a/vendor/benchmark-38df9da/cmake/Modules/FindLLVMAr.cmake b/vendor/benchmark-38df9da/cmake/Modules/FindLLVMAr.cmake deleted file mode 100644 index 23469813c..000000000 --- a/vendor/benchmark-38df9da/cmake/Modules/FindLLVMAr.cmake +++ /dev/null @@ -1,16 +0,0 @@ -include(FeatureSummary) - -find_program(LLVMAR_EXECUTABLE - NAMES llvm-ar - DOC "The llvm-ar executable" - ) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(LLVMAr - DEFAULT_MSG - LLVMAR_EXECUTABLE) - -SET_PACKAGE_PROPERTIES(LLVMAr PROPERTIES - URL https://llvm.org/docs/CommandGuide/llvm-ar.html - DESCRIPTION "create, modify, and extract from archives" -) diff --git a/vendor/benchmark-38df9da/cmake/Modules/FindLLVMNm.cmake b/vendor/benchmark-38df9da/cmake/Modules/FindLLVMNm.cmake deleted file mode 100644 index e56430a04..000000000 --- a/vendor/benchmark-38df9da/cmake/Modules/FindLLVMNm.cmake +++ /dev/null @@ -1,16 +0,0 @@ -include(FeatureSummary) - -find_program(LLVMNM_EXECUTABLE - NAMES llvm-nm - DOC "The llvm-nm executable" - ) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(LLVMNm - DEFAULT_MSG - LLVMNM_EXECUTABLE) - -SET_PACKAGE_PROPERTIES(LLVMNm PROPERTIES - URL https://llvm.org/docs/CommandGuide/llvm-nm.html - DESCRIPTION "list LLVM bitcode and object file’s symbol table" -) diff --git a/vendor/benchmark-38df9da/cmake/Modules/FindLLVMRanLib.cmake b/vendor/benchmark-38df9da/cmake/Modules/FindLLVMRanLib.cmake deleted file mode 100644 index 7b53e1a79..000000000 --- a/vendor/benchmark-38df9da/cmake/Modules/FindLLVMRanLib.cmake +++ /dev/null @@ -1,15 +0,0 @@ -include(FeatureSummary) - -find_program(LLVMRANLIB_EXECUTABLE - NAMES llvm-ranlib - DOC "The llvm-ranlib executable" - ) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(LLVMRanLib - DEFAULT_MSG - LLVMRANLIB_EXECUTABLE) - -SET_PACKAGE_PROPERTIES(LLVMRanLib PROPERTIES - DESCRIPTION "generate index for LLVM archive" -) diff --git a/vendor/benchmark-38df9da/cmake/Modules/FindPFM.cmake b/vendor/benchmark-38df9da/cmake/Modules/FindPFM.cmake deleted file mode 100644 index 4c1ce938f..000000000 --- a/vendor/benchmark-38df9da/cmake/Modules/FindPFM.cmake +++ /dev/null @@ -1,28 +0,0 @@ -# If successful, the following variables will be defined: -# PFM_FOUND. -# PFM_LIBRARIES -# PFM_INCLUDE_DIRS -# the following target will be defined: -# PFM::libpfm - -include(FeatureSummary) -include(FindPackageHandleStandardArgs) - -set_package_properties(PFM PROPERTIES - URL http://perfmon2.sourceforge.net/ - DESCRIPTION "A helper library to develop monitoring tools" - PURPOSE "Used to program specific performance monitoring events") - -find_library(PFM_LIBRARY NAMES pfm) -find_path(PFM_INCLUDE_DIR NAMES perfmon/pfmlib.h) - -find_package_handle_standard_args(PFM REQUIRED_VARS PFM_LIBRARY PFM_INCLUDE_DIR) - -if (PFM_FOUND AND NOT TARGET PFM::libpfm) - add_library(PFM::libpfm UNKNOWN IMPORTED) - set_target_properties(PFM::libpfm PROPERTIES - IMPORTED_LOCATION "${PFM_LIBRARY}" - INTERFACE_INCLUDE_DIRECTORIES "${PFM_INCLUDE_DIR}") -endif() - -mark_as_advanced(PFM_LIBRARY PFM_INCLUDE_DIR) diff --git a/vendor/benchmark-38df9da/test/cxx03_test.cc b/vendor/benchmark-38df9da/test/cxx03_test.cc deleted file mode 100644 index 9711c1bd4..000000000 --- a/vendor/benchmark-38df9da/test/cxx03_test.cc +++ /dev/null @@ -1,62 +0,0 @@ -#undef NDEBUG -#include -#include - -#include "benchmark/benchmark.h" - -#if __cplusplus >= 201103L -#error C++11 or greater detected. Should be C++03. -#endif - -#ifdef BENCHMARK_HAS_CXX11 -#error C++11 or greater detected by the library. BENCHMARK_HAS_CXX11 is defined. -#endif - -void BM_empty(benchmark::State& state) { - while (state.KeepRunning()) { - volatile benchmark::IterationCount x = state.iterations(); - ((void)x); - } -} -BENCHMARK(BM_empty); - -// The new C++11 interface for args/ranges requires initializer list support. -// Therefore we provide the old interface to support C++03. -void BM_old_arg_range_interface(benchmark::State& state) { - assert((state.range(0) == 1 && state.range(1) == 2) || - (state.range(0) == 5 && state.range(1) == 6)); - while (state.KeepRunning()) { - } -} -BENCHMARK(BM_old_arg_range_interface)->ArgPair(1, 2)->RangePair(5, 5, 6, 6); - -template -void BM_template2(benchmark::State& state) { - BM_empty(state); -} -BENCHMARK_TEMPLATE2(BM_template2, int, long); - -template -void BM_template1(benchmark::State& state) { - BM_empty(state); -} -BENCHMARK_TEMPLATE(BM_template1, long); -BENCHMARK_TEMPLATE1(BM_template1, int); - -template -struct BM_Fixture : public ::benchmark::Fixture {}; - -BENCHMARK_TEMPLATE_F(BM_Fixture, BM_template1, long)(benchmark::State& state) { - BM_empty(state); -} -BENCHMARK_TEMPLATE1_F(BM_Fixture, BM_template2, int)(benchmark::State& state) { - BM_empty(state); -} - -void BM_counters(benchmark::State& state) { - BM_empty(state); - state.counters["Foo"] = 2; -} -BENCHMARK(BM_counters); - -BENCHMARK_MAIN(); diff --git a/vendor/benchmark-38df9da/tools/libpfm.BUILD.bazel b/vendor/benchmark-38df9da/tools/libpfm.BUILD.bazel deleted file mode 100644 index 62695342a..000000000 --- a/vendor/benchmark-38df9da/tools/libpfm.BUILD.bazel +++ /dev/null @@ -1,22 +0,0 @@ -# Build rule for libpfm, which is required to collect performance counters for -# BENCHMARK_ENABLE_LIBPFM builds. - -load("@rules_foreign_cc//foreign_cc:defs.bzl", "make") - -filegroup( - name = "pfm_srcs", - srcs = glob(["**"]), -) - -make( - name = "libpfm", - lib_source = ":pfm_srcs", - lib_name = "libpfm", - copts = [ - "-Wno-format-truncation", - "-Wno-use-after-free", - ], - visibility = [ - "//visibility:public", - ], -) diff --git a/vendor/benchmark-38df9da/tools/requirements.txt b/vendor/benchmark-38df9da/tools/requirements.txt deleted file mode 100644 index f32f35b8f..000000000 --- a/vendor/benchmark-38df9da/tools/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -numpy == 1.25 -scipy == 1.10.0 diff --git a/vendor/benchmark-4ed29ae/.bazelversion b/vendor/benchmark-4ed29ae/.bazelversion new file mode 100644 index 000000000..2b0aa2121 --- /dev/null +++ b/vendor/benchmark-4ed29ae/.bazelversion @@ -0,0 +1 @@ +8.2.1 diff --git a/vendor/benchmark-38df9da/.clang-format b/vendor/benchmark-4ed29ae/.clang-format similarity index 100% rename from vendor/benchmark-38df9da/.clang-format rename to vendor/benchmark-4ed29ae/.clang-format diff --git a/vendor/benchmark-4ed29ae/.clang-tidy b/vendor/benchmark-4ed29ae/.clang-tidy new file mode 100644 index 000000000..d6cd768f6 --- /dev/null +++ b/vendor/benchmark-4ed29ae/.clang-tidy @@ -0,0 +1,37 @@ +--- +Checks: > + abseil-*, + bugprone-*, + clang-analyzer-*, + cppcoreguidelines-*, + google-*, + misc-*, + performance-*, + readability-*, + -clang-analyzer-deadcode*, + -clang-analyzer-optin*, + -readability-identifier-length +WarningsAsErrors: '' +HeaderFilterRegex: '' +FormatStyle: none +CheckOptions: + llvm-else-after-return.WarnOnConditionVariables: 'false' + modernize-loop-convert.MinConfidence: reasonable + modernize-replace-auto-ptr.IncludeStyle: llvm + cert-str34-c.DiagnoseSignedUnsignedCharComparisons: 'false' + google-readability-namespace-comments.ShortNamespaceLines: '10' + cert-err33-c.CheckedFunctions: '::aligned_alloc;::asctime_s;::at_quick_exit;::atexit;::bsearch;::bsearch_s;::btowc;::c16rtomb;::c32rtomb;::calloc;::clock;::cnd_broadcast;::cnd_init;::cnd_signal;::cnd_timedwait;::cnd_wait;::ctime_s;::fclose;::fflush;::fgetc;::fgetpos;::fgets;::fgetwc;::fopen;::fopen_s;::fprintf;::fprintf_s;::fputc;::fputs;::fputwc;::fputws;::fread;::freopen;::freopen_s;::fscanf;::fscanf_s;::fseek;::fsetpos;::ftell;::fwprintf;::fwprintf_s;::fwrite;::fwscanf;::fwscanf_s;::getc;::getchar;::getenv;::getenv_s;::gets_s;::getwc;::getwchar;::gmtime;::gmtime_s;::localtime;::localtime_s;::malloc;::mbrtoc16;::mbrtoc32;::mbsrtowcs;::mbsrtowcs_s;::mbstowcs;::mbstowcs_s;::memchr;::mktime;::mtx_init;::mtx_lock;::mtx_timedlock;::mtx_trylock;::mtx_unlock;::printf_s;::putc;::putwc;::raise;::realloc;::remove;::rename;::scanf;::scanf_s;::setlocale;::setvbuf;::signal;::snprintf;::snprintf_s;::sprintf;::sprintf_s;::sscanf;::sscanf_s;::strchr;::strerror_s;::strftime;::strpbrk;::strrchr;::strstr;::strtod;::strtof;::strtoimax;::strtok;::strtok_s;::strtol;::strtold;::strtoll;::strtoul;::strtoull;::strtoumax;::strxfrm;::swprintf;::swprintf_s;::swscanf;::swscanf_s;::thrd_create;::thrd_detach;::thrd_join;::thrd_sleep;::time;::timespec_get;::tmpfile;::tmpfile_s;::tmpnam;::tmpnam_s;::tss_create;::tss_get;::tss_set;::ungetc;::ungetwc;::vfprintf;::vfprintf_s;::vfscanf;::vfscanf_s;::vfwprintf;::vfwprintf_s;::vfwscanf;::vfwscanf_s;::vprintf_s;::vscanf;::vscanf_s;::vsnprintf;::vsnprintf_s;::vsprintf;::vsprintf_s;::vsscanf;::vsscanf_s;::vswprintf;::vswprintf_s;::vswscanf;::vswscanf_s;::vwprintf_s;::vwscanf;::vwscanf_s;::wcrtomb;::wcschr;::wcsftime;::wcspbrk;::wcsrchr;::wcsrtombs;::wcsrtombs_s;::wcsstr;::wcstod;::wcstof;::wcstoimax;::wcstok;::wcstok_s;::wcstol;::wcstold;::wcstoll;::wcstombs;::wcstombs_s;::wcstoul;::wcstoull;::wcstoumax;::wcsxfrm;::wctob;::wctrans;::wctype;::wmemchr;::wprintf_s;::wscanf;::wscanf_s;' + cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField: 'false' + cert-dcl16-c.NewSuffixes: 'L;LL;LU;LLU' + google-readability-braces-around-statements.ShortStatementLines: '1' + cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: 'true' + google-readability-namespace-comments.SpacesBeforeComments: '2' + modernize-loop-convert.MaxCopySize: '16' + modernize-pass-by-value.IncludeStyle: llvm + modernize-use-nullptr.NullMacros: 'NULL' + llvm-qualified-auto.AddConstToQualified: 'false' + modernize-loop-convert.NamingStyle: CamelCase + llvm-else-after-return.WarnOnUnfixable: 'false' + google-readability-function-size.StatementThreshold: '800' +... + diff --git a/vendor/benchmark-4ed29ae/.clang-tidy.ignore b/vendor/benchmark-4ed29ae/.clang-tidy.ignore new file mode 100644 index 000000000..dba559d6c --- /dev/null +++ b/vendor/benchmark-4ed29ae/.clang-tidy.ignore @@ -0,0 +1 @@ +.*third_party/.* diff --git a/vendor/benchmark-38df9da/.github/ISSUE_TEMPLATE/bug_report.md b/vendor/benchmark-4ed29ae/.github/ISSUE_TEMPLATE/bug_report.md similarity index 100% rename from vendor/benchmark-38df9da/.github/ISSUE_TEMPLATE/bug_report.md rename to vendor/benchmark-4ed29ae/.github/ISSUE_TEMPLATE/bug_report.md diff --git a/vendor/benchmark-38df9da/.github/ISSUE_TEMPLATE/feature_request.md b/vendor/benchmark-4ed29ae/.github/ISSUE_TEMPLATE/feature_request.md similarity index 100% rename from vendor/benchmark-38df9da/.github/ISSUE_TEMPLATE/feature_request.md rename to vendor/benchmark-4ed29ae/.github/ISSUE_TEMPLATE/feature_request.md diff --git a/vendor/benchmark-4ed29ae/.github/dependabot.yml b/vendor/benchmark-4ed29ae/.github/dependabot.yml new file mode 100644 index 000000000..3661e978b --- /dev/null +++ b/vendor/benchmark-4ed29ae/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: daily + + - package-ecosystem: pip + directory: /tools + schedule: + interval: daily diff --git a/vendor/benchmark-38df9da/.github/install_bazel.sh b/vendor/benchmark-4ed29ae/.github/install_bazel.sh similarity index 83% rename from vendor/benchmark-38df9da/.github/install_bazel.sh rename to vendor/benchmark-4ed29ae/.github/install_bazel.sh index 1b0d63c98..a1693b87e 100644 --- a/vendor/benchmark-38df9da/.github/install_bazel.sh +++ b/vendor/benchmark-4ed29ae/.github/install_bazel.sh @@ -4,7 +4,7 @@ if ! bazel version; then arch="arm64" fi echo "Downloading $arch Bazel binary from GitHub releases." - curl -L -o $HOME/bin/bazel --create-dirs "https://github.com/bazelbuild/bazel/releases/download/7.1.1/bazel-7.1.1-linux-$arch" + curl -L -o $HOME/bin/bazel --create-dirs "https://github.com/bazelbuild/bazel/releases/download/8.2.0/bazel-8.2.0-linux-$arch" chmod +x $HOME/bin/bazel else # Bazel is installed for the correct architecture diff --git a/vendor/benchmark-4ed29ae/.github/libcxx-setup.sh b/vendor/benchmark-4ed29ae/.github/libcxx-setup.sh new file mode 100755 index 000000000..8966194d5 --- /dev/null +++ b/vendor/benchmark-4ed29ae/.github/libcxx-setup.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +set -e + +# Checkout LLVM sources +git clone --filter=blob:none --depth=1 --branch llvmorg-19.1.6 --no-checkout https://github.com/llvm/llvm-project.git llvm-project +cd llvm-project +git sparse-checkout set --cone +git checkout llvmorg-19.1.6 +git sparse-checkout set cmake llvm/cmake runtimes libcxx libcxxabi +cd .. + +## Setup libc++ options +if [ -z "$BUILD_32_BITS" ]; then + export BUILD_32_BITS=OFF && echo disabling 32 bit build +fi + +## Build and install libc++ (Use unstable ABI for better sanitizer coverage) +mkdir llvm-build && cd llvm-build +cmake -GNinja \ + -DCMAKE_C_COMPILER=${CC} \ + -DCMAKE_CXX_COMPILER=${CXX} \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DLIBCXX_ABI_UNSTABLE=OFF \ + -DLLVM_USE_SANITIZER=${LIBCXX_SANITIZER} \ + -DLLVM_BUILD_32_BITS=${BUILD_32_BITS} \ + -DLIBCXXABI_USE_LLVM_UNWINDER=OFF \ + -DLLVM_INCLUDE_TESTS=OFF \ + -DLIBCXX_INCLUDE_TESTS=OFF \ + -DLIBCXX_INCLUDE_BENCHMARKS=OFF \ + -DLLVM_ENABLE_RUNTIMES='libcxx;libcxxabi' \ + ../llvm-project/runtimes/ +cmake --build . -- cxx cxxabi +cd .. diff --git a/vendor/benchmark-38df9da/.github/workflows/bazel.yml b/vendor/benchmark-4ed29ae/.github/workflows/bazel.yml similarity index 57% rename from vendor/benchmark-38df9da/.github/workflows/bazel.yml rename to vendor/benchmark-4ed29ae/.github/workflows/bazel.yml index a669cda84..aab9aebd2 100644 --- a/vendor/benchmark-38df9da/.github/workflows/bazel.yml +++ b/vendor/benchmark-4ed29ae/.github/workflows/bazel.yml @@ -4,20 +4,25 @@ on: push: {} pull_request: {} +env: + CMAKE_GENERATOR: Ninja + +permissions: + contents: read + jobs: build_and_test_default: - name: bazel.${{ matrix.os }}.${{ matrix.bzlmod && 'bzlmod' || 'no_bzlmod' }} + name: bazel.${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - bzlmod: [false, true] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: mount bazel cache - uses: actions/cache@v3 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 env: cache-name: bazel-cache with: @@ -28,8 +33,8 @@ jobs: - name: build run: | - bazel build ${{ matrix.bzlmod && '--enable_bzlmod' || '--noenable_bzlmod' }} //:benchmark //:benchmark_main //test/... + bazel build //:benchmark //:benchmark_main //test/... - name: test run: | - bazel test ${{ matrix.bzlmod && '--enable_bzlmod' || '--noenable_bzlmod' }} --test_output=all //test/... + bazel test --test_output=all //test/... diff --git a/vendor/benchmark-38df9da/.github/workflows/build-and-test-min-cmake.yml b/vendor/benchmark-4ed29ae/.github/workflows/build-and-test-min-cmake.yml similarity index 82% rename from vendor/benchmark-38df9da/.github/workflows/build-and-test-min-cmake.yml rename to vendor/benchmark-4ed29ae/.github/workflows/build-and-test-min-cmake.yml index e3e321752..72d9e7d3a 100644 --- a/vendor/benchmark-38df9da/.github/workflows/build-and-test-min-cmake.yml +++ b/vendor/benchmark-4ed29ae/.github/workflows/build-and-test-min-cmake.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [ main ] +env: + CMAKE_GENERATOR: Ninja + jobs: job: name: ${{ matrix.os }}.min-cmake @@ -16,11 +19,11 @@ jobs: os: [ubuntu-latest, macos-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: lukka/get-cmake@latest + - uses: lukka/get-cmake@f176ccd3f28bda569c43aae4894f06b2435a3375 # latest with: - cmakeVersion: 3.10.0 + cmakeVersion: 3.13.0 - name: create build environment run: cmake -E make_directory ${{ runner.workspace }}/_build diff --git a/vendor/benchmark-38df9da/.github/workflows/build-and-test-perfcounters.yml b/vendor/benchmark-4ed29ae/.github/workflows/build-and-test-perfcounters.yml similarity index 89% rename from vendor/benchmark-38df9da/.github/workflows/build-and-test-perfcounters.yml rename to vendor/benchmark-4ed29ae/.github/workflows/build-and-test-perfcounters.yml index 97e4d8ea6..81b4170fe 100644 --- a/vendor/benchmark-38df9da/.github/workflows/build-and-test-perfcounters.yml +++ b/vendor/benchmark-4ed29ae/.github/workflows/build-and-test-perfcounters.yml @@ -6,6 +6,12 @@ on: pull_request: branches: [ main ] +env: + CMAKE_GENERATOR: Ninja + +permissions: + contents: read + jobs: job: # TODO(dominic): Extend this to include compiler and set through env: CC/CXX. @@ -14,10 +20,10 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04, ubuntu-20.04] + os: [ubuntu-latest] build_type: ['Release', 'Debug'] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: install libpfm run: | diff --git a/vendor/benchmark-38df9da/.github/workflows/build-and-test.yml b/vendor/benchmark-4ed29ae/.github/workflows/build-and-test.yml similarity index 60% rename from vendor/benchmark-38df9da/.github/workflows/build-and-test.yml rename to vendor/benchmark-4ed29ae/.github/workflows/build-and-test.yml index 95e0482ae..e3ea00139 100644 --- a/vendor/benchmark-38df9da/.github/workflows/build-and-test.yml +++ b/vendor/benchmark-4ed29ae/.github/workflows/build-and-test.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [ main ] +env: + CMAKE_GENERATOR: Ninja + jobs: # TODO: add 32-bit builds (g++ and clang++) for ubuntu # (requires g++-multilib and libc6:i386) @@ -17,41 +20,30 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04, ubuntu-20.04, macos-latest] + os: [ubuntu-24.04, ubuntu-22.04, ubuntu-24.04-arm, macos-latest] build_type: ['Release', 'Debug'] compiler: ['g++', 'clang++'] lib: ['shared', 'static'] steps: - - uses: actions/checkout@v3 - - - uses: lukka/get-cmake@latest - - - name: create build environment - run: cmake -E make_directory ${{ runner.workspace }}/_build + - name: Install dependencies (macos) + if: runner.os == 'macOS' + run: brew install ninja - - name: setup cmake initial cache - run: touch compiler-cache.cmake - - - name: configure cmake - env: - CXX: ${{ matrix.compiler }} - shell: bash - working-directory: ${{ runner.workspace }}/_build - run: > - cmake -C ${{ github.workspace }}/compiler-cache.cmake - $GITHUB_WORKSPACE - -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON - -DBUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }} - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} - -DCMAKE_CXX_COMPILER=${{ env.CXX }} - -DCMAKE_CXX_VISIBILITY_PRESET=hidden - -DCMAKE_VISIBILITY_INLINES_HIDDEN=ON + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: build - shell: bash - working-directory: ${{ runner.workspace }}/_build - run: cmake --build . --config ${{ matrix.build_type }} + uses: threeal/cmake-action@725d1314ccf9ea922805d7e3f9d9bcbca892b406 # v2.1.0 + with: + build-dir: ${{ runner.workspace }}/_build + cxx-compiler: ${{ matrix.compiler }} + options: | + BENCHMARK_DOWNLOAD_DEPENDENCIES=ON + BUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }} + CMAKE_BUILD_TYPE=${{ matrix.build_type }} + CMAKE_CXX_COMPILER=${{ matrix.compiler }} + CMAKE_CXX_VISIBILITY_PRESET=hidden + CMAKE_VISIBILITY_INLINES_HIDDEN=ON - name: test shell: bash @@ -68,10 +60,8 @@ jobs: fail-fast: false matrix: msvc: - - VS-16-2019 + - VS-17-2025 - VS-17-2022 - arch: - - x64 build_type: - Debug - Release @@ -79,31 +69,30 @@ jobs: - shared - static include: - - msvc: VS-16-2019 - os: windows-2019 - generator: 'Visual Studio 16 2019' + - msvc: VS-17-2025 + os: windows-2025 + generator: 'Visual Studio 17 2022' - msvc: VS-17-2022 os: windows-2022 generator: 'Visual Studio 17 2022' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: lukka/get-cmake@latest + - uses: lukka/get-cmake@f176ccd3f28bda569c43aae4894f06b2435a3375 # latest - name: configure cmake run: > - cmake -S . -B _build/ - -A ${{ matrix.arch }} + cmake -S . -B ${{ runner.workspace }}/_build/ -G "${{ matrix.generator }}" -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON -DBUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }} - name: build - run: cmake --build _build/ --config ${{ matrix.build_type }} + run: cmake --build ${{ runner.workspace }}/_build/ --config ${{ matrix.build_type }} - name: test - run: ctest --test-dir _build/ -C ${{ matrix.build_type }} -VV + run: ctest --test-dir ${{ runner.workspace }}/_build/ -C ${{ matrix.build_type }} -VV msys2: name: ${{ matrix.os }}.${{ matrix.build_type }}.${{ matrix.lib }}.${{ matrix.msys2.msystem }} @@ -117,9 +106,7 @@ jobs: os: [ windows-latest ] msys2: - { msystem: MINGW64, arch: x86_64, family: GNU, compiler: g++ } - - { msystem: MINGW32, arch: i686, family: GNU, compiler: g++ } - { msystem: CLANG64, arch: x86_64, family: LLVM, compiler: clang++ } - - { msystem: CLANG32, arch: i686, family: LLVM, compiler: clang++ } - { msystem: UCRT64, arch: x86_64, family: GNU, compiler: g++ } build_type: - Debug @@ -129,10 +116,8 @@ jobs: - static steps: - - uses: actions/checkout@v2 - - - name: Install Base Dependencies - uses: msys2/setup-msys2@v2 + - name: setup msys2 + uses: msys2/setup-msys2@4f806de0a5a7294ffabaff804b38a9b435a73bda # v2.30.0 with: cache: false msystem: ${{ matrix.msys2.msystem }} @@ -141,10 +126,14 @@ jobs: git base-devel pacboy: >- - cc:p + gcc:p + clang:p cmake:p ninja:p + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + # NOTE: we can't use cmake actions here as we need to do everything in msys2 shell. - name: configure cmake env: CXX: ${{ matrix.msys2.compiler }} @@ -158,4 +147,5 @@ jobs: run: cmake --build _build/ --config ${{ matrix.build_type }} - name: test - run: ctest --test-dir _build/ -C ${{ matrix.build_type }} -VV + working-directory: _build + run: ctest -C ${{ matrix.build_type }} -VV diff --git a/vendor/benchmark-4ed29ae/.github/workflows/clang-format-lint.yml b/vendor/benchmark-4ed29ae/.github/workflows/clang-format-lint.yml new file mode 100644 index 000000000..6f29b973a --- /dev/null +++ b/vendor/benchmark-4ed29ae/.github/workflows/clang-format-lint.yml @@ -0,0 +1,22 @@ +name: clang-format-lint +on: + push: {} + pull_request: {} + +env: + CMAKE_GENERATOR: Ninja + +permissions: + contents: read + +jobs: + job: + name: check-clang-format + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: DoozyX/clang-format-lint-action@bcb4eb2cb0d707ee4f3e5cc3b456eb075f12cf73 # v0.20 + with: + source: './include/benchmark ./src ./test ./bindings' + clangFormatVersion: 18 diff --git a/vendor/benchmark-38df9da/.github/workflows/clang-tidy.yml b/vendor/benchmark-4ed29ae/.github/workflows/clang-tidy-lint.yml similarity index 64% rename from vendor/benchmark-38df9da/.github/workflows/clang-tidy.yml rename to vendor/benchmark-4ed29ae/.github/workflows/clang-tidy-lint.yml index 2eaab9c1e..20a077f09 100644 --- a/vendor/benchmark-38df9da/.github/workflows/clang-tidy.yml +++ b/vendor/benchmark-4ed29ae/.github/workflows/clang-tidy-lint.yml @@ -4,6 +4,12 @@ on: push: {} pull_request: {} +env: + CMAKE_GENERATOR: Ninja + +permissions: + contents: read + jobs: job: name: run-clang-tidy @@ -11,17 +17,17 @@ jobs: strategy: fail-fast: false steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: install clang-tidy run: sudo apt update && sudo apt -y install clang-tidy - name: create build environment - run: cmake -E make_directory ${{ runner.workspace }}/_build + run: cmake -E make_directory ${{ github.workspace }}/_build - name: configure cmake shell: bash - working-directory: ${{ runner.workspace }}/_build + working-directory: ${{ github.workspace }}/_build run: > cmake $GITHUB_WORKSPACE -DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF @@ -34,5 +40,5 @@ jobs: - name: run shell: bash - working-directory: ${{ runner.workspace }}/_build - run: run-clang-tidy + working-directory: ${{ github.workspace }}/_build + run: run-clang-tidy -config-file=$GITHUB_WORKSPACE/.clang-tidy diff --git a/vendor/benchmark-38df9da/.github/workflows/doxygen.yml b/vendor/benchmark-4ed29ae/.github/workflows/doxygen.yml similarity index 82% rename from vendor/benchmark-38df9da/.github/workflows/doxygen.yml rename to vendor/benchmark-4ed29ae/.github/workflows/doxygen.yml index da92c46a2..4cfd99c9f 100644 --- a/vendor/benchmark-38df9da/.github/workflows/doxygen.yml +++ b/vendor/benchmark-4ed29ae/.github/workflows/doxygen.yml @@ -6,13 +6,19 @@ on: pull_request: branches: [main] +env: + CMAKE_GENERATOR: Ninja + +permissions: + contents: read + jobs: build-and-deploy: name: Build HTML documentation runs-on: ubuntu-latest steps: - name: Fetching sources - uses: actions/checkout@v3 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Installing build dependencies run: | diff --git a/vendor/benchmark-4ed29ae/.github/workflows/ossf.yml b/vendor/benchmark-4ed29ae/.github/workflows/ossf.yml new file mode 100644 index 000000000..8c3db2e13 --- /dev/null +++ b/vendor/benchmark-4ed29ae/.github/workflows/ossf.yml @@ -0,0 +1,27 @@ +name: OSSF Scorecard Weekly + +on: + schedule: + - cron: '0 0 * * 0' # Runs every Sunday at midnight UTC + workflow_dispatch: + +permissions: + contents: read + +jobs: + ossf-scorecard: + # To write a badge + permissions: + id-token: write + + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Run analysis + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 + with: + publish_results: true + results_file: ossf_scorecard.json + results_format: json diff --git a/vendor/benchmark-4ed29ae/.github/workflows/pre-commit.yml b/vendor/benchmark-4ed29ae/.github/workflows/pre-commit.yml new file mode 100644 index 000000000..26e18b225 --- /dev/null +++ b/vendor/benchmark-4ed29ae/.github/workflows/pre-commit.yml @@ -0,0 +1,22 @@ +name: python + Bazel pre-commit checks + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + pre-commit: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - name: Install uv + uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0 + with: + python-version: 3.12 + - name: Run pre-commit checks + run: uv run --only-group=dev pre-commit run --all-files --verbose --show-diff-on-failure diff --git a/vendor/benchmark-38df9da/.github/workflows/sanitizer.yml b/vendor/benchmark-4ed29ae/.github/workflows/sanitizer.yml similarity index 87% rename from vendor/benchmark-38df9da/.github/workflows/sanitizer.yml rename to vendor/benchmark-4ed29ae/.github/workflows/sanitizer.yml index 86cccf410..802475298 100644 --- a/vendor/benchmark-38df9da/.github/workflows/sanitizer.yml +++ b/vendor/benchmark-4ed29ae/.github/workflows/sanitizer.yml @@ -5,6 +5,7 @@ on: pull_request: {} env: + CMAKE_GENERATOR: Ninja UBSAN_OPTIONS: "print_stacktrace=1" jobs: @@ -18,7 +19,7 @@ jobs: sanitizer: ['asan', 'ubsan', 'tsan', 'msan'] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: configure msan env if: matrix.sanitizer == 'msan' @@ -51,7 +52,7 @@ jobs: echo "ASAN_OPTIONS=alloc_dealloc_mismatch=0" >> $GITHUB_ENV - name: setup clang - uses: egor-tensin/setup-clang@v1 + uses: egor-tensin/setup-clang@471a6f8ef1d449dba8e1a51780e7f943572a3f99 # v2.1 with: version: latest platform: x64 @@ -65,7 +66,7 @@ jobs: if: matrix.sanitizer != 'asan' run: | "${GITHUB_WORKSPACE}/.github/libcxx-setup.sh" - echo "EXTRA_CXX_FLAGS=-stdlib=libc++ -L ${GITHUB_WORKSPACE}/llvm-build/lib -lc++abi -Isystem${GITHUB_WORKSPACE}/llvm-build/include -Isystem${GITHUB_WORKSPACE}/llvm-build/include/c++/v1 -Wl,-rpath,${GITHUB_WORKSPACE}/llvm-build/lib" >> $GITHUB_ENV + echo "EXTRA_CXX_FLAGS=-stdlib=libc++ -L${GITHUB_WORKSPACE}/llvm-build/lib -lc++abi -I${GITHUB_WORKSPACE}/llvm-build/include/c++/v1 -Isystem${GITHUB_WORKSPACE}/llvm-build/include/c++/v1 -Wl,-rpath,${GITHUB_WORKSPACE}/llvm-build/lib" >> $GITHUB_ENV - name: create build environment run: cmake -E make_directory ${{ runner.workspace }}/_build @@ -75,7 +76,7 @@ jobs: working-directory: ${{ runner.workspace }}/_build run: > VERBOSE=1 - cmake $GITHUB_WORKSPACE + cmake -GNinja $GITHUB_WORKSPACE -DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF -DBENCHMARK_ENABLE_LIBPFM=OFF -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON diff --git a/vendor/benchmark-4ed29ae/.github/workflows/test_bindings.yml b/vendor/benchmark-4ed29ae/.github/workflows/test_bindings.yml new file mode 100644 index 000000000..016a6b2d9 --- /dev/null +++ b/vendor/benchmark-4ed29ae/.github/workflows/test_bindings.yml @@ -0,0 +1,36 @@ +name: test-bindings + +on: + push: + branches: [main] + pull_request: + branches: [main] + +env: + CMAKE_GENERATOR: Ninja + +permissions: + contents: read + +jobs: + python_bindings: + name: Test GBM Python ${{ matrix.python-version }} bindings on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest, macos-latest, windows-latest ] + python-version: [ "3.10", "3.11", "3.12", "3.13" ] + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: ${{ matrix.python-version }} + - name: Install GBM Python bindings on ${{ matrix.os }} + run: python -m pip install . + - name: Run example on ${{ matrix.os }} under Python ${{ matrix.python-version }} + run: python bindings/python/google_benchmark/example.py diff --git a/vendor/benchmark-4ed29ae/.github/workflows/wheels.yml b/vendor/benchmark-4ed29ae/.github/workflows/wheels.yml new file mode 100644 index 000000000..26312c937 --- /dev/null +++ b/vendor/benchmark-4ed29ae/.github/workflows/wheels.yml @@ -0,0 +1,84 @@ +name: Build and upload Python wheels + +on: + workflow_dispatch: + release: + types: + - published + +env: + CMAKE_GENERATOR: Ninja + +jobs: + build_sdist: + name: Build source distribution + runs-on: ubuntu-latest + steps: + - name: Check out repo + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + - name: Install Python 3.12 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: "3.12" + - run: python -m pip install build + - name: Build sdist + run: python -m build --sdist + - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + with: + name: dist-sdist + path: dist/*.tar.gz + + build_wheels: + name: Build Google Benchmark wheels on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, ubuntu-24.04-arm, macos-15-intel, macos-latest, windows-latest] + steps: + - name: Check out Google Benchmark + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + name: Install Python 3.12 + with: + python-version: "3.12" + - name: Install the latest version of uv + uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0 + + - name: Build wheels on ${{ matrix.os }} using cibuildwheel + uses: pypa/cibuildwheel@298ed2fb2c105540f5ed055e8a6ad78d82dd3a7e # v3.3.1 + env: + CIBW_BUILD: "cp310-* cp311-* cp312-*" + CIBW_BUILD_FRONTEND: "build[uv]" + CIBW_SKIP: "*-musllinux_*" + CIBW_ARCHS: auto64 + CIBW_BEFORE_ALL_LINUX: bash .github/install_bazel.sh + # Grab the rootless Bazel installation inside the container. + CIBW_ENVIRONMENT_LINUX: PATH=$PATH:$HOME/bin + CIBW_TEST_COMMAND: python {project}/bindings/python/google_benchmark/example.py + # unused by Bazel, but needed explicitly by delocate on MacOS. + MACOSX_DEPLOYMENT_TARGET: ${{ matrix.os == 'macos-15-intel' && 10.14 || 11.0 }} + + - name: Upload Google Benchmark ${{ matrix.os }} wheels + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + with: + name: dist-${{ matrix.os }} + path: wheelhouse/*.whl + + pypi_upload: + name: Publish google-benchmark wheels to PyPI + needs: [build_sdist, build_wheels] + runs-on: ubuntu-latest + permissions: + id-token: write + steps: + - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + path: dist + pattern: dist-* + merge-multiple: true + - uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1 diff --git a/vendor/benchmark-4ed29ae/.gitignore b/vendor/benchmark-4ed29ae/.gitignore new file mode 100644 index 000000000..8f6ce84ef --- /dev/null +++ b/vendor/benchmark-4ed29ae/.gitignore @@ -0,0 +1,69 @@ +*.a +*.so +*.so.?* +*.dll +*.exe +*.dylib +*.cmake +!/cmake/*.cmake +!/test/AssemblyTests.cmake +*~ +*.swp +*.pyc +__pycache__ +.DS_Store + +# lcov +*.lcov +/lcov + +# cmake files. +/Testing +CMakeCache.txt +CMakeFiles/ +cmake_install.cmake + +# makefiles. +Makefile + +# in-source build. +bin/ +lib/ +/test/*_test + +# exuberant ctags. +tags + +# YouCompleteMe configuration. +.ycm_extra_conf.pyc + +# ninja generated files. +.ninja_deps +.ninja_log +build.ninja +install_manifest.txt +rules.ninja + +# bazel output symlinks. +bazel-* +MODULE.bazel.lock + +# out-of-source build top-level folders. +build/ +_build/ +build*/ + +# in-source dependencies +/googletest/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +CMakeSettings.json + +# Visual Studio Code cache/options directory +.vscode/ + +# Python build stuff +dist/ +*.egg-info* +uv.lock diff --git a/vendor/benchmark-38df9da/.pre-commit-config.yaml b/vendor/benchmark-4ed29ae/.pre-commit-config.yaml similarity index 81% rename from vendor/benchmark-38df9da/.pre-commit-config.yaml rename to vendor/benchmark-4ed29ae/.pre-commit-config.yaml index a019caf41..57af012f7 100644 --- a/vendor/benchmark-38df9da/.pre-commit-config.yaml +++ b/vendor/benchmark-4ed29ae/.pre-commit-config.yaml @@ -1,18 +1,18 @@ repos: - repo: https://github.com/keith/pre-commit-buildifier - rev: 6.4.0 + rev: 8.2.1 hooks: - id: buildifier - id: buildifier-lint - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.10.0 + rev: v1.18.2 hooks: - id: mypy types_or: [ python, pyi ] args: [ "--ignore-missing-imports", "--scripts-are-modules" ] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.5 + rev: v0.14.0 hooks: - - id: ruff + - id: ruff-check args: [ --fix, --exit-non-zero-on-fix ] - - id: ruff-format \ No newline at end of file + - id: ruff-format diff --git a/vendor/benchmark-38df9da/.ycm_extra_conf.py b/vendor/benchmark-4ed29ae/.ycm_extra_conf.py similarity index 94% rename from vendor/benchmark-38df9da/.ycm_extra_conf.py rename to vendor/benchmark-4ed29ae/.ycm_extra_conf.py index caf257f05..ffef1b4da 100644 --- a/vendor/benchmark-38df9da/.ycm_extra_conf.py +++ b/vendor/benchmark-4ed29ae/.ycm_extra_conf.py @@ -83,10 +83,10 @@ def IsHeaderFile(filename): def GetCompilationInfoForFile(filename): - # The compilation_commands.json file generated by CMake does not have entries - # for header files. So we do our best by asking the db for flags for a - # corresponding source file, if any. If one exists, the flags for that file - # should be good enough. + # The compilation_commands.json file generated by CMake does not have + # entries for header files. So we do our best by asking the db for flags for + # a corresponding source file, if any. If one exists, the flags for that + # file should be good enough. if IsHeaderFile(filename): basename = os.path.splitext(filename)[0] for extension in SOURCE_EXTENSIONS: diff --git a/vendor/benchmark-38df9da/AUTHORS b/vendor/benchmark-4ed29ae/AUTHORS similarity index 94% rename from vendor/benchmark-38df9da/AUTHORS rename to vendor/benchmark-4ed29ae/AUTHORS index 2170e46fd..11d28f722 100644 --- a/vendor/benchmark-38df9da/AUTHORS +++ b/vendor/benchmark-4ed29ae/AUTHORS @@ -44,6 +44,7 @@ Jordan Williams Jussi Knuuttila Kaito Udagawa Kishan Kumar +Kostiantyn Lazukin Lei Xu Marcel Jacobse Matt Clarkson @@ -54,14 +55,17 @@ MongoDB Inc. Nick Hutchinson Norman Heino Oleksandr Sochka +Olga Fadeeva Ori Livneh Paul Redmond +Prithvi Rao Radoslav Yovchev Raghu Raja Rainer Orth Roman Lebedev Sayan Bhattacharjee Shapr3D +Shashank Thakur Shuo Chen Staffan Tjernstrom Steinar H. Gunderson diff --git a/vendor/benchmark-38df9da/BUILD.bazel b/vendor/benchmark-4ed29ae/BUILD.bazel similarity index 85% rename from vendor/benchmark-38df9da/BUILD.bazel rename to vendor/benchmark-4ed29ae/BUILD.bazel index 094ed6243..993b26120 100644 --- a/vendor/benchmark-38df9da/BUILD.bazel +++ b/vendor/benchmark-4ed29ae/BUILD.bazel @@ -1,15 +1,18 @@ +load("@rules_cc//cc:defs.bzl", "cc_library") + licenses(["notice"]) COPTS = [ "-pedantic", "-pedantic-errors", - "-std=c++14", + "-std=c++17", "-Wall", "-Wconversion", "-Wextra", "-Wshadow", # "-Wshorten-64-to-32", "-Wfloat-equal", + "-Wformat=2", "-fstrict-aliasing", ## assert() are used a lot in tests upstream, which may be optimised out leading to ## unused-variable warning. @@ -17,30 +20,16 @@ COPTS = [ "-Werror=old-style-cast", ] -config_setting( - name = "qnx", - constraint_values = ["@platforms//os:qnx"], - values = { - "cpu": "x64_qnx", - }, - visibility = [":__subpackages__"], -) +MSVC_COPTS = [ + "/std:c++17", +] config_setting( name = "windows", constraint_values = ["@platforms//os:windows"], - values = { - "cpu": "x64_windows", - }, visibility = [":__subpackages__"], ) -config_setting( - name = "macos", - constraint_values = ["@platforms//os:macos"], - visibility = ["//visibility:public"], -) - config_setting( name = "perfcounters", define_values = { @@ -63,7 +52,7 @@ cc_library( "include/benchmark/export.h", ], copts = select({ - ":windows": [], + ":windows": MSVC_COPTS, "//conditions:default": COPTS, }), defines = [ diff --git a/vendor/benchmark-38df9da/CMakeLists.txt b/vendor/benchmark-4ed29ae/CMakeLists.txt similarity index 92% rename from vendor/benchmark-38df9da/CMakeLists.txt rename to vendor/benchmark-4ed29ae/CMakeLists.txt index 77eb30a3e..a450a349e 100644 --- a/vendor/benchmark-38df9da/CMakeLists.txt +++ b/vendor/benchmark-4ed29ae/CMakeLists.txt @@ -1,7 +1,7 @@ # Require CMake 3.10. If available, use the policies up to CMake 3.22. -cmake_minimum_required (VERSION 3.10...3.22) +cmake_minimum_required (VERSION 3.13...3.22) -project (benchmark VERSION 1.8.4 LANGUAGES CXX) +project (benchmark VERSION 1.9.5 LANGUAGES CXX) option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." ON) option(BENCHMARK_ENABLE_EXCEPTIONS "Enable the use of exceptions in the benchmark library." ON) @@ -29,6 +29,7 @@ endif() option(BENCHMARK_ENABLE_INSTALL "Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)" ON) option(BENCHMARK_ENABLE_DOXYGEN "Build documentation with Doxygen." OFF) option(BENCHMARK_INSTALL_DOCS "Enable installation of documentation." ON) +option(BENCHMARK_INSTALL_TOOLS "Enable installation of tools." ON) # Allow unmet dependencies to be met using CMake's ExternalProject mechanics, which # may require downloading the source code. @@ -132,13 +133,18 @@ include(CheckCXXCompilerFlag) include(CheckLibraryExists) include(CXXFeatureCheck) -check_library_exists(rt shm_open "" HAVE_LIB_RT) +# Check for rt library, but explicitly disable for QNX +if(QNXNTO) + set(HAVE_LIB_RT FALSE) +else() + check_library_exists(rt shm_open "" HAVE_LIB_RT) +endif() if (BENCHMARK_BUILD_32_BITS) add_required_cxx_compiler_flag(-m32) endif() -set(BENCHMARK_CXX_STANDARD 14) +set(BENCHMARK_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD ${BENCHMARK_CXX_STANDARD}) set(CMAKE_CXX_STANDARD_REQUIRED YES) @@ -148,8 +154,17 @@ if (MSVC) # Turn compiler warnings up to 11 string(REGEX REPLACE "[-/]W[1-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") + + # MP flag only applies to cl, not cl frontends to other compilers (e.g. clang-cl, icx-cl etc) + if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") + endif() add_definitions(-D_CRT_SECURE_NO_WARNINGS) + if(BENCHMARK_ENABLE_WERROR) + add_cxx_compiler_flag(-WX) + endif() + if (NOT BENCHMARK_ENABLE_EXCEPTIONS) add_cxx_compiler_flag(-EHs-) add_cxx_compiler_flag(-EHa-) @@ -187,6 +202,7 @@ else() add_cxx_compiler_flag(-Wfloat-equal) add_cxx_compiler_flag(-Wold-style-cast) add_cxx_compiler_flag(-Wconversion) + add_cxx_compiler_flag(-Wformat=2) if(BENCHMARK_ENABLE_WERROR) add_cxx_compiler_flag(-Werror) endif() @@ -207,6 +223,9 @@ else() # See #631 for rationale. add_cxx_compiler_flag(-wd1786) add_cxx_compiler_flag(-fno-finite-math-only) + # ICC17u2: overloaded virtual function "benchmark::Fixture::SetUp" is only partially + # overridden (because of deprecated overload) + add_cxx_compiler_flag(-wd654) endif() # Disable deprecation warnings for release builds (when -Werror is enabled). if(BENCHMARK_ENABLE_WERROR) @@ -221,9 +240,7 @@ else() add_cxx_compiler_flag(-Wstrict-aliasing) endif() endif() - # ICC17u2: overloaded virtual function "benchmark::Fixture::SetUp" is only partially overridden - # (because of deprecated overload) - add_cxx_compiler_flag(-wd654) + add_cxx_compiler_flag(-Wthread-safety) if (HAVE_CXX_FLAG_WTHREAD_SAFETY) cxx_feature_check(THREAD_SAFETY_ATTRIBUTES "-DINCLUDE_DIRECTORIES=${PROJECT_SOURCE_DIR}/include") @@ -297,17 +314,18 @@ if (BENCHMARK_USE_LIBCXX) endif() endif(BENCHMARK_USE_LIBCXX) -set(EXTRA_CXX_FLAGS "") -if (WIN32 AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - # Clang on Windows fails to compile the regex feature check under C++11 - set(EXTRA_CXX_FLAGS "-DCMAKE_CXX_STANDARD=14") +# C++ feature checks +# Determine the correct regular expression engine to use. First compatible engine found is used. +cxx_feature_check(STD_REGEX) + +if(NOT HAVE_STD_REGEX) + cxx_feature_check(GNU_POSIX_REGEX) +endif() + +if(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX) + cxx_feature_check(POSIX_REGEX) endif() -# C++ feature checks -# Determine the correct regular expression engine to use -cxx_feature_check(STD_REGEX ${EXTRA_CXX_FLAGS}) -cxx_feature_check(GNU_POSIX_REGEX ${EXTRA_CXX_FLAGS}) -cxx_feature_check(POSIX_REGEX ${EXTRA_CXX_FLAGS}) if(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX) message(FATAL_ERROR "Failed to determine the source files for the regular expression backend") endif() diff --git a/vendor/benchmark-38df9da/CONTRIBUTING.md b/vendor/benchmark-4ed29ae/CONTRIBUTING.md similarity index 100% rename from vendor/benchmark-38df9da/CONTRIBUTING.md rename to vendor/benchmark-4ed29ae/CONTRIBUTING.md diff --git a/vendor/benchmark-38df9da/CONTRIBUTORS b/vendor/benchmark-4ed29ae/CONTRIBUTORS similarity index 95% rename from vendor/benchmark-38df9da/CONTRIBUTORS rename to vendor/benchmark-4ed29ae/CONTRIBUTORS index 9ca2caa3e..52e49cce4 100644 --- a/vendor/benchmark-38df9da/CONTRIBUTORS +++ b/vendor/benchmark-4ed29ae/CONTRIBUTORS @@ -42,6 +42,7 @@ Dominic Hamon Dominik Czarnota Dominik Korman Donald Aingworth +Doug Evans Eric Backus Eric Fiselier Eugene Zhuk @@ -66,6 +67,7 @@ Jussi Knuuttila Kaito Udagawa Kai Wolf Kishan Kumar +Kostiantyn Lazukin Lei Xu Marcel Jacobse Matt Clarkson @@ -75,10 +77,12 @@ Min-Yih Hsu Nick Hutchinson Norman Heino Oleksandr Sochka +Olga Fadeeva Ori Livneh Pascal Leroy Paul Redmond Pierre Phaneuf +Prithvi Rao Radoslav Yovchev Raghu Raja Rainer Orth @@ -87,6 +91,7 @@ Ray Glover Robert Guo Roman Lebedev Sayan Bhattacharjee +Shashank Thakur Shuo Chen Steven Wan Tobias Schmidt diff --git a/vendor/benchmark-38df9da/LICENSE b/vendor/benchmark-4ed29ae/LICENSE similarity index 100% rename from vendor/benchmark-38df9da/LICENSE rename to vendor/benchmark-4ed29ae/LICENSE diff --git a/vendor/benchmark-38df9da/MODULE.bazel b/vendor/benchmark-4ed29ae/MODULE.bazel similarity index 70% rename from vendor/benchmark-38df9da/MODULE.bazel rename to vendor/benchmark-4ed29ae/MODULE.bazel index 0624a34f0..c162d0531 100644 --- a/vendor/benchmark-38df9da/MODULE.bazel +++ b/vendor/benchmark-4ed29ae/MODULE.bazel @@ -1,17 +1,16 @@ module( name = "google_benchmark", - version = "1.8.4", + version = "1.9.5", ) -bazel_dep(name = "bazel_skylib", version = "1.5.0") -bazel_dep(name = "platforms", version = "0.0.8") -bazel_dep(name = "rules_foreign_cc", version = "0.10.1") +bazel_dep(name = "bazel_skylib", version = "1.7.1") +bazel_dep(name = "platforms", version = "0.0.10") bazel_dep(name = "rules_cc", version = "0.0.9") -bazel_dep(name = "rules_python", version = "0.31.0", dev_dependency = True) -bazel_dep(name = "googletest", version = "1.12.1", dev_dependency = True, repo_name = "com_google_googletest") +bazel_dep(name = "rules_python", version = "1.0.0", dev_dependency = True) +bazel_dep(name = "googletest", version = "1.14.0", dev_dependency = True, repo_name = "com_google_googletest") -bazel_dep(name = "libpfm", version = "4.11.0") +bazel_dep(name = "libpfm", version = "4.11.0.bcr.1") # Register a toolchain for Python 3.9 to be able to build numpy. Python # versions >=3.10 are problematic. @@ -27,6 +26,7 @@ python.toolchain( is_default = True, python_version = "3.12", ) +python.toolchain(python_version = "3.13") pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip", dev_dependency = True) pip.parse( @@ -38,4 +38,4 @@ use_repo(pip, "tools_pip_deps") # -- bazel_dep definitions -- # -bazel_dep(name = "nanobind_bazel", version = "1.0.0", dev_dependency = True) +bazel_dep(name = "nanobind_bazel", version = "2.9.2", dev_dependency = True) diff --git a/vendor/benchmark-38df9da/README.md b/vendor/benchmark-4ed29ae/README.md similarity index 95% rename from vendor/benchmark-38df9da/README.md rename to vendor/benchmark-4ed29ae/README.md index 8e5428f99..1d4470e8e 100644 --- a/vendor/benchmark-38df9da/README.md +++ b/vendor/benchmark-4ed29ae/README.md @@ -2,9 +2,9 @@ [![build-and-test](https://github.com/google/benchmark/workflows/build-and-test/badge.svg)](https://github.com/google/benchmark/actions?query=workflow%3Abuild-and-test) [![bazel](https://github.com/google/benchmark/actions/workflows/bazel.yml/badge.svg)](https://github.com/google/benchmark/actions/workflows/bazel.yml) -[![pylint](https://github.com/google/benchmark/workflows/pylint/badge.svg)](https://github.com/google/benchmark/actions?query=workflow%3Apylint) [![test-bindings](https://github.com/google/benchmark/workflows/test-bindings/badge.svg)](https://github.com/google/benchmark/actions?query=workflow%3Atest-bindings) [![Coverage Status](https://coveralls.io/repos/google/benchmark/badge.svg)](https://coveralls.io/r/google/benchmark) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/google/benchmark/badge)](https://securityscorecards.dev/viewer/?uri=github.com/google/benchmark) [![Discord](https://discordapp.com/api/guilds/1125694995928719494/widget.png?style=shield)](https://discord.gg/cz7UX7wKC2) @@ -50,7 +50,7 @@ IRC channels: ## Requirements -The library can be used with C++03. However, it requires C++14 to build, +The library can be used with C++11. However, it requires C++17 to build, including compiler and standard library support. _See [dependencies.md](docs/dependencies.md) for more details regarding supported @@ -78,7 +78,7 @@ $ cmake -E make_directory "build" # Generate build system files with cmake, and download any dependencies. $ cmake -E chdir "build" cmake -DBENCHMARK_DOWNLOAD_DEPENDENCIES=on -DCMAKE_BUILD_TYPE=Release ../ # or, starting with CMake 3.13, use a simpler form: -# cmake -DCMAKE_BUILD_TYPE=Release -S . -B "build" +# cmake -DBENCHMARK_DOWNLOAD_DEPENDENCIES=on -DCMAKE_BUILD_TYPE=Release -S . -B "build" # Build the library. $ cmake --build "build" --config Release ``` diff --git a/vendor/benchmark-38df9da/WORKSPACE b/vendor/benchmark-4ed29ae/WORKSPACE similarity index 77% rename from vendor/benchmark-38df9da/WORKSPACE rename to vendor/benchmark-4ed29ae/WORKSPACE index 503202465..dca485093 100644 --- a/vendor/benchmark-38df9da/WORKSPACE +++ b/vendor/benchmark-4ed29ae/WORKSPACE @@ -4,10 +4,6 @@ load("//:bazel/benchmark_deps.bzl", "benchmark_deps") benchmark_deps() -load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies") - -rules_foreign_cc_dependencies() - load("@rules_python//python:repositories.bzl", "py_repositories") py_repositories() diff --git a/vendor/benchmark-38df9da/WORKSPACE.bzlmod b/vendor/benchmark-4ed29ae/WORKSPACE.bzlmod similarity index 100% rename from vendor/benchmark-38df9da/WORKSPACE.bzlmod rename to vendor/benchmark-4ed29ae/WORKSPACE.bzlmod diff --git a/vendor/benchmark-38df9da/_config.yml b/vendor/benchmark-4ed29ae/_config.yml similarity index 100% rename from vendor/benchmark-38df9da/_config.yml rename to vendor/benchmark-4ed29ae/_config.yml diff --git a/vendor/benchmark-38df9da/appveyor.yml b/vendor/benchmark-4ed29ae/appveyor.yml similarity index 100% rename from vendor/benchmark-38df9da/appveyor.yml rename to vendor/benchmark-4ed29ae/appveyor.yml diff --git a/vendor/benchmark-38df9da/bazel/benchmark_deps.bzl b/vendor/benchmark-4ed29ae/bazel/benchmark_deps.bzl similarity index 84% rename from vendor/benchmark-38df9da/bazel/benchmark_deps.bzl rename to vendor/benchmark-4ed29ae/bazel/benchmark_deps.bzl index 4fb45a538..a6be60241 100644 --- a/vendor/benchmark-38df9da/bazel/benchmark_deps.bzl +++ b/vendor/benchmark-4ed29ae/bazel/benchmark_deps.bzl @@ -18,14 +18,6 @@ def benchmark_deps(): ], ) - if "rules_foreign_cc" not in native.existing_rules(): - http_archive( - name = "rules_foreign_cc", - sha256 = "476303bd0f1b04cc311fc258f1708a5f6ef82d3091e53fd1977fa20383425a6a", - strip_prefix = "rules_foreign_cc-0.10.1", - url = "https://github.com/bazelbuild/rules_foreign_cc/releases/download/0.10.1/rules_foreign_cc-0.10.1.tar.gz", - ) - if "rules_python" not in native.existing_rules(): http_archive( name = "rules_python", @@ -45,7 +37,7 @@ def benchmark_deps(): new_git_repository( name = "nanobind", remote = "https://github.com/wjakob/nanobind.git", - tag = "v1.8.0", + tag = "v1.9.2", build_file = "@//bindings/python:nanobind.BUILD", recursive_init_submodules = True, ) diff --git a/vendor/benchmark-38df9da/bindings/python/google_benchmark/BUILD b/vendor/benchmark-4ed29ae/bindings/python/google_benchmark/BUILD similarity index 61% rename from vendor/benchmark-38df9da/bindings/python/google_benchmark/BUILD rename to vendor/benchmark-4ed29ae/bindings/python/google_benchmark/BUILD index 0c8e3c103..8938b3716 100644 --- a/vendor/benchmark-38df9da/bindings/python/google_benchmark/BUILD +++ b/vendor/benchmark-4ed29ae/bindings/python/google_benchmark/BUILD @@ -1,4 +1,5 @@ -load("@nanobind_bazel//:build_defs.bzl", "nanobind_extension") +load("@nanobind_bazel//:build_defs.bzl", "nanobind_extension", "nanobind_stubgen") +load("@rules_python//python:defs.bzl", "py_library", "py_test") py_library( name = "google_benchmark", @@ -15,6 +16,12 @@ nanobind_extension( deps = ["//:benchmark"], ) +nanobind_stubgen( + name = "benchmark_stubgen", + marker_file = "bindings/python/google_benchmark/py.typed", + module = ":_benchmark", +) + py_test( name = "example", srcs = ["example.py"], diff --git a/vendor/benchmark-38df9da/bindings/python/google_benchmark/__init__.py b/vendor/benchmark-4ed29ae/bindings/python/google_benchmark/__init__.py similarity index 86% rename from vendor/benchmark-38df9da/bindings/python/google_benchmark/__init__.py rename to vendor/benchmark-4ed29ae/bindings/python/google_benchmark/__init__.py index c1393b4e5..331a88e9b 100644 --- a/vendor/benchmark-38df9da/bindings/python/google_benchmark/__init__.py +++ b/vendor/benchmark-4ed29ae/bindings/python/google_benchmark/__init__.py @@ -29,8 +29,6 @@ def my_benchmark(state): import atexit -from absl import app - from google_benchmark import _benchmark from google_benchmark._benchmark import ( Counter as Counter, @@ -49,7 +47,8 @@ def my_benchmark(state): oNone as oNone, oNSquared as oNSquared, ) -from google_benchmark.version import __version__ as __version__ + +__version__ = "1.9.5" class __OptionMaker: @@ -59,7 +58,8 @@ class __OptionMaker: """ class Options: - """Pure data class to store options calls, along with the benchmarked function.""" + """Pure data class to store options calls, along with the benchmarked + function.""" def __init__(self, func): self.func = func @@ -82,8 +82,8 @@ def __builder_method(*args, **kwargs): def __decorator(func_or_options): options = self.make(func_or_options) options.builder_calls.append((builder_name, args, kwargs)) - # The decorator returns Options so it is not technically a decorator - # and needs a final call to @register + # The decorator returns Options so it is not technically a + # decorator and needs a final call to @register return options return __decorator @@ -92,8 +92,8 @@ def __decorator(func_or_options): # Alias for nicer API. -# We have to instantiate an object, even if stateless, to be able to use __getattr__ -# on option.range +# We have to instantiate an object, even if stateless, to be able to use +# __getattr__ on option.range option = __OptionMaker() @@ -103,8 +103,8 @@ def register(undefined=None, *, name=None): # Decorator is called without parenthesis so we return a decorator return lambda f: register(f, name=name) - # We have either the function to benchmark (simple case) or an instance of Options - # (@option._ case). + # We have either the function to benchmark (simple case) or an instance of + # Options (@option._ case). options = __OptionMaker.make(undefined) if name is None: @@ -120,22 +120,17 @@ def register(undefined=None, *, name=None): return options.func -def _flags_parser(argv): - argv = _benchmark.Initialize(argv) - return app.parse_flags_with_usage(argv) +def main(argv: list[str] | None = None) -> None: + import sys - -def _run_benchmarks(argv): - if len(argv) > 1: - raise app.UsageError("Too many command-line arguments.") + _benchmark.Initialize(argv or sys.argv) return _benchmark.RunSpecifiedBenchmarks() -def main(argv=None): - return app.run(_run_benchmarks, argv=argv, flags_parser=_flags_parser) - +# FIXME: can we rerun with disabled ASLR? # Methods for use with custom main function. initialize = _benchmark.Initialize run_benchmarks = _benchmark.RunSpecifiedBenchmarks +add_custom_context = _benchmark.AddCustomContext atexit.register(_benchmark.ClearRegisteredBenchmarks) diff --git a/vendor/benchmark-38df9da/bindings/python/google_benchmark/benchmark.cc b/vendor/benchmark-4ed29ae/bindings/python/google_benchmark/benchmark.cc similarity index 73% rename from vendor/benchmark-38df9da/bindings/python/google_benchmark/benchmark.cc rename to vendor/benchmark-4ed29ae/bindings/python/google_benchmark/benchmark.cc index f44476901..ccd7eb5a5 100644 --- a/vendor/benchmark-38df9da/bindings/python/google_benchmark/benchmark.cc +++ b/vendor/benchmark-4ed29ae/bindings/python/google_benchmark/benchmark.cc @@ -14,16 +14,18 @@ namespace { namespace nb = nanobind; std::vector Initialize(const std::vector& argv) { - // The `argv` pointers here become invalid when this function returns, but - // benchmark holds the pointer to `argv[0]`. We create a static copy of it - // so it persists, and replace the pointer below. - static std::string executable_name(argv[0]); std::vector ptrs; ptrs.reserve(argv.size()); for (auto& arg : argv) { ptrs.push_back(const_cast(arg.c_str())); } - ptrs[0] = const_cast(executable_name.c_str()); + if (!ptrs.empty()) { + // The `argv` pointers here become invalid when this function returns, but + // benchmark holds the pointer to `argv[0]`. We create a static copy of it + // so it persists, and replace the pointer below. + static std::string executable_name(argv[0]); + ptrs[0] = const_cast(executable_name.c_str()); + } int argc = static_cast(argv.size()); benchmark::Initialize(&argc, ptrs.data()); std::vector remaining_argv; @@ -34,14 +36,13 @@ std::vector Initialize(const std::vector& argv) { return remaining_argv; } -benchmark::internal::Benchmark* RegisterBenchmark(const std::string& name, - nb::callable f) { +benchmark::Benchmark* RegisterBenchmark(const std::string& name, + nb::callable f) { return benchmark::RegisterBenchmark( name, [f](benchmark::State& state) { f(&state); }); } NB_MODULE(_benchmark, m) { - using benchmark::TimeUnit; nb::enum_(m, "TimeUnit") .value("kNanosecond", TimeUnit::kNanosecond) @@ -63,7 +64,7 @@ NB_MODULE(_benchmark, m) { .value("oLambda", BigO::oLambda) .export_values(); - using benchmark::internal::Benchmark; + using benchmark::Benchmark; nb::class_(m, "Benchmark") // For methods returning a pointer to the current object, reference // return policy is used to ask nanobind not to take ownership of the @@ -78,47 +79,40 @@ NB_MODULE(_benchmark, m) { .def("args", &Benchmark::Args, nb::rv_policy::reference) .def("range", &Benchmark::Range, nb::rv_policy::reference, nb::arg("start"), nb::arg("limit")) - .def("dense_range", &Benchmark::DenseRange, - nb::rv_policy::reference, nb::arg("start"), - nb::arg("limit"), nb::arg("step") = 1) + .def("dense_range", &Benchmark::DenseRange, nb::rv_policy::reference, + nb::arg("start"), nb::arg("limit"), nb::arg("step") = 1) .def("ranges", &Benchmark::Ranges, nb::rv_policy::reference) - .def("args_product", &Benchmark::ArgsProduct, - nb::rv_policy::reference) + .def("args_product", &Benchmark::ArgsProduct, nb::rv_policy::reference) .def("arg_name", &Benchmark::ArgName, nb::rv_policy::reference) - .def("arg_names", &Benchmark::ArgNames, - nb::rv_policy::reference) - .def("range_pair", &Benchmark::RangePair, - nb::rv_policy::reference, nb::arg("lo1"), nb::arg("hi1"), - nb::arg("lo2"), nb::arg("hi2")) + .def("arg_names", &Benchmark::ArgNames, nb::rv_policy::reference) + .def("range_pair", &Benchmark::RangePair, nb::rv_policy::reference, + nb::arg("lo1"), nb::arg("hi1"), nb::arg("lo2"), nb::arg("hi2")) .def("range_multiplier", &Benchmark::RangeMultiplier, nb::rv_policy::reference) .def("min_time", &Benchmark::MinTime, nb::rv_policy::reference) .def("min_warmup_time", &Benchmark::MinWarmUpTime, nb::rv_policy::reference) - .def("iterations", &Benchmark::Iterations, - nb::rv_policy::reference) - .def("repetitions", &Benchmark::Repetitions, - nb::rv_policy::reference) + .def("iterations", &Benchmark::Iterations, nb::rv_policy::reference) + .def("repetitions", &Benchmark::Repetitions, nb::rv_policy::reference) .def("report_aggregates_only", &Benchmark::ReportAggregatesOnly, nb::rv_policy::reference, nb::arg("value") = true) .def("display_aggregates_only", &Benchmark::DisplayAggregatesOnly, nb::rv_policy::reference, nb::arg("value") = true) .def("measure_process_cpu_time", &Benchmark::MeasureProcessCPUTime, nb::rv_policy::reference) - .def("use_real_time", &Benchmark::UseRealTime, - nb::rv_policy::reference) + .def("use_real_time", &Benchmark::UseRealTime, nb::rv_policy::reference) .def("use_manual_time", &Benchmark::UseManualTime, nb::rv_policy::reference) .def( "complexity", (Benchmark * (Benchmark::*)(benchmark::BigO)) & Benchmark::Complexity, - nb::rv_policy::reference, - nb::arg("complexity") = benchmark::oAuto); + nb::rv_policy::reference, nb::arg("complexity") = benchmark::oAuto); using benchmark::Counter; nb::class_ py_counter(m, "Counter"); - nb::enum_(py_counter, "Flags") + nb::enum_(py_counter, "Flags", nb::is_arithmetic(), + nb::is_flag()) .value("kDefaults", Counter::Flags::kDefaults) .value("kIsRate", Counter::Flags::kIsRate) .value("kAvgThreads", Counter::Flags::kAvgThreads) @@ -129,8 +123,7 @@ NB_MODULE(_benchmark, m) { .value("kAvgIterations", Counter::Flags::kAvgIterations) .value("kAvgIterationsRate", Counter::Flags::kAvgIterationsRate) .value("kInvert", Counter::Flags::kInvert) - .export_values() - .def(nb::self | nb::self); + .export_values(); nb::enum_(py_counter, "OneK") .value("kIs1000", Counter::OneK::kIs1000) @@ -141,7 +134,8 @@ NB_MODULE(_benchmark, m) { .def(nb::init(), nb::arg("value") = 0., nb::arg("flags") = Counter::kDefaults, nb::arg("k") = Counter::kIs1000) - .def("__init__", ([](Counter *c, double value) { new (c) Counter(value); })) + .def("__init__", + ([](Counter* c, double value) { new (c) Counter(value); })) .def_rw("value", &Counter::value) .def_rw("flags", &Counter::flags) .def_rw("oneK", &Counter::oneK) @@ -161,13 +155,21 @@ NB_MODULE(_benchmark, m) { .def_prop_ro("error_occurred", &State::error_occurred) .def("set_iteration_time", &State::SetIterationTime) .def_prop_rw("bytes_processed", &State::bytes_processed, - &State::SetBytesProcessed) + &State::SetBytesProcessed) .def_prop_rw("complexity_n", &State::complexity_length_n, - &State::SetComplexityN) + &State::SetComplexityN) .def_prop_rw("items_processed", &State::items_processed, &State::SetItemsProcessed) .def("set_label", &State::SetLabel) - .def("range", &State::range, nb::arg("pos") = 0) + .def( + "range", + [](const State& state, std::size_t pos = 0) -> int64_t { + if (pos < state.range_size()) { + return state.range(pos); + } + throw nb::index_error("pos is out of range"); + }, + nb::arg("pos") = 0) .def_prop_ro("iterations", &State::iterations) .def_prop_ro("name", &State::name) .def_rw("counters", &State::counters) @@ -175,10 +177,13 @@ NB_MODULE(_benchmark, m) { .def_prop_ro("threads", &State::threads); m.def("Initialize", Initialize); - m.def("RegisterBenchmark", RegisterBenchmark, - nb::rv_policy::reference); + m.def("RegisterBenchmark", RegisterBenchmark, nb::rv_policy::reference); m.def("RunSpecifiedBenchmarks", []() { benchmark::RunSpecifiedBenchmarks(); }); m.def("ClearRegisteredBenchmarks", benchmark::ClearRegisteredBenchmarks); + m.def("AddCustomContext", benchmark::AddCustomContext, nb::arg("key"), + nb::arg("value"), + "Add a key-value pair to output as part of the context stanza in the " + "report."); }; } // namespace diff --git a/vendor/benchmark-38df9da/bindings/python/google_benchmark/example.py b/vendor/benchmark-4ed29ae/bindings/python/google_benchmark/example.py similarity index 96% rename from vendor/benchmark-38df9da/bindings/python/google_benchmark/example.py rename to vendor/benchmark-4ed29ae/bindings/python/google_benchmark/example.py index b5b2f88ff..8217b409e 100644 --- a/vendor/benchmark-38df9da/bindings/python/google_benchmark/example.py +++ b/vendor/benchmark-4ed29ae/bindings/python/google_benchmark/example.py @@ -13,7 +13,8 @@ # limitations under the License. """Example of Python using C++ benchmark framework. -To run this example, you must first install the `google_benchmark` Python package. +To run this example, you must first install the `google_benchmark` Python +package. To install using `setup.py`, download and extract the `google_benchmark` source. In the extracted directory, execute: @@ -21,6 +22,7 @@ """ import random +import sys import time import google_benchmark as benchmark @@ -57,10 +59,11 @@ def skipped(state): state.skip_with_error("some error") return # NOTE: You must explicitly return, or benchmark will continue. - ... # Benchmark code would be here. + # Benchmark code would be here. @benchmark.register +@benchmark.option.use_manual_time() def manual_timing(state): while state: # Manually count Python CPU time @@ -77,7 +80,6 @@ def custom_counters(state): num_foo = 0.0 while state: # Benchmark some code here - pass # Collect some custom metric named foo num_foo += 0.13 @@ -136,4 +138,5 @@ def computing_complexity(state): if __name__ == "__main__": + benchmark.add_custom_context("python", sys.version) benchmark.main() diff --git a/vendor/benchmark-38df9da/cmake/AddCXXCompilerFlag.cmake b/vendor/benchmark-4ed29ae/cmake/AddCXXCompilerFlag.cmake similarity index 100% rename from vendor/benchmark-38df9da/cmake/AddCXXCompilerFlag.cmake rename to vendor/benchmark-4ed29ae/cmake/AddCXXCompilerFlag.cmake diff --git a/vendor/benchmark-4ed29ae/cmake/CXXFeatureCheck.cmake b/vendor/benchmark-4ed29ae/cmake/CXXFeatureCheck.cmake new file mode 100644 index 000000000..a163a6e09 --- /dev/null +++ b/vendor/benchmark-4ed29ae/cmake/CXXFeatureCheck.cmake @@ -0,0 +1,100 @@ +# - Compile and run code to check for C++ features +# +# This functions compiles a source file under the `cmake` folder +# and adds the corresponding `HAVE_[FILENAME]` flag to the CMake +# environment +# +# cxx_feature_check( []) +# +# - Example +# +# include(CXXFeatureCheck) +# cxx_feature_check(STD_REGEX) +# Requires CMake 3.13+ + +if(__cxx_feature_check) + return() +endif() +set(__cxx_feature_check INCLUDED) + +option(CXXFEATURECHECK_DEBUG OFF "Enable debug messages for CXX feature checks") + +function(cxx_feature_check_print log) + if(CXXFEATURECHECK_DEBUG) + message(STATUS "${log}") + endif() +endfunction() + +function(cxx_feature_check FEATURE) + string(TOLOWER ${FEATURE} FILE) + string(TOUPPER HAVE_${FEATURE} VAR) + + # Check if the variable is already defined to a true or false for a quick return. + # This allows users to predefine the variable to skip the check. + # Or, if the variable is already defined by a previous check, we skip the costly check. + if (DEFINED ${VAR}) + if (${VAR}) + cxx_feature_check_print("Feature ${FEATURE} already enabled.") + add_compile_definitions(${VAR}) + else() + cxx_feature_check_print("Feature ${FEATURE} already disabled.") + endif() + return() + endif() + + set(FEATURE_CHECK_CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS}) + if (ARGC GREATER 1) + message(STATUS "Enabling additional flags: ${ARGV1}") + list(APPEND FEATURE_CHECK_CMAKE_FLAGS ${ARGV1}) + endif() + + if(CMAKE_CROSSCOMPILING) + cxx_feature_check_print("Cross-compiling to test ${FEATURE}") + try_compile( + COMPILE_STATUS + ${CMAKE_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON + CMAKE_FLAGS "${FEATURE_CHECK_CMAKE_FLAGS}" + LINK_LIBRARIES "${BENCHMARK_CXX_LIBRARIES}" + OUTPUT_VARIABLE COMPILE_OUTPUT_VAR + ) + if(COMPILE_STATUS) + set(RUN_STATUS 0) + message(WARNING + "If you see build failures due to cross compilation, try setting ${VAR} to 0") + endif() + else() + cxx_feature_check_print("Compiling and running to test ${FEATURE}") + try_run( + RUN_STATUS + COMPILE_STATUS + ${CMAKE_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON + CMAKE_FLAGS "${FEATURE_CHECK_CMAKE_FLAGS}" + LINK_LIBRARIES "${BENCHMARK_CXX_LIBRARIES}" + COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT + RUN_OUTPUT_VARIABLE RUN_OUTPUT + ) + endif() + + if(COMPILE_STATUS AND RUN_STATUS EQUAL 0) + message(STATUS "Performing Test ${FEATURE} -- success") + set(${VAR} TRUE CACHE BOOL "" FORCE) + add_compile_definitions(${VAR}) + return() + endif() + + set(${VAR} FALSE CACHE BOOL "" FORCE) + message(STATUS "Performing Test ${FEATURE} -- failed") + + if(NOT COMPILE_STATUS) + cxx_feature_check_print("Compile Output: ${COMPILE_OUTPUT}") + else() + cxx_feature_check_print("Run Output: ${RUN_OUTPUT}") + endif() + +endfunction() diff --git a/vendor/benchmark-38df9da/cmake/Config.cmake.in b/vendor/benchmark-4ed29ae/cmake/Config.cmake.in similarity index 76% rename from vendor/benchmark-38df9da/cmake/Config.cmake.in rename to vendor/benchmark-4ed29ae/cmake/Config.cmake.in index 3659cfa2a..c65cdb54e 100644 --- a/vendor/benchmark-38df9da/cmake/Config.cmake.in +++ b/vendor/benchmark-4ed29ae/cmake/Config.cmake.in @@ -5,6 +5,7 @@ include (CMakeFindDependencyMacro) find_dependency (Threads) if (@BENCHMARK_ENABLE_LIBPFM@) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") find_dependency (PFM) endif() diff --git a/vendor/benchmark-38df9da/cmake/GetGitVersion.cmake b/vendor/benchmark-4ed29ae/cmake/GetGitVersion.cmake similarity index 100% rename from vendor/benchmark-38df9da/cmake/GetGitVersion.cmake rename to vendor/benchmark-4ed29ae/cmake/GetGitVersion.cmake diff --git a/vendor/benchmark-38df9da/cmake/GoogleTest.cmake b/vendor/benchmark-4ed29ae/cmake/GoogleTest.cmake similarity index 100% rename from vendor/benchmark-38df9da/cmake/GoogleTest.cmake rename to vendor/benchmark-4ed29ae/cmake/GoogleTest.cmake diff --git a/vendor/benchmark-38df9da/cmake/GoogleTest.cmake.in b/vendor/benchmark-4ed29ae/cmake/GoogleTest.cmake.in similarity index 93% rename from vendor/benchmark-38df9da/cmake/GoogleTest.cmake.in rename to vendor/benchmark-4ed29ae/cmake/GoogleTest.cmake.in index ce653ac37..647389248 100644 --- a/vendor/benchmark-38df9da/cmake/GoogleTest.cmake.in +++ b/vendor/benchmark-4ed29ae/cmake/GoogleTest.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required (VERSION 3.13...3.22) project(googletest-download NONE) @@ -34,11 +34,12 @@ else() message(SEND_ERROR "Did not find Google Test sources! Either pass correct path in GOOGLETEST_PATH, or enable BENCHMARK_DOWNLOAD_DEPENDENCIES, or disable BENCHMARK_USE_BUNDLED_GTEST, or disable BENCHMARK_ENABLE_GTEST_TESTS / BENCHMARK_ENABLE_TESTING.") return() else() - message(WARNING "Did not find Google Test sources! Fetching from web...") + message(STATUS "Did not find Google Test sources! Fetching from web...") ExternalProject_Add( googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG "release-1.11.0" + GIT_TAG "v1.15.2" + GIT_SHALLOW "ON" PREFIX "${CMAKE_BINARY_DIR}" STAMP_DIR "${CMAKE_BINARY_DIR}/stamp" DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/download" diff --git a/vendor/benchmark-38df9da/cmake/benchmark.pc.in b/vendor/benchmark-4ed29ae/cmake/benchmark.pc.in similarity index 91% rename from vendor/benchmark-38df9da/cmake/benchmark.pc.in rename to vendor/benchmark-4ed29ae/cmake/benchmark.pc.in index 043f2fc75..bbed29d1e 100644 --- a/vendor/benchmark-38df9da/cmake/benchmark.pc.in +++ b/vendor/benchmark-4ed29ae/cmake/benchmark.pc.in @@ -5,7 +5,7 @@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ Name: @PROJECT_NAME@ Description: Google microbenchmark framework -Version: @VERSION@ +Version: @NORMALIZED_VERSION@ Libs: -L${libdir} -lbenchmark Libs.private: -lpthread @BENCHMARK_PRIVATE_LINK_LIBRARIES@ diff --git a/vendor/benchmark-38df9da/cmake/benchmark_main.pc.in b/vendor/benchmark-4ed29ae/cmake/benchmark_main.pc.in similarity index 85% rename from vendor/benchmark-38df9da/cmake/benchmark_main.pc.in rename to vendor/benchmark-4ed29ae/cmake/benchmark_main.pc.in index a90f3cd06..e9d81a05e 100644 --- a/vendor/benchmark-38df9da/cmake/benchmark_main.pc.in +++ b/vendor/benchmark-4ed29ae/cmake/benchmark_main.pc.in @@ -2,6 +2,6 @@ libdir=@CMAKE_INSTALL_FULL_LIBDIR@ Name: @PROJECT_NAME@ Description: Google microbenchmark framework (with main() function) -Version: @VERSION@ +Version: @NORMALIZED_VERSION@ Requires: benchmark Libs: -L${libdir} -lbenchmark_main diff --git a/vendor/benchmark-38df9da/cmake/gnu_posix_regex.cpp b/vendor/benchmark-4ed29ae/cmake/gnu_posix_regex.cpp similarity index 100% rename from vendor/benchmark-38df9da/cmake/gnu_posix_regex.cpp rename to vendor/benchmark-4ed29ae/cmake/gnu_posix_regex.cpp diff --git a/vendor/benchmark-38df9da/cmake/llvm-toolchain.cmake b/vendor/benchmark-4ed29ae/cmake/llvm-toolchain.cmake similarity index 100% rename from vendor/benchmark-38df9da/cmake/llvm-toolchain.cmake rename to vendor/benchmark-4ed29ae/cmake/llvm-toolchain.cmake diff --git a/vendor/benchmark-38df9da/cmake/posix_regex.cpp b/vendor/benchmark-4ed29ae/cmake/posix_regex.cpp similarity index 100% rename from vendor/benchmark-38df9da/cmake/posix_regex.cpp rename to vendor/benchmark-4ed29ae/cmake/posix_regex.cpp diff --git a/vendor/benchmark-38df9da/cmake/pthread_affinity.cpp b/vendor/benchmark-4ed29ae/cmake/pthread_affinity.cpp similarity index 100% rename from vendor/benchmark-38df9da/cmake/pthread_affinity.cpp rename to vendor/benchmark-4ed29ae/cmake/pthread_affinity.cpp diff --git a/vendor/benchmark-38df9da/cmake/split_list.cmake b/vendor/benchmark-4ed29ae/cmake/split_list.cmake similarity index 100% rename from vendor/benchmark-38df9da/cmake/split_list.cmake rename to vendor/benchmark-4ed29ae/cmake/split_list.cmake diff --git a/vendor/benchmark-38df9da/cmake/std_regex.cpp b/vendor/benchmark-4ed29ae/cmake/std_regex.cpp similarity index 100% rename from vendor/benchmark-38df9da/cmake/std_regex.cpp rename to vendor/benchmark-4ed29ae/cmake/std_regex.cpp diff --git a/vendor/benchmark-38df9da/cmake/steady_clock.cpp b/vendor/benchmark-4ed29ae/cmake/steady_clock.cpp similarity index 100% rename from vendor/benchmark-38df9da/cmake/steady_clock.cpp rename to vendor/benchmark-4ed29ae/cmake/steady_clock.cpp diff --git a/vendor/benchmark-38df9da/cmake/thread_safety_attributes.cpp b/vendor/benchmark-4ed29ae/cmake/thread_safety_attributes.cpp similarity index 100% rename from vendor/benchmark-38df9da/cmake/thread_safety_attributes.cpp rename to vendor/benchmark-4ed29ae/cmake/thread_safety_attributes.cpp diff --git a/vendor/benchmark-38df9da/docs/AssemblyTests.md b/vendor/benchmark-4ed29ae/docs/AssemblyTests.md similarity index 100% rename from vendor/benchmark-38df9da/docs/AssemblyTests.md rename to vendor/benchmark-4ed29ae/docs/AssemblyTests.md diff --git a/vendor/benchmark-38df9da/docs/_config.yml b/vendor/benchmark-4ed29ae/docs/_config.yml similarity index 100% rename from vendor/benchmark-38df9da/docs/_config.yml rename to vendor/benchmark-4ed29ae/docs/_config.yml diff --git a/vendor/benchmark-38df9da/docs/assets/images/icon.png b/vendor/benchmark-4ed29ae/docs/assets/images/icon.png similarity index 100% rename from vendor/benchmark-38df9da/docs/assets/images/icon.png rename to vendor/benchmark-4ed29ae/docs/assets/images/icon.png diff --git a/vendor/benchmark-38df9da/docs/assets/images/icon.xcf b/vendor/benchmark-4ed29ae/docs/assets/images/icon.xcf similarity index 100% rename from vendor/benchmark-38df9da/docs/assets/images/icon.xcf rename to vendor/benchmark-4ed29ae/docs/assets/images/icon.xcf diff --git a/vendor/benchmark-38df9da/docs/assets/images/icon_black.png b/vendor/benchmark-4ed29ae/docs/assets/images/icon_black.png similarity index 100% rename from vendor/benchmark-38df9da/docs/assets/images/icon_black.png rename to vendor/benchmark-4ed29ae/docs/assets/images/icon_black.png diff --git a/vendor/benchmark-38df9da/docs/assets/images/icon_black.xcf b/vendor/benchmark-4ed29ae/docs/assets/images/icon_black.xcf similarity index 100% rename from vendor/benchmark-38df9da/docs/assets/images/icon_black.xcf rename to vendor/benchmark-4ed29ae/docs/assets/images/icon_black.xcf diff --git a/vendor/benchmark-38df9da/docs/dependencies.md b/vendor/benchmark-4ed29ae/docs/dependencies.md similarity index 58% rename from vendor/benchmark-38df9da/docs/dependencies.md rename to vendor/benchmark-4ed29ae/docs/dependencies.md index 07760e10e..98ce99639 100644 --- a/vendor/benchmark-38df9da/docs/dependencies.md +++ b/vendor/benchmark-4ed29ae/docs/dependencies.md @@ -11,3 +11,9 @@ distributions include newer versions, for example: * Ubuntu 20.04 provides CMake 3.16.3 * Debian 11.4 provides CMake 3.18.4 * Ubuntu 22.04 provides CMake 3.22.1 + +## Python + +The Python bindings require Python 3.10+ as of v1.9.0 (2024-08-16) for installation from PyPI. +Building from source for older versions probably still works, though. See the [user guide](python_bindings.md) for details on how to build from source. +The minimum theoretically supported version is Python 3.8, since the used bindings generator (nanobind) only supports Python 3.8+. diff --git a/vendor/benchmark-38df9da/docs/index.md b/vendor/benchmark-4ed29ae/docs/index.md similarity index 100% rename from vendor/benchmark-38df9da/docs/index.md rename to vendor/benchmark-4ed29ae/docs/index.md diff --git a/vendor/benchmark-38df9da/docs/perf_counters.md b/vendor/benchmark-4ed29ae/docs/perf_counters.md similarity index 100% rename from vendor/benchmark-38df9da/docs/perf_counters.md rename to vendor/benchmark-4ed29ae/docs/perf_counters.md diff --git a/vendor/benchmark-38df9da/docs/platform_specific_build_instructions.md b/vendor/benchmark-4ed29ae/docs/platform_specific_build_instructions.md similarity index 80% rename from vendor/benchmark-38df9da/docs/platform_specific_build_instructions.md rename to vendor/benchmark-4ed29ae/docs/platform_specific_build_instructions.md index 2d5d6c47e..5c1439d0a 100644 --- a/vendor/benchmark-38df9da/docs/platform_specific_build_instructions.md +++ b/vendor/benchmark-4ed29ae/docs/platform_specific_build_instructions.md @@ -15,22 +15,26 @@ On QNX, the pthread library is part of libc and usually included automatically [`pthread_create()`](https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.lib_ref/topic/p/pthread_create.html)). There's no separate pthread library to link. -## Building with Visual Studio 2015 or 2017 +## Building with Visual Studio 2015, 2017 or 2022 The `shlwapi` library (`-lshlwapi`) is required to support a call to `CPUInfo` which reads the registry. Either add `shlwapi.lib` under `[ Configuration Properties > Linker > Input ]`, or use the following: ``` // Alternatively, can add libraries using linker options. + +// First, Add the path to the generated library files (directory containing the `benchmark.lib`) in `[Configuration Properties > Linker > General > Additional Library Directories]`. Then do the following: #ifdef _WIN32 #pragma comment ( lib, "Shlwapi.lib" ) #ifdef _DEBUG -#pragma comment ( lib, "benchmarkd.lib" ) +#pragma comment ( lib, "benchmark.lib" ) #else #pragma comment ( lib, "benchmark.lib" ) #endif #endif ``` +When using the static library, make sure to add `BENCHMARK_STATIC_DEFINE` under `[Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions]` + Can also use the graphical version of CMake: * Open `CMake GUI`. * Under `Where to build the binaries`, same path as source plus `build`. diff --git a/vendor/benchmark-38df9da/docs/python_bindings.md b/vendor/benchmark-4ed29ae/docs/python_bindings.md similarity index 100% rename from vendor/benchmark-38df9da/docs/python_bindings.md rename to vendor/benchmark-4ed29ae/docs/python_bindings.md diff --git a/vendor/benchmark-38df9da/docs/random_interleaving.md b/vendor/benchmark-4ed29ae/docs/random_interleaving.md similarity index 100% rename from vendor/benchmark-38df9da/docs/random_interleaving.md rename to vendor/benchmark-4ed29ae/docs/random_interleaving.md diff --git a/vendor/benchmark-38df9da/docs/reducing_variance.md b/vendor/benchmark-4ed29ae/docs/reducing_variance.md similarity index 69% rename from vendor/benchmark-38df9da/docs/reducing_variance.md rename to vendor/benchmark-4ed29ae/docs/reducing_variance.md index 105f96e76..364f4af15 100644 --- a/vendor/benchmark-38df9da/docs/reducing_variance.md +++ b/vendor/benchmark-4ed29ae/docs/reducing_variance.md @@ -39,6 +39,41 @@ The benchmarks you subsequently run will have less variance. +## Disabling ASLR + +If you see this error: + +``` +***WARNING*** ASLR is enabled, the results may have unreproducible noise in them. +``` + +you might want to disable the ASLR security hardening feature while running the +benchmark. + +The simplest way is to add +``` +benchmark::MaybeReenterWithoutASLR(argc, argv); +``` +as the first line of your `main()` function. It will try to disable ASLR +for the current processor, and, if successful, re-execute the binary. +Note that `personality(2)` may be forbidden by e.g. seccomp (which happens +by default if you are running in a Docker container). + +Note that if you link to `benchmark_main` already does that for you. + +To globally disable ASLR on Linux, run +``` +echo 0 > /proc/sys/kernel/randomize_va_space +``` + +To run a single benchmark with ASLR disabled on Linux, do: +``` +setarch `uname -m` -R ./a_benchmark +``` + +Note that for the information on how to disable ASLR on other operating systems, +please refer to their documentation. + ## Reducing Variance in Benchmarks The Linux CPU frequency governor [discussed @@ -70,23 +105,28 @@ Linux workstation are: 1. Use the performance governor as [discussed above](user_guide#disabling-cpu-frequency-scaling). -1. Disable processor boosting by: +2. Disable processor boosting by: ```sh echo 0 | sudo tee /sys/devices/system/cpu/cpufreq/boost ``` See the Linux kernel's [boost.txt](https://www.kernel.org/doc/Documentation/cpu-freq/boost.txt) for more information. -2. Set the benchmark program's task affinity to a fixed cpu. For example: +3. Set the benchmark program's task affinity to a fixed cpu. For example: ```sh taskset -c 0 ./mybenchmark ``` -3. Disabling Hyperthreading/SMT. This can be done in the Bios or using the +4. Increase the program's scheduling priority to minimize context switches using `nice` or `chrt`: + ```sh + sudo nice -n -20 ./mybenchmark + sudo chrt -f 80 ./mybenchmark + ``` +5. Disabling Hyperthreading/SMT. This can be done in the Bios or using the `/sys` file system (see the LLVM project's [Benchmarking tips](https://llvm.org/docs/Benchmarking.html)). -4. Close other programs that do non-trivial things based on timers, such as +6. Close other programs that do non-trivial things based on timers, such as your web browser, desktop environment, etc. -5. Reduce the working set of your benchmark to fit within the L1 cache, but +7. Reduce the working set of your benchmark to fit within the L1 cache, but do be aware that this may lead you to optimize for an unrealistic situation. diff --git a/vendor/benchmark-38df9da/docs/releasing.md b/vendor/benchmark-4ed29ae/docs/releasing.md similarity index 64% rename from vendor/benchmark-38df9da/docs/releasing.md rename to vendor/benchmark-4ed29ae/docs/releasing.md index 09bf93764..ab664a864 100644 --- a/vendor/benchmark-38df9da/docs/releasing.md +++ b/vendor/benchmark-4ed29ae/docs/releasing.md @@ -8,16 +8,24 @@ * `git log $(git describe --abbrev=0 --tags)..HEAD` gives you the list of commits between the last annotated tag and HEAD * Pick the most interesting. -* Create one last commit that updates the version saved in `CMakeLists.txt` and `MODULE.bazel` - to the release version you're creating. (This version will be used if benchmark is installed - from the archive you'll be creating in the next step.) +* Create one last commit that updates the version saved in `CMakeLists.txt`, `MODULE.bazel`, + and `bindings/python/google_benchmark/__init__.py` to the release version you're creating. + (This version will be used if benchmark is installed from the archive you'll be creating + in the next step.) ``` -project (benchmark VERSION 1.8.0 LANGUAGES CXX) +# CMakeLists.txt +project (benchmark VERSION 1.9.0 LANGUAGES CXX) ``` ``` -module(name = "com_github_google_benchmark", version="1.8.0") +# MODULE.bazel +module(name = "com_github_google_benchmark", version="1.9.0") +``` + +``` +# google_benchmark/__init__.py +__version__ = "1.9.0" ``` * Create a release through github's interface @@ -28,4 +36,3 @@ module(name = "com_github_google_benchmark", version="1.8.0") * `git push --force --tags origin` * Confirm that the "Build and upload Python wheels" action runs to completion * Run it manually if it hasn't run. - * IMPORTANT: When re-running manually, make sure to select the newly created `` as the workflow version in the "Run workflow" tab on the GitHub Actions page. diff --git a/vendor/benchmark-38df9da/docs/tools.md b/vendor/benchmark-4ed29ae/docs/tools.md similarity index 100% rename from vendor/benchmark-38df9da/docs/tools.md rename to vendor/benchmark-4ed29ae/docs/tools.md diff --git a/vendor/benchmark-38df9da/docs/user_guide.md b/vendor/benchmark-4ed29ae/docs/user_guide.md similarity index 89% rename from vendor/benchmark-38df9da/docs/user_guide.md rename to vendor/benchmark-4ed29ae/docs/user_guide.md index d22a90690..997737f63 100644 --- a/vendor/benchmark-38df9da/docs/user_guide.md +++ b/vendor/benchmark-4ed29ae/docs/user_guide.md @@ -82,9 +82,9 @@ tabular data on stdout. Example tabular output looks like: ``` Benchmark Time(ns) CPU(ns) Iterations ---------------------------------------------------------------------- -BM_SetInsert/1024/1 28928 29349 23853 133.097kB/s 33.2742k items/s -BM_SetInsert/1024/8 32065 32913 21375 949.487kB/s 237.372k items/s -BM_SetInsert/1024/10 33157 33648 21431 1.13369MB/s 290.225k items/s +BM_SetInsert/1024/1 28928 29349 23853 133.097kiB/s 33.2742k items/s +BM_SetInsert/1024/8 32065 32913 21375 949.487kiB/s 237.372k items/s +BM_SetInsert/1024/10 33157 33648 21431 1.13369MiB/s 290.225k items/s ``` The JSON format outputs human readable json split into two top level attributes. @@ -167,6 +167,13 @@ line interface or by setting environment variables before execution. For every prevails). A complete list of CLI options is available running benchmarks with the `--help` switch. +### Dry runs + +To confirm that benchmarks can run successfully without needing to wait for +multiple repetitions and iterations, the `--benchmark_dry_run` flag can be +used. This will run the benchmarks as normal, but for 1 iteration and 1 +repetition only. + ## Running a Subset of Benchmarks @@ -445,7 +452,7 @@ benchmark. The following example enumerates a dense range on one parameter, and a sparse range on the second. ```c++ -static void CustomArguments(benchmark::internal::Benchmark* b) { +static void CustomArguments(benchmark::Benchmark* b) { for (int i = 0; i <= 10; ++i) for (int j = 32; j <= 1024*1024; j *= 8) b->Args({i, j}); @@ -455,7 +462,7 @@ BENCHMARK(BM_SetInsert)->Apply(CustomArguments); ### Passing Arbitrary Arguments to a Benchmark -In C++11 it is possible to define a benchmark that takes an arbitrary number +It is possible to define a benchmark that takes an arbitrary number of extra arguments. The `BENCHMARK_CAPTURE(func, test_case_name, ...args)` macro creates a benchmark that invokes `func` with the `benchmark::State` as the first argument followed by the specified `args...`. @@ -556,22 +563,19 @@ template void BM_Sequential(benchmark::State& state) { state.SetBytesProcessed( static_cast(state.iterations())*state.range(0)); } -// C++03 -BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue)->Range(1<<0, 1<<10); -// C++11 or newer, you can use the BENCHMARK macro with template parameters: +// You can use the BENCHMARK macro with template parameters: BENCHMARK(BM_Sequential>)->Range(1<<0, 1<<10); +// Old, legacy verbose C++03 syntax: +BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue)->Range(1<<0, 1<<10); + ``` Three macros are provided for adding benchmark templates. ```c++ -#ifdef BENCHMARK_HAS_CXX11 #define BENCHMARK(func<...>) // Takes any number of parameters. -#else // C++ < C++11 -#define BENCHMARK_TEMPLATE(func, arg1) -#endif #define BENCHMARK_TEMPLATE1(func, arg1) #define BENCHMARK_TEMPLATE2(func, arg1, arg2) ``` @@ -624,20 +628,22 @@ public: } }; +// Defines and registers `FooTest` using the class `MyFixture`. BENCHMARK_F(MyFixture, FooTest)(benchmark::State& st) { for (auto _ : st) { ... } } +// Only defines `BarTest` using the class `MyFixture`. BENCHMARK_DEFINE_F(MyFixture, BarTest)(benchmark::State& st) { for (auto _ : st) { ... } } -/* BarTest is NOT registered */ +// `BarTest` is NOT registered. BENCHMARK_REGISTER_F(MyFixture, BarTest)->Threads(2); -/* BarTest is now registered */ +// `BarTest` is now registered. ``` ### Templated Fixtures @@ -653,19 +659,70 @@ For example: template class MyFixture : public benchmark::Fixture {}; +// Defines and registers `IntTest` using the class template `MyFixture`. BENCHMARK_TEMPLATE_F(MyFixture, IntTest, int)(benchmark::State& st) { for (auto _ : st) { ... } } +// Only defines `DoubleTest` using the class template `MyFixture`. BENCHMARK_TEMPLATE_DEFINE_F(MyFixture, DoubleTest, double)(benchmark::State& st) { for (auto _ : st) { ... } } - +// `DoubleTest` is NOT registered. BENCHMARK_REGISTER_F(MyFixture, DoubleTest)->Threads(2); +// `DoubleTest` is now registered. +``` + +If you want to use a method template for your fixtures, +which you instantiate afterward, use the following macros: + +* `BENCHMARK_TEMPLATE_METHOD_F(ClassName, Method)` +* `BENCHMARK_TEMPLATE_INSTANTIATE_F(ClassName, Method, ...)` + +With these macros you can define one method for several instantiations. +Example (using `MyFixture` from above): + +```c++ +// Defines `Test` using the class template `MyFixture`. +BENCHMARK_TEMPLATE_METHOD_F(MyFixture, Test)(benchmark::State& st) { + for (auto _ : st) { + ... + } +} + +// Instantiates and registers the benchmark `MyFixture::Test`. +BENCHMARK_TEMPLATE_INSTANTIATE_F(MyFixture, Test, int)->Threads(2); +// Instantiates and registers the benchmark `MyFixture::Test`. +BENCHMARK_TEMPLATE_INSTANTIATE_F(MyFixture, Test, double)->Threads(4); +``` + +Inside the method definition of `BENCHMARK_TEMPLATE_METHOD_F` the type `Base` refers +to the type of the instantiated fixture. +Accesses to members of the fixture must be prefixed by `this->`. + +`BENCHMARK_TEMPLATE_METHOD_F`and `BENCHMARK_TEMPLATE_INSTANTIATE_F` can only be used, +if the fixture does not use non-type template parameters. +If you want to pass values as template parameters, use e.g. `std::integral_constant`. +For example: + +```c++ +template +class SizedFixture : public benchmark::Fixture { + static constexpr auto Size = Sz::value; + int myValue; +}; + +BENCHMARK_TEMPLATE_METHOD_F(SizedFixture, Test)(benchmark::State& st) { + for (auto _ : st) { + this->myValue = Base::Size; + } +} + +BENCHMARK_TEMPLATE_INSTANTIATE_F(SizedFixture, Test, std::integral_constant<5>)->Threads(2); ``` @@ -692,10 +749,6 @@ and `Counter` values. The latter is a `double`-like class, via an implicit conversion to `double&`. Thus you can use all of the standard arithmetic assignment operators (`=,+=,-=,*=,/=`) to change the value of each counter. -In multithreaded benchmarks, each counter is set on the calling thread only. -When the benchmark finishes, the counters from each thread will be summed; -the resulting sum is the value which will be shown for the benchmark. - The `Counter` constructor accepts three parameters: the value as a `double` ; a bit flag which allows you to show counters as rates, and/or as per-thread iteration, and/or as per-thread averages, and/or iteration invariants, @@ -728,12 +781,10 @@ is 1k a 1000 (default, `benchmark::Counter::OneK::kIs1000`), or 1024 state.counters["BytesProcessed"] = Counter(state.range(0), benchmark::Counter::kIsIterationInvariantRate, benchmark::Counter::OneK::kIs1024); ``` -When you're compiling in C++11 mode or later you can use `insert()` with -`std::initializer_list`: +You can use `insert()` with `std::initializer_list`: ```c++ - // With C++11, this can be done: state.counters.insert({{"Foo", numFoos}, {"Bar", numBars}, {"Baz", numBazs}}); // ... instead of: state.counters["Foo"] = numFoos; @@ -742,6 +793,10 @@ When you're compiling in C++11 mode or later you can use `insert()` with ``` +In multithreaded benchmarks, each counter is set on the calling thread only. +When the benchmark finishes, the counters from each thread will be summed. +Counters that are configured with `kIsRate`, will report the average rate across all threads, while `kAvgThreadsRate` counters will report the average rate per thread. + ### Counter Reporting When using the console reporter, by default, user counters are printed at @@ -856,6 +911,46 @@ BENCHMARK(BM_test)->Range(8, 8<<10)->UseRealTime(); Without `UseRealTime`, CPU time is used by default. +### Manual Multithreaded Benchmarks + +Google/benchmark uses `std::thread` as multithreading environment per default. +If you want to use another multithreading environment (e.g. OpenMP), you can provide +a factory function to your benchmark using the `ThreadRunner` function. +The factory function takes the number of threads as argument and creates a custom class +derived from `benchmark::ThreadRunnerBase`. +This custom class must override the function +`void RunThreads(const std::function& fn)`. +`RunThreads` is called by the main thread and spawns the requested number of threads. +Each spawned thread must call `fn(thread_index)`, where `thread_index` is its own +thread index. Before `RunThreads` returns, all spawned threads must be joined. +```c++ +class OpenMPThreadRunner : public benchmark::ThreadRunnerBase +{ + OpenMPThreadRunner(int num_threads) + : num_threads_(num_threads) + {} + + void RunThreads(const std::function& fn) final + { +#pragma omp parallel num_threads(num_threads_) + fn(omp_get_thread_num()); + } + +private: + int num_threads_; +}; + +BENCHMARK(BM_MultiThreaded) + ->ThreadRunner([](int num_threads) { + return std::make_unique(num_threads); + }) + ->Threads(1)->Threads(2)->Threads(4); +``` +The above example creates a parallel OpenMP region before it enters `BM_MultiThreaded`. +The actual benchmark code can remain the same and is therefore not tied to a specific +thread runner. The measurement does not include the time for creating and joining the +threads. + ## CPU Timers @@ -1012,11 +1107,11 @@ in any way. `` may even be removed entirely when the result is already known. For example: ```c++ - /* Example 1: `` is removed entirely. */ + // Example 1: `` is removed entirely. int foo(int x) { return x + 42; } while (...) DoNotOptimize(foo(0)); // Optimized to DoNotOptimize(42); - /* Example 2: Result of '' is only reused */ + // Example 2: Result of '' is only reused. int bar(int) __attribute__((const)); while (...) DoNotOptimize(bar(0)); // Optimized to: // int __result__ = bar(0); @@ -1094,6 +1189,7 @@ void BM_spin_empty(benchmark::State& state) { } BENCHMARK(BM_spin_empty) + ->Repetitions(3) // or add option --benchmark_repetitions=3 ->ComputeStatistics("max", [](const std::vector& v) -> double { return *(std::max_element(std::begin(v), std::end(v))); }) @@ -1113,8 +1209,9 @@ void BM_spin_empty(benchmark::State& state) { } BENCHMARK(BM_spin_empty) + ->Repetitions(3) // or add option --benchmark_repetitions=3 ->ComputeStatistics("ratio", [](const std::vector& v) -> double { - return std::begin(v) / std::end(v); + return v.front() / v.back(); }, benchmark::StatisticUnit::kPercentage) ->Arg(512); ``` @@ -1134,6 +1231,21 @@ a report on the number of allocations, bytes used, etc. This data will then be reported alongside other performance data, currently only when using JSON output. + + +## Profiling + +It's often useful to also profile benchmarks in particular ways, in addition to +CPU performance. For this reason, benchmark offers the `RegisterProfilerManager` +method that allows a custom `ProfilerManager` to be injected. + +If set, the `ProfilerManager::AfterSetupStart` and +`ProfilerManager::BeforeTeardownStop` methods will be called at the start and +end of a separate benchmark run to allow user code to collect and report +user-provided profile metrics. + +Output collected from this profiling run must be reported separately. + ## Using RegisterBenchmark(name, fn, args...) @@ -1156,6 +1268,7 @@ For Example: auto BM_test = [](benchmark::State& st, auto Inputs) { /* ... */ }; int main(int argc, char** argv) { + benchmark::MaybeReenterWithoutASLR(argc, argv); for (auto& test_input : { /* ... */ }) benchmark::RegisterBenchmark(test_input.name(), BM_test, test_input); benchmark::Initialize(&argc, argv); @@ -1220,7 +1333,7 @@ static void BM_test_ranged_fo(benchmark::State & state) { ## A Faster KeepRunning Loop -In C++11 mode, a ranged-based for loop should be used in preference to +A ranged-based for loop should be used in preference to the `KeepRunning` loop for running the benchmarks. For example: ```c++ diff --git a/vendor/benchmark-38df9da/include/benchmark/benchmark.h b/vendor/benchmark-4ed29ae/include/benchmark/benchmark.h similarity index 83% rename from vendor/benchmark-38df9da/include/benchmark/benchmark.h rename to vendor/benchmark-4ed29ae/include/benchmark/benchmark.h index 08cfe29da..f7d1341c8 100644 --- a/vendor/benchmark-38df9da/include/benchmark/benchmark.h +++ b/vendor/benchmark-4ed29ae/include/benchmark/benchmark.h @@ -40,6 +40,7 @@ BENCHMARK(BM_StringCopy); // my_unittest --benchmark_filter=String // my_unittest --benchmark_filter='Copy|Creation' int main(int argc, char** argv) { + benchmark::MaybeReenterWithoutASLR(argc, argv); benchmark::Initialize(&argc, argv); benchmark::RunSpecifiedBenchmarks(); benchmark::Shutdown(); @@ -102,7 +103,7 @@ BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}}); // arbitrary set of arguments to run the microbenchmark on. // The following example enumerates a dense range on // one parameter, and a sparse range on the second. -static void CustomArguments(benchmark::internal::Benchmark* b) { +static void CustomArguments(benchmark::Benchmark* b) { for (int i = 0; i <= 10; ++i) for (int j = 32; j <= 1024*1024; j *= 8) b->Args({i, j}); @@ -163,52 +164,32 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond); #ifndef BENCHMARK_BENCHMARK_H_ #define BENCHMARK_BENCHMARK_H_ -// The _MSVC_LANG check should detect Visual Studio 2015 Update 3 and newer. -#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L) -#define BENCHMARK_HAS_CXX11 -#endif - -// This _MSC_VER check should detect VS 2017 v15.3 and newer. -#if __cplusplus >= 201703L || \ - (defined(_MSC_VER) && _MSC_VER >= 1911 && _MSVC_LANG >= 201703L) -#define BENCHMARK_HAS_CXX17 -#endif - #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include "benchmark/export.h" -#if defined(BENCHMARK_HAS_CXX11) -#include -#include -#include -#include -#endif - #if defined(_MSC_VER) #include // for _ReadWriteBarrier #endif -#ifndef BENCHMARK_HAS_CXX11 -#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - TypeName& operator=(const TypeName&) -#else #define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&) = delete; \ TypeName& operator=(const TypeName&) = delete -#endif #ifdef BENCHMARK_HAS_CXX17 #define BENCHMARK_UNUSED [[maybe_unused]] @@ -257,6 +238,16 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond); _Pragma("diagnostic push") \ _Pragma("diag_suppress deprecated_entity_with_custom_message") #define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("diagnostic pop") +#elif defined(_MSC_VER) +#define BENCHMARK_BUILTIN_EXPECT(x, y) x +#define BENCHMARK_DEPRECATED_MSG(msg) __declspec(deprecated(msg)) +#define BENCHMARK_WARNING_MSG(msg) \ + __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \ + __LINE__) ") : warning note: " msg)) +#define BENCHMARK_DISABLE_DEPRECATED_WARNING \ + __pragma(warning(push)) \ + __pragma(warning(disable : 4996)) +#define BENCHMARK_RESTORE_DEPRECATED_WARNING __pragma(warning(pop)) #else #define BENCHMARK_BUILTIN_EXPECT(x, y) x #define BENCHMARK_DEPRECATED_MSG(msg) @@ -284,31 +275,84 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond); #define BENCHMARK_UNREACHABLE() ((void)0) #endif -#ifdef BENCHMARK_HAS_CXX11 -#define BENCHMARK_OVERRIDE override +#if defined(__GNUC__) +// Determine the cacheline size based on architecture +#if defined(__i386__) || defined(__x86_64__) +#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64 +#elif defined(__powerpc64__) +#define BENCHMARK_INTERNAL_CACHELINE_SIZE 128 +#elif defined(__aarch64__) +#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64 +#elif defined(__arm__) +// Cache line sizes for ARM: These values are not strictly correct since +// cache line sizes depend on implementations, not architectures. There +// are even implementations with cache line sizes configurable at boot +// time. +#if defined(__ARM_ARCH_5T__) +#define BENCHMARK_INTERNAL_CACHELINE_SIZE 32 +#elif defined(__ARM_ARCH_7A__) +#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64 +#endif // ARM_ARCH +#endif // arches +#endif // __GNUC__ + +#ifndef BENCHMARK_INTERNAL_CACHELINE_SIZE +// A reasonable default guess. Note that overestimates tend to waste more +// space, while underestimates tend to waste more time. +#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64 +#endif + +#if defined(__GNUC__) +// Indicates that the declared object be cache aligned using +// `BENCHMARK_INTERNAL_CACHELINE_SIZE` (see above). +#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \ + __attribute__((aligned(BENCHMARK_INTERNAL_CACHELINE_SIZE))) +#elif defined(_MSC_VER) +#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \ + __declspec(align(BENCHMARK_INTERNAL_CACHELINE_SIZE)) #else -#define BENCHMARK_OVERRIDE +#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED #endif #if defined(_MSC_VER) #pragma warning(push) // C4251: needs to have dll-interface to be used by clients of class #pragma warning(disable : 4251) -#endif +#endif // _MSC_VER_ namespace benchmark { + +namespace internal { +#if (__cplusplus < 201402L || (defined(_MSC_VER) && _MSVC_LANG < 201402L)) +template +std::unique_ptr make_unique(Args&&... args) { + return std::unique_ptr(new T(std::forward(args)...)); +} +#else +using ::std::make_unique; +#endif +} // namespace internal + class BenchmarkReporter; +class State; + +using IterationCount = int64_t; + +// Define alias of Setup/Teardown callback function type +using callback_function = std::function; // Default number of minimum benchmark running time in seconds. const char kDefaultMinTimeStr[] = "0.5s"; +BENCHMARK_EXPORT void MaybeReenterWithoutASLR(int, char**); + // Returns the version of the library. BENCHMARK_EXPORT std::string GetBenchmarkVersion(); BENCHMARK_EXPORT void PrintDefaultHelp(); BENCHMARK_EXPORT void Initialize(int* argc, char** argv, - void (*HelperPrinterf)() = PrintDefaultHelp); + void (*HelperPrintf)() = PrintDefaultHelp); BENCHMARK_EXPORT void Shutdown(); // Report to stdout all arguments in 'argv' as unrecognized except the first. @@ -377,14 +421,15 @@ BENCHMARK_EXPORT void SetDefaultTimeUnit(TimeUnit unit); // benchmark. class MemoryManager { public: - static const int64_t TombstoneValue; + static constexpr int64_t TombstoneValue = std::numeric_limits::max(); struct Result { Result() : num_allocs(0), max_bytes_used(0), total_allocated_bytes(TombstoneValue), - net_heap_growth(TombstoneValue) {} + net_heap_growth(TombstoneValue), + memory_iterations(0) {} // The number of allocations made in total between Start and Stop. int64_t num_allocs; @@ -400,6 +445,8 @@ class MemoryManager { // ie., total_allocated_bytes - total_deallocated_bytes. // Init'ed to TombstoneValue if metric not available. int64_t net_heap_growth; + + IterationCount memory_iterations; }; virtual ~MemoryManager() {} @@ -416,12 +463,33 @@ class MemoryManager { BENCHMARK_EXPORT void RegisterMemoryManager(MemoryManager* memory_manager); +// If a ProfilerManager is registered (via RegisterProfilerManager()), the +// benchmark will be run an additional time under the profiler to collect and +// report profile metrics for the run of the benchmark. +class ProfilerManager { + public: + virtual ~ProfilerManager() {} + + // This is called after `Setup()` code and right before the benchmark is run. + virtual void AfterSetupStart() = 0; + + // This is called before `Teardown()` code and right after the benchmark + // completes. + virtual void BeforeTeardownStop() = 0; +}; + +// Register a ProfilerManager instance that will be used to collect and report +// profile measurements for benchmark runs. +BENCHMARK_EXPORT +void RegisterProfilerManager(ProfilerManager* profiler_manager); + // Add a key-value pair to output as part of the context stanza in the report. BENCHMARK_EXPORT -void AddCustomContext(const std::string& key, const std::string& value); +void AddCustomContext(std::string key, std::string value); -namespace internal { class Benchmark; + +namespace internal { class BenchmarkImp; class BenchmarkFamilies; @@ -432,7 +500,8 @@ void UseCharPointer(char const volatile*); // Take ownership of the pointer and register the benchmark. Return the // registered benchmark. -BENCHMARK_EXPORT Benchmark* RegisterBenchmarkInternal(Benchmark*); +BENCHMARK_EXPORT Benchmark* RegisterBenchmarkInternal( + std::unique_ptr); // Ensure that the standard streams are properly initialized in every TU. BENCHMARK_EXPORT int InitializeStreams(); @@ -447,11 +516,9 @@ BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams(); // Force the compiler to flush pending writes to global memory. Acts as an // effective read/write barrier -#ifdef BENCHMARK_HAS_CXX11 inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { std::atomic_signal_fence(std::memory_order_acq_rel); } -#endif // The DoNotOptimize(...) function can be used to prevent a value or // expression from being optimized away by the compiler. This function is @@ -476,7 +543,6 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) { #endif } -#ifdef BENCHMARK_HAS_CXX11 template inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) { #if defined(__clang__) @@ -485,8 +551,8 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) { asm volatile("" : "+m,r"(value) : : "memory"); #endif } -#endif -#elif defined(BENCHMARK_HAS_CXX11) && (__GNUC__ >= 5) +// !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER) +#elif (__GNUC__ >= 5) // Workaround for a bug with full argument copy overhead with GCC. // See: #1340 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105519 template @@ -542,70 +608,35 @@ inline BENCHMARK_ALWAYS_INLINE DoNotOptimize(Tp&& value) { asm volatile("" : "+m"(value) : : "memory"); } +// !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER) +#endif -#else -// Fallback for GCC < 5. Can add some overhead because the compiler is forced -// to use memory operations instead of operations with registers. -// TODO: Remove if GCC < 5 will be unsupported. +#elif defined(_MSC_VER) template BENCHMARK_DEPRECATED_MSG( "The const-ref version of this method can permit " "undesired compiler optimizations in benchmarks") inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { - asm volatile("" : : "m"(value) : "memory"); + internal::UseCharPointer(&reinterpret_cast(value)); + _ReadWriteBarrier(); } template inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) { - asm volatile("" : "+m"(value) : : "memory"); -} - -#ifdef BENCHMARK_HAS_CXX11 -template -inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) { - asm volatile("" : "+m"(value) : : "memory"); -} -#endif -#endif - -#ifndef BENCHMARK_HAS_CXX11 -inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { - asm volatile("" : : : "memory"); -} -#endif -#elif defined(_MSC_VER) -template -BENCHMARK_DEPRECATED_MSG( - "The const-ref version of this method can permit " - "undesired compiler optimizations in benchmarks") -inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { internal::UseCharPointer(&reinterpret_cast(value)); _ReadWriteBarrier(); } -#ifndef BENCHMARK_HAS_CXX11 -inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { _ReadWriteBarrier(); } -#endif -#else -#ifdef BENCHMARK_HAS_CXX11 template inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) { internal::UseCharPointer(&reinterpret_cast(value)); + _ReadWriteBarrier(); } #else template -BENCHMARK_DEPRECATED_MSG( - "The const-ref version of this method can permit " - "undesired compiler optimizations in benchmarks") -inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { - internal::UseCharPointer(&reinterpret_cast(value)); -} - -template -inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) { +inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) { internal::UseCharPointer(&reinterpret_cast(value)); } -#endif // FIXME Add ClobberMemory() for non-gnu and non-msvc compilers, before C++11. #endif @@ -654,7 +685,7 @@ class Counter { Counter(double v = 0., Flags f = kDefaults, OneK k = kIs1000) : value(v), flags(f), oneK(k) {} - BENCHMARK_ALWAYS_INLINE operator double const &() const { return value; } + BENCHMARK_ALWAYS_INLINE operator double const&() const { return value; } BENCHMARK_ALWAYS_INLINE operator double&() { return value; } }; @@ -677,8 +708,6 @@ enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda }; typedef int64_t ComplexityN; -typedef int64_t IterationCount; - enum StatisticUnit { kTime, kPercentage }; // BigOFunc is passed to a benchmark in order to specify the asymptotic @@ -705,12 +734,7 @@ class ThreadTimer; class ThreadManager; class PerfCountersMeasurement; -enum AggregationReportMode -#if defined(BENCHMARK_HAS_CXX11) - : unsigned -#else -#endif -{ +enum AggregationReportMode : unsigned { // The mode has not been manually specified ARM_Unspecified = 0, // The mode is user-specified. @@ -725,11 +749,7 @@ enum AggregationReportMode ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly }; -enum Skipped -#if defined(BENCHMARK_HAS_CXX11) - : unsigned -#endif -{ +enum Skipped : unsigned { NotSkipped = 0, SkippedWithMessage, SkippedWithError @@ -737,9 +757,14 @@ enum Skipped } // namespace internal +#if defined(_MSC_VER) +#pragma warning(push) +// C4324: 'benchmark::State': structure was padded due to alignment specifier +#pragma warning(disable : 4324) +#endif // _MSC_VER_ // State is passed to a running Benchmark and contains state for the // benchmark to use. -class BENCHMARK_EXPORT State { +class BENCHMARK_EXPORT BENCHMARK_INTERNAL_CACHELINE_ALIGNED State { public: struct StateIterator; friend struct StateIterator; @@ -952,6 +977,8 @@ class BENCHMARK_EXPORT State { BENCHMARK_ALWAYS_INLINE std::string name() const { return name_; } + size_t range_size() const { return range_.size(); } + private: // items we expect on the first cache line (ie 64 bytes of the struct) // When total_iterations_ is 0, KeepRunning() and friends will return false. @@ -984,7 +1011,8 @@ class BENCHMARK_EXPORT State { State(std::string name, IterationCount max_iters, const std::vector& ranges, int thread_i, int n_threads, internal::ThreadTimer* timer, internal::ThreadManager* manager, - internal::PerfCountersMeasurement* perf_counters_measurement); + internal::PerfCountersMeasurement* perf_counters_measurement, + ProfilerManager* profiler_manager); void StartKeepRunning(); // Implementation of KeepRunning() and KeepRunningBatch(). @@ -999,9 +1027,13 @@ class BENCHMARK_EXPORT State { internal::ThreadTimer* const timer_; internal::ThreadManager* const manager_; internal::PerfCountersMeasurement* const perf_counters_measurement_; + ProfilerManager* const profiler_manager_; friend class internal::BenchmarkInstance; }; +#if defined(_MSC_VER) +#pragma warning(pop) +#endif // _MSC_VER_ inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunning() { return KeepRunningInternal(1, /*is_batch=*/false); @@ -1087,16 +1119,21 @@ inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() { return StateIterator(); } -namespace internal { +// Base class for user-defined multi-threading +struct ThreadRunnerBase { + virtual ~ThreadRunnerBase() {} + virtual void RunThreads(const std::function& fn) = 0; +}; -typedef void(Function)(State&); +// Define alias of ThreadRunner factory function type +using threadrunner_factory = + std::function(int)>; // ------------------------------------------------------ -// Benchmark registration object. The BENCHMARK() macro expands -// into an internal::Benchmark* object. Various methods can -// be called on this object to change the properties of the benchmark. -// Each method returns "this" so that multiple method calls can -// chained into one expression. +// Benchmark registration object. The BENCHMARK() macro expands into a +// Benchmark* object. Various methods can be called on this object to +// change the properties of the benchmark. Each method returns "this" so +// that multiple method calls can chained into one expression. class BENCHMARK_EXPORT Benchmark { public: virtual ~Benchmark(); @@ -1143,12 +1180,12 @@ class BENCHMARK_EXPORT Benchmark { // Run this benchmark once for a number of values picked from the // ranges [start..limit]. (starts and limits are always picked.) // REQUIRES: The function passed to the constructor must accept arg1, arg2 ... - Benchmark* Ranges(const std::vector >& ranges); + Benchmark* Ranges(const std::vector>& ranges); // Run this benchmark once for each combination of values in the (cartesian) // product of the supplied argument lists. // REQUIRES: The function passed to the constructor must accept arg1, arg2 ... - Benchmark* ArgsProduct(const std::vector >& arglists); + Benchmark* ArgsProduct(const std::vector>& arglists); // Equivalent to ArgNames({name}) Benchmark* ArgName(const std::string& name); @@ -1161,7 +1198,7 @@ class BENCHMARK_EXPORT Benchmark { // NOTE: This is a legacy C++03 interface provided for compatibility only. // New code should use 'Ranges'. Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) { - std::vector > ranges; + std::vector> ranges; ranges.push_back(std::make_pair(lo1, hi1)); ranges.push_back(std::make_pair(lo2, hi2)); return Ranges(ranges); @@ -1179,15 +1216,15 @@ class BENCHMARK_EXPORT Benchmark { // // The callback will be passed a State object, which includes the number // of threads, thread-index, benchmark arguments, etc. - // - // The callback must not be NULL or self-deleting. - Benchmark* Setup(void (*setup)(const benchmark::State&)); - Benchmark* Teardown(void (*teardown)(const benchmark::State&)); + Benchmark* Setup(callback_function&&); + Benchmark* Setup(const callback_function&); + Benchmark* Teardown(callback_function&&); + Benchmark* Teardown(const callback_function&); // Pass this benchmark object to *func, which can customize // the benchmark by calling various methods like Arg, Args, // Threads, etc. - Benchmark* Apply(void (*func)(Benchmark* benchmark)); + Benchmark* Apply(const std::function&); // Set the range multiplier for non-dense range. If not called, the range // multiplier kRangeMultiplier will be used. @@ -1293,6 +1330,9 @@ class BENCHMARK_EXPORT Benchmark { // Equivalent to ThreadRange(NumCPUs(), NumCPUs()) Benchmark* ThreadPerCpu(); + // Sets a user-defined threadrunner (see ThreadRunnerBase) + Benchmark* ThreadRunner(threadrunner_factory&& factory); + virtual void Run(State& state) = 0; TimeUnit GetTimeUnit() const; @@ -1307,13 +1347,13 @@ class BENCHMARK_EXPORT Benchmark { const char* GetArgName(int arg) const; private: - friend class BenchmarkFamilies; - friend class BenchmarkInstance; + friend class internal::BenchmarkFamilies; + friend class internal::BenchmarkInstance; std::string name_; - AggregationReportMode aggregation_report_mode_; - std::vector arg_names_; // Args for all benchmark runs - std::vector > args_; // Args for all benchmark runs + internal::AggregationReportMode aggregation_report_mode_; + std::vector arg_names_; // Args for all benchmark runs + std::vector> args_; // Args for all benchmark runs TimeUnit time_unit_; bool use_default_time_unit_; @@ -1328,39 +1368,39 @@ class BENCHMARK_EXPORT Benchmark { bool use_manual_time_; BigO complexity_; BigOFunc* complexity_lambda_; - std::vector statistics_; + std::vector statistics_; std::vector thread_counts_; - typedef void (*callback_function)(const benchmark::State&); callback_function setup_; callback_function teardown_; - Benchmark(Benchmark const&) -#if defined(BENCHMARK_HAS_CXX11) - = delete -#endif - ; + threadrunner_factory threadrunner_; - Benchmark& operator=(Benchmark const&) -#if defined(BENCHMARK_HAS_CXX11) - = delete -#endif - ; + BENCHMARK_DISALLOW_COPY_AND_ASSIGN(Benchmark); }; +namespace internal { + +// clang-format off +typedef BENCHMARK_DEPRECATED_MSG("Use ::benchmark::Benchmark instead") + ::benchmark::Benchmark Benchmark; +typedef BENCHMARK_DEPRECATED_MSG( + "Use ::benchmark::threadrunner_factory instead") + ::benchmark::threadrunner_factory threadrunner_factory; +// clang-format on + +typedef void(Function)(State&); + } // namespace internal // Create and register a benchmark with the specified 'name' that invokes // the specified functor 'fn'. // // RETURNS: A pointer to the registered benchmark. -internal::Benchmark* RegisterBenchmark(const std::string& name, - internal::Function* fn); +Benchmark* RegisterBenchmark(const std::string& name, internal::Function* fn); -#if defined(BENCHMARK_HAS_CXX11) template -internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn); -#endif +Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn); // Remove all registered benchmarks. All pointers to previously registered // benchmarks are invalidated. @@ -1369,76 +1409,61 @@ BENCHMARK_EXPORT void ClearRegisteredBenchmarks(); namespace internal { // The class used to hold all Benchmarks created from static function. // (ie those created using the BENCHMARK(...) macros. -class BENCHMARK_EXPORT FunctionBenchmark : public Benchmark { +class BENCHMARK_EXPORT FunctionBenchmark : public benchmark::Benchmark { public: FunctionBenchmark(const std::string& name, Function* func) : Benchmark(name), func_(func) {} - void Run(State& st) BENCHMARK_OVERRIDE; + void Run(State& st) override; private: Function* func_; }; -#ifdef BENCHMARK_HAS_CXX11 template -class LambdaBenchmark : public Benchmark { +class LambdaBenchmark : public benchmark::Benchmark { public: - void Run(State& st) BENCHMARK_OVERRIDE { lambda_(st); } + void Run(State& st) override { lambda_(st); } - private: template LambdaBenchmark(const std::string& name, OLambda&& lam) : Benchmark(name), lambda_(std::forward(lam)) {} + private: LambdaBenchmark(LambdaBenchmark const&) = delete; - - template // NOLINTNEXTLINE(readability-redundant-declaration) - friend Benchmark* ::benchmark::RegisterBenchmark(const std::string&, Lam&&); - Lambda lambda_; }; -#endif } // namespace internal -inline internal::Benchmark* RegisterBenchmark(const std::string& name, - internal::Function* fn) { - // FIXME: this should be a `std::make_unique<>()` but we don't have C++14. - // codechecker_intentional [cplusplus.NewDeleteLeaks] +inline Benchmark* RegisterBenchmark(const std::string& name, + internal::Function* fn) { return internal::RegisterBenchmarkInternal( - ::new internal::FunctionBenchmark(name, fn)); + ::benchmark::internal::make_unique(name, + fn)); } -#ifdef BENCHMARK_HAS_CXX11 template -internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) { +Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) { using BenchType = internal::LambdaBenchmark::type>; - // FIXME: this should be a `std::make_unique<>()` but we don't have C++14. - // codechecker_intentional [cplusplus.NewDeleteLeaks] return internal::RegisterBenchmarkInternal( - ::new BenchType(name, std::forward(fn))); + ::benchmark::internal::make_unique(name, + std::forward(fn))); } -#endif -#if defined(BENCHMARK_HAS_CXX11) && \ - (!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409) template -internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn, - Args&&... args) { +Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn, + Args&&... args) { return benchmark::RegisterBenchmark( name, [=](benchmark::State& st) { fn(st, args...); }); } -#else -#define BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK -#endif // The base class for all fixture tests. -class Fixture : public internal::Benchmark { +class Fixture : public Benchmark { public: - Fixture() : internal::Benchmark("") {} + Fixture() : Benchmark("") {} - void Run(State& st) BENCHMARK_OVERRIDE { + void Run(State& st) override { this->SetUp(st); this->BenchmarkCase(st); this->TearDown(st); @@ -1459,24 +1484,34 @@ class Fixture : public internal::Benchmark { // ------------------------------------------------------ // Macro to register benchmarks +// clang-format off +#if defined(__clang__) +#define BENCHMARK_DISABLE_COUNTER_WARNING \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wunknown-warning-option\"") \ + _Pragma("GCC diagnostic ignored \"-Wc2y-extensions\"") +#define BENCHMARK_RESTORE_COUNTER_WARNING _Pragma("GCC diagnostic pop") +#else +#define BENCHMARK_DISABLE_COUNTER_WARNING +#define BENCHMARK_RESTORE_COUNTER_WARNING +#endif +// clang-format on + // Check that __COUNTER__ is defined and that __COUNTER__ increases by 1 // every time it is expanded. X + 1 == X + 0 is used in case X is defined to be // empty. If X is empty the expression becomes (+1 == +0). +BENCHMARK_DISABLE_COUNTER_WARNING #if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0) #define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__ #else #define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__ #endif +BENCHMARK_RESTORE_COUNTER_WARNING // Helpers for generating unique variable names -#ifdef BENCHMARK_HAS_CXX11 #define BENCHMARK_PRIVATE_NAME(...) \ BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \ __VA_ARGS__) -#else -#define BENCHMARK_PRIVATE_NAME(n) \ - BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, n) -#endif // BENCHMARK_HAS_CXX11 #define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c) #define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c @@ -1484,22 +1519,19 @@ class Fixture : public internal::Benchmark { #define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \ BaseClass##_##Method##_Benchmark -#define BENCHMARK_PRIVATE_DECLARE(n) \ - static ::benchmark::internal::Benchmark* BENCHMARK_PRIVATE_NAME(n) \ - BENCHMARK_UNUSED +#define BENCHMARK_PRIVATE_DECLARE(n) \ + BENCHMARK_DISABLE_COUNTER_WARNING \ + /* NOLINTNEXTLINE(misc-use-anonymous-namespace) */ \ + static ::benchmark::Benchmark const* const BENCHMARK_PRIVATE_NAME(n) \ + BENCHMARK_RESTORE_COUNTER_WARNING BENCHMARK_UNUSED -#ifdef BENCHMARK_HAS_CXX11 -#define BENCHMARK(...) \ - BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \ - (::benchmark::internal::RegisterBenchmarkInternal( \ - new ::benchmark::internal::FunctionBenchmark(#__VA_ARGS__, \ - __VA_ARGS__))) -#else -#define BENCHMARK(n) \ - BENCHMARK_PRIVATE_DECLARE(n) = \ +#define BENCHMARK(...) \ + BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \ (::benchmark::internal::RegisterBenchmarkInternal( \ - new ::benchmark::internal::FunctionBenchmark(#n, n))) -#endif // BENCHMARK_HAS_CXX11 + ::benchmark::internal::make_unique< \ + ::benchmark::internal::FunctionBenchmark>( \ + #__VA_ARGS__, \ + static_cast<::benchmark::internal::Function*>(__VA_ARGS__)))) // Old-style macros #define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a)) @@ -1509,8 +1541,6 @@ class Fixture : public internal::Benchmark { #define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \ BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}}) -#ifdef BENCHMARK_HAS_CXX11 - // Register a benchmark which invokes the function specified by `func` // with the additional arguments specified by `...`. // @@ -1525,12 +1555,11 @@ class Fixture : public internal::Benchmark { #define BENCHMARK_CAPTURE(func, test_case_name, ...) \ BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \ (::benchmark::internal::RegisterBenchmarkInternal( \ - new ::benchmark::internal::FunctionBenchmark( \ + ::benchmark::internal::make_unique< \ + ::benchmark::internal::FunctionBenchmark>( \ #func "/" #test_case_name, \ [](::benchmark::State& st) { func(st, __VA_ARGS__); }))) -#endif // BENCHMARK_HAS_CXX11 - // This will register a benchmark for a templatized function. For example: // // template @@ -1542,25 +1571,27 @@ class Fixture : public internal::Benchmark { #define BENCHMARK_TEMPLATE1(n, a) \ BENCHMARK_PRIVATE_DECLARE(n) = \ (::benchmark::internal::RegisterBenchmarkInternal( \ - new ::benchmark::internal::FunctionBenchmark(#n "<" #a ">", n))) + ::benchmark::internal::make_unique< \ + ::benchmark::internal::FunctionBenchmark>( \ + #n "<" #a ">", \ + static_cast<::benchmark::internal::Function*>(n)))) -#define BENCHMARK_TEMPLATE2(n, a, b) \ - BENCHMARK_PRIVATE_DECLARE(n) = \ - (::benchmark::internal::RegisterBenchmarkInternal( \ - new ::benchmark::internal::FunctionBenchmark(#n "<" #a "," #b ">", \ - n))) +#define BENCHMARK_TEMPLATE2(n, a, b) \ + BENCHMARK_PRIVATE_DECLARE(n) = \ + (::benchmark::internal::RegisterBenchmarkInternal( \ + ::benchmark::internal::make_unique< \ + ::benchmark::internal::FunctionBenchmark>( \ + #n "<" #a "," #b ">", \ + static_cast<::benchmark::internal::Function*>(n)))) -#ifdef BENCHMARK_HAS_CXX11 #define BENCHMARK_TEMPLATE(n, ...) \ BENCHMARK_PRIVATE_DECLARE(n) = \ (::benchmark::internal::RegisterBenchmarkInternal( \ - new ::benchmark::internal::FunctionBenchmark( \ - #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>))) -#else -#define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a) -#endif + ::benchmark::internal::make_unique< \ + ::benchmark::internal::FunctionBenchmark>( \ + #n "<" #__VA_ARGS__ ">", \ + static_cast<::benchmark::internal::Function*>(n<__VA_ARGS__>)))) -#ifdef BENCHMARK_HAS_CXX11 // This will register a benchmark for a templatized function, // with the additional arguments specified by `...`. // @@ -1579,21 +1610,21 @@ class Fixture : public internal::Benchmark { #define BENCHMARK_TEMPLATE2_CAPTURE(func, a, b, test_case_name, ...) \ BENCHMARK_PRIVATE_DECLARE(func) = \ (::benchmark::internal::RegisterBenchmarkInternal( \ - new ::benchmark::internal::FunctionBenchmark( \ + ::benchmark::internal::make_unique< \ + ::benchmark::internal::FunctionBenchmark>( \ #func "<" #a "," #b ">" \ "/" #test_case_name, \ [](::benchmark::State& st) { func(st, __VA_ARGS__); }))) -#endif // BENCHMARK_HAS_CXX11 - -#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ - class BaseClass##_##Method##_Benchmark : public BaseClass { \ - public: \ - BaseClass##_##Method##_Benchmark() { \ - this->SetName(#BaseClass "/" #Method); \ - } \ - \ - protected: \ - void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \ + +#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ + class BaseClass##_##Method##_Benchmark : public BaseClass { \ + public: \ + BaseClass##_##Method##_Benchmark() { \ + this->SetName(#BaseClass "/" #Method); \ + } \ + \ + protected: \ + void BenchmarkCase(::benchmark::State&) override; \ }; #define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \ @@ -1604,7 +1635,7 @@ class Fixture : public internal::Benchmark { } \ \ protected: \ - void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \ + void BenchmarkCase(::benchmark::State&) override; \ }; #define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \ @@ -1615,10 +1646,9 @@ class Fixture : public internal::Benchmark { } \ \ protected: \ - void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \ + void BenchmarkCase(::benchmark::State&) override; \ }; -#ifdef BENCHMARK_HAS_CXX11 #define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...) \ class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \ public: \ @@ -1627,12 +1657,8 @@ class Fixture : public internal::Benchmark { } \ \ protected: \ - void BenchmarkCase(::benchmark::State&) BENCHMARK_OVERRIDE; \ + void BenchmarkCase(::benchmark::State&) override; \ }; -#else -#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(n, a) \ - BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(n, a) -#endif #define BENCHMARK_DEFINE_F(BaseClass, Method) \ BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ @@ -1646,21 +1672,50 @@ class Fixture : public internal::Benchmark { BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \ void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase -#ifdef BENCHMARK_HAS_CXX11 #define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...) \ BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \ void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase -#else -#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, a) \ - BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a) -#endif #define BENCHMARK_REGISTER_F(BaseClass, Method) \ BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)) -#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \ - BENCHMARK_PRIVATE_DECLARE(TestName) = \ - (::benchmark::internal::RegisterBenchmarkInternal(new TestName())) +#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \ + BENCHMARK_PRIVATE_DECLARE(TestName) = \ + (::benchmark::internal::RegisterBenchmarkInternal( \ + ::benchmark::internal::make_unique())) + +#define BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(BaseClass, Method) \ + BaseClass##_##Method##_BenchmarkTemplate + +#define BENCHMARK_TEMPLATE_METHOD_F(BaseClass, Method) \ + template \ + class BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(BaseClass, Method) \ + : public BaseClass { \ + protected: \ + using Base = BaseClass; \ + void BenchmarkCase(::benchmark::State&) override; \ + }; \ + template \ + void BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F( \ + BaseClass, Method)::BenchmarkCase + +#define BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F(BaseClass, Method, \ + UniqueName, ...) \ + class UniqueName : public BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F( \ + BaseClass, Method)<__VA_ARGS__> { \ + public: \ + UniqueName() { this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); } \ + }; \ + BENCHMARK_PRIVATE_DECLARE(BaseClass##_##Method##_Benchmark) = \ + (::benchmark::internal::RegisterBenchmarkInternal( \ + ::benchmark::internal::make_unique())) + +#define BENCHMARK_TEMPLATE_INSTANTIATE_F(BaseClass, Method, ...) \ + BENCHMARK_DISABLE_COUNTER_WARNING \ + BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F( \ + BaseClass, Method, BENCHMARK_PRIVATE_NAME(BaseClass##Method), \ + __VA_ARGS__) \ + BENCHMARK_RESTORE_COUNTER_WARNING // This macro will define and register a benchmark within a fixture class. #define BENCHMARK_F(BaseClass, Method) \ @@ -1678,22 +1733,18 @@ class Fixture : public internal::Benchmark { BENCHMARK_REGISTER_F(BaseClass, Method); \ void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase -#ifdef BENCHMARK_HAS_CXX11 #define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...) \ BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \ BENCHMARK_REGISTER_F(BaseClass, Method); \ void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase -#else -#define BENCHMARK_TEMPLATE_F(BaseClass, Method, a) \ - BENCHMARK_TEMPLATE1_F(BaseClass, Method, a) -#endif // Helper macro to create a main routine in a test that runs the benchmarks // Note the workaround for Hexagon simulator passing argc != 0, argv = NULL. #define BENCHMARK_MAIN() \ int main(int argc, char** argv) { \ + benchmark::MaybeReenterWithoutASLR(argc, argv); \ char arg0_default[] = "benchmark"; \ - char* args_default = arg0_default; \ + char* args_default = reinterpret_cast(arg0_default); \ if (!argv) { \ argc = 1; \ argv = &args_default; \ @@ -1736,7 +1787,10 @@ struct BENCHMARK_EXPORT CPUInfo { // Adding Struct for System Information struct BENCHMARK_EXPORT SystemInfo { + enum class ASLR { UNKNOWN, ENABLED, DISABLED }; + std::string name; + ASLR ASLRStatus; static const SystemInfo& Get(); private: @@ -1773,7 +1827,7 @@ class BENCHMARK_EXPORT BenchmarkReporter { CPUInfo const& cpu_info; SystemInfo const& sys_info; // The number of chars in the longest benchmark name. - size_t name_field_width; + size_t name_field_width = 0; static const char* executable_name; Context(); }; @@ -1796,9 +1850,9 @@ class BENCHMARK_EXPORT BenchmarkReporter { complexity(oNone), complexity_lambda(), complexity_n(0), + statistics(), report_big_o(false), report_rms(false), - memory_result(NULL), allocs_per_iter(0.0) {} std::string benchmark_name() const; @@ -1854,7 +1908,7 @@ class BENCHMARK_EXPORT BenchmarkReporter { UserCounters counters; // Memory metrics. - const MemoryManager::Result* memory_result; + MemoryManager::Result memory_result; double allocs_per_iter; }; @@ -1946,12 +2000,12 @@ class BENCHMARK_EXPORT ConsoleReporter : public BenchmarkReporter { explicit ConsoleReporter(OutputOptions opts_ = OO_Defaults) : output_options_(opts_), name_field_width_(0), printed_header_(false) {} - bool ReportContext(const Context& context) BENCHMARK_OVERRIDE; - void ReportRuns(const std::vector& reports) BENCHMARK_OVERRIDE; + bool ReportContext(const Context& context) override; + void ReportRuns(const std::vector& reports) override; protected: - virtual void PrintRunData(const Run& report); - virtual void PrintHeader(const Run& report); + virtual void PrintRunData(const Run& result); + virtual void PrintHeader(const Run& run); OutputOptions output_options_; size_t name_field_width_; @@ -1962,12 +2016,12 @@ class BENCHMARK_EXPORT ConsoleReporter : public BenchmarkReporter { class BENCHMARK_EXPORT JSONReporter : public BenchmarkReporter { public: JSONReporter() : first_report_(true) {} - bool ReportContext(const Context& context) BENCHMARK_OVERRIDE; - void ReportRuns(const std::vector& reports) BENCHMARK_OVERRIDE; - void Finalize() BENCHMARK_OVERRIDE; + bool ReportContext(const Context& context) override; + void ReportRuns(const std::vector& reports) override; + void Finalize() override; private: - void PrintRunData(const Run& report); + void PrintRunData(const Run& run); bool first_report_; }; @@ -1977,11 +2031,11 @@ class BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG( : public BenchmarkReporter { public: CSVReporter() : printed_header_(false) {} - bool ReportContext(const Context& context) BENCHMARK_OVERRIDE; - void ReportRuns(const std::vector& reports) BENCHMARK_OVERRIDE; + bool ReportContext(const Context& context) override; + void ReportRuns(const std::vector& reports) override; private: - void PrintRunData(const Run& report); + void PrintRunData(const Run& run); bool printed_header_; std::set user_counter_names_; diff --git a/vendor/benchmark-38df9da/include/benchmark/export.h b/vendor/benchmark-4ed29ae/include/benchmark/export.h similarity index 100% rename from vendor/benchmark-38df9da/include/benchmark/export.h rename to vendor/benchmark-4ed29ae/include/benchmark/export.h diff --git a/vendor/benchmark-38df9da/pyproject.toml b/vendor/benchmark-4ed29ae/pyproject.toml similarity index 75% rename from vendor/benchmark-38df9da/pyproject.toml rename to vendor/benchmark-4ed29ae/pyproject.toml index 62507a870..f55daf260 100644 --- a/vendor/benchmark-38df9da/pyproject.toml +++ b/vendor/benchmark-4ed29ae/pyproject.toml @@ -1,42 +1,33 @@ [build-system] -requires = ["setuptools", "setuptools-scm[toml]", "wheel"] +requires = ["setuptools"] build-backend = "setuptools.build_meta" [project] name = "google_benchmark" description = "A library to benchmark code snippets." -requires-python = ">=3.8" -license = {file = "LICENSE"} +requires-python = ">=3.10" +license = { file = "LICENSE" } keywords = ["benchmark"] -authors = [ - {name = "Google", email = "benchmark-discuss@googlegroups.com"}, -] +authors = [{ name = "Google", email = "benchmark-discuss@googlegroups.com" }] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Intended Audience :: Science/Research", "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Software Development :: Testing", "Topic :: System :: Benchmark", ] dynamic = ["readme", "version"] -dependencies = [ - "absl-py>=0.7.1", -] - -[project.optional-dependencies] -dev = [ - "pre-commit>=3.3.3", -] +[dependency-groups] +dev = ["pre-commit>=3.3.3"] [project.urls] Homepage = "https://github.com/google/benchmark" @@ -45,7 +36,7 @@ Repository = "https://github.com/google/benchmark.git" Discord = "https://discord.gg/cz7UX7wKC2" [tool.setuptools] -package-dir = {"" = "bindings/python"} +package-dir = { "" = "bindings/python" } zip-safe = false [tool.setuptools.packages.find] @@ -53,8 +44,7 @@ where = ["bindings/python"] [tool.setuptools.dynamic] readme = { file = "README.md", content-type = "text/markdown" } - -[tool.setuptools_scm] +version = { attr = "google_benchmark.__version__" } [tool.mypy] check_untyped_defs = true @@ -77,9 +67,10 @@ target-version = "py311" [tool.ruff.lint] # Enable pycodestyle (`E`, `W`), Pyflakes (`F`), and isort (`I`) codes by default. -select = ["E", "F", "I", "W"] +select = ["ASYNC", "B", "C4", "C90", "E", "F", "I", "PERF", "PIE", "PT018", "RUF", "SIM", "UP", "W"] ignore = [ - "E501", # line too long + "PLW2901", # redefined-loop-name + "UP031", # printf-string-formatting ] [tool.ruff.lint.isort] diff --git a/vendor/benchmark-38df9da/setup.py b/vendor/benchmark-4ed29ae/setup.py similarity index 66% rename from vendor/benchmark-38df9da/setup.py rename to vendor/benchmark-4ed29ae/setup.py index 40cdc8d33..d7807b499 100644 --- a/vendor/benchmark-38df9da/setup.py +++ b/vendor/benchmark-4ed29ae/setup.py @@ -3,8 +3,10 @@ import platform import re import shutil +import sys +from collections.abc import Generator from pathlib import Path -from typing import Any, Generator +from typing import Any import setuptools from setuptools.command import build_ext @@ -15,8 +17,7 @@ # hardcoded SABI-related options. Requires that each Python interpreter # (hermetic or not) participating is of the same major-minor version. -version_tuple = tuple(int(i) for i in platform.python_version_tuple()) -py_limited_api = version_tuple >= (3, 12) +py_limited_api = sys.version_info >= (3, 12) options = {"bdist_wheel": {"py_limited_api": "cp312"}} if py_limited_api else {} @@ -43,10 +44,10 @@ def fmt_toolchain_args(matchobj): return "python.toolchain(" + callargs + ")" CIBW_LINUX = is_cibuildwheel() and IS_LINUX + module_bazel = Path("MODULE.bazel") + content: str = module_bazel.read_text() try: if CIBW_LINUX: - module_bazel = Path("MODULE.bazel") - content: str = module_bazel.read_text() module_bazel.write_text( re.sub( r"python.toolchain\(([\w\"\s,.=]*)\)", @@ -77,7 +78,6 @@ class BuildBazelExtension(build_ext.build_ext): def run(self): for ext in self.extensions: self.bazel_build(ext) - super().run() # explicitly call `bazel shutdown` for graceful exit self.spawn(["bazel", "shutdown"]) @@ -87,19 +87,18 @@ def copy_extensions_to_source(self): This is done in the ``bazel_build`` method, so it's not necessary to do again in the `build_ext` base class. """ - pass - def bazel_build(self, ext: BazelExtension) -> None: + def bazel_build(self, ext: BazelExtension) -> None: # noqa: C901 """Runs the bazel build to create the package.""" temp_path = Path(self.build_temp) - # omit the patch version to avoid build errors if the toolchain is not - # yet registered in the current @rules_python version. - # patch version differences should be fine. - python_version = ".".join(platform.python_version_tuple()[:2]) + + # We round to the minor version, which makes rules_python + # look up the latest available patch version internally. + python_version = "{}.{}".format(*sys.version_info[:2]) bazel_argv = [ "bazel", - "build", + "run", ext.bazel_target, f"--symlink_prefix={temp_path / 'bazel-'}", f"--compilation_mode={'dbg' if self.debug else 'opt'}", @@ -127,20 +126,44 @@ def bazel_build(self, ext: BazelExtension) -> None: else: suffix = ".abi3.so" if ext.py_limited_api else ".so" - ext_name = ext.target_name + suffix - ext_bazel_bin_path = temp_path / "bazel-bin" / ext.relpath / ext_name - ext_dest_path = Path(self.get_ext_fullpath(ext.name)).with_name( - ext_name - ) - shutil.copyfile(ext_bazel_bin_path, ext_dest_path) + # copy the Bazel build artifacts into setuptools' libdir, + # from where the wheel is built. + pkgname = "google_benchmark" + pythonroot = Path("bindings") / "python" / "google_benchmark" + srcdir = temp_path / "bazel-bin" / pythonroot + if not self.inplace: + libdir = Path(self.build_lib) / pkgname + else: + build_py = self.get_finalized_command("build_py") + libdir = Path(build_py.get_package_dir(pkgname)) + + for root, dirs, files in os.walk(srcdir, topdown=True): + # exclude runfiles directories and children. + dirs[:] = [d for d in dirs if "runfiles" not in d] + + for f in files: + fp = Path(f) + should_copy = False + # we do not want the bare .so file included + # when building for ABI3, so we require a + # full and exact match on the file extension. + if "".join(fp.suffixes) == suffix or fp.suffix == ".pyi": + should_copy = True + elif Path(root) == srcdir and f == "py.typed": + # copy py.typed, but only at the package root. + should_copy = True + + if should_copy: + shutil.copyfile(root / fp, libdir / fp) setuptools.setup( - cmdclass=dict(build_ext=BuildBazelExtension), + cmdclass={"build_ext": BuildBazelExtension}, + package_data={"google_benchmark": ["py.typed", "*.pyi"]}, ext_modules=[ BazelExtension( name="google_benchmark._benchmark", - bazel_target="//bindings/python/google_benchmark:_benchmark", + bazel_target="//bindings/python/google_benchmark:benchmark_stubgen", py_limited_api=py_limited_api, ) ], diff --git a/vendor/benchmark-38df9da/src/CMakeLists.txt b/vendor/benchmark-4ed29ae/src/CMakeLists.txt similarity index 85% rename from vendor/benchmark-38df9da/src/CMakeLists.txt rename to vendor/benchmark-4ed29ae/src/CMakeLists.txt index d17964f9b..8e5db4115 100644 --- a/vendor/benchmark-38df9da/src/CMakeLists.txt +++ b/vendor/benchmark-4ed29ae/src/CMakeLists.txt @@ -1,4 +1,4 @@ -# Allow the source files to find headers in src/ +#Allow the source files to find headers in src / include(GNUInstallDirs) include_directories(${PROJECT_SOURCE_DIR}/src) @@ -39,6 +39,9 @@ set_property( if (PFM_FOUND) target_link_libraries(benchmark PRIVATE PFM::libpfm) target_compile_definitions(benchmark PRIVATE -DHAVE_LIBPFM) + install( + FILES "${PROJECT_SOURCE_DIR}/cmake/Modules/FindPFM.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") endif() # pthread affinity, if available @@ -64,7 +67,6 @@ endif() # We need extra libraries on Solaris if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS") target_link_libraries(benchmark PRIVATE kstat) - set(BENCHMARK_PRIVATE_LINK_LIBRARIES -lkstat) endif() if (NOT BUILD_SHARED_LIBS) @@ -106,6 +108,20 @@ write_basic_package_version_file( "${version_config}" VERSION ${GENERIC_LIB_VERSION} COMPATIBILITY SameMajorVersion ) +# Derive private link libraries from target +if(NOT BUILD_SHARED_LIBS) + get_target_property(LINK_LIBS benchmark LINK_LIBRARIES) + if(LINK_LIBS) + set(BENCHMARK_PRIVATE_LINK_LIBRARIES "") + foreach(LIB IN LISTS LINK_LIBS) + if(NOT TARGET "${LIB}" AND LIB MATCHES "^[a-zA-Z0-9_.-]+$") + list(APPEND BENCHMARK_PRIVATE_LINK_LIBRARIES "-l${LIB}") + endif() + endforeach() + string(JOIN " " BENCHMARK_PRIVATE_LINK_LIBRARIES ${BENCHMARK_PRIVATE_LINK_LIBRARIES}) + endif() +endif() + configure_file("${PROJECT_SOURCE_DIR}/cmake/benchmark.pc.in" "${pkg_config}" @ONLY) configure_file("${PROJECT_SOURCE_DIR}/cmake/benchmark_main.pc.in" "${pkg_config_main}" @ONLY) @@ -178,3 +194,11 @@ else() DESTINATION ${CMAKE_INSTALL_DOCDIR}) endif() endif() + +set(CMAKE_INSTALL_PYTOOLSDIR "${CMAKE_INSTALL_DATADIR}/googlebenchmark/tools" CACHE PATH "") + +if (BENCHMARK_ENABLE_INSTALL AND BENCHMARK_INSTALL_TOOLS) + install( + DIRECTORY "${PROJECT_SOURCE_DIR}/tools/" + DESTINATION ${CMAKE_INSTALL_PYTOOLSDIR}) +endif() diff --git a/vendor/benchmark-38df9da/src/arraysize.h b/vendor/benchmark-4ed29ae/src/arraysize.h similarity index 100% rename from vendor/benchmark-38df9da/src/arraysize.h rename to vendor/benchmark-4ed29ae/src/arraysize.h diff --git a/vendor/benchmark-38df9da/src/benchmark.cc b/vendor/benchmark-4ed29ae/src/benchmark.cc similarity index 84% rename from vendor/benchmark-38df9da/src/benchmark.cc rename to vendor/benchmark-4ed29ae/src/benchmark.cc index 337bb3faa..fc36fedb1 100644 --- a/vendor/benchmark-38df9da/src/benchmark.cc +++ b/vendor/benchmark-4ed29ae/src/benchmark.cc @@ -26,6 +26,10 @@ #include #endif +#ifdef BENCHMARK_OS_LINUX +#include +#endif + #include #include #include @@ -46,7 +50,6 @@ #include "commandlineflags.h" #include "complexity.h" #include "counter.h" -#include "internal_macros.h" #include "log.h" #include "mutex.h" #include "perf_counters.h" @@ -92,6 +95,11 @@ BM_DEFINE_double(benchmark_min_warmup_time, 0.0); // standard deviation of the runs will be reported. BM_DEFINE_int32(benchmark_repetitions, 1); +// If enabled, forces each benchmark to execute exactly one iteration and one +// repetition, bypassing any configured +// MinTime()/MinWarmUpTime()/Iterations()/Repetitions() +BM_DEFINE_bool(benchmark_dry_run, false); + // If set, enable random interleaving of repetitions of all benchmarks. // See http://github.com/google/benchmark/issues/1051 for details. BM_DEFINE_bool(benchmark_enable_random_interleaving, false); @@ -146,13 +154,17 @@ BM_DEFINE_int32(v, 0); namespace internal { +// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) std::map* global_context = nullptr; BENCHMARK_EXPORT std::map*& GetGlobalContext() { return global_context; } -static void const volatile* volatile global_force_escape_pointer; +namespace { +// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) +void const volatile* volatile global_force_escape_pointer; +} // namespace // FIXME: Verify if LTO still messes this up? void UseCharPointer(char const volatile* const v) { @@ -168,7 +180,8 @@ void UseCharPointer(char const volatile* const v) { State::State(std::string name, IterationCount max_iters, const std::vector& ranges, int thread_i, int n_threads, internal::ThreadTimer* timer, internal::ThreadManager* manager, - internal::PerfCountersMeasurement* perf_counters_measurement) + internal::PerfCountersMeasurement* perf_counters_measurement, + ProfilerManager* profiler_manager) : total_iterations_(0), batch_leftover_(0), max_iterations(max_iters), @@ -182,7 +195,8 @@ State::State(std::string name, IterationCount max_iters, threads_(n_threads), timer_(timer), manager_(manager), - perf_counters_measurement_(perf_counters_measurement) { + perf_counters_measurement_(perf_counters_measurement), + profiler_manager_(profiler_manager) { BM_CHECK(max_iterations != 0) << "At least one iteration must be run"; BM_CHECK_LT(thread_index_, threads_) << "thread_index must be less than threads"; @@ -191,7 +205,7 @@ State::State(std::string name, IterationCount max_iters, // `PauseTiming`, a new `Counter` will be inserted the first time, which // won't have the flag. Inserting them now also reduces the allocations // during the benchmark. - if (perf_counters_measurement_) { + if (perf_counters_measurement_ != nullptr) { for (const std::string& counter_name : perf_counters_measurement_->names()) { counters[counter_name] = Counter(0.0, Counter::kAvgIterations); @@ -207,7 +221,7 @@ State::State(std::string name, IterationCount max_iters, #if defined(__INTEL_COMPILER) #pragma warning push #pragma warning(disable : 1875) -#elif defined(__GNUC__) +#elif defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Winvalid-offsetof" #endif @@ -225,7 +239,7 @@ State::State(std::string name, IterationCount max_iters, offsetof(State, skipped_) <= (cache_line_size - sizeof(skipped_)), ""); #if defined(__INTEL_COMPILER) #pragma warning pop -#elif defined(__GNUC__) +#elif defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop #endif #if defined(__NVCC__) @@ -240,7 +254,7 @@ void State::PauseTiming() { // Add in time accumulated so far BM_CHECK(started_ && !finished_ && !skipped()); timer_->StopTimer(); - if (perf_counters_measurement_) { + if (perf_counters_measurement_ != nullptr) { std::vector> measurements; if (!perf_counters_measurement_->Stop(measurements)) { BM_CHECK(false) << "Perf counters read the value failed."; @@ -258,7 +272,7 @@ void State::PauseTiming() { void State::ResumeTiming() { BM_CHECK(started_ && !finished_ && !skipped()); timer_->StartTimer(); - if (perf_counters_measurement_) { + if (perf_counters_measurement_ != nullptr) { perf_counters_measurement_->Start(); } } @@ -273,7 +287,9 @@ void State::SkipWithMessage(const std::string& msg) { } } total_iterations_ = 0; - if (timer_->running()) timer_->StopTimer(); + if (timer_->running()) { + timer_->StopTimer(); + } } void State::SkipWithError(const std::string& msg) { @@ -286,7 +302,9 @@ void State::SkipWithError(const std::string& msg) { } } total_iterations_ = 0; - if (timer_->running()) timer_->StopTimer(); + if (timer_->running()) { + timer_->StopTimer(); + } } void State::SetIterationTime(double seconds) { @@ -302,8 +320,13 @@ void State::StartKeepRunning() { BM_CHECK(!started_ && !finished_); started_ = true; total_iterations_ = skipped() ? 0 : max_iterations; + if (BENCHMARK_BUILTIN_EXPECT(profiler_manager_ != nullptr, false)) { + profiler_manager_->AfterSetupStart(); + } manager_->StartStopBarrier(); - if (!skipped()) ResumeTiming(); + if (!skipped()) { + ResumeTiming(); + } } void State::FinishKeepRunning() { @@ -315,6 +338,9 @@ void State::FinishKeepRunning() { total_iterations_ = 0; finished_ = true; manager_->StartStopBarrier(); + if (BENCHMARK_BUILTIN_EXPECT(profiler_manager_ != nullptr, false)) { + profiler_manager_->BeforeTeardownStop(); + } } namespace internal { @@ -323,7 +349,9 @@ namespace { // Flushes streams after invoking reporter methods that write to them. This // ensures users get timely updates even when streams are not line-buffered. void FlushStreams(BenchmarkReporter* reporter) { - if (!reporter) return; + if (reporter == nullptr) { + return; + } std::flush(reporter->GetOutputStream()); std::flush(reporter->GetErrorStream()); } @@ -336,16 +364,20 @@ void Report(BenchmarkReporter* display_reporter, assert(reporter); // If there are no aggregates, do output non-aggregates. aggregates_only &= !results.aggregates_only.empty(); - if (!aggregates_only) reporter->ReportRuns(results.non_aggregates); - if (!results.aggregates_only.empty()) + if (!aggregates_only) { + reporter->ReportRuns(results.non_aggregates); + } + if (!results.aggregates_only.empty()) { reporter->ReportRuns(results.aggregates_only); + } }; report_one(display_reporter, run_results.display_report_aggregates_only, run_results); - if (file_reporter) + if (file_reporter != nullptr) { report_one(file_reporter, run_results.file_report_aggregates_only, run_results); + } FlushStreams(display_reporter); FlushStreams(file_reporter); @@ -366,10 +398,13 @@ void RunBenchmarks(const std::vector& benchmarks, std::max(name_field_width, benchmark.name().str().size()); might_have_aggregates |= benchmark.repetitions() > 1; - for (const auto& Stat : benchmark.statistics()) + for (const auto& Stat : benchmark.statistics()) { stat_field_width = std::max(stat_field_width, Stat.name_.size()); + } + } + if (might_have_aggregates) { + name_field_width += 1 + stat_field_width; } - if (might_have_aggregates) name_field_width += 1 + stat_field_width; // Print header here BenchmarkReporter::Context context; @@ -380,7 +415,7 @@ void RunBenchmarks(const std::vector& benchmarks, per_family_reports; if (display_reporter->ReportContext(context) && - (!file_reporter || file_reporter->ReportContext(context))) { + ((file_reporter == nullptr) || file_reporter->ReportContext(context))) { FlushStreams(display_reporter); FlushStreams(file_reporter); @@ -402,15 +437,17 @@ void RunBenchmarks(const std::vector& benchmarks, // Loop through all benchmarks for (const BenchmarkInstance& benchmark : benchmarks) { BenchmarkReporter::PerFamilyRunReports* reports_for_family = nullptr; - if (benchmark.complexity() != oNone) + if (benchmark.complexity() != oNone) { reports_for_family = &per_family_reports[benchmark.family_index()]; - benchmarks_with_threads += (benchmark.threads() > 1); + } + benchmarks_with_threads += static_cast(benchmark.threads() > 1); runners.emplace_back(benchmark, &perfcounters, reports_for_family); int num_repeats_of_this_instance = runners.back().GetNumRepeats(); num_repetitions_total += static_cast(num_repeats_of_this_instance); - if (reports_for_family) + if (reports_for_family != nullptr) { reports_for_family->num_runs_total += num_repeats_of_this_instance; + } } assert(runners.size() == benchmarks.size() && "Unexpected runner count."); @@ -445,14 +482,17 @@ void RunBenchmarks(const std::vector& benchmarks, for (size_t repetition_index : repetition_indices) { internal::BenchmarkRunner& runner = runners[repetition_index]; runner.DoOneRepetition(); - if (runner.HasRepeatsRemaining()) continue; + if (runner.HasRepeatsRemaining()) { + continue; + } // FIXME: report each repetition separately, not all of them in bulk. display_reporter->ReportRunsConfig( runner.GetMinTime(), runner.HasExplicitIters(), runner.GetIters()); - if (file_reporter) + if (file_reporter != nullptr) { file_reporter->ReportRunsConfig( runner.GetMinTime(), runner.HasExplicitIters(), runner.GetIters()); + } RunResults run_results = runner.GetResults(); @@ -473,7 +513,9 @@ void RunBenchmarks(const std::vector& benchmarks, } } display_reporter->Finalize(); - if (file_reporter) file_reporter->Finalize(); + if (file_reporter != nullptr) { + file_reporter->Finalize(); + } FlushStreams(display_reporter); FlushStreams(file_reporter); } @@ -495,6 +537,7 @@ std::unique_ptr CreateReporter( return PtrType(new CSVReporter()); } std::cerr << "Unexpected format: '" << name << "'\n"; + std::flush(std::cerr); std::exit(1); } @@ -533,7 +576,7 @@ ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color) { } // end namespace internal BenchmarkReporter* CreateDefaultDisplayReporter() { - static auto default_display_reporter = + static auto* default_display_reporter = internal::CreateReporter(FLAGS_benchmark_format, internal::GetOutputOptions()) .release(); @@ -567,14 +610,15 @@ size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter, std::string spec) { - if (spec.empty() || spec == "all") + if (spec.empty() || spec == "all") { spec = "."; // Regexp that matches all benchmarks + } // Setup the reporters std::ofstream output_file; std::unique_ptr default_display_reporter; std::unique_ptr default_file_reporter; - if (!display_reporter) { + if (display_reporter == nullptr) { default_display_reporter.reset(CreateDefaultDisplayReporter()); display_reporter = default_display_reporter.get(); } @@ -582,10 +626,9 @@ size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, auto& Err = display_reporter->GetErrorStream(); std::string const& fname = FLAGS_benchmark_out; - if (fname.empty() && file_reporter) { + if (fname.empty() && (file_reporter != nullptr)) { Err << "A custom file reporter was provided but " - "--benchmark_out= was not specified." - << std::endl; + "--benchmark_out= was not specified.\n"; Out.flush(); Err.flush(); std::exit(1); @@ -593,12 +636,12 @@ size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, if (!fname.empty()) { output_file.open(fname); if (!output_file.is_open()) { - Err << "invalid file name: '" << fname << "'" << std::endl; + Err << "invalid file name: '" << fname << "'\n"; Out.flush(); Err.flush(); std::exit(1); } - if (!file_reporter) { + if (file_reporter == nullptr) { default_file_reporter = internal::CreateReporter( FLAGS_benchmark_out_format, FLAGS_benchmark_counters_tabular ? ConsoleReporter::OO_Tabular @@ -624,8 +667,9 @@ size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, } if (FLAGS_benchmark_list_tests) { - for (auto const& benchmark : benchmarks) + for (auto const& benchmark : benchmarks) { Out << benchmark.name().str() << "\n"; + } } else { internal::RunBenchmarks(benchmarks, display_reporter, file_reporter); } @@ -656,11 +700,20 @@ void RegisterMemoryManager(MemoryManager* manager) { internal::memory_manager = manager; } -void AddCustomContext(const std::string& key, const std::string& value) { +void RegisterProfilerManager(ProfilerManager* manager) { + // Don't allow overwriting an existing manager. + if (manager != nullptr) { + BM_CHECK_EQ(internal::profiler_manager, nullptr); + } + internal::profiler_manager = manager; +} + +void AddCustomContext(std::string key, std::string value) { if (internal::global_context == nullptr) { internal::global_context = new std::map(); } - if (!internal::global_context->emplace(key, value).second) { + if (!internal::global_context->emplace(std::move(key), std::move(value)) + .second) { std::cerr << "Failed to add custom context \"" << key << "\" as it already " << "exists with value \"" << value << "\"\n"; } @@ -670,9 +723,12 @@ namespace internal { void (*HelperPrintf)(); +namespace { void PrintUsageAndExit() { HelperPrintf(); - exit(0); + std::flush(std::cout); + std::flush(std::cerr); + std::exit(0); } void SetDefaultTimeUnitFromFlag(const std::string& time_unit_flag) { @@ -696,8 +752,8 @@ void SetDefaultTimeUnitFromFlag(const std::string& time_unit_flag) { void ParseCommandLineFlags(int* argc, char** argv) { using namespace benchmark; BenchmarkReporter::Context::executable_name = - (argc && *argc > 0) ? argv[0] : "unknown"; - for (int i = 1; argc && i < *argc; ++i) { + ((argc != nullptr) && *argc > 0) ? argv[0] : "unknown"; + for (int i = 1; (argc != nullptr) && i < *argc; ++i) { if (ParseBoolFlag(argv[i], "benchmark_list_tests", &FLAGS_benchmark_list_tests) || ParseStringFlag(argv[i], "benchmark_filter", &FLAGS_benchmark_filter) || @@ -707,6 +763,7 @@ void ParseCommandLineFlags(int* argc, char** argv) { &FLAGS_benchmark_min_warmup_time) || ParseInt32Flag(argv[i], "benchmark_repetitions", &FLAGS_benchmark_repetitions) || + ParseBoolFlag(argv[i], "benchmark_dry_run", &FLAGS_benchmark_dry_run) || ParseBoolFlag(argv[i], "benchmark_enable_random_interleaving", &FLAGS_benchmark_enable_random_interleaving) || ParseBoolFlag(argv[i], "benchmark_report_aggregates_only", @@ -727,7 +784,9 @@ void ParseCommandLineFlags(int* argc, char** argv) { ParseStringFlag(argv[i], "benchmark_time_unit", &FLAGS_benchmark_time_unit) || ParseInt32Flag(argv[i], "v", &FLAGS_v)) { - for (int j = i; j != *argc - 1; ++j) argv[j] = argv[j + 1]; + for (int j = i; j != *argc - 1; ++j) { + argv[j] = argv[j + 1]; + } --(*argc); --i; @@ -745,18 +804,66 @@ void ParseCommandLineFlags(int* argc, char** argv) { if (FLAGS_benchmark_color.empty()) { PrintUsageAndExit(); } + if (FLAGS_benchmark_dry_run) { + AddCustomContext("dry_run", "true"); + } for (const auto& kv : FLAGS_benchmark_context) { AddCustomContext(kv.first, kv.second); } } +} // end namespace + int InitializeStreams() { static std::ios_base::Init init; return 0; } +template +std::make_unsigned_t get_as_unsigned(T v) { + using UnsignedT = std::make_unsigned_t; + return static_cast(v); +} + } // end namespace internal +void MaybeReenterWithoutASLR(int /*argc*/, char** argv) { + // On e.g. Hexagon simulator, argv may be NULL. + if (!argv) return; + +#ifdef BENCHMARK_OS_LINUX + const auto curr_personality = personality(0xffffffff); + + // We should never fail to read-only query the current personality, + // but let's be cautious. + if (curr_personality == -1) return; + + // If ASLR is already disabled, we have nothing more to do. + if (internal::get_as_unsigned(curr_personality) & ADDR_NO_RANDOMIZE) return; + + // Try to change the personality to disable ASLR. + const auto proposed_personality = + internal::get_as_unsigned(curr_personality) | ADDR_NO_RANDOMIZE; + const auto prev_personality = personality(proposed_personality); + + // Have we failed to change the personality? That may happen. + if (prev_personality == -1) return; + + // Make sure the parsona has been updated with the no-ASLR flag, + // otherwise we will try to reenter infinitely. + // This seems impossible, but can happen in some docker configurations. + const auto new_personality = personality(0xffffffff); + if ((internal::get_as_unsigned(new_personality) & ADDR_NO_RANDOMIZE) == 0) + return; + + execv(argv[0], argv); + // The exec() functions return only if an error has occurred, + // in which case we want to just continue as-is. +#else + return; +#endif +} + std::string GetBenchmarkVersion() { #ifdef BENCHMARK_VERSION return {BENCHMARK_VERSION}; @@ -773,6 +880,7 @@ void PrintDefaultHelp() { " [--benchmark_min_time=`x` OR `s` ]\n" " [--benchmark_min_warmup_time=]\n" " [--benchmark_repetitions=]\n" + " [--benchmark_dry_run={true|false}]\n" " [--benchmark_enable_random_interleaving={true|false}]\n" " [--benchmark_report_aggregates_only={true|false}]\n" " [--benchmark_display_aggregates_only={true|false}]\n" diff --git a/vendor/benchmark-38df9da/src/benchmark_api_internal.cc b/vendor/benchmark-4ed29ae/src/benchmark_api_internal.cc similarity index 86% rename from vendor/benchmark-38df9da/src/benchmark_api_internal.cc rename to vendor/benchmark-4ed29ae/src/benchmark_api_internal.cc index 286f98653..f9c4990dd 100644 --- a/vendor/benchmark-38df9da/src/benchmark_api_internal.cc +++ b/vendor/benchmark-4ed29ae/src/benchmark_api_internal.cc @@ -7,7 +7,8 @@ namespace benchmark { namespace internal { -BenchmarkInstance::BenchmarkInstance(Benchmark* benchmark, int family_idx, +BenchmarkInstance::BenchmarkInstance(benchmark::Benchmark* benchmark, + int family_idx, int per_family_instance_idx, const std::vector& args, int thread_count) @@ -27,7 +28,9 @@ BenchmarkInstance::BenchmarkInstance(Benchmark* benchmark, int family_idx, min_time_(benchmark_.min_time_), min_warmup_time_(benchmark_.min_warmup_time_), iterations_(benchmark_.iterations_), - threads_(thread_count) { + threads_(thread_count), + setup_(benchmark_.setup_), + teardown_(benchmark_.teardown_) { name_.function_name = benchmark_.name_; size_t arg_i = 0; @@ -84,33 +87,31 @@ BenchmarkInstance::BenchmarkInstance(Benchmark* benchmark, int family_idx, if (!benchmark_.thread_counts_.empty()) { name_.threads = StrFormat("threads:%d", threads_); } - - setup_ = benchmark_.setup_; - teardown_ = benchmark_.teardown_; } State BenchmarkInstance::Run( IterationCount iters, int thread_id, internal::ThreadTimer* timer, internal::ThreadManager* manager, - internal::PerfCountersMeasurement* perf_counters_measurement) const { + internal::PerfCountersMeasurement* perf_counters_measurement, + ProfilerManager* profiler_manager) const { State st(name_.function_name, iters, args_, thread_id, threads_, timer, - manager, perf_counters_measurement); + manager, perf_counters_measurement, profiler_manager); benchmark_.Run(st); return st; } void BenchmarkInstance::Setup() const { - if (setup_) { + if (setup_ != nullptr) { State st(name_.function_name, /*iters*/ 1, args_, /*thread_id*/ 0, threads_, - nullptr, nullptr, nullptr); + nullptr, nullptr, nullptr, nullptr); setup_(st); } } void BenchmarkInstance::Teardown() const { - if (teardown_) { + if (teardown_ != nullptr) { State st(name_.function_name, /*iters*/ 1, args_, /*thread_id*/ 0, threads_, - nullptr, nullptr, nullptr); + nullptr, nullptr, nullptr, nullptr); teardown_(st); } } diff --git a/vendor/benchmark-38df9da/src/benchmark_api_internal.h b/vendor/benchmark-4ed29ae/src/benchmark_api_internal.h similarity index 87% rename from vendor/benchmark-38df9da/src/benchmark_api_internal.h rename to vendor/benchmark-4ed29ae/src/benchmark_api_internal.h index 94f516531..5b48ea2fd 100644 --- a/vendor/benchmark-38df9da/src/benchmark_api_internal.h +++ b/vendor/benchmark-4ed29ae/src/benchmark_api_internal.h @@ -17,9 +17,9 @@ namespace internal { // Information kept per benchmark we may want to run class BenchmarkInstance { public: - BenchmarkInstance(Benchmark* benchmark, int family_index, - int per_family_instance_index, - const std::vector& args, int threads); + BenchmarkInstance(benchmark::Benchmark* benchmark, int family_idx, + int per_family_instance_idx, + const std::vector& args, int thread_count); const BenchmarkName& name() const { return name_; } int family_index() const { return family_index_; } @@ -41,14 +41,18 @@ class BenchmarkInstance { int threads() const { return threads_; } void Setup() const; void Teardown() const; + const auto& GetUserThreadRunnerFactory() const { + return benchmark_.threadrunner_; + } State Run(IterationCount iters, int thread_id, internal::ThreadTimer* timer, internal::ThreadManager* manager, - internal::PerfCountersMeasurement* perf_counters_measurement) const; + internal::PerfCountersMeasurement* perf_counters_measurement, + ProfilerManager* profiler_manager) const; private: BenchmarkName name_; - Benchmark& benchmark_; + benchmark::Benchmark& benchmark_; const int family_index_; const int per_family_instance_index_; AggregationReportMode aggregation_report_mode_; @@ -67,9 +71,8 @@ class BenchmarkInstance { IterationCount iterations_; int threads_; // Number of concurrent threads to us - typedef void (*callback_function)(const benchmark::State&); - callback_function setup_ = nullptr; - callback_function teardown_ = nullptr; + callback_function setup_; + callback_function teardown_; }; bool FindBenchmarksInternal(const std::string& re, diff --git a/vendor/benchmark-38df9da/src/benchmark_main.cc b/vendor/benchmark-4ed29ae/src/benchmark_main.cc similarity index 91% rename from vendor/benchmark-38df9da/src/benchmark_main.cc rename to vendor/benchmark-4ed29ae/src/benchmark_main.cc index cd61cd2ad..15c76eace 100644 --- a/vendor/benchmark-38df9da/src/benchmark_main.cc +++ b/vendor/benchmark-4ed29ae/src/benchmark_main.cc @@ -14,5 +14,5 @@ #include "benchmark/benchmark.h" -BENCHMARK_EXPORT int main(int, char**); +BENCHMARK_EXPORT int main(int /*argc*/, char** /*argv*/); BENCHMARK_MAIN(); diff --git a/vendor/benchmark-38df9da/src/benchmark_name.cc b/vendor/benchmark-4ed29ae/src/benchmark_name.cc similarity index 94% rename from vendor/benchmark-38df9da/src/benchmark_name.cc rename to vendor/benchmark-4ed29ae/src/benchmark_name.cc index 01676bbc8..804cfbd3b 100644 --- a/vendor/benchmark-38df9da/src/benchmark_name.cc +++ b/vendor/benchmark-4ed29ae/src/benchmark_name.cc @@ -27,8 +27,8 @@ size_t size_impl(const Head& head, const Tail&... tail) { } // Join a pack of std::strings using a delimiter -// TODO: use absl::StrJoin -void join_impl(std::string&, char) {} +// TODO(dominic): use absl::StrJoin +void join_impl(std::string& /*unused*/, char /*unused*/) {} template void join_impl(std::string& s, const char delimiter, const Head& head, diff --git a/vendor/benchmark-38df9da/src/benchmark_register.cc b/vendor/benchmark-4ed29ae/src/benchmark_register.cc similarity index 83% rename from vendor/benchmark-38df9da/src/benchmark_register.cc rename to vendor/benchmark-4ed29ae/src/benchmark_register.cc index 8ade04822..65e1afced 100644 --- a/vendor/benchmark-38df9da/src/benchmark_register.cc +++ b/vendor/benchmark-4ed29ae/src/benchmark_register.cc @@ -53,13 +53,13 @@ namespace benchmark { namespace { // For non-dense Range, intermediate values are powers of kRangeMultiplier. -static constexpr int kRangeMultiplier = 8; +constexpr int kRangeMultiplier = 8; // The size of a benchmark family determines is the number of inputs to repeat // the benchmark on. If this is "large" then warn the user during configuration. -static constexpr size_t kMaxFamilySize = 100; +constexpr size_t kMaxFamilySize = 100; -static constexpr char kDisabledPrefix[] = "DISABLED_"; +constexpr char kDisabledPrefix[] = "DISABLED_"; } // end namespace namespace internal { @@ -75,21 +75,21 @@ class BenchmarkFamilies { static BenchmarkFamilies* GetInstance(); // Registers a benchmark family and returns the index assigned to it. - size_t AddBenchmark(std::unique_ptr family); + size_t AddBenchmark(std::unique_ptr family); // Clear all registered benchmark families. void ClearBenchmarks(); // Extract the list of benchmark instances that match the specified // regular expression. - bool FindBenchmarks(std::string re, + bool FindBenchmarks(std::string spec, std::vector* benchmarks, std::ostream* Err); private: BenchmarkFamilies() {} - std::vector> families_; + std::vector> families_; Mutex mutex_; }; @@ -98,7 +98,8 @@ BenchmarkFamilies* BenchmarkFamilies::GetInstance() { return &instance; } -size_t BenchmarkFamilies::AddBenchmark(std::unique_ptr family) { +size_t BenchmarkFamilies::AddBenchmark( + std::unique_ptr family) { MutexLock l(mutex_); size_t index = families_.size(); families_.push_back(std::move(family)); @@ -125,7 +126,7 @@ bool BenchmarkFamilies::FindBenchmarks( is_negative_filter = true; } if (!re.Init(spec, &error_msg)) { - Err << "Could not compile benchmark re: " << error_msg << std::endl; + Err << "Could not compile benchmark re: " << error_msg << '\n'; return false; } @@ -135,12 +136,14 @@ bool BenchmarkFamilies::FindBenchmarks( int next_family_index = 0; MutexLock l(mutex_); - for (std::unique_ptr& family : families_) { + for (std::unique_ptr& family : families_) { int family_index = next_family_index; int per_family_instance_index = 0; // Family was deleted or benchmark doesn't match - if (!family) continue; + if (!family) { + continue; + } if (family->ArgsCnt() == -1) { family->Args({}); @@ -159,7 +162,9 @@ bool BenchmarkFamilies::FindBenchmarks( // reserve in the special case the regex ".", since we know the final // family size. this doesn't take into account any disabled benchmarks // so worst case we reserve more than we need. - if (spec == ".") benchmarks->reserve(benchmarks->size() + family_size); + if (spec == ".") { + benchmarks->reserve(benchmarks->size() + family_size); + } for (auto const& args : family->args_) { for (int num_threads : *thread_counts) { @@ -175,9 +180,11 @@ bool BenchmarkFamilies::FindBenchmarks( ++per_family_instance_index; - // Only bump the next family index once we've estabilished that + // Only bump the next family index once we've established that // at least one instance of this family will be run. - if (next_family_index == family_index) ++next_family_index; + if (next_family_index == family_index) { + ++next_family_index; + } } } } @@ -185,11 +192,12 @@ bool BenchmarkFamilies::FindBenchmarks( return true; } -Benchmark* RegisterBenchmarkInternal(Benchmark* bench) { - std::unique_ptr bench_ptr(bench); +benchmark::Benchmark* RegisterBenchmarkInternal( + std::unique_ptr bench) { + benchmark::Benchmark* bench_ptr = bench.get(); BenchmarkFamilies* families = BenchmarkFamilies::GetInstance(); - families->AddBenchmark(std::move(bench_ptr)); - return bench; + families->AddBenchmark(std::move(bench)); + return bench_ptr; } // FIXME: This function is a hack so that benchmark.cc can access @@ -200,13 +208,15 @@ bool FindBenchmarksInternal(const std::string& re, return BenchmarkFamilies::GetInstance()->FindBenchmarks(re, benchmarks, Err); } +} // end namespace internal + //=============================================================================// // Benchmark //=============================================================================// Benchmark::Benchmark(const std::string& name) : name_(name), - aggregation_report_mode_(ARM_Unspecified), + aggregation_report_mode_(internal::ARM_Unspecified), time_unit_(GetDefaultTimeUnit()), use_default_time_unit_(true), range_multiplier_(kRangeMultiplier), @@ -218,9 +228,7 @@ Benchmark::Benchmark(const std::string& name) use_real_time_(false), use_manual_time_(false), complexity_(oNone), - complexity_lambda_(nullptr), - setup_(nullptr), - teardown_(nullptr) { + complexity_lambda_(nullptr) { ComputeStatistics("mean", StatisticsMean); ComputeStatistics("median", StatisticsMedian); ComputeStatistics("stddev", StatisticsStdDev); @@ -249,7 +257,7 @@ Benchmark* Benchmark::Unit(TimeUnit unit) { Benchmark* Benchmark::Range(int64_t start, int64_t limit) { BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1); std::vector arglist; - AddRange(&arglist, start, limit, range_multiplier_); + internal::AddRange(&arglist, start, limit, range_multiplier_); for (int64_t i : arglist) { args_.push_back({i}); @@ -262,8 +270,8 @@ Benchmark* Benchmark::Ranges( BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast(ranges.size())); std::vector> arglists(ranges.size()); for (std::size_t i = 0; i < ranges.size(); i++) { - AddRange(&arglists[i], ranges[i].first, ranges[i].second, - range_multiplier_); + internal::AddRange(&arglists[i], ranges[i].first, ranges[i].second, + range_multiplier_); } ArgsProduct(arglists); @@ -326,18 +334,31 @@ Benchmark* Benchmark::Args(const std::vector& args) { return this; } -Benchmark* Benchmark::Apply(void (*custom_arguments)(Benchmark* benchmark)) { +Benchmark* Benchmark::Apply( + const std::function& custom_arguments) { custom_arguments(this); return this; } -Benchmark* Benchmark::Setup(void (*setup)(const benchmark::State&)) { +Benchmark* Benchmark::Setup(callback_function&& setup) { + BM_CHECK(setup != nullptr); + setup_ = std::forward(setup); + return this; +} + +Benchmark* Benchmark::Setup(const callback_function& setup) { BM_CHECK(setup != nullptr); setup_ = setup; return this; } -Benchmark* Benchmark::Teardown(void (*teardown)(const benchmark::State&)) { +Benchmark* Benchmark::Teardown(callback_function&& teardown) { + BM_CHECK(teardown != nullptr); + teardown_ = std::forward(teardown); + return this; +} + +Benchmark* Benchmark::Teardown(const callback_function& teardown) { BM_CHECK(teardown != nullptr); teardown_ = teardown; return this; @@ -365,8 +386,8 @@ Benchmark* Benchmark::MinWarmUpTime(double t) { Benchmark* Benchmark::Iterations(IterationCount n) { BM_CHECK(n > 0); - BM_CHECK(IsZero(min_time_)); - BM_CHECK(IsZero(min_warmup_time_)); + BM_CHECK(internal::IsZero(min_time_)); + BM_CHECK(internal::IsZero(min_warmup_time_)); iterations_ = n; return this; } @@ -378,21 +399,23 @@ Benchmark* Benchmark::Repetitions(int n) { } Benchmark* Benchmark::ReportAggregatesOnly(bool value) { - aggregation_report_mode_ = value ? ARM_ReportAggregatesOnly : ARM_Default; + aggregation_report_mode_ = + value ? internal::ARM_ReportAggregatesOnly : internal::ARM_Default; return this; } Benchmark* Benchmark::DisplayAggregatesOnly(bool value) { // If we were called, the report mode is no longer 'unspecified', in any case. + using internal::AggregationReportMode; aggregation_report_mode_ = static_cast( - aggregation_report_mode_ | ARM_Default); + aggregation_report_mode_ | internal::ARM_Default); if (value) { aggregation_report_mode_ = static_cast( - aggregation_report_mode_ | ARM_DisplayReportAggregatesOnly); + aggregation_report_mode_ | internal::ARM_DisplayReportAggregatesOnly); } else { aggregation_report_mode_ = static_cast( - aggregation_report_mode_ & ~ARM_DisplayReportAggregatesOnly); + aggregation_report_mode_ & ~internal::ARM_DisplayReportAggregatesOnly); } return this; @@ -446,7 +469,7 @@ Benchmark* Benchmark::ThreadRange(int min_threads, int max_threads) { BM_CHECK_GT(min_threads, 0); BM_CHECK_GE(max_threads, min_threads); - AddRange(&thread_counts_, min_threads, max_threads, 2); + internal::AddRange(&thread_counts_, min_threads, max_threads, 2); return this; } @@ -468,13 +491,20 @@ Benchmark* Benchmark::ThreadPerCpu() { return this; } +Benchmark* Benchmark::ThreadRunner(threadrunner_factory&& factory) { + threadrunner_ = std::move(factory); + return this; +} + void Benchmark::SetName(const std::string& name) { name_ = name; } const char* Benchmark::GetName() const { return name_.c_str(); } int Benchmark::ArgsCnt() const { if (args_.empty()) { - if (arg_names_.empty()) return -1; + if (arg_names_.empty()) { + return -1; + } return static_cast(arg_names_.size()); } return static_cast(args_.front().size()); @@ -491,6 +521,8 @@ TimeUnit Benchmark::GetTimeUnit() const { return use_default_time_unit_ ? GetDefaultTimeUnit() : time_unit_; } +namespace internal { + //=============================================================================// // FunctionBenchmark //=============================================================================// diff --git a/vendor/benchmark-38df9da/src/benchmark_register.h b/vendor/benchmark-4ed29ae/src/benchmark_register.h similarity index 99% rename from vendor/benchmark-38df9da/src/benchmark_register.h rename to vendor/benchmark-4ed29ae/src/benchmark_register.h index be50265f7..e0ace51ef 100644 --- a/vendor/benchmark-38df9da/src/benchmark_register.h +++ b/vendor/benchmark-4ed29ae/src/benchmark_register.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "check.h" diff --git a/vendor/benchmark-38df9da/src/benchmark_runner.cc b/vendor/benchmark-4ed29ae/src/benchmark_runner.cc similarity index 71% rename from vendor/benchmark-38df9da/src/benchmark_runner.cc rename to vendor/benchmark-4ed29ae/src/benchmark_runner.cc index a74bdadd3..fb688672a 100644 --- a/vendor/benchmark-38df9da/src/benchmark_runner.cc +++ b/vendor/benchmark-4ed29ae/src/benchmark_runner.cc @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -46,7 +47,6 @@ #include "commandlineflags.h" #include "complexity.h" #include "counter.h" -#include "internal_macros.h" #include "log.h" #include "mutex.h" #include "perf_counters.h" @@ -58,13 +58,23 @@ namespace benchmark { +BM_DECLARE_bool(benchmark_dry_run); +BM_DECLARE_string(benchmark_min_time); +BM_DECLARE_double(benchmark_min_warmup_time); +BM_DECLARE_int32(benchmark_repetitions); +BM_DECLARE_bool(benchmark_report_aggregates_only); +BM_DECLARE_bool(benchmark_display_aggregates_only); +BM_DECLARE_string(benchmark_perf_counters); + namespace internal { MemoryManager* memory_manager = nullptr; +ProfilerManager* profiler_manager = nullptr; + namespace { -static constexpr IterationCount kMaxIterations = 1000000000000; +constexpr IterationCount kMaxIterations = 1000000000000; const double kDefaultMinTime = std::strtod(::benchmark::kDefaultMinTimeStr, /*p_end*/ nullptr); @@ -72,7 +82,7 @@ BenchmarkReporter::Run CreateRunReport( const benchmark::internal::BenchmarkInstance& b, const internal::ThreadManager::Result& results, IterationCount memory_iterations, - const MemoryManager::Result* memory_result, double seconds, + const MemoryManager::Result& memory_result, double seconds, int64_t repetition_index, int64_t repeats) { // Create report about this benchmark run. BenchmarkReporter::Run report; @@ -90,7 +100,7 @@ BenchmarkReporter::Run CreateRunReport( report.repetition_index = repetition_index; report.repetitions = repeats; - if (!report.skipped) { + if (report.skipped == 0u) { if (b.use_manual_time()) { report.real_accumulated_time = results.manual_time_used; } else { @@ -105,15 +115,20 @@ BenchmarkReporter::Run CreateRunReport( report.counters = results.counters; if (memory_iterations > 0) { - assert(memory_result != nullptr); report.memory_result = memory_result; report.allocs_per_iter = - memory_iterations ? static_cast(memory_result->num_allocs) / - static_cast(memory_iterations) - : 0; + memory_iterations != 0 + ? static_cast(memory_result.num_allocs) / + static_cast(memory_iterations) + : 0; } - internal::Finish(&report.counters, results.iterations, seconds, + // The CPU time is the total time taken by all thread. If we used that as + // the denominator, we'd be calculating the rate per thread here. This is + // why we have to divide the total cpu_time by the number of threads for + // global counters to get a global rate. + const double thread_seconds = seconds / b.threads(); + internal::Finish(&report.counters, results.iterations, thread_seconds, b.threads()); } return report; @@ -123,16 +138,20 @@ BenchmarkReporter::Run CreateRunReport( // Adds the stats collected for the thread into manager->results. void RunInThread(const BenchmarkInstance* b, IterationCount iters, int thread_id, ThreadManager* manager, - PerfCountersMeasurement* perf_counters_measurement) { + PerfCountersMeasurement* perf_counters_measurement, + ProfilerManager* profiler_manager_) { internal::ThreadTimer timer( b->measure_process_cpu_time() ? internal::ThreadTimer::CreateProcessCpuTime() : internal::ThreadTimer::Create()); - State st = - b->Run(iters, thread_id, &timer, manager, perf_counters_measurement); - BM_CHECK(st.skipped() || st.iterations() >= st.max_iterations) - << "Benchmark returned before State::KeepRunning() returned false!"; + State st = b->Run(iters, thread_id, &timer, manager, + perf_counters_measurement, profiler_manager_); + if (!(st.skipped() || st.iterations() >= st.max_iterations)) { + st.SkipWithError( + "The benchmark didn't run, nor was it explicitly skipped. Please call " + "'SkipWithXXX` in your benchmark as appropriate."); + } { MutexLock l(manager->GetBenchmarkMutex()); internal::ThreadManager::Result& results = manager->results; @@ -148,17 +167,23 @@ void RunInThread(const BenchmarkInstance* b, IterationCount iters, double ComputeMinTime(const benchmark::internal::BenchmarkInstance& b, const BenchTimeType& iters_or_time) { - if (!IsZero(b.min_time())) return b.min_time(); + if (!IsZero(b.min_time())) { + return b.min_time(); + } // If the flag was used to specify number of iters, then return the default // min_time. - if (iters_or_time.tag == BenchTimeType::ITERS) return kDefaultMinTime; + if (iters_or_time.tag == BenchTimeType::ITERS) { + return kDefaultMinTime; + } return iters_or_time.time; } IterationCount ComputeIters(const benchmark::internal::BenchmarkInstance& b, const BenchTimeType& iters_or_time) { - if (b.iterations() != 0) return b.iterations(); + if (b.iterations() != 0) { + return b.iterations(); + } // We've already concluded that this flag is currently used to pass // iters but do a check here again anyway. @@ -166,10 +191,43 @@ IterationCount ComputeIters(const benchmark::internal::BenchmarkInstance& b, return iters_or_time.iters; } +class ThreadRunnerDefault : public ThreadRunnerBase { + public: + explicit ThreadRunnerDefault(int num_threads) + : pool(static_cast(num_threads - 1)) {} + + void RunThreads(const std::function& fn) override final { + // Run all but one thread in separate threads + for (std::size_t ti = 0; ti < pool.size(); ++ti) { + pool[ti] = std::thread(fn, static_cast(ti + 1)); + } + // And run one thread here directly. + // (If we were asked to run just one thread, we don't create new threads.) + // Yes, we need to do this here *after* we start the separate threads. + fn(0); + + // The main thread has finished. Now let's wait for the other threads. + for (std::thread& thread : pool) { + thread.join(); + } + } + + private: + std::vector pool; +}; + +std::unique_ptr GetThreadRunner( + const benchmark::threadrunner_factory& userThreadRunnerFactory, + int num_threads) { + return userThreadRunnerFactory + ? userThreadRunnerFactory(num_threads) + : std::make_unique(num_threads); +} + } // end namespace BenchTimeType ParseBenchMinTime(const std::string& value) { - BenchTimeType ret; + BenchTimeType ret = {}; if (value.empty()) { ret.tag = BenchTimeType::TIME; @@ -178,7 +236,7 @@ BenchTimeType ParseBenchMinTime(const std::string& value) { } if (value.back() == 'x') { - char* p_end; + char* p_end = nullptr; // Reset errno before it's changed by strtol. errno = 0; IterationCount num_iters = std::strtol(value.c_str(), &p_end, 10); @@ -200,7 +258,7 @@ BenchTimeType ParseBenchMinTime(const std::string& value) { "Eg., `30s` for 30-seconds."; } - char* p_end; + char* p_end = nullptr; // Reset errno before it's changed by strtod. errno = 0; double min_time = std::strtod(value.c_str(), &p_end); @@ -225,20 +283,30 @@ BenchmarkRunner::BenchmarkRunner( : b(b_), reports_for_family(reports_for_family_), parsed_benchtime_flag(ParseBenchMinTime(FLAGS_benchmark_min_time)), - min_time(ComputeMinTime(b_, parsed_benchtime_flag)), - min_warmup_time((!IsZero(b.min_time()) && b.min_warmup_time() > 0.0) - ? b.min_warmup_time() - : FLAGS_benchmark_min_warmup_time), - warmup_done(!(min_warmup_time > 0.0)), - repeats(b.repetitions() != 0 ? b.repetitions() - : FLAGS_benchmark_repetitions), + min_time(FLAGS_benchmark_dry_run + ? 0 + : ComputeMinTime(b_, parsed_benchtime_flag)), + min_warmup_time( + FLAGS_benchmark_dry_run + ? 0 + : ((!IsZero(b.min_time()) && b.min_warmup_time() > 0.0) + ? b.min_warmup_time() + : FLAGS_benchmark_min_warmup_time)), + warmup_done(FLAGS_benchmark_dry_run ? true : !(min_warmup_time > 0.0)), + repeats(FLAGS_benchmark_dry_run + ? 1 + : (b.repetitions() != 0 ? b.repetitions() + : FLAGS_benchmark_repetitions)), has_explicit_iteration_count(b.iterations() != 0 || parsed_benchtime_flag.tag == BenchTimeType::ITERS), - pool(static_cast(b.threads() - 1)), - iters(has_explicit_iteration_count - ? ComputeIters(b_, parsed_benchtime_flag) - : 1), + thread_runner( + GetThreadRunner(b.GetUserThreadRunnerFactory(), b.threads())), + iters(FLAGS_benchmark_dry_run + ? 1 + : (has_explicit_iteration_count + ? ComputeIters(b_, parsed_benchtime_flag) + : 1)), perf_counters_measurement_ptr(pcm_) { run_results.display_report_aggregates_only = (FLAGS_benchmark_report_aggregates_only || @@ -247,10 +315,11 @@ BenchmarkRunner::BenchmarkRunner( FLAGS_benchmark_report_aggregates_only; if (b.aggregation_report_mode() != internal::ARM_Unspecified) { run_results.display_report_aggregates_only = - (b.aggregation_report_mode() & - internal::ARM_DisplayReportAggregatesOnly); + ((b.aggregation_report_mode() & + internal::ARM_DisplayReportAggregatesOnly) != 0u); run_results.file_report_aggregates_only = - (b.aggregation_report_mode() & internal::ARM_FileReportAggregatesOnly); + ((b.aggregation_report_mode() & + internal::ARM_FileReportAggregatesOnly) != 0u); BM_CHECK(FLAGS_benchmark_perf_counters.empty() || (perf_counters_measurement_ptr->num_counters() == 0)) << "Perf counters were requested but could not be set up."; @@ -263,19 +332,10 @@ BenchmarkRunner::IterationResults BenchmarkRunner::DoNIterations() { std::unique_ptr manager; manager.reset(new internal::ThreadManager(b.threads())); - // Run all but one thread in separate threads - for (std::size_t ti = 0; ti < pool.size(); ++ti) { - pool[ti] = std::thread(&RunInThread, &b, iters, static_cast(ti + 1), - manager.get(), perf_counters_measurement_ptr); - } - // And run one thread here directly. - // (If we were asked to run just one thread, we don't create new threads.) - // Yes, we need to do this here *after* we start the separate threads. - RunInThread(&b, iters, 0, manager.get(), perf_counters_measurement_ptr); - - // The main thread has finished. Now let's wait for the other threads. - manager->WaitForAllThreads(); - for (std::thread& thread : pool) thread.join(); + thread_runner->RunThreads([&](int thread_idx) { + RunInThread(&b, iters, thread_idx, manager.get(), + perf_counters_measurement_ptr, /*profiler_manager=*/nullptr); + }); IterationResults i; // Acquire the measurements/counters from the manager, UNDER THE LOCK! @@ -287,12 +347,6 @@ BenchmarkRunner::IterationResults BenchmarkRunner::DoNIterations() { // And get rid of the manager. manager.reset(); - // Adjust real/manual time stats since they were reported per thread. - i.results.real_time_used /= b.threads(); - i.results.manual_time_used /= b.threads(); - // If we were measuring whole-process CPU usage, adjust the CPU time too. - if (b.measure_process_cpu_time()) i.results.cpu_time_used /= b.threads(); - BM_VLOG(2) << "Ran in " << i.results.cpu_time_used << "/" << i.results.real_time_used << "\n"; @@ -340,7 +394,7 @@ bool BenchmarkRunner::ShouldReportIterationResults( // Determine if this run should be reported; // Either it has run for a sufficient amount of time // or because an error was reported. - return i.results.skipped_ || + return (i.results.skipped_ != 0u) || FLAGS_benchmark_dry_run || i.iters >= kMaxIterations || // Too many iterations already. i.seconds >= GetMinTimeToApply() || // The elapsed time is large enough. @@ -352,7 +406,7 @@ bool BenchmarkRunner::ShouldReportIterationResults( } double BenchmarkRunner::GetMinTimeToApply() const { - // In order to re-use functionality to run and measure benchmarks for running + // In order to reuse functionality to run and measure benchmarks for running // a warmup phase of the benchmark, we need a way of telling whether to apply // min_time or min_warmup_time. This function will figure out if we are in the // warmup phase and therefore need to apply min_warmup_time or if we already @@ -401,6 +455,34 @@ void BenchmarkRunner::RunWarmUp() { } } +MemoryManager::Result BenchmarkRunner::RunMemoryManager( + IterationCount memory_iterations) { + memory_manager->Start(); + std::unique_ptr manager; + manager.reset(new internal::ThreadManager(1)); + b.Setup(); + RunInThread(&b, memory_iterations, 0, manager.get(), + perf_counters_measurement_ptr, + /*profiler_manager=*/nullptr); + manager.reset(); + b.Teardown(); + MemoryManager::Result memory_result; + memory_manager->Stop(memory_result); + memory_result.memory_iterations = memory_iterations; + return memory_result; +} + +void BenchmarkRunner::RunProfilerManager(IterationCount profile_iterations) { + std::unique_ptr manager; + manager.reset(new internal::ThreadManager(1)); + b.Setup(); + RunInThread(&b, profile_iterations, 0, manager.get(), + /*perf_counters_measurement_ptr=*/nullptr, + /*profiler_manager=*/profiler_manager); + manager.reset(); + b.Teardown(); +} + void BenchmarkRunner::DoOneRepetition() { assert(HasRepeatsRemaining() && "Already done all repetitions?"); @@ -411,7 +493,9 @@ void BenchmarkRunner::DoOneRepetition() { // this warmup never happened except the fact that warmup_done is set. Every // other manipulation of the BenchmarkRunner instance would be a bug! Please // fix it. - if (!warmup_done) RunWarmUp(); + if (!warmup_done) { + RunWarmUp(); + } IterationResults i; // We *may* be gradually increasing the length (iteration count) @@ -433,8 +517,10 @@ void BenchmarkRunner::DoOneRepetition() { const bool results_are_significant = !is_the_first_repetition || has_explicit_iteration_count || ShouldReportIterationResults(i); - - if (results_are_significant) break; // Good, let's report them! + // Good, let's report them! + if (results_are_significant) { + break; + } // Nope, bad iteration. Let's re-estimate the hopefully-sufficient // iteration count, and run the benchmark again... @@ -445,28 +531,21 @@ void BenchmarkRunner::DoOneRepetition() { "then we should have accepted the current iteration run."); } - // Oh, one last thing, we need to also produce the 'memory measurements'.. - MemoryManager::Result* memory_result = nullptr; + // Produce memory measurements if requested. + MemoryManager::Result memory_result; IterationCount memory_iterations = 0; if (memory_manager != nullptr) { - // TODO(vyng): Consider making BenchmarkReporter::Run::memory_result an - // optional so we don't have to own the Result here. - // Can't do it now due to cxx03. - memory_results.push_back(MemoryManager::Result()); - memory_result = &memory_results.back(); // Only run a few iterations to reduce the impact of one-time // allocations in benchmarks that are not properly managed. memory_iterations = std::min(16, iters); - memory_manager->Start(); - std::unique_ptr manager; - manager.reset(new internal::ThreadManager(1)); - b.Setup(); - RunInThread(&b, memory_iterations, 0, manager.get(), - perf_counters_measurement_ptr); - manager->WaitForAllThreads(); - manager.reset(); - b.Teardown(); - memory_manager->Stop(*memory_result); + memory_result = RunMemoryManager(memory_iterations); + } + + if (profiler_manager != nullptr) { + // We want to externally profile the benchmark for the same number of + // iterations because, for example, if we're tracing the benchmark then we + // want trace data to reasonably match PMU data. + RunProfilerManager(iters); } // Ok, now actually report. @@ -474,9 +553,11 @@ void BenchmarkRunner::DoOneRepetition() { CreateRunReport(b, i.results, memory_iterations, memory_result, i.seconds, num_repetitions_done, repeats); - if (reports_for_family) { + if (reports_for_family != nullptr) { ++reports_for_family->num_runs_done; - if (!report.skipped) reports_for_family->Runs.push_back(report); + if (report.skipped == 0u) { + reports_for_family->Runs.push_back(report); + } } run_results.non_aggregates.push_back(report); diff --git a/vendor/benchmark-38df9da/src/benchmark_runner.h b/vendor/benchmark-4ed29ae/src/benchmark_runner.h similarity index 88% rename from vendor/benchmark-38df9da/src/benchmark_runner.h rename to vendor/benchmark-4ed29ae/src/benchmark_runner.h index db2fa0439..9a2231a2a 100644 --- a/vendor/benchmark-38df9da/src/benchmark_runner.h +++ b/vendor/benchmark-4ed29ae/src/benchmark_runner.h @@ -15,26 +15,20 @@ #ifndef BENCHMARK_RUNNER_H_ #define BENCHMARK_RUNNER_H_ +#include #include #include #include "benchmark_api_internal.h" -#include "internal_macros.h" #include "perf_counters.h" #include "thread_manager.h" namespace benchmark { -BM_DECLARE_string(benchmark_min_time); -BM_DECLARE_double(benchmark_min_warmup_time); -BM_DECLARE_int32(benchmark_repetitions); -BM_DECLARE_bool(benchmark_report_aggregates_only); -BM_DECLARE_bool(benchmark_display_aggregates_only); -BM_DECLARE_string(benchmark_perf_counters); - namespace internal { extern MemoryManager* memory_manager; +extern ProfilerManager* profiler_manager; struct RunResults { std::vector non_aggregates; @@ -45,7 +39,7 @@ struct RunResults { }; struct BENCHMARK_EXPORT BenchTimeType { - enum { ITERS, TIME } tag; + enum { UNSPECIFIED, ITERS, TIME } tag; union { IterationCount iters; double time; @@ -58,7 +52,7 @@ BenchTimeType ParseBenchMinTime(const std::string& value); class BenchmarkRunner { public: BenchmarkRunner(const benchmark::internal::BenchmarkInstance& b_, - benchmark::internal::PerfCountersMeasurement* pmc_, + benchmark::internal::PerfCountersMeasurement* pcm_, BenchmarkReporter::PerFamilyRunReports* reports_for_family); int GetNumRepeats() const { return repeats; } @@ -96,9 +90,7 @@ class BenchmarkRunner { int num_repetitions_done = 0; - std::vector pool; - - std::vector memory_results; + std::unique_ptr thread_runner; IterationCount iters; // preserved between repetitions! // So only the first repetition has to find/calculate it, @@ -113,6 +105,10 @@ class BenchmarkRunner { }; IterationResults DoNIterations(); + MemoryManager::Result RunMemoryManager(IterationCount memory_iterations); + + void RunProfilerManager(IterationCount profile_iterations); + IterationCount PredictNumItersNeeded(const IterationResults& i) const; bool ShouldReportIterationResults(const IterationResults& i) const; diff --git a/vendor/benchmark-38df9da/src/check.cc b/vendor/benchmark-4ed29ae/src/check.cc similarity index 58% rename from vendor/benchmark-38df9da/src/check.cc rename to vendor/benchmark-4ed29ae/src/check.cc index 5f7526e08..3e2a40b4b 100644 --- a/vendor/benchmark-38df9da/src/check.cc +++ b/vendor/benchmark-4ed29ae/src/check.cc @@ -3,7 +3,10 @@ namespace benchmark { namespace internal { -static AbortHandlerT* handler = &std::abort; +namespace { +// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) +AbortHandlerT* handler = &std::abort; +} // namespace BENCHMARK_EXPORT AbortHandlerT*& GetAbortHandler() { return handler; } diff --git a/vendor/benchmark-38df9da/src/check.h b/vendor/benchmark-4ed29ae/src/check.h similarity index 84% rename from vendor/benchmark-38df9da/src/check.h rename to vendor/benchmark-4ed29ae/src/check.h index c1cd5e85e..aa8c78c92 100644 --- a/vendor/benchmark-38df9da/src/check.h +++ b/vendor/benchmark-4ed29ae/src/check.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "benchmark/export.h" #include "internal_macros.h" @@ -36,6 +37,8 @@ AbortHandlerT*& GetAbortHandler(); BENCHMARK_NORETURN inline void CallAbortHandler() { GetAbortHandler()(); + std::flush(std::cout); + std::flush(std::cerr); std::abort(); // fallback to enforce noreturn } @@ -44,7 +47,8 @@ BENCHMARK_NORETURN inline void CallAbortHandler() { // destructed. class CheckHandler { public: - CheckHandler(const char* check, const char* file, const char* func, int line) + CheckHandler(std::string_view check, std::string_view file, + std::string_view func, int line) : log_(GetErrorLogInstance()) { log_ << file << ":" << line << ": " << func << ": Check `" << check << "' failed. "; @@ -57,7 +61,7 @@ class CheckHandler { #pragma warning(disable : 4722) #endif BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) { - log_ << std::endl; + log_ << '\n'; CallAbortHandler(); } #if defined(COMPILER_MSVC) @@ -78,9 +82,11 @@ class CheckHandler { // The BM_CHECK macro returns a std::ostream object that can have extra // information written to it. #ifndef NDEBUG -#define BM_CHECK(b) \ - (b ? ::benchmark::internal::GetNullLogInstance() \ - : ::benchmark::internal::CheckHandler(#b, __FILE__, __func__, __LINE__) \ +#define BM_CHECK(b) \ + (b ? ::benchmark::internal::GetNullLogInstance() \ + : ::benchmark::internal::CheckHandler( \ + std::string_view(#b), std::string_view(__FILE__), \ + std::string_view(__func__), __LINE__) \ .GetLog()) #else #define BM_CHECK(b) ::benchmark::internal::GetNullLogInstance() diff --git a/vendor/benchmark-38df9da/src/colorprint.cc b/vendor/benchmark-4ed29ae/src/colorprint.cc similarity index 87% rename from vendor/benchmark-38df9da/src/colorprint.cc rename to vendor/benchmark-4ed29ae/src/colorprint.cc index abc71492f..c90232f20 100644 --- a/vendor/benchmark-38df9da/src/colorprint.cc +++ b/vendor/benchmark-4ed29ae/src/colorprint.cc @@ -135,22 +135,30 @@ void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, // Gets the current text color. CONSOLE_SCREEN_BUFFER_INFO buffer_info; GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); - const WORD old_color_attrs = buffer_info.wAttributes; + const WORD original_color_attrs = buffer_info.wAttributes; // We need to flush the stream buffers into the console before each // SetConsoleTextAttribute call lest it affect the text that is already // printed but has not yet reached the console. out.flush(); - SetConsoleTextAttribute(stdout_handle, - GetPlatformColorCode(color) | FOREGROUND_INTENSITY); + + const WORD original_background_attrs = + original_color_attrs & (BACKGROUND_RED | BACKGROUND_GREEN | + BACKGROUND_BLUE | BACKGROUND_INTENSITY); + + SetConsoleTextAttribute(stdout_handle, GetPlatformColorCode(color) | + FOREGROUND_INTENSITY | + original_background_attrs); out << FormatString(fmt, args); out.flush(); - // Restores the text color. - SetConsoleTextAttribute(stdout_handle, old_color_attrs); + // Restores the text and background color. + SetConsoleTextAttribute(stdout_handle, original_color_attrs); #else const char* color_code = GetPlatformColorCode(color); - if (color_code) out << FormatString("\033[0;3%sm", color_code); + if (color_code != nullptr) { + out << FormatString("\033[0;3%sm", color_code); + } out << FormatString(fmt, args) << "\033[m"; #endif } @@ -187,7 +195,7 @@ bool IsColorTerminal() { bool term_supports_color = false; for (const char* candidate : SUPPORTED_TERM_VALUES) { - if (term && 0 == strcmp(term, candidate)) { + if ((term != nullptr) && 0 == strcmp(term, candidate)) { term_supports_color = true; break; } diff --git a/vendor/benchmark-38df9da/src/colorprint.h b/vendor/benchmark-4ed29ae/src/colorprint.h similarity index 77% rename from vendor/benchmark-38df9da/src/colorprint.h rename to vendor/benchmark-4ed29ae/src/colorprint.h index 9f6fab9b3..469045c5f 100644 --- a/vendor/benchmark-38df9da/src/colorprint.h +++ b/vendor/benchmark-4ed29ae/src/colorprint.h @@ -5,6 +5,8 @@ #include #include +#include "internal_macros.h" + namespace benchmark { enum LogColor { COLOR_DEFAULT, @@ -17,11 +19,14 @@ enum LogColor { COLOR_WHITE }; +PRINTF_FORMAT_STRING_FUNC(1, 0) std::string FormatString(const char* msg, va_list args); -std::string FormatString(const char* msg, ...); +PRINTF_FORMAT_STRING_FUNC(1, 2) std::string FormatString(const char* msg, ...); +PRINTF_FORMAT_STRING_FUNC(3, 0) void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, va_list args); +PRINTF_FORMAT_STRING_FUNC(3, 4) void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...); // Returns true if stdout appears to be a terminal that supports colored diff --git a/vendor/benchmark-38df9da/src/commandlineflags.cc b/vendor/benchmark-4ed29ae/src/commandlineflags.cc similarity index 92% rename from vendor/benchmark-38df9da/src/commandlineflags.cc rename to vendor/benchmark-4ed29ae/src/commandlineflags.cc index dcb414959..99a240c12 100644 --- a/vendor/benchmark-38df9da/src/commandlineflags.cc +++ b/vendor/benchmark-4ed29ae/src/commandlineflags.cc @@ -109,12 +109,13 @@ bool ParseKvPairs(const std::string& src_text, const char* str, // Returns the name of the environment variable corresponding to the // given flag. For example, FlagToEnvVar("foo") will return // "BENCHMARK_FOO" in the open-source version. -static std::string FlagToEnvVar(const char* flag) { +std::string FlagToEnvVar(const char* flag) { const std::string flag_str(flag); std::string env_var; - for (size_t i = 0; i != flag_str.length(); ++i) + for (size_t i = 0; i != flag_str.length(); ++i) { env_var += static_cast(::toupper(flag_str.c_str()[i])); + } return env_var; } @@ -167,7 +168,9 @@ std::map KvPairsFromEnv( const std::string env_var = FlagToEnvVar(flag); const char* const value_str = getenv(env_var.c_str()); - if (value_str == nullptr) return default_val; + if (value_str == nullptr) { + return default_val; + } std::map value; if (!ParseKvPairs("Environment variable " + env_var, value_str, &value)) { @@ -176,6 +179,8 @@ std::map KvPairsFromEnv( return value; } +namespace { + // Parses a string as a command line flag. The string should have // the format "--flag=value". When def_optional is true, the "=value" // part can be omitted. @@ -184,35 +189,47 @@ std::map KvPairsFromEnv( const char* ParseFlagValue(const char* str, const char* flag, bool def_optional) { // str and flag must not be nullptr. - if (str == nullptr || flag == nullptr) return nullptr; + if (str == nullptr || flag == nullptr) { + return nullptr; + } // The flag must start with "--". const std::string flag_str = std::string("--") + std::string(flag); const size_t flag_len = flag_str.length(); - if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr; + if (strncmp(str, flag_str.c_str(), flag_len) != 0) { + return nullptr; + } // Skips the flag name. const char* flag_end = str + flag_len; // When def_optional is true, it's OK to not have a "=value" part. - if (def_optional && (flag_end[0] == '\0')) return flag_end; + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } // If def_optional is true and there are more characters after the // flag name, or if def_optional is false, there must be a '=' after // the flag name. - if (flag_end[0] != '=') return nullptr; + if (flag_end[0] != '=') { + return nullptr; + } // Returns the string after "=". return flag_end + 1; } +} // end namespace + BENCHMARK_EXPORT bool ParseBoolFlag(const char* str, const char* flag, bool* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, true); // Aborts if the parsing failed. - if (value_str == nullptr) return false; + if (value_str == nullptr) { + return false; + } // Converts the string value to a bool. *value = IsTruthyFlagValue(value_str); @@ -225,7 +242,9 @@ bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) { const char* const value_str = ParseFlagValue(str, flag, false); // Aborts if the parsing failed. - if (value_str == nullptr) return false; + if (value_str == nullptr) { + return false; + } // Sets *value to the value of the flag. return ParseInt32(std::string("The value of flag --") + flag, value_str, @@ -238,7 +257,9 @@ bool ParseDoubleFlag(const char* str, const char* flag, double* value) { const char* const value_str = ParseFlagValue(str, flag, false); // Aborts if the parsing failed. - if (value_str == nullptr) return false; + if (value_str == nullptr) { + return false; + } // Sets *value to the value of the flag. return ParseDouble(std::string("The value of flag --") + flag, value_str, @@ -251,7 +272,9 @@ bool ParseStringFlag(const char* str, const char* flag, std::string* value) { const char* const value_str = ParseFlagValue(str, flag, false); // Aborts if the parsing failed. - if (value_str == nullptr) return false; + if (value_str == nullptr) { + return false; + } *value = value_str; return true; @@ -262,11 +285,15 @@ bool ParseKeyValueFlag(const char* str, const char* flag, std::map* value) { const char* const value_str = ParseFlagValue(str, flag, false); - if (value_str == nullptr) return false; + if (value_str == nullptr) { + return false; + } for (const auto& kvpair : StrSplit(value_str, ',')) { const auto kv = StrSplit(kvpair, '='); - if (kv.size() != 2) return false; + if (kv.size() != 2) { + return false; + } value->emplace(kv[0], kv[1]); } diff --git a/vendor/benchmark-38df9da/src/commandlineflags.h b/vendor/benchmark-4ed29ae/src/commandlineflags.h similarity index 95% rename from vendor/benchmark-38df9da/src/commandlineflags.h rename to vendor/benchmark-4ed29ae/src/commandlineflags.h index 788262897..5f9ebf1d5 100644 --- a/vendor/benchmark-38df9da/src/commandlineflags.h +++ b/vendor/benchmark-4ed29ae/src/commandlineflags.h @@ -11,14 +11,17 @@ #define FLAG(name) FLAGS_##name // Macros for declaring flags. +// NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables) #define BM_DECLARE_bool(name) BENCHMARK_EXPORT extern bool FLAG(name) #define BM_DECLARE_int32(name) BENCHMARK_EXPORT extern int32_t FLAG(name) #define BM_DECLARE_double(name) BENCHMARK_EXPORT extern double FLAG(name) #define BM_DECLARE_string(name) BENCHMARK_EXPORT extern std::string FLAG(name) #define BM_DECLARE_kvpairs(name) \ BENCHMARK_EXPORT extern std::map FLAG(name) +// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables) // Macros for defining flags. +// NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables) #define BM_DEFINE_bool(name, default_val) \ BENCHMARK_EXPORT bool FLAG(name) = benchmark::BoolFromEnv(#name, default_val) #define BM_DEFINE_int32(name, default_val) \ @@ -33,6 +36,7 @@ #define BM_DEFINE_kvpairs(name, default_val) \ BENCHMARK_EXPORT std::map FLAG(name) = \ benchmark::KvPairsFromEnv(#name, default_val) +// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables) namespace benchmark { diff --git a/vendor/benchmark-38df9da/src/complexity.cc b/vendor/benchmark-4ed29ae/src/complexity.cc similarity index 94% rename from vendor/benchmark-38df9da/src/complexity.cc rename to vendor/benchmark-4ed29ae/src/complexity.cc index eee312264..4c9ef6d0c 100644 --- a/vendor/benchmark-38df9da/src/complexity.cc +++ b/vendor/benchmark-4ed29ae/src/complexity.cc @@ -17,7 +17,6 @@ #include "complexity.h" -#include #include #include "benchmark/benchmark.h" @@ -25,9 +24,10 @@ namespace benchmark { +namespace { + // Internal function to calculate the different scalability forms BigOFunc* FittingCurve(BigO complexity) { - static const double kLog2E = 1.44269504088896340736; switch (complexity) { case oN: return [](IterationCount n) -> double { return static_cast(n); }; @@ -36,15 +36,12 @@ BigOFunc* FittingCurve(BigO complexity) { case oNCubed: return [](IterationCount n) -> double { return std::pow(n, 3); }; case oLogN: - /* Note: can't use log2 because Android's GNU STL lacks it */ - return [](IterationCount n) { - return kLog2E * std::log(static_cast(n)); + return [](IterationCount n) -> double { + return std::log2(static_cast(n)); }; case oNLogN: - /* Note: can't use log2 because Android's GNU STL lacks it */ - return [](IterationCount n) { - return kLog2E * static_cast(n) * - std::log(static_cast(n)); + return [](IterationCount n) -> double { + return static_cast(n) * std::log2(static_cast(n)); }; case o1: default: @@ -52,6 +49,8 @@ BigOFunc* FittingCurve(BigO complexity) { } } +} // end namespace + // Function to return an string for the calculated complexity std::string GetBigOString(BigO complexity) { switch (complexity) { @@ -72,6 +71,8 @@ std::string GetBigOString(BigO complexity) { } } +namespace { + // Find the coefficient for the high-order term in the running time, by // minimizing the sum of squares of relative error, for the fitting curve // given by the lambda expression. @@ -156,12 +157,16 @@ LeastSq MinimalLeastSq(const std::vector& n, return best_fit; } +} // end namespace + std::vector ComputeBigO( const std::vector& reports) { typedef BenchmarkReporter::Run Run; std::vector results; - if (reports.size() < 2) return results; + if (reports.size() < 2) { + return results; + } // Accumulators. std::vector n; diff --git a/vendor/benchmark-38df9da/src/complexity.h b/vendor/benchmark-4ed29ae/src/complexity.h similarity index 100% rename from vendor/benchmark-38df9da/src/complexity.h rename to vendor/benchmark-4ed29ae/src/complexity.h diff --git a/vendor/benchmark-38df9da/src/console_reporter.cc b/vendor/benchmark-4ed29ae/src/console_reporter.cc similarity index 90% rename from vendor/benchmark-38df9da/src/console_reporter.cc rename to vendor/benchmark-4ed29ae/src/console_reporter.cc index 35c3de2a4..6db6788f9 100644 --- a/vendor/benchmark-38df9da/src/console_reporter.cc +++ b/vendor/benchmark-4ed29ae/src/console_reporter.cc @@ -63,7 +63,7 @@ void ConsoleReporter::PrintHeader(const Run& run) { FormatString("%-*s %13s %15s %12s", static_cast(name_field_width_), "Benchmark", "Time", "CPU", "Iterations"); if (!run.counters.empty()) { - if (output_options_ & OO_Tabular) { + if ((output_options_ & OO_Tabular) != 0) { for (auto const& c : run.counters) { str += FormatString(" %10s", c.first.c_str()); } @@ -83,7 +83,7 @@ void ConsoleReporter::ReportRuns(const std::vector& reports) { bool print_header = !printed_header_; // --- or if the format is tabular and this run // has different fields from the prev header - print_header |= (output_options_ & OO_Tabular) && + print_header |= ((output_options_ & OO_Tabular) != 0) && (!internal::SameNames(run.counters, prev_counters_)); if (print_header) { printed_header_ = true; @@ -97,8 +97,9 @@ void ConsoleReporter::ReportRuns(const std::vector& reports) { } } -static void IgnoreColorPrint(std::ostream& out, LogColor, const char* fmt, - ...) { +PRINTF_FORMAT_STRING_FUNC(3, 4) +static void IgnoreColorPrint(std::ostream& out, LogColor /*unused*/, + const char* fmt, ...) { va_list args; va_start(args, fmt); out << FormatString(fmt, args); @@ -131,7 +132,7 @@ BENCHMARK_EXPORT void ConsoleReporter::PrintRunData(const Run& result) { typedef void(PrinterFn)(std::ostream&, LogColor, const char*, ...); auto& Out = GetOutputStream(); - PrinterFn* printer = (output_options_ & OO_Color) + PrinterFn* printer = (output_options_ & OO_Color) != 0 ? static_cast(ColorPrintf) : IgnoreColorPrint; auto name_color = @@ -144,7 +145,8 @@ void ConsoleReporter::PrintRunData(const Run& result) { result.skip_message.c_str()); printer(Out, COLOR_DEFAULT, "\n"); return; - } else if (internal::SkippedWithMessage == result.skipped) { + } + if (internal::SkippedWithMessage == result.skipped) { printer(Out, COLOR_WHITE, "SKIPPED: \'%s\'", result.skip_message.c_str()); printer(Out, COLOR_DEFAULT, "\n"); return; @@ -178,9 +180,9 @@ void ConsoleReporter::PrintRunData(const Run& result) { printer(Out, COLOR_CYAN, "%10lld", result.iterations); } - for (auto& c : result.counters) { + for (const auto& c : result.counters) { const std::size_t cNameLen = - std::max(std::string::size_type(10), c.first.length()); + std::max(static_cast(10), c.first.length()); std::string s; const char* unit = ""; if (result.run_type == Run::RT_Aggregate && @@ -189,10 +191,11 @@ void ConsoleReporter::PrintRunData(const Run& result) { unit = "%"; } else { s = HumanReadableNumber(c.second.value, c.second.oneK); - if (c.second.flags & Counter::kIsRate) - unit = (c.second.flags & Counter::kInvert) ? "s" : "/s"; + if ((c.second.flags & Counter::kIsRate) != 0) { + unit = (c.second.flags & Counter::kInvert) != 0 ? "s" : "/s"; + } } - if (output_options_ & OO_Tabular) { + if ((output_options_ & OO_Tabular) != 0) { printer(Out, COLOR_DEFAULT, " %*s%s", cNameLen - strlen(unit), s.c_str(), unit); } else { diff --git a/vendor/benchmark-38df9da/src/counter.cc b/vendor/benchmark-4ed29ae/src/counter.cc similarity index 84% rename from vendor/benchmark-38df9da/src/counter.cc rename to vendor/benchmark-4ed29ae/src/counter.cc index aa14cd809..4bdd5e9b5 100644 --- a/vendor/benchmark-38df9da/src/counter.cc +++ b/vendor/benchmark-4ed29ae/src/counter.cc @@ -17,28 +17,32 @@ namespace benchmark { namespace internal { +namespace { + double Finish(Counter const& c, IterationCount iterations, double cpu_time, double num_threads) { double v = c.value; - if (c.flags & Counter::kIsRate) { + if ((c.flags & Counter::kIsRate) != 0) { v /= cpu_time; } - if (c.flags & Counter::kAvgThreads) { + if ((c.flags & Counter::kAvgThreads) != 0) { v /= num_threads; } - if (c.flags & Counter::kIsIterationInvariant) { + if ((c.flags & Counter::kIsIterationInvariant) != 0) { v *= static_cast(iterations); } - if (c.flags & Counter::kAvgIterations) { + if ((c.flags & Counter::kAvgIterations) != 0) { v /= static_cast(iterations); } - if (c.flags & Counter::kInvert) { // Invert is *always* last. + if ((c.flags & Counter::kInvert) != 0) { // Invert is *always* last. v = 1.0 / v; } return v; } +} // namespace + void Finish(UserCounters* l, IterationCount iterations, double cpu_time, double num_threads) { for (auto& c : *l) { @@ -64,7 +68,9 @@ void Increment(UserCounters* l, UserCounters const& r) { } bool SameNames(UserCounters const& l, UserCounters const& r) { - if (&l == &r) return true; + if (&l == &r) { + return true; + } if (l.size() != r.size()) { return false; } diff --git a/vendor/benchmark-38df9da/src/counter.h b/vendor/benchmark-4ed29ae/src/counter.h similarity index 100% rename from vendor/benchmark-38df9da/src/counter.h rename to vendor/benchmark-4ed29ae/src/counter.h diff --git a/vendor/benchmark-38df9da/src/csv_reporter.cc b/vendor/benchmark-4ed29ae/src/csv_reporter.cc similarity index 92% rename from vendor/benchmark-38df9da/src/csv_reporter.cc rename to vendor/benchmark-4ed29ae/src/csv_reporter.cc index 4b39e2c52..0f998045b 100644 --- a/vendor/benchmark-38df9da/src/csv_reporter.cc +++ b/vendor/benchmark-4ed29ae/src/csv_reporter.cc @@ -12,29 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include -#include #include #include -#include #include #include "benchmark/benchmark.h" #include "check.h" #include "complexity.h" -#include "string_util.h" -#include "timers.h" // File format reference: http://edoceo.com/utilitas/csv-file-format. namespace benchmark { namespace { -std::vector elements = { +const std::vector elements = { "name", "iterations", "real_time", "cpu_time", "time_unit", "bytes_per_second", "items_per_second", "label", "error_occurred", "error_message"}; -} // namespace std::string CsvEscape(const std::string& s) { std::string tmp; @@ -51,6 +45,7 @@ std::string CsvEscape(const std::string& s) { } return '"' + tmp + '"'; } +} // namespace BENCHMARK_EXPORT bool CSVReporter::ReportContext(const Context& context) { @@ -66,8 +61,10 @@ void CSVReporter::ReportRuns(const std::vector& reports) { // save the names of all the user counters for (const auto& run : reports) { for (const auto& cnt : run.counters) { - if (cnt.first == "bytes_per_second" || cnt.first == "items_per_second") + if (cnt.first == "bytes_per_second" || + cnt.first == "items_per_second") { continue; + } user_counter_names_.insert(cnt.first); } } @@ -75,7 +72,9 @@ void CSVReporter::ReportRuns(const std::vector& reports) { // print the header for (auto B = elements.begin(); B != elements.end();) { Out << *B++; - if (B != elements.end()) Out << ","; + if (B != elements.end()) { + Out << ","; + } } for (auto B = user_counter_names_.begin(); B != user_counter_names_.end();) { @@ -88,8 +87,10 @@ void CSVReporter::ReportRuns(const std::vector& reports) { // check that all the current counters are saved in the name set for (const auto& run : reports) { for (const auto& cnt : run.counters) { - if (cnt.first == "bytes_per_second" || cnt.first == "items_per_second") + if (cnt.first == "bytes_per_second" || + cnt.first == "items_per_second") { continue; + } BM_CHECK(user_counter_names_.find(cnt.first) != user_counter_names_.end()) << "All counters must be present in each run. " @@ -109,7 +110,7 @@ BENCHMARK_EXPORT void CSVReporter::PrintRunData(const Run& run) { std::ostream& Out = GetOutputStream(); Out << CsvEscape(run.benchmark_name()) << ","; - if (run.skipped) { + if (run.skipped != 0u) { Out << std::string(elements.size() - 3, ','); Out << std::boolalpha << (internal::SkippedWithError == run.skipped) << ","; Out << CsvEscape(run.skip_message) << "\n"; diff --git a/vendor/benchmark-38df9da/src/cycleclock.h b/vendor/benchmark-4ed29ae/src/cycleclock.h similarity index 90% rename from vendor/benchmark-38df9da/src/cycleclock.h rename to vendor/benchmark-4ed29ae/src/cycleclock.h index bd62f5d7e..0671a425f 100644 --- a/vendor/benchmark-38df9da/src/cycleclock.h +++ b/vendor/benchmark-4ed29ae/src/cycleclock.h @@ -36,6 +36,9 @@ // declarations of some other intrinsics, breaking compilation. // Therefore, we simply declare __rdtsc ourselves. See also // http://connect.microsoft.com/VisualStudio/feedback/details/262047 +// +// Note that MSVC defines the x64 preprocessor macros when building +// for Arm64EC, despite it using Arm64 assembly instructions. #if defined(COMPILER_MSVC) && !defined(_M_IX86) && !defined(_M_ARM64) && \ !defined(_M_ARM64EC) extern "C" uint64_t __rdtsc(); @@ -79,7 +82,10 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() { int64_t ret; __asm__ volatile("rdtsc" : "=A"(ret)); return ret; -#elif defined(__x86_64__) || defined(__amd64__) + +// Note that Clang, like MSVC, defines the x64 preprocessor macros when building +// for Arm64EC, despite it using Arm64 assembly instructions. +#elif (defined(__x86_64__) || defined(__amd64__)) && !defined(__arm64ec__) uint64_t low, high; __asm__ volatile("rdtsc" : "=a"(low), "=d"(high)); return static_cast((high << 32) | low); @@ -139,7 +145,7 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() { struct timespec ts = {0, 0}; clock_gettime(CLOCK_MONOTONIC, &ts); return static_cast(ts.tv_sec) * 1000000000 + ts.tv_nsec; -#elif defined(__aarch64__) +#elif defined(__aarch64__) || defined(__arm64ec__) // System timer of ARMv8 runs at a different frequency than the CPU's. // The frequency is fixed, typically in the range 1-50MHz. It can be // read at CNTFRQ special register. We assume the OS has set up @@ -219,7 +225,7 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() { #elif defined(__hexagon__) uint64_t pcycle; asm volatile("%0 = C15:14" : "=r"(pcycle)); - return static_cast(pcycle); + return static_cast(pcycle); #elif defined(__alpha__) // Alpha has a cycle counter, the PCC register, but it is an unsigned 32-bit // integer and thus wraps every ~4s, making using it for tick counts @@ -229,6 +235,18 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() { struct timeval tv; gettimeofday(&tv, nullptr); return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; +#elif defined(__hppa__) || defined(__linux__) + // Fallback for all other architectures with a recent Linux kernel, e.g.: + // HP PA-RISC provides a user-readable clock counter (cr16), but + // it's not syncronized across CPUs and only 32-bit wide when programs + // are built as 32-bit binaries. + // Same for SH-4 and possibly others. + // Use clock_gettime(CLOCK_MONOTONIC, ...) instead of gettimeofday + // because is provides nanosecond resolution. + // Initialize to always return 0 if clock_gettime fails. + struct timespec ts = {0, 0}; + clock_gettime(CLOCK_MONOTONIC, &ts); + return static_cast(ts.tv_sec) * 1000000000 + ts.tv_nsec; #else // The soft failover to a generic implementation is automatic only for ARM. // For other platforms the developer is expected to make an attempt to create diff --git a/vendor/benchmark-38df9da/src/internal_macros.h b/vendor/benchmark-4ed29ae/src/internal_macros.h similarity index 88% rename from vendor/benchmark-38df9da/src/internal_macros.h rename to vendor/benchmark-4ed29ae/src/internal_macros.h index f4894ba8e..22e3e2175 100644 --- a/vendor/benchmark-38df9da/src/internal_macros.h +++ b/vendor/benchmark-4ed29ae/src/internal_macros.h @@ -106,6 +106,16 @@ #define BENCHMARK_MAYBE_UNUSED #endif +#if defined(__GNUC__) || defined(__clang__) +#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx) \ + __attribute__((format(printf, format_arg, first_idx))) +#elif defined(__MINGW32__) +#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx) \ + __attribute__((format(__MINGW_PRINTF_FORMAT, format_arg, first_idx))) +#else +#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx) +#endif + // clang-format on #endif // BENCHMARK_INTERNAL_MACROS_H_ diff --git a/vendor/benchmark-38df9da/src/json_reporter.cc b/vendor/benchmark-4ed29ae/src/json_reporter.cc similarity index 89% rename from vendor/benchmark-38df9da/src/json_reporter.cc rename to vendor/benchmark-4ed29ae/src/json_reporter.cc index b8c8c94c0..2b84cd14a 100644 --- a/vendor/benchmark-38df9da/src/json_reporter.cc +++ b/vendor/benchmark-4ed29ae/src/json_reporter.cc @@ -81,19 +81,25 @@ std::string FormatKV(std::string const& key, bool value) { std::string FormatKV(std::string const& key, int64_t value) { std::stringstream ss; - ss << '"' << StrEscape(key) << "\": " << value; + // We really want to just dump the integer as-is, + // without the system locale interfering. + ss << '"' << StrEscape(key) << "\": " << std::to_string(value); return ss.str(); } +std::string FormatKV(std::string const& key, int value) { + return FormatKV(key, static_cast(value)); +} + std::string FormatKV(std::string const& key, double value) { std::stringstream ss; ss << '"' << StrEscape(key) << "\": "; - if (std::isnan(value)) + if (std::isnan(value)) { ss << (value < 0 ? "-" : "") << "NaN"; - else if (std::isinf(value)) + } else if (std::isinf(value)) { ss << (value < 0 ? "-" : "") << "Infinity"; - else { + } else { const auto max_digits10 = std::numeric_limits::max_digits10; const auto max_fractional_digits10 = max_digits10 - 1; @@ -122,7 +128,7 @@ bool JSONReporter::ReportContext(const Context& context) { out << indent << FormatKV("host_name", context.sys_info.name) << ",\n"; - if (Context::executable_name) { + if (Context::executable_name != nullptr) { out << indent << FormatKV("executable", Context::executable_name) << ",\n"; } @@ -136,7 +142,15 @@ bool JSONReporter::ReportContext(const Context& context) { if (CPUInfo::Scaling::UNKNOWN != info.scaling) { out << indent << FormatKV("cpu_scaling_enabled", - info.scaling == CPUInfo::Scaling::ENABLED ? true : false) + info.scaling == CPUInfo::Scaling::ENABLED) + << ",\n"; + } + + const SystemInfo& sysinfo = context.sys_info; + if (SystemInfo::ASLR::UNKNOWN != sysinfo.ASLRStatus) { + out << indent + << FormatKV("aslr_enabled", + sysinfo.ASLRStatus == SystemInfo::ASLR::ENABLED) << ",\n"; } @@ -144,7 +158,7 @@ bool JSONReporter::ReportContext(const Context& context) { indent = std::string(6, ' '); std::string cache_indent(8, ' '); for (size_t i = 0; i < info.caches.size(); ++i) { - auto& CI = info.caches[i]; + const auto& CI = info.caches[i]; out << indent << "{\n"; out << cache_indent << FormatKV("type", CI.type) << ",\n"; out << cache_indent << FormatKV("level", static_cast(CI.level)) @@ -155,7 +169,9 @@ bool JSONReporter::ReportContext(const Context& context) { << FormatKV("num_sharing", static_cast(CI.num_sharing)) << "\n"; out << indent << "}"; - if (i != info.caches.size() - 1) out << ","; + if (i != info.caches.size() - 1) { + out << ","; + } out << "\n"; } indent = std::string(4, ' '); @@ -163,7 +179,9 @@ bool JSONReporter::ReportContext(const Context& context) { out << indent << "\"load_avg\": ["; for (auto it = info.load_avg.begin(); it != info.load_avg.end();) { out << *it++; - if (it != info.load_avg.end()) out << ","; + if (it != info.load_avg.end()) { + out << ","; + } } out << "],\n"; @@ -179,7 +197,7 @@ bool JSONReporter::ReportContext(const Context& context) { out << ",\n"; // NOTE: our json schema is not strictly tied to the library version! - out << indent << FormatKV("json_schema_version", int64_t(1)); + out << indent << FormatKV("json_schema_version", 1); std::map* global_context = internal::GetGlobalContext(); @@ -294,20 +312,21 @@ void JSONReporter::PrintRunData(Run const& run) { out << indent << FormatKV("rms", run.GetAdjustedCPUTime()); } - for (auto& c : run.counters) { + for (const auto& c : run.counters) { out << ",\n" << indent << FormatKV(c.first, c.second); } - if (run.memory_result) { - const MemoryManager::Result memory_result = *run.memory_result; + if (run.memory_result.memory_iterations > 0) { + const auto& memory_result = run.memory_result; out << ",\n" << indent << FormatKV("allocs_per_iter", run.allocs_per_iter); out << ",\n" << indent << FormatKV("max_bytes_used", memory_result.max_bytes_used); auto report_if_present = [&out, &indent](const std::string& label, int64_t val) { - if (val != MemoryManager::TombstoneValue) + if (val != MemoryManager::TombstoneValue) { out << ",\n" << indent << FormatKV(label, val); + } }; report_if_present("total_allocated_bytes", @@ -321,7 +340,4 @@ void JSONReporter::PrintRunData(Run const& run) { out << '\n'; } -const int64_t MemoryManager::TombstoneValue = - std::numeric_limits::max(); - } // end namespace benchmark diff --git a/vendor/benchmark-38df9da/src/log.h b/vendor/benchmark-4ed29ae/src/log.h similarity index 82% rename from vendor/benchmark-38df9da/src/log.h rename to vendor/benchmark-4ed29ae/src/log.h index 9a21400b0..57b7bdfc4 100644 --- a/vendor/benchmark-38df9da/src/log.h +++ b/vendor/benchmark-4ed29ae/src/log.h @@ -4,13 +4,6 @@ #include #include -// NOTE: this is also defined in benchmark.h but we're trying to avoid a -// dependency. -// The _MSVC_LANG check should detect Visual Studio 2015 Update 3 and newer. -#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L) -#define BENCHMARK_HAS_CXX11 -#endif - namespace benchmark { namespace internal { @@ -31,13 +24,8 @@ class LogType { // NOTE: we could use BENCHMARK_DISALLOW_COPY_AND_ASSIGN but we shouldn't have // a dependency on benchmark.h from here. -#ifndef BENCHMARK_HAS_CXX11 - LogType(const LogType&); - LogType& operator=(const LogType&); -#else LogType(const LogType&) = delete; LogType& operator=(const LogType&) = delete; -#endif }; template diff --git a/vendor/benchmark-38df9da/src/mutex.h b/vendor/benchmark-4ed29ae/src/mutex.h similarity index 100% rename from vendor/benchmark-38df9da/src/mutex.h rename to vendor/benchmark-4ed29ae/src/mutex.h diff --git a/vendor/benchmark-38df9da/src/perf_counters.cc b/vendor/benchmark-4ed29ae/src/perf_counters.cc similarity index 97% rename from vendor/benchmark-38df9da/src/perf_counters.cc rename to vendor/benchmark-4ed29ae/src/perf_counters.cc index e2758afb9..f47aa7b42 100644 --- a/vendor/benchmark-38df9da/src/perf_counters.cc +++ b/vendor/benchmark-4ed29ae/src/perf_counters.cc @@ -26,8 +26,6 @@ namespace benchmark { namespace internal { -constexpr size_t PerfCounterValues::kMaxCounters; - #if defined HAVE_LIBPFM size_t PerfCounterValues::Read(const std::vector& leaders) { @@ -157,8 +155,8 @@ PerfCounters PerfCounters::Create( attr.exclude_hv = true; // Read all counters in a group in one read. - attr.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_TOTAL_TIME_ENABLED | - PERF_FORMAT_TOTAL_TIME_RUNNING; + attr.read_format = PERF_FORMAT_GROUP; //| PERF_FORMAT_TOTAL_TIME_ENABLED | + // PERF_FORMAT_TOTAL_TIME_RUNNING; int id = -1; while (id < 0) { @@ -216,9 +214,9 @@ PerfCounters PerfCounters::Create( // This should never happen but if it does, we give up on the // entire batch as recovery would be a mess. GetErrorLogInstance() << "***WARNING*** Failed to start counters. " - "Claring out all counters.\n"; + "Clearing out all counters.\n"; - // Close all peformance counters + // Close all performance counters for (int id : counter_ids) { ::close(id); } diff --git a/vendor/benchmark-38df9da/src/perf_counters.h b/vendor/benchmark-4ed29ae/src/perf_counters.h similarity index 100% rename from vendor/benchmark-38df9da/src/perf_counters.h rename to vendor/benchmark-4ed29ae/src/perf_counters.h diff --git a/vendor/benchmark-38df9da/src/re.h b/vendor/benchmark-4ed29ae/src/re.h similarity index 96% rename from vendor/benchmark-38df9da/src/re.h rename to vendor/benchmark-4ed29ae/src/re.h index 9afb869be..1486dd877 100644 --- a/vendor/benchmark-38df9da/src/re.h +++ b/vendor/benchmark-4ed29ae/src/re.h @@ -15,6 +15,8 @@ #ifndef BENCHMARK_RE_H_ #define BENCHMARK_RE_H_ +#include + #include "internal_macros.h" // clang-format off @@ -121,15 +123,13 @@ inline bool Regex::Init(const std::string& spec, std::string* error) { if (ec != 0) { if (error) { size_t needed = regerror(ec, &re_, nullptr, 0); - char* errbuf = new char[needed]; - regerror(ec, &re_, errbuf, needed); + std::vector errbuf(needed); + regerror(ec, &re_, errbuf.data(), needed); // regerror returns the number of bytes necessary to null terminate // the string, so we move that when assigning to error. BM_CHECK_NE(needed, 0); - error->assign(errbuf, needed - 1); - - delete[] errbuf; + error->assign(errbuf.data(), needed - 1); } return false; diff --git a/vendor/benchmark-38df9da/src/reporter.cc b/vendor/benchmark-4ed29ae/src/reporter.cc similarity index 81% rename from vendor/benchmark-38df9da/src/reporter.cc rename to vendor/benchmark-4ed29ae/src/reporter.cc index 076bc31a2..71926b15e 100644 --- a/vendor/benchmark-38df9da/src/reporter.cc +++ b/vendor/benchmark-4ed29ae/src/reporter.cc @@ -42,20 +42,23 @@ void BenchmarkReporter::PrintBasicContext(std::ostream *out, Out << LocalDateTimeString() << "\n"; #endif - if (context.executable_name) - Out << "Running " << context.executable_name << "\n"; + if (benchmark::BenchmarkReporter::Context::executable_name != nullptr) { + Out << "Running " << benchmark::BenchmarkReporter::Context::executable_name + << "\n"; + } const CPUInfo &info = context.cpu_info; Out << "Run on (" << info.num_cpus << " X " << (info.cycles_per_second / 1000000.0) << " MHz CPU " << ((info.num_cpus > 1) ? "s" : "") << ")\n"; - if (info.caches.size() != 0) { + if (!info.caches.empty()) { Out << "CPU Caches:\n"; - for (auto &CInfo : info.caches) { + for (const auto &CInfo : info.caches) { Out << " L" << CInfo.level << " " << CInfo.type << " " << (CInfo.size / 1024) << " KiB"; - if (CInfo.num_sharing != 0) + if (CInfo.num_sharing != 0) { Out << " (x" << (info.num_cpus / CInfo.num_sharing) << ")"; + } Out << "\n"; } } @@ -63,7 +66,9 @@ void BenchmarkReporter::PrintBasicContext(std::ostream *out, Out << "Load Average: "; for (auto It = info.load_avg.begin(); It != info.load_avg.end();) { Out << StrFormat("%.2f", *It++); - if (It != info.load_avg.end()) Out << ", "; + if (It != info.load_avg.end()) { + Out << ", "; + } } Out << "\n"; } @@ -83,6 +88,12 @@ void BenchmarkReporter::PrintBasicContext(std::ostream *out, "overhead.\n"; } + const SystemInfo &sysinfo = context.sys_info; + if (SystemInfo::ASLR::ENABLED == sysinfo.ASLRStatus) { + Out << "***WARNING*** ASLR is enabled, the results may have unreproducible " + "noise in them.\n"; + } + #ifndef NDEBUG Out << "***WARNING*** Library was built as DEBUG. Timings may be " "affected.\n"; @@ -105,13 +116,17 @@ std::string BenchmarkReporter::Run::benchmark_name() const { double BenchmarkReporter::Run::GetAdjustedRealTime() const { double new_time = real_accumulated_time * GetTimeUnitMultiplier(time_unit); - if (iterations != 0) new_time /= static_cast(iterations); + if (iterations != 0) { + new_time /= static_cast(iterations); + } return new_time; } double BenchmarkReporter::Run::GetAdjustedCPUTime() const { double new_time = cpu_accumulated_time * GetTimeUnitMultiplier(time_unit); - if (iterations != 0) new_time /= static_cast(iterations); + if (iterations != 0) { + new_time /= static_cast(iterations); + } return new_time; } diff --git a/vendor/benchmark-38df9da/src/statistics.cc b/vendor/benchmark-4ed29ae/src/statistics.cc similarity index 90% rename from vendor/benchmark-38df9da/src/statistics.cc rename to vendor/benchmark-4ed29ae/src/statistics.cc index 16b60261f..fc7450ef9 100644 --- a/vendor/benchmark-38df9da/src/statistics.cc +++ b/vendor/benchmark-4ed29ae/src/statistics.cc @@ -26,17 +26,21 @@ namespace benchmark { -auto StatisticsSum = [](const std::vector& v) { +const auto StatisticsSum = [](const std::vector& v) { return std::accumulate(v.begin(), v.end(), 0.0); }; double StatisticsMean(const std::vector& v) { - if (v.empty()) return 0.0; + if (v.empty()) { + return 0.0; + } return StatisticsSum(v) * (1.0 / static_cast(v.size())); } double StatisticsMedian(const std::vector& v) { - if (v.size() < 3) return StatisticsMean(v); + if (v.size() < 3) { + return StatisticsMean(v); + } std::vector copy(v); auto center = copy.begin() + v.size() / 2; @@ -47,29 +51,37 @@ double StatisticsMedian(const std::vector& v) { // before. Instead of resorting, we just look for the max value before it, // which is not necessarily the element immediately preceding `center` Since // `copy` is only partially sorted by `nth_element`. - if (v.size() % 2 == 1) return *center; + if (v.size() % 2 == 1) { + return *center; + } auto center2 = std::max_element(copy.begin(), center); return (*center + *center2) / 2.0; } // Return the sum of the squares of this sample set -auto SumSquares = [](const std::vector& v) { +const auto SumSquares = [](const std::vector& v) { return std::inner_product(v.begin(), v.end(), v.begin(), 0.0); }; -auto Sqr = [](const double dat) { return dat * dat; }; -auto Sqrt = [](const double dat) { +const auto Sqr = [](const double dat) { return dat * dat; }; +const auto Sqrt = [](const double dat) { // Avoid NaN due to imprecision in the calculations - if (dat < 0.0) return 0.0; + if (dat < 0.0) { + return 0.0; + } return std::sqrt(dat); }; double StatisticsStdDev(const std::vector& v) { const auto mean = StatisticsMean(v); - if (v.empty()) return mean; + if (v.empty()) { + return mean; + } // Sample standard deviation is undefined for n = 1 - if (v.size() == 1) return 0.0; + if (v.size() == 1) { + return 0.0; + } const double avg_squares = SumSquares(v) * (1.0 / static_cast(v.size())); @@ -79,12 +91,16 @@ double StatisticsStdDev(const std::vector& v) { } double StatisticsCV(const std::vector& v) { - if (v.size() < 2) return 0.0; + if (v.size() < 2) { + return 0.0; + } const auto stddev = StatisticsStdDev(v); const auto mean = StatisticsMean(v); - if (std::fpclassify(mean) == FP_ZERO) return 0.0; + if (std::fpclassify(mean) == FP_ZERO) { + return 0.0; + } return stddev / mean; } @@ -137,7 +153,9 @@ std::vector ComputeStats( for (Run const& run : reports) { BM_CHECK_EQ(reports[0].benchmark_name(), run.benchmark_name()); BM_CHECK_EQ(run_iterations, run.iterations); - if (run.skipped) continue; + if (run.skipped != 0u) { + continue; + } real_accumulated_time_stat.emplace_back(run.real_accumulated_time); cpu_accumulated_time_stat.emplace_back(run.cpu_accumulated_time); // user counters @@ -158,7 +176,7 @@ std::vector ComputeStats( } const double iteration_rescale_factor = - double(reports.size()) / double(run_iterations); + static_cast(reports.size()) / static_cast(run_iterations); for (const auto& Stat : *reports[0].statistics) { // Get the data from the accumulator to BenchmarkReporter::Run's. diff --git a/vendor/benchmark-38df9da/src/statistics.h b/vendor/benchmark-4ed29ae/src/statistics.h similarity index 100% rename from vendor/benchmark-38df9da/src/statistics.h rename to vendor/benchmark-4ed29ae/src/statistics.h diff --git a/vendor/benchmark-38df9da/src/string_util.cc b/vendor/benchmark-4ed29ae/src/string_util.cc similarity index 94% rename from vendor/benchmark-38df9da/src/string_util.cc rename to vendor/benchmark-4ed29ae/src/string_util.cc index 9ba63a700..9c5df3ba2 100644 --- a/vendor/benchmark-38df9da/src/string_util.cc +++ b/vendor/benchmark-4ed29ae/src/string_util.cc @@ -29,7 +29,7 @@ static_assert(arraysize(kBigSIUnits) == arraysize(kBigIECUnits), static_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits), "Small SI and Big SI unit arrays must be the same size"); -static const int64_t kUnitsSize = arraysize(kBigSIUnits); +const int64_t kUnitsSize = arraysize(kBigSIUnits); void ToExponentAndMantissa(double val, int precision, double one_k, std::string* mantissa, int64_t* exponent) { @@ -87,10 +87,14 @@ void ToExponentAndMantissa(double val, int precision, double one_k, } std::string ExponentToPrefix(int64_t exponent, bool iec) { - if (exponent == 0) return ""; + if (exponent == 0) { + return {}; + } const int64_t index = (exponent > 0 ? exponent - 1 : -exponent - 1); - if (index >= kUnitsSize) return ""; + if (index >= kUnitsSize) { + return {}; + } const char* const* array = (exponent > 0 ? (iec ? kBigIECUnits : kBigSIUnits) : kSmallSIUnits); @@ -101,21 +105,22 @@ std::string ExponentToPrefix(int64_t exponent, bool iec) { std::string ToBinaryStringFullySpecified(double value, int precision, Counter::OneK one_k) { std::string mantissa; - int64_t exponent; + int64_t exponent = 0; ToExponentAndMantissa(value, precision, one_k == Counter::kIs1024 ? 1024.0 : 1000.0, &mantissa, &exponent); return mantissa + ExponentToPrefix(exponent, one_k == Counter::kIs1024); } +PRINTF_FORMAT_STRING_FUNC(1, 0) std::string StrFormatImp(const char* msg, va_list args) { // we might need a second shot at this, so pre-emptivly make a copy va_list args_cp; va_copy(args_cp, args); - // TODO(ericwf): use std::array for first attempt to avoid one memory - // allocation guess what the size might be - std::array local_buff; + // Use std::array for first attempt to avoid one memory allocation guess what + // the size might be + std::array local_buff = {}; // 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation // in the android-ndk @@ -124,9 +129,12 @@ std::string StrFormatImp(const char* msg, va_list args) { va_end(args_cp); // handle empty expansion - if (ret == 0) return std::string{}; - if (static_cast(ret) < local_buff.size()) + if (ret == 0) { + return {}; + } + if (static_cast(ret) < local_buff.size()) { return std::string(local_buff.data()); + } // we did not provide a long enough buffer on our first attempt. // add 1 to size to account for null-byte in size cast to prevent overflow @@ -153,7 +161,9 @@ std::string StrFormat(const char* format, ...) { } std::vector StrSplit(const std::string& str, char delim) { - if (str.empty()) return {}; + if (str.empty()) { + return {}; + } std::vector ret; size_t first = 0; size_t next = str.find(delim); diff --git a/vendor/benchmark-38df9da/src/string_util.h b/vendor/benchmark-4ed29ae/src/string_util.h similarity index 98% rename from vendor/benchmark-38df9da/src/string_util.h rename to vendor/benchmark-4ed29ae/src/string_util.h index 731aa2c04..f1e50be4f 100644 --- a/vendor/benchmark-38df9da/src/string_util.h +++ b/vendor/benchmark-4ed29ae/src/string_util.h @@ -9,7 +9,6 @@ #include "benchmark/benchmark.h" #include "benchmark/export.h" #include "check.h" -#include "internal_macros.h" namespace benchmark { diff --git a/vendor/benchmark-38df9da/src/sysinfo.cc b/vendor/benchmark-4ed29ae/src/sysinfo.cc similarity index 86% rename from vendor/benchmark-38df9da/src/sysinfo.cc rename to vendor/benchmark-4ed29ae/src/sysinfo.cc index 7261e2a96..3977772bf 100644 --- a/vendor/benchmark-38df9da/src/sysinfo.cc +++ b/vendor/benchmark-4ed29ae/src/sysinfo.cc @@ -54,6 +54,10 @@ #include #endif +#if defined(BENCHMARK_OS_LINUX) +#include +#endif + #include #include #include @@ -76,7 +80,6 @@ #include "benchmark/benchmark.h" #include "check.h" #include "cycleclock.h" -#include "internal_macros.h" #include "log.h" #include "string_util.h" #include "timers.h" @@ -84,7 +87,7 @@ namespace benchmark { namespace { -void PrintImp(std::ostream& out) { out << std::endl; } +void PrintImp(std::ostream& out) { out << '\n'; } template void PrintImp(std::ostream& out, First&& f, Rest&&... rest) { @@ -95,6 +98,7 @@ void PrintImp(std::ostream& out, First&& f, Rest&&... rest) { template BENCHMARK_NORETURN void PrintErrorAndDie(Args&&... args) { PrintImp(std::cerr, std::forward(args)...); + std::cerr << std::flush; std::exit(EXIT_FAILURE); } @@ -120,7 +124,7 @@ struct ValueUnion { explicit ValueUnion(std::size_t buff_size) : size(sizeof(DataT) + buff_size), - buff(::new (std::malloc(size)) DataT(), &std::free) {} + buff(::new(std::malloc(size)) DataT(), &std::free) {} ValueUnion(ValueUnion&& other) = default; @@ -153,11 +157,11 @@ ValueUnion GetSysctlImp(std::string const& name) { int mib[2]; mib[0] = CTL_HW; - if ((name == "hw.ncpu") || (name == "hw.cpuspeed")) { + if ((name == "hw.ncpuonline") || (name == "hw.cpuspeed")) { ValueUnion buff(sizeof(int)); - if (name == "hw.ncpu") { - mib[1] = HW_NCPU; + if (name == "hw.ncpuonline") { + mib[1] = HW_NCPUONLINE; } else { mib[1] = HW_CPUSPEED; } @@ -212,14 +216,18 @@ template bool ReadFromFile(std::string const& fname, ArgT* arg) { *arg = ArgT(); std::ifstream f(fname.c_str()); - if (!f.is_open()) return false; + if (!f.is_open()) { + return false; + } f >> *arg; return f.good(); } CPUInfo::Scaling CpuScaling(int num_cpus) { // We don't have a valid CPU count, so don't even bother. - if (num_cpus <= 0) return CPUInfo::Scaling::UNKNOWN; + if (num_cpus <= 0) { + return CPUInfo::Scaling::UNKNOWN; + } #if defined(BENCHMARK_OS_QNX) return CPUInfo::Scaling::UNKNOWN; #elif !defined(BENCHMARK_OS_WINDOWS) @@ -230,8 +238,9 @@ CPUInfo::Scaling CpuScaling(int num_cpus) { for (int cpu = 0; cpu < num_cpus; ++cpu) { std::string governor_file = StrCat("/sys/devices/system/cpu/cpu", cpu, "/cpufreq/scaling_governor"); - if (ReadFromFile(governor_file, &res) && res != "performance") + if (ReadFromFile(governor_file, &res) && res != "performance") { return CPUInfo::Scaling::ENABLED; + } } return CPUInfo::Scaling::DISABLED; #else @@ -246,7 +255,7 @@ int CountSetBitsInCPUMap(std::string val) { CPUMask mask(benchmark::stoul(part, nullptr, 16)); return static_cast(mask.count()); }; - std::size_t pos; + std::size_t pos = 0; int total = 0; while ((pos = val.find(',')) != std::string::npos) { total += CountBits(val.substr(0, pos)); @@ -267,28 +276,35 @@ std::vector GetCacheSizesFromKVFS() { CPUInfo::CacheInfo info; std::string fpath = StrCat(dir, "index", idx++, "/"); std::ifstream f(StrCat(fpath, "size").c_str()); - if (!f.is_open()) break; + if (!f.is_open()) { + break; + } std::string suffix; f >> info.size; - if (f.fail()) + if (f.fail()) { PrintErrorAndDie("Failed while reading file '", fpath, "size'"); + } if (f.good()) { f >> suffix; - if (f.bad()) + if (f.bad()) { PrintErrorAndDie( "Invalid cache size format: failed to read size suffix"); - else if (f && suffix != "K") + } else if (f && suffix != "K") { PrintErrorAndDie("Invalid cache size format: Expected bytes ", suffix); - else if (suffix == "K") + } else if (suffix == "K") { info.size *= 1024; + } } - if (!ReadFromFile(StrCat(fpath, "type"), &info.type)) + if (!ReadFromFile(StrCat(fpath, "type"), &info.type)) { PrintErrorAndDie("Failed to read from file ", fpath, "type"); - if (!ReadFromFile(StrCat(fpath, "level"), &info.level)) + } + if (!ReadFromFile(StrCat(fpath, "level"), &info.level)) { PrintErrorAndDie("Failed to read from file ", fpath, "level"); + } std::string map_str; - if (!ReadFromFile(StrCat(fpath, "shared_cpu_map"), &map_str)) + if (!ReadFromFile(StrCat(fpath, "shared_cpu_map"), &map_str)) { PrintErrorAndDie("Failed to read from file ", fpath, "shared_cpu_map"); + } info.num_sharing = CountSetBitsInCPUMap(map_str); res.push_back(info); } @@ -333,15 +349,18 @@ std::vector GetCacheSizesWindows() { using UPtr = std::unique_ptr; GetLogicalProcessorInformation(nullptr, &buffer_size); UPtr buff(static_cast(std::malloc(buffer_size)), &std::free); - if (!GetLogicalProcessorInformation(buff.get(), &buffer_size)) + if (!GetLogicalProcessorInformation(buff.get(), &buffer_size)) { PrintErrorAndDie("Failed during call to GetLogicalProcessorInformation: ", GetLastError()); + } PInfo* it = buff.get(); PInfo* end = buff.get() + (buffer_size / sizeof(PInfo)); for (; it != end; ++it) { - if (it->Relationship != RelationCache) continue; + if (it->Relationship != RelationCache) { + continue; + } using BitSet = std::bitset; BitSet b(it->ProcessorMask); // To prevent duplicates, only consider caches where CPU 0 is specified @@ -353,6 +372,11 @@ std::vector GetCacheSizesWindows() { C.size = static_cast(cache.Size); C.type = "Unknown"; switch (cache.Type) { +// Windows SDK version >= 10.0.26100.0 +#ifdef NTDDI_WIN11_GE + case CacheUnknown: + break; +#endif case CacheUnified: C.type = "Unified"; break; @@ -415,7 +439,7 @@ std::vector GetCacheSizes() { return GetCacheSizesWindows(); #elif defined(BENCHMARK_OS_QNX) return GetCacheSizesQNX(); -#elif defined(BENCHMARK_OS_QURT) +#elif defined(BENCHMARK_OS_QURT) || defined(__EMSCRIPTEN__) return std::vector(); #else return GetCacheSizesFromKVFS(); @@ -437,7 +461,7 @@ std::string GetSystemName() { DWCOUNT, NULL, 0, NULL, NULL); str.resize(len); WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, hostname, DWCOUNT, &str[0], - str.size(), NULL, NULL); + static_cast(str.size()), NULL, NULL); #endif return str; #elif defined(BENCHMARK_OS_QURT) @@ -469,17 +493,23 @@ std::string GetSystemName() { #endif // def HOST_NAME_MAX char hostname[HOST_NAME_MAX]; int retVal = gethostname(hostname, HOST_NAME_MAX); - if (retVal != 0) return std::string(""); - return std::string(hostname); + return retVal != 0 ? std::string() : std::string(hostname); #endif // Catch-all POSIX block. } +SystemInfo::ASLR GetASLR() { +#ifdef BENCHMARK_OS_LINUX + const auto curr_personality = personality(0xffffffff); + return (curr_personality & ADDR_NO_RANDOMIZE) ? SystemInfo::ASLR::DISABLED + : SystemInfo::ASLR::ENABLED; +#else + // FIXME: support detecting ASLR on other OS. + return SystemInfo::ASLR::UNKNOWN; +#endif +} + int GetNumCPUsImpl() { -#ifdef BENCHMARK_HAS_SYSCTL - int num_cpu = -1; - if (GetSysctl("hw.ncpu", &num_cpu)) return num_cpu; - PrintErrorAndDie("Err: ", strerror(errno)); -#elif defined(BENCHMARK_OS_WINDOWS) +#ifdef BENCHMARK_OS_WINDOWS SYSTEM_INFO sysinfo; // Use memset as opposed to = {} to avoid GCC missing initializer false // positives. @@ -487,14 +517,6 @@ int GetNumCPUsImpl() { GetSystemInfo(&sysinfo); // number of logical processors in the current group return static_cast(sysinfo.dwNumberOfProcessors); -#elif defined(BENCHMARK_OS_SOLARIS) - // Returns -1 in case of a failure. - long num_cpu = sysconf(_SC_NPROCESSORS_ONLN); - if (num_cpu < 0) { - PrintErrorAndDie("sysconf(_SC_NPROCESSORS_ONLN) failed with error: ", - strerror(errno)); - } - return (int)num_cpu; #elif defined(BENCHMARK_OS_QNX) return static_cast(_syspage_ptr->num_cpu); #elif defined(BENCHMARK_OS_QURT) @@ -502,64 +524,42 @@ int GetNumCPUsImpl() { if (qurt_sysenv_get_max_hw_threads(&hardware_threads) != QURT_EOK) { hardware_threads.max_hthreads = 1; } - return hardware_threads.max_hthreads; -#else - int num_cpus = 0; - int max_id = -1; - std::ifstream f("/proc/cpuinfo"); - if (!f.is_open()) { - PrintErrorAndDie("Failed to open /proc/cpuinfo"); - } -#if defined(__alpha__) - const std::string Key = "cpus detected"; -#else - const std::string Key = "processor"; -#endif - std::string ln; - while (std::getline(f, ln)) { - if (ln.empty()) continue; - std::size_t split_idx = ln.find(':'); - std::string value; -#if defined(__s390__) - // s390 has another format in /proc/cpuinfo - // it needs to be parsed differently - if (split_idx != std::string::npos) - value = ln.substr(Key.size() + 1, split_idx - Key.size() - 1); + return static_cast(hardware_threads.max_hthreads); +#elif defined(BENCHMARK_HAS_SYSCTL) + // *BSD, macOS + int num_cpu = -1; + constexpr auto* hwncpu = +#if defined BENCHMARK_OS_MACOSX + "hw.logicalcpu"; +#elif defined(HW_NCPUONLINE) + "hw.ncpuonline"; #else - if (split_idx != std::string::npos) value = ln.substr(split_idx + 1); + "hw.ncpu"; #endif - if (ln.size() >= Key.size() && ln.compare(0, Key.size(), Key) == 0) { - num_cpus++; - if (!value.empty()) { - const int cur_id = benchmark::stoi(value); - max_id = std::max(cur_id, max_id); - } - } - } - if (f.bad()) { - PrintErrorAndDie("Failure reading /proc/cpuinfo"); - } - if (!f.eof()) { - PrintErrorAndDie("Failed to read to end of /proc/cpuinfo"); - } - f.close(); - - if ((max_id + 1) != num_cpus) { - fprintf(stderr, - "CPU ID assignments in /proc/cpuinfo seem messed up." - " This is usually caused by a bad BIOS.\n"); + if (GetSysctl(hwncpu, &num_cpu)) return num_cpu; + PrintErrorAndDie("Err: ", strerror(errno)); +#elif defined(_SC_NPROCESSORS_ONLN) + // Linux, Solaris, AIX, Haiku, WASM, etc. + // Returns -1 in case of a failure. + int num_cpu = static_cast(sysconf(_SC_NPROCESSORS_ONLN)); + if (num_cpu < 0) { + PrintErrorAndDie("sysconf(_SC_NPROCESSORS_ONLN) failed with error: ", + strerror(errno)); } - return num_cpus; + return num_cpu; +#else + // Fallback, no other API exists. + return -1; #endif BENCHMARK_UNREACHABLE(); } int GetNumCPUs() { - const int num_cpus = GetNumCPUsImpl(); + int num_cpus = GetNumCPUsImpl(); if (num_cpus < 1) { - PrintErrorAndDie( - "Unable to extract number of CPUs. If your platform uses " - "/proc/cpuinfo, custom support may need to be added."); + std::cerr << "Unable to extract number of CPUs.\n"; + // There must be at least one CPU on which we're running. + num_cpus = 1; } return num_cpus; } @@ -567,22 +567,28 @@ int GetNumCPUs() { class ThreadAffinityGuard final { public: ThreadAffinityGuard() : reset_affinity(SetAffinity()) { - if (!reset_affinity) + if (!reset_affinity) { std::cerr << "***WARNING*** Failed to set thread affinity. Estimated CPU " - "frequency may be incorrect." - << std::endl; + "frequency may be incorrect.\n"; + } } ~ThreadAffinityGuard() { - if (!reset_affinity) return; + if (!reset_affinity) { + return; + } #if defined(BENCHMARK_HAS_PTHREAD_AFFINITY) int ret = pthread_setaffinity_np(self, sizeof(previous_affinity), &previous_affinity); - if (ret == 0) return; + if (ret == 0) { + return; + } #elif defined(BENCHMARK_OS_WINDOWS_WIN32) DWORD_PTR ret = SetThreadAffinityMask(self, previous_affinity); - if (ret != 0) return; + if (ret != 0) { + return; + } #endif // def BENCHMARK_HAS_PTHREAD_AFFINITY PrintErrorAndDie("Failed to reset thread affinity"); } @@ -595,26 +601,32 @@ class ThreadAffinityGuard final { private: bool SetAffinity() { #if defined(BENCHMARK_HAS_PTHREAD_AFFINITY) - int ret; + int ret = 0; self = pthread_self(); ret = pthread_getaffinity_np(self, sizeof(previous_affinity), &previous_affinity); - if (ret != 0) return false; + if (ret != 0) { + return false; + } cpu_set_t affinity; memcpy(&affinity, &previous_affinity, sizeof(affinity)); bool is_first_cpu = true; - for (int i = 0; i < CPU_SETSIZE; ++i) + for (int i = 0; i < CPU_SETSIZE; ++i) { if (CPU_ISSET(i, &affinity)) { - if (is_first_cpu) + if (is_first_cpu) { is_first_cpu = false; - else + } else { CPU_CLR(i, &affinity); + } } + } - if (is_first_cpu) return false; + if (is_first_cpu) { + return false; + } ret = pthread_setaffinity_np(self, sizeof(affinity), &affinity); return ret == 0; @@ -629,8 +641,8 @@ class ThreadAffinityGuard final { } #if defined(BENCHMARK_HAS_PTHREAD_AFFINITY) - pthread_t self; - cpu_set_t previous_affinity; + pthread_t self{}; + cpu_set_t previous_affinity{}; #elif defined(BENCHMARK_OS_WINDOWS_WIN32) HANDLE self; DWORD_PTR previous_affinity; @@ -644,7 +656,7 @@ double GetCPUCyclesPerSecond(CPUInfo::Scaling scaling) { (void)scaling; #if defined BENCHMARK_OS_LINUX || defined BENCHMARK_OS_CYGWIN - long freq; + long freq = 0; // If the kernel is exporting the tsc frequency use that. There are issues // where cpuinfo_max_freq cannot be relied on because the BIOS may be @@ -679,7 +691,9 @@ double GetCPUCyclesPerSecond(CPUInfo::Scaling scaling) { } auto StartsWithKey = [](std::string const& Value, std::string const& Key) { - if (Key.size() > Value.size()) return false; + if (Key.size() > Value.size()) { + return false; + } auto Cmp = [&](char X, char Y) { return std::tolower(X) == std::tolower(Y); }; @@ -688,22 +702,30 @@ double GetCPUCyclesPerSecond(CPUInfo::Scaling scaling) { std::string ln; while (std::getline(f, ln)) { - if (ln.empty()) continue; + if (ln.empty()) { + continue; + } std::size_t split_idx = ln.find(':'); std::string value; - if (split_idx != std::string::npos) value = ln.substr(split_idx + 1); + if (split_idx != std::string::npos) { + value = ln.substr(split_idx + 1); + } // When parsing the "cpu MHz" and "bogomips" (fallback) entries, we only // accept positive values. Some environments (virtual machines) report zero, // which would cause infinite looping in WallTime_Init. if (StartsWithKey(ln, "cpu MHz")) { if (!value.empty()) { double cycles_per_second = benchmark::stod(value) * 1000000.0; - if (cycles_per_second > 0) return cycles_per_second; + if (cycles_per_second > 0) { + return cycles_per_second; + } } } else if (StartsWithKey(ln, "bogomips")) { if (!value.empty()) { bogo_clock = benchmark::stod(value) * 1000000.0; - if (bogo_clock < 0.0) bogo_clock = error_value; + if (bogo_clock < 0.0) { + bogo_clock = error_value; + } } } } @@ -719,7 +741,9 @@ double GetCPUCyclesPerSecond(CPUInfo::Scaling scaling) { // If we found the bogomips clock, but nothing better, we'll use it (but // we're not happy about it); otherwise, fallback to the rough estimation // below. - if (bogo_clock >= 0.0) return bogo_clock; + if (bogo_clock >= 0.0) { + return bogo_clock; + } #elif defined BENCHMARK_HAS_SYSCTL constexpr auto* freqStr = @@ -734,9 +758,13 @@ double GetCPUCyclesPerSecond(CPUInfo::Scaling scaling) { #endif unsigned long long hz = 0; #if defined BENCHMARK_OS_OPENBSD - if (GetSysctl(freqStr, &hz)) return static_cast(hz * 1000000); + if (GetSysctl(freqStr, &hz)) { + return static_cast(hz * 1000000); + } #else - if (GetSysctl(freqStr, &hz)) return static_cast(hz); + if (GetSysctl(freqStr, &hz)) { + return static_cast(hz); + } #endif fprintf(stderr, "Unable to determine clock rate from sysctl: %s: %s\n", freqStr, strerror(errno)); @@ -752,9 +780,10 @@ double GetCPUCyclesPerSecond(CPUInfo::Scaling scaling) { SUCCEEDED( SHGetValueA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", - "~MHz", nullptr, &data, &data_size))) + "~MHz", nullptr, &data, &data_size))) { return static_cast(static_cast(data) * static_cast(1000 * 1000)); // was mhz + } #elif defined(BENCHMARK_OS_SOLARIS) kstat_ctl_t* kc = kstat_open(); if (!kc) { @@ -836,11 +865,11 @@ std::vector GetLoadAvg() { !(defined(__ANDROID__) && __ANDROID_API__ < 29) static constexpr int kMaxSamples = 3; std::vector res(kMaxSamples, 0.0); - const size_t nelem = static_cast(getloadavg(res.data(), kMaxSamples)); + const auto nelem = getloadavg(res.data(), kMaxSamples); if (nelem < 1) { res.clear(); } else { - res.resize(nelem); + res.resize(static_cast(nelem)); } return res; #else @@ -867,5 +896,5 @@ const SystemInfo& SystemInfo::Get() { return *info; } -SystemInfo::SystemInfo() : name(GetSystemName()) {} +SystemInfo::SystemInfo() : name(GetSystemName()), ASLRStatus(GetASLR()) {} } // end namespace benchmark diff --git a/vendor/benchmark-38df9da/src/thread_manager.h b/vendor/benchmark-4ed29ae/src/thread_manager.h similarity index 54% rename from vendor/benchmark-38df9da/src/thread_manager.h rename to vendor/benchmark-4ed29ae/src/thread_manager.h index 819b3c44d..a0ac37a8b 100644 --- a/vendor/benchmark-38df9da/src/thread_manager.h +++ b/vendor/benchmark-4ed29ae/src/thread_manager.h @@ -11,30 +11,15 @@ namespace internal { class ThreadManager { public: - explicit ThreadManager(int num_threads) - : alive_threads_(num_threads), start_stop_barrier_(num_threads) {} + explicit ThreadManager(int num_threads) : start_stop_barrier_(num_threads) {} Mutex& GetBenchmarkMutex() const RETURN_CAPABILITY(benchmark_mutex_) { return benchmark_mutex_; } - bool StartStopBarrier() EXCLUDES(end_cond_mutex_) { - return start_stop_barrier_.wait(); - } - - void NotifyThreadComplete() EXCLUDES(end_cond_mutex_) { - start_stop_barrier_.removeThread(); - if (--alive_threads_ == 0) { - MutexLock lock(end_cond_mutex_); - end_condition_.notify_all(); - } - } + bool StartStopBarrier() { return start_stop_barrier_.wait(); } - void WaitForAllThreads() EXCLUDES(end_cond_mutex_) { - MutexLock lock(end_cond_mutex_); - end_condition_.wait(lock.native_handle(), - [this]() { return alive_threads_ == 0; }); - } + void NotifyThreadComplete() { start_stop_barrier_.removeThread(); } struct Result { IterationCount iterations = 0; @@ -51,10 +36,7 @@ class ThreadManager { private: mutable Mutex benchmark_mutex_; - std::atomic alive_threads_; Barrier start_stop_barrier_; - Mutex end_cond_mutex_; - Condition end_condition_; }; } // namespace internal diff --git a/vendor/benchmark-38df9da/src/thread_timer.h b/vendor/benchmark-4ed29ae/src/thread_timer.h similarity index 100% rename from vendor/benchmark-38df9da/src/thread_timer.h rename to vendor/benchmark-4ed29ae/src/thread_timer.h diff --git a/vendor/benchmark-38df9da/src/timers.cc b/vendor/benchmark-4ed29ae/src/timers.cc similarity index 95% rename from vendor/benchmark-38df9da/src/timers.cc rename to vendor/benchmark-4ed29ae/src/timers.cc index 7ba540b88..f8d9560ed 100644 --- a/vendor/benchmark-38df9da/src/timers.cc +++ b/vendor/benchmark-4ed29ae/src/timers.cc @@ -107,8 +107,9 @@ double MakeTime(struct timespec const& ts) { } #endif -BENCHMARK_NORETURN static void DiagnoseAndExit(const char* msg) { - std::cerr << "ERROR: " << msg << std::endl; +BENCHMARK_NORETURN void DiagnoseAndExit(const char* msg) { + std::cerr << "ERROR: " << msg << '\n'; + std::flush(std::cerr); std::exit(EXIT_FAILURE); } @@ -142,9 +143,10 @@ double ProcessCPUUsage() { #elif defined(CLOCK_PROCESS_CPUTIME_ID) && !defined(BENCHMARK_OS_MACOSX) // FIXME We want to use clock_gettime, but its not available in MacOS 10.11. // See https://github.com/google/benchmark/pull/292 - struct timespec spec; - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &spec) == 0) + struct timespec spec {}; + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &spec) == 0) { return MakeTime(spec); + } DiagnoseAndExit("clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) failed"); #else struct rusage ru; @@ -198,8 +200,10 @@ double ThreadCPUUsage() { if (getrusage(RUSAGE_LWP, &ru) == 0) return MakeTime(ru); DiagnoseAndExit("getrusage(RUSAGE_LWP, ...) failed"); #elif defined(CLOCK_THREAD_CPUTIME_ID) - struct timespec ts; - if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0) return MakeTime(ts); + struct timespec ts {}; + if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0) { + return MakeTime(ts); + } DiagnoseAndExit("clock_gettime(CLOCK_THREAD_CPUTIME_ID, ...) failed"); #else #error Per-thread timing is not available on your system. @@ -213,9 +217,9 @@ std::string LocalDateTimeString() { const std::size_t kTzOffsetLen = 6; const std::size_t kTimestampLen = 19; - std::size_t tz_len; - std::size_t timestamp_len; - long int offset_minutes; + std::size_t tz_len = 0; + std::size_t timestamp_len = 0; + long int offset_minutes = 0; char tz_offset_sign = '+'; // tz_offset is set in one of three ways: // * strftime with %z - This either returns empty or the ISO 8601 time. The @@ -235,7 +239,7 @@ std::string LocalDateTimeString() { #if defined(BENCHMARK_OS_WINDOWS) std::tm* timeinfo_p = ::localtime(&now); #else - std::tm timeinfo; + std::tm timeinfo{}; std::tm* timeinfo_p = &timeinfo; ::localtime_r(&now, &timeinfo); #endif diff --git a/vendor/benchmark-38df9da/src/timers.h b/vendor/benchmark-4ed29ae/src/timers.h similarity index 100% rename from vendor/benchmark-38df9da/src/timers.h rename to vendor/benchmark-4ed29ae/src/timers.h diff --git a/vendor/benchmark-38df9da/test/AssemblyTests.cmake b/vendor/benchmark-4ed29ae/test/AssemblyTests.cmake similarity index 100% rename from vendor/benchmark-38df9da/test/AssemblyTests.cmake rename to vendor/benchmark-4ed29ae/test/AssemblyTests.cmake diff --git a/vendor/benchmark-38df9da/test/BUILD b/vendor/benchmark-4ed29ae/test/BUILD similarity index 89% rename from vendor/benchmark-38df9da/test/BUILD rename to vendor/benchmark-4ed29ae/test/BUILD index b245fa762..9a2697067 100644 --- a/vendor/benchmark-38df9da/test/BUILD +++ b/vendor/benchmark-4ed29ae/test/BUILD @@ -10,7 +10,7 @@ platform( TEST_COPTS = [ "-pedantic", "-pedantic-errors", - "-std=c++11", + "-std=c++17", "-Wall", "-Wconversion", "-Wextra", @@ -24,6 +24,10 @@ TEST_COPTS = [ "-Werror=old-style-cast", ] +TEST_MSVC_OPTS = [ + "/std:c++17", +] + # Some of the issues with DoNotOptimize only occur when optimization is enabled PER_SRC_COPTS = { "donotoptimize_test.cc": ["-O3"], @@ -45,7 +49,7 @@ cc_library( srcs = ["output_test_helper.cc"], hdrs = ["output_test.h"], copts = select({ - "//:windows": [], + "//:windows": TEST_MSVC_OPTS, "//conditions:default": TEST_COPTS, }), deps = [ @@ -61,7 +65,7 @@ cc_library( size = "small", srcs = [test_src], copts = select({ - "//:windows": [], + "//:windows": TEST_MSVC_OPTS, "//conditions:default": TEST_COPTS, }) + PER_SRC_COPTS.get(test_src, []), deps = [ @@ -82,7 +86,7 @@ cc_library( srcs = [test_src], args = TEST_ARGS + PER_SRC_TEST_ARGS.get(test_src, []), copts = select({ - "//:windows": [], + "//:windows": TEST_MSVC_OPTS, "//conditions:default": TEST_COPTS, }) + PER_SRC_COPTS.get(test_src, []), deps = [ @@ -98,25 +102,24 @@ cc_library( ["*_test.cc"], exclude = [ "*_assembly_test.cc", - "cxx03_test.cc", + "cxx11_test.cc", "link_main_test.cc", ], ) ] cc_test( - name = "cxx03_test", + name = "cxx11_test", size = "small", - srcs = ["cxx03_test.cc"], - copts = TEST_COPTS + ["-std=c++03"], + srcs = ["cxx11_test.cc"], + copts = TEST_COPTS + ["-std=c++11"], target_compatible_with = select({ "//:windows": ["@platforms//:incompatible"], "//conditions:default": [], }), deps = [ ":output_test_helper", - "//:benchmark", - "//:benchmark_internal_headers", + "//:benchmark_main", ], ) @@ -125,7 +128,7 @@ cc_test( size = "small", srcs = ["link_main_test.cc"], copts = select({ - "//:windows": [], + "//:windows": TEST_MSVC_OPTS, "//conditions:default": TEST_COPTS, }), deps = ["//:benchmark_main"], diff --git a/vendor/benchmark-38df9da/test/CMakeLists.txt b/vendor/benchmark-4ed29ae/test/CMakeLists.txt similarity index 88% rename from vendor/benchmark-38df9da/test/CMakeLists.txt rename to vendor/benchmark-4ed29ae/test/CMakeLists.txt index 1de175f98..8a1a1a968 100644 --- a/vendor/benchmark-38df9da/test/CMakeLists.txt +++ b/vendor/benchmark-4ed29ae/test/CMakeLists.txt @@ -1,4 +1,4 @@ -# Enable the tests +#Enable the tests set(THREADS_PREFER_PTHREAD_FLAG ON) @@ -73,6 +73,18 @@ macro(benchmark_add_test) endmacro(benchmark_add_test) # Demonstration executable + +compile_benchmark_test_with_main(cxx11_test) +if(DEFINED MSVC) + # MSVC does not really support C++11. + set_property(TARGET cxx11_test PROPERTY CXX_STANDARD 14) +else() + set_property(TARGET cxx11_test PROPERTY CXX_STANDARD 11) +endif() +set_property(TARGET cxx11_test PROPERTY CXX_STANDARD_REQUIRED ON) +set_property(TARGET cxx11_test PROPERTY CXX_EXTENSIONS OFF) +benchmark_add_test(NAME cxx11_test COMMAND cxx11_test --benchmark_min_time=0.01s) + compile_benchmark_test(benchmark_test) benchmark_add_test(NAME benchmark COMMAND benchmark_test --benchmark_min_time=0.01s) @@ -168,15 +180,24 @@ benchmark_add_test(NAME reporter_output_test COMMAND reporter_output_test --benc compile_output_test(templated_fixture_test) benchmark_add_test(NAME templated_fixture_test COMMAND templated_fixture_test --benchmark_min_time=0.01s) +compile_output_test(templated_fixture_method_test) +benchmark_add_test(NAME templated_fixture_method_test COMMAND templated_fixture_method_test --benchmark_min_time=0.01s) + compile_output_test(user_counters_test) benchmark_add_test(NAME user_counters_test COMMAND user_counters_test --benchmark_min_time=0.01s) +compile_output_test(user_counters_threads_test) +benchmark_add_test(NAME user_counters_threads_test COMMAND user_counters_threads_test --benchmark_min_time=0.01s) + compile_output_test(perf_counters_test) benchmark_add_test(NAME perf_counters_test COMMAND perf_counters_test --benchmark_min_time=0.01s --benchmark_perf_counters=CYCLES,INSTRUCTIONS) compile_output_test(internal_threading_test) benchmark_add_test(NAME internal_threading_test COMMAND internal_threading_test --benchmark_min_time=0.01s) +compile_output_test(manual_threading_test) +benchmark_add_test(NAME manual_threading_test COMMAND manual_threading_test --benchmark_min_time=0.01s) + compile_output_test(report_aggregates_only_test) benchmark_add_test(NAME report_aggregates_only_test COMMAND report_aggregates_only_test --benchmark_min_time=0.01s) @@ -192,35 +213,18 @@ benchmark_add_test(NAME user_counters_thousands_test COMMAND user_counters_thous compile_output_test(memory_manager_test) benchmark_add_test(NAME memory_manager_test COMMAND memory_manager_test --benchmark_min_time=0.01s) -# MSVC does not allow to set the language standard to C++98/03. -if(NOT (MSVC OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")) - compile_benchmark_test(cxx03_test) - set_target_properties(cxx03_test - PROPERTIES - CXX_STANDARD 98 - CXX_STANDARD_REQUIRED YES) - # libstdc++ provides different definitions within between dialects. When - # LTO is enabled and -Werror is specified GCC diagnoses this ODR violation - # causing the test to fail to compile. To prevent this we explicitly disable - # the warning. - check_cxx_compiler_flag(-Wno-odr BENCHMARK_HAS_WNO_ODR) - check_cxx_compiler_flag(-Wno-lto-type-mismatch BENCHMARK_HAS_WNO_LTO_TYPE_MISMATCH) - # Cannot set_target_properties multiple times here because the warnings will - # be overwritten on each call - set (DISABLE_LTO_WARNINGS "") - if (BENCHMARK_HAS_WNO_ODR) - set(DISABLE_LTO_WARNINGS "${DISABLE_LTO_WARNINGS} -Wno-odr") - endif() - if (BENCHMARK_HAS_WNO_LTO_TYPE_MISMATCH) - set(DISABLE_LTO_WARNINGS "${DISABLE_LTO_WARNINGS} -Wno-lto-type-mismatch") - endif() - set_target_properties(cxx03_test PROPERTIES LINK_FLAGS "${DISABLE_LTO_WARNINGS}") - benchmark_add_test(NAME cxx03 COMMAND cxx03_test --benchmark_min_time=0.01s) -endif() +compile_output_test(profiler_manager_test) +benchmark_add_test(NAME profiler_manager_test COMMAND profiler_manager_test --benchmark_min_time=0.01s) + +compile_benchmark_test(profiler_manager_iterations_test) +benchmark_add_test(NAME profiler_manager_iterations COMMAND profiler_manager_iterations_test) compile_output_test(complexity_test) benchmark_add_test(NAME complexity_benchmark COMMAND complexity_test --benchmark_min_time=1000000x) +compile_output_test(locale_impermeability_test) +benchmark_add_test(NAME locale_impermeability_test COMMAND locale_impermeability_test) + ############################################################################### # GoogleTest Unit Tests ############################################################################### @@ -251,6 +255,9 @@ if (BENCHMARK_ENABLE_GTEST_TESTS) add_gtest(perf_counters_gtest) add_gtest(time_unit_gtest) add_gtest(min_time_parse_gtest) + add_gtest(profiler_manager_gtest) + add_gtest(benchmark_setup_teardown_cb_types_gtest) + add_gtest(memory_results_gtest) endif(BENCHMARK_ENABLE_GTEST_TESTS) ############################################################################### @@ -292,7 +299,7 @@ if (${CMAKE_BUILD_TYPE_LOWER} MATCHES "coverage") COMMAND ${LCOV} -q -a before.lcov -a after.lcov --output-file final.lcov COMMAND ${LCOV} -q -r final.lcov "'${CMAKE_SOURCE_DIR}/test/*'" -o final.lcov COMMAND ${GENHTML} final.lcov -o lcov --demangle-cpp --sort -p "${CMAKE_BINARY_DIR}" -t benchmark - DEPENDS filter_test benchmark_test options_test basic_test fixture_test cxx03_test complexity_test + DEPENDS filter_test benchmark_test options_test basic_test fixture_test complexity_test WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Running LCOV" ) diff --git a/vendor/benchmark-38df9da/test/args_product_test.cc b/vendor/benchmark-4ed29ae/test/args_product_test.cc similarity index 100% rename from vendor/benchmark-38df9da/test/args_product_test.cc rename to vendor/benchmark-4ed29ae/test/args_product_test.cc diff --git a/vendor/benchmark-38df9da/test/basic_test.cc b/vendor/benchmark-4ed29ae/test/basic_test.cc similarity index 97% rename from vendor/benchmark-38df9da/test/basic_test.cc rename to vendor/benchmark-4ed29ae/test/basic_test.cc index c25bec7dd..068cd9847 100644 --- a/vendor/benchmark-38df9da/test/basic_test.cc +++ b/vendor/benchmark-4ed29ae/test/basic_test.cc @@ -3,9 +3,11 @@ #define BASIC_BENCHMARK_TEST(x) BENCHMARK(x)->Arg(8)->Arg(512)->Arg(8192) +namespace { void BM_empty(benchmark::State& state) { for (auto _ : state) { - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } } @@ -142,7 +144,6 @@ void BM_RangedFor(benchmark::State& state) { } BENCHMARK(BM_RangedFor); -#ifdef BENCHMARK_HAS_CXX11 template void BM_OneTemplateFunc(benchmark::State& state) { auto arg = state.range(0); @@ -167,8 +168,6 @@ void BM_TwoTemplateFunc(benchmark::State& state) { BENCHMARK(BM_TwoTemplateFunc)->Arg(1); BENCHMARK(BM_TwoTemplateFunc)->Arg(1); -#endif // BENCHMARK_HAS_CXX11 - // Ensure that StateIterator provides all the necessary typedefs required to // instantiate std::iterator_traits. static_assert( @@ -176,5 +175,6 @@ static_assert( benchmark::State::StateIterator>::value_type, typename benchmark::State::StateIterator::value_type>::value, ""); +} // end namespace BENCHMARK_MAIN(); diff --git a/vendor/benchmark-38df9da/test/benchmark_gtest.cc b/vendor/benchmark-4ed29ae/test/benchmark_gtest.cc similarity index 100% rename from vendor/benchmark-38df9da/test/benchmark_gtest.cc rename to vendor/benchmark-4ed29ae/test/benchmark_gtest.cc diff --git a/vendor/benchmark-38df9da/test/benchmark_min_time_flag_iters_test.cc b/vendor/benchmark-4ed29ae/test/benchmark_min_time_flag_iters_test.cc similarity index 72% rename from vendor/benchmark-38df9da/test/benchmark_min_time_flag_iters_test.cc rename to vendor/benchmark-4ed29ae/test/benchmark_min_time_flag_iters_test.cc index 3de93a750..dedcbe6fa 100644 --- a/vendor/benchmark-38df9da/test/benchmark_min_time_flag_iters_test.cc +++ b/vendor/benchmark-4ed29ae/test/benchmark_min_time_flag_iters_test.cc @@ -1,7 +1,6 @@ #include #include #include -#include #include #include @@ -13,11 +12,11 @@ namespace { class TestReporter : public benchmark::ConsoleReporter { public: - virtual bool ReportContext(const Context& context) BENCHMARK_OVERRIDE { + bool ReportContext(const Context& context) override { return ConsoleReporter::ReportContext(context); }; - virtual void ReportRuns(const std::vector& report) BENCHMARK_OVERRIDE { + void ReportRuns(const std::vector& report) override { assert(report.size() == 1); iter_nums_.push_back(report[0].iterations); ConsoleReporter::ReportRuns(report); @@ -25,7 +24,7 @@ class TestReporter : public benchmark::ConsoleReporter { TestReporter() {} - virtual ~TestReporter() {} + ~TestReporter() override {} const std::vector& GetIters() const { return iter_nums_; @@ -35,22 +34,26 @@ class TestReporter : public benchmark::ConsoleReporter { std::vector iter_nums_; }; -} // end namespace - -static void BM_MyBench(benchmark::State& state) { +void BM_MyBench(benchmark::State& state) { for (auto s : state) { } } +} // end namespace + BENCHMARK(BM_MyBench); int main(int argc, char** argv) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + // Make a fake argv and append the new --benchmark_min_time= to it. int fake_argc = argc + 1; - const char** fake_argv = new const char*[static_cast(fake_argc)]; - for (int i = 0; i < argc; ++i) fake_argv[i] = argv[i]; - fake_argv[argc] = "--benchmark_min_time=4x"; + std::vector fake_argv(static_cast(fake_argc)); + for (size_t i = 0; i < static_cast(argc); ++i) { + fake_argv[i] = argv[i]; + } + fake_argv[static_cast(argc)] = "--benchmark_min_time=4x"; - benchmark::Initialize(&fake_argc, const_cast(fake_argv)); + benchmark::Initialize(&fake_argc, const_cast(fake_argv.data())); TestReporter test_reporter; const size_t returned_count = @@ -61,6 +64,5 @@ int main(int argc, char** argv) { const std::vector iters = test_reporter.GetIters(); assert(!iters.empty() && iters[0] == 4); - delete[] fake_argv; return 0; } diff --git a/vendor/benchmark-38df9da/test/benchmark_min_time_flag_time_test.cc b/vendor/benchmark-4ed29ae/test/benchmark_min_time_flag_time_test.cc similarity index 69% rename from vendor/benchmark-38df9da/test/benchmark_min_time_flag_time_test.cc rename to vendor/benchmark-4ed29ae/test/benchmark_min_time_flag_time_test.cc index 04a82eb95..bbc2cc35d 100644 --- a/vendor/benchmark-38df9da/test/benchmark_min_time_flag_time_test.cc +++ b/vendor/benchmark-4ed29ae/test/benchmark_min_time_flag_time_test.cc @@ -19,23 +19,23 @@ typedef int64_t IterationCount; class TestReporter : public benchmark::ConsoleReporter { public: - virtual bool ReportContext(const Context& context) BENCHMARK_OVERRIDE { + bool ReportContext(const Context& context) override { return ConsoleReporter::ReportContext(context); }; - virtual void ReportRuns(const std::vector& report) BENCHMARK_OVERRIDE { + void ReportRuns(const std::vector& report) override { assert(report.size() == 1); ConsoleReporter::ReportRuns(report); }; - virtual void ReportRunsConfig(double min_time, bool /* has_explicit_iters */, - IterationCount /* iters */) BENCHMARK_OVERRIDE { + void ReportRunsConfig(double min_time, bool /* has_explicit_iters */, + IterationCount /* iters */) override { min_times_.push_back(min_time); } TestReporter() {} - virtual ~TestReporter() {} + ~TestReporter() override {} const std::vector& GetMinTimes() const { return min_times_; } @@ -60,31 +60,34 @@ void DoTestHelper(int* argc, const char** argv, double expected) { assert(!min_times.empty() && AlmostEqual(min_times[0], expected)); } -} // end namespace - -static void BM_MyBench(benchmark::State& state) { +void BM_MyBench(benchmark::State& state) { for (auto s : state) { } } BENCHMARK(BM_MyBench); +} // end namespace + int main(int argc, char** argv) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + // Make a fake argv and append the new --benchmark_min_time= to it. int fake_argc = argc + 1; - const char** fake_argv = new const char*[static_cast(fake_argc)]; + std::vector fake_argv(static_cast(fake_argc)); - for (int i = 0; i < argc; ++i) fake_argv[i] = argv[i]; + for (size_t i = 0; i < static_cast(argc); ++i) { + fake_argv[i] = argv[i]; + } const char* no_suffix = "--benchmark_min_time=4"; const char* with_suffix = "--benchmark_min_time=4.0s"; double expected = 4.0; - fake_argv[argc] = no_suffix; - DoTestHelper(&fake_argc, fake_argv, expected); + fake_argv[static_cast(argc)] = no_suffix; + DoTestHelper(&fake_argc, fake_argv.data(), expected); - fake_argv[argc] = with_suffix; - DoTestHelper(&fake_argc, fake_argv, expected); + fake_argv[static_cast(argc)] = with_suffix; + DoTestHelper(&fake_argc, fake_argv.data(), expected); - delete[] fake_argv; return 0; } diff --git a/vendor/benchmark-38df9da/test/benchmark_name_gtest.cc b/vendor/benchmark-4ed29ae/test/benchmark_name_gtest.cc similarity index 100% rename from vendor/benchmark-38df9da/test/benchmark_name_gtest.cc rename to vendor/benchmark-4ed29ae/test/benchmark_name_gtest.cc diff --git a/vendor/benchmark-38df9da/test/benchmark_random_interleaving_gtest.cc b/vendor/benchmark-4ed29ae/test/benchmark_random_interleaving_gtest.cc similarity index 95% rename from vendor/benchmark-38df9da/test/benchmark_random_interleaving_gtest.cc rename to vendor/benchmark-4ed29ae/test/benchmark_random_interleaving_gtest.cc index 7f2086750..5f3a55474 100644 --- a/vendor/benchmark-38df9da/test/benchmark_random_interleaving_gtest.cc +++ b/vendor/benchmark-4ed29ae/test/benchmark_random_interleaving_gtest.cc @@ -34,7 +34,8 @@ class EventQueue : public std::queue { } }; -EventQueue* queue = new EventQueue(); +// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) +EventQueue* const queue = new EventQueue(); class NullReporter : public BenchmarkReporter { public: @@ -48,7 +49,7 @@ class BenchmarkTest : public testing::Test { static void TeardownHook(int /* num_threads */) { queue->push("Teardown"); } - void Execute(const std::string& pattern) { + static void Execute(const std::string& pattern) { queue->Clear(); std::unique_ptr reporter(new NullReporter()); diff --git a/vendor/benchmark-4ed29ae/test/benchmark_setup_teardown_cb_types_gtest.cc b/vendor/benchmark-4ed29ae/test/benchmark_setup_teardown_cb_types_gtest.cc new file mode 100644 index 000000000..2ed255dcd --- /dev/null +++ b/vendor/benchmark-4ed29ae/test/benchmark_setup_teardown_cb_types_gtest.cc @@ -0,0 +1,126 @@ +#include "benchmark/benchmark.h" +#include "gtest/gtest.h" + +using benchmark::Benchmark; +using benchmark::BenchmarkReporter; +using benchmark::callback_function; +using benchmark::ClearRegisteredBenchmarks; +using benchmark::RegisterBenchmark; +using benchmark::RunSpecifiedBenchmarks; +using benchmark::State; + +static int functor_called = 0; +struct Functor { + void operator()(const benchmark::State& /*unused*/) { functor_called++; } +}; + +class NullReporter : public BenchmarkReporter { + public: + bool ReportContext(const Context& /*context*/) override { return true; } + void ReportRuns(const std::vector& /* report */) override {} +}; + +class BenchmarkTest : public testing::Test { + public: + Benchmark* bm; + NullReporter null_reporter; + + int setup_calls; + int teardown_calls; + + void SetUp() override { + setup_calls = 0; + teardown_calls = 0; + functor_called = 0; + + bm = RegisterBenchmark("BM", [](State& st) { + for (auto _ : st) { + } + }); + bm->Iterations(1); + } + + void TearDown() override { ClearRegisteredBenchmarks(); } +}; + +// Test that Setup/Teardown can correctly take a lambda expressions +TEST_F(BenchmarkTest, LambdaTestCopy) { + auto setup_lambda = [this](const State&) { setup_calls++; }; + auto teardown_lambda = [this](const State&) { teardown_calls++; }; + bm->Setup(setup_lambda); + bm->Teardown(teardown_lambda); + RunSpecifiedBenchmarks(&null_reporter); + EXPECT_EQ(setup_calls, 1); + EXPECT_EQ(teardown_calls, 1); +} + +// Test that Setup/Teardown can correctly take a lambda expressions +TEST_F(BenchmarkTest, LambdaTestMove) { + auto setup_lambda = [this](const State&) { setup_calls++; }; + auto teardown_lambda = [this](const State&) { teardown_calls++; }; + bm->Setup(std::move(setup_lambda)); + bm->Teardown(std::move(teardown_lambda)); + RunSpecifiedBenchmarks(&null_reporter); + EXPECT_EQ(setup_calls, 1); + EXPECT_EQ(teardown_calls, 1); +} + +// Test that Setup/Teardown can correctly take std::function +TEST_F(BenchmarkTest, CallbackFunctionCopy) { + callback_function setup_lambda = [this](const State&) { setup_calls++; }; + callback_function teardown_lambda = [this](const State&) { + teardown_calls++; + }; + bm->Setup(setup_lambda); + bm->Teardown(teardown_lambda); + RunSpecifiedBenchmarks(&null_reporter); + EXPECT_EQ(setup_calls, 1); + EXPECT_EQ(teardown_calls, 1); +} + +// Test that Setup/Teardown can correctly take std::function +TEST_F(BenchmarkTest, CallbackFunctionMove) { + callback_function setup_lambda = [this](const State&) { setup_calls++; }; + callback_function teardown_lambda = [this](const State&) { + teardown_calls++; + }; + bm->Setup(std::move(setup_lambda)); + bm->Teardown(std::move(teardown_lambda)); + RunSpecifiedBenchmarks(&null_reporter); + EXPECT_EQ(setup_calls, 1); + EXPECT_EQ(teardown_calls, 1); +} + +// Test that Setup/Teardown can correctly take functors +TEST_F(BenchmarkTest, FunctorCopy) { + Functor func; + bm->Setup(func); + bm->Teardown(func); + RunSpecifiedBenchmarks(&null_reporter); + EXPECT_EQ(functor_called, 2); +} + +// Test that Setup/Teardown can correctly take functors +TEST_F(BenchmarkTest, FunctorMove) { + Functor func1; + Functor func2; + bm->Setup(std::move(func1)); + bm->Teardown(std::move(func2)); + RunSpecifiedBenchmarks(&null_reporter); + EXPECT_EQ(functor_called, 2); +} + +// Test that Setup/Teardown can not take nullptr +TEST_F(BenchmarkTest, NullptrTest) { +#if GTEST_HAS_DEATH_TEST + // Tests only runnable in debug mode (when BM_CHECK is enabled). +#ifndef NDEBUG +#ifndef TEST_BENCHMARK_LIBRARY_HAS_NO_ASSERTIONS + EXPECT_DEATH(bm->Setup(nullptr), "setup != nullptr"); + EXPECT_DEATH(bm->Teardown(nullptr), "teardown != nullptr"); +#else + GTEST_SKIP() << "Test skipped because BM_CHECK is disabled"; +#endif +#endif +#endif +} diff --git a/vendor/benchmark-38df9da/test/benchmark_setup_teardown_test.cc b/vendor/benchmark-4ed29ae/test/benchmark_setup_teardown_test.cc similarity index 88% rename from vendor/benchmark-38df9da/test/benchmark_setup_teardown_test.cc rename to vendor/benchmark-4ed29ae/test/benchmark_setup_teardown_test.cc index 6c3cc2e58..eb45a73e9 100644 --- a/vendor/benchmark-38df9da/test/benchmark_setup_teardown_test.cc +++ b/vendor/benchmark-4ed29ae/test/benchmark_setup_teardown_test.cc @@ -2,18 +2,18 @@ #include #include #include -#include -#include #include #include "benchmark/benchmark.h" // Test that Setup() and Teardown() are called exactly once // for each benchmark run (single-threaded). +namespace { namespace singlethreaded { static int setup_call = 0; static int teardown_call = 0; } // namespace singlethreaded +} // namespace static void DoSetup1(const benchmark::State& state) { ++singlethreaded::setup_call; @@ -40,23 +40,24 @@ BENCHMARK(BM_with_setup) ->Teardown(DoTeardown1); // Test that Setup() and Teardown() are called once for each group of threads. +namespace { namespace concurrent { static std::atomic setup_call(0); static std::atomic teardown_call(0); static std::atomic func_call(0); } // namespace concurrent -static void DoSetup2(const benchmark::State& state) { +void DoSetup2(const benchmark::State& state) { concurrent::setup_call.fetch_add(1, std::memory_order_acquire); assert(state.thread_index() == 0); } -static void DoTeardown2(const benchmark::State& state) { +void DoTeardown2(const benchmark::State& state) { concurrent::teardown_call.fetch_add(1, std::memory_order_acquire); assert(state.thread_index() == 0); } -static void BM_concurrent(benchmark::State& state) { +void BM_concurrent(benchmark::State& state) { for (auto s : state) { } concurrent::func_call.fetch_add(1, std::memory_order_acquire); @@ -80,7 +81,7 @@ int fixture_setup = 0; class FIXTURE_BECHMARK_NAME : public ::benchmark::Fixture { public: - void SetUp(const ::benchmark::State&) override { + void SetUp(const ::benchmark::State& /*unused*/) override { fixture_interaction::fixture_setup++; } @@ -92,7 +93,7 @@ BENCHMARK_F(FIXTURE_BECHMARK_NAME, BM_WithFixture)(benchmark::State& st) { } } -static void DoSetupWithFixture(const benchmark::State&) { +void DoSetupWithFixture(const benchmark::State& /*unused*/) { fixture_interaction::setup++; } @@ -110,10 +111,10 @@ namespace repetitions { int setup = 0; } -static void DoSetupWithRepetitions(const benchmark::State&) { +void DoSetupWithRepetitions(const benchmark::State& /*unused*/) { repetitions::setup++; } -static void BM_WithRep(benchmark::State& state) { +void BM_WithRep(benchmark::State& state) { for (auto _ : state) { } } @@ -126,8 +127,11 @@ BENCHMARK(BM_WithRep) ->Setup(DoSetupWithRepetitions) ->Iterations(100) ->Repetitions(4); +} // namespace int main(int argc, char** argv) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + benchmark::Initialize(&argc, argv); size_t ret = benchmark::RunSpecifiedBenchmarks("."); diff --git a/vendor/benchmark-38df9da/test/benchmark_test.cc b/vendor/benchmark-4ed29ae/test/benchmark_test.cc similarity index 83% rename from vendor/benchmark-38df9da/test/benchmark_test.cc rename to vendor/benchmark-4ed29ae/test/benchmark_test.cc index 8b14017d0..49cbfba6f 100644 --- a/vendor/benchmark-38df9da/test/benchmark_test.cc +++ b/vendor/benchmark-4ed29ae/test/benchmark_test.cc @@ -8,10 +8,9 @@ #include #include #include -#include #include -#include #include +#include #include #include #include @@ -44,18 +43,22 @@ double CalculatePi(int depth) { std::set ConstructRandomSet(int64_t size) { std::set s; - for (int i = 0; i < size; ++i) s.insert(s.end(), i); + for (int i = 0; i < size; ++i) { + s.insert(s.end(), i); + } return s; } +// NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables) std::mutex test_vector_mu; -std::vector* test_vector = nullptr; - -} // end namespace +std::optional> test_vector; +// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables) -static void BM_Factorial(benchmark::State& state) { +void BM_Factorial(benchmark::State& state) { int fac_42 = 0; - for (auto _ : state) fac_42 = Factorial(8); + for (auto _ : state) { + fac_42 = Factorial(8); + } // Prevent compiler optimizations std::stringstream ss; ss << fac_42; @@ -64,16 +67,18 @@ static void BM_Factorial(benchmark::State& state) { BENCHMARK(BM_Factorial); BENCHMARK(BM_Factorial)->UseRealTime(); -static void BM_CalculatePiRange(benchmark::State& state) { +void BM_CalculatePiRange(benchmark::State& state) { double pi = 0.0; - for (auto _ : state) pi = CalculatePi(static_cast(state.range(0))); + for (auto _ : state) { + pi = CalculatePi(static_cast(state.range(0))); + } std::stringstream ss; ss << pi; state.SetLabel(ss.str()); } BENCHMARK_RANGE(BM_CalculatePiRange, 1, 1024 * 1024); -static void BM_CalculatePi(benchmark::State& state) { +void BM_CalculatePi(benchmark::State& state) { static const int depth = 1024; for (auto _ : state) { double pi = CalculatePi(static_cast(depth)); @@ -84,13 +89,15 @@ BENCHMARK(BM_CalculatePi)->Threads(8); BENCHMARK(BM_CalculatePi)->ThreadRange(1, 32); BENCHMARK(BM_CalculatePi)->ThreadPerCpu(); -static void BM_SetInsert(benchmark::State& state) { +void BM_SetInsert(benchmark::State& state) { std::set data; for (auto _ : state) { state.PauseTiming(); data = ConstructRandomSet(state.range(0)); state.ResumeTiming(); - for (int j = 0; j < state.range(1); ++j) data.insert(rand()); + for (int j = 0; j < state.range(1); ++j) { + data.insert(rand()); + } } state.SetItemsProcessed(state.iterations() * state.range(1)); state.SetBytesProcessed(state.iterations() * state.range(1) * @@ -104,11 +111,13 @@ BENCHMARK(BM_SetInsert)->Ranges({{1 << 10, 8 << 10}, {128, 512}}); template -static void BM_Sequential(benchmark::State& state) { +void BM_Sequential(benchmark::State& state) { ValueType v = 42; for (auto _ : state) { Container c; - for (int64_t i = state.range(0); --i;) c.push_back(v); + for (int64_t i = state.range(0); --i;) { + c.push_back(v); + } } const int64_t items_processed = state.iterations() * state.range(0); state.SetItemsProcessed(items_processed); @@ -118,11 +127,9 @@ BENCHMARK_TEMPLATE2(BM_Sequential, std::vector, int) ->Range(1 << 0, 1 << 10); BENCHMARK_TEMPLATE(BM_Sequential, std::list)->Range(1 << 0, 1 << 10); // Test the variadic version of BENCHMARK_TEMPLATE in C++11 and beyond. -#ifdef BENCHMARK_HAS_CXX11 BENCHMARK_TEMPLATE(BM_Sequential, std::vector, int)->Arg(512); -#endif -static void BM_StringCompare(benchmark::State& state) { +void BM_StringCompare(benchmark::State& state) { size_t len = static_cast(state.range(0)); std::string s1(len, '-'); std::string s2(len, '-'); @@ -133,43 +140,45 @@ static void BM_StringCompare(benchmark::State& state) { } BENCHMARK(BM_StringCompare)->Range(1, 1 << 20); -static void BM_SetupTeardown(benchmark::State& state) { +void BM_SetupTeardown(benchmark::State& state) { if (state.thread_index() == 0) { // No need to lock test_vector_mu here as this is running single-threaded. - test_vector = new std::vector(); + test_vector = std::vector(); } int i = 0; for (auto _ : state) { std::lock_guard l(test_vector_mu); - if (i % 2 == 0) + if (i % 2 == 0) { test_vector->push_back(i); - else + } else { test_vector->pop_back(); + } ++i; } if (state.thread_index() == 0) { - delete test_vector; + test_vector.reset(); } } BENCHMARK(BM_SetupTeardown)->ThreadPerCpu(); -static void BM_LongTest(benchmark::State& state) { +void BM_LongTest(benchmark::State& state) { double tracker = 0.0; for (auto _ : state) { - for (int i = 0; i < state.range(0); ++i) + for (int i = 0; i < state.range(0); ++i) { benchmark::DoNotOptimize(tracker += i); + } } } BENCHMARK(BM_LongTest)->Range(1 << 16, 1 << 28); -static void BM_ParallelMemset(benchmark::State& state) { +void BM_ParallelMemset(benchmark::State& state) { int64_t size = state.range(0) / static_cast(sizeof(int)); int thread_size = static_cast(size) / state.threads(); int from = thread_size * state.thread_index(); int to = from + thread_size; if (state.thread_index() == 0) { - test_vector = new std::vector(static_cast(size)); + test_vector = std::vector(static_cast(size)); } for (auto _ : state) { @@ -181,12 +190,12 @@ static void BM_ParallelMemset(benchmark::State& state) { } if (state.thread_index() == 0) { - delete test_vector; + test_vector.reset(); } } BENCHMARK(BM_ParallelMemset)->Arg(10 << 20)->ThreadRange(1, 4); -static void BM_ManualTiming(benchmark::State& state) { +void BM_ManualTiming(benchmark::State& state) { int64_t slept_for = 0; int64_t microseconds = state.range(0); std::chrono::duration sleep_duration{ @@ -210,8 +219,6 @@ static void BM_ManualTiming(benchmark::State& state) { BENCHMARK(BM_ManualTiming)->Range(1, 1 << 14)->UseRealTime(); BENCHMARK(BM_ManualTiming)->Range(1, 1 << 14)->UseManualTime(); -#ifdef BENCHMARK_HAS_CXX11 - template void BM_with_args(benchmark::State& state, Args&&...) { for (auto _ : state) { @@ -252,9 +259,7 @@ void BM_template1_capture(benchmark::State& state, ExtraArgs&&... extra_args) { BENCHMARK_TEMPLATE1_CAPTURE(BM_template1_capture, void, foo, 24UL); BENCHMARK_CAPTURE(BM_template1_capture, foo, 24UL); -#endif // BENCHMARK_HAS_CXX11 - -static void BM_DenseThreadRanges(benchmark::State& st) { +void BM_DenseThreadRanges(benchmark::State& st) { switch (st.range(0)) { case 1: assert(st.threads() == 1 || st.threads() == 2 || st.threads() == 3); @@ -276,7 +281,7 @@ BENCHMARK(BM_DenseThreadRanges)->Arg(1)->DenseThreadRange(1, 3); BENCHMARK(BM_DenseThreadRanges)->Arg(2)->DenseThreadRange(1, 4, 2); BENCHMARK(BM_DenseThreadRanges)->Arg(3)->DenseThreadRange(5, 14, 3); -static void BM_BenchmarkName(benchmark::State& state) { +void BM_BenchmarkName(benchmark::State& state) { for (auto _ : state) { } @@ -287,14 +292,15 @@ BENCHMARK(BM_BenchmarkName); // regression test for #1446 template -static void BM_templated_test(benchmark::State& state) { +void BM_templated_test(benchmark::State& state) { for (auto _ : state) { type created_string; benchmark::DoNotOptimize(created_string); } } -static auto BM_templated_test_double = BM_templated_test>; +const auto BM_templated_test_double = BM_templated_test>; BENCHMARK(BM_templated_test_double); +} // end namespace BENCHMARK_MAIN(); diff --git a/vendor/benchmark-38df9da/test/clobber_memory_assembly_test.cc b/vendor/benchmark-4ed29ae/test/clobber_memory_assembly_test.cc similarity index 100% rename from vendor/benchmark-38df9da/test/clobber_memory_assembly_test.cc rename to vendor/benchmark-4ed29ae/test/clobber_memory_assembly_test.cc diff --git a/vendor/benchmark-38df9da/test/commandlineflags_gtest.cc b/vendor/benchmark-4ed29ae/test/commandlineflags_gtest.cc similarity index 100% rename from vendor/benchmark-38df9da/test/commandlineflags_gtest.cc rename to vendor/benchmark-4ed29ae/test/commandlineflags_gtest.cc diff --git a/vendor/benchmark-38df9da/test/complexity_test.cc b/vendor/benchmark-4ed29ae/test/complexity_test.cc similarity index 84% rename from vendor/benchmark-38df9da/test/complexity_test.cc rename to vendor/benchmark-4ed29ae/test/complexity_test.cc index 0729d15aa..8cf17f41d 100644 --- a/vendor/benchmark-38df9da/test/complexity_test.cc +++ b/vendor/benchmark-4ed29ae/test/complexity_test.cc @@ -1,5 +1,4 @@ #undef NDEBUG -#include #include #include #include @@ -11,12 +10,12 @@ namespace { #define ADD_COMPLEXITY_CASES(...) \ - int CONCAT(dummy, __LINE__) = AddComplexityTest(__VA_ARGS__) + const int CONCAT(dummy, __LINE__) = AddComplexityTest(__VA_ARGS__) -int AddComplexityTest(const std::string &test_name, - const std::string &big_o_test_name, - const std::string &rms_test_name, - const std::string &big_o, int family_index) { +int AddComplexityTest(const std::string& test_name, + const std::string& big_o_test_name, + const std::string& rms_test_name, + const std::string& big_o, int family_index) { SetSubstitutions({{"%name", test_name}, {"%bigo_name", big_o_test_name}, {"%rms_name", rms_test_name}, @@ -61,13 +60,11 @@ int AddComplexityTest(const std::string &test_name, return 0; } -} // end namespace - // ========================================================================= // // --------------------------- Testing BigO O(1) --------------------------- // // ========================================================================= // -void BM_Complexity_O1(benchmark::State &state) { +void BM_Complexity_O1(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero benchmark::DoNotOptimize(state.iterations()); @@ -94,11 +91,11 @@ BENCHMARK(BM_Complexity_O1) ->UseManualTime() ->Complexity([](benchmark::IterationCount) { return 1.0; }); -const char *one_test_name = "BM_Complexity_O1/manual_time"; -const char *big_o_1_test_name = "BM_Complexity_O1/manual_time_BigO"; -const char *rms_o_1_test_name = "BM_Complexity_O1/manual_time_RMS"; -const char *enum_auto_big_o_1 = "\\([0-9]+\\)"; -const char *lambda_big_o_1 = "f\\(N\\)"; +constexpr char one_test_name[] = "BM_Complexity_O1/manual_time"; +constexpr char big_o_1_test_name[] = "BM_Complexity_O1/manual_time_BigO"; +constexpr char rms_o_1_test_name[] = "BM_Complexity_O1/manual_time_RMS"; +constexpr char enum_auto_big_o_1[] = "\\([0-9]+\\)"; +constexpr char lambda_big_o_1[] = "f\\(N\\)"; // Add enum tests ADD_COMPLEXITY_CASES(one_test_name, big_o_1_test_name, rms_o_1_test_name, @@ -116,7 +113,7 @@ ADD_COMPLEXITY_CASES(one_test_name, big_o_1_test_name, rms_o_1_test_name, // --------------------------- Testing BigO O(N) --------------------------- // // ========================================================================= // -void BM_Complexity_O_N(benchmark::State &state) { +void BM_Complexity_O_N(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero benchmark::DoNotOptimize(state.iterations()); @@ -151,11 +148,11 @@ BENCHMARK(BM_Complexity_O_N) return static_cast(n); }); -const char *n_test_name = "BM_Complexity_O_N/manual_time"; -const char *big_o_n_test_name = "BM_Complexity_O_N/manual_time_BigO"; -const char *rms_o_n_test_name = "BM_Complexity_O_N/manual_time_RMS"; -const char *enum_auto_big_o_n = "N"; -const char *lambda_big_o_n = "f\\(N\\)"; +constexpr char n_test_name[] = "BM_Complexity_O_N/manual_time"; +constexpr char big_o_n_test_name[] = "BM_Complexity_O_N/manual_time_BigO"; +constexpr char rms_o_n_test_name[] = "BM_Complexity_O_N/manual_time_RMS"; +constexpr char enum_auto_big_o_n[] = "N"; +constexpr char lambda_big_o_n[] = "f\\(N\\)"; // Add enum tests ADD_COMPLEXITY_CASES(n_test_name, big_o_n_test_name, rms_o_n_test_name, @@ -173,8 +170,8 @@ ADD_COMPLEXITY_CASES(n_test_name, big_o_n_test_name, rms_o_n_test_name, // ------------------------- Testing BigO O(NlgN) ------------------------- // // ========================================================================= // -static const double kLog2E = 1.44269504088896340736; -static void BM_Complexity_O_N_log_N(benchmark::State &state) { +const double kLog2E = 1.44269504088896340736; +void BM_Complexity_O_N_log_N(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero benchmark::DoNotOptimize(state.iterations()); @@ -209,11 +206,13 @@ BENCHMARK(BM_Complexity_O_N_log_N) return kLog2E * static_cast(n) * std::log(static_cast(n)); }); -const char *n_lg_n_test_name = "BM_Complexity_O_N_log_N/manual_time"; -const char *big_o_n_lg_n_test_name = "BM_Complexity_O_N_log_N/manual_time_BigO"; -const char *rms_o_n_lg_n_test_name = "BM_Complexity_O_N_log_N/manual_time_RMS"; -const char *enum_auto_big_o_n_lg_n = "NlgN"; -const char *lambda_big_o_n_lg_n = "f\\(N\\)"; +constexpr char n_lg_n_test_name[] = "BM_Complexity_O_N_log_N/manual_time"; +constexpr char big_o_n_lg_n_test_name[] = + "BM_Complexity_O_N_log_N/manual_time_BigO"; +constexpr char rms_o_n_lg_n_test_name[] = + "BM_Complexity_O_N_log_N/manual_time_RMS"; +constexpr char enum_auto_big_o_n_lg_n[] = "NlgN"; +constexpr char lambda_big_o_n_lg_n[] = "f\\(N\\)"; // Add enum tests ADD_COMPLEXITY_CASES(n_lg_n_test_name, big_o_n_lg_n_test_name, @@ -234,7 +233,7 @@ ADD_COMPLEXITY_CASES(n_lg_n_test_name, big_o_n_lg_n_test_name, // -------- Testing formatting of Complexity with captured args ------------ // // ========================================================================= // -void BM_ComplexityCaptureArgs(benchmark::State &state, int n) { +void BM_ComplexityCaptureArgs(benchmark::State& state, int n) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero benchmark::DoNotOptimize(state.iterations()); @@ -262,9 +261,13 @@ const std::string complexity_capture_name = ADD_COMPLEXITY_CASES(complexity_capture_name, complexity_capture_name + "_BigO", complexity_capture_name + "_RMS", "N", /*family_index=*/9); +} // end namespace // ========================================================================= // // --------------------------- TEST CASES END ------------------------------ // // ========================================================================= // -int main(int argc, char *argv[]) { RunOutputTests(argc, argv); } +int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + RunOutputTests(argc, argv); +} diff --git a/vendor/benchmark-4ed29ae/test/cxx11_test.cc b/vendor/benchmark-4ed29ae/test/cxx11_test.cc new file mode 100644 index 000000000..db1a99334 --- /dev/null +++ b/vendor/benchmark-4ed29ae/test/cxx11_test.cc @@ -0,0 +1,12 @@ +#include "benchmark/benchmark.h" + +#if defined(_MSC_VER) +#if _MSVC_LANG != 201402L +// MSVC, even in C++11 mode, dooes not claim to be in C++11 mode. +#error "Trying to compile C++11 test with wrong C++ standard" +#endif // _MSVC_LANG +#else // Non-MSVC +#if __cplusplus != 201103L +#error "Trying to compile C++11 test with wrong C++ standard" +#endif // Non-MSVC +#endif diff --git a/vendor/benchmark-38df9da/test/diagnostics_test.cc b/vendor/benchmark-4ed29ae/test/diagnostics_test.cc similarity index 74% rename from vendor/benchmark-38df9da/test/diagnostics_test.cc rename to vendor/benchmark-4ed29ae/test/diagnostics_test.cc index 7c68a9892..e8d7d9119 100644 --- a/vendor/benchmark-38df9da/test/diagnostics_test.cc +++ b/vendor/benchmark-4ed29ae/test/diagnostics_test.cc @@ -17,6 +17,7 @@ #define TEST_HAS_NO_EXCEPTIONS #endif +namespace { void TestHandler() { #ifndef TEST_HAS_NO_EXCEPTIONS throw std::logic_error(""); @@ -46,14 +47,19 @@ void try_invalid_pause_resume(benchmark::State& state) { void BM_diagnostic_test(benchmark::State& state) { static bool called_once = false; - if (called_once == false) try_invalid_pause_resume(state); + if (!called_once) { + try_invalid_pause_resume(state); + } for (auto _ : state) { - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } - if (called_once == false) try_invalid_pause_resume(state); + if (!called_once) { + try_invalid_pause_resume(state); + } called_once = true; } @@ -62,28 +68,35 @@ BENCHMARK(BM_diagnostic_test); void BM_diagnostic_test_keep_running(benchmark::State& state) { static bool called_once = false; - if (called_once == false) try_invalid_pause_resume(state); + if (!called_once) { + try_invalid_pause_resume(state); + } while (state.KeepRunning()) { - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } - if (called_once == false) try_invalid_pause_resume(state); + if (!called_once) { + try_invalid_pause_resume(state); + } called_once = true; } BENCHMARK(BM_diagnostic_test_keep_running); +} // end namespace int main(int argc, char* argv[]) { #ifdef NDEBUG // This test is exercising functionality for debug builds, which are not // available in release builds. Skip the test if we are in that environment // to avoid a test failure. - std::cout << "Diagnostic test disabled in release build" << std::endl; + std::cout << "Diagnostic test disabled in release build\n"; (void)argc; (void)argv; #else + benchmark::MaybeReenterWithoutASLR(argc, argv); benchmark::internal::GetAbortHandler() = &TestHandler; benchmark::Initialize(&argc, argv); benchmark::RunSpecifiedBenchmarks(); diff --git a/vendor/benchmark-38df9da/test/display_aggregates_only_test.cc b/vendor/benchmark-4ed29ae/test/display_aggregates_only_test.cc similarity index 95% rename from vendor/benchmark-38df9da/test/display_aggregates_only_test.cc rename to vendor/benchmark-4ed29ae/test/display_aggregates_only_test.cc index 6ad65e7f5..bae97593a 100644 --- a/vendor/benchmark-38df9da/test/display_aggregates_only_test.cc +++ b/vendor/benchmark-4ed29ae/test/display_aggregates_only_test.cc @@ -10,13 +10,17 @@ // reporter in the presence of DisplayAggregatesOnly(). // We do not care about console output, the normal tests check that already. +namespace { void BM_SummaryRepeat(benchmark::State& state) { for (auto _ : state) { } } BENCHMARK(BM_SummaryRepeat)->Repetitions(3)->DisplayAggregatesOnly(); +} // end namespace int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + const std::string output = GetFileReporterOutput(argc, argv); if (SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3") != 7 || diff --git a/vendor/benchmark-38df9da/test/donotoptimize_assembly_test.cc b/vendor/benchmark-4ed29ae/test/donotoptimize_assembly_test.cc similarity index 97% rename from vendor/benchmark-38df9da/test/donotoptimize_assembly_test.cc rename to vendor/benchmark-4ed29ae/test/donotoptimize_assembly_test.cc index dc286f53e..1f817e02b 100644 --- a/vendor/benchmark-38df9da/test/donotoptimize_assembly_test.cc +++ b/vendor/benchmark-4ed29ae/test/donotoptimize_assembly_test.cc @@ -2,6 +2,7 @@ #ifdef __clang__ #pragma clang diagnostic ignored "-Wreturn-type" +#pragma clang diagnostic ignored "-Wmissing-prototypes" #endif BENCHMARK_DISABLE_DEPRECATED_WARNING @@ -19,7 +20,7 @@ inline int Add42(int x) { return x + 42; } struct NotTriviallyCopyable { NotTriviallyCopyable(); explicit NotTriviallyCopyable(int x) : value(x) {} - NotTriviallyCopyable(NotTriviallyCopyable const &); + NotTriviallyCopyable(NotTriviallyCopyable const&); int value; }; @@ -185,7 +186,7 @@ extern "C" void test_pointer_const_lvalue() { // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z]+]]) // CHECK: ret int x = 42; - int *const xp = &x; + int* const xp = &x; benchmark::DoNotOptimize(xp); } @@ -196,6 +197,6 @@ extern "C" void test_pointer_lvalue() { // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z+]+]]) // CHECK: ret int x = 42; - int *xp = &x; + int* xp = &x; benchmark::DoNotOptimize(xp); } diff --git a/vendor/benchmark-38df9da/test/donotoptimize_test.cc b/vendor/benchmark-4ed29ae/test/donotoptimize_test.cc similarity index 90% rename from vendor/benchmark-38df9da/test/donotoptimize_test.cc rename to vendor/benchmark-4ed29ae/test/donotoptimize_test.cc index 04ec9386a..7571cf445 100644 --- a/vendor/benchmark-38df9da/test/donotoptimize_test.cc +++ b/vendor/benchmark-4ed29ae/test/donotoptimize_test.cc @@ -4,7 +4,7 @@ namespace { #if defined(__GNUC__) -std::int64_t double_up(const std::int64_t x) __attribute__((const)); +std::int64_t double_up(std::int64_t x) __attribute__((const)); #endif std::int64_t double_up(const std::int64_t x) { return x * 2; } } // namespace @@ -26,7 +26,9 @@ struct BitRef { BitRef(int i, unsigned char& b) : index(i), byte(b) {} }; -int main(int, char*[]) { +int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + // this test verifies compilation of DoNotOptimize() for some types char buffer1[1] = ""; @@ -62,8 +64,6 @@ int main(int, char*[]) { BitRef lval = BitRef::Make(); benchmark::DoNotOptimize(lval); -#ifdef BENCHMARK_HAS_CXX11 // Check that accept rvalue. benchmark::DoNotOptimize(BitRef::Make()); -#endif } diff --git a/vendor/benchmark-38df9da/test/filter_test.cc b/vendor/benchmark-4ed29ae/test/filter_test.cc similarity index 85% rename from vendor/benchmark-38df9da/test/filter_test.cc rename to vendor/benchmark-4ed29ae/test/filter_test.cc index 4c8b8ea48..8c150eb2d 100644 --- a/vendor/benchmark-38df9da/test/filter_test.cc +++ b/vendor/benchmark-4ed29ae/test/filter_test.cc @@ -37,43 +37,45 @@ class TestReporter : public benchmark::ConsoleReporter { mutable int64_t max_family_index_; }; -} // end namespace - -static void NoPrefix(benchmark::State& state) { +void NoPrefix(benchmark::State& state) { for (auto _ : state) { } } BENCHMARK(NoPrefix); -static void BM_Foo(benchmark::State& state) { +void BM_Foo(benchmark::State& state) { for (auto _ : state) { } } BENCHMARK(BM_Foo); -static void BM_Bar(benchmark::State& state) { +void BM_Bar(benchmark::State& state) { for (auto _ : state) { } } BENCHMARK(BM_Bar); -static void BM_FooBar(benchmark::State& state) { +void BM_FooBar(benchmark::State& state) { for (auto _ : state) { } } BENCHMARK(BM_FooBar); -static void BM_FooBa(benchmark::State& state) { +void BM_FooBa(benchmark::State& state) { for (auto _ : state) { } } BENCHMARK(BM_FooBa); +} // end namespace int main(int argc, char** argv) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + bool list_only = false; - for (int i = 0; i < argc; ++i) + for (int i = 0; i < argc; ++i) { list_only |= std::string(argv[i]).find("--benchmark_list_tests") != std::string::npos; + } benchmark::Initialize(&argc, argv); @@ -84,13 +86,13 @@ int main(int argc, char** argv) { if (argc == 2) { // Make sure we ran all of the tests std::stringstream ss(argv[1]); - int64_t expected_return; + int64_t expected_return = 0; ss >> expected_return; if (returned_count != expected_return) { std::cerr << "ERROR: Expected " << expected_return << " tests to match the filter but returned_count = " - << returned_count << std::endl; + << returned_count << '\n'; return -1; } @@ -99,7 +101,7 @@ int main(int argc, char** argv) { if (reports_count != expected_reports) { std::cerr << "ERROR: Expected " << expected_reports << " tests to be run but reported_count = " << reports_count - << std::endl; + << '\n'; return -1; } @@ -108,7 +110,7 @@ int main(int argc, char** argv) { if (num_families != expected_reports) { std::cerr << "ERROR: Expected " << expected_reports << " test families to be run but num_families = " - << num_families << std::endl; + << num_families << '\n'; return -1; } } diff --git a/vendor/benchmark-38df9da/test/fixture_test.cc b/vendor/benchmark-4ed29ae/test/fixture_test.cc similarity index 100% rename from vendor/benchmark-38df9da/test/fixture_test.cc rename to vendor/benchmark-4ed29ae/test/fixture_test.cc diff --git a/vendor/benchmark-38df9da/test/internal_threading_test.cc b/vendor/benchmark-4ed29ae/test/internal_threading_test.cc similarity index 95% rename from vendor/benchmark-38df9da/test/internal_threading_test.cc rename to vendor/benchmark-4ed29ae/test/internal_threading_test.cc index 62b5b955a..c57bf44b0 100644 --- a/vendor/benchmark-38df9da/test/internal_threading_test.cc +++ b/vendor/benchmark-4ed29ae/test/internal_threading_test.cc @@ -8,8 +8,9 @@ #include "benchmark/benchmark.h" #include "output_test.h" -static const std::chrono::duration time_frame(50); -static const double time_frame_in_sec( +namespace { +const std::chrono::duration time_frame(50); +const double time_frame_in_sec( std::chrono::duration_cast>>( time_frame) .count()); @@ -22,8 +23,9 @@ void MyBusySpinwait() { const auto elapsed = now - start; if (std::chrono::duration(elapsed) >= - time_frame) + time_frame) { return; + } } } @@ -177,9 +179,14 @@ BENCHMARK(BM_MainThreadAndWorkerThread) ->Threads(2) ->MeasureProcessCPUTime() ->UseManualTime(); +} // end namespace // ========================================================================= // // ---------------------------- TEST CASES END ----------------------------- // // ========================================================================= // -int main(int argc, char* argv[]) { RunOutputTests(argc, argv); } +int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + + RunOutputTests(argc, argv); +} diff --git a/vendor/benchmark-38df9da/test/link_main_test.cc b/vendor/benchmark-4ed29ae/test/link_main_test.cc similarity index 51% rename from vendor/benchmark-38df9da/test/link_main_test.cc rename to vendor/benchmark-4ed29ae/test/link_main_test.cc index 131937eeb..41dbac9ab 100644 --- a/vendor/benchmark-38df9da/test/link_main_test.cc +++ b/vendor/benchmark-4ed29ae/test/link_main_test.cc @@ -1,9 +1,12 @@ #include "benchmark/benchmark.h" +namespace { void BM_empty(benchmark::State& state) { for (auto _ : state) { - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } } BENCHMARK(BM_empty); +} // end namespace diff --git a/vendor/benchmark-4ed29ae/test/locale_impermeability_test.cc b/vendor/benchmark-4ed29ae/test/locale_impermeability_test.cc new file mode 100644 index 000000000..e2dd6cfd9 --- /dev/null +++ b/vendor/benchmark-4ed29ae/test/locale_impermeability_test.cc @@ -0,0 +1,47 @@ +#undef NDEBUG +#include +#include +#include + +#include "benchmark/benchmark.h" +#include "output_test.h" + +namespace { +void BM_ostream(benchmark::State& state) { +#if !defined(__MINGW64__) || defined(__clang__) + // GCC-based versions of MINGW64 do not support locale manipulations, + // don't run the test under them. + std::locale::global(std::locale("en_US.UTF-8")); +#endif + while (state.KeepRunning()) { + state.SetIterationTime(1e-6); + } +} +BENCHMARK(BM_ostream)->UseManualTime()->Iterations(1000000); + +ADD_CASES(TC_ConsoleOut, {{"^BM_ostream/iterations:1000000/manual_time" + " %console_report$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_ostream/iterations:1000000/manual_time\",$"}, + {"\"family_index\": 0,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": " + "\"BM_ostream/iterations:1000000/manual_time\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": 1000000,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\"$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_ostream/iterations:1000000/" + "manual_time\",1000000,%float,%float,ns,,,,,$"}}); +} // end namespace + +int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + RunOutputTests(argc, argv); +} diff --git a/vendor/benchmark-4ed29ae/test/manual_threading_test.cc b/vendor/benchmark-4ed29ae/test/manual_threading_test.cc new file mode 100644 index 000000000..b3252ec16 --- /dev/null +++ b/vendor/benchmark-4ed29ae/test/manual_threading_test.cc @@ -0,0 +1,175 @@ + +#include +#undef NDEBUG + +#include +#include + +#include "../src/timers.h" +#include "benchmark/benchmark.h" + +namespace { + +const std::chrono::duration time_frame(50); +const double time_frame_in_sec( + std::chrono::duration_cast>>( + time_frame) + .count()); + +void MyBusySpinwait() { + const auto start = benchmark::ChronoClockNow(); + + while (true) { + const auto now = benchmark::ChronoClockNow(); + const auto elapsed = now - start; + + if (std::chrono::duration(elapsed) >= + time_frame) { + return; + } + } +} + +int numRunThreadsCalled_ = 0; + +class ManualThreadRunner : public benchmark::ThreadRunnerBase { + public: + explicit ManualThreadRunner(int num_threads) + : pool(static_cast(num_threads - 1)) {} + + void RunThreads(const std::function& fn) final { + for (std::size_t ti = 0; ti < pool.size(); ++ti) { + pool[ti] = std::thread(fn, static_cast(ti + 1)); + } + + fn(0); + + for (std::thread& thread : pool) { + thread.join(); + } + + ++numRunThreadsCalled_; + } + + private: + std::vector pool; +}; + +// ========================================================================= // +// --------------------------- TEST CASES BEGIN ---------------------------- // +// ========================================================================= // + +// ========================================================================= // +// BM_ManualThreading +// Creation of threads is done before the start of the measurement, +// joining after the finish of the measurement. +void BM_ManualThreading(benchmark::State& state) { + for (auto _ : state) { + MyBusySpinwait(); + state.SetIterationTime(time_frame_in_sec); + } + state.counters["invtime"] = + benchmark::Counter{1, benchmark::Counter::kIsRate}; +} + +} // end namespace + +BENCHMARK(BM_ManualThreading) + ->Iterations(1) + ->ThreadRunner([](int num_threads) { + return std::make_unique(num_threads); + }) + ->Threads(1); +BENCHMARK(BM_ManualThreading) + ->Iterations(1) + ->ThreadRunner([](int num_threads) { + return std::make_unique(num_threads); + }) + ->Threads(1) + ->UseRealTime(); +BENCHMARK(BM_ManualThreading) + ->Iterations(1) + ->ThreadRunner([](int num_threads) { + return std::make_unique(num_threads); + }) + ->Threads(1) + ->UseManualTime(); +BENCHMARK(BM_ManualThreading) + ->Iterations(1) + ->ThreadRunner([](int num_threads) { + return std::make_unique(num_threads); + }) + ->Threads(1) + ->MeasureProcessCPUTime(); +BENCHMARK(BM_ManualThreading) + ->Iterations(1) + ->ThreadRunner([](int num_threads) { + return std::make_unique(num_threads); + }) + ->Threads(1) + ->MeasureProcessCPUTime() + ->UseRealTime(); +BENCHMARK(BM_ManualThreading) + ->Iterations(1) + ->ThreadRunner([](int num_threads) { + return std::make_unique(num_threads); + }) + ->Threads(1) + ->MeasureProcessCPUTime() + ->UseManualTime(); + +BENCHMARK(BM_ManualThreading) + ->Iterations(1) + ->ThreadRunner([](int num_threads) { + return std::make_unique(num_threads); + }) + ->Threads(2); +BENCHMARK(BM_ManualThreading) + ->Iterations(1) + ->ThreadRunner([](int num_threads) { + return std::make_unique(num_threads); + }) + ->Threads(2) + ->UseRealTime(); +BENCHMARK(BM_ManualThreading) + ->Iterations(1) + ->ThreadRunner([](int num_threads) { + return std::make_unique(num_threads); + }) + ->Threads(2) + ->UseManualTime(); +BENCHMARK(BM_ManualThreading) + ->Iterations(1) + ->ThreadRunner([](int num_threads) { + return std::make_unique(num_threads); + }) + ->Threads(2) + ->MeasureProcessCPUTime(); +BENCHMARK(BM_ManualThreading) + ->Iterations(1) + ->ThreadRunner([](int num_threads) { + return std::make_unique(num_threads); + }) + ->Threads(2) + ->MeasureProcessCPUTime() + ->UseRealTime(); +BENCHMARK(BM_ManualThreading) + ->Iterations(1) + ->ThreadRunner([](int num_threads) { + return std::make_unique(num_threads); + }) + ->Threads(2) + ->MeasureProcessCPUTime() + ->UseManualTime(); + +// ========================================================================= // +// ---------------------------- TEST CASES END ----------------------------- // +// ========================================================================= // + +int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + benchmark::Initialize(&argc, argv); + benchmark::RunSpecifiedBenchmarks(); + benchmark::Shutdown(); + assert(numRunThreadsCalled_ > 0); +} diff --git a/vendor/benchmark-38df9da/test/map_test.cc b/vendor/benchmark-4ed29ae/test/map_test.cc similarity index 91% rename from vendor/benchmark-38df9da/test/map_test.cc rename to vendor/benchmark-4ed29ae/test/map_test.cc index 0fdba7c87..018e12a75 100644 --- a/vendor/benchmark-38df9da/test/map_test.cc +++ b/vendor/benchmark-4ed29ae/test/map_test.cc @@ -13,10 +13,8 @@ std::map ConstructRandomMap(int size) { return m; } -} // namespace - // Basic version. -static void BM_MapLookup(benchmark::State& state) { +void BM_MapLookup(benchmark::State& state) { const int size = static_cast(state.range(0)); std::map m; for (auto _ : state) { @@ -31,6 +29,7 @@ static void BM_MapLookup(benchmark::State& state) { state.SetItemsProcessed(state.iterations() * size); } BENCHMARK(BM_MapLookup)->Range(1 << 3, 1 << 12); +} // namespace // Using fixtures. class MapFixture : public ::benchmark::Fixture { @@ -39,7 +38,7 @@ class MapFixture : public ::benchmark::Fixture { m = ConstructRandomMap(static_cast(st.range(0))); } - void TearDown(const ::benchmark::State&) override { m.clear(); } + void TearDown(const ::benchmark::State& /*unused*/) override { m.clear(); } std::map m; }; diff --git a/vendor/benchmark-38df9da/test/memory_manager_test.cc b/vendor/benchmark-4ed29ae/test/memory_manager_test.cc similarity index 88% rename from vendor/benchmark-38df9da/test/memory_manager_test.cc rename to vendor/benchmark-4ed29ae/test/memory_manager_test.cc index 4df674d58..39b32169d 100644 --- a/vendor/benchmark-38df9da/test/memory_manager_test.cc +++ b/vendor/benchmark-4ed29ae/test/memory_manager_test.cc @@ -1,9 +1,9 @@ #include -#include "../src/check.h" #include "benchmark/benchmark.h" #include "output_test.h" +namespace { class TestMemoryManager : public benchmark::MemoryManager { void Start() override {} void Stop(Result& result) override { @@ -14,11 +14,13 @@ class TestMemoryManager : public benchmark::MemoryManager { void BM_empty(benchmark::State& state) { for (auto _ : state) { - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } } BENCHMARK(BM_empty); +} // end namespace ADD_CASES(TC_ConsoleOut, {{"^BM_empty %console_report$"}}); ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_empty\",$"}, @@ -39,6 +41,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_empty\",$"}, ADD_CASES(TC_CSVOut, {{"^\"BM_empty\",%csv_report$"}}); int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); std::unique_ptr mm(new TestMemoryManager()); benchmark::RegisterMemoryManager(mm.get()); diff --git a/vendor/benchmark-4ed29ae/test/memory_results_gtest.cc b/vendor/benchmark-4ed29ae/test/memory_results_gtest.cc new file mode 100644 index 000000000..70a5a5a98 --- /dev/null +++ b/vendor/benchmark-4ed29ae/test/memory_results_gtest.cc @@ -0,0 +1,101 @@ +#include + +#include "benchmark/benchmark.h" +#include "gtest/gtest.h" + +namespace { + +using benchmark::Benchmark; +using benchmark::ClearRegisteredBenchmarks; +using benchmark::ConsoleReporter; +using benchmark::MemoryManager; +using benchmark::RegisterBenchmark; +using benchmark::RunSpecifiedBenchmarks; +using benchmark::State; + +constexpr int N_REPETITIONS = 100; +constexpr int N_ITERATIONS = 1; + +int num_allocs = 0; +int max_bytes_used = 0; +int total_allocated_bytes = 0; +int net_heap_growth = 0; + +void reset() { + num_allocs = 0; + max_bytes_used = 0; + total_allocated_bytes = 0; + net_heap_growth = 0; +} +class TestMemoryManager : public MemoryManager { + void Start() override {} + void Stop(Result& result) override { + result.num_allocs = num_allocs; + result.net_heap_growth = net_heap_growth; + result.max_bytes_used = max_bytes_used; + result.total_allocated_bytes = total_allocated_bytes; + + num_allocs += 1; + max_bytes_used += 2; + net_heap_growth += 4; + total_allocated_bytes += 10; + } +}; + +class TestReporter : public ConsoleReporter { + public: + TestReporter() = default; + virtual ~TestReporter() = default; + + bool ReportContext(const Context& /*unused*/) override { return true; } + + void PrintHeader(const Run&) override {} + void PrintRunData(const Run& run) override { + if (run.repetition_index == -1) return; + if (!run.memory_result.memory_iterations) return; + + store.push_back(run.memory_result); + } + + std::vector store; +}; + +class MemoryResultsTest : public testing::Test { + public: + Benchmark* bm; + TestReporter reporter; + + void SetUp() override { + bm = RegisterBenchmark("BM", [](State& st) { + for (auto _ : st) { + } + }); + bm->Repetitions(N_REPETITIONS); + bm->Iterations(N_ITERATIONS); + reset(); + } + void TearDown() override { ClearRegisteredBenchmarks(); } +}; + +TEST_F(MemoryResultsTest, NoMMTest) { + RunSpecifiedBenchmarks(&reporter); + EXPECT_EQ(reporter.store.size(), 0); +} + +TEST_F(MemoryResultsTest, ResultsTest) { + auto mm = std::make_unique(); + RegisterMemoryManager(mm.get()); + + RunSpecifiedBenchmarks(&reporter); + EXPECT_EQ(reporter.store.size(), N_REPETITIONS); + + for (size_t i = 0; i < reporter.store.size(); i++) { + EXPECT_EQ(reporter.store[i].num_allocs, static_cast(i)); + EXPECT_EQ(reporter.store[i].max_bytes_used, static_cast(i) * 2); + EXPECT_EQ(reporter.store[i].net_heap_growth, static_cast(i) * 4); + EXPECT_EQ(reporter.store[i].total_allocated_bytes, + static_cast(i) * 10); + } +} + +} // namespace diff --git a/vendor/benchmark-38df9da/test/min_time_parse_gtest.cc b/vendor/benchmark-4ed29ae/test/min_time_parse_gtest.cc similarity index 100% rename from vendor/benchmark-38df9da/test/min_time_parse_gtest.cc rename to vendor/benchmark-4ed29ae/test/min_time_parse_gtest.cc diff --git a/vendor/benchmark-38df9da/test/multiple_ranges_test.cc b/vendor/benchmark-4ed29ae/test/multiple_ranges_test.cc similarity index 97% rename from vendor/benchmark-38df9da/test/multiple_ranges_test.cc rename to vendor/benchmark-4ed29ae/test/multiple_ranges_test.cc index 5300a9603..987b69c82 100644 --- a/vendor/benchmark-38df9da/test/multiple_ranges_test.cc +++ b/vendor/benchmark-4ed29ae/test/multiple_ranges_test.cc @@ -5,6 +5,7 @@ #include "benchmark/benchmark.h" +namespace { class MultipleRangesFixture : public ::benchmark::Fixture { public: MultipleRangesFixture() @@ -87,10 +88,11 @@ void BM_CheckDefaultArgument(benchmark::State& state) { } BENCHMARK(BM_CheckDefaultArgument)->Ranges({{1, 5}, {6, 10}}); -static void BM_MultipleRanges(benchmark::State& st) { +void BM_MultipleRanges(benchmark::State& st) { for (auto _ : st) { } } BENCHMARK(BM_MultipleRanges)->Ranges({{5, 5}, {6, 6}}); +} // end namespace BENCHMARK_MAIN(); diff --git a/vendor/benchmark-38df9da/test/options_test.cc b/vendor/benchmark-4ed29ae/test/options_test.cc similarity index 96% rename from vendor/benchmark-38df9da/test/options_test.cc rename to vendor/benchmark-4ed29ae/test/options_test.cc index a1b209f3e..70e3e18e2 100644 --- a/vendor/benchmark-38df9da/test/options_test.cc +++ b/vendor/benchmark-4ed29ae/test/options_test.cc @@ -8,6 +8,7 @@ #endif #include +namespace { void BM_basic(benchmark::State& state) { for (auto _ : state) { } @@ -50,7 +51,7 @@ BENCHMARK(BM_basic)->RangeMultiplier(4)->Range(-8, 8); BENCHMARK(BM_basic)->DenseRange(-2, 2, 1); BENCHMARK(BM_basic)->Ranges({{-64, 1}, {-8, -1}}); -void CustomArgs(benchmark::internal::Benchmark* b) { +void CustomArgs(benchmark::Benchmark* b) { for (int i = 0; i < 10; ++i) { b->Arg(i); } @@ -73,5 +74,6 @@ void BM_explicit_iteration_count(benchmark::State& state) { assert(state.iterations() == 42); } BENCHMARK(BM_explicit_iteration_count)->Iterations(42); +} // end namespace BENCHMARK_MAIN(); diff --git a/vendor/benchmark-38df9da/test/output_test.h b/vendor/benchmark-4ed29ae/test/output_test.h similarity index 95% rename from vendor/benchmark-38df9da/test/output_test.h rename to vendor/benchmark-4ed29ae/test/output_test.h index c08fe1d87..0fd557d90 100644 --- a/vendor/benchmark-38df9da/test/output_test.h +++ b/vendor/benchmark-4ed29ae/test/output_test.h @@ -16,12 +16,13 @@ #define CONCAT2(x, y) x##y #define CONCAT(x, y) CONCAT2(x, y) -#define ADD_CASES(...) int CONCAT(dummy, __LINE__) = ::AddCases(__VA_ARGS__) +#define ADD_CASES(...) \ + const int CONCAT(dummy, __LINE__) = ::AddCases(__VA_ARGS__) #define SET_SUBSTITUTIONS(...) \ - int CONCAT(dummy, __LINE__) = ::SetSubstitutions(__VA_ARGS__) + const int CONCAT(dummy, __LINE__) = ::SetSubstitutions(__VA_ARGS__) -enum MatchRules { +enum MatchRules : uint8_t { MR_Default, // Skip non-matching lines until a match is found. MR_Next, // Match must occur on the next line. MR_Not // No line between the current position and the next match matches @@ -37,7 +38,7 @@ struct TestCase { std::shared_ptr regex; }; -enum TestCaseID { +enum TestCaseID : uint8_t { TC_ConsoleOut, TC_ConsoleErr, TC_JSONOut, @@ -80,7 +81,8 @@ std::string GetFileReporterOutput(int argc, char* argv[]); // will be the subject of a call to checker_function // checker_function: should be of type ResultsCheckFn (see below) #define CHECK_BENCHMARK_RESULTS(bm_name_pattern, checker_function) \ - size_t CONCAT(dummy, __LINE__) = AddChecker(bm_name_pattern, checker_function) + const size_t CONCAT(dummy, __LINE__) = \ + AddChecker(bm_name_pattern, checker_function) struct Results; typedef std::function ResultsCheckFn; @@ -101,7 +103,7 @@ struct Results { double NumIterations() const; - typedef enum { kCpuTime, kRealTime } BenchmarkTime; + typedef enum : uint8_t { kCpuTime, kRealTime } BenchmarkTime; // get cpu_time or real_time in seconds double GetTime(BenchmarkTime which) const; diff --git a/vendor/benchmark-38df9da/test/output_test_helper.cc b/vendor/benchmark-4ed29ae/test/output_test_helper.cc similarity index 90% rename from vendor/benchmark-38df9da/test/output_test_helper.cc rename to vendor/benchmark-4ed29ae/test/output_test_helper.cc index 265f28aae..43a1bfde8 100644 --- a/vendor/benchmark-38df9da/test/output_test_helper.cc +++ b/vendor/benchmark-4ed29ae/test/output_test_helper.cc @@ -83,7 +83,7 @@ std::string PerformSubstitutions(std::string source) { SubMap const& subs = GetSubstitutions(); using SizeT = std::string::size_type; for (auto const& KV : subs) { - SizeT pos; + SizeT pos = 0; SizeT next_start = 0; while ((pos = source.find(KV.first, next_start)) != std::string::npos) { next_start = pos + KV.second.size(); @@ -98,7 +98,7 @@ void CheckCase(std::stringstream& remaining_output, TestCase const& TC, std::string first_line; bool on_first = true; std::string line; - while (remaining_output.eof() == false) { + while (!remaining_output.eof()) { BM_CHECK(remaining_output.good()); std::getline(remaining_output, line); if (on_first) { @@ -112,7 +112,9 @@ void CheckCase(std::stringstream& remaining_output, TestCase const& TC, << "\n actual regex string \"" << TC.substituted_regex << "\"" << "\n started matching near: " << first_line; } - if (TC.regex->Match(line)) return; + if (TC.regex->Match(line)) { + return; + } BM_CHECK(TC.match_rule != MR_Next) << "Expected line \"" << line << "\" to match regex \"" << TC.regex_str << "\"" @@ -147,7 +149,7 @@ class TestReporter : public benchmark::BenchmarkReporter { bool ReportContext(const Context& context) override { bool last_ret = false; bool first = true; - for (auto rep : reporters_) { + for (auto* rep : reporters_) { bool new_ret = rep->ReportContext(context); BM_CHECK(first || new_ret == last_ret) << "Reports return different values for ReportContext"; @@ -159,10 +161,14 @@ class TestReporter : public benchmark::BenchmarkReporter { } void ReportRuns(const std::vector& report) override { - for (auto rep : reporters_) rep->ReportRuns(report); + for (auto* rep : reporters_) { + rep->ReportRuns(report); + } } void Finalize() override { - for (auto rep : reporters_) rep->Finalize(); + for (auto* rep : reporters_) { + rep->Finalize(); + } } private: @@ -200,15 +206,17 @@ class ResultsChecker { void SetHeader_(const std::string& csv_header); void SetValues_(const std::string& entry_csv_line); - std::vector SplitCsv_(const std::string& line); + std::vector SplitCsv_(const std::string& line) const; }; +namespace { // store the static ResultsChecker in a function to prevent initialization // order problems ResultsChecker& GetResultsChecker() { static ResultsChecker rc; return rc; } +} // end namespace // add a results checker for a benchmark void ResultsChecker::Add(const std::string& entry_pattern, @@ -224,14 +232,16 @@ void ResultsChecker::CheckResults(std::stringstream& output) { // clear before calling tellg() output.clear(); // seek to zero only when needed - if (output.tellg() > start) output.seekg(start); + if (output.tellg() > start) { + output.seekg(start); + } // and just in case output.clear(); } // now go over every line and publish it to the ResultsChecker std::string line; bool on_first = true; - while (output.eof() == false) { + while (!output.eof()) { BM_CHECK(output.good()); std::getline(output, line); if (on_first) { @@ -265,7 +275,9 @@ void ResultsChecker::SetHeader_(const std::string& csv_header) { // set the values for a benchmark void ResultsChecker::SetValues_(const std::string& entry_csv_line) { - if (entry_csv_line.empty()) return; // some lines are empty + if (entry_csv_line.empty()) { + return; + } // some lines are empty BM_CHECK(!field_names.empty()); auto vals = SplitCsv_(entry_csv_line); BM_CHECK_EQ(vals.size(), field_names.size()); @@ -277,23 +289,38 @@ void ResultsChecker::SetValues_(const std::string& entry_csv_line) { } // a quick'n'dirty csv splitter (eliminating quotes) -std::vector ResultsChecker::SplitCsv_(const std::string& line) { +std::vector ResultsChecker::SplitCsv_( + const std::string& line) const { std::vector out; - if (line.empty()) return out; - if (!field_names.empty()) out.reserve(field_names.size()); - size_t prev = 0, pos = line.find_first_of(','), curr = pos; - while (pos != line.npos) { + if (line.empty()) { + return out; + } + if (!field_names.empty()) { + out.reserve(field_names.size()); + } + size_t prev = 0; + size_t pos = line.find_first_of(','); + size_t curr = pos; + while (pos != std::string::npos) { BM_CHECK(curr > 0); - if (line[prev] == '"') ++prev; - if (line[curr - 1] == '"') --curr; + if (line[prev] == '"') { + ++prev; + } + if (line[curr - 1] == '"') { + --curr; + } out.push_back(line.substr(prev, curr - prev)); prev = pos + 1; pos = line.find_first_of(',', pos + 1); curr = pos; } curr = line.size(); - if (line[prev] == '"') ++prev; - if (line[curr - 1] == '"') --curr; + if (line[prev] == '"') { + ++prev; + } + if (line[curr - 1] == '"') { + --curr; + } out.push_back(line.substr(prev, curr - prev)); return out; } @@ -308,7 +335,9 @@ size_t AddChecker(const std::string& bm_name, const ResultsCheckFn& fn) { int Results::NumThreads() const { auto pos = name.find("/threads:"); - if (pos == name.npos) return 1; + if (pos == std::string::npos) { + return 1; + } auto end = name.find('/', pos + 9); std::stringstream ss; ss << name.substr(pos + 9, end); @@ -324,7 +353,7 @@ double Results::GetTime(BenchmarkTime which) const { BM_CHECK(which == kCpuTime || which == kRealTime); const char* which_str = which == kCpuTime ? "cpu_time" : "real_time"; double val = GetAs(which_str); - auto unit = Get("time_unit"); + const auto* unit = Get("time_unit"); BM_CHECK(unit); if (*unit == "ns") { return val * 1.e-9; @@ -378,7 +407,9 @@ int SetSubstitutions( break; } } - if (!exists) subs.push_back(std::move(KV)); + if (!exists) { + subs.push_back(std::move(KV)); + } } return 0; } @@ -449,50 +480,60 @@ void RunOutputTests(int argc, char* argv[]) { BENCHMARK_RESTORE_DEPRECATED_WARNING int SubstrCnt(const std::string& haystack, const std::string& pat) { - if (pat.length() == 0) return 0; + if (pat.length() == 0) { + return 0; + } int count = 0; for (size_t offset = haystack.find(pat); offset != std::string::npos; - offset = haystack.find(pat, offset + pat.length())) + offset = haystack.find(pat, offset + pat.length())) { ++count; + } return count; } -static char ToHex(int ch) { +namespace { +char ToHex(int ch) { return ch < 10 ? static_cast('0' + ch) : static_cast('a' + (ch - 10)); } -static char RandomHexChar() { +char RandomHexChar() { static std::mt19937 rd{std::random_device{}()}; static std::uniform_int_distribution mrand{0, 15}; return ToHex(mrand(rd)); } -static std::string GetRandomFileName() { +std::string GetRandomFileName() { std::string model = "test.%%%%%%"; for (auto& ch : model) { - if (ch == '%') ch = RandomHexChar(); + if (ch == '%') { + ch = RandomHexChar(); + } } return model; } -static bool FileExists(std::string const& name) { +bool FileExists(std::string const& name) { std::ifstream in(name.c_str()); return in.good(); } -static std::string GetTempFileName() { +std::string GetTempFileName() { // This function attempts to avoid race conditions where two tests // create the same file at the same time. However, it still introduces races // similar to tmpnam. int retries = 3; - while (--retries) { + while (--retries != 0) { std::string name = GetRandomFileName(); - if (!FileExists(name)) return name; + if (!FileExists(name)) { + return name; + } } - std::cerr << "Failed to create unique temporary file name" << std::endl; - std::abort(); + std::cerr << "Failed to create unique temporary file name\n"; + std::flush(std::cerr); + std::exit(1); } +} // end namespace std::string GetFileReporterOutput(int argc, char* argv[]) { std::vector new_argv(argv, argv + argc); @@ -505,7 +546,7 @@ std::string GetFileReporterOutput(int argc, char* argv[]) { tmp += tmp_file_name; new_argv.emplace_back(const_cast(tmp.c_str())); - argc = int(new_argv.size()); + argc = static_cast(new_argv.size()); benchmark::Initialize(&argc, new_argv.data()); benchmark::RunSpecifiedBenchmarks(); diff --git a/vendor/benchmark-4ed29ae/test/overload_test.cc b/vendor/benchmark-4ed29ae/test/overload_test.cc new file mode 100644 index 000000000..d1fee9a78 --- /dev/null +++ b/vendor/benchmark-4ed29ae/test/overload_test.cc @@ -0,0 +1,35 @@ +#include "benchmark/benchmark.h" + +namespace { +// Simulate an overloaded function name. +// This version does nothing and is just here to create ambiguity for +// MyOverloadedBenchmark. +BENCHMARK_UNUSED void MyOverloadedBenchmark() {} + +// This is the actual benchmark function we want to register. +// It has the signature void(benchmark::State&) required by the library. +void MyOverloadedBenchmark(benchmark::State& state) { + for (auto _ : state) { + } +} + +// This macro invocation should compile correctly if benchmark.h +// contains the fix (using static_cast), but would fail to compile +// if the benchmark name were ambiguous (e.g., when using + or no cast +// with an overloaded function). +BENCHMARK(MyOverloadedBenchmark); + +// Also test BENCHMARK_TEMPLATE with an overloaded name. +template +void MyTemplatedOverloadedBenchmark() {} + +template +void MyTemplatedOverloadedBenchmark(benchmark::State& state) { + for (auto _ : state) { + } +} + +BENCHMARK_TEMPLATE(MyTemplatedOverloadedBenchmark, 1); +} // end namespace + +BENCHMARK_MAIN(); diff --git a/vendor/benchmark-38df9da/test/perf_counters_gtest.cc b/vendor/benchmark-4ed29ae/test/perf_counters_gtest.cc similarity index 99% rename from vendor/benchmark-38df9da/test/perf_counters_gtest.cc rename to vendor/benchmark-4ed29ae/test/perf_counters_gtest.cc index 2e6304928..5de262fa2 100644 --- a/vendor/benchmark-38df9da/test/perf_counters_gtest.cc +++ b/vendor/benchmark-4ed29ae/test/perf_counters_gtest.cc @@ -226,9 +226,13 @@ void measure(size_t threadcount, PerfCounterValues* before, // threadpool. auto counters = PerfCounters::Create({kGenericPerfEvent1, kGenericPerfEvent2}); - for (auto& t : threads) t = std::thread(work); + for (auto& t : threads) { + t = std::thread(work); + } counters.Snapshot(before); - for (auto& t : threads) t.join(); + for (auto& t : threads) { + t.join(); + } counters.Snapshot(after); } diff --git a/vendor/benchmark-38df9da/test/perf_counters_test.cc b/vendor/benchmark-4ed29ae/test/perf_counters_test.cc similarity index 90% rename from vendor/benchmark-38df9da/test/perf_counters_test.cc rename to vendor/benchmark-4ed29ae/test/perf_counters_test.cc index 3cc593e62..a830b5ef1 100644 --- a/vendor/benchmark-38df9da/test/perf_counters_test.cc +++ b/vendor/benchmark-4ed29ae/test/perf_counters_test.cc @@ -11,8 +11,9 @@ namespace benchmark { BM_DECLARE_string(benchmark_perf_counters); } // namespace benchmark +namespace { -static void BM_Simple(benchmark::State& state) { +void BM_Simple(benchmark::State& state) { for (auto _ : state) { auto iterations = double(state.iterations()) * double(state.iterations()); benchmark::DoNotOptimize(iterations); @@ -66,19 +67,21 @@ static void CheckSimple(Results const& e) { double withoutPauseResumeInstrCount = 0.0; double withPauseResumeInstrCount = 0.0; -static void SaveInstrCountWithoutResume(Results const& e) { +void SaveInstrCountWithoutResume(Results const& e) { withoutPauseResumeInstrCount = e.GetAs("INSTRUCTIONS"); } -static void SaveInstrCountWithResume(Results const& e) { +void SaveInstrCountWithResume(Results const& e) { withPauseResumeInstrCount = e.GetAs("INSTRUCTIONS"); } CHECK_BENCHMARK_RESULTS("BM_Simple", &CheckSimple); CHECK_BENCHMARK_RESULTS("BM_WithoutPauseResume", &SaveInstrCountWithoutResume); CHECK_BENCHMARK_RESULTS("BM_WithPauseResume", &SaveInstrCountWithResume); +} // end namespace int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); if (!benchmark::internal::PerfCounters::kSupported) { return 0; } diff --git a/vendor/benchmark-4ed29ae/test/profiler_manager_gtest.cc b/vendor/benchmark-4ed29ae/test/profiler_manager_gtest.cc new file mode 100644 index 000000000..434e4ecad --- /dev/null +++ b/vendor/benchmark-4ed29ae/test/profiler_manager_gtest.cc @@ -0,0 +1,42 @@ +#include + +#include "benchmark/benchmark.h" +#include "gtest/gtest.h" + +namespace { + +class TestProfilerManager : public benchmark::ProfilerManager { + public: + void AfterSetupStart() override { ++start_called; } + void BeforeTeardownStop() override { ++stop_called; } + + int start_called = 0; + int stop_called = 0; +}; + +void BM_empty(benchmark::State& state) { + for (auto _ : state) { + auto iterations = state.iterations(); + benchmark::DoNotOptimize(iterations); + } +} +BENCHMARK(BM_empty); + +TEST(ProfilerManager, ReregisterManager) { +#if GTEST_HAS_DEATH_TEST + // Tests only runnable in debug mode (when BM_CHECK is enabled). +#ifndef NDEBUG +#ifndef TEST_BENCHMARK_LIBRARY_HAS_NO_ASSERTIONS + ASSERT_DEATH_IF_SUPPORTED( + { + std::unique_ptr pm(new TestProfilerManager()); + benchmark::RegisterProfilerManager(pm.get()); + benchmark::RegisterProfilerManager(pm.get()); + }, + "RegisterProfilerManager"); +#endif +#endif +#endif +} + +} // namespace diff --git a/vendor/benchmark-4ed29ae/test/profiler_manager_iterations_test.cc b/vendor/benchmark-4ed29ae/test/profiler_manager_iterations_test.cc new file mode 100644 index 000000000..c4983eb34 --- /dev/null +++ b/vendor/benchmark-4ed29ae/test/profiler_manager_iterations_test.cc @@ -0,0 +1,62 @@ +#include +#include +#include +#include + +#include "benchmark/benchmark.h" + +// Tests that we can specify the number of profiler iterations with +// --benchmark_min_time=x. +namespace { + +int iteration_count = 0; +int end_profiler_iteration_count = 0; + +class TestProfilerManager : public benchmark::ProfilerManager { + void AfterSetupStart() override { iteration_count = 0; } + void BeforeTeardownStop() override { + end_profiler_iteration_count = iteration_count; + } +}; + +class NullReporter : public benchmark::BenchmarkReporter { + public: + bool ReportContext(const Context& /*context*/) override { return true; } + void ReportRuns(const std::vector& /* report */) override {} +}; + +void BM_MyBench(benchmark::State& state) { + for (auto s : state) { + ++iteration_count; + } +} +BENCHMARK(BM_MyBench); +} // end namespace + +int main(int argc, char** argv) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + // Make a fake argv and append the new --benchmark_profiler_iterations= + // to it. + int fake_argc = argc + 1; + std::vector fake_argv(static_cast(fake_argc)); + for (size_t i = 0; i < static_cast(argc); ++i) { + fake_argv[i] = argv[i]; + } + fake_argv[static_cast(argc)] = "--benchmark_min_time=4x"; + + std::unique_ptr pm(new TestProfilerManager()); + benchmark::RegisterProfilerManager(pm.get()); + + benchmark::Initialize(&fake_argc, const_cast(fake_argv.data())); + + NullReporter null_reporter; + const size_t returned_count = + benchmark::RunSpecifiedBenchmarks(&null_reporter, "BM_MyBench"); + assert(returned_count == 1); + + // Check the executed iters. + assert(end_profiler_iteration_count == 4); + + benchmark::RegisterProfilerManager(nullptr); + return 0; +} diff --git a/vendor/benchmark-4ed29ae/test/profiler_manager_test.cc b/vendor/benchmark-4ed29ae/test/profiler_manager_test.cc new file mode 100644 index 000000000..5c4b14daa --- /dev/null +++ b/vendor/benchmark-4ed29ae/test/profiler_manager_test.cc @@ -0,0 +1,54 @@ +// FIXME: WIP + +#include +#include + +#include "benchmark/benchmark.h" +#include "output_test.h" + +namespace { +class TestProfilerManager : public benchmark::ProfilerManager { + public: + void AfterSetupStart() override { ++start_called; } + void BeforeTeardownStop() override { ++stop_called; } + + int start_called = 0; + int stop_called = 0; +}; + +void BM_empty(benchmark::State& state) { + for (auto _ : state) { + auto iterations = state.iterations(); + benchmark::DoNotOptimize(iterations); + } +} +BENCHMARK(BM_empty); + +ADD_CASES(TC_ConsoleOut, {{"^BM_empty %console_report$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_empty\",$"}, + {"\"family_index\": 0,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": \"BM_empty\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": 1,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\"$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_empty\",%csv_report$"}}); +} // end namespace + +int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + std::unique_ptr pm(new TestProfilerManager()); + + benchmark::RegisterProfilerManager(pm.get()); + RunOutputTests(argc, argv); + benchmark::RegisterProfilerManager(nullptr); + + assert(pm->start_called == 1); + assert(pm->stop_called == 1); +} diff --git a/vendor/benchmark-38df9da/test/register_benchmark_test.cc b/vendor/benchmark-4ed29ae/test/register_benchmark_test.cc similarity index 92% rename from vendor/benchmark-38df9da/test/register_benchmark_test.cc rename to vendor/benchmark-4ed29ae/test/register_benchmark_test.cc index d69d144a4..3e39437a2 100644 --- a/vendor/benchmark-38df9da/test/register_benchmark_test.cc +++ b/vendor/benchmark-4ed29ae/test/register_benchmark_test.cc @@ -53,11 +53,10 @@ int AddCases(std::initializer_list const& v) { #define CONCAT(x, y) CONCAT2(x, y) #define CONCAT2(x, y) x##y -#define ADD_CASES(...) int CONCAT(dummy, __LINE__) = AddCases({__VA_ARGS__}) +#define ADD_CASES(...) \ + const int CONCAT(dummy, __LINE__) = AddCases({__VA_ARGS__}) -} // end namespace - -typedef benchmark::internal::Benchmark* ReturnVal; +using ReturnVal = benchmark::Benchmark const* const; //----------------------------------------------------------------------------// // Test RegisterBenchmark with no additional arguments @@ -76,7 +75,6 @@ ADD_CASES({"BM_function"}, {"BM_function_manual_registration"}); // Note: GCC <= 4.8 do not support this form of RegisterBenchmark because they // reject the variadic pack expansion of lambda captures. //----------------------------------------------------------------------------// -#ifndef BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK void BM_extra_args(benchmark::State& st, const char* label) { for (auto _ : st) { @@ -86,15 +84,14 @@ void BM_extra_args(benchmark::State& st, const char* label) { int RegisterFromFunction() { std::pair cases[] = { {"test1", "One"}, {"test2", "Two"}, {"test3", "Three"}}; - for (auto const& c : cases) + for (auto const& c : cases) { benchmark::RegisterBenchmark(c.first, &BM_extra_args, c.second); + } return 0; } -int dummy2 = RegisterFromFunction(); +const int dummy2 = RegisterFromFunction(); ADD_CASES({"test1", "One"}, {"test2", "Two"}, {"test3", "Three"}); -#endif // BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK - //----------------------------------------------------------------------------// // Test RegisterBenchmark with DISABLED_ benchmark //----------------------------------------------------------------------------// @@ -119,14 +116,11 @@ struct CustomFixture { }; void TestRegistrationAtRuntime() { -#ifdef BENCHMARK_HAS_CXX11 { CustomFixture fx; benchmark::RegisterBenchmark("custom_fixture", fx); AddCases({std::string("custom_fixture")}); } -#endif -#ifndef BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK { const char* x = "42"; auto capturing_lam = [=](benchmark::State& st) { @@ -137,7 +131,6 @@ void TestRegistrationAtRuntime() { benchmark::RegisterBenchmark("lambda_benchmark", capturing_lam); AddCases({{"lambda_benchmark", x}}); } -#endif } // Test that all benchmarks, registered at either during static init or runtime, @@ -163,7 +156,7 @@ void RunTestOne() { // benchmarks. // Also test that new benchmarks can be registered and ran afterwards. void RunTestTwo() { - assert(ExpectedResults.size() != 0 && + assert(!ExpectedResults.empty() && "must have at least one registered benchmark"); ExpectedResults.clear(); benchmark::ClearRegisteredBenchmarks(); @@ -187,8 +180,10 @@ void RunTestTwo() { } assert(EB == ExpectedResults.end()); } +} // end namespace int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); benchmark::Initialize(&argc, argv); RunTestOne(); diff --git a/vendor/benchmark-38df9da/test/repetitions_test.cc b/vendor/benchmark-4ed29ae/test/repetitions_test.cc similarity index 97% rename from vendor/benchmark-38df9da/test/repetitions_test.cc rename to vendor/benchmark-4ed29ae/test/repetitions_test.cc index 569777d5f..9116fa65b 100644 --- a/vendor/benchmark-38df9da/test/repetitions_test.cc +++ b/vendor/benchmark-4ed29ae/test/repetitions_test.cc @@ -2,11 +2,12 @@ #include "benchmark/benchmark.h" #include "output_test.h" +namespace { // ========================================================================= // // ------------------------ Testing Basic Output --------------------------- // // ========================================================================= // -static void BM_ExplicitRepetitions(benchmark::State& state) { +void BM_ExplicitRepetitions(benchmark::State& state) { for (auto _ : state) { } } @@ -108,7 +109,7 @@ ADD_CASES(TC_CSVOut, // ------------------------ Testing Basic Output --------------------------- // // ========================================================================= // -static void BM_ImplicitRepetitions(benchmark::State& state) { +void BM_ImplicitRepetitions(benchmark::State& state) { for (auto _ : state) { } } @@ -206,9 +207,13 @@ ADD_CASES(TC_CSVOut, {{"^\"BM_ImplicitRepetitions\",%csv_report$"}}); ADD_CASES(TC_CSVOut, {{"^\"BM_ImplicitRepetitions_mean\",%csv_report$"}}); ADD_CASES(TC_CSVOut, {{"^\"BM_ImplicitRepetitions_median\",%csv_report$"}}); ADD_CASES(TC_CSVOut, {{"^\"BM_ImplicitRepetitions_stddev\",%csv_report$"}}); +} // end namespace // ========================================================================= // // --------------------------- TEST CASES END ------------------------------ // // ========================================================================= // -int main(int argc, char* argv[]) { RunOutputTests(argc, argv); } +int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + RunOutputTests(argc, argv); +} diff --git a/vendor/benchmark-38df9da/test/report_aggregates_only_test.cc b/vendor/benchmark-4ed29ae/test/report_aggregates_only_test.cc similarity index 94% rename from vendor/benchmark-38df9da/test/report_aggregates_only_test.cc rename to vendor/benchmark-4ed29ae/test/report_aggregates_only_test.cc index 47da50358..707d92383 100644 --- a/vendor/benchmark-38df9da/test/report_aggregates_only_test.cc +++ b/vendor/benchmark-4ed29ae/test/report_aggregates_only_test.cc @@ -6,6 +6,7 @@ #include "benchmark/benchmark.h" #include "output_test.h" +namespace { // Ok this test is super ugly. We want to check what happens with the file // reporter in the presence of ReportAggregatesOnly(). // We do not care about console output, the normal tests check that already. @@ -15,8 +16,10 @@ void BM_SummaryRepeat(benchmark::State& state) { } } BENCHMARK(BM_SummaryRepeat)->Repetitions(3)->ReportAggregatesOnly(); +} // end namespace int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); const std::string output = GetFileReporterOutput(argc, argv); if (SubstrCnt(output, "\"name\": \"BM_SummaryRepeat/repeats:3") != 4 || diff --git a/vendor/benchmark-38df9da/test/reporter_output_test.cc b/vendor/benchmark-4ed29ae/test/reporter_output_test.cc similarity index 98% rename from vendor/benchmark-38df9da/test/reporter_output_test.cc rename to vendor/benchmark-4ed29ae/test/reporter_output_test.cc index 7867165d1..9940ab75d 100644 --- a/vendor/benchmark-38df9da/test/reporter_output_test.cc +++ b/vendor/benchmark-4ed29ae/test/reporter_output_test.cc @@ -1,11 +1,9 @@ - #undef NDEBUG -#include -#include #include "benchmark/benchmark.h" #include "output_test.h" +namespace { // ========================================================================= // // ---------------------- Testing Prologue Output -------------------------- // // ========================================================================= // @@ -13,7 +11,7 @@ ADD_CASES(TC_ConsoleOut, {{"^[-]+$", MR_Next}, {"^Benchmark %s Time %s CPU %s Iterations$", MR_Next}, {"^[-]+$", MR_Next}}); -static int AddContextCases() { +int AddContextCases() { AddCases(TC_ConsoleErr, { {"^%int-%int-%intT%int:%int:%int[-+]%int:%int$", MR_Default}, @@ -60,7 +58,7 @@ static int AddContextCases() { AddCases(TC_JSONOut, {{"\"json_schema_version\": 1$", MR_Next}}); return 0; } -int dummy_register = AddContextCases(); +const int dummy_register = AddContextCases(); ADD_CASES(TC_CSVOut, {{"%csv_header"}}); // ========================================================================= // @@ -96,7 +94,8 @@ ADD_CASES(TC_CSVOut, {{"^\"BM_basic\",%csv_report$"}}); void BM_bytes_per_second(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } state.SetBytesProcessed(1); @@ -128,7 +127,8 @@ ADD_CASES(TC_CSVOut, {{"^\"BM_bytes_per_second\",%csv_bytes_report$"}}); void BM_items_per_second(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } state.SetItemsProcessed(1); @@ -409,7 +409,8 @@ ADD_CASES(TC_ConsoleOut, {{"^BM_BigArgs/1073741824 %console_report$"}, void BM_Complexity_O1(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } state.SetComplexityN(state.range(0)); @@ -1125,9 +1126,13 @@ void BM_CSV_Format(benchmark::State& state) { } BENCHMARK(BM_CSV_Format); ADD_CASES(TC_CSVOut, {{"^\"BM_CSV_Format\",,,,,,,,true,\"\"\"freedom\"\"\"$"}}); +} // end namespace // ========================================================================= // // --------------------------- TEST CASES END ------------------------------ // // ========================================================================= // -int main(int argc, char* argv[]) { RunOutputTests(argc, argv); } +int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + RunOutputTests(argc, argv); +} diff --git a/vendor/benchmark-38df9da/test/skip_with_error_test.cc b/vendor/benchmark-4ed29ae/test/skip_with_error_test.cc similarity index 89% rename from vendor/benchmark-38df9da/test/skip_with_error_test.cc rename to vendor/benchmark-4ed29ae/test/skip_with_error_test.cc index 2139a19e2..425895988 100644 --- a/vendor/benchmark-38df9da/test/skip_with_error_test.cc +++ b/vendor/benchmark-4ed29ae/test/skip_with_error_test.cc @@ -46,6 +46,7 @@ struct TestCase { } }; +// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) std::vector ExpectedResults; int AddCases(const std::string& base_name, @@ -59,9 +60,7 @@ int AddCases(const std::string& base_name, #define CONCAT(x, y) CONCAT2(x, y) #define CONCAT2(x, y) x##y -#define ADD_CASES(...) int CONCAT(dummy, __LINE__) = AddCases(__VA_ARGS__) - -} // end namespace +#define ADD_CASES(...) const int CONCAT(dummy, __LINE__) = AddCases(__VA_ARGS__) void BM_error_no_running(benchmark::State& state) { state.SkipWithError("error message"); @@ -97,11 +96,11 @@ BENCHMARK(BM_error_before_running_range_for); ADD_CASES("BM_error_before_running_range_for", {{"", true, "error message"}}); void BM_error_during_running(benchmark::State& state) { - int first_iter = true; + int first_iter = 1; while (state.KeepRunning()) { if (state.range(0) == 1 && state.thread_index() <= (state.threads() / 2)) { assert(first_iter); - first_iter = false; + first_iter = 0; state.SkipWithError("error message"); } else { state.PauseTiming(); @@ -143,11 +142,13 @@ ADD_CASES("BM_error_during_running_ranged_for", void BM_error_after_running(benchmark::State& state) { for (auto _ : state) { - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } - if (state.thread_index() <= (state.threads() / 2)) + if (state.thread_index() <= (state.threads() / 2)) { state.SkipWithError("error message"); + } } BENCHMARK(BM_error_after_running)->ThreadRange(1, 8); ADD_CASES("BM_error_after_running", {{"/threads:1", true, "error message"}, @@ -179,7 +180,18 @@ ADD_CASES("BM_error_while_paused", {{"/1/threads:1", true, "error message"}, {"/2/threads:4", false, ""}, {"/2/threads:8", false, ""}}); +void BM_malformed(benchmark::State& /*unused*/) { + // NOTE: empty body wanted. No thing else. +} +BENCHMARK(BM_malformed); +ADD_CASES("BM_malformed", + {{"", true, + "The benchmark didn't run, nor was it explicitly skipped. Please " + "call 'SkipWithXXX` in your benchmark as appropriate."}}); +} // end namespace + int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); benchmark::Initialize(&argc, argv); TestReporter test_reporter; diff --git a/vendor/benchmark-38df9da/test/spec_arg_test.cc b/vendor/benchmark-4ed29ae/test/spec_arg_test.cc similarity index 95% rename from vendor/benchmark-38df9da/test/spec_arg_test.cc rename to vendor/benchmark-4ed29ae/test/spec_arg_test.cc index 06aafbeb9..21275ef0d 100644 --- a/vendor/benchmark-38df9da/test/spec_arg_test.cc +++ b/vendor/benchmark-4ed29ae/test/spec_arg_test.cc @@ -39,22 +39,24 @@ class TestReporter : public benchmark::ConsoleReporter { std::vector matched_functions; }; -} // end namespace - -static void BM_NotChosen(benchmark::State& state) { +void BM_NotChosen(benchmark::State& state) { assert(false && "SHOULD NOT BE CALLED"); for (auto _ : state) { } } BENCHMARK(BM_NotChosen); -static void BM_Chosen(benchmark::State& state) { +void BM_Chosen(benchmark::State& state) { for (auto _ : state) { } } BENCHMARK(BM_Chosen); +} // end namespace + int main(int argc, char** argv) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + const std::string flag = "BM_NotChosen"; // Verify that argv specify --benchmark_filter=BM_NotChosen. diff --git a/vendor/benchmark-38df9da/test/spec_arg_verbosity_test.cc b/vendor/benchmark-4ed29ae/test/spec_arg_verbosity_test.cc similarity index 88% rename from vendor/benchmark-38df9da/test/spec_arg_verbosity_test.cc rename to vendor/benchmark-4ed29ae/test/spec_arg_verbosity_test.cc index 8f8eb6d37..318784cff 100644 --- a/vendor/benchmark-38df9da/test/spec_arg_verbosity_test.cc +++ b/vendor/benchmark-4ed29ae/test/spec_arg_verbosity_test.cc @@ -4,14 +4,18 @@ #include "benchmark/benchmark.h" +namespace { // Tests that the user specified verbosity level can be get. -static void BM_Verbosity(benchmark::State& state) { +void BM_Verbosity(benchmark::State& state) { for (auto _ : state) { } } BENCHMARK(BM_Verbosity); +} // end namespace int main(int argc, char** argv) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + const int32_t flagv = 42; // Verify that argv specify --v=42. diff --git a/vendor/benchmark-38df9da/test/state_assembly_test.cc b/vendor/benchmark-4ed29ae/test/state_assembly_test.cc similarity index 96% rename from vendor/benchmark-38df9da/test/state_assembly_test.cc rename to vendor/benchmark-4ed29ae/test/state_assembly_test.cc index 7ddbb3b2a..e9ecfebf1 100644 --- a/vendor/benchmark-38df9da/test/state_assembly_test.cc +++ b/vendor/benchmark-4ed29ae/test/state_assembly_test.cc @@ -2,6 +2,7 @@ #ifdef __clang__ #pragma clang diagnostic ignored "-Wreturn-type" +#pragma clang diagnostic ignored "-Wmissing-prototypes" #endif // clang-format off diff --git a/vendor/benchmark-38df9da/test/statistics_gtest.cc b/vendor/benchmark-4ed29ae/test/statistics_gtest.cc similarity index 100% rename from vendor/benchmark-38df9da/test/statistics_gtest.cc rename to vendor/benchmark-4ed29ae/test/statistics_gtest.cc diff --git a/vendor/benchmark-38df9da/test/string_util_gtest.cc b/vendor/benchmark-4ed29ae/test/string_util_gtest.cc similarity index 58% rename from vendor/benchmark-38df9da/test/string_util_gtest.cc rename to vendor/benchmark-4ed29ae/test/string_util_gtest.cc index 67b4bc0c2..5a9a09e19 100644 --- a/vendor/benchmark-38df9da/test/string_util_gtest.cc +++ b/vendor/benchmark-4ed29ae/test/string_util_gtest.cc @@ -13,18 +13,18 @@ namespace { TEST(StringUtilTest, stoul) { { size_t pos = 0; - EXPECT_EQ(0ul, benchmark::stoul("0", &pos)); - EXPECT_EQ(1ul, pos); + EXPECT_EQ(0UL, benchmark::stoul("0", &pos)); + EXPECT_EQ(1UL, pos); } { size_t pos = 0; - EXPECT_EQ(7ul, benchmark::stoul("7", &pos)); - EXPECT_EQ(1ul, pos); + EXPECT_EQ(7UL, benchmark::stoul("7", &pos)); + EXPECT_EQ(1UL, pos); } { size_t pos = 0; - EXPECT_EQ(135ul, benchmark::stoul("135", &pos)); - EXPECT_EQ(3ul, pos); + EXPECT_EQ(135UL, benchmark::stoul("135", &pos)); + EXPECT_EQ(3UL, pos); } #if ULONG_MAX == 0xFFFFFFFFul { @@ -35,35 +35,35 @@ TEST(StringUtilTest, stoul) { #elif ULONG_MAX == 0xFFFFFFFFFFFFFFFFul { size_t pos = 0; - EXPECT_EQ(0xFFFFFFFFFFFFFFFFul, + EXPECT_EQ(0xFFFFFFFFFFFFFFFFUL, benchmark::stoul("18446744073709551615", &pos)); - EXPECT_EQ(20ul, pos); + EXPECT_EQ(20UL, pos); } #endif { size_t pos = 0; - EXPECT_EQ(10ul, benchmark::stoul("1010", &pos, 2)); - EXPECT_EQ(4ul, pos); + EXPECT_EQ(10UL, benchmark::stoul("1010", &pos, 2)); + EXPECT_EQ(4UL, pos); } { size_t pos = 0; - EXPECT_EQ(520ul, benchmark::stoul("1010", &pos, 8)); - EXPECT_EQ(4ul, pos); + EXPECT_EQ(520UL, benchmark::stoul("1010", &pos, 8)); + EXPECT_EQ(4UL, pos); } { size_t pos = 0; - EXPECT_EQ(1010ul, benchmark::stoul("1010", &pos, 10)); - EXPECT_EQ(4ul, pos); + EXPECT_EQ(1010UL, benchmark::stoul("1010", &pos, 10)); + EXPECT_EQ(4UL, pos); } { size_t pos = 0; - EXPECT_EQ(4112ul, benchmark::stoul("1010", &pos, 16)); - EXPECT_EQ(4ul, pos); + EXPECT_EQ(4112UL, benchmark::stoul("1010", &pos, 16)); + EXPECT_EQ(4UL, pos); } { size_t pos = 0; - EXPECT_EQ(0xBEEFul, benchmark::stoul("BEEF", &pos, 16)); - EXPECT_EQ(4ul, pos); + EXPECT_EQ(0xBEEFUL, benchmark::stoul("BEEF", &pos, 16)); + EXPECT_EQ(4UL, pos); } #ifndef BENCHMARK_HAS_NO_EXCEPTIONS { @@ -73,83 +73,87 @@ TEST(StringUtilTest, stoul) { #endif } -TEST(StringUtilTest, stoi){{size_t pos = 0; -EXPECT_EQ(0, benchmark::stoi("0", &pos)); -EXPECT_EQ(1ul, pos); -} // namespace -{ - size_t pos = 0; - EXPECT_EQ(-17, benchmark::stoi("-17", &pos)); - EXPECT_EQ(3ul, pos); -} -{ - size_t pos = 0; - EXPECT_EQ(1357, benchmark::stoi("1357", &pos)); - EXPECT_EQ(4ul, pos); -} -{ - size_t pos = 0; - EXPECT_EQ(10, benchmark::stoi("1010", &pos, 2)); - EXPECT_EQ(4ul, pos); -} -{ - size_t pos = 0; - EXPECT_EQ(520, benchmark::stoi("1010", &pos, 8)); - EXPECT_EQ(4ul, pos); -} -{ - size_t pos = 0; - EXPECT_EQ(1010, benchmark::stoi("1010", &pos, 10)); - EXPECT_EQ(4ul, pos); -} -{ - size_t pos = 0; - EXPECT_EQ(4112, benchmark::stoi("1010", &pos, 16)); - EXPECT_EQ(4ul, pos); -} -{ - size_t pos = 0; - EXPECT_EQ(0xBEEF, benchmark::stoi("BEEF", &pos, 16)); - EXPECT_EQ(4ul, pos); -} +TEST(StringUtilTest, stoi) { + { + size_t pos = 0; + EXPECT_EQ(0, benchmark::stoi("0", &pos)); + EXPECT_EQ(1UL, pos); + } // namespace + { + size_t pos = 0; + EXPECT_EQ(-17, benchmark::stoi("-17", &pos)); + EXPECT_EQ(3UL, pos); + } + { + size_t pos = 0; + EXPECT_EQ(1357, benchmark::stoi("1357", &pos)); + EXPECT_EQ(4UL, pos); + } + { + size_t pos = 0; + EXPECT_EQ(10, benchmark::stoi("1010", &pos, 2)); + EXPECT_EQ(4UL, pos); + } + { + size_t pos = 0; + EXPECT_EQ(520, benchmark::stoi("1010", &pos, 8)); + EXPECT_EQ(4UL, pos); + } + { + size_t pos = 0; + EXPECT_EQ(1010, benchmark::stoi("1010", &pos, 10)); + EXPECT_EQ(4UL, pos); + } + { + size_t pos = 0; + EXPECT_EQ(4112, benchmark::stoi("1010", &pos, 16)); + EXPECT_EQ(4UL, pos); + } + { + size_t pos = 0; + EXPECT_EQ(0xBEEF, benchmark::stoi("BEEF", &pos, 16)); + EXPECT_EQ(4UL, pos); + } #ifndef BENCHMARK_HAS_NO_EXCEPTIONS -{ - ASSERT_THROW(std::ignore = benchmark::stoi("this is a test"), - std::invalid_argument); -} + { + ASSERT_THROW(std::ignore = benchmark::stoi("this is a test"), + std::invalid_argument); + } #endif } -TEST(StringUtilTest, stod){{size_t pos = 0; -EXPECT_EQ(0.0, benchmark::stod("0", &pos)); -EXPECT_EQ(1ul, pos); -} -{ - size_t pos = 0; - EXPECT_EQ(-84.0, benchmark::stod("-84", &pos)); - EXPECT_EQ(3ul, pos); -} -{ - size_t pos = 0; - EXPECT_EQ(1234.0, benchmark::stod("1234", &pos)); - EXPECT_EQ(4ul, pos); -} -{ - size_t pos = 0; - EXPECT_EQ(1.5, benchmark::stod("1.5", &pos)); - EXPECT_EQ(3ul, pos); -} -{ - size_t pos = 0; - /* Note: exactly representable as double */ - EXPECT_EQ(-1.25e+9, benchmark::stod("-1.25e+9", &pos)); - EXPECT_EQ(8ul, pos); -} +TEST(StringUtilTest, stod) { + { + size_t pos = 0; + EXPECT_EQ(0.0, benchmark::stod("0", &pos)); + EXPECT_EQ(1UL, pos); + } + { + size_t pos = 0; + EXPECT_EQ(-84.0, benchmark::stod("-84", &pos)); + EXPECT_EQ(3UL, pos); + } + { + size_t pos = 0; + EXPECT_EQ(1234.0, benchmark::stod("1234", &pos)); + EXPECT_EQ(4UL, pos); + } + { + size_t pos = 0; + EXPECT_EQ(1.5, benchmark::stod("1.5", &pos)); + EXPECT_EQ(3UL, pos); + } + { + size_t pos = 0; + /* Note: exactly representable as double */ + EXPECT_EQ(-1.25e+9, benchmark::stod("-1.25e+9", &pos)); + EXPECT_EQ(8UL, pos); + } #ifndef BENCHMARK_HAS_NO_EXCEPTIONS -{ - ASSERT_THROW(std::ignore = benchmark::stod("this is a test"), - std::invalid_argument); -} + { + ASSERT_THROW(std::ignore = benchmark::stod("this is a test"), + std::invalid_argument); + } #endif } diff --git a/vendor/benchmark-4ed29ae/test/templated_fixture_method_test.cc b/vendor/benchmark-4ed29ae/test/templated_fixture_method_test.cc new file mode 100644 index 000000000..06fc7d83e --- /dev/null +++ b/vendor/benchmark-4ed29ae/test/templated_fixture_method_test.cc @@ -0,0 +1,26 @@ + +#include +#include + +#include "benchmark/benchmark.h" + +template +class MyFixture : public ::benchmark::Fixture { + public: + MyFixture() : data(0) {} + + T data; + + using type = T; +}; + +BENCHMARK_TEMPLATE_METHOD_F(MyFixture, Foo)(benchmark::State& st) { + for (auto _ : st) { + this->data += typename Base::type(1); + } +} + +BENCHMARK_TEMPLATE_INSTANTIATE_F(MyFixture, Foo, int); +BENCHMARK_TEMPLATE_INSTANTIATE_F(MyFixture, Foo, double); + +BENCHMARK_MAIN(); diff --git a/vendor/benchmark-38df9da/test/templated_fixture_test.cc b/vendor/benchmark-4ed29ae/test/templated_fixture_test.cc similarity index 100% rename from vendor/benchmark-38df9da/test/templated_fixture_test.cc rename to vendor/benchmark-4ed29ae/test/templated_fixture_test.cc diff --git a/vendor/benchmark-38df9da/test/time_unit_gtest.cc b/vendor/benchmark-4ed29ae/test/time_unit_gtest.cc similarity index 89% rename from vendor/benchmark-38df9da/test/time_unit_gtest.cc rename to vendor/benchmark-4ed29ae/test/time_unit_gtest.cc index 484ecbcfb..0da11092b 100644 --- a/vendor/benchmark-38df9da/test/time_unit_gtest.cc +++ b/vendor/benchmark-4ed29ae/test/time_unit_gtest.cc @@ -6,10 +6,10 @@ namespace internal { namespace { -class DummyBenchmark : public Benchmark { +class DummyBenchmark : public benchmark::Benchmark { public: DummyBenchmark() : Benchmark("dummy") {} - void Run(State&) override {} + void Run(State& /*state*/) override {} }; TEST(DefaultTimeUnitTest, TimeUnitIsNotSet) { diff --git a/vendor/benchmark-38df9da/test/user_counters_tabular_test.cc b/vendor/benchmark-4ed29ae/test/user_counters_tabular_test.cc similarity index 98% rename from vendor/benchmark-38df9da/test/user_counters_tabular_test.cc rename to vendor/benchmark-4ed29ae/test/user_counters_tabular_test.cc index cfc1ab069..7db0e2082 100644 --- a/vendor/benchmark-38df9da/test/user_counters_tabular_test.cc +++ b/vendor/benchmark-4ed29ae/test/user_counters_tabular_test.cc @@ -4,6 +4,7 @@ #include "benchmark/benchmark.h" #include "output_test.h" +namespace { // @todo: this checks the full output at once; the rule for // CounterSet1 was failing because it was not matching "^[-]+$". // @todo: check that the counters are vertically aligned. @@ -64,7 +65,8 @@ ADD_CASES(TC_CSVOut, {{"%csv_header," void BM_Counters_Tabular(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } namespace bm = benchmark; @@ -375,7 +377,8 @@ CHECK_BENCHMARK_RESULTS("BM_Counters_Tabular/repeats:2/threads:2$", void BM_CounterRates_Tabular(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } namespace bm = benchmark; @@ -415,7 +418,7 @@ ADD_CASES(TC_CSVOut, {{"^\"BM_CounterRates_Tabular/threads:%int\",%csv_report," // VS2013 does not allow this function to be passed as a lambda argument // to CHECK_BENCHMARK_RESULTS() void CheckTabularRate(Results const& e) { - double t = e.DurationCPUTime(); + double t = e.DurationCPUTime() / e.NumThreads(); CHECK_FLOAT_COUNTER_VALUE(e, "Foo", EQ, 1. / t, 0.001); CHECK_FLOAT_COUNTER_VALUE(e, "Bar", EQ, 2. / t, 0.001); CHECK_FLOAT_COUNTER_VALUE(e, "Baz", EQ, 4. / t, 0.001); @@ -553,9 +556,13 @@ void CheckSet2(Results const& e) { CHECK_COUNTER_VALUE(e, int, "Baz", EQ, 40); } CHECK_BENCHMARK_RESULTS("BM_CounterSet2_Tabular", &CheckSet2); +} // end namespace // ========================================================================= // // --------------------------- TEST CASES END ------------------------------ // // ========================================================================= // -int main(int argc, char* argv[]) { RunOutputTests(argc, argv); } +int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + RunOutputTests(argc, argv); +} diff --git a/vendor/benchmark-38df9da/test/user_counters_test.cc b/vendor/benchmark-4ed29ae/test/user_counters_test.cc similarity index 94% rename from vendor/benchmark-38df9da/test/user_counters_test.cc rename to vendor/benchmark-4ed29ae/test/user_counters_test.cc index 22252acbf..a8af0877c 100644 --- a/vendor/benchmark-38df9da/test/user_counters_test.cc +++ b/vendor/benchmark-4ed29ae/test/user_counters_test.cc @@ -21,7 +21,7 @@ ADD_CASES(TC_CSVOut, {{"%csv_header,\"bar\",\"foo\""}}); // ========================================================================= // // ------------------------- Simple Counters Output ------------------------ // // ========================================================================= // - +namespace { void BM_Counters_Simple(benchmark::State& state) { for (auto _ : state) { } @@ -56,6 +56,7 @@ void CheckSimple(Results const& e) { CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * its, 0.001); } CHECK_BENCHMARK_RESULTS("BM_Counters_Simple", &CheckSimple); +} // end namespace // ========================================================================= // // --------------------- Counters+Items+Bytes/s Output --------------------- // @@ -63,11 +64,11 @@ CHECK_BENCHMARK_RESULTS("BM_Counters_Simple", &CheckSimple); namespace { int num_calls1 = 0; -} void BM_Counters_WithBytesAndItemsPSec(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } state.counters["foo"] = 1; @@ -111,15 +112,17 @@ void CheckBytesAndItemsPSec(Results const& e) { } CHECK_BENCHMARK_RESULTS("BM_Counters_WithBytesAndItemsPSec", &CheckBytesAndItemsPSec); +} // end namespace // ========================================================================= // // ------------------------- Rate Counters Output -------------------------- // // ========================================================================= // - +namespace { void BM_Counters_Rate(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } namespace bm = benchmark; @@ -155,15 +158,18 @@ void CheckRate(Results const& e) { CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / t, 0.001); } CHECK_BENCHMARK_RESULTS("BM_Counters_Rate", &CheckRate); +} // end namespace // ========================================================================= // // ----------------------- Inverted Counters Output ------------------------ // // ========================================================================= // +namespace { void BM_Invert(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } namespace bm = benchmark; @@ -196,15 +202,18 @@ void CheckInvert(Results const& e) { CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 0.0001, 0.0001); } CHECK_BENCHMARK_RESULTS("BM_Invert", &CheckInvert); +} // end namespace // ========================================================================= // // --------------------- InvertedRate Counters Output ---------------------- // // ========================================================================= // +namespace { void BM_Counters_InvertedRate(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } namespace bm = benchmark; @@ -243,11 +252,13 @@ void CheckInvertedRate(Results const& e) { CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, t / 8192.0, 0.001); } CHECK_BENCHMARK_RESULTS("BM_Counters_InvertedRate", &CheckInvertedRate); +} // end namespace // ========================================================================= // // ------------------------- Thread Counters Output ------------------------ // // ========================================================================= // +namespace { void BM_Counters_Threads(benchmark::State& state) { for (auto _ : state) { } @@ -283,11 +294,13 @@ void CheckThreads(Results const& e) { CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2 * e.NumThreads()); } CHECK_BENCHMARK_RESULTS("BM_Counters_Threads/threads:%int", &CheckThreads); +} // end namespace // ========================================================================= // // ---------------------- ThreadAvg Counters Output ------------------------ // // ========================================================================= // +namespace { void BM_Counters_AvgThreads(benchmark::State& state) { for (auto _ : state) { } @@ -325,15 +338,18 @@ void CheckAvgThreads(Results const& e) { } CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreads/threads:%int", &CheckAvgThreads); +} // end namespace // ========================================================================= // // ---------------------- ThreadAvg Counters Output ------------------------ // // ========================================================================= // +namespace { void BM_Counters_AvgThreadsRate(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } namespace bm = benchmark; @@ -365,16 +381,20 @@ ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgThreadsRate/" // VS2013 does not allow this function to be passed as a lambda argument // to CHECK_BENCHMARK_RESULTS() void CheckAvgThreadsRate(Results const& e) { - CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / e.DurationCPUTime(), 0.001); - CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / e.DurationCPUTime(), 0.001); + // this (and not real time) is the time used + double t = e.DurationCPUTime() / e.NumThreads(); + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / t, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / t, 0.001); } CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreadsRate/threads:%int", &CheckAvgThreadsRate); +} // end namespace // ========================================================================= // // ------------------- IterationInvariant Counters Output ------------------ // // ========================================================================= // +namespace { void BM_Counters_IterationInvariant(benchmark::State& state) { for (auto _ : state) { } @@ -413,15 +433,18 @@ void CheckIterationInvariant(Results const& e) { } CHECK_BENCHMARK_RESULTS("BM_Counters_IterationInvariant", &CheckIterationInvariant); +} // end namespace // ========================================================================= // // ----------------- IterationInvariantRate Counters Output ---------------- // // ========================================================================= // +namespace { void BM_Counters_kIsIterationInvariantRate(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } namespace bm = benchmark; @@ -463,11 +486,13 @@ void CheckIsIterationInvariantRate(Results const& e) { } CHECK_BENCHMARK_RESULTS("BM_Counters_kIsIterationInvariantRate", &CheckIsIterationInvariantRate); +} // end namespace // ========================================================================= // // --------------------- AvgIterations Counters Output --------------------- // // ========================================================================= // +namespace { void BM_Counters_AvgIterations(benchmark::State& state) { for (auto _ : state) { } @@ -505,15 +530,18 @@ void CheckAvgIterations(Results const& e) { CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / its, 0.001); } CHECK_BENCHMARK_RESULTS("BM_Counters_AvgIterations", &CheckAvgIterations); +} // end namespace // ========================================================================= // // ------------------- AvgIterationsRate Counters Output ------------------- // // ========================================================================= // +namespace { void BM_Counters_kAvgIterationsRate(benchmark::State& state) { for (auto _ : state) { // This test requires a non-zero CPU time to avoid divide-by-zero - auto iterations = double(state.iterations()) * double(state.iterations()); + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); benchmark::DoNotOptimize(iterations); } namespace bm = benchmark; @@ -553,9 +581,13 @@ void CheckAvgIterationsRate(Results const& e) { } CHECK_BENCHMARK_RESULTS("BM_Counters_kAvgIterationsRate", &CheckAvgIterationsRate); +} // end namespace // ========================================================================= // // --------------------------- TEST CASES END ------------------------------ // // ========================================================================= // -int main(int argc, char* argv[]) { RunOutputTests(argc, argv); } +int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + RunOutputTests(argc, argv); +} diff --git a/vendor/benchmark-38df9da/test/user_counters_thousands_test.cc b/vendor/benchmark-4ed29ae/test/user_counters_thousands_test.cc similarity index 97% rename from vendor/benchmark-38df9da/test/user_counters_thousands_test.cc rename to vendor/benchmark-4ed29ae/test/user_counters_thousands_test.cc index fc153835f..0ef78d378 100644 --- a/vendor/benchmark-38df9da/test/user_counters_thousands_test.cc +++ b/vendor/benchmark-4ed29ae/test/user_counters_thousands_test.cc @@ -4,6 +4,7 @@ #include "benchmark/benchmark.h" #include "output_test.h" +namespace { // ========================================================================= // // ------------------------ Thousands Customisation ------------------------ // // ========================================================================= // @@ -166,8 +167,9 @@ ADD_CASES( // VS2013 does not allow this function to be passed as a lambda argument // to CHECK_BENCHMARK_RESULTS() void CheckThousands(Results const& e) { - if (e.name != "BM_Counters_Thousands/repeats:2") + if (e.name != "BM_Counters_Thousands/repeats:2") { return; // Do not check the aggregates! + } // check that the values are within 0.01% of the expected values CHECK_FLOAT_COUNTER_VALUE(e, "t0_1000000DefaultBase", EQ, 1000 * 1000, @@ -178,9 +180,13 @@ void CheckThousands(Results const& e) { CHECK_FLOAT_COUNTER_VALUE(e, "t4_1048576Base1024", EQ, 1024 * 1024, 0.0001); } CHECK_BENCHMARK_RESULTS("BM_Counters_Thousands", &CheckThousands); +} // end namespace // ========================================================================= // // --------------------------- TEST CASES END ------------------------------ // // ========================================================================= // -int main(int argc, char* argv[]) { RunOutputTests(argc, argv); } +int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + RunOutputTests(argc, argv); +} diff --git a/vendor/benchmark-4ed29ae/test/user_counters_threads_test.cc b/vendor/benchmark-4ed29ae/test/user_counters_threads_test.cc new file mode 100644 index 000000000..e2e5ade46 --- /dev/null +++ b/vendor/benchmark-4ed29ae/test/user_counters_threads_test.cc @@ -0,0 +1,622 @@ + +#undef NDEBUG + +#include "benchmark/benchmark.h" +#include "output_test.h" + +// ========================================================================= // +// ---------------------- Testing Prologue Output -------------------------- // +// ========================================================================= // + +// clang-format off + +ADD_CASES(TC_ConsoleOut, + {{"^[-]+$", MR_Next}, + {"^Benchmark %s Time %s CPU %s Iterations UserCounters...$", MR_Next}, + {"^[-]+$", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"%csv_header,\"bar\",\"foo\""}}); + +// clang-format on + +// ========================================================================= // +// ------------------------- Simple Counters Output ------------------------ // +// ========================================================================= // + +namespace { +void BM_Counters_Simple(benchmark::State& state) { + for (auto _ : state) { + } + state.counters["foo"] = 1; + state.counters["bar"] = 2 * static_cast(state.iterations()); +} +BENCHMARK(BM_Counters_Simple)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_Simple/threads:%int %console_report " + "bar=%hrfloat foo=%hrfloat$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_Simple/threads:%int\",$"}, + {"\"family_index\": 0,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": \"BM_Counters_Simple/threads:%int\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": %int,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES( + TC_CSVOut, + {{"^\"BM_Counters_Simple/threads:%int\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckSimple(Results const& e) { + double its = e.NumIterations(); + CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1 * e.NumThreads()); + // check that the value of bar is within 0.1% of the expected value + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * its, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_Simple/threads:%int", &CheckSimple); +} // end namespace + +// ========================================================================= // +// --------------------- Counters+Items+Bytes/s Output --------------------- // +// ========================================================================= // + +namespace { +void BM_Counters_WithBytesAndItemsPSec(benchmark::State& state) { + for (auto _ : state) { + // This test requires a non-zero CPU time to avoid divide-by-zero + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); + benchmark::DoNotOptimize(iterations); + } + state.counters["foo"] = 1; + state.SetBytesProcessed(364); + state.SetItemsProcessed(150); +} +BENCHMARK(BM_Counters_WithBytesAndItemsPSec)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, + {{"^BM_Counters_WithBytesAndItemsPSec/threads:%int %console_report " + "bytes_per_second=%hrfloat/s " + "foo=%hrfloat items_per_second=%hrfloat/s$"}}); +ADD_CASES( + TC_JSONOut, + {{"\"name\": \"BM_Counters_WithBytesAndItemsPSec/threads:%int\",$"}, + {"\"family_index\": 1,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": \"BM_Counters_WithBytesAndItemsPSec/threads:%int\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": %int,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bytes_per_second\": %float,$", MR_Next}, + {"\"foo\": %float,$", MR_Next}, + {"\"items_per_second\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_WithBytesAndItemsPSec/threads:%int\"," + "%csv_bytes_items_report,,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckBytesAndItemsPSec(Results const& e) { + // this (and not real time) is the time used + double t = e.DurationCPUTime() / e.NumThreads(); + CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1 * e.NumThreads()); + // check that the values are within 0.1% of the expected values + CHECK_FLOAT_RESULT_VALUE(e, "bytes_per_second", EQ, + (364. * e.NumThreads()) / t, 0.001); + CHECK_FLOAT_RESULT_VALUE(e, "items_per_second", EQ, + (150. * e.NumThreads()) / t, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_WithBytesAndItemsPSec/threads:%int", + &CheckBytesAndItemsPSec); +} // end namespace + +// ========================================================================= // +// ------------------------- Rate Counters Output -------------------------- // +// ========================================================================= // +namespace { +void BM_Counters_Rate(benchmark::State& state) { + for (auto _ : state) { + // This test requires a non-zero CPU time to avoid divide-by-zero + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); + benchmark::DoNotOptimize(iterations); + } + namespace bm = benchmark; + state.counters["foo"] = bm::Counter{1, bm::Counter::kIsRate}; + state.counters["bar"] = bm::Counter{2, bm::Counter::kIsRate}; +} +BENCHMARK(BM_Counters_Rate)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_Rate/threads:%int %console_report " + "bar=%hrfloat/s foo=%hrfloat/s$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_Rate/threads:%int\",$"}, + {"\"family_index\": 2,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": \"BM_Counters_Rate/threads:%int\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": %int,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, + {{"^\"BM_Counters_Rate/threads:%int\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckRate(Results const& e) { + // this (and not real time) is the time used + double t = e.DurationCPUTime() / e.NumThreads(); + // check that the values are within 0.1% of the expected values + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, (1. * e.NumThreads()) / t, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, (2. * e.NumThreads()) / t, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_Rate/threads:%int", &CheckRate); +} // end namespace + +// ========================================================================= // +// ----------------------- Inverted Counters Output ------------------------ // +// ========================================================================= // + +namespace { +void BM_Invert(benchmark::State& state) { + for (auto _ : state) { + // This test requires a non-zero CPU time to avoid divide-by-zero + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); + benchmark::DoNotOptimize(iterations); + } + namespace bm = benchmark; + state.counters["foo"] = bm::Counter{0.0001, bm::Counter::kInvert}; + state.counters["bar"] = bm::Counter{10000, bm::Counter::kInvert}; +} +BENCHMARK(BM_Invert)->ThreadRange(1, 8); +ADD_CASES( + TC_ConsoleOut, + {{"^BM_Invert/threads:%int %console_report bar=%hrfloatu foo=%hrfloatk$"}}); +ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Invert/threads:%int\",$"}, + {"\"family_index\": 3,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": \"BM_Invert/threads:%int\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": %int,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, + {{"^\"BM_Invert/threads:%int\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckInvert(Results const& e) { + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / (0.0001 * e.NumThreads()), + 0.0001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 1. / (10000 * e.NumThreads()), + 0.0001); +} +CHECK_BENCHMARK_RESULTS("BM_Invert/threads:%int", &CheckInvert); +} // end namespace + +// ========================================================================= // +// --------------------- InvertedRate Counters Output ---------------------- // +// ========================================================================= // + +namespace { +void BM_Counters_InvertedRate(benchmark::State& state) { + for (auto _ : state) { + // This test requires a non-zero CPU time to avoid divide-by-zero + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); + benchmark::DoNotOptimize(iterations); + } + namespace bm = benchmark; + state.counters["foo"] = + bm::Counter{1, bm::Counter::kIsRate | bm::Counter::kInvert}; + state.counters["bar"] = + bm::Counter{8192, bm::Counter::kIsRate | bm::Counter::kInvert}; +} +BENCHMARK(BM_Counters_InvertedRate)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, + {{"^BM_Counters_InvertedRate/threads:%int %console_report " + "bar=%hrfloats foo=%hrfloats$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_InvertedRate/threads:%int\",$"}, + {"\"family_index\": 4,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": \"BM_Counters_InvertedRate/threads:%int\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": %int,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_InvertedRate/" + "threads:%int\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckInvertedRate(Results const& e) { + // this (and not real time) is the time used + double t = e.DurationCPUTime() / e.NumThreads(); + // check that the values are within 0.1% of the expected values + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, t / (e.NumThreads()), 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, t / (8192.0 * e.NumThreads()), 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_InvertedRate/threads:%int", + &CheckInvertedRate); +} // end namespace + +// ========================================================================= // +// ------------------------- Thread Counters Output ------------------------ // +// ========================================================================= // + +namespace { +void BM_Counters_Threads(benchmark::State& state) { + for (auto _ : state) { + } + state.counters["foo"] = 1; + state.counters["bar"] = 2; +} +BENCHMARK(BM_Counters_Threads)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_Threads/threads:%int %console_report " + "bar=%hrfloat foo=%hrfloat$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_Threads/threads:%int\",$"}, + {"\"family_index\": 5,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": \"BM_Counters_Threads/threads:%int\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": %int,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES( + TC_CSVOut, + {{"^\"BM_Counters_Threads/threads:%int\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckThreads(Results const& e) { + CHECK_COUNTER_VALUE(e, int, "foo", EQ, e.NumThreads()); + CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2 * e.NumThreads()); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_Threads/threads:%int", &CheckThreads); +} // end namespace + +// ========================================================================= // +// ---------------------- ThreadAvg Counters Output ------------------------ // +// ========================================================================= // + +namespace { +void BM_Counters_AvgThreads(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgThreads}; + state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgThreads}; +} +BENCHMARK(BM_Counters_AvgThreads)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgThreads/threads:%int " + "%console_report bar=%hrfloat foo=%hrfloat$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_AvgThreads/threads:%int\",$"}, + {"\"family_index\": 6,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": \"BM_Counters_AvgThreads/threads:%int\",$", MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": %int,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES( + TC_CSVOut, + {{"^\"BM_Counters_AvgThreads/threads:%int\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckAvgThreads(Results const& e) { + CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1); + CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreads/threads:%int", + &CheckAvgThreads); +} // end namespace + +// ========================================================================= // +// ---------------------- ThreadAvg Counters Output ------------------------ // +// ========================================================================= // + +namespace { +void BM_Counters_AvgThreadsRate(benchmark::State& state) { + for (auto _ : state) { + // This test requires a non-zero CPU time to avoid divide-by-zero + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); + benchmark::DoNotOptimize(iterations); + } + namespace bm = benchmark; + state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgThreadsRate}; + state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgThreadsRate}; +} +BENCHMARK(BM_Counters_AvgThreadsRate)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgThreadsRate/threads:%int " + "%console_report bar=%hrfloat/s foo=%hrfloat/s$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$"}, + {"\"family_index\": 7,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": %int,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgThreadsRate/" + "threads:%int\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckAvgThreadsRate(Results const& e) { + // this (and not real time) is the time used + double t = e.DurationCPUTime() / e.NumThreads(); + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / t, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / t, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreadsRate/threads:%int", + &CheckAvgThreadsRate); +} // end namespace + +// ========================================================================= // +// ------------------- IterationInvariant Counters Output ------------------ // +// ========================================================================= // + +namespace { +void BM_Counters_IterationInvariant(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters["foo"] = bm::Counter{1, bm::Counter::kIsIterationInvariant}; + state.counters["bar"] = bm::Counter{2, bm::Counter::kIsIterationInvariant}; +} +BENCHMARK(BM_Counters_IterationInvariant)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, + {{"^BM_Counters_IterationInvariant/threads:%int %console_report " + "bar=%hrfloat foo=%hrfloat$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_IterationInvariant/threads:%int\",$"}, + {"\"family_index\": 8,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": \"BM_Counters_IterationInvariant/threads:%int\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": %int,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_IterationInvariant/" + "threads:%int\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckIterationInvariant(Results const& e) { + double its = e.NumIterations(); + // check that the values are within 0.1% of the expected value + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, its * e.NumThreads(), 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * its * e.NumThreads(), 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_IterationInvariant/threads:%int", + &CheckIterationInvariant); +} // end namespace + +// ========================================================================= // +// ----------------- IterationInvariantRate Counters Output ---------------- // +// ========================================================================= // + +namespace { +void BM_Counters_kIsIterationInvariantRate(benchmark::State& state) { + for (auto _ : state) { + // This test requires a non-zero CPU time to avoid divide-by-zero + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); + benchmark::DoNotOptimize(iterations); + } + namespace bm = benchmark; + state.counters["foo"] = + bm::Counter{1, bm::Counter::kIsIterationInvariantRate}; + state.counters["bar"] = + bm::Counter{2, bm::Counter::kIsRate | bm::Counter::kIsIterationInvariant}; +} +BENCHMARK(BM_Counters_kIsIterationInvariantRate)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, + {{"^BM_Counters_kIsIterationInvariantRate/threads:%int " + "%console_report bar=%hrfloat/s foo=%hrfloat/s$"}}); +ADD_CASES( + TC_JSONOut, + {{"\"name\": \"BM_Counters_kIsIterationInvariantRate/threads:%int\",$"}, + {"\"family_index\": 9,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": \"BM_Counters_kIsIterationInvariantRate/threads:%int\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": %int,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES( + TC_CSVOut, + {{"^\"BM_Counters_kIsIterationInvariantRate/threads:%int\",%csv_report," + "%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckIsIterationInvariantRate(Results const& e) { + double its = e.NumIterations(); + // this (and not real time) is the time used + double t = e.DurationCPUTime() / e.NumThreads(); + // check that the values are within 0.1% of the expected values + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, its * 1. * e.NumThreads() / t, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, its * 2. * e.NumThreads() / t, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_kIsIterationInvariantRate/threads:%int", + &CheckIsIterationInvariantRate); +} // end namespace + +// ========================================================================= // +// --------------------- AvgIterations Counters Output --------------------- // +// ========================================================================= // + +namespace { +void BM_Counters_AvgIterations(benchmark::State& state) { + for (auto _ : state) { + } + namespace bm = benchmark; + state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgIterations}; + state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgIterations}; +} +BENCHMARK(BM_Counters_AvgIterations)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, + {{"^BM_Counters_AvgIterations/threads:%int %console_report " + "bar=%hrfloat foo=%hrfloat$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_AvgIterations/threads:%int\",$"}, + {"\"family_index\": 10,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": \"BM_Counters_AvgIterations/threads:%int\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": %int,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgIterations/" + "threads:%int\",%csv_report,%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckAvgIterations(Results const& e) { + double its = e.NumIterations(); + // check that the values are within 0.1% of the expected value + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. * e.NumThreads() / its, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * e.NumThreads() / its, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_AvgIterations/threads:%int", + &CheckAvgIterations); +} // end namespace + +// ========================================================================= // +// ------------------- AvgIterationsRate Counters Output ------------------- // +// ========================================================================= // + +namespace { +void BM_Counters_kAvgIterationsRate(benchmark::State& state) { + for (auto _ : state) { + // This test requires a non-zero CPU time to avoid divide-by-zero + auto iterations = static_cast(state.iterations()) * + static_cast(state.iterations()); + benchmark::DoNotOptimize(iterations); + } + namespace bm = benchmark; + state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgIterationsRate}; + state.counters["bar"] = + bm::Counter{2, bm::Counter::kIsRate | bm::Counter::kAvgIterations}; +} +BENCHMARK(BM_Counters_kAvgIterationsRate)->ThreadRange(1, 8); +ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_kAvgIterationsRate/threads:%int " + "%console_report bar=%hrfloat/s foo=%hrfloat/s$"}}); +ADD_CASES(TC_JSONOut, + {{"\"name\": \"BM_Counters_kAvgIterationsRate/threads:%int\",$"}, + {"\"family_index\": 11,$", MR_Next}, + {"\"per_family_instance_index\": 0,$", MR_Next}, + {"\"run_name\": \"BM_Counters_kAvgIterationsRate/threads:%int\",$", + MR_Next}, + {"\"run_type\": \"iteration\",$", MR_Next}, + {"\"repetitions\": 1,$", MR_Next}, + {"\"repetition_index\": 0,$", MR_Next}, + {"\"threads\": %int,$", MR_Next}, + {"\"iterations\": %int,$", MR_Next}, + {"\"real_time\": %float,$", MR_Next}, + {"\"cpu_time\": %float,$", MR_Next}, + {"\"time_unit\": \"ns\",$", MR_Next}, + {"\"bar\": %float,$", MR_Next}, + {"\"foo\": %float$", MR_Next}, + {"}", MR_Next}}); +ADD_CASES(TC_CSVOut, + {{"^\"BM_Counters_kAvgIterationsRate/threads:%int\",%csv_report," + "%float,%float$"}}); +// VS2013 does not allow this function to be passed as a lambda argument +// to CHECK_BENCHMARK_RESULTS() +void CheckAvgIterationsRate(Results const& e) { + double its = e.NumIterations(); + // this (and not real time) is the time used + double t = e.DurationCPUTime() / e.NumThreads(); + // check that the values are within 0.1% of the expected values + CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. * e.NumThreads() / its / t, 0.001); + CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * e.NumThreads() / its / t, 0.001); +} +CHECK_BENCHMARK_RESULTS("BM_Counters_kAvgIterationsRate/threads:%int", + &CheckAvgIterationsRate); +} // end namespace + +// ========================================================================= // +// --------------------------- TEST CASES END ------------------------------ // +// ========================================================================= // + +int main(int argc, char* argv[]) { + benchmark::MaybeReenterWithoutASLR(argc, argv); + RunOutputTests(argc, argv); +} diff --git a/vendor/benchmark-38df9da/tools/BUILD.bazel b/vendor/benchmark-4ed29ae/tools/BUILD.bazel similarity index 84% rename from vendor/benchmark-38df9da/tools/BUILD.bazel rename to vendor/benchmark-4ed29ae/tools/BUILD.bazel index 8ef6a8659..a49edb7f7 100644 --- a/vendor/benchmark-38df9da/tools/BUILD.bazel +++ b/vendor/benchmark-4ed29ae/tools/BUILD.bazel @@ -1,3 +1,4 @@ +load("@rules_python//python:defs.bzl", "py_binary", "py_library") load("@tools_pip_deps//:requirements.bzl", "requirement") py_library( diff --git a/vendor/benchmark-38df9da/tools/compare.py b/vendor/benchmark-4ed29ae/tools/compare.py similarity index 92% rename from vendor/benchmark-38df9da/tools/compare.py rename to vendor/benchmark-4ed29ae/tools/compare.py index 7572520cc..1a656345c 100755 --- a/vendor/benchmark-38df9da/tools/compare.py +++ b/vendor/benchmark-4ed29ae/tools/compare.py @@ -21,8 +21,8 @@ def check_inputs(in1, in2, flags): """ Perform checking on the user provided inputs and diagnose any abnormalities """ - in1_kind, in1_err = util.classify_input_file(in1) - in2_kind, in2_err = util.classify_input_file(in2) + in1_kind, _ = util.classify_input_file(in1) + in2_kind, _ = util.classify_input_file(in2) output_file = util.find_benchmark_flag("--benchmark_out=", flags) output_type = util.find_benchmark_flag("--benchmark_out_format=", flags) if ( @@ -85,7 +85,10 @@ def create_parser(): "-d", "--dump_to_json", dest="dump_to_json", - help="Additionally, dump benchmark comparison output to this file in JSON format.", + help=( + "Additionally, dump benchmark comparison output to this file in" + " JSON format." + ), ) utest = parser.add_argument_group() @@ -94,8 +97,15 @@ def create_parser(): dest="utest", default=True, action="store_false", - help="The tool can do a two-tailed Mann-Whitney U test with the null hypothesis that it is equally likely that a randomly selected value from one sample will be less than or greater than a randomly selected value from a second sample.\nWARNING: requires **LARGE** (no less than {}) number of repetitions to be meaningful!\nThe test is being done by default, if at least {} repetitions were done.\nThis option can disable the U Test.".format( - report.UTEST_OPTIMAL_REPETITIONS, report.UTEST_MIN_REPETITIONS + help=( + "The tool can do a two-tailed Mann-Whitney U test with the null" + " hypothesis that it is equally likely that a randomly selected" + " value from one sample will be less than or greater than a" + " randomly selected value from a second sample.\nWARNING: requires" + f" **LARGE** (no less than {report.UTEST_OPTIMAL_REPETITIONS})" + " number of repetitions to be meaningful!\nThe test is being done" + f" by default, if at least {report.UTEST_MIN_REPETITIONS}" + " repetitions were done.\nThis option can disable the U Test." ), ) alpha_default = 0.05 @@ -105,7 +115,9 @@ def create_parser(): default=alpha_default, type=float, help=( - "significance level alpha. if the calculated p-value is below this value, then the result is said to be statistically significant and the null hypothesis is rejected.\n(default: %0.4f)" + "significance level alpha. if the calculated p-value is below this" + " value, then the result is said to be statistically significant" + " and the null hypothesis is rejected.\n(default: %0.4f)" ) % alpha_default, ) @@ -116,7 +128,10 @@ def create_parser(): parser_a = subparsers.add_parser( "benchmarks", - help="The most simple use-case, compare all the output of these two benchmarks", + help=( + "The most simple use-case, compare all the output of these two" + " benchmarks" + ), ) baseline = parser_a.add_argument_group("baseline", "The benchmark baseline") baseline.add_argument( @@ -180,7 +195,10 @@ def create_parser(): parser_c = subparsers.add_parser( "benchmarksfiltered", - help="Compare filter one of first benchmark with filter two of the second benchmark", + help=( + "Compare filter one of first benchmark with filter two of the" + " second benchmark" + ), ) baseline = parser_c.add_argument_group("baseline", "The benchmark baseline") baseline.add_argument( @@ -205,7 +223,10 @@ def create_parser(): metavar="test_contender", type=argparse.FileType("r"), nargs=1, - help="The second benchmark executable or JSON output file, that will be compared against the baseline", + help=( + "The second benchmark executable or JSON output file, that will be" + " compared against the baseline" + ), ) contender.add_argument( "filter_contender", diff --git a/vendor/benchmark-38df9da/tools/gbench/Inputs/test1_run1.json b/vendor/benchmark-4ed29ae/tools/gbench/Inputs/test1_run1.json similarity index 100% rename from vendor/benchmark-38df9da/tools/gbench/Inputs/test1_run1.json rename to vendor/benchmark-4ed29ae/tools/gbench/Inputs/test1_run1.json diff --git a/vendor/benchmark-38df9da/tools/gbench/Inputs/test1_run2.json b/vendor/benchmark-4ed29ae/tools/gbench/Inputs/test1_run2.json similarity index 100% rename from vendor/benchmark-38df9da/tools/gbench/Inputs/test1_run2.json rename to vendor/benchmark-4ed29ae/tools/gbench/Inputs/test1_run2.json diff --git a/vendor/benchmark-38df9da/tools/gbench/Inputs/test2_run.json b/vendor/benchmark-4ed29ae/tools/gbench/Inputs/test2_run.json similarity index 100% rename from vendor/benchmark-38df9da/tools/gbench/Inputs/test2_run.json rename to vendor/benchmark-4ed29ae/tools/gbench/Inputs/test2_run.json diff --git a/vendor/benchmark-38df9da/tools/gbench/Inputs/test3_run0.json b/vendor/benchmark-4ed29ae/tools/gbench/Inputs/test3_run0.json similarity index 100% rename from vendor/benchmark-38df9da/tools/gbench/Inputs/test3_run0.json rename to vendor/benchmark-4ed29ae/tools/gbench/Inputs/test3_run0.json diff --git a/vendor/benchmark-38df9da/tools/gbench/Inputs/test3_run1.json b/vendor/benchmark-4ed29ae/tools/gbench/Inputs/test3_run1.json similarity index 100% rename from vendor/benchmark-38df9da/tools/gbench/Inputs/test3_run1.json rename to vendor/benchmark-4ed29ae/tools/gbench/Inputs/test3_run1.json diff --git a/vendor/benchmark-38df9da/tools/gbench/Inputs/test4_run.json b/vendor/benchmark-4ed29ae/tools/gbench/Inputs/test4_run.json similarity index 100% rename from vendor/benchmark-38df9da/tools/gbench/Inputs/test4_run.json rename to vendor/benchmark-4ed29ae/tools/gbench/Inputs/test4_run.json diff --git a/vendor/benchmark-38df9da/tools/gbench/Inputs/test4_run0.json b/vendor/benchmark-4ed29ae/tools/gbench/Inputs/test4_run0.json similarity index 100% rename from vendor/benchmark-38df9da/tools/gbench/Inputs/test4_run0.json rename to vendor/benchmark-4ed29ae/tools/gbench/Inputs/test4_run0.json diff --git a/vendor/benchmark-38df9da/tools/gbench/Inputs/test4_run1.json b/vendor/benchmark-4ed29ae/tools/gbench/Inputs/test4_run1.json similarity index 100% rename from vendor/benchmark-38df9da/tools/gbench/Inputs/test4_run1.json rename to vendor/benchmark-4ed29ae/tools/gbench/Inputs/test4_run1.json diff --git a/vendor/benchmark-38df9da/tools/gbench/Inputs/test5_run0.json b/vendor/benchmark-4ed29ae/tools/gbench/Inputs/test5_run0.json similarity index 100% rename from vendor/benchmark-38df9da/tools/gbench/Inputs/test5_run0.json rename to vendor/benchmark-4ed29ae/tools/gbench/Inputs/test5_run0.json diff --git a/vendor/benchmark-38df9da/tools/gbench/Inputs/test5_run1.json b/vendor/benchmark-4ed29ae/tools/gbench/Inputs/test5_run1.json similarity index 100% rename from vendor/benchmark-38df9da/tools/gbench/Inputs/test5_run1.json rename to vendor/benchmark-4ed29ae/tools/gbench/Inputs/test5_run1.json diff --git a/vendor/benchmark-38df9da/tools/gbench/__init__.py b/vendor/benchmark-4ed29ae/tools/gbench/__init__.py similarity index 100% rename from vendor/benchmark-38df9da/tools/gbench/__init__.py rename to vendor/benchmark-4ed29ae/tools/gbench/__init__.py diff --git a/vendor/benchmark-38df9da/tools/gbench/report.py b/vendor/benchmark-4ed29ae/tools/gbench/report.py similarity index 94% rename from vendor/benchmark-38df9da/tools/gbench/report.py rename to vendor/benchmark-4ed29ae/tools/gbench/report.py index 7158fd165..e143e45a7 100644 --- a/vendor/benchmark-38df9da/tools/gbench/report.py +++ b/vendor/benchmark-4ed29ae/tools/gbench/report.py @@ -14,7 +14,7 @@ from scipy.stats import gmean, mannwhitneyu -class BenchmarkColor(object): +class BenchmarkColor: def __init__(self, name, code): self.name = name self.code = code @@ -249,8 +249,9 @@ def get_utest_color(pval): # We still got some results to show but issue a warning about it. if not utest["have_optimal_repetitions"]: dsc_color = BC_WARNING - dsc += ". WARNING: Results unreliable! {}+ repetitions recommended.".format( - UTEST_OPTIMAL_REPETITIONS + dsc += ( + f". WARNING: Results unreliable! {UTEST_OPTIMAL_REPETITIONS}+" + " repetitions recommended." ) special_str = "{}{:<{}s}{endc}{}{:16.4f}{endc}{}{:16.4f}{endc}{} {}" @@ -260,7 +261,7 @@ def get_utest_color(pval): use_color, special_str, BC_HEADER, - "{}{}".format(bc_name, UTEST_COL_NAME), + f"{bc_name}{UTEST_COL_NAME}", first_col_width, get_utest_color(utest["time_pvalue"]), utest["time_pvalue"], @@ -285,7 +286,7 @@ def get_difference_report(json1, json2, utest=False): partitions = partition_benchmarks(json1, json2) for partition in partitions: benchmark_name = partition[0][0]["name"] - label = partition[0][0]["label"] if "label" in partition[0][0] else "" + label = partition[0][0].get("label", "") time_unit = partition[0][0]["time_unit"] measurements = [] utest_results = {} @@ -329,11 +330,7 @@ def get_difference_report(json1, json2, utest=False): # time units which are not compatible with other time units in the # benchmark suite. if measurements: - run_type = ( - partition[0][0]["run_type"] - if "run_type" in partition[0][0] - else "" - ) + run_type = partition[0][0].get("run_type", "") aggregate_name = ( partition[0][0]["aggregate_name"] if run_type == "aggregate" @@ -403,12 +400,17 @@ def get_color(res): first_col_width = find_longest_name(json_diff_report) first_col_width = max(first_col_width, len("Benchmark")) first_col_width += len(UTEST_COL_NAME) - first_line = "{:<{}s}Time CPU Time Old Time New CPU Old CPU New".format( - "Benchmark", 12 + first_col_width + fmt_str = ( + "{:<{}s}Time CPU Time Old Time New CPU Old" + " CPU New" ) + first_line = fmt_str.format("Benchmark", 12 + first_col_width) output_strs = [first_line, "-" * len(first_line)] - fmt_str = "{}{:<{}s}{endc}{}{:+16.4f}{endc}{}{:+16.4f}{endc}{:14.0f}{:14.0f}{endc}{:14.0f}{:14.0f}" + fmt_str = ( + "{}{:<{}s}{endc}{}{:+16.4f}{endc}{}{:+16.4f}{endc}{:14.0f}{:14.0f}" + "{endc}{:14.0f}{:14.0f}" + ) for benchmark in json_diff_report: # *If* we were asked to only include aggregates, # and if it is non-aggregate, then don't print it. @@ -464,7 +466,7 @@ def load_results(self): os.path.dirname(os.path.realpath(__file__)), "Inputs" ) testOutput = os.path.join(testInputs, "test3_run0.json") - with open(testOutput, "r") as f: + with open(testOutput) as f: json = json.load(f) return json @@ -480,8 +482,8 @@ def test_basic(self): print("\n") print("\n".join(output_lines)) self.assertEqual(len(output_lines), len(expect_lines)) - for i in range(0, len(output_lines)): - self.assertEqual(expect_lines[i], output_lines[i]) + for i, output_line in enumerate(output_lines): + self.assertEqual(expect_lines[i], output_line) class TestReportDifference(unittest.TestCase): @@ -495,9 +497,9 @@ def load_results(): ) testOutput1 = os.path.join(testInputs, "test1_run1.json") testOutput2 = os.path.join(testInputs, "test1_run2.json") - with open(testOutput1, "r") as f: + with open(testOutput1) as f: json1 = json.load(f) - with open(testOutput2, "r") as f: + with open(testOutput2) as f: json2 = json.load(f) return json1, json2 @@ -584,8 +586,8 @@ def test_json_diff_report_pretty_printing(self): print("\n") print("\n".join(output_lines_with_header)) self.assertEqual(len(output_lines), len(expect_lines)) - for i in range(0, len(output_lines)): - parts = [x for x in output_lines[i].split(" ") if x] + for i, output_line in enumerate(output_lines): + parts = [x for x in output_line.split(" ") if x] self.assertEqual(len(parts), 7) self.assertEqual(expect_lines[i], parts) @@ -819,7 +821,9 @@ def test_json_diff_report_output(self): }, ] self.assertEqual(len(self.json_diff_report), len(expected_output)) - for out, expected in zip(self.json_diff_report, expected_output): + for out, expected in zip( + self.json_diff_report, expected_output, strict=True + ): self.assertEqual(out["name"], expected["name"]) self.assertEqual(out["label"], expected["label"]) self.assertEqual(out["time_unit"], expected["time_unit"]) @@ -837,7 +841,7 @@ def load_result(): os.path.dirname(os.path.realpath(__file__)), "Inputs" ) testOutput = os.path.join(testInputs, "test2_run.json") - with open(testOutput, "r") as f: + with open(testOutput) as f: json = json.load(f) return json @@ -861,8 +865,8 @@ def test_json_diff_report_pretty_printing(self): print("\n") print("\n".join(output_lines_with_header)) self.assertEqual(len(output_lines), len(expect_lines)) - for i in range(0, len(output_lines)): - parts = [x for x in output_lines[i].split(" ") if x] + for i, output_line in enumerate(output_lines): + parts = [x for x in output_line.split(" ") if x] self.assertEqual(len(parts), 7) self.assertEqual(expect_lines[i], parts) @@ -947,7 +951,9 @@ def test_json_diff_report(self): }, ] self.assertEqual(len(self.json_diff_report), len(expected_output)) - for out, expected in zip(self.json_diff_report, expected_output): + for out, expected in zip( + self.json_diff_report, expected_output, strict=True + ): self.assertEqual(out["name"], expected["name"]) self.assertEqual(out["time_unit"], expected["time_unit"]) assert_utest(self, out, expected) @@ -965,9 +971,9 @@ def load_results(): ) testOutput1 = os.path.join(testInputs, "test3_run0.json") testOutput2 = os.path.join(testInputs, "test3_run1.json") - with open(testOutput1, "r") as f: + with open(testOutput1) as f: json1 = json.load(f) - with open(testOutput2, "r") as f: + with open(testOutput2) as f: json2 = json.load(f) return json1, json2 @@ -1025,8 +1031,8 @@ def test_json_diff_report_pretty_printing(self): print("\n") print("\n".join(output_lines_with_header)) self.assertEqual(len(output_lines), len(expect_lines)) - for i in range(0, len(output_lines)): - parts = [x for x in output_lines[i].split(" ") if x] + for i, output_line in enumerate(output_lines): + parts = [x for x in output_line.split(" ") if x] self.assertEqual(expect_lines[i], parts) def test_json_diff_report_pretty_printing_aggregates_only(self): @@ -1081,8 +1087,8 @@ def test_json_diff_report_pretty_printing_aggregates_only(self): print("\n") print("\n".join(output_lines_with_header)) self.assertEqual(len(output_lines), len(expect_lines)) - for i in range(0, len(output_lines)): - parts = [x for x in output_lines[i].split(" ") if x] + for i, output_line in enumerate(output_lines): + parts = [x for x in output_line.split(" ") if x] self.assertEqual(expect_lines[i], parts) def test_json_diff_report(self): @@ -1190,7 +1196,9 @@ def test_json_diff_report(self): }, ] self.assertEqual(len(self.json_diff_report), len(expected_output)) - for out, expected in zip(self.json_diff_report, expected_output): + for out, expected in zip( + self.json_diff_report, expected_output, strict=True + ): self.assertEqual(out["name"], expected["name"]) self.assertEqual(out["time_unit"], expected["time_unit"]) assert_utest(self, out, expected) @@ -1210,9 +1218,9 @@ def load_results(): ) testOutput1 = os.path.join(testInputs, "test3_run0.json") testOutput2 = os.path.join(testInputs, "test3_run1.json") - with open(testOutput1, "r") as f: + with open(testOutput1) as f: json1 = json.load(f) - with open(testOutput2, "r") as f: + with open(testOutput2) as f: json2 = json.load(f) return json1, json2 @@ -1270,8 +1278,8 @@ def test_json_diff_report_pretty_printing(self): print("\n") print("\n".join(output_lines_with_header)) self.assertEqual(len(output_lines), len(expect_lines)) - for i in range(0, len(output_lines)): - parts = [x for x in output_lines[i].split(" ") if x] + for i, output_line in enumerate(output_lines): + parts = [x for x in output_line.split(" ") if x] self.assertEqual(expect_lines[i], parts) def test_json_diff_report(self): @@ -1380,7 +1388,9 @@ def test_json_diff_report(self): }, ] self.assertEqual(len(self.json_diff_report), len(expected_output)) - for out, expected in zip(self.json_diff_report, expected_output): + for out, expected in zip( + self.json_diff_report, expected_output, strict=True + ): self.assertEqual(out["name"], expected["name"]) self.assertEqual(out["time_unit"], expected["time_unit"]) assert_utest(self, out, expected) @@ -1398,9 +1408,9 @@ def load_results(): ) testOutput1 = os.path.join(testInputs, "test4_run0.json") testOutput2 = os.path.join(testInputs, "test4_run1.json") - with open(testOutput1, "r") as f: + with open(testOutput1) as f: json1 = json.load(f) - with open(testOutput2, "r") as f: + with open(testOutput2) as f: json2 = json.load(f) return json1, json2 @@ -1416,8 +1426,8 @@ def test_json_diff_report_pretty_printing(self): print("\n") print("\n".join(output_lines_with_header)) self.assertEqual(len(output_lines), len(expect_lines)) - for i in range(0, len(output_lines)): - parts = [x for x in output_lines[i].split(" ") if x] + for i, output_line in enumerate(output_lines): + parts = [x for x in output_line.split(" ") if x] self.assertEqual(expect_lines[i], parts) def test_json_diff_report(self): @@ -1439,7 +1449,9 @@ def test_json_diff_report(self): } ] self.assertEqual(len(self.json_diff_report), len(expected_output)) - for out, expected in zip(self.json_diff_report, expected_output): + for out, expected in zip( + self.json_diff_report, expected_output, strict=True + ): self.assertEqual(out["name"], expected["name"]) self.assertEqual(out["time_unit"], expected["time_unit"]) assert_utest(self, out, expected) @@ -1456,7 +1468,7 @@ def load_result(): os.path.dirname(os.path.realpath(__file__)), "Inputs" ) testOutput = os.path.join(testInputs, "test4_run.json") - with open(testOutput, "r") as f: + with open(testOutput) as f: json = json.load(f) return json @@ -1480,13 +1492,15 @@ def test_json_diff_report_pretty_printing(self): "88 family 1 instance 1 aggregate", ] - for n in range(len(self.json["benchmarks"]) ** 2): + for _n in range(len(self.json["benchmarks"]) ** 2): random.shuffle(self.json["benchmarks"]) sorted_benchmarks = util.sort_benchmark_results(self.json)[ "benchmarks" ] self.assertEqual(len(expected_names), len(sorted_benchmarks)) - for out, expected in zip(sorted_benchmarks, expected_names): + for out, expected in zip( + sorted_benchmarks, expected_names, strict=True + ): self.assertEqual(out["name"], expected) @@ -1503,12 +1517,12 @@ def load_results(): ) testOutput1 = os.path.join(testInputs, "test5_run0.json") testOutput2 = os.path.join(testInputs, "test5_run1.json") - with open(testOutput1, "r") as f: + with open(testOutput1) as f: json1 = json.load(f) json1["benchmarks"] = [ json1["benchmarks"][0] for i in range(1000) ] - with open(testOutput2, "r") as f: + with open(testOutput2) as f: json2 = json.load(f) json2["benchmarks"] = [ json2["benchmarks"][0] for i in range(1000) @@ -1535,8 +1549,8 @@ def test_json_diff_report_pretty_printing(self): ) output_lines = output_lines_with_header[2:] found = False - for i in range(0, len(output_lines)): - parts = [x for x in output_lines[i].split(" ") if x] + for output_line in output_lines: + parts = [x for x in output_line.split(" ") if x] found = expect_line == parts if found: break @@ -1578,7 +1592,9 @@ def test_json_diff_report(self): }, ] self.assertEqual(len(self.json_diff_report), len(expected_output)) - for out, expected in zip(self.json_diff_report, expected_output): + for out, expected in zip( + self.json_diff_report, expected_output, strict=True + ): self.assertEqual(out["name"], expected["name"]) self.assertEqual(out["time_unit"], expected["time_unit"]) assert_utest(self, out, expected) @@ -1602,7 +1618,7 @@ def assert_utest(unittest_instance, lhs, rhs): def assert_measurements(unittest_instance, lhs, rhs): - for m1, m2 in zip(lhs["measurements"], rhs["measurements"]): + for m1, m2 in zip(lhs["measurements"], rhs["measurements"], strict=False): unittest_instance.assertEqual(m1["real_time"], m2["real_time"]) unittest_instance.assertEqual(m1["cpu_time"], m2["cpu_time"]) # m1['time'] and m1['cpu'] hold values which are being calculated, diff --git a/vendor/benchmark-38df9da/tools/gbench/util.py b/vendor/benchmark-4ed29ae/tools/gbench/util.py similarity index 84% rename from vendor/benchmark-38df9da/tools/gbench/util.py rename to vendor/benchmark-4ed29ae/tools/gbench/util.py index 1119a1a2c..2e91006be 100644 --- a/vendor/benchmark-38df9da/tools/gbench/util.py +++ b/vendor/benchmark-4ed29ae/tools/gbench/util.py @@ -1,4 +1,6 @@ -"""util.py - General utilities for running, loading, and processing benchmarks""" +"""util.py - General utilities for running, loading, and processing +benchmarks +""" import json import os @@ -46,7 +48,7 @@ def is_json_file(filename): 'False' otherwise. """ try: - with open(filename, "r") as f: + with open(filename) as f: json.load(f) return True except BaseException: @@ -97,7 +99,8 @@ def find_benchmark_flag(prefix, benchmark_flags): if it is found return the arg it specifies. If specified more than once the last value is returned. If the flag is not found None is returned. """ - assert prefix.startswith("--") and prefix.endswith("=") + assert prefix.startswith("--") + assert prefix.endswith("=") result = None for f in benchmark_flags: if f.startswith(prefix): @@ -110,7 +113,8 @@ def remove_benchmark_flags(prefix, benchmark_flags): Return a new list containing the specified benchmark_flags except those with the specified prefix. """ - assert prefix.startswith("--") and prefix.endswith("=") + assert prefix.startswith("--") + assert prefix.endswith("=") return [f for f in benchmark_flags if not f.startswith(prefix)] @@ -133,17 +137,16 @@ def benchmark_wanted(benchmark): name = benchmark.get("run_name", None) or benchmark["name"] return re.search(benchmark_filter, name) is not None - with open(fname, "r") as f: + with open(fname) as f: results = json.load(f) - if "context" in results: - if "json_schema_version" in results["context"]: - json_schema_version = results["context"]["json_schema_version"] - if json_schema_version != 1: - print( - "In %s, got unnsupported JSON schema version: %i, expected 1" - % (fname, json_schema_version) - ) - sys.exit(1) + if "json_schema_version" in results.get("context", {}): + json_schema_version = results["context"]["json_schema_version"] + if json_schema_version != 1: + print( + f"In {fname}, got unnsupported JSON schema version:" + f" {json_schema_version}, expected 1" + ) + sys.exit(1) if "benchmarks" in results: results["benchmarks"] = list( filter(benchmark_wanted, results["benchmarks"]) @@ -157,9 +160,7 @@ def sort_benchmark_results(result): # From inner key to the outer key! benchmarks = sorted( benchmarks, - key=lambda benchmark: benchmark["repetition_index"] - if "repetition_index" in benchmark - else -1, + key=lambda benchmark: benchmark.get("repetition_index", -1), ) benchmarks = sorted( benchmarks, @@ -169,15 +170,11 @@ def sort_benchmark_results(result): ) benchmarks = sorted( benchmarks, - key=lambda benchmark: benchmark["per_family_instance_index"] - if "per_family_instance_index" in benchmark - else -1, + key=lambda benchmark: benchmark.get("per_family_instance_index", -1), ) benchmarks = sorted( benchmarks, - key=lambda benchmark: benchmark["family_index"] - if "family_index" in benchmark - else -1, + key=lambda benchmark: benchmark.get("family_index", -1), ) result["benchmarks"] = benchmarks @@ -197,11 +194,12 @@ def run_benchmark(exe_name, benchmark_flags): is_temp_output = True thandle, output_name = tempfile.mkstemp() os.close(thandle) - benchmark_flags = list(benchmark_flags) + [ - "--benchmark_out=%s" % output_name + benchmark_flags = [ + *list(benchmark_flags), + "--benchmark_out=%s" % output_name, ] - cmd = [exe_name] + benchmark_flags + cmd = [exe_name, *benchmark_flags] print("RUNNING: %s" % " ".join(cmd)) exitCode = subprocess.call(cmd) if exitCode != 0: diff --git a/vendor/benchmark-4ed29ae/tools/libpfm.BUILD.bazel b/vendor/benchmark-4ed29ae/tools/libpfm.BUILD.bazel new file mode 100644 index 000000000..30b585452 --- /dev/null +++ b/vendor/benchmark-4ed29ae/tools/libpfm.BUILD.bazel @@ -0,0 +1,242 @@ +"""Build rule for libpfm, which is required to collect performance counters for BENCHMARK_ENABLE_LIBPFM builds.""" + +load("@rules_cc//cc:defs.bzl", "cc_library") + +AARCH32_SRCS_COMMON = [ + "lib/pfmlib_arm.c", + "lib/pfmlib_arm_armv7_pmuv1.c", + "lib/pfmlib_arm_armv6.c", + "lib/pfmlib_arm_armv8.c", + "lib/pfmlib_tx2_unc_perf_event.c", +] + +AARCH32_SRCS_LINUX = [ + "lib/pfmlib_arm_perf_event.c", +] + +AARCH64_SRCS_COMMON = [ + "lib/pfmlib_arm.c", + "lib/pfmlib_arm_armv8.c", + "lib/pfmlib_tx2_unc_perf_event.c", +] + +AARCH64_SRCS_LINUX = [ + "lib/pfmlib_arm_perf_event.c", +] + +MIPS_SRCS_COMMON = [ + "lib/pfmlib_mips.c", + "lib/pfmlib_mips_74k.c", +] + +MIPS_SRCS_LINUX = [ + "lib/pfmlib_mips_perf_event.c", +] + +POWERPC_SRCS_COMMON = [ + "lib/pfmlib_powerpc.c", + "lib/pfmlib_power4.c", + "lib/pfmlib_ppc970.c", + "lib/pfmlib_power5.c", + "lib/pfmlib_power6.c", + "lib/pfmlib_power7.c", + "lib/pfmlib_torrent.c", + "lib/pfmlib_power8.c", + "lib/pfmlib_power9.c", + "lib/pfmlib_powerpc_nest.c", +] + +POWERPC_SRCS_LINUX = [ + "lib/pfmlib_powerpc_perf_event.c", +] + +S390X_SRCS_COMMON = [ + "lib/pfmlib_s390x_cpumf.c", +] + +S390X_SRCS_LINUX = [ + "lib/pfmlib_s390x_perf_event.c", +] + +X86_64_SRCS_COMMON = [ + "lib/pfmlib_amd64.c", + "lib/pfmlib_intel_core.c", + "lib/pfmlib_intel_x86.c", + "lib/pfmlib_intel_x86_arch.c", + "lib/pfmlib_intel_atom.c", + "lib/pfmlib_intel_nhm_unc.c", + "lib/pfmlib_intel_nhm.c", + "lib/pfmlib_intel_wsm.c", + "lib/pfmlib_intel_snb.c", + "lib/pfmlib_intel_snb_unc.c", + "lib/pfmlib_intel_ivb.c", + "lib/pfmlib_intel_ivb_unc.c", + "lib/pfmlib_intel_hsw.c", + "lib/pfmlib_intel_bdw.c", + "lib/pfmlib_intel_skl.c", + "lib/pfmlib_intel_icl.c", + "lib/pfmlib_intel_rapl.c", + "lib/pfmlib_intel_snbep_unc.c", + "lib/pfmlib_intel_snbep_unc_cbo.c", + "lib/pfmlib_intel_snbep_unc_ha.c", + "lib/pfmlib_intel_snbep_unc_imc.c", + "lib/pfmlib_intel_snbep_unc_pcu.c", + "lib/pfmlib_intel_snbep_unc_qpi.c", + "lib/pfmlib_intel_snbep_unc_ubo.c", + "lib/pfmlib_intel_snbep_unc_r2pcie.c", + "lib/pfmlib_intel_snbep_unc_r3qpi.c", + "lib/pfmlib_intel_ivbep_unc_cbo.c", + "lib/pfmlib_intel_ivbep_unc_ha.c", + "lib/pfmlib_intel_ivbep_unc_imc.c", + "lib/pfmlib_intel_ivbep_unc_pcu.c", + "lib/pfmlib_intel_ivbep_unc_qpi.c", + "lib/pfmlib_intel_ivbep_unc_ubo.c", + "lib/pfmlib_intel_ivbep_unc_r2pcie.c", + "lib/pfmlib_intel_ivbep_unc_r3qpi.c", + "lib/pfmlib_intel_ivbep_unc_irp.c", + "lib/pfmlib_intel_hswep_unc_cbo.c", + "lib/pfmlib_intel_hswep_unc_ha.c", + "lib/pfmlib_intel_hswep_unc_imc.c", + "lib/pfmlib_intel_hswep_unc_pcu.c", + "lib/pfmlib_intel_hswep_unc_qpi.c", + "lib/pfmlib_intel_hswep_unc_ubo.c", + "lib/pfmlib_intel_hswep_unc_r2pcie.c", + "lib/pfmlib_intel_hswep_unc_r3qpi.c", + "lib/pfmlib_intel_hswep_unc_irp.c", + "lib/pfmlib_intel_hswep_unc_sbo.c", + "lib/pfmlib_intel_bdx_unc_cbo.c", + "lib/pfmlib_intel_bdx_unc_ubo.c", + "lib/pfmlib_intel_bdx_unc_sbo.c", + "lib/pfmlib_intel_bdx_unc_ha.c", + "lib/pfmlib_intel_bdx_unc_imc.c", + "lib/pfmlib_intel_bdx_unc_irp.c", + "lib/pfmlib_intel_bdx_unc_pcu.c", + "lib/pfmlib_intel_bdx_unc_qpi.c", + "lib/pfmlib_intel_bdx_unc_r2pcie.c", + "lib/pfmlib_intel_bdx_unc_r3qpi.c", + "lib/pfmlib_intel_skx_unc_cha.c", + "lib/pfmlib_intel_skx_unc_iio.c", + "lib/pfmlib_intel_skx_unc_imc.c", + "lib/pfmlib_intel_skx_unc_irp.c", + "lib/pfmlib_intel_skx_unc_m2m.c", + "lib/pfmlib_intel_skx_unc_m3upi.c", + "lib/pfmlib_intel_skx_unc_pcu.c", + "lib/pfmlib_intel_skx_unc_ubo.c", + "lib/pfmlib_intel_skx_unc_upi.c", + "lib/pfmlib_intel_knc.c", + "lib/pfmlib_intel_slm.c", + "lib/pfmlib_intel_tmt.c", + "lib/pfmlib_intel_knl.c", + "lib/pfmlib_intel_knl_unc_imc.c", + "lib/pfmlib_intel_knl_unc_edc.c", + "lib/pfmlib_intel_knl_unc_cha.c", + "lib/pfmlib_intel_knl_unc_m2pcie.c", + "lib/pfmlib_intel_glm.c", + "lib/pfmlib_intel_netburst.c", + "lib/pfmlib_amd64_k7.c", + "lib/pfmlib_amd64_k8.c", + "lib/pfmlib_amd64_fam10h.c", + "lib/pfmlib_amd64_fam11h.c", + "lib/pfmlib_amd64_fam12h.c", + "lib/pfmlib_amd64_fam14h.c", + "lib/pfmlib_amd64_fam15h.c", + "lib/pfmlib_amd64_fam17h.c", + "lib/pfmlib_amd64_fam16h.c", +] + +X86_SRCS_COMMON = X86_64_SRCS_COMMON + [ + "lib/pfmlib_intel_coreduo.c", + "lib/pfmlib_intel_p6.c", +] + +filegroup( + name = "cpu_srcs", + srcs = select({ + "@platforms//cpu:x86_32": X86_SRCS_COMMON, + "@platforms//cpu:x86_64": X86_64_SRCS_COMMON, + "@platforms//cpu:aarch32": AARCH32_SRCS_COMMON, + "@platforms//cpu:aarch64": AARCH64_SRCS_COMMON, + "@platforms//cpu:mips64": MIPS_SRCS_COMMON, + "@platforms//cpu:ppc32": POWERPC_SRCS_COMMON, + "@platforms//cpu:ppc64le": POWERPC_SRCS_COMMON, + "@platforms//cpu:ppc": POWERPC_SRCS_COMMON, + "@platforms//cpu:s390x": S390X_SRCS_COMMON, + "//conditions:default": [], + }), +) + +filegroup( + name = "linux_srcs", + srcs = select({ + "@platforms//cpu:aarch32": AARCH32_SRCS_LINUX, + "@platforms//cpu:aarch64": AARCH64_SRCS_LINUX, + "@platforms//cpu:mips64": MIPS_SRCS_LINUX, + "@platforms//cpu:ppc32": POWERPC_SRCS_LINUX, + "@platforms//cpu:ppc64le": POWERPC_SRCS_LINUX, + "@platforms//cpu:ppc": POWERPC_SRCS_LINUX, + "@platforms//cpu:s390x": S390X_SRCS_LINUX, + "//conditions:default": [], + }), +) + +filegroup( + name = "srcs", + srcs = [ + "lib/pfmlib_common.c", + "lib/pfmlib_perf_event.c", + "lib/pfmlib_perf_event_pmu.c", + "lib/pfmlib_perf_event_priv.h", + "lib/pfmlib_perf_event_raw.c", + "lib/pfmlib_torrent.c", + "lib/pfmlib_tx2_unc_perf_event.c", + ":cpu_srcs", + ] + select({ + "@platforms//os:linux": [":linux_srcs"], + "//conditions:default": [], + }), +) + +cc_library( + name = "pfm", + srcs = [ + ":srcs", + ], + hdrs = glob([ + "include/perfmon/*.h", + ]), + copts = [ + "-Wno-format-truncation", + "-Wno-use-after-free", + "-fPIC", + "-D_REENTRANT", + "-fvisibility=hidden", + ] + select({ + "@platforms//cpu:aarch32": ["-DCONFIG_PFMLIB_ARCH_ARM"], + "@platforms//cpu:aarch64": ["-DCONFIG_PFMLIB_ARCH_ARM64"], + "@platforms//cpu:mips64": ["-DCONFIG_PFMLIB_ARCH_MIPS"], + "@platforms//cpu:ppc32": ["-DCONFIG_PFMLIB_ARCH_POWERPC"], + "@platforms//cpu:ppc64le": ["-DCONFIG_PFMLIB_ARCH_POWERPC"], + "@platforms//cpu:ppc": ["-DCONFIG_PFMLIB_ARCH_POWERPC"], + "@platforms//cpu:s390x": ["-DCONFIG_PFMLIB_ARCH_S390X"], + "//conditions:default": [], + }), + includes = [ + "include", + "lib", + ], + strip_include_prefix = "include", + textual_hdrs = glob([ + "lib/**/*.h", + ]), + visibility = [ + "//visibility:public", + ], +) + +alias( + name = "libpfm", + actual = ":pfm", + visibility = [ + "//visibility:public", + ], +) diff --git a/vendor/benchmark-4ed29ae/tools/requirements.txt b/vendor/benchmark-4ed29ae/tools/requirements.txt new file mode 100644 index 000000000..12d5d9ce9 --- /dev/null +++ b/vendor/benchmark-4ed29ae/tools/requirements.txt @@ -0,0 +1,2 @@ +numpy == 2.4.1 +scipy == 1.17.0 diff --git a/vendor/benchmark-38df9da/tools/strip_asm.py b/vendor/benchmark-4ed29ae/tools/strip_asm.py similarity index 94% rename from vendor/benchmark-38df9da/tools/strip_asm.py rename to vendor/benchmark-4ed29ae/tools/strip_asm.py index bc3a774a7..f49a8c85a 100755 --- a/vendor/benchmark-38df9da/tools/strip_asm.py +++ b/vendor/benchmark-4ed29ae/tools/strip_asm.py @@ -73,16 +73,16 @@ def process_identifiers(line): parts = re.split(r"([a-zA-Z0-9_]+)", line) new_line = "" for tk in parts: - if is_identifier(tk): - if tk.startswith("__Z"): - tk = tk[1:] - elif ( + if is_identifier(tk) and ( + tk.startswith("__Z") + or ( tk.startswith("_") and len(tk) > 1 and tk[1].isalpha() and tk[1] != "Z" - ): - tk = tk[1:] + ) + ): + tk = tk[1:] new_line += tk return new_line @@ -141,14 +141,14 @@ def main(): parser.add_argument( "out", metavar="output", type=str, nargs=1, help="The output file" ) - args, unknown_args = parser.parse_known_args() + args, _ = parser.parse_known_args() input = args.input[0] output = args.out[0] if not os.path.isfile(input): print("ERROR: input file '%s' does not exist" % input) sys.exit(1) - with open(input, "r") as f: + with open(input) as f: contents = f.read() new_contents = process_asm(contents) with open(output, "w") as f: diff --git a/vendor/googletest-b4aaf97/.clang-format b/vendor/googletest-56efe39/.clang-format similarity index 100% rename from vendor/googletest-b4aaf97/.clang-format rename to vendor/googletest-56efe39/.clang-format diff --git a/vendor/googletest-b4aaf97/.github/ISSUE_TEMPLATE/00-bug_report.yml b/vendor/googletest-56efe39/.github/ISSUE_TEMPLATE/00-bug_report.yml similarity index 100% rename from vendor/googletest-b4aaf97/.github/ISSUE_TEMPLATE/00-bug_report.yml rename to vendor/googletest-56efe39/.github/ISSUE_TEMPLATE/00-bug_report.yml diff --git a/vendor/googletest-b4aaf97/.github/ISSUE_TEMPLATE/10-feature_request.yml b/vendor/googletest-56efe39/.github/ISSUE_TEMPLATE/10-feature_request.yml similarity index 100% rename from vendor/googletest-b4aaf97/.github/ISSUE_TEMPLATE/10-feature_request.yml rename to vendor/googletest-56efe39/.github/ISSUE_TEMPLATE/10-feature_request.yml diff --git a/vendor/googletest-b4aaf97/.github/ISSUE_TEMPLATE/config.yml b/vendor/googletest-56efe39/.github/ISSUE_TEMPLATE/config.yml similarity index 100% rename from vendor/googletest-b4aaf97/.github/ISSUE_TEMPLATE/config.yml rename to vendor/googletest-56efe39/.github/ISSUE_TEMPLATE/config.yml diff --git a/vendor/googletest-56efe39/.gitignore b/vendor/googletest-56efe39/.gitignore new file mode 100644 index 000000000..f0df39db1 --- /dev/null +++ b/vendor/googletest-56efe39/.gitignore @@ -0,0 +1,89 @@ +# Ignore CI build directory +build/ +xcuserdata +cmake-build-debug/ +.idea/ +bazel-bin +bazel-genfiles +bazel-googletest +bazel-out +bazel-testlogs +MODULE.bazel.lock +# python +*.pyc + +# Visual Studio files +.vs +*.sdf +*.opensdf +*.VC.opendb +*.suo +*.user +_ReSharper.Caches/ +Win32-Debug/ +Win32-Release/ +x64-Debug/ +x64-Release/ + +# VSCode files +.cache/ +cmake-variants.yaml + +# Ignore autoconf / automake files +Makefile.in +aclocal.m4 +configure +build-aux/ +autom4te.cache/ +googletest/m4/libtool.m4 +googletest/m4/ltoptions.m4 +googletest/m4/ltsugar.m4 +googletest/m4/ltversion.m4 +googletest/m4/lt~obsolete.m4 +googlemock/m4 + +# Ignore generated directories. +googlemock/fused-src/ +googletest/fused-src/ + +# macOS files +.DS_Store +googletest/.DS_Store +googletest/xcode/.DS_Store + +# Ignore cmake generated directories and files. +CMakeFiles +CTestTestfile.cmake +Makefile +cmake_install.cmake +googlemock/CMakeFiles +googlemock/CTestTestfile.cmake +googlemock/Makefile +googlemock/cmake_install.cmake +googlemock/gtest +/bin +/googlemock/gmock.dir +/googlemock/gmock_main.dir +/googlemock/RUN_TESTS.vcxproj.filters +/googlemock/RUN_TESTS.vcxproj +/googlemock/INSTALL.vcxproj.filters +/googlemock/INSTALL.vcxproj +/googlemock/gmock_main.vcxproj.filters +/googlemock/gmock_main.vcxproj +/googlemock/gmock.vcxproj.filters +/googlemock/gmock.vcxproj +/googlemock/gmock.sln +/googlemock/ALL_BUILD.vcxproj.filters +/googlemock/ALL_BUILD.vcxproj +/lib +/Win32 +/ZERO_CHECK.vcxproj.filters +/ZERO_CHECK.vcxproj +/RUN_TESTS.vcxproj.filters +/RUN_TESTS.vcxproj +/INSTALL.vcxproj.filters +/INSTALL.vcxproj +/googletest-distribution.sln +/CMakeCache.txt +/ALL_BUILD.vcxproj.filters +/ALL_BUILD.vcxproj diff --git a/vendor/googletest-b4aaf97/BUILD.bazel b/vendor/googletest-56efe39/BUILD.bazel similarity index 85% rename from vendor/googletest-b4aaf97/BUILD.bazel rename to vendor/googletest-56efe39/BUILD.bazel index e407ae29f..5ab4e114f 100644 --- a/vendor/googletest-b4aaf97/BUILD.bazel +++ b/vendor/googletest-56efe39/BUILD.bazel @@ -30,6 +30,8 @@ # # Bazel Build for Google C++ Testing Framework(Google Test) +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") + package(default_visibility = ["//visibility:public"]) licenses(["notice"]) @@ -83,6 +85,10 @@ cc_library( ) # Google Test including Google Mock + +# For an actual test, use `gtest` and also `gtest_main` if you depend on gtest's +# main(). For a library, use `gtest_for_library` instead if the library can be +# testonly. cc_library( name = "gtest", srcs = glob( @@ -138,19 +144,16 @@ cc_library( }), deps = select({ ":has_absl": [ - "@com_google_absl//absl/container:flat_hash_set", - "@com_google_absl//absl/debugging:failure_signal_handler", - "@com_google_absl//absl/debugging:stacktrace", - "@com_google_absl//absl/debugging:symbolize", - "@com_google_absl//absl/flags:flag", - "@com_google_absl//absl/flags:parse", - "@com_google_absl//absl/flags:reflection", - "@com_google_absl//absl/flags:usage", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/types:any", - "@com_google_absl//absl/types:optional", - "@com_google_absl//absl/types:variant", - "@com_googlesource_code_re2//:re2", + "@abseil-cpp//absl/container:flat_hash_set", + "@abseil-cpp//absl/debugging:failure_signal_handler", + "@abseil-cpp//absl/debugging:stacktrace", + "@abseil-cpp//absl/debugging:symbolize", + "@abseil-cpp//absl/flags:flag", + "@abseil-cpp//absl/flags:parse", + "@abseil-cpp//absl/flags:reflection", + "@abseil-cpp//absl/flags:usage", + "@abseil-cpp//absl/strings", + "@re2", ], "//conditions:default": [], }) + select({ @@ -160,13 +163,22 @@ cc_library( # Otherwise, builds targeting Fuchsia would fail to compile. ":fuchsia": [ "@fuchsia_sdk//pkg/fdio", - "@fuchsia_sdk//pkg/syslog", "@fuchsia_sdk//pkg/zx", ], "//conditions:default": [], }), ) +# `gtest`, but testonly. See guidance on `gtest` for when to use this. +alias( + name = "gtest_for_library", + testonly = True, + actual = ":gtest", +) + +# Implements main() for tests using gtest. Prefer to depend on `gtest` as well +# to ensure compliance with the layering_check Bazel feature where only the +# direct hdrs values are available. cc_library( name = "gtest_main", srcs = ["googlemock/src/gmock_main.cc"], diff --git a/vendor/googletest-b4aaf97/CMakeLists.txt b/vendor/googletest-56efe39/CMakeLists.txt similarity index 93% rename from vendor/googletest-b4aaf97/CMakeLists.txt rename to vendor/googletest-56efe39/CMakeLists.txt index 9e6d6440d..c784f3c7c 100644 --- a/vendor/googletest-b4aaf97/CMakeLists.txt +++ b/vendor/googletest-56efe39/CMakeLists.txt @@ -1,10 +1,10 @@ # Note: CMake support is community-based. The maintainers do not use CMake # internally. -cmake_minimum_required(VERSION 3.13) +cmake_minimum_required(VERSION 3.16) project(googletest-distribution) -set(GOOGLETEST_VERSION 1.14.0) +set(GOOGLETEST_VERSION 1.16.0) if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX) set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/vendor/googletest-b4aaf97/CONTRIBUTING.md b/vendor/googletest-56efe39/CONTRIBUTING.md similarity index 100% rename from vendor/googletest-b4aaf97/CONTRIBUTING.md rename to vendor/googletest-56efe39/CONTRIBUTING.md diff --git a/vendor/googletest-b4aaf97/CONTRIBUTORS b/vendor/googletest-56efe39/CONTRIBUTORS similarity index 100% rename from vendor/googletest-b4aaf97/CONTRIBUTORS rename to vendor/googletest-56efe39/CONTRIBUTORS diff --git a/vendor/googletest-b4aaf97/LICENSE b/vendor/googletest-56efe39/LICENSE similarity index 100% rename from vendor/googletest-b4aaf97/LICENSE rename to vendor/googletest-56efe39/LICENSE diff --git a/vendor/googletest-b4aaf97/MODULE.bazel b/vendor/googletest-56efe39/MODULE.bazel similarity index 66% rename from vendor/googletest-b4aaf97/MODULE.bazel rename to vendor/googletest-56efe39/MODULE.bazel index b81ebf043..c07e6a931 100644 --- a/vendor/googletest-b4aaf97/MODULE.bazel +++ b/vendor/googletest-56efe39/MODULE.bazel @@ -39,23 +39,43 @@ module( # Only direct dependencies need to be listed below. # Please keep the versions in sync with the versions in the WORKSPACE file. -bazel_dep(name = "abseil-cpp", - version = "20240116.0", - repo_name = "com_google_absl") - -bazel_dep(name = "platforms", - version = "0.0.8") - -bazel_dep(name = "re2", - repo_name = "com_googlesource_code_re2", - version = "2023-11-01") +bazel_dep( + name = "abseil-cpp", + version = "20260107.0", +) +bazel_dep( + name = "platforms", + version = "0.0.11", +) +bazel_dep( + name = "re2", + version = "2024-07-02.bcr.1", +) -bazel_dep(name = "rules_python", - version = "0.29.0") +bazel_dep( + name = "rules_cc", + version = "0.2.8" +) +bazel_dep( + name = "rules_python", + version = "1.3.0", + dev_dependency = True, +) -fake_fuchsia_sdk = use_repo_rule("//:fake_fuchsia_sdk.bzl", "fake_fuchsia_sdk") -fake_fuchsia_sdk(name = "fuchsia_sdk") +# https://rules-python.readthedocs.io/en/stable/toolchains.html#library-modules-with-dev-only-python-usage +python = use_extension( + "@rules_python//python/extensions:python.bzl", + "python", + dev_dependency = True, +) +python.toolchain( + ignore_root_user_error = True, + is_default = True, + python_version = "3.12", +) -# https://github.com/bazelbuild/rules_python/blob/main/BZLMOD_SUPPORT.md#default-toolchain-is-not-the-local-system-python -register_toolchains("@bazel_tools//tools/python:autodetecting_toolchain") +# See fake_fuchsia_sdk.bzl for instructions on how to override this with a real SDK, if needed. +fuchsia_sdk = use_extension("//:fake_fuchsia_sdk.bzl", "fuchsia_sdk") +fuchsia_sdk.create_fake() +use_repo(fuchsia_sdk, "fuchsia_sdk") diff --git a/vendor/googletest-b4aaf97/README.md b/vendor/googletest-56efe39/README.md similarity index 85% rename from vendor/googletest-b4aaf97/README.md rename to vendor/googletest-56efe39/README.md index c1c144659..1584c793d 100644 --- a/vendor/googletest-b4aaf97/README.md +++ b/vendor/googletest-56efe39/README.md @@ -2,40 +2,28 @@ ### Announcements -#### Live at Head - -GoogleTest now follows the -[Abseil Live at Head philosophy](https://abseil.io/about/philosophy#upgrade-support). -We recommend -[updating to the latest commit in the `main` branch as often as possible](https://github.com/abseil/abseil-cpp/blob/master/FAQ.md#what-is-live-at-head-and-how-do-i-do-it). -We do publish occasional semantic versions, tagged with -`v${major}.${minor}.${patch}` (e.g. `v1.14.0`). - #### Documentation Updates Our documentation is now live on GitHub Pages at https://google.github.io/googletest/. We recommend browsing the documentation on GitHub Pages rather than directly in the repository. -#### Release 1.14.0 +#### Release 1.17.0 -[Release 1.14.0](https://github.com/google/googletest/releases/tag/v1.14.0) is +[Release 1.17.0](https://github.com/google/googletest/releases/tag/v1.17.0) is now available. -The 1.14.x branch requires at least C++14. +The 1.17.x branch +[requires at least C++17](https://opensource.google/documentation/policies/cplusplus-support#c_language_standard). #### Continuous Integration -We use Google's internal systems for continuous integration. \ -GitHub Actions were added for the convenience of open-source contributors. They -are exclusively maintained by the open-source community and not used by the -GoogleTest team. +We use Google's internal systems for continuous integration. #### Coming Soon * We are planning to take a dependency on [Abseil](https://github.com/abseil/abseil-cpp). -* More documentation improvements are planned. ## Welcome to **GoogleTest**, Google's C++ test framework! diff --git a/vendor/googletest-56efe39/WORKSPACE b/vendor/googletest-56efe39/WORKSPACE new file mode 100644 index 000000000..f004f565d --- /dev/null +++ b/vendor/googletest-56efe39/WORKSPACE @@ -0,0 +1,61 @@ +# Copyright 2024 Google Inc. +# All Rights Reserved. +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +workspace(name = "googletest") + +load("//:googletest_deps.bzl", "googletest_deps") +googletest_deps() + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "rules_python", + sha256 = "2cc26bbd53854ceb76dd42a834b1002cd4ba7f8df35440cf03482e045affc244", + strip_prefix = "rules_python-1.3.0", + url = "https://github.com/bazelbuild/rules_python/releases/download/1.3.0/rules_python-1.3.0.tar.gz", +) +# https://github.com/bazelbuild/rules_python/releases/tag/1.1.0 +load("@rules_python//python:repositories.bzl", "py_repositories") +py_repositories() + +http_archive( + name = "platforms", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.11/platforms-0.0.11.tar.gz", + "https://github.com/bazelbuild/platforms/releases/download/0.0.11/platforms-0.0.11.tar.gz", + ], + sha256 = "29742e87275809b5e598dc2f04d86960cc7a55b3067d97221c9abbc9926bff0f", +) + +load("@bazel_features//:deps.bzl", "bazel_features_deps") +bazel_features_deps() + +load("@rules_cc//cc:extensions.bzl", "compatibility_proxy_repo") +compatibility_proxy_repo() diff --git a/vendor/googletest-b4aaf97/WORKSPACE.bzlmod b/vendor/googletest-56efe39/WORKSPACE.bzlmod similarity index 100% rename from vendor/googletest-b4aaf97/WORKSPACE.bzlmod rename to vendor/googletest-56efe39/WORKSPACE.bzlmod diff --git a/vendor/googletest-56efe39/ci/linux-presubmit.sh b/vendor/googletest-56efe39/ci/linux-presubmit.sh new file mode 100644 index 000000000..9842f4c2f --- /dev/null +++ b/vendor/googletest-56efe39/ci/linux-presubmit.sh @@ -0,0 +1,177 @@ +#!/bin/bash +# +# Copyright 2020, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set -euox pipefail + +readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20250430" +readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20250430" + +if [[ -z ${GTEST_ROOT:-} ]]; then + GTEST_ROOT="$(realpath $(dirname ${0})/..)" +fi + +# Use Bazel Vendor mode to reduce reliance on external dependencies. +# See https://bazel.build/external/vendor and the Dockerfile for +# an explaination of how this works. +if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f "${KOKORO_GFILE_DIR}/distdir/googletest_vendor.tar.gz" ]]; then + DOCKER_EXTRA_ARGS="--mount type=bind,source=${KOKORO_GFILE_DIR}/distdir,target=/distdir,readonly --env=BAZEL_VENDOR_ARCHIVE=/distdir/googletest_vendor.tar.gz ${DOCKER_EXTRA_ARGS:-}" + BAZEL_EXTRA_ARGS="--vendor_dir=/googletest_vendor ${BAZEL_EXTRA_ARGS:-}" +fi + +if [[ -z ${STD:-} ]]; then + STD="c++17 c++20 c++23" +fi + +# Test CMake + GCC +for cmake_off_on in OFF ON; do + time docker run \ + --volume="${GTEST_ROOT}:/src:ro" \ + --tmpfs="/build:exec" \ + --workdir="/build" \ + --rm \ + --env="CC=/usr/local/bin/gcc" \ + --env=CXXFLAGS="-Werror -Wdeprecated" \ + ${LINUX_LATEST_CONTAINER} \ + /bin/bash -c " + cmake /src \ + -DCMAKE_CXX_STANDARD=17 \ + -Dgtest_build_samples=ON \ + -Dgtest_build_tests=ON \ + -Dgmock_build_tests=ON \ + -Dcxx_no_exception=${cmake_off_on} \ + -Dcxx_no_rtti=${cmake_off_on} && \ + make -j$(nproc) && \ + ctest -j$(nproc) --output-on-failure" +done + +# Test CMake + Clang +for cmake_off_on in OFF ON; do + time docker run \ + --volume="${GTEST_ROOT}:/src:ro" \ + --tmpfs="/build:exec" \ + --workdir="/build" \ + --rm \ + --env="CC=/opt/llvm/clang/bin/clang" \ + --env=CXXFLAGS="-Werror -Wdeprecated --gcc-toolchain=/usr/local" \ + ${LINUX_LATEST_CONTAINER} \ + /bin/bash -c " + cmake /src \ + -DCMAKE_CXX_STANDARD=17 \ + -Dgtest_build_samples=ON \ + -Dgtest_build_tests=ON \ + -Dgmock_build_tests=ON \ + -Dcxx_no_exception=${cmake_off_on} \ + -Dcxx_no_rtti=${cmake_off_on} && \ + make -j$(nproc) && \ + ctest -j$(nproc) --output-on-failure" +done + +# Do one test with an older version of GCC +time docker run \ + --volume="${GTEST_ROOT}:/src:ro" \ + --workdir="/src" \ + --rm \ + --env="CC=/usr/local/bin/gcc" \ + --env="BAZEL_CXXOPTS=-std=c++17" \ + ${DOCKER_EXTRA_ARGS:-} \ + ${LINUX_GCC_FLOOR_CONTAINER} \ + /bin/bash --login -c " + /usr/local/bin/bazel test ... \ + --copt=\"-Wall\" \ + --copt=\"-Werror\" \ + --copt=\"-Wuninitialized\" \ + --copt=\"-Wundef\" \ + --copt=\"-Wno-error=pragmas\" \ + --enable_bzlmod=false \ + --features=external_include_paths \ + --keep_going \ + --per_file_copt=\"external/.*@-w\" \ + --show_timestamps \ + --test_output=errors \ + ${BAZEL_EXTRA_ARGS:-}" + +# Test GCC +for std in ${STD}; do + for absl in 0 1; do + time docker run \ + --volume="${GTEST_ROOT}:/src:ro" \ + --workdir="/src" \ + --rm \ + --env="CC=/usr/local/bin/gcc" \ + --env="BAZEL_CXXOPTS=-std=${std}" \ + ${DOCKER_EXTRA_ARGS:-} \ + ${LINUX_LATEST_CONTAINER} \ + /bin/bash --login -c " + /usr/local/bin/bazel test ... \ + --copt=\"-Wall\" \ + --copt=\"-Werror\" \ + --copt=\"-Wuninitialized\" \ + --copt=\"-Wundef\" \ + --define=\"absl=${absl}\" \ + --enable_bzlmod=true \ + --features=external_include_paths \ + --keep_going \ + --per_file_copt=\"external/.*@-w\" \ + --show_timestamps \ + --test_output=errors \ + ${BAZEL_EXTRA_ARGS:-}" + done +done + +# Test Clang +for std in ${STD}; do + for absl in 0 1; do + time docker run \ + --volume="${GTEST_ROOT}:/src:ro" \ + --workdir="/src" \ + --rm \ + --env="CC=/opt/llvm/clang/bin/clang" \ + --env="BAZEL_CXXOPTS=-std=${std}" \ + ${DOCKER_EXTRA_ARGS:-} \ + ${LINUX_LATEST_CONTAINER} \ + /bin/bash --login -c " + /usr/local/bin/bazel test ... \ + --copt=\"--gcc-toolchain=/usr/local\" \ + --copt=\"-Wall\" \ + --copt=\"-Werror\" \ + --copt=\"-Wuninitialized\" \ + --copt=\"-Wundef\" \ + --define=\"absl=${absl}\" \ + --enable_bzlmod=true \ + --features=external_include_paths \ + --keep_going \ + --linkopt=\"--gcc-toolchain=/usr/local\" \ + --per_file_copt=\"external/.*@-w\" \ + --show_timestamps \ + --test_output=errors \ + ${BAZEL_EXTRA_ARGS:-}" + done +done diff --git a/vendor/googletest-b4aaf97/ci/macos-presubmit.sh b/vendor/googletest-56efe39/ci/macos-presubmit.sh similarity index 79% rename from vendor/googletest-b4aaf97/ci/macos-presubmit.sh rename to vendor/googletest-56efe39/ci/macos-presubmit.sh index 70eaa74fb..4278ec272 100644 --- a/vendor/googletest-b4aaf97/ci/macos-presubmit.sh +++ b/vendor/googletest-56efe39/ci/macos-presubmit.sh @@ -31,6 +31,9 @@ set -euox pipefail +# Use Xcode 16.0 +sudo xcode-select -s /Applications/Xcode_16.0.app/Contents/Developer + if [[ -z ${GTEST_ROOT:-} ]]; then GTEST_ROOT="$(realpath $(dirname ${0})/..)" fi @@ -40,20 +43,20 @@ for cmake_off_on in OFF ON; do BUILD_DIR=$(mktemp -d build_dir.XXXXXXXX) cd ${BUILD_DIR} time cmake ${GTEST_ROOT} \ - -DCMAKE_CXX_STANDARD=14 \ + -DCMAKE_CXX_STANDARD=17 \ -Dgtest_build_samples=ON \ -Dgtest_build_tests=ON \ -Dgmock_build_tests=ON \ -Dcxx_no_exception=${cmake_off_on} \ -Dcxx_no_rtti=${cmake_off_on} - time make + time make -j$(nproc) time ctest -j$(nproc) --output-on-failure done # Test the Bazel build # If we are running on Kokoro, check for a versioned Bazel binary. -KOKORO_GFILE_BAZEL_BIN="bazel-7.0.0-darwin-x86_64" +KOKORO_GFILE_BAZEL_BIN="bazel-8.2.1-darwin-x86_64" if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f ${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN} ]]; then BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}" chmod +x ${BAZEL_BIN} @@ -61,17 +64,25 @@ else BAZEL_BIN="bazel" fi +# Use Bazel Vendor mode to reduce reliance on external dependencies. +if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f "${KOKORO_GFILE_DIR}/distdir/googletest_vendor.tar.gz" ]]; then + tar -xf "${KOKORO_GFILE_DIR}/distdir/googletest_vendor.tar.gz" -C "${HOME}/" + BAZEL_EXTRA_ARGS="--vendor_dir=${HOME}/googletest_vendor ${BAZEL_EXTRA_ARGS:-}" +fi + cd ${GTEST_ROOT} for absl in 0 1; do ${BAZEL_BIN} test ... \ --copt="-Wall" \ --copt="-Werror" \ --copt="-Wundef" \ - --cxxopt="-std=c++14" \ + --cxxopt="-std=c++17" \ --define="absl=${absl}" \ --enable_bzlmod=true \ --features=external_include_paths \ --keep_going \ + --per_file_copt="external/.*@-w" \ --show_timestamps \ - --test_output=errors + --test_output=errors \ + ${BAZEL_EXTRA_ARGS:-} done diff --git a/vendor/googletest-56efe39/ci/windows-presubmit.bat b/vendor/googletest-56efe39/ci/windows-presubmit.bat new file mode 100644 index 000000000..de3de5a87 --- /dev/null +++ b/vendor/googletest-56efe39/ci/windows-presubmit.bat @@ -0,0 +1,87 @@ +SETLOCAL ENABLEDELAYEDEXPANSION + +SET BAZEL_EXE=%KOKORO_GFILE_DIR%\bazel-8.2.1-windows-x86_64.exe + +SET PATH=C:\Python34;%PATH% +SET BAZEL_PYTHON=C:\python34\python.exe +SET BAZEL_SH=C:\tools\msys64\usr\bin\bash.exe +SET CMAKE_BIN="cmake.exe" +SET CTEST_BIN="ctest.exe" +SET CTEST_OUTPUT_ON_FAILURE=1 +SET CMAKE_BUILD_PARALLEL_LEVEL=16 +SET CTEST_PARALLEL_LEVEL=16 + +SET GTEST_ROOT=%~dp0\.. +IF %errorlevel% neq 0 EXIT /B 1 + +:: ---------------------------------------------------------------------------- +:: CMake +SET CMAKE_BUILD_PATH=cmake_msvc2022 +MKDIR %CMAKE_BUILD_PATH% +CD %CMAKE_BUILD_PATH% + +%CMAKE_BIN% %GTEST_ROOT% ^ + -G "Visual Studio 17 2022" ^ + -DCMAKE_CXX_STANDARD=17 ^ + -DPYTHON_EXECUTABLE:FILEPATH=c:\python37\python.exe ^ + -DPYTHON_INCLUDE_DIR:PATH=c:\python37\include ^ + -DPYTHON_LIBRARY:FILEPATH=c:\python37\lib\site-packages\pip ^ + -Dgtest_build_samples=ON ^ + -Dgtest_build_tests=ON ^ + -Dgmock_build_tests=ON +IF %errorlevel% neq 0 EXIT /B 1 + +%CMAKE_BIN% --build . --target ALL_BUILD --config Debug -- -maxcpucount +IF %errorlevel% neq 0 EXIT /B 1 + +%CTEST_BIN% -C Debug --timeout 600 +IF %errorlevel% neq 0 EXIT /B 1 + +CD %GTEST_ROOT% +RMDIR /S /Q %CMAKE_BUILD_PATH% + +:: ---------------------------------------------------------------------------- +:: Bazel + +:: The default home directory on Kokoro is a long path which causes errors +:: because of Windows limitations on path length. +:: --output_user_root=C:\tmp causes Bazel to use a shorter path. +SET BAZEL_VS=C:\Program Files\Microsoft Visual Studio\2022\Community + +:: Use Bazel Vendor mode to reduce reliance on external dependencies. +IF EXIST "%KOKORO_GFILE_DIR%\distdir\googletest_vendor.tar.gz" ( + tar --force-local -xf "%KOKORO_GFILE_DIR%\distdir\googletest_vendor.tar.gz" -C c: + SET VENDOR_FLAG=--vendor_dir=c:\googletest_vendor +) ELSE ( + SET VENDOR_FLAG= +) + +:: C++17 +%BAZEL_EXE% ^ + --output_user_root=C:\tmp ^ + test ... ^ + --compilation_mode=dbg ^ + --copt=/std:c++17 ^ + --copt=/WX ^ + --enable_bzlmod=true ^ + --keep_going ^ + --per_file_copt=external/.*@/w ^ + --test_output=errors ^ + --test_tag_filters=-no_test_msvc2017 ^ + %VENDOR_FLAG% +IF %errorlevel% neq 0 EXIT /B 1 + +:: C++20 +%BAZEL_EXE% ^ + --output_user_root=C:\tmp ^ + test ... ^ + --compilation_mode=dbg ^ + --copt=/std:c++20 ^ + --copt=/WX ^ + --enable_bzlmod=true ^ + --keep_going ^ + --per_file_copt=external/.*@/w ^ + --test_output=errors ^ + --test_tag_filters=-no_test_msvc2017 ^ + %VENDOR_FLAG% +IF %errorlevel% neq 0 EXIT /B 1 diff --git a/vendor/googletest-b4aaf97/docs/_config.yml b/vendor/googletest-56efe39/docs/_config.yml similarity index 100% rename from vendor/googletest-b4aaf97/docs/_config.yml rename to vendor/googletest-56efe39/docs/_config.yml diff --git a/vendor/googletest-b4aaf97/docs/_data/navigation.yml b/vendor/googletest-56efe39/docs/_data/navigation.yml similarity index 100% rename from vendor/googletest-b4aaf97/docs/_data/navigation.yml rename to vendor/googletest-56efe39/docs/_data/navigation.yml diff --git a/vendor/googletest-b4aaf97/docs/_layouts/default.html b/vendor/googletest-56efe39/docs/_layouts/default.html similarity index 81% rename from vendor/googletest-b4aaf97/docs/_layouts/default.html rename to vendor/googletest-56efe39/docs/_layouts/default.html index c7f331b87..f0ae47426 100644 --- a/vendor/googletest-b4aaf97/docs/_layouts/default.html +++ b/vendor/googletest-56efe39/docs/_layouts/default.html @@ -7,15 +7,15 @@ {% seo %} + + -