From 4d04f8fb03d30f0accb3d5e29a859c4c8d9a2112 Mon Sep 17 00:00:00 2001 From: Mahmoud Elkarargy <113839437+mahmoudElkarargyBS@users.noreply.github.com> Date: Wed, 23 Oct 2024 19:04:13 +0300 Subject: [PATCH 1/5] Ft automatic installation parsec (#11) * installation * fix Jenkins * rename HICMA-x to HICMA-X * update find hicma-x * resolve threads --- CMakeLists.txt | 90 ++++++++++----- README.md | 5 +- USER_MANUAL.md | 1 + cmake/FindHICMA-X.cmake | 108 ++++++++++++++++++ cmake/{FindHWLOC.cmake => FindHwloc.cmake} | 7 +- cmake/ImportHiCMAX.cmake | 40 +++++++ cmake/ImportHwloc.cmake | 2 +- cmake/ImportStarsH.cmake | 30 +++-- cmake/macros/BuildDependency.cmake | 5 + examples/CMakeLists.txt | 21 ++-- examples/climate-emulator/CMakeLists.txt | 16 +++ examples/climate-emulator/ClimateEmulator.cpp | 95 +++++++++++++++ inst/include/data-units/DescriptorData.hpp | 1 + .../descriptor/ExaGeoStatDescriptor.hpp | 2 + inst/include/kernels/Kernel.hpp | 2 + .../chameleon/ChameleonImplementation.hpp | 1 + src/CMakeLists.txt | 26 +++-- src/configurations/Configurations.cpp | 4 +- src/data-units/CMakeLists.txt | 25 ++-- src/data-units/descriptor/CMakeLists.txt | 4 +- src/helpers/CommunicatorMPI.cpp | 11 +- .../LinearAlgebraMethods.cpp | 1 + .../chameleon/dense/ChameleonDense.cpp | 1 + src/runtime/CMakeLists.txt | 2 +- src/runtime/parsec/ParsecFunctions.cpp | 88 ++++++++------ tests/cpp-tests/CMakeLists.txt | 28 +++-- 26 files changed, 495 insertions(+), 121 deletions(-) create mode 100644 cmake/FindHICMA-X.cmake rename cmake/{FindHWLOC.cmake => FindHwloc.cmake} (96%) create mode 100644 cmake/ImportHiCMAX.cmake create mode 100644 examples/climate-emulator/CMakeLists.txt create mode 100644 examples/climate-emulator/ClimateEmulator.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 18ce5b92..17241215 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,8 +18,8 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) cmake_policy(SET CMP0048 NEW) # Set project options -option(USE_CUDA "Use Cuda, if available" false) -option(USE_MPI "Use MPI, if available" false) +option(USE_CUDA "Use CUDA, if available" OFF) +option(USE_MPI "Use MPI, if available" OFF) option(BUILD_TESTS "Option to enable building tests" OFF) option(BUILD_HEAVY_TESTS "Option to enable building heavy tests, This may take a lot of time" OFF) option(BUILD_EXAMPLES "Option to enable building examples" ON) @@ -27,15 +27,27 @@ option(BUILD_DOCS "Build documentation in docs directory" ON) option(USE_R "Enable the use of R and Rcpp in the project" OFF) option(CREATE_PACKAGE "Enable a packaging system for distribution" OFF) +# Declare the RUNTIME_TYPE variable with a default value +set(RUNTIME_TYPE "starpu" CACHE STRING "Specify the runtime type (e.g., starpu or parsec)") # Cmake Module Paths set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}") - if (${BUILD_SHARED_LIBS}) set(BLA_STATIC OFF) else () set(BLA_STATIC ON) endif () +# Project Name and Version +project(ExaGeoStatCPP VERSION 2.0.0 DESCRIPTION "ExaGeoStatCPP is a parallel high performance unified framework for geostatistics on manycore systems.") +set(CMAKE_CXX_EXTENSIONS OFF) +string(TOUPPER ${RUNTIME_TYPE} RUNTIME_TYPE) + +if(RUNTIME_TYPE STREQUAL "PARSEC") + message(STATUS "MPI is required to be enabled in order to use PaRSEC") + set(USE_MPI ON) + set(USE_HICMA OFF) +endif() + # Select toolchain based on whether CUDA is enabled or not if (USE_CUDA) message("") @@ -53,9 +65,6 @@ else () include(toolchains/GccToolchain) endif () -# Project Name and Version -project(ExaGeoStatCPP VERSION 1.0.0 DESCRIPTION "ExaGeoStatCPP is a parallel high performance unified framework for geostatistics on manycore systems.") - # Show the current version of CMake. message(STATUS "CMAKE VERSION: ${CMAKE_VERSION}") # Enable C++ language @@ -110,30 +119,43 @@ include(ImportHwloc) list(APPEND STARPU_COMPONENT_LIST "HWLOC") string(REPLACE ";" " " STARPU_COMPONENT_STRING "${STARPU_COMPONENT_LIST}") -# ExaGeoStatCPP depends on StarPU runtime +# ExaGeoStatCPP depends on NLOPT # ------------------------------- -include(ImportStarPu) +include(ImportNLOPT) # ExaGeoStatCPP depends on GSL # ------------------------------- include(ImportGSL) -# ExaGeoStatCPP depends on NLOPT -# ------------------------------- -include(ImportNLOPT) - -# ExaGeoStatCPP depends on HiCMA -# ------------------------------- -if (USE_HICMA) - add_definitions(-DUSE_HICMA=TRUE) - include(ImportHCore) +message("---------------------------------------- ${RUNTIME_TYPE}") +if(RUNTIME_TYPE STREQUAL "STARPU") + message(STATUS "Using StarPU as the runtime") + # ExaGeoStatCPP depends on StarPU runtime + # ------------------------------- + include(ImportStarPu) + # ExaGeoStatCPP depends on HiCMA + # ------------------------------- + if (USE_HICMA) + add_definitions(-DUSE_HICMA=TRUE) + include(ImportHCore) + include(ImportStarsH) + include(ImportHiCMA) + endif () + # ExaGeoStatCPP depends on Chameleon + # ------------------------------- + include(ImportChameleon) + +elseif(RUNTIME_TYPE STREQUAL "PARSEC") + message(STATUS "Using PaRSEC as the runtime") + # ExaGeoStatCPP depends on StarPU runtime + # ------------------------------- include(ImportStarsH) - include(ImportHiCMA) -endif () + include(ImportHCore) + include(ImportHiCMAX) +else() + message(FATAL_ERROR "Unknown RUNTIME_TYPE: ${RUNTIME_TYPE}. Supported values are 'STARPU' or 'PARSEC'.") +endif() -# ExaGeoStatCPP depends on Chameleon -# ------------------------------- -include(ImportChameleon) # ExaGeoStatCPP depends on LAPACK/BLASPP # ------------------------------- @@ -168,10 +190,16 @@ if (USE_R) endif () endif () - # Add src Directory to expose added libraries add_subdirectory(src) +# Define USE_STARPU or USE_RUNTIME based on the selected runtime +if(RUNTIME_TYPE STREQUAL "STARPU") + target_compile_definitions(${PROJECT_NAME} PRIVATE DEFAULT_RUNTIME=1) +elseif(RUNTIME_TYPE STREQUAL "PARSEC") + target_compile_definitions(${PROJECT_NAME} PRIVATE DEFAULT_RUNTIME=0) +endif() + # Creates a new INTERFACE library target named ${PROJECT_NAME}_INTERFACE. # The INTERFACE keyword specifies that this library will not be built, but instead will only be used for its properties. add_library(${PROJECT_NAME}_INTERFACE INTERFACE) @@ -213,15 +241,21 @@ endif () message(" \n \t ** Configurations of ExaGeoStatCPP and installation of dependence is done successfully ** ") message("\t - Export the following line to avoid re-install dependencies each time. -") message("\t ----------------------------------------------------------------------------------------------------------------------------------- ") -message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/CHAMELEON/lib/pkgconfig:$PKG_CONFIG_PATH") -message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/STARPU/lib/pkgconfig:$PKG_CONFIG_PATH") message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/HWLOC/lib/pkgconfig:$PKG_CONFIG_PATH") -message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/GSL/lib/pkgconfig:$PKG_CONFIG_PATH") message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/NLOPT/lib/pkgconfig:${CMAKE_INSTALL_PREFIX}/NLOPT/lib64/pkgconfig:$PKG_CONFIG_PATH") -if(USE_HICMA) +message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/GSL/lib/pkgconfig:$PKG_CONFIG_PATH") +if(RUNTIME_TYPE STREQUAL "STARPU") + message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/STARPU/lib/pkgconfig:$PKG_CONFIG_PATH") + message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/CHAMELEON/lib/pkgconfig:$PKG_CONFIG_PATH") + if(USE_HICMA) + message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/STARSH/lib/pkgconfig:$PKG_CONFIG_PATH") + message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/HCORE/lib/pkgconfig:$PKG_CONFIG_PATH") + message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/HICMA/lib/pkgconfig:$PKG_CONFIG_PATH") + endif() +elseif(RUNTIME_TYPE STREQUAL "PARSEC") message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/STARSH/lib/pkgconfig:$PKG_CONFIG_PATH") message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/HCORE/lib/pkgconfig:$PKG_CONFIG_PATH") - message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/HICMA/lib/pkgconfig:$PKG_CONFIG_PATH") + message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/HICMA-X/lib/pkgconfig:${CMAKE_INSTALL_PREFIX}/HICMA-X/lib64:$PKG_CONFIG_PATH") endif() message("\t ----------------------------------------------------------------------------------------------------------------------------------- \n") diff --git a/README.md b/README.md index 6f6e83f1..3f699598 100644 --- a/README.md +++ b/README.md @@ -60,12 +60,12 @@ statisticians with modest computational resources. ### C++ source code installation To install the `ExaGeoStat` project locally, run the following commands in your terminal: -1. Clone the project from the remote gitHub repository into your local machine using the following command +1. Clone the project repository to your local machine: ```bash git clone https://github.com/ecrc/ExaGeoStatCPP.git ``` -2. Change your current directory by getting into the `ExaGeoStatCPP` project directory +2. Navigate to the cloned directory: ```bash cd ExaGeoStatCPP ``` @@ -84,6 +84,7 @@ To install the `ExaGeoStat` project locally, run the following commands in your ```bash export PKG_CONFIG_PATH=$PWD/installdir/_deps/DEPENDENCY_NAME/lib/pkgconfig:$PKG_CONFIG_PATH ``` + or copy/paste the output pkg-config paths from the configure step Now, you can use the pkg-config executable to collect compiler and linker flags for ExaGeoStatCPP. diff --git a/USER_MANUAL.md b/USER_MANUAL.md index 6b95b532..7f7bfcfb 100644 --- a/USER_MANUAL.md +++ b/USER_MANUAL.md @@ -80,6 +80,7 @@ * To enable packaging system for distribution, add `-p` disabled by default. * To enable showing code warnings, add `-w` disabled by default. * To manually set mkl as blas vendor, add `--use-mkl`. MKL is required as blas vendor and it's automatically detected but in some environments it need to be manually set. +* To enable PaRSEC as a runtime system, add `--use=parsec`, StarPU by default. ## Building diff --git a/cmake/FindHICMA-X.cmake b/cmake/FindHICMA-X.cmake new file mode 100644 index 00000000..a0d3ff3c --- /dev/null +++ b/cmake/FindHICMA-X.cmake @@ -0,0 +1,108 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file FindHICMA-X.cmake +# @brief This is a CMakeLists file for finding HiCMA-X and link and include it's headers +# @version 2.0.0 +# @author Mahmoud ElKarargy +# @date 2024-09-28 + +# Include pkg-config +find_package(PkgConfig QUIET) + +# Try to find dplasma and parsec via pkg-config +if(PKG_CONFIG_FOUND) + pkg_check_modules(DPLASMA_PKG dplasma) + pkg_check_modules(PARSEC_PKG parsec) + if(DPLASMA_PKG_FOUND AND PARSEC_PKG_FOUND) + # Try to find the HICMA-X or hicma-x path in the library directories + string(FIND "${PARSEC_PKG_LIBRARY_DIRS}" "HICMA-X" HICMA_X_START) + if(HICMA_X_START EQUAL -1) + string(FIND "${PARSEC_PKG_LIBRARY_DIRS}" "hicma-x" HICMA_X_START) + endif() + if(HICMA_X_START GREATER -1) + # Extract the full path to HICMA-X or hicma-x and set the include directory + string(REGEX MATCH "([^;]*(HICMA-X|hicma-x)[^;]*/lib)" HICMA_X_LIB_PATH "${PARSEC_PKG_LIBRARY_DIRS}") + get_filename_component(HICMA_X_ROOT "${HICMA_X_LIB_PATH}" DIRECTORY) # Go one level up + set(HICMA-X_INCLUDE_DIRS "${HICMA_X_ROOT}/include") # Set the include path + endif() + # TODO: This is not generalized for the case of hicma installed manually + set(HICMA_X_SRC_DIR ${HICMA_X_ROOT}/hicma-x-src) + set(HICMA-X_FOUND TRUE) + set(HICMA-X_LIBRARIES ${DPLASMA_PKG_LIBRARIES} ${PARSEC_PKG_LIBRARIES}) + set(HICMA-X_LIBRARY_DIRS "${HICMA_X_LIB_PATH}") + # Add a search for lib64 directories and set HICMA-X_LIBRARY_DIRS_DEP + set(HICMA-X_LIBRARY_DIRS_DEP "${HICMA_X_LIB_PATH}64") + + find_library(HICMA_PARSEC_LIB hicma_parsec PATHS ${HICMA-X_LIBRARY_DIRS_DEP}) + + if(HICMA_PARSEC_LIB) + list(APPEND HICMA-X_LIBRARIES ${HICMA_PARSEC_LIB}) + else() + message(FATAL_ERROR "libhicma_parsec.so not found") + endif() + + endif() +endif() + +# Fallback: Manual search if pkg-config fails or HICMA-X path isn't set +if(NOT HICMA-X_FOUND) + # Improved search to handle multiple possible paths and fallback for include directories + find_path(HICMA-X_INCLUDE_DIR + NAMES hicma.h + PATHS + ${CMAKE_CURRENT_LIST_DIR}/../hicma-x/include + /usr/local/include/hicma-x + /usr/local/include + /usr/include/hicma-x + /usr/include + DOC "Path to HICMA-X include directory" + ) + + # Search for the main HICMA-X library + find_library(HICMA-X_LIBRARY + NAMES hicma-x + PATHS + ${CMAKE_CURRENT_LIST_DIR}/../hicma-x/lib + /usr/local/lib + /usr/lib + DOC "Path to HICMA-X library" + ) + + # Search for the hicma_parsec library in the lib64 directory if it's not found in the standard lib + find_library(HICMA_PARSEC_LIB + NAMES hicma_parsec + PATHS + ${CMAKE_CURRENT_LIST_DIR}/../hicma-x/lib64 + /usr/local/lib64 + /usr/lib64 + DOC "Path to HICMA-Parsec library" + ) + + # Check if both the include directory and libraries were found + if(HICMA-X_INCLUDE_DIR AND HICMA-X_LIBRARY AND HICMA_PARSEC_LIB) + set(HICMA-X_FOUND TRUE) + # Combine the found libraries + set(HICMA-X_LIBRARIES ${HICMA-X_LIBRARY} ${HICMA_PARSEC_LIB}) + # Set the include directory + set(HICMA-X_INCLUDE_DIRS "${HICMA-X_INCLUDE_DIR}") + # Include both lib and lib64 directories + # TODO: This paths are not generalized, if the install is not with the same dir. + set(HICMA-X_LIBRARY_DIRS "${HICMA-X_LIBRARY}/lib") + set(HICMA-X_LIBRARY_DIRS_DEP "${HICMA-X_LIBRARY}/lib64") + else() + set(HICMA-X_FOUND FALSE) + endif() +endif() + +# Mark the variables as advanced to keep the CMake GUI clean +mark_as_advanced(HICMA-X_INCLUDE_DIR HICMA-X_LIBRARY HICMA_PARSEC_LIB) + +# Provide feedback on whether the library was found +if(HICMA-X_FOUND) + message(STATUS "Found HICMA-X") +else() + message("Could not find HICMA-X or its dependencies (dplasma, parsec)") +endif() diff --git a/cmake/FindHWLOC.cmake b/cmake/FindHwloc.cmake similarity index 96% rename from cmake/FindHWLOC.cmake rename to cmake/FindHwloc.cmake index 2613be08..5b333b4b 100644 --- a/cmake/FindHWLOC.cmake +++ b/cmake/FindHwloc.cmake @@ -13,6 +13,7 @@ # Hwloc_FOUND - True if hwloc was found # Hwloc_INCLUDE_DIRS - include directories for hwloc # Hwloc_LIBRARIES - link against these libraries to use hwloc +# Hwloc_LIBRARY_DIRS - directories where hwloc libraries are found # Hwloc_VERSION - version # Hwloc_CFLAGS - include directories as compiler flags # Hwloc_LDLFAGS - link paths and libs as compiler flags @@ -171,6 +172,9 @@ else() list(GET Hwloc_VERSION_PARSED 1 Hwloc_VERSION_MINOR) set(Hwloc_VERSION_MINOR "${Hwloc_VERSION_MINOR}" CACHE STRING "Minor version of Hwloc") + # Capture the library directories + set(Hwloc_LIBRARY_DIRS ${Hwloc_LIBRARY_DIRS} CACHE STRING "Directories where hwloc libraries are found") + include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Hwloc DEFAULT_MSG Hwloc_LIBRARIES) @@ -184,5 +188,4 @@ else() endif() endif() - -endif() +endif() \ No newline at end of file diff --git a/cmake/ImportHiCMAX.cmake b/cmake/ImportHiCMAX.cmake new file mode 100644 index 00000000..06493016 --- /dev/null +++ b/cmake/ImportHiCMAX.cmake @@ -0,0 +1,40 @@ +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file ImportHiCMAX.cmake +# @brief Find and include HiCMA-X library as a dependency. +# @version 2.0.0 +# @author Mahmoud ElKarargy +# @author Sameh Abdulah +# @date 2024-09-21 + +# Configuration settings for integrating the HICMA-X library into the project +# 'name' sets the identifier for the HICMA-X library within this script to "HICMA-X". +set(name "HICMA-X") +# Set the version tag for HiCMA-X. +set(tag "FIX-package-installation-MK") +# Flags to configure the build for HiCMA-X, including precision settings for DPLASMA +# and disabling GPU support for both CUDA and HIP. +set(flags '-DDPLASMA_PRECISIONS="s;d"' \-DPARSEC_WITH_DEVEL_HEADERS=ON \-DCMAKE_Fortran_FLAGS="-Wno-main" \-DPARSEC_GPU_WITH_HIP=OFF \-DPARSEC_GPU_WITH_CUDA=OFF \-DPARSEC_HAVE_CUDA=OFF \-DPARSEC_DIST_SHORT_LIMIT=0 \-DPARSEC_DIST_COLLECTIVES=ON \-DPARSEC_HAVE_DEV_CUDA_SUPPORT=OFF \-DDPLASMA_HAVE_CUDA=OFF) +# Indicates that HiCMA-X uses CMake for its build system. +set(is_cmake ON) +# Indicates that HiCMA-X is hosted on a Git repository. +set(is_git ON) +# Indicates that autogen scripts are not required for HiCMA-X. +set(auto_gen OFF) +# Set the URL of the HiCMA-X GitHub repository. +set(url "https://github.com/SAbdulah/hicma-x-dev.git") +# Include the macro to import HiCMA-X as a dependency. +include(macros/ImportDependency) + +# Use the ImportDependency macro to handle fetching, detecting, and setting up HiCMA-X. +ImportDependency(${name} ${tag} "" ${url} "${flags}" "" ${is_cmake} ${is_git} ${auto_gen}) + +# Include necessary directories for HiCMA-X and its dependencies. +include_directories(${HICMA_X_SRC_DIR}) +include_directories(${HICMA_X_SRC_DIR}/dplasma/src) +include_directories(${HICMA_X_SRC_DIR}/hicma_parsec) +include_directories(${HICMA_X_SRC_DIR}/bin/dplasma/src) +# Display a status message indicating that HiCMA-X has been successfully included. +message(STATUS "HiCMA-X done") diff --git a/cmake/ImportHwloc.cmake b/cmake/ImportHwloc.cmake index 5f632725..9607943f 100644 --- a/cmake/ImportHwloc.cmake +++ b/cmake/ImportHwloc.cmake @@ -12,7 +12,7 @@ # Configuration settings for integrating the HWLOC library # 'name' sets the identifier for the HWLOC library within this script to "HWLOC". -set(name "HWLOC") +set(name "Hwloc") # 'tag' specifies "hwloc-2.10.0" as the version tag, identifying a specific release of HWLOC to be used. set(tag "hwloc-2.10.0") # 'version' defines "2.10.0" as the version of HWLOC, ensuring it meets project compatibility requirements. diff --git a/cmake/ImportStarsH.cmake b/cmake/ImportStarsH.cmake index 0fd9cde5..10ec8347 100644 --- a/cmake/ImportStarsH.cmake +++ b/cmake/ImportStarsH.cmake @@ -5,18 +5,31 @@ # @file CMakeLists.txt # @brief Find and include STARSH library as a dependency. -# @version 1.1.0 +# @version 2.0.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah -# @date 2023-03-13 +# @date 2024-09-28 # Configuration parameters for integrating the STARSH library # 'name' is set to "STARSH" to identify the STARSH library within this script. set(name "STARSH") -# 'tag' specifies "v0.3.1" as the version tag for STARSH, denoting the exact release to be used. -set(tag "v0.3.1") -# 'version' sets "0.3.1" as the version of the STARSH library, ensuring it aligns with project requirements. -set(version "0.3.1") + +# Check the value of RUNTIME_TYPE and configure STARSH accordingly +if(RUNTIME_TYPE STREQUAL "STARPU") + # Default values for STARPU runtime + set(STARSH_TAG "v0.3.1") + set(STARSH_VERSION "0.3.1") + set(STARSH_URL "https://github.com/ecrc/stars-h.git") + message(STATUS "RUNTIME_TYPE is STARPU. Using default STARSH configuration.") + +elseif(RUNTIME_TYPE STREQUAL "PARSEC") + # Custom values for PARSEC runtime + set(STARSH_TAG "sabdulah/non-gaussian-kernel") + set(STARSH_VERSION "0") + set(STARSH_URL "https://github.com/SAbdulah/stars-h.git") + message(STATUS "RUNTIME_TYPE is PARSEC. Using custom STARSH configuration for PARSEC.") +endif() + # 'flag' is used for additional build configuration options, specifically disabling StarPU and optionally enabling MPI. set(flag \-DSTARPU=OFF \-DMPI=${USE_MPI}) # 'is_cmake' indicates that STARSH uses CMake as its build system, set to ON. @@ -25,13 +38,10 @@ set(is_cmake ON) set(is_git ON) # 'auto_gen' signals whether autogen scripts are needed for the build process; it is set to OFF for STARSH. set(auto_gen OFF) -# 'url' provides the GitHub repository URL for STARSH, specifying the source code's location. -set(url "https://github.com/ecrc/stars-h.git") - # The 'ImportDependency' macro, located in the 'macros' directory, is included to manage the import and setup of the STARSH library. include(macros/ImportDependency) # The 'ImportDependency' macro is called with the configuration parameters set above to manage the detection, fetching, and setup of STARSH. -ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) +ImportDependency(${name} ${STARSH_TAG} ${STARSH_VERSION} ${STARSH_URL} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) # A message is output to indicate the successful integration of the STARSH library into the project. message(STATUS "${name} done") diff --git a/cmake/macros/BuildDependency.cmake b/cmake/macros/BuildDependency.cmake index 50f5c125..a16e45c2 100644 --- a/cmake/macros/BuildDependency.cmake +++ b/cmake/macros/BuildDependency.cmake @@ -85,6 +85,11 @@ macro(BuildDependency raw_name url tag flags is_using_cmake is_using_git auto_ge # Include the ProcessorCount module to determine the number of CPUs for parallel build and install commands. include(ProcessorCount) ProcessorCount(N) + # Subtract 5 from N, ensuring it doesn't go below 0 + math(EXPR N "${N} - 5") + if (N LESS 0) + set(N 1) + endif() # Build the project using make, with parallel jobs based on processor count. This applies to both CMake and non-CMake projects. if (${is_using_cmake}) execute_process(COMMAND make -j ${N} diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 450c6d91..1cf40017 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -5,14 +5,19 @@ # @file CMakeLists.txt # @brief Includes subdirectories for different modules of the ExaGeoStat software package. -# @version 1.1.0 +# @version 2.0.0 # @author Mahmoud ElKarargy -# @date 2024-02-24 +# @date 2024-09-28 # Include subdirectories for end-to-end module, configurations module and data-generators module. -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/configurations) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/data-generators) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/data-loader) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/descriptors) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/end-to-end) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/hardware) +# Check the value of RUNTIME_TYPE +if (RUNTIME_TYPE STREQUAL "STARPU") + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/hardware) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/configurations) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/data-loader) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/end-to-end) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/data-generators) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/descriptors) +elseif (RUNTIME_TYPE STREQUAL "PARSEC") + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/climate-emulator) +endif () diff --git a/examples/climate-emulator/CMakeLists.txt b/examples/climate-emulator/CMakeLists.txt new file mode 100644 index 00000000..01ee6898 --- /dev/null +++ b/examples/climate-emulator/CMakeLists.txt @@ -0,0 +1,16 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @brief Defines an executables and links them with the ExaGeoStat library and other libraries. +# @version 2.0.0 +# @author Mahmoud ElKarargy +# @date 2024-09-23 + +# Define the target executable +add_executable(Example_Climate_Emulator ${CMAKE_CURRENT_SOURCE_DIR}/ClimateEmulator.cpp) + +# Link the target executable with the project and any additional libraries +target_link_libraries(Example_Climate_Emulator PUBLIC ${PROJECT_NAME}_INTERFACE) diff --git a/examples/climate-emulator/ClimateEmulator.cpp b/examples/climate-emulator/ClimateEmulator.cpp new file mode 100644 index 00000000..1f27dafd --- /dev/null +++ b/examples/climate-emulator/ClimateEmulator.cpp @@ -0,0 +1,95 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ClimateEmulator.cpp + * @brief + * @details + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-09-23 +**/ + +#include + +int main(int argc, char ** argv) +{ + int iparam[IPARAM_SIZEOF] = {0}; + double dparam[DPARAM_SIZEOF]; + char *cparam[CPARAM_SIZEOF]; + hicma_parsec_params_t params; + starsh_params_t params_kernel; + hicma_parsec_data_t data; + hicma_parsec_matrix_analysis_t analysis; + + /* Init */ + parsec_context_t* parsec = hicma_parsec_init( argc, argv, iparam, dparam, cparam, ¶ms, ¶ms_kernel, &data ); + + SYNC_TIME_START(); + //gb24_init_serial(&gb); + SYNC_TIME_PRINT(params.rank, ("gb24_init\n")); + + // Forward SHT + SYNC_TIME_START(); + + // Forward SHT reshape + SYNC_TIME_START(); + SYNC_TIME_PRINT(params.rank, ("geqsht_forward_reshape\n")); + + // Make sure it's dense and only off_band maters + if(params.band_size_dist != 0) { + if( 0 == params.rank ) { + fprintf(stderr, RED "Fatal error: band_size_dist= %d needs to be 0\n" RESET, params.band_size_dist); + } + params.band_size_dist = 0; + //return 1; + } + + if(params.band_size_dense < ceil((double)params.N/params.NB)) { + if( 0 == params.rank ) { + fprintf(stderr, RED "Fatal error: the matrix needs to be all DENSE\n" RESET); + } + return 1; + } + + /* Generate matrix */ + SYNC_TIME_START(); + SYNC_TIME_PRINT(params.rank, ("Matrix genneration Matrix norm: norm_global= %le\n", params.norm_global)); + + // SYRK + SYNC_TIME_START(); + dplasma_dsyrk(parsec, dplasmaLower, dplasmaNoTrans, + 1.0, (parsec_tiled_matrix_t *)&data.dcA, + 0.0, (parsec_tiled_matrix_t *)&data.dcA); + SYNC_TIME_PRINT(params.rank, ("SYRK\n")); + + // Calculate norm + SYNC_TIME_START(); + SYNC_TIME_PRINT(params.rank, ("Matrix norm: norm_global= %le\n", params.norm_global)); + + /* Analyze matrix before Cholesky */ + hicma_parsec_matrix_pre_analysis( parsec, &data, ¶ms, ¶ms_kernel, &analysis ); + + /* HiCMA Cholesky */ + for( int i= 0; i < params.nruns; i++ ) { + hicma_parsec_potrf( parsec, &data, ¶ms, &analysis ); + } + + if( 0 == params.rank && params.info != 0 && 1 == params.nruns ) { + fprintf(stderr, "-- Factorization is suspicious (info = %d) ! \n", params.info); + //exit(params.info); + } + + /* Analyze matrix after Cholesky */ + hicma_parsec_matrix_post_analysis( parsec, &data, ¶ms, ¶ms_kernel, &analysis ); + + SYNC_TIME_PRINT(params.rank, ("mse\n")); + + /* Finalize */ + hicma_parsec_fini( parsec, argc, argv, iparam, dparam, cparam, ¶ms, ¶ms_kernel, &data, &analysis ); + + return 0; +} diff --git a/inst/include/data-units/DescriptorData.hpp b/inst/include/data-units/DescriptorData.hpp index 4c2b1d89..dc291b7e 100644 --- a/inst/include/data-units/DescriptorData.hpp +++ b/inst/include/data-units/DescriptorData.hpp @@ -19,6 +19,7 @@ #include #include +#include namespace exageostat::dataunits { diff --git a/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp b/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp index fbf1eb3d..d8a734fa 100644 --- a/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp +++ b/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp @@ -15,7 +15,9 @@ #ifndef EXAGEOSTATCPP_EXAGEOSTATDESCRIPTOR_HPP #define EXAGEOSTATCPP_EXAGEOSTATDESCRIPTOR_HPP +#if DEFAULT_RUNTIME #include +#endif #include #include diff --git a/inst/include/kernels/Kernel.hpp b/inst/include/kernels/Kernel.hpp index 3d018d5c..2460c0f3 100644 --- a/inst/include/kernels/Kernel.hpp +++ b/inst/include/kernels/Kernel.hpp @@ -20,7 +20,9 @@ #include +#if DEFAULT_RUNTIME #include +#endif extern "C" { #include diff --git a/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp b/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp index 8653bfc5..6ecfb1fb 100644 --- a/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp +++ b/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp @@ -17,6 +17,7 @@ #define EXAGEOSTATCPP_CHAMELEONIMPLEMENTATION_HPP #include +#include namespace exageostat::linearAlgebra { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index beb9378f..1ec74fb5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,18 +11,24 @@ # @date 2024-02-04 # Add subdirectories for configurations, data-generators, data-units, and linear-algebra-solvers. -add_subdirectory(api) add_subdirectory(configurations) -add_subdirectory(data-generators) -add_subdirectory(data-loader) -add_subdirectory(data-units) -add_subdirectory(hardware) -add_subdirectory(helpers) add_subdirectory(kernels) -add_subdirectory(linear-algebra-solvers) -add_subdirectory(prediction) -add_subdirectory(results) -add_subdirectory(runtime) +add_subdirectory(helpers) +add_subdirectory(data-units) + +# Check the value of RUNTIME_TYPE and configure chameleon/starpu accordingly +if(RUNTIME_TYPE STREQUAL "STARPU") + add_subdirectory(api) + add_subdirectory(data-generators) + add_subdirectory(data-loader) + add_subdirectory(hardware) + add_subdirectory(linear-algebra-solvers) + add_subdirectory(prediction) + add_subdirectory(results) + add_subdirectory(runtime) + +elseif(RUNTIME_TYPE STREQUAL "PARSEC") +endif() if (USE_R) add_subdirectory(Rcpp-adapters) diff --git a/src/configurations/Configurations.cpp b/src/configurations/Configurations.cpp index 8da6a38f..e3b1557b 100644 --- a/src/configurations/Configurations.cpp +++ b/src/configurations/Configurations.cpp @@ -12,9 +12,11 @@ * @date 2024-02-04 **/ +#include + #include -#include #include +#include using namespace std; diff --git a/src/data-units/CMakeLists.txt b/src/data-units/CMakeLists.txt index 85e48392..70977f00 100644 --- a/src/data-units/CMakeLists.txt +++ b/src/data-units/CMakeLists.txt @@ -9,13 +9,20 @@ # @author Sameh Abdulah # @date 2023-02-27 -# Include the concrete implementations of the ExaGeoStat Descriptor class -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/descriptor) +# Initialize SOURCES variable if not already initialized +set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Locations.cpp ${SOURCES}) -set(SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/Locations.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DescriptorData.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/ExaGeoStatData.cpp - ${SOURCES} - PARENT_SCOPE - ) \ No newline at end of file +if (RUNTIME_TYPE STREQUAL "STARPU") + + # Include the concrete implementations of the ExaGeoStat Descriptor class + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/descriptor) + # Append the necessary source files for the STARPU runtime + list(APPEND SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/DescriptorData.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ExaGeoStatData.cpp + + ) +endif() + +# Set the SOURCES variable to the parent scope +set(SOURCES ${SOURCES} PARENT_SCOPE) diff --git a/src/data-units/descriptor/CMakeLists.txt b/src/data-units/descriptor/CMakeLists.txt index 352aec33..608bbf07 100644 --- a/src/data-units/descriptor/CMakeLists.txt +++ b/src/data-units/descriptor/CMakeLists.txt @@ -10,7 +10,9 @@ # @date 2023-08-15 # Include the concrete implementations of the ExaGeoStat Descriptor class -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/concrete) +if (RUNTIME_TYPE STREQUAL "STARPU") + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/concrete) +endif () set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/ExaGeoStatDescriptor.cpp diff --git a/src/helpers/CommunicatorMPI.cpp b/src/helpers/CommunicatorMPI.cpp index 0abc6d1c..b4227e26 100644 --- a/src/helpers/CommunicatorMPI.cpp +++ b/src/helpers/CommunicatorMPI.cpp @@ -12,8 +12,9 @@ **/ #include +#if DEFAULT_RUNTIME #include - +#endif using namespace exageostat::helpers; CommunicatorMPI *CommunicatorMPI::GetInstance() { @@ -27,12 +28,14 @@ int CommunicatorMPI::GetRank() const { #ifdef USE_MPI if (!mIsHardwareInitialized) { return 0; - } else { + } + #if DEFAULT_RUNTIME + else { return CHAMELEON_Comm_rank(); } -#else - return 0; + #endif #endif + return 0; } void CommunicatorMPI::SetHardwareInitialization() { diff --git a/src/linear-algebra-solvers/LinearAlgebraMethods.cpp b/src/linear-algebra-solvers/LinearAlgebraMethods.cpp index 31931325..146ccf9e 100644 --- a/src/linear-algebra-solvers/LinearAlgebraMethods.cpp +++ b/src/linear-algebra-solvers/LinearAlgebraMethods.cpp @@ -22,6 +22,7 @@ #include #include +#include using namespace std; diff --git a/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp b/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp index f08c8c3b..f5f843a7 100644 --- a/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp +++ b/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp @@ -15,6 +15,7 @@ #include #include +#include using namespace std; diff --git a/src/runtime/CMakeLists.txt b/src/runtime/CMakeLists.txt index 74d34df3..e4d999e5 100644 --- a/src/runtime/CMakeLists.txt +++ b/src/runtime/CMakeLists.txt @@ -10,7 +10,7 @@ # @date 2024-03-10 # Include runtime directory,based on runtime flag. -if ("${RUNTIME_TYPE}" STREQUAL "parsec") +if ("${RUNTIME_TYPE}" STREQUAL "PARSEC") add_subdirectory(parsec) else () #by default use StarPu runtime. diff --git a/src/runtime/parsec/ParsecFunctions.cpp b/src/runtime/parsec/ParsecFunctions.cpp index 65b0073d..02e46b93 100644 --- a/src/runtime/parsec/ParsecFunctions.cpp +++ b/src/runtime/parsec/ParsecFunctions.cpp @@ -20,68 +20,92 @@ using namespace exageostat::dataunits; //TODO: implement parsec functions template -void RuntimeFunctions::CovarianceMatrix(DescriptorData &aDescriptorData, void *apDescriptor, - const int &aTriangularPart, Locations *apLocation1, - Locations *apLocation2, Locations *apLocation3, - T *apLocalTheta, const int &aDistanceMetric, - const kernels::Kernel *apKernel, void *apContext) {} +void RuntimeFunctions::CovarianceMatrix(dataunits::DescriptorData &aDescriptorData, void *apDescriptor, + const int &aTriangularPart, + dataunits::Locations *apLocation1, dataunits::Locations *apLocation2, + dataunits::Locations *apLocation3, T *apLocalTheta, + const int &aDistanceMetric, + const kernels::Kernel *apKernel) { +} + template -void RuntimeFunctions::ExaGeoStatMLETileAsyncMLOEMMOM(void *apDescExpr1, void *apDescExpr2, void *apDescExpr3, +void RuntimeFunctions::ExaGeoStatMLETileAsyncMLOEMMOM(void *apDescExpr2, void *apDescExpr3, void *apDescExpr4, void *apDescMLOE, void *apDescMMOM, void *apSequence, - void *apRequest, void *apContext) {} + void *apRequest) { + +} template void RuntimeFunctions::ExaGeoStatMLEMSPETileAsync(void *apDescZPredict, void *apDescZMiss, void *apDescError, - void *apSequence, void *apRequest, void *apContext) {} + void *apSequence, + void *apRequest) { + +} template -void RuntimeFunctions::CopyDescriptorZ(DescriptorData &aDescriptorData, void *apDescriptor, T *apDoubleVector, - void *apContext) {} +void RuntimeFunctions::CopyDescriptorZ(dataunits::DescriptorData &aDescriptorData, void *apDescriptor, + T *apDoubleVector) { + +} template -void -RuntimeFunctions::ExaGeoStatGaussianToNonTileAsync(DescriptorData &aDescriptorData, void *apDesc, T *apTheta, - void *apContext) {} +void RuntimeFunctions::ExaGeoStatGaussianToNonTileAsync(dataunits::DescriptorData &aDescriptorData, void *apDesc, + T *apTheta) { + +} template void -RuntimeFunctions::ExaGeoStatMeasureDetTileAsync(const Computation &aComputation, void *apDescA, void *apSequence, - void *apRequest, void *apDescDet, void *apContext) {} +RuntimeFunctions::ExaGeoStatMeasureDetTileAsync(const common::Computation &aComputation, void *apDescA, + void *apSequence, void *apRequest, + void *apDescDet) { +} template void RuntimeFunctions::ExaGeoStaStrideVectorTileAsync(void *apDescA, void *apDescB, void *apDescC, void *apSequence, void *apRequest, void *apContext) {} template -void RuntimeFunctions::ExaGeoStaStrideVectorTileAsync(void *apDescA, void *apDescB, void *apDescC, void *apDescD, - void *apSequence, void *apRequest, void *apContext) {} +void RuntimeFunctions::ExaGeoStaStrideVectorTileAsync(void *apDescA, void *apDescB, void *apDescC, void *apSequence, + void *apRequest) { +} template -void -RuntimeFunctions::ExaGeoStatMLETraceTileAsync(void *apDescA, void *apSequence, void *apRequest, void *apDescNum, - void *apDescTrace, void *apContext) {} +void RuntimeFunctions::ExaGeoStatMLETraceTileAsync(void *apDescA, void *apSequence, void *apRequest, void *apDescNum, + void *apDescTrace) { + +} template void -RuntimeFunctions::ExaGeoStatDoubleDotProduct(void *apDescA, void *apDescProduct, void *apSequence, - void *apRequest, - void *apContext) {} +RuntimeFunctions::ExaGeoStatDoubleDotProduct(void *apDescA, void *apDescProduct, void *apSequence, void *apRequest) { + + +} template -void -RuntimeFunctions::ExaGeoStatMLEMSPEBivariateTileAsync(void *apDescZPre, void *apDescZMiss, void *apDescsError1, - void *apDescsError2, void *apDescsError, void *apSequence, - void *apRequest, void *apContext) {} +void RuntimeFunctions::ExaGeoStatMLEMSPEBivariateTileAsync(void *apDescZPre, void *apDescZMiss, void *apDescError1, + void *apDescError2, + void *apDescError, void *apSequence, void *apRequest) { + +} template -void RuntimeFunctions::ExaGeoStatNonGaussianLogLikeTileAsync(const Computation &aComputation, void *apDescZ, - void *apDescSum, const T *apTheta, void *apSequence, - void *apRequest, void *apContext) {} +void RuntimeFunctions::ExaGeoStatNonGaussianLogLikeTileAsync(const common::Computation &aComputation, void *apDescZ, + void *apDescSum, + const T *apTheta, void *apSequence, void *apRequest) { + + + +} template void -RuntimeFunctions::ExaGeoStatNonGaussianTransformTileAsync(const Computation &aComputation, void *apDescZ, +RuntimeFunctions::ExaGeoStatNonGaussianTransformTileAsync(const common::Computation &aComputation, void *apDescZ, const T *apTheta, - void *apSequence, void *apRequest, void *apContext) {} + void *apSequence, void *apRequest) { + + +} diff --git a/tests/cpp-tests/CMakeLists.txt b/tests/cpp-tests/CMakeLists.txt index 75c33860..b1a4f2d8 100644 --- a/tests/cpp-tests/CMakeLists.txt +++ b/tests/cpp-tests/CMakeLists.txt @@ -8,19 +8,23 @@ # @author Mahmoud ElKarargy # @date 2024-01-24 -add_subdirectory(api) -add_subdirectory(configurations) -add_subdirectory(data-generators) -add_subdirectory(hardware) -add_subdirectory(helpers) -add_subdirectory(kernels) -add_subdirectory(linear-algebra-solvers) -add_subdirectory(prediction) -add_subdirectory(results) +# Check the value of RUNTIME_TYPE +if(RUNTIME_TYPE STREQUAL "STARPU") + add_subdirectory(api) + add_subdirectory(configurations) + add_subdirectory(data-generators) + add_subdirectory(hardware) + add_subdirectory(helpers) + add_subdirectory(kernels) + add_subdirectory(linear-algebra-solvers) + add_subdirectory(prediction) + add_subdirectory(results) + if (USE_HICMA) + add_subdirectory(data-units) + endif () +elseif(RUNTIME_TYPE STREQUAL "PARSEC") -if (USE_HICMA) - add_subdirectory(data-units) -endif () +endif() if (USE_R) add_subdirectory(Rcpp-adapters) From 64e3fe94d506d871a8961f693edffec3e6d2bb3b Mon Sep 17 00:00:00 2001 From: Mahmoud Elkarargy <113839437+mahmoudElkarargyBS@users.noreply.github.com> Date: Tue, 29 Oct 2024 12:41:12 +0300 Subject: [PATCH 2/5] Parsec Headers and Hardware (#12) --- CMakeLists.txt | 4 +- examples/climate-emulator/ClimateEmulator.cpp | 106 +++------ inst/include/api/ExaGeoStat.hpp | 21 +- .../include/configurations/Configurations.hpp | 36 +++ inst/include/data-analyzer/DataAnalyzer.hpp | 61 +++++ .../data-transformer/DataTransformer.hpp | 52 +++++ inst/include/data-units/DescriptorData.hpp | 4 + inst/include/hardware/ExaGeoStatHardware.hpp | 18 ++ .../LinearAlgebraMethods.hpp | 220 ++++++++++-------- .../chameleon/ChameleonImplementation.hpp | 50 +++- .../hicma/tlr/HicmaImplementation.hpp | 48 +++- .../concrete/parsec/ParsecImplementation.hpp | 122 ++++++++++ inst/include/runtime/parsec/ParsecHeader.hpp | 16 ++ inst/include/utilities/EnumStringParser.hpp | 4 + src/CMakeLists.txt | 24 +- src/api/ExaGeoStat.cpp | 23 +- src/configurations/Configurations.cpp | 42 +++- src/data-analyzer/CMakeLists.txt | 17 ++ src/data-analyzer/DataAnalyzer.cpp | 27 +++ .../concrete/SyntheticGenerator.cpp | 3 + src/data-loader/DataLoader.cpp | 4 + src/data-transformer/CMakeLists.txt | 17 ++ src/data-transformer/DataTransformer.cpp | 32 +++ src/data-units/CMakeLists.txt | 21 +- src/data-units/DescriptorData.cpp | 11 +- src/hardware/ExaGeoStatHardware.cpp | 83 ++++++- src/linear-algebra-solvers/CMakeLists.txt | 13 +- .../LinearAlgebraFactory.cpp | 5 +- .../LinearAlgebraMethods.cpp | 31 --- .../concrete/CMakeLists.txt | 28 ++- .../chameleon/ChameleonImplementation.cpp | 37 ++- .../concrete/parsec/ParsecImplementation.cpp | 90 +++++++ .../concrete/tlr/HicmaImplementation.cpp | 63 ++++- src/prediction/Prediction.cpp | 5 +- tests/cpp-tests/CMakeLists.txt | 3 +- .../configurations/TestConfigurations.cpp | 45 ++++ 36 files changed, 1114 insertions(+), 272 deletions(-) create mode 100644 inst/include/data-analyzer/DataAnalyzer.hpp create mode 100644 inst/include/data-transformer/DataTransformer.hpp create mode 100644 inst/include/linear-algebra-solvers/concrete/parsec/ParsecImplementation.hpp create mode 100644 inst/include/runtime/parsec/ParsecHeader.hpp create mode 100644 src/data-analyzer/CMakeLists.txt create mode 100644 src/data-analyzer/DataAnalyzer.cpp create mode 100644 src/data-transformer/CMakeLists.txt create mode 100644 src/data-transformer/DataTransformer.cpp create mode 100644 src/linear-algebra-solvers/concrete/parsec/ParsecImplementation.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 17241215..accf04e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -195,9 +195,9 @@ add_subdirectory(src) # Define USE_STARPU or USE_RUNTIME based on the selected runtime if(RUNTIME_TYPE STREQUAL "STARPU") - target_compile_definitions(${PROJECT_NAME} PRIVATE DEFAULT_RUNTIME=1) + target_compile_definitions(${PROJECT_NAME} PUBLIC DEFAULT_RUNTIME=1) elseif(RUNTIME_TYPE STREQUAL "PARSEC") - target_compile_definitions(${PROJECT_NAME} PRIVATE DEFAULT_RUNTIME=0) + target_compile_definitions(${PROJECT_NAME} PUBLIC DEFAULT_RUNTIME=0) endif() # Creates a new INTERFACE library target named ${PROJECT_NAME}_INTERFACE. diff --git a/examples/climate-emulator/ClimateEmulator.cpp b/examples/climate-emulator/ClimateEmulator.cpp index 1f27dafd..44f5424f 100644 --- a/examples/climate-emulator/ClimateEmulator.cpp +++ b/examples/climate-emulator/ClimateEmulator.cpp @@ -5,91 +5,39 @@ /** * @file ClimateEmulator.cpp - * @brief - * @details + * @brief example of climate emulator. * @version 2.0.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2024-09-23 **/ -#include - -int main(int argc, char ** argv) -{ - int iparam[IPARAM_SIZEOF] = {0}; - double dparam[DPARAM_SIZEOF]; - char *cparam[CPARAM_SIZEOF]; - hicma_parsec_params_t params; - starsh_params_t params_kernel; - hicma_parsec_data_t data; - hicma_parsec_matrix_analysis_t analysis; - - /* Init */ - parsec_context_t* parsec = hicma_parsec_init( argc, argv, iparam, dparam, cparam, ¶ms, ¶ms_kernel, &data ); - - SYNC_TIME_START(); - //gb24_init_serial(&gb); - SYNC_TIME_PRINT(params.rank, ("gb24_init\n")); - - // Forward SHT - SYNC_TIME_START(); - - // Forward SHT reshape - SYNC_TIME_START(); - SYNC_TIME_PRINT(params.rank, ("geqsht_forward_reshape\n")); - - // Make sure it's dense and only off_band maters - if(params.band_size_dist != 0) { - if( 0 == params.rank ) { - fprintf(stderr, RED "Fatal error: band_size_dist= %d needs to be 0\n" RESET, params.band_size_dist); - } - params.band_size_dist = 0; - //return 1; - } - - if(params.band_size_dense < ceil((double)params.N/params.NB)) { - if( 0 == params.rank ) { - fprintf(stderr, RED "Fatal error: the matrix needs to be all DENSE\n" RESET); - } - return 1; - } - - /* Generate matrix */ - SYNC_TIME_START(); - SYNC_TIME_PRINT(params.rank, ("Matrix genneration Matrix norm: norm_global= %le\n", params.norm_global)); - - // SYRK - SYNC_TIME_START(); - dplasma_dsyrk(parsec, dplasmaLower, dplasmaNoTrans, - 1.0, (parsec_tiled_matrix_t *)&data.dcA, - 0.0, (parsec_tiled_matrix_t *)&data.dcA); - SYNC_TIME_PRINT(params.rank, ("SYRK\n")); - - // Calculate norm - SYNC_TIME_START(); - SYNC_TIME_PRINT(params.rank, ("Matrix norm: norm_global= %le\n", params.norm_global)); - - /* Analyze matrix before Cholesky */ - hicma_parsec_matrix_pre_analysis( parsec, &data, ¶ms, ¶ms_kernel, &analysis ); - - /* HiCMA Cholesky */ - for( int i= 0; i < params.nruns; i++ ) { - hicma_parsec_potrf( parsec, &data, ¶ms, &analysis ); - } - - if( 0 == params.rank && params.info != 0 && 1 == params.nruns ) { - fprintf(stderr, "-- Factorization is suspicious (info = %d) ! \n", params.info); - //exit(params.info); - } - - /* Analyze matrix after Cholesky */ - hicma_parsec_matrix_post_analysis( parsec, &data, ¶ms, ¶ms_kernel, &analysis ); - - SYNC_TIME_PRINT(params.rank, ("mse\n")); - - /* Finalize */ - hicma_parsec_fini( parsec, argc, argv, iparam, dparam, cparam, ¶ms, ¶ms_kernel, &data, &analysis ); +#include +#include +#include + +using namespace exageostat::configurations; +using namespace exageostat::api; + +int main(int argc, char **argv) { + + // Create a new configurations object. + Configurations configurations; + // Initialize the arguments with the provided command line arguments + configurations.InitializeArguments(argc, argv); + // Initialize the ExaGeoStat Hardware + auto hardware = ExaGeoStatHardware(configurations); + +// // Create a unique pointer to hold the data. +// std::unique_ptr> data; +// // Transform and prepare the data. +// ExaGeoStat::ExaGeoStatTransformData(configurations, data); +// // Load the data, either by reading from a file or generating synthetic data. +// ExaGeoStat::ExaGeoStatLoadData(configurations, data); +// // Perform data modeling. +// ExaGeoStat::ExaGeoStatDataModeling(configurations, data); +// // Analyze the data. +// ExaGeoStat::ExaGeoStatDataAnalyzer(configurations, data); return 0; } diff --git a/inst/include/api/ExaGeoStat.hpp b/inst/include/api/ExaGeoStat.hpp index 54c61c16..0430cac2 100644 --- a/inst/include/api/ExaGeoStat.hpp +++ b/inst/include/api/ExaGeoStat.hpp @@ -60,7 +60,7 @@ namespace exageostat::api { * @return double MLE results. * */ - static double ExaGeoStatMLETileAPI(const std::vector &aTheta, std::vector &aGrad, void *apInfo); + static double ModelingAPI(const std::vector &aTheta, std::vector &aGrad, void *apInfo); /** * @brief Predict missing measurements values. @@ -76,6 +76,25 @@ namespace exageostat::api { ExaGeoStatPrediction(configurations::Configurations &aConfigurations, std::unique_ptr> &aData, T *apMeasurementsMatrix = nullptr, dataunits::Locations *apTrainLocations = nullptr, dataunits::Locations *apTestLocations = nullptr); + /** + * @brief Transform data into the required format for ExaGeoStat operations. + * @param[in] aConfigurations Reference to Configurations object containing user input data. + * @param[in, out] aData Reference to an ExaGeoStatData object containing the descriptors and locations to be transformed. + * @return void + * + */ + static void + ExaGeoStatTransformData(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); + + /** + * @brief Analyze the data to extract insights and patterns. + * @param[in] aConfigurations Reference to Configurations object containing user input data. + * @param[in, out] aData Reference to an ExaGeoStatData object that contains the data to be analyzed. + * @return void + * + */ + static void + ExaGeoStatDataAnalyzer(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); }; diff --git a/inst/include/configurations/Configurations.hpp b/inst/include/configurations/Configurations.hpp index 5e523cc8..3821a34d 100644 --- a/inst/include/configurations/Configurations.hpp +++ b/inst/include/configurations/Configurations.hpp @@ -237,6 +237,42 @@ namespace exageostat::configurations { static void SetVerbosity(const common::Verbose &aVerbose); /** END OF THE COMMON ARGUMENTS BETWEEN ALL MODULES. **/ + + /** START OF THE HICMA-PARSEC SPECIFIC ARGUEMNTS. **/ + + CREATE_SETTER_FUNCTION(DenseBandDP, int, aDenseBandDP, "DenseBandDoublePrecision") + + CREATE_GETTER_FUNCTION(DenseBandDP, int, "DenseBandDoublePrecision") + + CREATE_SETTER_FUNCTION(ObjectsNumber, int, aObjectsNumber, "ObjectsNumber") + + CREATE_GETTER_FUNCTION(ObjectsNumber, int, "ObjectsNumber") + + CREATE_SETTER_FUNCTION(AdaptiveDecision, int, aAdaptiveDecision, "AdaptiveDecision") + + CREATE_GETTER_FUNCTION(AdaptiveDecision, int, "AdaptiveDecision") + + CREATE_SETTER_FUNCTION(DiagonalAddition, int, aDiagonalAddition, "DiagonalAddition") + + CREATE_GETTER_FUNCTION(DiagonalAddition, int, "DiagonalAddition") + + CREATE_SETTER_FUNCTION(TimeSlotPerFile, int, aTimeSlotPerFile, "TimeSlotPerFile") + + CREATE_GETTER_FUNCTION(TimeSlotPerFile, int, "TimeSlotPerFile") + + CREATE_SETTER_FUNCTION(FileNumber, int, aFileNumber, "FileNumber") + + CREATE_GETTER_FUNCTION(FileNumber, int, "FileNumber") + + CREATE_SETTER_FUNCTION(EnableInverse, bool , aEnableInverse, "EnableInverse") + + CREATE_GETTER_FUNCTION(EnableInverse, bool , "EnableInverse") + + CREATE_SETTER_FUNCTION(MPIIO, bool, aMPIIO, "MPIIO") + + CREATE_GETTER_FUNCTION(MPIIO, bool, "MPIIO") + + /** END OF THE HICMA-PARSEC SPECIFIC ARGUEMNTS. **/ /** START OF THE DATA GENERATION MODULES. **/ CREATE_SETTER_FUNCTION(Dimension, exageostat::common::Dimension, aDimension, "Dimension") diff --git a/inst/include/data-analyzer/DataAnalyzer.hpp b/inst/include/data-analyzer/DataAnalyzer.hpp new file mode 100644 index 00000000..72cadf02 --- /dev/null +++ b/inst/include/data-analyzer/DataAnalyzer.hpp @@ -0,0 +1,61 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file DataAnalyzer.hpp + * @brief Contains the definition of the DataAnalyzer class. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-10-15 +**/ + +#ifndef EXAGEOSTATCPP_DATAANALYZER_HPP +#define EXAGEOSTATCPP_DATAANALYZER_HPP + +#include +#include + +namespace exageostat::analyzer{ + /** + * @brief Class represents the data analyzer for the Climate Emulator. + * @tparam T Data Type: float or double + */ + template + class DataAnalyzer { + + public: + /** + * @brief Default constructor. + */ + DataAnalyzer(); + + /** + * @brief Default destructor. + */ + ~DataAnalyzer(); + + /** + * @brief Analyzes the given matrix data. + * @param[in] aConfigurations Reference to Configurations object containing needed parameters. + * @param[in, out] aData Reference to an ExaGeoStatData object that contains matrix to be analyzed. + * @return void + * + */ + static void AnalyzeMatrix(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); + + /** + * @brief Compares betweent two matrices by getting the difference. + * @param[in] aConfigurations Reference to Configurations object containing needed parameters. + * @param[in, out] aData Reference to an ExaGeoStatData object that contains matrix to be analyzed. + * @return the calculated MSE. + * + */ + static double CompareMatDifference(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); + }; + +}//namespace exageostat + +#endif // EXAGEOSTATCPP_DATAANALYZER_HPP \ No newline at end of file diff --git a/inst/include/data-transformer/DataTransformer.hpp b/inst/include/data-transformer/DataTransformer.hpp new file mode 100644 index 00000000..a63e3c01 --- /dev/null +++ b/inst/include/data-transformer/DataTransformer.hpp @@ -0,0 +1,52 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file DataTransformer.hpp + * @brief Contains the definition of the DataTransformer class. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-10-15 +**/ + +#ifndef EXAGEOSTATCPP_DATATRANSFORMER_HPP +#define EXAGEOSTATCPP_DATATRANSFORMER_HPP + +#include +#include + +namespace exageostat::transformer{ + + /** + * @brief Class represents the data transformer for the Climate Emulator. + * @tparam T Data Type: float or double + */ + template + class DataTransformer { + + /** + * @brief Performs the forward spherical harmonics transform (SHT). + * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. + */ + static void ForwardSHT(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); + + /** + * @brief Reshapes data during the forward phase of the simulation. + * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. + */ + static void ForwardReshape(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); + + /** + * @brief Performs the inverse spherical harmonics transform (SHT). + * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. + */ + static void InverseSHT(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); + }; +} +#endif // EXAGEOSTATCPP_DATATRANSFORMER_HPP diff --git a/inst/include/data-units/DescriptorData.hpp b/inst/include/data-units/DescriptorData.hpp index dc291b7e..f5775187 100644 --- a/inst/include/data-units/DescriptorData.hpp +++ b/inst/include/data-units/DescriptorData.hpp @@ -19,7 +19,9 @@ #include #include +#if DEFAULT_RUNTIME #include +#endif namespace exageostat::dataunits { @@ -29,9 +31,11 @@ namespace exageostat::dataunits { * */ union BaseDescriptor { +#if DEFAULT_RUNTIME CHAM_desc_t *chameleon_desc; #ifdef USE_HICMA HICMA_desc_t *hicma_desc; +#endif #endif }; diff --git a/inst/include/hardware/ExaGeoStatHardware.hpp b/inst/include/hardware/ExaGeoStatHardware.hpp index 6e872091..5d1ed2ea 100644 --- a/inst/include/hardware/ExaGeoStatHardware.hpp +++ b/inst/include/hardware/ExaGeoStatHardware.hpp @@ -16,6 +16,7 @@ #define EXAGEOSTATCPP_EXAGEOSTATHARDWARE_HPP #include +#include /** * @brief Class represents the hardware configuration for the ExaGeoStat solver. @@ -24,6 +25,14 @@ class ExaGeoStatHardware { public: + + /** + * @brief Constructor for ExaGeoStatHardware. + * @param[in] aConfigurations The set of arguments from the configurations. + * + */ + explicit ExaGeoStatHardware(exageostat::configurations::Configurations &aConfigurations); + /** * @brief Constructor for ExaGeoStatHardware. * @param[in] aComputation The computation mode for the solver. @@ -89,6 +98,13 @@ class ExaGeoStatHardware { */ [[nodiscard]] static void *GetHicmaContext(); + /** + * @brief Get the PaRSEC hardware context. + * @return Pointer to the hardware context. + * + */ + [[nodiscard]] static void *GetParsecContext(); + /** * @brief Get the hardware context. * @param[in] aComputation Used computation to decide whether to use Hicma or Chameleon context. @@ -136,6 +152,8 @@ class ExaGeoStatHardware { static void *mpChameleonContext; //// Used Pointer to the Hicma hardware context. static void *mpHicmaContext; + //// Used Pointer to the PaRSEC hardware context. + static void *mpParsecContext; //// Used P-Grid static int mPGrid; //// Used Q-Grid diff --git a/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp b/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp index 251d6319..2b35a6c9 100644 --- a/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp +++ b/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp @@ -49,6 +49,9 @@ namespace exageostat::linearAlgebra { */ virtual ~LinearAlgebraMethods() = default; + // TODO: Since the common linear algebra fn between HiCMA andChameleon won't work with PaRSEC, + // consider move them and make this file as an Interface for virtual fns +#if DEFAULT_RUNTIME /** * @brief Initializes the descriptors necessary for the linear algebra solver. * @details This method initializes the descriptors necessary for the linear algebra solver. @@ -127,84 +130,6 @@ namespace exageostat::linearAlgebra { dataunits::Locations *apLocation3, const int &aDistanceMetric, const kernels::Kernel &aKernel); - /** - * @brief Calculates the log likelihood value of a given value theta. - * @param[in,out] aData DescriptorData object to be populated with descriptors and data. - * @param[in] aConfigurations Configurations object containing relevant settings. - * @param[in] apTheta Optimization parameter used by NLOPT. - * @param[in] apMeasurementsMatrix measurements matrix to be stored in DescZ. - * @param[in] aKernel Reference to the kernel object to use. - * @return log likelihood value - * - */ - virtual T ExaGeoStatMLETile(std::unique_ptr> &aData, - configurations::Configurations &aConfigurations, const double *apTheta, - T *apMeasurementsMatrix, const kernels::Kernel &aKernel) = 0; - - - /** - * @brief Copies a matrix in the tile layout from source to destination - * @param[in] aUpperLower Specifies the part of the matrix A to be copied to B. - * @param[in] apA Source matrix A. - * @param[in,out] apB Destination matrix B. On exit, B = A in the locations specified by Upper Lower. - * @return void - * - */ - virtual void ExaGeoStatLapackCopyTile(const common::UpperLower &aUpperLower, void *apA, void *apB) = 0; - - /** - * @brief Wait for the completion of a sequence. - * @param[in] apSequence apSequence A pointer to either CHAMELEON or HiCMA sequence. - * @return void - * - */ - virtual void ExaGeoStatSequenceWait(void *apSequence) = 0; - - /** - * @brief Create Sequence. - * @param[out] apSequence A pointer to either CHAMELEON or HiCMA sequence. - * @return void - * - */ - virtual void - ExaGeoStatCreateSequence(void *apSequence) = 0; - - /** - * @brief Computes the Cholesky factorization of a symmetric positive definite or Symmetric positive definite matrix. - * @param[in] aUpperLower Whether upper or lower part of the matrix A. - * @param[in, out] apA Symmetric matrix A. - * @param[in] aBand Diagonal thickness parameter. - * @param[in] apCD Additional matrix CD. - * @param[in] apCrk Additional matrix Crk. - * @param[in] aMaxRank Maximum rank parameter. - * @param[in] aAcc Accuracy parameter. - * @return void - * - */ - virtual void - ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, void *apCD, void *apCrk, - const int &aMaxRank, const int &aAcc) = 0; - - /** - * @brief Solves one of the matrix equations op( A )*X = alpha*B, or X*op( A ) = alpha*B. - * @param[in] aSide Specifies whether op(A) appears on the left or on the right of X. - * @param[in] aUpperLower Specifies whether the matrix A is upper triangular or lower triangular. - * @param[in] aTrans Specifies the form of op( A ) to be used in the matrix multiplication. - * @param[in] aDiag Specifies whether or not A is unit triangular. - * @param[in] aAlpha Specifies the scalar alpha. When alpha is zero, A is not referenced and B need not be set before entry. - * @param[in] apA The triangular matrix A. - * @param[in] apCD Additional matrix CD. - * @param[in] apCrk Additional matrix Crk. - * @param[in, out] apZ The matrix B of dimension, on exit is overwritten by the solution matrix X. - * @param[in] aMaxRank Maximum rank parameter. - * @return void - * - */ - virtual void ExaGeoStatTrsmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, - const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, - void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) = 0; - - /** * @brief Solve a positive definite linear system of equations AX = B using tiled algorithms. * @param[in] aUpperLower Specifies whether the matrix A is upper triangular or lower triangular. @@ -285,22 +210,6 @@ namespace exageostat::linearAlgebra { */ void ExaGeoStatDesc2Lap(T *apA, const int &aLDA, void *apDescA, const common::UpperLower &aUpperLower); -#ifdef USE_HICMA - - /** - * @brief Copy Descriptor Matrix to another Descriptor matrix. - * @param[out] apSourceDesc Descriptor matrix to be copied - * @param[out] apDestinationDesc Descriptor matrix to be copied to. - * @param[in] aSize Size of matrix to be copied. - * @param[in] aDirection Specifies the type of Descriptors to be copied. - * @return void - * - */ - void CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, - const common::CopyDirection &aDirection); - -#endif - /** * @brief Sets the values of all or part of a two-dimensional Tile. * @param[in] aUpperLower Specifies Specifies whether the upper or lower triangular part of the covariance matrix is stored. @@ -399,6 +308,129 @@ namespace exageostat::linearAlgebra { * */ bool Recover(char *apPath, const int &aIterationCount, T *apTheta, T *apLogLik, const int &aNumParams); +#endif + + /** + * @brief Copy Descriptor Matrix to another Descriptor matrix. + * @param[out] apSourceDesc Descriptor matrix to be copied + * @param[out] apDestinationDesc Descriptor matrix to be copied to. + * @param[in] aSize Size of matrix to be copied. + * @param[in] aDirection Specifies the type of Descriptors to be copied. + * @return void + * + */ + virtual void CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, + const common::CopyDirection &aDirection) = 0; + + /** + * @brief The Gateway for the Modeling Operation + * @param[in,out] aData DescriptorData object to be populated with descriptors and data. + * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in] apTheta Optimization parameter used by NLOPT. + * @param[in] apMeasurementsMatrix measurements matrix to be stored in DescZ. + * @param[in] aKernel Reference to the kernel object to use. + * @return log likelihood value + * + */ + virtual T ModelingOperations(std::unique_ptr> &aData, + configurations::Configurations &aConfigurations, const double *apTheta, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) = 0; + + /** + * @brief Copies a matrix in the tile layout from source to destination + * @param[in] aUpperLower Specifies the part of the matrix A to be copied to B. + * @param[in] apA Source matrix A. + * @param[in,out] apB Destination matrix B. On exit, B = A in the locations specified by Upper Lower. + * @return void + * + */ + virtual void ExaGeoStatLapackCopyTile(const common::UpperLower &aUpperLower, void *apA, void *apB) = 0; + + /** + * @brief Wait for the completion of a sequence. + * @param[in] apSequence apSequence A pointer to either CHAMELEON or HiCMA sequence. + * @return void + * + */ + virtual void ExaGeoStatSequenceWait(void *apSequence) = 0; + + /** + * @brief Create Sequence. + * @param[out] apSequence A pointer to either CHAMELEON or HiCMA sequence. + * @return void + * + */ + virtual void + ExaGeoStatCreateSequence(void *apSequence) = 0; + + /** + * @brief Computes the Cholesky factorization of a symmetric positive definite or Symmetric positive definite matrix. + * @param[in] aUpperLower Whether upper or lower part of the matrix A. + * @param[in, out] apA Symmetric matrix A. + * @param[in] aBand Diagonal thickness parameter. + * @param[in] apCD Additional matrix CD. + * @param[in] apCrk Additional matrix Crk. + * @param[in] aMaxRank Maximum rank parameter. + * @param[in] aAcc Accuracy parameter. + * @return void + * + */ + virtual void + ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, void *apCD, void *apCrk, + const int &aMaxRank, const int &aAcc) = 0; + + /** + * @brief Solves one of the matrix equations op( A )*X = alpha*B, or X*op( A ) = alpha*B. + * @param[in] aSide Specifies whether op(A) appears on the left or on the right of X. + * @param[in] aUpperLower Specifies whether the matrix A is upper triangular or lower triangular. + * @param[in] aTrans Specifies the form of op( A ) to be used in the matrix multiplication. + * @param[in] aDiag Specifies whether or not A is unit triangular. + * @param[in] aAlpha Specifies the scalar alpha. When alpha is zero, A is not referenced and B need not be set before entry. + * @param[in] apA The triangular matrix A. + * @param[in] apCD Additional matrix CD. + * @param[in] apCrk Additional matrix Crk. + * @param[in, out] apZ The matrix B of dimension, on exit is overwritten by the solution matrix X. + * @param[in] aMaxRank Maximum rank parameter. + * @return void + * + */ + virtual void ExaGeoStatTrsmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, + const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, + void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) = 0; + + /** + * @brief Performs a SYRK (symmetric rank-k update) operation on the matrix. + * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. + * + */ + virtual void + ExaGeoStatSYRK(configurations::Configurations &aConfigurations, std::unique_ptr> &aData) = 0; + + /** + * @brief Performs TLR Cholesky operation on the matrix. + * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. + * + */ + virtual void ExaGeoStatTLRCholesky(configurations::Configurations &aConfigurations, std::unique_ptr> &aData) = 0; + + /** + * @brief Calculates norm. + * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. + * + */ + virtual void ExaGeoStatNorm(configurations::Configurations &aConfigurations, std::unique_ptr> &aData) =0; + + /** + * @brief Calculates the Mean Squared Error (MSE). + * @param[in] aConfigurations Reference to Configurations object containing needed parameters. + * @param[out] aData Reference to an ExaGeoStatData object that contains matrix to be analyzed. + * @return the calculated MSE. + * + */ + virtual double CalculateMSE(configurations::Configurations &aConfigurations, std::unique_ptr> &aData) =0; }; /** diff --git a/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp b/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp index 6ecfb1fb..0b421af8 100644 --- a/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp +++ b/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp @@ -32,12 +32,12 @@ namespace exageostat::linearAlgebra { /** * @brief Calculates the log likelihood value of a given value theta. - * @copydoc LinearAlgebraMethods::ExaGeoStatMLETile() + * @copydoc LinearAlgebraMethods::ModelingOperations() * */ - T ExaGeoStatMLETile(std::unique_ptr> &aData, - configurations::Configurations &aConfigurations, const double *theta, - T *apMeasurementsMatrix, const kernels::Kernel &aKernel) override; + T ModelingOperations(std::unique_ptr > &aData, + configurations::Configurations &aConfigurations, const double *theta, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) override; /** * @brief Copies a matrix in the tile layout from source to destination @@ -55,6 +55,14 @@ namespace exageostat::linearAlgebra { const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) override; + /** + * @brief Copy Descriptor Matrix to another Descriptor matrix. + * @copydoc LinearAlgebraMethods::CopyDescriptors() + * + */ + void CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, + const common::CopyDirection &aDirection) override; + /** * @brief Wait for the completion of a sequence. * @copydoc LinearAlgebraMethods::ExaGeoStatSequenceWait() @@ -70,6 +78,40 @@ namespace exageostat::linearAlgebra { */ void ExaGeoStatCreateSequence(void *apSequence) override; + + /** + * @brief Performs a SYRK (symmetric rank-k update) operation on the matrix. + * @copydoc LinearAlgebraMethods::ExaGeoStatSYRK() + * + */ + void ExaGeoStatSYRK(configurations::Configurations &aConfigurations, + std::unique_ptr > &aData) override; + + /** + * @brief Performs TLR Cholesky operation on the matrix. + * @copydoc LinearAlgebraMethods::ExaGeoStatTLRCholesky() + * + */ + void ExaGeoStatTLRCholesky(configurations::Configurations &aConfigurations, + std::unique_ptr > &aData) override; + + /** + * @brief Calculates norm. + * @copydoc LinearAlgebraMethods::ExaGeoStatNorm() + * + */ + void ExaGeoStatNorm(configurations::Configurations &aConfigurations, + std::unique_ptr > &aData) override; + + /** + * @brief Calculates the Mean Squared Error (MSE). + * @copydoc LinearAlgebraMethods::CalculateMSE() + * + */ + double CalculateMSE(configurations::Configurations &aConfigurations, + std::unique_ptr > &aData) override; + + }; EXAGEOSTAT_INSTANTIATE_CLASS(ChameleonImplementation) diff --git a/inst/include/linear-algebra-solvers/concrete/hicma/tlr/HicmaImplementation.hpp b/inst/include/linear-algebra-solvers/concrete/hicma/tlr/HicmaImplementation.hpp index 4c488a3d..b7667205 100644 --- a/inst/include/linear-algebra-solvers/concrete/hicma/tlr/HicmaImplementation.hpp +++ b/inst/include/linear-algebra-solvers/concrete/hicma/tlr/HicmaImplementation.hpp @@ -50,11 +50,11 @@ namespace exageostat::linearAlgebra::tileLowRank { /** * @brief Calculates the log likelihood value of a given value theta. - * @copydoc LinearAlgebraMethods::ExaGeoStatMLETile() + * @copydoc LinearAlgebraMethods::ModelingOperations() */ - T ExaGeoStatMLETile(std::unique_ptr> &aData, - configurations::Configurations &aConfigurations, const double *theta, - T *apMeasurementsMatrix, const kernels::Kernel &aKernel) override; + T ModelingOperations(std::unique_ptr > &aData, + configurations::Configurations &aConfigurations, const double *theta, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) override; /** * @brief Copies a matrix in the tile layout from source to destination @@ -91,6 +91,46 @@ namespace exageostat::linearAlgebra::tileLowRank { const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) override; + /** + * @brief Copy Descriptor Matrix to another Descriptor matrix. + * @copydoc LinearAlgebraMethods::CopyDescriptors() + * + */ + void CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, + const common::CopyDirection &aDirection) override; + + /** + * @brief Performs a SYRK (symmetric rank-k update) operation on the matrix. + * @copydoc LinearAlgebraMethods::ExaGeoStatSYRK() + * + */ + void ExaGeoStatSYRK(configurations::Configurations &aConfigurations, + std::unique_ptr > &aData) override; + + /** + * @brief Performs TLR Cholesky operation on the matrix. + * @copydoc LinearAlgebraMethods::ExaGeoStatTLRCholesky() + * + */ + void ExaGeoStatTLRCholesky(configurations::Configurations &aConfigurations, + std::unique_ptr > &aData) override; + + /** + * @brief Calculates norm. + * @copydoc LinearAlgebraMethods::ExaGeoStatNorm() + * + */ + void ExaGeoStatNorm(configurations::Configurations &aConfigurations, + std::unique_ptr > &aData) override; + + /** + * @brief Calculates the Mean Squared Error (MSE). + * @copydoc LinearAlgebraMethods::CalculateMSE() + * + */ + double CalculateMSE(configurations::Configurations &aConfigurations, + std::unique_ptr > &aData) override; + }; /** diff --git a/inst/include/linear-algebra-solvers/concrete/parsec/ParsecImplementation.hpp b/inst/include/linear-algebra-solvers/concrete/parsec/ParsecImplementation.hpp new file mode 100644 index 00000000..6d7df8cd --- /dev/null +++ b/inst/include/linear-algebra-solvers/concrete/parsec/ParsecImplementation.hpp @@ -0,0 +1,122 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ParsecImplementation.hpp + * @brief This file contains the declaration of ParsecImplementation class. + * @details ParsecImplementation is a concrete implementation of the LinearAlgebraMethods class. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-10-15 +**/ + +#ifndef EXAGEOSTATCPP_PARSECIMPLEMENTATION_HPP +#define EXAGEOSTATCPP_PARSECIMPLEMENTATION_HPP + +#include + +namespace exageostat::linearAlgebra { + + /** + * @brief ParsecImplementation is a concrete implementation of LinearAlgebraMethods class. + * @tparam T Data Type: float or double + * + */ + template + class ParsecImplementation : public LinearAlgebraMethods { + + /** + * @brief Performs a SYRK (symmetric rank-k update) operation on the matrix. + * @copydoc LinearAlgebraMethods::ExaGeoStatSYRK() + * + */ + void ExaGeoStatSYRK(configurations::Configurations &aConfigurations, std::unique_ptr> &aData) override; + + /** + * @brief Performs TLR Cholesky operation on the matrix. + * @copydoc LinearAlgebraMethods::ExaGeoStatTLRCholesky() + * + */ + void ExaGeoStatTLRCholesky(configurations::Configurations &aConfigurations, std::unique_ptr> &aData) override; + + /** + * @brief Calculates norm. + * @copydoc LinearAlgebraMethods::ExaGeoStatNorm() + * + */ + void ExaGeoStatNorm(configurations::Configurations &aConfigurations, + std::unique_ptr> &aData) override; + + /** + * @brief Calculates the Mean Squared Error (MSE). + * @copydoc LinearAlgebraMethods::CalculateMSE() + * + */ + double CalculateMSE(configurations::Configurations &aConfigurations, + std::unique_ptr> &aData) override; + + /** + * @brief The Gateway for the Modeling Operation + * @copydoc LinearAlgebraMethods::ModelingOperations() + * + */ + virtual T ModelingOperations(std::unique_ptr> &aData, + configurations::Configurations &aConfigurations, const double *apTheta, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) = 0; + + /** + * @brief Copies a matrix in the tile layout from source to destination + * @copydoc LinearAlgebraMethods::ExaGeoStatLapackCopyTile() + * + */ + virtual void ExaGeoStatLapackCopyTile(const common::UpperLower &aUpperLower, void *apA, void *apB) = 0; + + /** + * @brief Wait for the completion of a sequence. + * @copydoc LinearAlgebraMethods::ExaGeoStatSequenceWait() + * + */ + virtual void ExaGeoStatSequenceWait(void *apSequence) = 0; + + /** + * @brief Create Sequence. + * @copydoc LinearAlgebraMethods::ExaGeoStatCreateSequence() + * + */ + virtual void + ExaGeoStatCreateSequence(void *apSequence) = 0; + + /** + * @brief Computes the Cholesky factorization of a symmetric positive definite or Symmetric positive definite matrix. + * @copydoc LinearAlgebraMethods::ExaGeoStatPotrfTile() + * + */ + virtual void + ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, void *apCD, void *apCrk, + const int &aMaxRank, const int &aAcc) = 0; + + /** + * @brief Solves one of the matrix equations op( A )*X = alpha*B, or X*op( A ) = alpha*B. + * @copydoc LinearAlgebraMethods::ExaGeoStatTrsmTile() + * + */ + virtual void ExaGeoStatTrsmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, + const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, + void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) = 0; + + /** + * @brief Copy Descriptor Matrix to another Descriptor matrix. + * @copydoc LinearAlgebraMethods::CopyDescriptors() + * + */ + virtual void CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, + const common::CopyDirection &aDirection) = 0; + + }; + EXAGEOSTAT_INSTANTIATE_CLASS(ParsecImplementation) +}//namespace exageostat + +#endif //EXAGEOSTATCPP_PARSECIMPLEMENTATION_HPP \ No newline at end of file diff --git a/inst/include/runtime/parsec/ParsecHeader.hpp b/inst/include/runtime/parsec/ParsecHeader.hpp new file mode 100644 index 00000000..37b367ce --- /dev/null +++ b/inst/include/runtime/parsec/ParsecHeader.hpp @@ -0,0 +1,16 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ParsecHeader.hpp + * @brief A header file to include hicma_parsec and undo str definition inside it. + * @details Due to an error occuers when using hicma_parsec.h which set a defination called str() it conflicts with the standart C++ str() fn + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @date 2024-10-08 +**/ + +#include +#undef str diff --git a/inst/include/utilities/EnumStringParser.hpp b/inst/include/utilities/EnumStringParser.hpp index ee7201bb..46bf13d3 100644 --- a/inst/include/utilities/EnumStringParser.hpp +++ b/inst/include/utilities/EnumStringParser.hpp @@ -14,6 +14,10 @@ #ifndef EXAGEOSTATCPP_ENUMSTRINGPARSER_HPP #define EXAGEOSTATCPP_ENUMSTRINGPARSER_HPP +#ifdef min +#undef min +#endif + #include #include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1ec74fb5..713d0b05 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,20 +15,20 @@ add_subdirectory(configurations) add_subdirectory(kernels) add_subdirectory(helpers) add_subdirectory(data-units) +add_subdirectory(runtime) +add_subdirectory(linear-algebra-solvers) +add_subdirectory(api) +add_subdirectory(results) +add_subdirectory(hardware) +add_subdirectory(data-generators) +add_subdirectory(data-loader) +add_subdirectory(prediction) # Check the value of RUNTIME_TYPE and configure chameleon/starpu accordingly -if(RUNTIME_TYPE STREQUAL "STARPU") - add_subdirectory(api) - add_subdirectory(data-generators) - add_subdirectory(data-loader) - add_subdirectory(hardware) - add_subdirectory(linear-algebra-solvers) - add_subdirectory(prediction) - add_subdirectory(results) - add_subdirectory(runtime) - -elseif(RUNTIME_TYPE STREQUAL "PARSEC") -endif() +if (RUNTIME_TYPE STREQUAL "PARSEC") + add_subdirectory(data-analyzer) + add_subdirectory(data-transformer) +endif () if (USE_R) add_subdirectory(Rcpp-adapters) diff --git a/src/api/ExaGeoStat.cpp b/src/api/ExaGeoStat.cpp index e1f1b1d1..1e2a371e 100644 --- a/src/api/ExaGeoStat.cpp +++ b/src/api/ExaGeoStat.cpp @@ -66,7 +66,10 @@ T ExaGeoStat::ExaGeoStatDataModeling(Configurations &aConfigurations, std::un optimizing_function.set_ftol_abs(aConfigurations.GetTolerance()); // Set max iterations value. optimizing_function.set_maxeval(max_number_of_iterations); - optimizing_function.set_max_objective(ExaGeoStatMLETileAPI, (void *) modeling_data); + // TODO: ON API level it should be consistent regardless of the runtime being implemented +#if DEFAULT_RUNTIME + optimizing_function.set_max_objective(ModelingAPI, (void *) modeling_data); +#endif // Optimize mle using nlopt. optimizing_function.optimize(aConfigurations.GetStartingTheta(), opt_f); aConfigurations.SetEstimatedTheta(aConfigurations.GetStartingTheta()); @@ -89,8 +92,7 @@ T ExaGeoStat::ExaGeoStatDataModeling(Configurations &aConfigurations, std::un } template -double -ExaGeoStat::ExaGeoStatMLETileAPI(const std::vector &aTheta, std::vector &aGrad, void *apInfo) { +double ExaGeoStat::ModelingAPI(const std::vector &aTheta, std::vector &aGrad, void *apInfo) { auto config = ((mModelingData *) apInfo)->mpConfiguration; auto data = ((mModelingData *) apInfo)->mpData; @@ -100,7 +102,8 @@ ExaGeoStat::ExaGeoStatMLETileAPI(const std::vector &aTheta, std::vect // We do Date Modeling with any computation. auto linear_algebra_solver = linearAlgebra::LinearAlgebraFactory::CreateLinearAlgebraSolver( config->GetComputation()); - return linear_algebra_solver->ExaGeoStatMLETile(*data, *config, aTheta.data(), measurements, *kernel); + + return linear_algebra_solver->ModelingOperations(*data, *config, aTheta.data(), measurements, *kernel); } @@ -119,4 +122,14 @@ void ExaGeoStat::ExaGeoStatPrediction(Configurations &aConfigurations, std::u prediction::Prediction::PredictMissingData(aData, aConfigurations, apMeasurementsMatrix, *pKernel, apTrainLocations, apTestLocations); delete pKernel; -} \ No newline at end of file +} + +template +void ExaGeoStat::ExaGeoStatTransformData(Configurations &aConfigurations, std::unique_ptr> &aData){ + +} + +template +void ExaGeoStat::ExaGeoStatDataAnalyzer(Configurations &aConfigurations, std::unique_ptr> &aData){ + +} diff --git a/src/configurations/Configurations.cpp b/src/configurations/Configurations.cpp index e3b1557b..0e77e2c6 100644 --- a/src/configurations/Configurations.cpp +++ b/src/configurations/Configurations.cpp @@ -70,6 +70,17 @@ Configurations::Configurations() { SetAccuracy(0); SetIsNonGaussian(false); mIsThetaInit = false; +#if !DEFAULT_RUNTIME + // Set default values for Hicma-Parsec params + SetDenseBandDP(0); + SetObjectsNumber(0); + SetAdaptiveDecision(0); + SetDiagonalAddition(0); + SetTimeSlotPerFile(1); + SetFileNumber(1); + SetEnableInverse(false); + SetMPIIO(true); +#endif } void Configurations::InitializeArguments(const int &aArgC, char **apArgV, const bool &aEnableR) { @@ -122,7 +133,7 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV, const } else if (argument_name == "--gpus" || argument_name == "--GPUsNumbers" || argument_name == "--gpu_number" || argument_name == "--ngpus") { SetGPUsNumbers(CheckNumericalValue(argument_value)); - } else if (argument_name == "--DTS" || argument_name == "--dts" || argument_name == "--Dts") { + } else if (argument_name == "--DTS" || argument_name == "--dts" || argument_name == "--Dts" || argument_name == "--NB") { SetDenseTileSize(CheckNumericalValue(argument_value)); } else if (argument_name == "--LTS" || argument_name == "--lts" || argument_name == "--Lts") { SetLowTileSize(CheckNumericalValue(argument_value)); @@ -154,6 +165,19 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV, const ParseDistanceMetric(argument_value); } else if (argument_name == "--logpath" || argument_name == "--log_path" || argument_name == "--logPath") { SetLoggerPath(argument_value); + } else if(argument_name == "--band_dense" || argument_name == "--bandDense"){ + SetDenseBandDP(CheckNumericalValue(argument_value)); + } else if(argument_name == "--numobj" || argument_name == "--obj-num" || argument_name == "--objnum"){ + SetObjectsNumber(CheckNumericalValue(argument_value)); + } else if(argument_name == "--adaptive_decision"){ + SetAdaptiveDecision(CheckNumericalValue(argument_value)); + } else if(argument_name == "--add_diag" || argument_name == "--add-diag" || argument_name == "--add-diagonal" + || argument_name == "--add-diag-elements"){ + SetDiagonalAddition(CheckNumericalValue(argument_value)); + } else if(argument_name == "--file_time_slot" || argument_name == "--fileTimeSlot"){ + SetTimeSlotPerFile(CheckNumericalValue(argument_value)); + } else if(argument_name == "--numFiles" || argument_name == "--file-num"){ + SetFileNumber(CheckNumericalValue(argument_value)); } else { if (!(argument_name == "--ZmissNumber" || argument_name == "--Zmiss" || argument_name == "--ZMiss" || argument_name == "--predict" || argument_name == "--Predict" || @@ -183,6 +207,10 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV, const SetApproximationMode(true); } else if (argument_name == "--log" || argument_name == "--Log") { SetLogger(true); + } else if(argument_name == "--enable-inverse" || argument_name == "--enable_inverse"){ + SetEnableInverse(true); + } else if(argument_name == "--mpiio"){ + SetMPIIO(true); } else { if (!(argument_name == "--mspe" || argument_name == "--MSPE" || argument_name == "--idw" || argument_name == "--IDW" || @@ -200,13 +228,17 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV, const if (GetProblemSize() == 0 && GetIsSynthetic()) { throw domain_error("You need to set the problem size, before starting"); } + if (GetDenseTileSize() == 0) { throw domain_error("You need to set the Dense tile size, before starting"); } + +#if DEFAULT_RUNTIME // Throw Errors if any of these arguments aren't given by the user. if (GetKernelName().empty()) { throw domain_error("You need to set the Kernel, before starting"); } +#endif size_t found = GetKernelName().find("NonGaussian"); // Check if the substring was found @@ -423,6 +455,14 @@ void Configurations::PrintUsage() { LOGGER("--approximation_mode : Used to enable Approximation mode.") LOGGER("--log : Enable logging.") LOGGER("--acc : Used to set the accuracy when using tlr.") + LOGGER("--band_dense=value : Used to set the dense band double precision, Used with PaRSEC runtime only.") + LOGGER("--numobj=value : Used to set the number of objects (number of viruses within a population), Used with PaRSEC runtime only.") + LOGGER("--adaptive_decision=value : Used to set the adaptive decision of each tile's format using norm approach, if enabled, otherwise 0, Used with PaRSEC runtime only.") + LOGGER("--add_diag=value : Used to add this number to diagonal elements to make the matrix positive definite in electrodynamics problem, Used with PaRSEC runtime only.") + LOGGER("--file_time_slot=value : Used to set time slot per file, Used with PaRSEC runtime only.") + LOGGER("--numFiles=value : Used to set file number, Used with PaRSEC runtime only.") + LOGGER("--enable-inverse : Used to enable inverse spherical harmonics transform, Used with PaRSEC runtime only.") + LOGGER("--mpiio : Used to enable MPI IO, Used with PaRSEC runtime only.") LOGGER("\n\n") exit(0); diff --git a/src/data-analyzer/CMakeLists.txt b/src/data-analyzer/CMakeLists.txt new file mode 100644 index 00000000..c257f99f --- /dev/null +++ b/src/data-analyzer/CMakeLists.txt @@ -0,0 +1,17 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @brief This file contains the CMake configuration for the data-analyzer directory. +# @version 2.0.0 +# @author Mahmoud ElKarargy +# @author Sameh Abdulah +# @date 2024-10-15 + +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/DataAnalyzer.cpp + ${SOURCES} + PARENT_SCOPE +) \ No newline at end of file diff --git a/src/data-analyzer/DataAnalyzer.cpp b/src/data-analyzer/DataAnalyzer.cpp new file mode 100644 index 00000000..942c9df8 --- /dev/null +++ b/src/data-analyzer/DataAnalyzer.cpp @@ -0,0 +1,27 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file DataAnalyzer.cpp + * @brief Contains the implementation of the DataAnalyzer class. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-04 +**/ + +#include + +using namespace exageostat::configurations; + +template +static void AnalyzeMatrix(Configurations &aConfigurations, std::unique_ptr> &aData){ + +} + +template +static double CompareMatDifference(Configurations &aConfigurations, std::unique_ptr> &aData){ + +} diff --git a/src/data-generators/concrete/SyntheticGenerator.cpp b/src/data-generators/concrete/SyntheticGenerator.cpp index 85cfa7ec..dea29b27 100644 --- a/src/data-generators/concrete/SyntheticGenerator.cpp +++ b/src/data-generators/concrete/SyntheticGenerator.cpp @@ -51,6 +51,8 @@ SyntheticGenerator::CreateData(Configurations &aConfigurations, *locations); data->SetLocations(*locations); + // TODO: May need to get refactored to avoid the if/else guards +#if DEFAULT_RUNTIME // Generate Descriptors phase auto linear_algebra_solver = linearAlgebra::LinearAlgebraFactory::CreateLinearAlgebraSolver(EXACT_DENSE); linear_algebra_solver->GenerateSyntheticData(aConfigurations, data, aKernel); @@ -81,6 +83,7 @@ SyntheticGenerator::CreateData(Configurations &aConfigurations, #endif VERBOSE("Done.") } +#endif Results::GetInstance()->SetGeneratedLocationsNumber(n); Results::GetInstance()->SetIsLogger(aConfigurations.GetLogger()); Results::GetInstance()->SetLoggerPath(aConfigurations.GetLoggerPath()); diff --git a/src/data-loader/DataLoader.cpp b/src/data-loader/DataLoader.cpp index fb7ca2fd..65874148 100644 --- a/src/data-loader/DataLoader.cpp +++ b/src/data-loader/DataLoader.cpp @@ -42,6 +42,9 @@ DataLoader::CreateData(configurations::Configurations &aConfigurations, exage //Initialize the descriptors. auto linear_algebra_solver = linearAlgebra::LinearAlgebraFactory::CreateLinearAlgebraSolver(EXACT_DENSE); + + // TODO: May need to get refactored to avoid the if/else guards +#if DEFAULT_RUNTIME linear_algebra_solver->InitiateDescriptors(aConfigurations, *data->GetDescriptorData(), p); linear_algebra_solver->ExaGeoStatLaSetTile(EXAGEOSTAT_UPPER_LOWER, 0, 0, data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, @@ -58,6 +61,7 @@ DataLoader::CreateData(configurations::Configurations &aConfigurations, exage ((T *) data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc->mat)[i] = measurements_vector[i]; } +#endif Results::GetInstance()->SetGeneratedLocationsNumber(aConfigurations.GetProblemSize() / p); Results::GetInstance()->SetIsLogger(aConfigurations.GetLogger()); diff --git a/src/data-transformer/CMakeLists.txt b/src/data-transformer/CMakeLists.txt new file mode 100644 index 00000000..273aeaf9 --- /dev/null +++ b/src/data-transformer/CMakeLists.txt @@ -0,0 +1,17 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @brief CMake configuration file for data-transformer directory +# @version 2.0.0 +# @author Mahmoud ElKarargy +# @date 2024-10-15 + +# Add source files to the parent scope +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/DataTransformer.cpp + ${SOURCES} + PARENT_SCOPE +) diff --git a/src/data-transformer/DataTransformer.cpp b/src/data-transformer/DataTransformer.cpp new file mode 100644 index 00000000..2145204e --- /dev/null +++ b/src/data-transformer/DataTransformer.cpp @@ -0,0 +1,32 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file DataTransformer.cpp + * @brief Contains the implementation of the DataTransformer class. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-04 +**/ + +#include + +using namespace exageostat::configurations; + +template +static void ForwardSHT(Configurations &aConfigurations, std::unique_ptr> &aData){ + +} + +template +static void ForwardReshape(Configurations &aConfigurations, std::unique_ptr> &aData){ + +} + +template +static void InverseSHT(Configurations &aConfigurations, std::unique_ptr> &aData){ + +} diff --git a/src/data-units/CMakeLists.txt b/src/data-units/CMakeLists.txt index 70977f00..43a185ae 100644 --- a/src/data-units/CMakeLists.txt +++ b/src/data-units/CMakeLists.txt @@ -9,20 +9,17 @@ # @author Sameh Abdulah # @date 2023-02-27 -# Initialize SOURCES variable if not already initialized -set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Locations.cpp ${SOURCES}) - if (RUNTIME_TYPE STREQUAL "STARPU") - # Include the concrete implementations of the ExaGeoStat Descriptor class add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/descriptor) - # Append the necessary source files for the STARPU runtime - list(APPEND SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/DescriptorData.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/ExaGeoStatData.cpp - - ) endif() -# Set the SOURCES variable to the parent scope -set(SOURCES ${SOURCES} PARENT_SCOPE) +# Initialize SOURCES variable if not already initialized +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/Locations.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DescriptorData.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ExaGeoStatData.cpp + ${SOURCES} + PARENT_SCOPE + ) + diff --git a/src/data-units/DescriptorData.cpp b/src/data-units/DescriptorData.cpp index eff728d3..34efa842 100644 --- a/src/data-units/DescriptorData.cpp +++ b/src/data-units/DescriptorData.cpp @@ -21,6 +21,7 @@ using namespace exageostat::dataunits::descriptor; template DescriptorData::~DescriptorData() { +#if DEFAULT_RUNTIME ExaGeoStatDescriptor exaGeoStatDescriptor; // Destroy descriptors. const std::string &chameleon = "_CHAMELEON"; @@ -47,6 +48,7 @@ DescriptorData::~DescriptorData() { if (this->mpSequence) { CHAMELEON_Sequence_Destroy((RUNTIME_sequence_t *) this->mpSequence); } +#endif } template @@ -91,6 +93,8 @@ BaseDescriptor DescriptorData::GetDescriptor(const DescriptorType &aDescriptorType, const DescriptorName &aDescriptorName) { BaseDescriptor descriptor{}; +#if DEFAULT_RUNTIME + if (aDescriptorType == CHAMELEON_DESCRIPTOR) { if (this->mDictionary.find(GetDescriptorName(aDescriptorName) + "_CHAMELEON") == this->mDictionary.end()) { descriptor.chameleon_desc = nullptr; @@ -119,6 +123,7 @@ DescriptorData::GetDescriptor(const DescriptorType &aDescriptorType, const De throw std::runtime_error("To use HiCMA descriptor you need to enable USE_HICMA!"); #endif } +#endif return descriptor; } @@ -132,6 +137,8 @@ void DescriptorData::SetDescriptor(const DescriptorType &aDescriptorType, con void *descriptor; std::string type; ExaGeoStatDescriptor exaGeoStatDescriptor; +#if DEFAULT_RUNTIME + if (aDescriptorType == CHAMELEON_DESCRIPTOR) { descriptor = exaGeoStatDescriptor.CreateDescriptor((CHAM_desc_t *) descriptor, aDescriptorType, aIsOOC, apMatrix, aFloatPoint, aMB, aNB, aSize, aLM, aLN, aI, aJ, aM, @@ -153,12 +160,13 @@ void DescriptorData::SetDescriptor(const DescriptorType &aDescriptorType, con type = "_CHAM_HIC"; } this->mDictionary[GetDescriptorName(aDescriptorName) + type] = descriptor; - +#endif } template T * DescriptorData::GetDescriptorMatrix(const DescriptorType &aDescriptorType, const DescriptorName &aDescriptorName) { +#if DEFAULT_RUNTIME if (aDescriptorType == CHAMELEON_DESCRIPTOR) { return (T *) (this->GetDescriptor(CHAMELEON_DESCRIPTOR, aDescriptorName).chameleon_desc)->mat; } else { @@ -168,6 +176,7 @@ DescriptorData::GetDescriptorMatrix(const DescriptorType &aDescriptorType, co throw std::runtime_error("To use Hicma descriptor you need to enable USE_HICMA!"); #endif } +#endif } // Define a function that returns the name of a DescriptorName value as a string diff --git a/src/hardware/ExaGeoStatHardware.cpp b/src/hardware/ExaGeoStatHardware.cpp index 3e9f3c18..d17631aa 100644 --- a/src/hardware/ExaGeoStatHardware.cpp +++ b/src/hardware/ExaGeoStatHardware.cpp @@ -12,13 +12,19 @@ * @date 2024-02-04 **/ +#include + +#if DEFAULT_RUNTIME #ifdef USE_MPI #include #endif #include #include -#include +#else +#include +#endif + #include #include #include @@ -26,6 +32,68 @@ using namespace exageostat::common; using namespace exageostat::results; +using namespace std; + +ExaGeoStatHardware::ExaGeoStatHardware(exageostat::configurations::Configurations &aConfigurations){ + + // These variables are named according to HiCMA-X inputs + const int N = aConfigurations.GetProblemSize(); + const int t = aConfigurations.GetDenseTileSize(); + const int e = aConfigurations.GetAccuracy(); + const int a = aConfigurations.GetAdaptiveDecision(); + const int g = aConfigurations.GetGPUsNumbers(); + const int c = aConfigurations.GetCoresNumber(); + const int j = aConfigurations.GetDiagonalAddition(); + const int J = aConfigurations.GetTimeSlot(); + const int K = aConfigurations.GetObjectsNumber(); + const int I = aConfigurations.GetDenseBandDP(); + const int time_slot_per_file = aConfigurations.GetTimeSlotPerFile(); + const int num_file = aConfigurations.GetFileNumber(); + + int v = 0; + if (aConfigurations.GetVerbosity() == Verbose::DETAILED_MODE){ + v = 1; + } + + // Create a vector to store the arguments as strings + std::vector new_args = { + "-g", to_string(g), + "-NB", to_string(t), + "-K", to_string(t), + "-N", to_string(N), + "-v", to_string(v), + "-I", to_string(I), + "-a", to_string(a), + "-J", to_string(J), + "-c", to_string(c), + "-K", to_string(K), + "-j", to_string(j) + }; + + // Convert std::vector to char** for the new argv + int new_argc = new_args.size(); + char **new_argv = new char*[new_argc]; + + for (int i = 0; i < new_argc; ++i) { + new_argv[i] = new char[new_args[i].length() + 1]; + strcpy(new_argv[i], new_args[i].c_str()); + } + +#if !DEFAULT_RUNTIME + int iparam[IPARAM_SIZEOF] = {0}; + double dparam[DPARAM_SIZEOF]; + char *cparam[CPARAM_SIZEOF]; + hicma_parsec_params_t params; + starsh_params_t params_kernel; + hicma_parsec_data_t data; + hicma_parsec_matrix_analysis_t analysis; + this->mpParsecContext = hicma_parsec_init( new_argc, new_argv, iparam, dparam, cparam, ¶ms, ¶ms_kernel, &data ); +#endif + + LOGGER("Climate Emulator Parameters") + LOGGER("L: " << t << "\tT: " << J << "\tNB: " << t << "\tgpus: " << g) + LOGGER("nodes: " << c << "\ttime_slot_per_file: " << time_slot_per_file << "\tnum_file: " << num_file << "\tfile_per_node: " << ((num_file%c)? num_file/c+1 : num_file/c)) +} ExaGeoStatHardware::ExaGeoStatHardware(const Computation &aComputation, const int &aCoreNumber, const int &aGpuNumber, const int &aP, const int &aQ) { @@ -45,6 +113,7 @@ void ExaGeoStatHardware::InitHardware(const Computation &aComputation, const int SetQGrid(aQ); int tag_width = 31, tag_sep = 40; +#if DEFAULT_RUNTIME // Init hardware using Chameleon if (!mpChameleonContext) { #ifdef USE_MPI @@ -80,12 +149,14 @@ void ExaGeoStatHardware::InitHardware(const Computation &aComputation, const int throw std::runtime_error("You need to enable HiCMA to use TLR computation!"); #endif } +#endif exageostat::helpers::CommunicatorMPI::GetInstance()->SetHardwareInitialization(); LOGGER("** Initialize ExaGeoStat hardware **") } void ExaGeoStatHardware::FinalizeHardware() { + #if DEFAULT_RUNTIME // finalize hardware using HiCMA #ifdef USE_HICMA if (mpHicmaContext) { @@ -104,6 +175,8 @@ void ExaGeoStatHardware::FinalizeHardware() { mpChameleonContext = nullptr; } +#endif + exageostat::helpers::CommunicatorMPI::GetInstance()->RemoveHardwareInitialization(); } @@ -127,6 +200,13 @@ void *ExaGeoStatHardware::GetChameleonContext() { return mpChameleonContext; } +void *ExaGeoStatHardware::GetParsecContext() { + if (!mpParsecContext) { + throw std::runtime_error("PaRSEC Hardware is not initialized!"); + } + return mpParsecContext; +} + void *ExaGeoStatHardware::GetContext(Computation aComputation) { if (aComputation == EXACT_DENSE || aComputation == DIAGONAL_APPROX) { return GetChameleonContext(); @@ -155,6 +235,7 @@ void ExaGeoStatHardware::SetQGrid(int aQ) { void *ExaGeoStatHardware::mpChameleonContext = nullptr; void *ExaGeoStatHardware::mpHicmaContext = nullptr; +void *ExaGeoStatHardware::mpParsecContext = nullptr; int ExaGeoStatHardware::mPGrid = 1; int ExaGeoStatHardware::mQGrid = 1; bool ExaGeoStatHardware::mIsMPIInit = false; diff --git a/src/linear-algebra-solvers/CMakeLists.txt b/src/linear-algebra-solvers/CMakeLists.txt index 8a9eba80..865936d7 100644 --- a/src/linear-algebra-solvers/CMakeLists.txt +++ b/src/linear-algebra-solvers/CMakeLists.txt @@ -16,7 +16,14 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/concrete) # Define the sources for the library set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebraFactory.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebraMethods.cpp ${SOURCES} - PARENT_SCOPE - ) \ No newline at end of file + ) + +if (RUNTIME_TYPE STREQUAL "STARPU") + set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/LinearAlgebraMethods.cpp + ${SOURCES} + ) +endif () + +set(SOURCES ${SOURCES} PARENT_SCOPE) diff --git a/src/linear-algebra-solvers/LinearAlgebraFactory.cpp b/src/linear-algebra-solvers/LinearAlgebraFactory.cpp index 0d72dbad..5a1fef26 100644 --- a/src/linear-algebra-solvers/LinearAlgebraFactory.cpp +++ b/src/linear-algebra-solvers/LinearAlgebraFactory.cpp @@ -15,13 +15,14 @@ #include +#if DEFAULT_RUNTIME #include #include #ifdef USE_HICMA - #include +#endif #endif @@ -31,6 +32,7 @@ using namespace exageostat::common; template std::unique_ptr> LinearAlgebraFactory::CreateLinearAlgebraSolver(Computation aComputation) { +#if DEFAULT_RUNTIME // Check the used Linear Algebra solver library, whether it's HiCMA or Chameleon. if (aComputation == EXACT_DENSE) { @@ -49,6 +51,7 @@ std::unique_ptr> LinearAlgebraFactory::CreateLinearAl return std::make_unique>(); } +#endif // Return nullptr if no computation is selected throw std::runtime_error("You need to enable whether HiCMA or Chameleon"); } diff --git a/src/linear-algebra-solvers/LinearAlgebraMethods.cpp b/src/linear-algebra-solvers/LinearAlgebraMethods.cpp index 146ccf9e..8a083d72 100644 --- a/src/linear-algebra-solvers/LinearAlgebraMethods.cpp +++ b/src/linear-algebra-solvers/LinearAlgebraMethods.cpp @@ -1340,37 +1340,6 @@ LinearAlgebraMethods::ExaGeoStatGetZObs(Configurations &aConfigurations, T *a this->ExaGeoStatDesc2Lap(apZ, aSize, z_desc, UpperLower::EXAGEOSTAT_UPPER_LOWER); } -#ifdef USE_HICMA - -template -void LinearAlgebraMethods::CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, - const common::CopyDirection &aDirection) { - auto *z = new T[aSize]; - int status; - if (aDirection == common::CHAMELEON_TO_HICMA) { - status = CHAMELEON_Desc2Lap((cham_uplo_t) EXAGEOSTAT_UPPER_LOWER, (CHAM_desc_t *) apSourceDesc, z, aSize); - if (status != CHAMELEON_SUCCESS) { - throw std::runtime_error("CHAMELEON_Desc2Lap Failed!"); - } - status = HICMA_Lapack_to_Tile(z, aSize, (HICMA_desc_t *) apDestinationDesc); - if (status != HICMA_SUCCESS) { - throw std::runtime_error("HICMA_Lapack_to_Tile Failed!"); - } - } else if (aDirection == common::HICMA_TO_CHAMELEON) { - status = HICMA_Tile_to_Lapack((HICMA_desc_t *) apSourceDesc, z, aSize); - if (status != HICMA_SUCCESS) { - throw std::runtime_error("HICMA_Tile_to_Lapack Failed!"); - } - status = CHAMELEON_Lap2Desc((cham_uplo_t) EXAGEOSTAT_UPPER_LOWER, z, aSize, (CHAM_desc_t *) apDestinationDesc); - if (status != CHAMELEON_SUCCESS) { - throw std::runtime_error("CHAMELEON_Lap2Desc Failed!"); - } - } - delete[] z; -} - -#endif - template void LinearAlgebraMethods::ExaGeoStatDesc2Lap(T *apA, const int &aLDA, void *apDescA, const UpperLower &aUpperLower) { diff --git a/src/linear-algebra-solvers/concrete/CMakeLists.txt b/src/linear-algebra-solvers/concrete/CMakeLists.txt index 74df59f8..f1989e2b 100644 --- a/src/linear-algebra-solvers/concrete/CMakeLists.txt +++ b/src/linear-algebra-solvers/concrete/CMakeLists.txt @@ -12,18 +12,24 @@ # @date 2023-03-20 # Include the concrete implementations of the LinearAlgebraMethods class based on the enabled libraries (HiCMA or Chameleon) -set(SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/chameleon/dense/ChameleonDense.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/chameleon/dst/ChameleonDST.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/chameleon/ChameleonImplementation.cpp - ${SOURCES} - ) +if (RUNTIME_TYPE STREQUAL "STARPU") + set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/chameleon/dense/ChameleonDense.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/chameleon/dst/ChameleonDST.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/chameleon/ChameleonImplementation.cpp + ${SOURCES} + ) -if (USE_HICMA) - list(APPEND SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/tlr/HicmaImplementation.cpp - ) + if (USE_HICMA) + list(APPEND SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/tlr/HicmaImplementation.cpp + ) + endif () +elseif (RUNTIME_TYPE STREQUAL "PARSEC") + set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/parsec/ParsecImplementation.cpp + ${SOURCES} + ) endif () - set(SOURCES ${SOURCES} PARENT_SCOPE) diff --git a/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp b/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp index 8ec6abe8..5c3dd8ef 100644 --- a/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp +++ b/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp @@ -33,9 +33,9 @@ using namespace exageostat::configurations; using namespace exageostat::linearAlgebra; template -T ChameleonImplementation::ExaGeoStatMLETile(std::unique_ptr> &aData, - configurations::Configurations &aConfigurations, const double *theta, - T *apMeasurementsMatrix, const kernels::Kernel &aKernel) { +T ChameleonImplementation::ModelingOperations(std::unique_ptr > &aData, + configurations::Configurations &aConfigurations, const double *theta, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) { if (!aData->GetDescriptorData()->GetIsDescriptorInitiated()) { this->InitiateDescriptors(aConfigurations, *aData->GetDescriptorData(), aKernel.GetVariablesNumber(), @@ -361,3 +361,34 @@ void ChameleonImplementation::ExaGeoStatCreateSequence(void *apSequence) { throw std::runtime_error("CHAMELEON_Sequence_Create Failed!"); } } + +template +void ChameleonImplementation::CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, + const common::CopyDirection &aDirection) { + +} + +template +void +ChameleonImplementation::ExaGeoStatSYRK(Configurations &aConfigurations, unique_ptr > &aData) { + +} + +template +void ChameleonImplementation::ExaGeoStatTLRCholesky(Configurations &aConfigurations, + unique_ptr > &aData) { + +} + +template +void +ChameleonImplementation::ExaGeoStatNorm(Configurations &aConfigurations, unique_ptr > &aData) { + +} + +template +double +ChameleonImplementation::CalculateMSE(Configurations &aConfigurations, unique_ptr > &aData) { + + return 0; +} \ No newline at end of file diff --git a/src/linear-algebra-solvers/concrete/parsec/ParsecImplementation.cpp b/src/linear-algebra-solvers/concrete/parsec/ParsecImplementation.cpp new file mode 100644 index 00000000..60a5f8fd --- /dev/null +++ b/src/linear-algebra-solvers/concrete/parsec/ParsecImplementation.cpp @@ -0,0 +1,90 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ParsecImplementation.cpp + * @brief This file contains the implementation of ParsecImplementation class. + * @details ParsecImplementation is a concrete implementation of the LinearAlgebraMethods class. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-10-15 +**/ + +#include + +using namespace exageostat::linearAlgebra; +using namespace exageostat::configurations; + +template +void ParsecImplementation::ExaGeoStatSYRK(Configurations &aConfigurations, std::unique_ptr> &aData){ + +} + +template +void ParsecImplementation::ExaGeoStatTLRCholesky(Configurations &aConfigurations, std::unique_ptr> &aData){ + +} + +template +void +ParsecImplementation::ExaGeoStatNorm(Configurations &aConfigurations, std::unique_ptr> &aData) { + +} + +template +double +ParsecImplementation::CalculateMSE(Configurations &aConfigurations, std::unique_ptr> &aData) { + + return 0; +} + +template +T ParsecImplementation::ModelingOperations(std::unique_ptr> &aData, + configurations::Configurations &aConfigurations, const double *apTheta, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) { + +} + +template +void ParsecImplementation::ExaGeoStatLapackCopyTile(const common::UpperLower &aUpperLower, void *apA, void *apB) { + +} + + +template +void ParsecImplementation::ExaGeoStatSequenceWait(void *apSequence) { + +} + + +template +void ParsecImplementation::ExaGeoStatCreateSequence(void *apSequence) { + +} + + +template +void +ParsecImplementation::ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, void *apCD, + void *apCrk, const int &aMaxRank, const int &aAcc) { + +} + + +template +void ParsecImplementation::ExaGeoStatTrsmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, + const common::Trans &aTrans, const common::Diag &aDiag, + const T &aAlpha, void *apA, void *apCD, void *apCrk, void *apZ, + const int &aMaxRank) { + +} + + +template +void ParsecImplementation::CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, + const common::CopyDirection &aDirection) { + +} \ No newline at end of file diff --git a/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp b/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp index c297bb01..a466ea4e 100644 --- a/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp +++ b/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp @@ -31,14 +31,15 @@ using namespace exageostat::dataunits; using namespace exageostat::kernels; using namespace exageostat::helpers; using namespace exageostat::results; +using namespace exageostat::configurations; int store_only_diagonal_tiles = 1; int use_scratch = 1; int global_check = 0; //used to create dense matrix for accuracy check template -void HicmaImplementation::SetModelingDescriptors(std::unique_ptr> &aData, - configurations::Configurations &aConfigurations, const int &aP) { +void HicmaImplementation::SetModelingDescriptors(std::unique_ptr > &aData, + Configurations &aConfigurations, const int &aP) { int full_problem_size = aConfigurations.GetProblemSize() * aP; int lts = aConfigurations.GetLowTileSize(); @@ -114,9 +115,9 @@ void HicmaImplementation::SetModelingDescriptors(std::unique_ptr -T HicmaImplementation::ExaGeoStatMLETile(std::unique_ptr> &aData, - configurations::Configurations &aConfigurations, const double *theta, - T *apMeasurementsMatrix, const Kernel &aKernel) { +T HicmaImplementation::ModelingOperations(std::unique_ptr > &aData, + Configurations &aConfigurations, const double *theta, + T *apMeasurementsMatrix, const Kernel &aKernel) { if (!aData->GetDescriptorData()->GetIsDescriptorInitiated()) { this->InitiateDescriptors(aConfigurations, *aData->GetDescriptorData(), aKernel.GetVariablesNumber(), @@ -402,3 +403,55 @@ void HicmaImplementation::ExaGeoStatTrsmTile(const common::Side &aSide, const throw std::runtime_error("HICMA_dtrsmd_Tile Failed!"); } } + + +template +void HicmaImplementation::CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, + const common::CopyDirection &aDirection) { + + auto *z = new T[aSize]; + int status; + if (aDirection == common::CHAMELEON_TO_HICMA) { + status = CHAMELEON_Desc2Lap((cham_uplo_t) EXAGEOSTAT_UPPER_LOWER, (CHAM_desc_t *) apSourceDesc, z, aSize); + if (status != CHAMELEON_SUCCESS) { + throw std::runtime_error("CHAMELEON_Desc2Lap Failed!"); + } + status = HICMA_Lapack_to_Tile(z, aSize, (HICMA_desc_t *) apDestinationDesc); + if (status != HICMA_SUCCESS) { + throw std::runtime_error("HICMA_Lapack_to_Tile Failed!"); + } + } else if (aDirection == common::HICMA_TO_CHAMELEON) { + status = HICMA_Tile_to_Lapack((HICMA_desc_t *) apSourceDesc, z, aSize); + if (status != HICMA_SUCCESS) { + throw std::runtime_error("HICMA_Tile_to_Lapack Failed!"); + } + status = CHAMELEON_Lap2Desc((cham_uplo_t) EXAGEOSTAT_UPPER_LOWER, z, aSize, (CHAM_desc_t *) apDestinationDesc); + if (status != CHAMELEON_SUCCESS) { + throw std::runtime_error("CHAMELEON_Lap2Desc Failed!"); + } + } + delete[] z; +} + + +template +void HicmaImplementation::ExaGeoStatSYRK(Configurations &aConfigurations, unique_ptr > &aData) { + +} + +template +void +HicmaImplementation::ExaGeoStatTLRCholesky(Configurations &aConfigurations, unique_ptr > &aData) { + +} + +template +void HicmaImplementation::ExaGeoStatNorm(Configurations &aConfigurations, unique_ptr > &aData) { + +} + +template +double HicmaImplementation::CalculateMSE(Configurations &aConfigurations, unique_ptr > &aData) { + + return 0; +} \ No newline at end of file diff --git a/src/prediction/Prediction.cpp b/src/prediction/Prediction.cpp index c5b625b7..943fc8b1 100644 --- a/src/prediction/Prediction.cpp +++ b/src/prediction/Prediction.cpp @@ -32,6 +32,7 @@ void Prediction::PredictMissingData(unique_ptr> &aData, Con T *apMeasurementsMatrix, const kernels::Kernel &aKernel, Locations *apTrainLocations, Locations *apTestLocations) { +#if DEFAULT_RUNTIME int i, j; bool can_predict = true; int num_params = aKernel.GetParametersNumbers(); @@ -201,6 +202,7 @@ void Prediction::PredictMissingData(unique_ptr> &aData, Con delete[] z_actual; delete miss_locations; delete obs_locations; +#endif } template @@ -209,7 +211,7 @@ void Prediction::InitializePredictionArguments(Configurations &aConfiguration T *apZObs, T *apZActual, Locations &aMissLocation, Locations &aObsLocation, T *apMeasurementsMatrix, const int &aP, Locations *apTrainLocations, Locations *apTestLocations) { - +#if DEFAULT_RUNTIME int full_problem_size = aConfigurations.GetProblemSize() * aP; T *z = new T[full_problem_size]; @@ -231,4 +233,5 @@ void Prediction::InitializePredictionArguments(Configurations &aConfiguration memcpy(apZObs, apMeasurementsMatrix, aObsLocation.GetSize() * sizeof(T)); } delete[] z; +#endif } \ No newline at end of file diff --git a/tests/cpp-tests/CMakeLists.txt b/tests/cpp-tests/CMakeLists.txt index b1a4f2d8..fcbb425e 100644 --- a/tests/cpp-tests/CMakeLists.txt +++ b/tests/cpp-tests/CMakeLists.txt @@ -8,10 +8,11 @@ # @author Mahmoud ElKarargy # @date 2024-01-24 +add_subdirectory(configurations) + # Check the value of RUNTIME_TYPE if(RUNTIME_TYPE STREQUAL "STARPU") add_subdirectory(api) - add_subdirectory(configurations) add_subdirectory(data-generators) add_subdirectory(hardware) add_subdirectory(helpers) diff --git a/tests/cpp-tests/configurations/TestConfigurations.cpp b/tests/cpp-tests/configurations/TestConfigurations.cpp index 6ea294f6..cfe0afa8 100644 --- a/tests/cpp-tests/configurations/TestConfigurations.cpp +++ b/tests/cpp-tests/configurations/TestConfigurations.cpp @@ -94,6 +94,48 @@ void TEST_ARGUMENT_INITIALIZATION() { } + +void TEST_ARGUMENT_INITIALIZATION_PARSEC() { + + const int argc = 12; + char *argv[] = { + const_cast("program_name"), + const_cast("--N=16"), + const_cast("--dts=8"), + const_cast("--precision=double"), + const_cast("--band_dense=100"), + const_cast("--numobj=72"), + const_cast("--adaptive_decision=1"), + const_cast("--add_diag=10"), + const_cast("--file_time_slot=1"), + const_cast("--file-num=1"), + const_cast("--enable-inverse"), + const_cast("--mpiio") + }; + + Configurations configurations; + // Initialize configuration dictionary with only common arguments + configurations.InitializeArguments(argc, argv); + + REQUIRE(configurations.GetProblemSize() == 16); + REQUIRE(configurations.GetDenseTileSize() == 8); + REQUIRE(configurations.GetPrecision() == DOUBLE); + + // Check Hicma-Parsec parameters + REQUIRE(configurations.GetDenseBandDP() == 100); + REQUIRE(configurations.GetObjectsNumber() == 72); + REQUIRE(configurations.GetAdaptiveDecision() == 1); + REQUIRE(configurations.GetDiagonalAddition() == 10); + REQUIRE(configurations.GetTimeSlotPerFile() == 1); + REQUIRE(configurations.GetFileNumber() == 1); + REQUIRE(configurations.GetEnableInverse() == true); + REQUIRE(configurations.GetMPIIO() == true); + + // No data generation arguments initialized + REQUIRE(configurations.GetDataPath() == string("")); +} + + void TEST_SYNTHETIC_CONFIGURATIONS() { Configurations synthetic_data_configurations; @@ -186,4 +228,7 @@ TEST_CASE("Configurations Tests") { TEST_SYNTHETIC_CONFIGURATIONS(); TEST_COPY_CONSTRUCTOR(); TEST_ARGUMENT_INITIALIZATION(); +#if !DEFAULT_RUNTIME + TEST_ARGUMENT_INITIALIZATION_PARSEC(); +#endif } From 216f79285cf181d542c2b8cb46e7324a63b606dd Mon Sep 17 00:00:00 2001 From: Mahmoud Elkarargy <113839437+mahmoudElkarargyBS@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:35:54 +0200 Subject: [PATCH 3/5] Data Transformers and Data Loaders (#13) * Data transformers * minior cleaning * resolve threads * fix NT value * full climate Emulator * Fix shaheen installation --- CMakeLists.txt | 1 - cmake/FindHICMA-X.cmake | 1 + cmake/ImportHiCMAX.cmake | 4 +- cmake/ImportStarsH.cmake | 2 +- examples/climate-emulator/ClimateEmulator.cpp | 17 +- inst/include/api/ExaGeoStat.hpp | 33 -- inst/include/common/Definitions.hpp | 21 +- inst/include/data-analyzer/DataAnalyzer.hpp | 28 +- .../include/data-generators/DataGenerator.hpp | 4 +- inst/include/data-loader/DataLoader.hpp | 29 ++ .../data-loader/concrete/CSVLoader.hpp | 10 +- .../data-loader/concrete/ParsecLoader.hpp | 121 ++++++ .../data-transformer/DataTransformer.hpp | 20 +- inst/include/data-units/DescriptorData.hpp | 18 +- .../descriptor/ExaGeoStatDescriptor.hpp | 7 +- .../descriptor/concrete/ParsecDescriptor.hpp | 58 +++ inst/include/hardware/ExaGeoStatHardware.hpp | 65 +++ .../LinearAlgebraMethods.hpp | 220 ++++------ .../chameleon/ChameleonImplementation.hpp | 56 +-- .../hicma/tlr/HicmaImplementation.hpp | 48 +- .../concrete/parsec/ParsecImplementation.hpp | 122 ------ .../runtime-solver/RuntimeSolverFactory.hpp | 52 +++ .../runtime-solver/RuntimeSolverMethods.hpp | 54 +++ .../concrete/ParsecRuntimeSolver.hpp | 83 ++++ .../concrete/StarpuRuntimeSolver.hpp | 62 +++ .../runtime/parsec/JDFHelperFunctions.h | 76 ++++ .../{ParsecHeader.hpp => ParsecHeader.h} | 0 .../runtime/parsec/jdf/JobDescriptionFormat.h | 266 ++++++++++++ src/CMakeLists.txt | 6 +- src/api/ExaGeoStat.cpp | 67 +-- src/configurations/Configurations.cpp | 32 +- src/data-analyzer/DataAnalyzer.cpp | 40 +- src/data-generators/DataGenerator.cpp | 33 +- .../concrete/SyntheticGenerator.cpp | 6 + src/data-loader/DataLoader.cpp | 65 +-- src/data-loader/concrete/CMakeLists.txt | 18 +- src/data-loader/concrete/CSVLoader.cpp | 52 ++- src/data-loader/concrete/ParsecLoader.cpp | 284 ++++++++++++ src/data-transformer/DataTransformer.cpp | 93 +++- src/data-units/CMakeLists.txt | 6 +- src/data-units/DescriptorData.cpp | 75 +++- src/data-units/descriptor/CMakeLists.txt | 4 +- .../descriptor/ExaGeoStatDescriptor.cpp | 31 +- .../descriptor/concrete/CMakeLists.txt | 22 +- .../descriptor/concrete/ParsecDescriptor.cpp | 34 ++ src/hardware/ExaGeoStatHardware.cpp | 72 ++- src/helpers/CommunicatorMPI.cpp | 8 +- .../LinearAlgebraFactory.cpp | 5 +- .../LinearAlgebraMethods.cpp | 32 +- .../concrete/CMakeLists.txt | 5 - .../chameleon/ChameleonImplementation.cpp | 37 +- .../chameleon/dense/ChameleonDense.cpp | 1 - .../concrete/parsec/ParsecImplementation.cpp | 90 ---- .../concrete/tlr/HicmaImplementation.cpp | 63 +-- src/runtime-solver/CMakeLists.txt | 19 + src/runtime-solver/RuntimeSolverFactory.cpp | 36 ++ src/runtime-solver/concrete/CMakeLists.txt | 27 ++ .../concrete/ParsecRuntimeSolver.cpp | 105 +++++ .../concrete/StarpuRuntimeSolver.cpp | 79 ++++ src/runtime/CMakeLists.txt | 5 +- src/runtime/parsec/CMakeLists.txt | 17 +- src/runtime/parsec/JDFHelperFunctions.c | 185 ++++++++ src/runtime/parsec/jdf/CMakeLists.txt | 50 +++ src/runtime/parsec/jdf/DifferenceDouble.jdf | 92 ++++ src/runtime/parsec/jdf/ForwardSHT.jdf | 290 +++++++++++++ src/runtime/parsec/jdf/ForwardSHTReshape.jdf | 236 ++++++++++ src/runtime/parsec/jdf/GetMatrixNorm.jdf | 139 ++++++ src/runtime/parsec/jdf/InverseSHT.jdf | 162 +++++++ src/runtime/parsec/jdf/MatrixCompress.jdf | 409 ++++++++++++++++++ src/runtime/parsec/jdf/MeanSquaredError.jdf | 96 ++++ src/runtime/parsec/jdf/ReadCSV.jdf | 123 ++++++ src/runtime/parsec/jdf/ReadCSVComplex.jdf | 133 ++++++ src/runtime/parsec/jdf/ReadCSVTimeSlot.jdf | 123 ++++++ src/runtime/parsec/jdf/ReadCSVToComplex.jdf | 130 ++++++ .../parsec/jdf/ReadCSVToComplexTimeSlot.jdf | 154 +++++++ .../configurations/TestConfigurations.cpp | 7 +- 76 files changed, 4465 insertions(+), 811 deletions(-) create mode 100644 inst/include/data-loader/concrete/ParsecLoader.hpp create mode 100644 inst/include/data-units/descriptor/concrete/ParsecDescriptor.hpp delete mode 100644 inst/include/linear-algebra-solvers/concrete/parsec/ParsecImplementation.hpp create mode 100644 inst/include/runtime-solver/RuntimeSolverFactory.hpp create mode 100644 inst/include/runtime-solver/RuntimeSolverMethods.hpp create mode 100644 inst/include/runtime-solver/concrete/ParsecRuntimeSolver.hpp create mode 100644 inst/include/runtime-solver/concrete/StarpuRuntimeSolver.hpp create mode 100644 inst/include/runtime/parsec/JDFHelperFunctions.h rename inst/include/runtime/parsec/{ParsecHeader.hpp => ParsecHeader.h} (100%) create mode 100644 inst/include/runtime/parsec/jdf/JobDescriptionFormat.h create mode 100644 src/data-loader/concrete/ParsecLoader.cpp create mode 100644 src/data-units/descriptor/concrete/ParsecDescriptor.cpp delete mode 100644 src/linear-algebra-solvers/concrete/parsec/ParsecImplementation.cpp create mode 100644 src/runtime-solver/CMakeLists.txt create mode 100644 src/runtime-solver/RuntimeSolverFactory.cpp create mode 100644 src/runtime-solver/concrete/CMakeLists.txt create mode 100644 src/runtime-solver/concrete/ParsecRuntimeSolver.cpp create mode 100644 src/runtime-solver/concrete/StarpuRuntimeSolver.cpp create mode 100644 src/runtime/parsec/JDFHelperFunctions.c create mode 100644 src/runtime/parsec/jdf/CMakeLists.txt create mode 100644 src/runtime/parsec/jdf/DifferenceDouble.jdf create mode 100644 src/runtime/parsec/jdf/ForwardSHT.jdf create mode 100644 src/runtime/parsec/jdf/ForwardSHTReshape.jdf create mode 100644 src/runtime/parsec/jdf/GetMatrixNorm.jdf create mode 100644 src/runtime/parsec/jdf/InverseSHT.jdf create mode 100644 src/runtime/parsec/jdf/MatrixCompress.jdf create mode 100644 src/runtime/parsec/jdf/MeanSquaredError.jdf create mode 100644 src/runtime/parsec/jdf/ReadCSV.jdf create mode 100644 src/runtime/parsec/jdf/ReadCSVComplex.jdf create mode 100644 src/runtime/parsec/jdf/ReadCSVTimeSlot.jdf create mode 100644 src/runtime/parsec/jdf/ReadCSVToComplex.jdf create mode 100644 src/runtime/parsec/jdf/ReadCSVToComplexTimeSlot.jdf diff --git a/CMakeLists.txt b/CMakeLists.txt index accf04e3..d08c78c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,7 +156,6 @@ else() message(FATAL_ERROR "Unknown RUNTIME_TYPE: ${RUNTIME_TYPE}. Supported values are 'STARPU' or 'PARSEC'.") endif() - # ExaGeoStatCPP depends on LAPACK/BLASPP # ------------------------------- include(ImportBLASPP) diff --git a/cmake/FindHICMA-X.cmake b/cmake/FindHICMA-X.cmake index a0d3ff3c..bb2a045e 100644 --- a/cmake/FindHICMA-X.cmake +++ b/cmake/FindHICMA-X.cmake @@ -30,6 +30,7 @@ if(PKG_CONFIG_FOUND) endif() # TODO: This is not generalized for the case of hicma installed manually set(HICMA_X_SRC_DIR ${HICMA_X_ROOT}/hicma-x-src) + set(HICMA_X_BIN_DIR ${HICMA_X_ROOT}/bin) set(HICMA-X_FOUND TRUE) set(HICMA-X_LIBRARIES ${DPLASMA_PKG_LIBRARIES} ${PARSEC_PKG_LIBRARIES}) set(HICMA-X_LIBRARY_DIRS "${HICMA_X_LIB_PATH}") diff --git a/cmake/ImportHiCMAX.cmake b/cmake/ImportHiCMAX.cmake index 06493016..6bdc2a79 100644 --- a/cmake/ImportHiCMAX.cmake +++ b/cmake/ImportHiCMAX.cmake @@ -16,7 +16,9 @@ set(name "HICMA-X") set(tag "FIX-package-installation-MK") # Flags to configure the build for HiCMA-X, including precision settings for DPLASMA # and disabling GPU support for both CUDA and HIP. -set(flags '-DDPLASMA_PRECISIONS="s;d"' \-DPARSEC_WITH_DEVEL_HEADERS=ON \-DCMAKE_Fortran_FLAGS="-Wno-main" \-DPARSEC_GPU_WITH_HIP=OFF \-DPARSEC_GPU_WITH_CUDA=OFF \-DPARSEC_HAVE_CUDA=OFF \-DPARSEC_DIST_SHORT_LIMIT=0 \-DPARSEC_DIST_COLLECTIVES=ON \-DPARSEC_HAVE_DEV_CUDA_SUPPORT=OFF \-DDPLASMA_HAVE_CUDA=OFF) +set(flags '-DDPLASMA_PRECISIONS="s;d"' \-DPARSEC_WITH_DEVEL_HEADERS=ON \-DCMAKE_Fortran_FLAGS="-Wno-main" + \-DPARSEC_GPU_WITH_HIP=OFF \-DPARSEC_GPU_WITH_CUDA=OFF \-DPARSEC_HAVE_CUDA=OFF \-DPARSEC_DIST_SHORT_LIMIT=0 + \-DPARSEC_DIST_COLLECTIVES=ON \-DPARSEC_HAVE_DEV_CUDA_SUPPORT=OFF \-DDPLASMA_HAVE_CUDA=OFF \-DBLA_VENDOR=${BLA_VENDOR}) # Indicates that HiCMA-X uses CMake for its build system. set(is_cmake ON) # Indicates that HiCMA-X is hosted on a Git repository. diff --git a/cmake/ImportStarsH.cmake b/cmake/ImportStarsH.cmake index 10ec8347..da715722 100644 --- a/cmake/ImportStarsH.cmake +++ b/cmake/ImportStarsH.cmake @@ -31,7 +31,7 @@ elseif(RUNTIME_TYPE STREQUAL "PARSEC") endif() # 'flag' is used for additional build configuration options, specifically disabling StarPU and optionally enabling MPI. -set(flag \-DSTARPU=OFF \-DMPI=${USE_MPI}) +set(flag \-DSTARPU=OFF \-DMPI=${USE_MPI} \-DBLA_VENDOR=${BLA_VENDOR}) # 'is_cmake' indicates that STARSH uses CMake as its build system, set to ON. set(is_cmake ON) # 'is_git' denotes that the source code for STARSH is hosted on a Git repository, set to ON. diff --git a/examples/climate-emulator/ClimateEmulator.cpp b/examples/climate-emulator/ClimateEmulator.cpp index 44f5424f..2ff03177 100644 --- a/examples/climate-emulator/ClimateEmulator.cpp +++ b/examples/climate-emulator/ClimateEmulator.cpp @@ -27,17 +27,12 @@ int main(int argc, char **argv) { configurations.InitializeArguments(argc, argv); // Initialize the ExaGeoStat Hardware auto hardware = ExaGeoStatHardware(configurations); - -// // Create a unique pointer to hold the data. -// std::unique_ptr> data; -// // Transform and prepare the data. -// ExaGeoStat::ExaGeoStatTransformData(configurations, data); -// // Load the data, either by reading from a file or generating synthetic data. -// ExaGeoStat::ExaGeoStatLoadData(configurations, data); -// // Perform data modeling. -// ExaGeoStat::ExaGeoStatDataModeling(configurations, data); -// // Analyze the data. -// ExaGeoStat::ExaGeoStatDataAnalyzer(configurations, data); + // Create a unique pointer to hold the data. + std::unique_ptr> data; + // Load the data, either by reading from a file or generating synthetic data. + ExaGeoStat::ExaGeoStatLoadData(configurations, data); + // Perform data modeling. + ExaGeoStat::ExaGeoStatDataModeling(configurations, data); return 0; } diff --git a/inst/include/api/ExaGeoStat.hpp b/inst/include/api/ExaGeoStat.hpp index 0430cac2..b399b460 100644 --- a/inst/include/api/ExaGeoStat.hpp +++ b/inst/include/api/ExaGeoStat.hpp @@ -14,8 +14,6 @@ #ifndef EXAGEOSTATCPP_EXAGEOSTAT_HPP #define EXAGEOSTATCPP_EXAGEOSTAT_HPP -#include - #include #include @@ -51,17 +49,6 @@ namespace exageostat::api { std::unique_ptr> &aData, T *apMeasurementsMatrix = nullptr); - - /** - * @brief Objective function used in optimization, and following the NLOPT objective function format. - * @param[in] aTheta An array of length n containing the current point in the parameter space. - * @param[in] aGrad An array of length n where you can optionally return the gradient of the objective function. - * @param[in] apInfo pointer containing needed configurations and data. - * @return double MLE results. - * - */ - static double ModelingAPI(const std::vector &aTheta, std::vector &aGrad, void *apInfo); - /** * @brief Predict missing measurements values. * @param[in] aConfigurations Reference to Configurations object containing user input data. @@ -76,26 +63,6 @@ namespace exageostat::api { ExaGeoStatPrediction(configurations::Configurations &aConfigurations, std::unique_ptr> &aData, T *apMeasurementsMatrix = nullptr, dataunits::Locations *apTrainLocations = nullptr, dataunits::Locations *apTestLocations = nullptr); - /** - * @brief Transform data into the required format for ExaGeoStat operations. - * @param[in] aConfigurations Reference to Configurations object containing user input data. - * @param[in, out] aData Reference to an ExaGeoStatData object containing the descriptors and locations to be transformed. - * @return void - * - */ - static void - ExaGeoStatTransformData(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); - - /** - * @brief Analyze the data to extract insights and patterns. - * @param[in] aConfigurations Reference to Configurations object containing user input data. - * @param[in, out] aData Reference to an ExaGeoStatData object that contains the data to be analyzed. - * @return void - * - */ - static void - ExaGeoStatDataAnalyzer(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); - }; /** diff --git a/inst/include/common/Definitions.hpp b/inst/include/common/Definitions.hpp index 400e26df..65707b02 100644 --- a/inst/include/common/Definitions.hpp +++ b/inst/include/common/Definitions.hpp @@ -131,7 +131,8 @@ namespace exageostat::common { */ enum DescriptorType { CHAMELEON_DESCRIPTOR = 0, - HICMA_DESCRIPTOR = 1 + HICMA_DESCRIPTOR = 1, + PARSEC_DESCRIPTOR = 2 }; /** @@ -141,7 +142,8 @@ namespace exageostat::common { */ enum DataSourceType { SYNTHETIC = 0, - CSV_FILE = 1 + CSV_FILE = 1, + PARSEC_FILE = 2 }; /** @@ -205,6 +207,21 @@ namespace exageostat::common { DESCRIPTOR_SUM = 52, DESCRIPTOR_R = 53, DESCRIPTOR_R_COPY = 54, + DESCRIPTOR_F_DATA = 55, + DESCRIPTOR_ET1 = 56, + DESCRIPTOR_ET2 = 57, + DESCRIPTOR_EP = 58, + DESCRIPTOR_SLMN = 59, + DESCRIPTOR_IE = 60, + DESCRIPTOR_IO = 61, + DESCRIPTOR_P = 62, + DESCRIPTOR_D = 63, + DESCRIPTOR_FLMERA = 64, + DESCRIPTOR_ZLM = 65, + DESCRIPTOR_SC = 66, + DESCRIPTOR_F_SPATIAL = 67, + DESCRIPTOR_FLM = 68, + DESCRIPTOR_FLMT = 69 }; /** diff --git a/inst/include/data-analyzer/DataAnalyzer.hpp b/inst/include/data-analyzer/DataAnalyzer.hpp index 72cadf02..f9f50379 100644 --- a/inst/include/data-analyzer/DataAnalyzer.hpp +++ b/inst/include/data-analyzer/DataAnalyzer.hpp @@ -27,35 +27,39 @@ namespace exageostat::analyzer{ class DataAnalyzer { public: - /** - * @brief Default constructor. - */ - DataAnalyzer(); /** - * @brief Default destructor. + * @brief Analyzes the given matrix data pre computation. + * @param[in, out] aData Reference to an ExaGeoStatData object that contains matrix to be analyzed. + * @return void + * */ - ~DataAnalyzer(); + static void PreAnalyzeMatrix(std::unique_ptr> &aData); /** - * @brief Analyzes the given matrix data. - * @param[in] aConfigurations Reference to Configurations object containing needed parameters. + * @brief Analyzes the given matrix data post computation. * @param[in, out] aData Reference to an ExaGeoStatData object that contains matrix to be analyzed. * @return void * */ - static void AnalyzeMatrix(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); + static void PostAnalyzeMatrix(std::unique_ptr> &aData); /** - * @brief Compares betweent two matrices by getting the difference. - * @param[in] aConfigurations Reference to Configurations object containing needed parameters. + * @brief Compares between two matrices by getting the difference. * @param[in, out] aData Reference to an ExaGeoStatData object that contains matrix to be analyzed. * @return the calculated MSE. * */ - static double CompareMatDifference(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); + static double CompareMatDifference(std::unique_ptr> &aData); }; + /** + * @brief Instantiates the ExaGeoStat class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(DataAnalyzer) + }//namespace exageostat #endif // EXAGEOSTATCPP_DATAANALYZER_HPP \ No newline at end of file diff --git a/inst/include/data-generators/DataGenerator.hpp b/inst/include/data-generators/DataGenerator.hpp index 2e5d4344..9f27e933 100644 --- a/inst/include/data-generators/DataGenerator.hpp +++ b/inst/include/data-generators/DataGenerator.hpp @@ -61,8 +61,8 @@ namespace exageostat::generators { protected: - /// Used enum for data generators types. - static common::DataSourceType aDataSourceType; + /// Used flag to determine if data generated is synthetic. + static bool aIsSynthetic; }; /** diff --git a/inst/include/data-loader/DataLoader.hpp b/inst/include/data-loader/DataLoader.hpp index 5f530bd6..931cdec0 100644 --- a/inst/include/data-loader/DataLoader.hpp +++ b/inst/include/data-loader/DataLoader.hpp @@ -67,6 +67,35 @@ namespace exageostat::dataLoader { virtual void WriteData(const T &aMatrixPointer, const int &aProblemSize, const int &aP, std::string &aLoggerPath, exageostat::dataunits::Locations &aLocations) = 0; + + /** + * @brief Abstract method for loading data based on provided configurations and kernel. + * @param[in] aConfigurations Reference to the configurations object that contains parameters for loading data. + * @param[in] aKernel Reference to the kernel object that defines the operations to be applied while loading the data. + * @return A unique pointer to the loaded ExaGeoStatData object. + * + */ + virtual std::unique_ptr> + LoadData(configurations::Configurations &aConfigurations, exageostat::kernels::Kernel &aKernel) = 0; + + /** + * @brief Factory method for creating a DataLoader instance based on the given configurations. + * This method dynamically determines the type of data loader to instantiate based on compile-time conditions. + * @param[in] aConfigurations Reference to the configurations object that contains parameters for loading data. + * @return A unique pointer to a DataLoader instance configured as per the specified runtime conditions. + * + */ + static std::unique_ptr> + CreateDataLoader(exageostat::configurations::Configurations &apConfigurations); + + /** + * @brief Releases the singleton instance of the currently active DataLoader. + * This method ensures proper deallocation of the singleton instance of the data loader, + * depending on the selected runtime. + * + */ + static void ReleaseDataLoader(); + }; /** diff --git a/inst/include/data-loader/concrete/CSVLoader.hpp b/inst/include/data-loader/concrete/CSVLoader.hpp index 52b185bd..153d8922 100644 --- a/inst/include/data-loader/concrete/CSVLoader.hpp +++ b/inst/include/data-loader/concrete/CSVLoader.hpp @@ -5,7 +5,7 @@ /** * @file CSVLoader.hpp - * @brief A class for generating synthetic data. + * @brief A class for loading csv format data. * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah @@ -54,6 +54,14 @@ namespace exageostat::dataLoader::csv { exageostat::dataunits::Locations &aLocations) override; /** + * @brief Loads data based on given configuration. + * @copydoc DataLoader::LoadData() + * + */ + std::unique_ptr> + LoadData(configurations::Configurations &aConfigurations, exageostat::kernels::Kernel &aKernel) override; + + /** * @brief Release the singleton instance of the CSVLoader class. * @return void * diff --git a/inst/include/data-loader/concrete/ParsecLoader.hpp b/inst/include/data-loader/concrete/ParsecLoader.hpp new file mode 100644 index 00000000..6d0a1b70 --- /dev/null +++ b/inst/include/data-loader/concrete/ParsecLoader.hpp @@ -0,0 +1,121 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ParsecLoader.hpp + * @brief A class for loading PaRSEC format data. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-04 +**/ + +#ifndef EXAGEOSTAT_CPP_PARSECDATALOADER_HPP +#define EXAGEOSTAT_CPP_PARSECDATALOADER_HPP + +#include + +namespace exageostat::dataLoader::parsec { + + /** + * @class ParsecLoader + * @brief A class for creating data by reading PaRSEC files. + * @tparam T Data Type: float or double + */ + template + class ParsecLoader : public DataLoader { + public: + + /** + * @brief Get a pointer to the singleton instance of the ParsecLoader class. + * @return A pointer to the instance of the ParsecLoader class. + * + */ + static ParsecLoader *GetInstance(); + + /** + * @brief Reads data from external sources into ExaGeoStat format. + * @copydoc DataLoader::ReadData() + * + */ + void ReadData(configurations::Configurations &aConfigurations, std::vector &aMeasurementsMatrix, + std::vector &aXLocations, std::vector &aYLocations, std::vector &aZLocations, + const int &aP) override; + + /** + * @brief Writes a matrix of vectors to disk. + * @copydoc DataLoader::WriteData() + * + */ + void + WriteData(const T &aMatrixPointer, const int &aProblemSize, const int &aP, std::string &aLoggerPath, + exageostat::dataunits::Locations &aLocations) override; + + /** + * @brief Creates the data by synthetically generating it. + * @copydoc DataGenerator::LoadData() + * + */ + std::unique_ptr> + LoadData(configurations::Configurations &aConfigurations, kernels::Kernel &aKernel) override; + + /** + * @brief Release the singleton instance of the ParsecLoader class. + * @return void + * + */ + static void ReleaseInstance(); + + /** + * @brief Reads data from a CSV file into a matrix. + * @param[in] apFilename Name of the CSV file. + * @param[out] apFileContent Pointer to an array where file contents will be stored. + * @param[in] aM Number of rows in the matrix. + * @param[in] aN Number of columns in the matrix. + * @return 0 on success, or a non-zero error code on failure. + * + */ + int ReadCSVFileHelper(const char* apFilename, double *apFileContent, int aM, int aN); + + /** + * @brief Adapter for the matrix compress operation + * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. + * @return void. + * + */ + void CompressMatrixHelper(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); + + + private: + /** + * @brief Constructor for the ParsecLoader class. + * @return void + * + */ + ParsecLoader() = default; + + /** + * @brief Default destructor. + * + */ + ~ParsecLoader() override = default; + + /** + * @brief Pointer to the singleton instance of the ParsecLoader class. + * + */ + static ParsecLoader *mpInstance; + + }; + + /** + * @brief Instantiates the PaRSEC Data Generator class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(ParsecLoader) +} +#endif //EXAGEOSTAT_CPP_PARSECDATALOADER_HPP \ No newline at end of file diff --git a/inst/include/data-transformer/DataTransformer.hpp b/inst/include/data-transformer/DataTransformer.hpp index a63e3c01..9cf640cc 100644 --- a/inst/include/data-transformer/DataTransformer.hpp +++ b/inst/include/data-transformer/DataTransformer.hpp @@ -18,7 +18,7 @@ #include #include -namespace exageostat::transformer{ +namespace exageostat::transformers{ /** * @brief Class represents the data transformer for the Climate Emulator. @@ -27,12 +27,13 @@ namespace exageostat::transformer{ template class DataTransformer { + public: /** * @brief Performs the forward spherical harmonics transform (SHT). - * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in] aLSize The size of tile size * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. */ - static void ForwardSHT(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); + static void ForwardSphericalHarmonicsTransform(const int &aLSize, std::unique_ptr> &aData); /** * @brief Reshapes data during the forward phase of the simulation. @@ -43,10 +44,17 @@ namespace exageostat::transformer{ /** * @brief Performs the inverse spherical harmonics transform (SHT). - * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in] aLSize The size of tile size * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. */ - static void InverseSHT(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); + static void InverseSphericalHarmonicsTransform(const int &aLSize, std::unique_ptr> &aData); }; -} + + /** + * @brief Instantiates the DataTransformers class for float and double types. + * @tparam T Data Type: float or double + */ + EXAGEOSTAT_INSTANTIATE_CLASS(DataTransformer) +} // namespace exageostat + #endif // EXAGEOSTATCPP_DATATRANSFORMER_HPP diff --git a/inst/include/data-units/DescriptorData.hpp b/inst/include/data-units/DescriptorData.hpp index f5775187..fe771445 100644 --- a/inst/include/data-units/DescriptorData.hpp +++ b/inst/include/data-units/DescriptorData.hpp @@ -19,9 +19,6 @@ #include #include -#if DEFAULT_RUNTIME -#include -#endif namespace exageostat::dataunits { @@ -33,9 +30,11 @@ namespace exageostat::dataunits { union BaseDescriptor { #if DEFAULT_RUNTIME CHAM_desc_t *chameleon_desc; -#ifdef USE_HICMA + #ifdef USE_HICMA HICMA_desc_t *hicma_desc; -#endif + #endif +#else + parsec_matrix_block_cyclic_t *parsec_desc; #endif }; @@ -141,10 +140,11 @@ namespace exageostat::dataunits { * */ void SetDescriptor(const common::DescriptorType &aDescriptorType, const common::DescriptorName &aDescriptorName, - const bool &aIsOOC, void *apMatrix, const common::FloatPoint &aFloatPoint, const int &aMB, - const int &aNB, const int &aSize, const int &aLM, const int &aLN, const int &aI, - const int &aJ, const int &aM, const int &aN, const int &aP, const int &aQ, - const bool &aValidOOC = true, const bool &aConverted = false); + const bool &aIsOOC = false, void *apMatrix = nullptr, + const common::FloatPoint &aFloatPoint = common::EXAGEOSTAT_REAL_DOUBLE, const int &aMB = 0, + const int &aNB = 0, const int &aSize = 0, const int &aLM = 0, const int &aLN = 0, + const int &aI = 0, const int &aJ = 0, const int &aM = 0, const int &aN = 0, + const int &aP = 0, const int &aQ = 0, const bool &aValidOOC = true, const bool &aConverted = false); /** * @brief Getter for the Descriptor matrix. diff --git a/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp b/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp index d8a734fa..c10bb8a8 100644 --- a/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp +++ b/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp @@ -16,9 +16,14 @@ #define EXAGEOSTATCPP_EXAGEOSTATDESCRIPTOR_HPP #if DEFAULT_RUNTIME + #include -#endif #include + +#else +#include +#endif + #include /** diff --git a/inst/include/data-units/descriptor/concrete/ParsecDescriptor.hpp b/inst/include/data-units/descriptor/concrete/ParsecDescriptor.hpp new file mode 100644 index 00000000..074a4744 --- /dev/null +++ b/inst/include/data-units/descriptor/concrete/ParsecDescriptor.hpp @@ -0,0 +1,58 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ParsecDescriptor.hpp + * @brief Defines the ParsecDescriptor class for creating matrix descriptors using the PaRSEC library. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-10-18 +**/ + +#ifndef EXAGEOSTATCPP_ParsecDESCRIPTOR_HPP +#define EXAGEOSTATCPP_ParsecDESCRIPTOR_HPP + +#include +#include + +namespace exageostat::dataunits::descriptor { + + /** + * @brief ParsecDescriptor is a class for creating matrix descriptors by Parsec library. + * @tparam T Data Type: float or double + * + */ + template + class ParsecDescriptor { + + public: + /** + * @brief Create a Parsec descriptor for a matrix with the given parameters. + * @param[in] apDescriptor A pointer to the existing parsec_matrix_block_cyclic_t descriptor. The new descriptor will be created based on this descriptor. + * @return A pointer to the newly created parsec_matrix_block_cyclic_t descriptor. + * + */ + static parsec_matrix_block_cyclic_t *CreateParsecDescriptor(void *apDescriptor); + + /** + * @brief destroys and finalize a descriptor + * @param[in] apDescriptor A pointer to the existing parsec_matrix_block_cyclic_t descriptor. + * @return An error code or success code. + * + */ + static int DestroyParsecDescriptor(void *apDescriptor); + }; + + /** + * @brief Instantiates the Parsec descriptor methods class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(ParsecDescriptor) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_ParsecDESCRIPTOR_HPP diff --git a/inst/include/hardware/ExaGeoStatHardware.hpp b/inst/include/hardware/ExaGeoStatHardware.hpp index 5d1ed2ea..8eb69570 100644 --- a/inst/include/hardware/ExaGeoStatHardware.hpp +++ b/inst/include/hardware/ExaGeoStatHardware.hpp @@ -18,6 +18,10 @@ #include #include +#if !DEFAULT_RUNTIME +#include +#endif + /** * @brief Class represents the hardware configuration for the ExaGeoStat solver. * @@ -113,6 +117,21 @@ class ExaGeoStatHardware { */ [[nodiscard]] static void *GetContext(exageostat::common::Computation aComputation); + /** + * @brief Sets the rank of MPI for PaRSEC. + * @param[in] aRank The new value for the rank. + * @return void + * + **/ + static void SetParsecMPIRank(int aRank); + + /** + * @brief Retrieves the rank of MPI for PaRSEC. + * @return The current rank of MPI PaRSEC. + * + **/ + static int GetParsecMPIRank(); + /** * @brief Retrieves the P dimension of the grid. * @details This function returns the current setting of the P dimension of the grid, which is part of the grid configuration used in various computational processes. @@ -147,6 +166,40 @@ class ExaGeoStatHardware { **/ static void SetQGrid(int aQ); +#if !DEFAULT_RUNTIME + /** + * @brief Retrieves the HiCMA parameters. + * @details This function returns a pointer to the current HiCMA parameters used in the computational process. + * @return A pointer to the current HiCMA parameters of type `hicma_parsec_params_t`. + * + */ + static hicma_parsec_params_t* GetHicmaParams(); + + /** + * @brief Retrieves the STARSH parameters. + * @details This function returns a pointer to the current STARSH parameters used in the computational process. + * @return A pointer to the current STARSH parameters of type `starsh_params_t`. + * + */ + static starsh_params_t* GetParamsKernel(); + + /** + * @brief Retrieves the HiCMA data. + * @details This function returns a pointer to the current HiCMA data used in the computational process. + * @return A pointer to the current HiCMA data of type `hicma_parsec_data_t`. + * + */ + static hicma_parsec_data_t* GetHicmaData(); + + /** + * @brief Retrieves the HiCMA matrix analysis. + * @details This function returns a pointer to the current HiCMA matrix analysis data used in the computational process. + * @return A pointer to the current HiCMA matrix analysis of type `hicma_parsec_matrix_analysis_t`. + * + */ + static hicma_parsec_matrix_analysis_t* GetAnalysis(); +#endif + private: //// Used Pointer to the Chameleon hardware context. static void *mpChameleonContext; @@ -155,11 +208,23 @@ class ExaGeoStatHardware { //// Used Pointer to the PaRSEC hardware context. static void *mpParsecContext; //// Used P-Grid + static int mParsecMPIRank; + //// Used P-Grid static int mPGrid; //// Used Q-Grid static int mQGrid; //// Used boolean to avoid re-init mpi static bool mIsMPIInit; +#if !DEFAULT_RUNTIME + //// HiCMA-specific variables - Himca_parsec_params + static std::unique_ptr mpHicmaParams; + //// HiCMA-specific variables - starsh_params_t + static std::unique_ptr mpParamsKernel; + //// HiCMA-specific variables - hicma_parsec_data_t + static std::unique_ptr mpHicmaData; + //// HiCMA-specific variables - hicma_parsec_matrix_analysis_t + static std::unique_ptr mpAnalysis; +#endif }; #endif // EXAGEOSTATCPP_EXAGEOSTATHARDWARE_HPP \ No newline at end of file diff --git a/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp b/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp index 2b35a6c9..251d6319 100644 --- a/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp +++ b/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp @@ -49,9 +49,6 @@ namespace exageostat::linearAlgebra { */ virtual ~LinearAlgebraMethods() = default; - // TODO: Since the common linear algebra fn between HiCMA andChameleon won't work with PaRSEC, - // consider move them and make this file as an Interface for virtual fns -#if DEFAULT_RUNTIME /** * @brief Initializes the descriptors necessary for the linear algebra solver. * @details This method initializes the descriptors necessary for the linear algebra solver. @@ -130,6 +127,84 @@ namespace exageostat::linearAlgebra { dataunits::Locations *apLocation3, const int &aDistanceMetric, const kernels::Kernel &aKernel); + /** + * @brief Calculates the log likelihood value of a given value theta. + * @param[in,out] aData DescriptorData object to be populated with descriptors and data. + * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in] apTheta Optimization parameter used by NLOPT. + * @param[in] apMeasurementsMatrix measurements matrix to be stored in DescZ. + * @param[in] aKernel Reference to the kernel object to use. + * @return log likelihood value + * + */ + virtual T ExaGeoStatMLETile(std::unique_ptr> &aData, + configurations::Configurations &aConfigurations, const double *apTheta, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) = 0; + + + /** + * @brief Copies a matrix in the tile layout from source to destination + * @param[in] aUpperLower Specifies the part of the matrix A to be copied to B. + * @param[in] apA Source matrix A. + * @param[in,out] apB Destination matrix B. On exit, B = A in the locations specified by Upper Lower. + * @return void + * + */ + virtual void ExaGeoStatLapackCopyTile(const common::UpperLower &aUpperLower, void *apA, void *apB) = 0; + + /** + * @brief Wait for the completion of a sequence. + * @param[in] apSequence apSequence A pointer to either CHAMELEON or HiCMA sequence. + * @return void + * + */ + virtual void ExaGeoStatSequenceWait(void *apSequence) = 0; + + /** + * @brief Create Sequence. + * @param[out] apSequence A pointer to either CHAMELEON or HiCMA sequence. + * @return void + * + */ + virtual void + ExaGeoStatCreateSequence(void *apSequence) = 0; + + /** + * @brief Computes the Cholesky factorization of a symmetric positive definite or Symmetric positive definite matrix. + * @param[in] aUpperLower Whether upper or lower part of the matrix A. + * @param[in, out] apA Symmetric matrix A. + * @param[in] aBand Diagonal thickness parameter. + * @param[in] apCD Additional matrix CD. + * @param[in] apCrk Additional matrix Crk. + * @param[in] aMaxRank Maximum rank parameter. + * @param[in] aAcc Accuracy parameter. + * @return void + * + */ + virtual void + ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, void *apCD, void *apCrk, + const int &aMaxRank, const int &aAcc) = 0; + + /** + * @brief Solves one of the matrix equations op( A )*X = alpha*B, or X*op( A ) = alpha*B. + * @param[in] aSide Specifies whether op(A) appears on the left or on the right of X. + * @param[in] aUpperLower Specifies whether the matrix A is upper triangular or lower triangular. + * @param[in] aTrans Specifies the form of op( A ) to be used in the matrix multiplication. + * @param[in] aDiag Specifies whether or not A is unit triangular. + * @param[in] aAlpha Specifies the scalar alpha. When alpha is zero, A is not referenced and B need not be set before entry. + * @param[in] apA The triangular matrix A. + * @param[in] apCD Additional matrix CD. + * @param[in] apCrk Additional matrix Crk. + * @param[in, out] apZ The matrix B of dimension, on exit is overwritten by the solution matrix X. + * @param[in] aMaxRank Maximum rank parameter. + * @return void + * + */ + virtual void ExaGeoStatTrsmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, + const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, + void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) = 0; + + /** * @brief Solve a positive definite linear system of equations AX = B using tiled algorithms. * @param[in] aUpperLower Specifies whether the matrix A is upper triangular or lower triangular. @@ -210,6 +285,22 @@ namespace exageostat::linearAlgebra { */ void ExaGeoStatDesc2Lap(T *apA, const int &aLDA, void *apDescA, const common::UpperLower &aUpperLower); +#ifdef USE_HICMA + + /** + * @brief Copy Descriptor Matrix to another Descriptor matrix. + * @param[out] apSourceDesc Descriptor matrix to be copied + * @param[out] apDestinationDesc Descriptor matrix to be copied to. + * @param[in] aSize Size of matrix to be copied. + * @param[in] aDirection Specifies the type of Descriptors to be copied. + * @return void + * + */ + void CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, + const common::CopyDirection &aDirection); + +#endif + /** * @brief Sets the values of all or part of a two-dimensional Tile. * @param[in] aUpperLower Specifies Specifies whether the upper or lower triangular part of the covariance matrix is stored. @@ -308,129 +399,6 @@ namespace exageostat::linearAlgebra { * */ bool Recover(char *apPath, const int &aIterationCount, T *apTheta, T *apLogLik, const int &aNumParams); -#endif - - /** - * @brief Copy Descriptor Matrix to another Descriptor matrix. - * @param[out] apSourceDesc Descriptor matrix to be copied - * @param[out] apDestinationDesc Descriptor matrix to be copied to. - * @param[in] aSize Size of matrix to be copied. - * @param[in] aDirection Specifies the type of Descriptors to be copied. - * @return void - * - */ - virtual void CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, - const common::CopyDirection &aDirection) = 0; - - /** - * @brief The Gateway for the Modeling Operation - * @param[in,out] aData DescriptorData object to be populated with descriptors and data. - * @param[in] aConfigurations Configurations object containing relevant settings. - * @param[in] apTheta Optimization parameter used by NLOPT. - * @param[in] apMeasurementsMatrix measurements matrix to be stored in DescZ. - * @param[in] aKernel Reference to the kernel object to use. - * @return log likelihood value - * - */ - virtual T ModelingOperations(std::unique_ptr> &aData, - configurations::Configurations &aConfigurations, const double *apTheta, - T *apMeasurementsMatrix, const kernels::Kernel &aKernel) = 0; - - /** - * @brief Copies a matrix in the tile layout from source to destination - * @param[in] aUpperLower Specifies the part of the matrix A to be copied to B. - * @param[in] apA Source matrix A. - * @param[in,out] apB Destination matrix B. On exit, B = A in the locations specified by Upper Lower. - * @return void - * - */ - virtual void ExaGeoStatLapackCopyTile(const common::UpperLower &aUpperLower, void *apA, void *apB) = 0; - - /** - * @brief Wait for the completion of a sequence. - * @param[in] apSequence apSequence A pointer to either CHAMELEON or HiCMA sequence. - * @return void - * - */ - virtual void ExaGeoStatSequenceWait(void *apSequence) = 0; - - /** - * @brief Create Sequence. - * @param[out] apSequence A pointer to either CHAMELEON or HiCMA sequence. - * @return void - * - */ - virtual void - ExaGeoStatCreateSequence(void *apSequence) = 0; - - /** - * @brief Computes the Cholesky factorization of a symmetric positive definite or Symmetric positive definite matrix. - * @param[in] aUpperLower Whether upper or lower part of the matrix A. - * @param[in, out] apA Symmetric matrix A. - * @param[in] aBand Diagonal thickness parameter. - * @param[in] apCD Additional matrix CD. - * @param[in] apCrk Additional matrix Crk. - * @param[in] aMaxRank Maximum rank parameter. - * @param[in] aAcc Accuracy parameter. - * @return void - * - */ - virtual void - ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, void *apCD, void *apCrk, - const int &aMaxRank, const int &aAcc) = 0; - - /** - * @brief Solves one of the matrix equations op( A )*X = alpha*B, or X*op( A ) = alpha*B. - * @param[in] aSide Specifies whether op(A) appears on the left or on the right of X. - * @param[in] aUpperLower Specifies whether the matrix A is upper triangular or lower triangular. - * @param[in] aTrans Specifies the form of op( A ) to be used in the matrix multiplication. - * @param[in] aDiag Specifies whether or not A is unit triangular. - * @param[in] aAlpha Specifies the scalar alpha. When alpha is zero, A is not referenced and B need not be set before entry. - * @param[in] apA The triangular matrix A. - * @param[in] apCD Additional matrix CD. - * @param[in] apCrk Additional matrix Crk. - * @param[in, out] apZ The matrix B of dimension, on exit is overwritten by the solution matrix X. - * @param[in] aMaxRank Maximum rank parameter. - * @return void - * - */ - virtual void ExaGeoStatTrsmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, - const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, - void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) = 0; - - /** - * @brief Performs a SYRK (symmetric rank-k update) operation on the matrix. - * @param[in] aConfigurations Configurations object containing relevant settings. - * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. - * - */ - virtual void - ExaGeoStatSYRK(configurations::Configurations &aConfigurations, std::unique_ptr> &aData) = 0; - - /** - * @brief Performs TLR Cholesky operation on the matrix. - * @param[in] aConfigurations Configurations object containing relevant settings. - * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. - * - */ - virtual void ExaGeoStatTLRCholesky(configurations::Configurations &aConfigurations, std::unique_ptr> &aData) = 0; - - /** - * @brief Calculates norm. - * @param[in] aConfigurations Configurations object containing relevant settings. - * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. - * - */ - virtual void ExaGeoStatNorm(configurations::Configurations &aConfigurations, std::unique_ptr> &aData) =0; - - /** - * @brief Calculates the Mean Squared Error (MSE). - * @param[in] aConfigurations Reference to Configurations object containing needed parameters. - * @param[out] aData Reference to an ExaGeoStatData object that contains matrix to be analyzed. - * @return the calculated MSE. - * - */ - virtual double CalculateMSE(configurations::Configurations &aConfigurations, std::unique_ptr> &aData) =0; }; /** diff --git a/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp b/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp index 0b421af8..b42c46c8 100644 --- a/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp +++ b/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp @@ -17,7 +17,6 @@ #define EXAGEOSTATCPP_CHAMELEONIMPLEMENTATION_HPP #include -#include namespace exageostat::linearAlgebra { @@ -32,12 +31,12 @@ namespace exageostat::linearAlgebra { /** * @brief Calculates the log likelihood value of a given value theta. - * @copydoc LinearAlgebraMethods::ModelingOperations() + * @copydoc LinearAlgebraMethods::ExaGeoStatMLETile() * */ - T ModelingOperations(std::unique_ptr > &aData, - configurations::Configurations &aConfigurations, const double *theta, - T *apMeasurementsMatrix, const kernels::Kernel &aKernel) override; + T ExaGeoStatMLETile(std::unique_ptr> &aData, + configurations::Configurations &aConfigurations, const double *theta, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) override; /** * @brief Copies a matrix in the tile layout from source to destination @@ -55,14 +54,6 @@ namespace exageostat::linearAlgebra { const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) override; - /** - * @brief Copy Descriptor Matrix to another Descriptor matrix. - * @copydoc LinearAlgebraMethods::CopyDescriptors() - * - */ - void CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, - const common::CopyDirection &aDirection) override; - /** * @brief Wait for the completion of a sequence. * @copydoc LinearAlgebraMethods::ExaGeoStatSequenceWait() @@ -78,42 +69,13 @@ namespace exageostat::linearAlgebra { */ void ExaGeoStatCreateSequence(void *apSequence) override; - - /** - * @brief Performs a SYRK (symmetric rank-k update) operation on the matrix. - * @copydoc LinearAlgebraMethods::ExaGeoStatSYRK() - * - */ - void ExaGeoStatSYRK(configurations::Configurations &aConfigurations, - std::unique_ptr > &aData) override; - - /** - * @brief Performs TLR Cholesky operation on the matrix. - * @copydoc LinearAlgebraMethods::ExaGeoStatTLRCholesky() - * - */ - void ExaGeoStatTLRCholesky(configurations::Configurations &aConfigurations, - std::unique_ptr > &aData) override; - - /** - * @brief Calculates norm. - * @copydoc LinearAlgebraMethods::ExaGeoStatNorm() - * - */ - void ExaGeoStatNorm(configurations::Configurations &aConfigurations, - std::unique_ptr > &aData) override; - - /** - * @brief Calculates the Mean Squared Error (MSE). - * @copydoc LinearAlgebraMethods::CalculateMSE() - * - */ - double CalculateMSE(configurations::Configurations &aConfigurations, - std::unique_ptr > &aData) override; - - }; + /** + * @brief Instantiates the Chameleon Implementation class for float and double types. + * @tparam T Data Type: float or double + * + */ EXAGEOSTAT_INSTANTIATE_CLASS(ChameleonImplementation) }//namespace exageostat diff --git a/inst/include/linear-algebra-solvers/concrete/hicma/tlr/HicmaImplementation.hpp b/inst/include/linear-algebra-solvers/concrete/hicma/tlr/HicmaImplementation.hpp index b7667205..4c488a3d 100644 --- a/inst/include/linear-algebra-solvers/concrete/hicma/tlr/HicmaImplementation.hpp +++ b/inst/include/linear-algebra-solvers/concrete/hicma/tlr/HicmaImplementation.hpp @@ -50,11 +50,11 @@ namespace exageostat::linearAlgebra::tileLowRank { /** * @brief Calculates the log likelihood value of a given value theta. - * @copydoc LinearAlgebraMethods::ModelingOperations() + * @copydoc LinearAlgebraMethods::ExaGeoStatMLETile() */ - T ModelingOperations(std::unique_ptr > &aData, - configurations::Configurations &aConfigurations, const double *theta, - T *apMeasurementsMatrix, const kernels::Kernel &aKernel) override; + T ExaGeoStatMLETile(std::unique_ptr> &aData, + configurations::Configurations &aConfigurations, const double *theta, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) override; /** * @brief Copies a matrix in the tile layout from source to destination @@ -91,46 +91,6 @@ namespace exageostat::linearAlgebra::tileLowRank { const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) override; - /** - * @brief Copy Descriptor Matrix to another Descriptor matrix. - * @copydoc LinearAlgebraMethods::CopyDescriptors() - * - */ - void CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, - const common::CopyDirection &aDirection) override; - - /** - * @brief Performs a SYRK (symmetric rank-k update) operation on the matrix. - * @copydoc LinearAlgebraMethods::ExaGeoStatSYRK() - * - */ - void ExaGeoStatSYRK(configurations::Configurations &aConfigurations, - std::unique_ptr > &aData) override; - - /** - * @brief Performs TLR Cholesky operation on the matrix. - * @copydoc LinearAlgebraMethods::ExaGeoStatTLRCholesky() - * - */ - void ExaGeoStatTLRCholesky(configurations::Configurations &aConfigurations, - std::unique_ptr > &aData) override; - - /** - * @brief Calculates norm. - * @copydoc LinearAlgebraMethods::ExaGeoStatNorm() - * - */ - void ExaGeoStatNorm(configurations::Configurations &aConfigurations, - std::unique_ptr > &aData) override; - - /** - * @brief Calculates the Mean Squared Error (MSE). - * @copydoc LinearAlgebraMethods::CalculateMSE() - * - */ - double CalculateMSE(configurations::Configurations &aConfigurations, - std::unique_ptr > &aData) override; - }; /** diff --git a/inst/include/linear-algebra-solvers/concrete/parsec/ParsecImplementation.hpp b/inst/include/linear-algebra-solvers/concrete/parsec/ParsecImplementation.hpp deleted file mode 100644 index 6d7df8cd..00000000 --- a/inst/include/linear-algebra-solvers/concrete/parsec/ParsecImplementation.hpp +++ /dev/null @@ -1,122 +0,0 @@ - -// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, -// All rights reserved. -// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). - -/** - * @file ParsecImplementation.hpp - * @brief This file contains the declaration of ParsecImplementation class. - * @details ParsecImplementation is a concrete implementation of the LinearAlgebraMethods class. - * @version 2.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @date 2024-10-15 -**/ - -#ifndef EXAGEOSTATCPP_PARSECIMPLEMENTATION_HPP -#define EXAGEOSTATCPP_PARSECIMPLEMENTATION_HPP - -#include - -namespace exageostat::linearAlgebra { - - /** - * @brief ParsecImplementation is a concrete implementation of LinearAlgebraMethods class. - * @tparam T Data Type: float or double - * - */ - template - class ParsecImplementation : public LinearAlgebraMethods { - - /** - * @brief Performs a SYRK (symmetric rank-k update) operation on the matrix. - * @copydoc LinearAlgebraMethods::ExaGeoStatSYRK() - * - */ - void ExaGeoStatSYRK(configurations::Configurations &aConfigurations, std::unique_ptr> &aData) override; - - /** - * @brief Performs TLR Cholesky operation on the matrix. - * @copydoc LinearAlgebraMethods::ExaGeoStatTLRCholesky() - * - */ - void ExaGeoStatTLRCholesky(configurations::Configurations &aConfigurations, std::unique_ptr> &aData) override; - - /** - * @brief Calculates norm. - * @copydoc LinearAlgebraMethods::ExaGeoStatNorm() - * - */ - void ExaGeoStatNorm(configurations::Configurations &aConfigurations, - std::unique_ptr> &aData) override; - - /** - * @brief Calculates the Mean Squared Error (MSE). - * @copydoc LinearAlgebraMethods::CalculateMSE() - * - */ - double CalculateMSE(configurations::Configurations &aConfigurations, - std::unique_ptr> &aData) override; - - /** - * @brief The Gateway for the Modeling Operation - * @copydoc LinearAlgebraMethods::ModelingOperations() - * - */ - virtual T ModelingOperations(std::unique_ptr> &aData, - configurations::Configurations &aConfigurations, const double *apTheta, - T *apMeasurementsMatrix, const kernels::Kernel &aKernel) = 0; - - /** - * @brief Copies a matrix in the tile layout from source to destination - * @copydoc LinearAlgebraMethods::ExaGeoStatLapackCopyTile() - * - */ - virtual void ExaGeoStatLapackCopyTile(const common::UpperLower &aUpperLower, void *apA, void *apB) = 0; - - /** - * @brief Wait for the completion of a sequence. - * @copydoc LinearAlgebraMethods::ExaGeoStatSequenceWait() - * - */ - virtual void ExaGeoStatSequenceWait(void *apSequence) = 0; - - /** - * @brief Create Sequence. - * @copydoc LinearAlgebraMethods::ExaGeoStatCreateSequence() - * - */ - virtual void - ExaGeoStatCreateSequence(void *apSequence) = 0; - - /** - * @brief Computes the Cholesky factorization of a symmetric positive definite or Symmetric positive definite matrix. - * @copydoc LinearAlgebraMethods::ExaGeoStatPotrfTile() - * - */ - virtual void - ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, void *apCD, void *apCrk, - const int &aMaxRank, const int &aAcc) = 0; - - /** - * @brief Solves one of the matrix equations op( A )*X = alpha*B, or X*op( A ) = alpha*B. - * @copydoc LinearAlgebraMethods::ExaGeoStatTrsmTile() - * - */ - virtual void ExaGeoStatTrsmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, - const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, - void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) = 0; - - /** - * @brief Copy Descriptor Matrix to another Descriptor matrix. - * @copydoc LinearAlgebraMethods::CopyDescriptors() - * - */ - virtual void CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, - const common::CopyDirection &aDirection) = 0; - - }; - EXAGEOSTAT_INSTANTIATE_CLASS(ParsecImplementation) -}//namespace exageostat - -#endif //EXAGEOSTATCPP_PARSECIMPLEMENTATION_HPP \ No newline at end of file diff --git a/inst/include/runtime-solver/RuntimeSolverFactory.hpp b/inst/include/runtime-solver/RuntimeSolverFactory.hpp new file mode 100644 index 00000000..f8034fb8 --- /dev/null +++ b/inst/include/runtime-solver/RuntimeSolverFactory.hpp @@ -0,0 +1,52 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file RuntimeSolverFactory.hpp + * @brief Header file for the RuntimeSolverFactory class, which creates runtime solvers based on the configured runtime. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @date 2024-11-04 +**/ + +#ifndef EXAGEOSTATCPP_RUNTIMESOLVERFACTORY_HPP +#define EXAGEOSTATCPP_RUNTIMESOLVERFACTORY_HPP + +#include + +#include +#include +#include + +namespace exageostat::runtimesolver { + + /** + * @class RuntimeSolverFactory + * @brief A class that creates linear algebra solvers based on the input computation type. + * @tparam T Data Type: float or double. + * + */ + template + class RuntimeSolverFactory { + public: + + /** + * @brief Creates a linear algebra solver based on the input computation type. + * @return Pointer to the created linear algebra solver. + * + */ + static std::unique_ptr> CreateRuntimeSolver(); + }; + + /** + * @brief Instantiates the Runtime Solver Factory class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(RuntimeSolverFactory) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_RUNTIMESOLVERFACTORY_HPP \ No newline at end of file diff --git a/inst/include/runtime-solver/RuntimeSolverMethods.hpp b/inst/include/runtime-solver/RuntimeSolverMethods.hpp new file mode 100644 index 00000000..acd87cf4 --- /dev/null +++ b/inst/include/runtime-solver/RuntimeSolverMethods.hpp @@ -0,0 +1,54 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file RuntimeSolverMethods.hpp + * @brief Header file for the RuntimeSolverMethods class, which defines the interface for runtime solvers. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-11-04 +**/ + +#ifndef EXAGEOSTATCPP_RUNTIMESOLVERMETHODS_HPP +#define EXAGEOSTATCPP_RUNTIMESOLVERMETHODS_HPP + +#include +#include + +namespace exageostat::runtimesolver { + + /** + * @class RuntimeSolverMethods + * @brief A class that defines the interface for linear algebra solvers. + * @tparam T Data Type: float or double. + * + */ + template + class RuntimeSolverMethods { + public: + + /** + * @brief Virtual destructor to allow calls to the correct concrete destructor. + * + */ + virtual ~RuntimeSolverMethods() = default; + + /** + * @brief The Gateway for the Modeling Operation + * @param[in,out] aData DescriptorData object to be populated with descriptors and data. + * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in] apMeasurementsMatrix measurements matrix to be stored in DescZ. + * @param[in] aKernel Reference to the kernel object to use. + * @return log likelihood value + * + */ + virtual T ModelingOperations(std::unique_ptr> &aData, configurations::Configurations &aConfigurations, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) = 0; + + }; +}//namespace exageostat + +#endif //EXAGEOSTATCPP_RUNTIMESOLVERMETHODS_HPP \ No newline at end of file diff --git a/inst/include/runtime-solver/concrete/ParsecRuntimeSolver.hpp b/inst/include/runtime-solver/concrete/ParsecRuntimeSolver.hpp new file mode 100644 index 00000000..0f88bb2a --- /dev/null +++ b/inst/include/runtime-solver/concrete/ParsecRuntimeSolver.hpp @@ -0,0 +1,83 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ParsecRuntimeSolver.hpp + * @brief This file contains the declaration of ParsecRuntimeSolver class. + * @details ParsecRuntimeSolver is a concrete implementation of the RuntimeSolverMethods class. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @author Qinglei Cao + * @date 2024-11-04 +**/ + +#ifndef EXAGEOSTATCPP_PARSECRUNTIMESOLVER_HPP +#define EXAGEOSTATCPP_PARSECRUNTIMESOLVER_HPP + +#include + +namespace exageostat::runtimesolver { + + /** + * @brief ParsecRuntimeSolver is a concrete implementation of RuntimeSolverMethods class for dense or diagonal-super tile matrices. + * @tparam T Data Type: float or double + * + */ + template + class ParsecRuntimeSolver : public RuntimeSolverMethods { + public: + + /** + * @brief Calculates the log likelihood value of a given value theta. + * @copydoc RuntimeSolverMethods::ModelingOperations() + * + */ + T ModelingOperations(std::unique_ptr > &aData, configurations::Configurations &aConfigurations, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) override; + + /** + * @brief Performs a SYRK (symmetric rank-k update) operation on the matrix. + * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. + * + */ + void ExaGeoStatSYRK(std::unique_ptr> &aData); + + /** + * @brief Performs TLR Cholesky operation on the matrix. + * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. + * + */ + void ExaGeoStatTLRCholesky(std::unique_ptr> &aData); + + /** + * @brief Calculates norm. + * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. + * + */ + double ExaGeoStatNorm(configurations::Configurations &aConfigurations, std::unique_ptr> &aData); + + /** + * @brief Calculates the Mean Squared Error (MSE). + * @param[in] aConfigurations Reference to Configurations object containing needed parameters. + * @param[out] aData Reference to an ExaGeoStatData object that contains matrix to be analyzed. + * @return the calculated MSE. + * + */ + double CalculateMSE(configurations::Configurations &aConfigurations, + std::unique_ptr> &aData); + + }; + + /** + * @brief Instantiates the Parsec Runtime Solver class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(ParsecRuntimeSolver) +}//namespace exageostat + +#endif //EXAGEOSTATCPP_PARSECRUNTIMESOLVER_HPP \ No newline at end of file diff --git a/inst/include/runtime-solver/concrete/StarpuRuntimeSolver.hpp b/inst/include/runtime-solver/concrete/StarpuRuntimeSolver.hpp new file mode 100644 index 00000000..09c32b04 --- /dev/null +++ b/inst/include/runtime-solver/concrete/StarpuRuntimeSolver.hpp @@ -0,0 +1,62 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file StarpuRuntimeSolver.hpp + * @brief This file contains the declaration of StarpuRuntimeSolver class. + * @details StarpuRuntimeSolver is a concrete implementation of the RuntimeSolverMethods class. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-11-04 +**/ + +#ifndef EXAGEOSTATCPP_STARPURUNTIMESOLVER_HPP +#define EXAGEOSTATCPP_STARPURUNTIMESOLVER_HPP + +#include +#include + +namespace exageostat::runtimesolver { + + /** + * @brief StarpuRuntimeSolver is a concrete implementation of RuntimeSolverMethods class for dense or diagonal-super tile matrices. + * @tparam T Data Type: float or double + * + */ + template + class StarpuRuntimeSolver : public RuntimeSolverMethods { + public: + + /** + * @brief Calculates the log likelihood value of a given value theta. + * @copydoc RuntimeSolverMethods::ModelingOperations() + * + */ + T ModelingOperations(std::unique_ptr > &aData, + configurations::Configurations &aConfigurations, T *apMeasurementsMatrix, const kernels::Kernel &aKernel) override; + + + /** + * @brief Objective function used in optimization, and following the NLOPT objective function format. + * @param[in] aTheta An array of length n containing the current point in the parameter space. + * @param[in] aGrad An array of length n where you can optionally return the gradient of the objective function. + * @param[in] apInfo pointer containing needed configurations and data. + * @return double MLE results. + * + */ + static double DataModelingAPI(const std::vector &aTheta, std::vector &aGrad, void *apInfo); + + }; + + /** + * @brief Instantiates the Starpu Runtime Solver class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(StarpuRuntimeSolver) +}//namespace exageostat + +#endif //EXAGEOSTATCPP_STARPURUNTIMESOLVER_HPP \ No newline at end of file diff --git a/inst/include/runtime/parsec/JDFHelperFunctions.h b/inst/include/runtime/parsec/JDFHelperFunctions.h new file mode 100644 index 00000000..bcba3377 --- /dev/null +++ b/inst/include/runtime/parsec/JDFHelperFunctions.h @@ -0,0 +1,76 @@ +/** + * @file JDFHelperFunctions.h + * @brief A header file for declarations of JDF helper functions. + * @details Contains function prototypes for JDF operations, including computations, + * transformations, file I/O, and MPI-related data handling for matrix and data structures. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @date 2024-10-20 +**/ + +#include +#include + +/** + * @brief Calculates a unique single index from given dimensions. + * @param[in] aN The row index. + * @param[in] aM The column index. + * @return The calculated single index. + * + */ +int CalculateSingleIndex(int aN, int aM); + +/** + * @brief Sums the elements of a double-precision data matrix. + * @param[in] apData Pointer to the data matrix. + * @param[in] aColumn The number of columns in the matrix. + * @param[in] aRow The number of rows in the matrix. + * @return The sum of matrix elements as a double. + * + */ +double SumDoubleData(double *apData, int aColumn, int aRow); + +/** + * @brief Sums the elements of a complex double-precision data matrix. + * @param[in] apData Pointer to the complex data matrix. + * @param[in] aColumn The number of columns in the matrix. + * @param[in] aRow The number of rows in the matrix. + * @return The sum of matrix elements as a complex double. + * @return void + * + */ +complex double SumComplexData(complex double *apData, int aColumn, int aRow); + +/** + * @brief Performs forward Spherical Harmonic Transform (SHT) calculations. + * @param[in,out] apFlm Pointer to SHT coefficients. + * @param[in] apF_data Pointer to spatial data for transformation. + * @param[in] aFDataM Number of rows in spatial data. + * @param[in] aFDataN Number of columns in spatial data. + * @param[in] apEt1, apEt2, apEp, apSlmn, apIe, apIo, apP Arrays for intermediate calculations. + * @param[in] aEt1M, aEt2M, aEpM, aEpN, aSlmnN, aSlmnM, aIeM, aIeN, aIoM, aIoN Dimensions of respective arrays. + * @param[in] apD, apGmtheta_r, apFmnm, apTmp1, apTmp2 Additional intermediate matrices. + * @param[in] aL Maximum degree for the SHT. + * @return void + * + */ +void ForwardSHTHelper(double *apFlm, complex double *apF_data, int aFDataM, int aFDataN, + complex double *apEt1, int aEt1M, complex double *apEt2, int aEt2M, + complex double *apEp, int aEpM, int aEpN, complex double *apSlmn, + int aSlmnN, int aSlmnM, complex double *apIe, int aIeM, int aIeN, + complex double *apIo, int aIoM, int aIoN, complex double *apP, + int aPM, int aPN, complex double *apD, complex double *apGmtheta_r, + complex double *apFmnm, complex double *apTmp1, + complex double *apTmp2, int aL); + +/** + * @brief Performs inverse Spherical Harmonic Transform (SHT) calculations. + * @param[in] apFlm Pointer to coefficients from forward SHT. + * @param[out] apF_spatial Pointer to result spatial data. + * @param[in] apZlm, apSC, apSmt Arrays for intermediate calculations. + * @param[in] aL Maximum degree for the SHT. + * @return void + * + */ +void InverseSHTHelper(double *apFlm, double *apF_spatial, double *apZlm, double *apSC, + double *apSmt, int aL); diff --git a/inst/include/runtime/parsec/ParsecHeader.hpp b/inst/include/runtime/parsec/ParsecHeader.h similarity index 100% rename from inst/include/runtime/parsec/ParsecHeader.hpp rename to inst/include/runtime/parsec/ParsecHeader.h diff --git a/inst/include/runtime/parsec/jdf/JobDescriptionFormat.h b/inst/include/runtime/parsec/jdf/JobDescriptionFormat.h new file mode 100644 index 00000000..3312f713 --- /dev/null +++ b/inst/include/runtime/parsec/jdf/JobDescriptionFormat.h @@ -0,0 +1,266 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file JobDescriptionFormat.h + * @brief A header file for parsec generated functions from jdf files. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @date 2024-10-08 +**/ + +#include + +/** + * @brief Reads a CSV file into a matrix description. + * @details This function reads data from a CSV file and populates the specified matrix description. + * @param[in] apContext Pointer to the parsec context. + * @param[in, out] apDesc Pointer to the matrix block cyclic descriptor. + * @param[in] aMB Number of rows in the block. + * @param[in] aNB Number of columns in the block. + * @param[in] aNodes Number of nodes. + * @param[in] aTimeSlot Time slot for the data. + * @param[in] apFilename Filename of the CSV file. + * @param[in] aRank Rank of the current process. + * @param[in] aVerbose Verbosity level for output. + * @param[in] aGpus Number of GPUs available. + * @return 0 on success, negative value on error. + * + */ +int ReadCSV(parsec_context_t *apContext, parsec_matrix_block_cyclic_t *apDesc, int aMB, int aNB, int aNodes, + int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus); + +/** + * @brief Reads a specific time slot from a CSV file. + * @details This function extracts data from a specified time slot in a CSV file and updates the matrix description. + * @param[in] apContext Pointer to the parsec context. + * @param[in, out] apDesc Pointer to the matrix block cyclic descriptor. + * @param[in] aMB Number of rows in the block. + * @param[in] aNB Number of columns in the block. + * @param[in] aNodes Number of nodes. + * @param[in] aTimeSlot Time slot for the data. + * @param[in] apFilename Filename of the CSV file. + * @param[in] aRank Rank of the current process. + * @param[in] aVerbose Verbosity level for output. + * @param[in] aGpus Number of GPUs available. + * @return 0 on success, negative value on error. + * + */ +int ReadCSVTimeSlot(parsec_context_t *apContext, parsec_matrix_block_cyclic_t *apDesc, int aMB, int aNB, + int aNodes, int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus); + +/** + * @brief Reads a complex CSV file for a specific time slot. + * @details This function reads complex data from a CSV file corresponding to a specific time slot. + * @param[in] apContext Pointer to the parsec context. + * @param[in, out] apDesc Pointer to the matrix block cyclic descriptor. + * @param[in] aMB Number of rows in the block. + * @param[in] aNB Number of columns in the block. + * @param[in] aNodes Number of nodes. + * @param[in] aTimeSlot Time slot for the data. + * @param[in] apFilename Filename of the CSV file. + * @param[in] aRank Rank of the current process. + * @param[in] aVerbose Verbosity level for output. + * @param[in] aGpus Number of GPUs available. + * @return 0 on success, negative value on error. + * + */ +int ReadCSVToComplexTimeSlot(parsec_context_t *apContext, parsec_matrix_block_cyclic_t *apDesc, int aMB, + int aNB, int aNodes, int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus); + +/** + * @brief Reads a complex CSV file. + * @details This function reads complex data from a CSV file and updates the matrix description. + * @param[in] apContext Pointer to the parsec context. + * @param[in, out] apDesc Pointer to the matrix block cyclic descriptor. + * @param[in] aMB Number of rows in the block. + * @param[in] aNB Number of columns in the block. + * @param[in] aNodes Number of nodes. + * @param[in] aTimeSlot Time slot for the data. + * @param[in] apFilename Filename of the CSV file. + * @param[in] aRank Rank of the current process. + * @param[in] aVerbose Verbosity level for output. + * @param[in] aGpus Number of GPUs available. + * @return 0 on success, negative value on error. + * + */ +int ReadCSVComplex(parsec_context_t *apContext, parsec_matrix_block_cyclic_t *apDesc, int aMB, int aNB, + int aNodes, int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus); + +/** + * @brief Reads a complex CSV file into a matrix description. + * @details This function reads complex data from a CSV file and populates the specified matrix description. + * @param[in] apContext Pointer to the parsec context. + * @param[in, out] apDesc Pointer to the matrix block cyclic descriptor. + * @param[in] aMB Number of rows in the block. + * @param[in] aNB Number of columns in the block. + * @param[in] aNodes Number of nodes. + * @param[in] aTimeSlot Time slot for the data. + * @param[in] apFilename Filename of the CSV file. + * @param[in] aRank Rank of the current process. + * @param[in] aVerbose Verbosity level for output. + * @param[in] aGpus Number of GPUs available. + * @return 0 on success, negative value on error. + * + */ +int ReadCSVToComplex(parsec_context_t *apContext, parsec_matrix_block_cyclic_t *apDesc, int aMB, int aNB, + int aNodes, int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus); + +/** + * @brief Performs forward spherical harmonic transform. + * @details This function computes the forward spherical harmonic transform using the provided data descriptors. + * @param[in] apContext Pointer to the parsec context. + * @param[in] apFDataDesc Pointer to the data descriptor for the forward transform. + * @param[in] apFLMDesc Pointer to the descriptor for the spherical harmonic coefficients. + * @param[in] apFLMTDesc Pointer to the descriptor for the transformed spherical harmonic coefficients. + * @param[in] apET1Desc Pointer to the first auxiliary descriptor. + * @param[in] apET2Desc Pointer to the second auxiliary descriptor. + * @param[in] apEPDesc Pointer to the endpoint descriptor. + * @param[in] apSLMNDesc Pointer to the descriptor for Spherical Harmonic Matrix. + * @param[in] apIEDesc Pointer to the input descriptor. + * @param[in] apIODesc Pointer to the output descriptor. + * @param[in] apPDesc Pointer to the parameter descriptor. + * @param[in] apDDesc Pointer to the descriptor for intermediate data. + * @param[in] aFDataM Number of rows in the forward data matrix. + * @param[in] aEPN Number of endpoints. + * @param[in] aET1M Number of rows in the first auxiliary matrix. + * @param[in] aET2M Number of rows in the second auxiliary matrix. + * @param[in] aPN Number of processes. + * @param[in] aFlmM Number of rows in the spherical harmonic coefficients matrix. + * @param[in] aFlmN Number of columns in the spherical harmonic coefficients matrix. + * @param[in] aLSize Size of the spherical harmonic basis. + * @return 0 on success, negative value on error. + * + */ +int ForwardSHT(parsec_context_t *apContext, parsec_tiled_matrix_t *apFDataDesc, parsec_tiled_matrix_t *apFLMDesc, + parsec_tiled_matrix_t *apFLMTDesc, parsec_tiled_matrix_t *apET1Desc, + parsec_tiled_matrix_t *apET2Desc, parsec_tiled_matrix_t *apEPDesc, + parsec_tiled_matrix_t *apSLMNDesc, parsec_tiled_matrix_t *apIEDesc, + parsec_tiled_matrix_t *apIODesc, parsec_tiled_matrix_t *apPDesc, + parsec_tiled_matrix_t *apDDesc, int aFDataM, int aEPN, int aET1M, + int aET2M, int aPN, int aFlmM, int aFlmN, int aLSize); + +/** + * @brief Computes the element-wise difference between two matrices. + * @details This function calculates the difference between corresponding elements + * of two matrices, `apDescA` and `apDescB`, which are described by a block-cyclic distribution. + * @param[in] apContext Pointer to the PaRSEC context (`parsec_context_t`) in which the computation will be performed. + * @param[in] apDescA Pointer to the descriptor of the first matrix. + * @param[in] apDescB Pointer to the descriptor of the second matrix. + * @return Returns 0 on successful completion or an error otherwise. + * + */ +int DifferenceDouble(parsec_context_t *apContext, parsec_matrix_block_cyclic_t *apDescA, parsec_matrix_block_cyclic_t *apDescB); + +/** + * @brief Performs forward spherical harmonic transform with reshaping. + * @details This function computes the forward spherical harmonic transform and reshapes the resulting data. + * @param[in] apContext Pointer to the parsec context. + * @param[in] aRank Rank of the current process. + * @param[in] aVerbose Verbosity level for output. + * @param[in] apFDataDesc Pointer to the data descriptor for the forward transform. + * @param[in] apFLMDesc Pointer to the descriptor for the spherical harmonic coefficients. + * @param[in] apFLMTDesc Pointer to the descriptor for the transformed spherical harmonic coefficients. + * @param[in] apET1Desc Pointer to the first auxiliary descriptor. + * @param[in] apET2Desc Pointer to the second auxiliary descriptor. + * @param[in] apEPDesc Pointer to the endpoint descriptor. + * @param[in] apSLMNDesc Pointer to the descriptor for Spherical Harmonic Matrix. + * @param[in] apIEDesc Pointer to the input descriptor. + * @param[in] apIODesc Pointer to the output descriptor. + * @param[in] apPDesc Pointer to the parameter descriptor. + * @param[in] apDDesc Pointer to the descriptor for intermediate data. + * @param[in] apADesc Pointer to the descriptor for A matrix. + * @param[in] aFDataM Number of rows in the forward data matrix. + * @param[in] aEPN Number of endpoints. + * @param[in] aET1M Number of rows in the first auxiliary matrix. + * @param[in] aET2M Number of rows in the second auxiliary matrix. + * @param[in] aPN Number of processes. + * @param[in] aFlmTNB Block size parameter specific to the reshaping of spherical harmonic coefficients. + * @param[in] aT Transform-specific parameter, often used to define temporal or frequency characteristics. + * @param[in] aLSize Size of the spherical harmonic basis, determining the resolution of the transformation. + * @param[out] apNormGlobal Pointer to an array storing global normalization values applied during the transform. + * @param[in] aNT Number of transformations applied, defining the iteration count for computation. + * @param[in] aUpperLower Specifies the range for the spherical harmonic transformation, either upper or lower spherical components. + * @return 0 on success, negative value on error. + * + */ +int ForwardSHTReshape(parsec_context_t *apContext, int aRank, int aVerbose, parsec_tiled_matrix_t *apFDataDesc, + parsec_tiled_matrix_t *apFLMDesc, parsec_tiled_matrix_t *apFLMTDesc, + parsec_tiled_matrix_t *apET1Desc, parsec_tiled_matrix_t *apET2Desc, + parsec_tiled_matrix_t *apEPDesc, parsec_tiled_matrix_t *apSLMNDesc, + parsec_tiled_matrix_t *apIEDesc, parsec_tiled_matrix_t *apIODesc, + parsec_tiled_matrix_t *apPDesc, parsec_tiled_matrix_t *apDDesc, + parsec_tiled_matrix_t *apADesc, int aFDataM, int aEPN, int aET1M, + int aET2M, int aPN, int aFlmTNB, int aT, int aLSize, double *apNormGlobal, + int aNT, int aUpperLower); + +/** + * @brief Computes the mean squared error between data and spatial descriptors. + * @details This function calculates the mean squared error (MSE) between two matrix descriptors, which represent + * the observed data and the spatial data for a given size of spherical harmonic basis. + * @param[in] apContext Pointer to the parsec context. + * @param[in] apFDataDesc Pointer to the matrix descriptor for the observed data. + * @param[in] apFSpatialDesc Pointer to the matrix descriptor for the spatial data. + * @param[in] aLSize Size of the spherical harmonic basis. + * @return 0 on success, negative value on error. + * + */ +int MeanSquaredError(parsec_context_t *apContext, parsec_matrix_block_cyclic_t* apFDataDesc, + parsec_matrix_block_cyclic_t* apFSpatialDesc, int aLSize); + +/** + * @brief Computes the norm of a tiled matrix. + * @details This function calculates the norm of a matrix represented by the given tiled matrix descriptor. + * The result can be computed for the entire matrix or for specific tiles based on the provided parameters. + * @param[in] apContext Pointer to the parsec context, which holds information about the execution environment. + * @param[in] apNormGlobal The global norm value to be updated. + * @param[in] apADesc Pointer to the descriptor of the tiled matrix for which the norm is being computed. + * @param[in] aNT The number of tiles in the tiled matrix. This indicates how many submatrices will be considered. + * @param[in] aIsSymmetric flag to specify if the data matrix is symmetric or not. + * @param[in] aUpperLower Specifies whether to calculate the norm for the upper or lower triangular part of the matrix. + * @return void + * + */ +void GetMatrixNorm(parsec_context_t *apContext, double *apNormGlobal, parsec_tiled_matrix_t *apADesc, + int aNT, int aUpperLower, int aIsSymmetric); + +/** + * @brief Performs inverse spherical harmonic transform. + * @details This function computes the inverse spherical harmonic transform using the provided data descriptors. + * @param[in] apContext Pointer to the parsec context. + * @param[in] apFSpatialDesc Pointer to the descriptor for the spherical harmonic coefficients. + * @param[in] apFLMTDesc Pointer to the descriptor for the transformed spherical harmonic coefficients. + * @param[in] apZLMDesc Pointer to the second auxiliary descriptor. + * @param[in] apSCDesc Pointer to the input descriptor. + * @param[in] aLSize Size of the spherical harmonic basis. + * @return 0 on success, negative value on error. + * + */ +int InverseSHT(parsec_context_t *apContext, parsec_tiled_matrix_t *apFSpatialDesc, parsec_tiled_matrix_t *apFLMDesc, + parsec_tiled_matrix_t *apZLMDesc, parsec_tiled_matrix_t *apSCDesc, int aLSize); + +/** + * @brief Compresses a matrix using a specified compression strategy and parameters. + * @details This function applies matrix compression based on the parameters provided. + * @param[in] apContex Pointer to the Parsec context, which manages task execution and dataflow. + * @param[in] apNormGlobal The global norm value to be updated. + * @param[in] aUpperLower Integer flag indicating which triangular part of the matrix to compress. + * @param[in] aBandSizeDense Band size for the dense region of the matrix in the compression process. + * @param[in] aNT Number of tiles in one dimension of the matrix. + * @param[in] aMaxRank Maximum allowable rank for the compressed matrix. Controls the degree of compression. + * @param[in] aN Total number of columns in the matrix, used to define the matrix dimensions. + * @param[in] aAdaptiveDecision Flag indicating whether to enable adaptive compression. + * @param[in] aTolerance Compression tolerance value, used to decide the accuracy of the compressed matrix. + * @param[in] aSendFullTile Flag indicating whether to transmit full tiles as part of the compression,. + * @param[in] aAutoBand Flag to enable automatic adjustment of the band size during compression. + * @param[in] aGpus Number of GPUs to utilize in the compression. + * @param[in] apHicmaData The HiCMA data struct of descriptors + * @param[in] apParamsKernel The Starsh struct of kernels + * @return void + * + */ +void MatrixCompress(parsec_context_t *apContext, double *apNormGlobal, int aUpperLower, int aBandSizeDense, int aNT, + int aMaxRank, int aN, int aAdaptiveDecision, int aTolerance, int aSendFullTile, int aAutoBand, + int aGpus, hicma_parsec_data_t *apHicmaData, starsh_params_t *apParamsKernel); \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 713d0b05..d7bf24f7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,18 +16,20 @@ add_subdirectory(kernels) add_subdirectory(helpers) add_subdirectory(data-units) add_subdirectory(runtime) -add_subdirectory(linear-algebra-solvers) add_subdirectory(api) add_subdirectory(results) add_subdirectory(hardware) add_subdirectory(data-generators) add_subdirectory(data-loader) add_subdirectory(prediction) +add_subdirectory(runtime-solver) # Check the value of RUNTIME_TYPE and configure chameleon/starpu accordingly if (RUNTIME_TYPE STREQUAL "PARSEC") add_subdirectory(data-analyzer) add_subdirectory(data-transformer) +else() + add_subdirectory(linear-algebra-solvers) endif () if (USE_R) @@ -37,7 +39,7 @@ endif () # Set the name of the library to be created. set(LIB_NAME ${PROJECT_NAME}) # Create the library with the specified source files and linking libraries. -add_library(${LIB_NAME} SHARED ${SOURCES}) +add_library(${LIB_NAME} SHARED ${SOURCES} ${JDF_GENERATED_SOURCES}) target_compile_definitions(${LIB_NAME} PUBLIC ${COMPILE_DEFINITIONS}) target_link_libraries(${LIB_NAME} ${LIBS}) diff --git a/src/api/ExaGeoStat.cpp b/src/api/ExaGeoStat.cpp index 1e2a371e..b9dc6a2d 100644 --- a/src/api/ExaGeoStat.cpp +++ b/src/api/ExaGeoStat.cpp @@ -13,11 +13,10 @@ #include #include -#include #include +#include using namespace std; -using namespace nlopt; using namespace exageostat::api; using namespace exageostat::generators; @@ -39,6 +38,7 @@ void ExaGeoStat::ExaGeoStatLoadData(Configurations &aConfigurations, std::uni aData = data_generator->CreateData(aConfigurations, *pKernel); delete pKernel; LOGGER("\t*Data generation/loading finished*") + } template @@ -53,57 +53,11 @@ T ExaGeoStat::ExaGeoStatDataModeling(Configurations &aConfigurations, std::un // Add the data modeling arguments. aConfigurations.InitializeDataModelingArguments(); - int parameters_number = pKernel->GetParametersNumbers(); - int max_number_of_iterations = aConfigurations.GetMaxMleIterations(); - // Setting struct of data to pass to the modeling. - auto modeling_data = new mModelingData(aData, aConfigurations, *apMeasurementsMatrix, *pKernel); - // Create nlopt - double opt_f; - opt optimizing_function(nlopt::LN_BOBYQA, parameters_number); - // Initialize problem's bound. - optimizing_function.set_lower_bounds(aConfigurations.GetLowerBounds()); - optimizing_function.set_upper_bounds(aConfigurations.GetUpperBounds()); - optimizing_function.set_ftol_abs(aConfigurations.GetTolerance()); - // Set max iterations value. - optimizing_function.set_maxeval(max_number_of_iterations); - // TODO: ON API level it should be consistent regardless of the runtime being implemented -#if DEFAULT_RUNTIME - optimizing_function.set_max_objective(ModelingAPI, (void *) modeling_data); -#endif - // Optimize mle using nlopt. - optimizing_function.optimize(aConfigurations.GetStartingTheta(), opt_f); - aConfigurations.SetEstimatedTheta(aConfigurations.GetStartingTheta()); - - auto theta = aConfigurations.GetStartingTheta(); - - LOGGER("--> Final Theta Values (", true) - for (int i = 0; i < parameters_number; i++) { - LOGGER_PRECISION(theta[i]) - if (i != parameters_number - 1) { - LOGGER_PRECISION(", ") - } - } - LOGGER_PRECISION(")") - LOGGER("") - - delete pKernel; - delete modeling_data; - return optimizing_function.last_optimum_value(); -} - -template -double ExaGeoStat::ModelingAPI(const std::vector &aTheta, std::vector &aGrad, void *apInfo) { - - auto config = ((mModelingData *) apInfo)->mpConfiguration; - auto data = ((mModelingData *) apInfo)->mpData; - auto measurements = ((mModelingData *) apInfo)->mpMeasurementsMatrix; - auto kernel = ((mModelingData *) apInfo)->mpKernel; - // We do Date Modeling with any computation. - auto linear_algebra_solver = linearAlgebra::LinearAlgebraFactory::CreateLinearAlgebraSolver( - config->GetComputation()); - - return linear_algebra_solver->ModelingOperations(*data, *config, aTheta.data(), measurements, *kernel); + auto runtime_solver = runtimesolver::RuntimeSolverFactory::CreateRuntimeSolver(); + T result = runtime_solver->ModelingOperations(aData, aConfigurations, apMeasurementsMatrix, *pKernel); + delete pKernel; + return result; } @@ -124,12 +78,3 @@ void ExaGeoStat::ExaGeoStatPrediction(Configurations &aConfigurations, std::u delete pKernel; } -template -void ExaGeoStat::ExaGeoStatTransformData(Configurations &aConfigurations, std::unique_ptr> &aData){ - -} - -template -void ExaGeoStat::ExaGeoStatDataAnalyzer(Configurations &aConfigurations, std::unique_ptr> &aData){ - -} diff --git a/src/configurations/Configurations.cpp b/src/configurations/Configurations.cpp index 0e77e2c6..cc0d790d 100644 --- a/src/configurations/Configurations.cpp +++ b/src/configurations/Configurations.cpp @@ -36,7 +36,7 @@ Configurations::Configurations() { SetGPUsNumbers(0); SetPGrid(1); SetQGrid(1); - SetMaxRank(1); + SetMaxRank(-1); SetIsOOC(false); SetKernelName(""); SetDimension(Dimension2D); @@ -80,6 +80,9 @@ Configurations::Configurations() { SetFileNumber(1); SetEnableInverse(false); SetMPIIO(true); + SetTolerance(0); + // TODO: currently, we support real data only in parsec. In the future, we should support synthetic and real data for both runtimes + SetIsSynthetic(false); #endif } @@ -133,7 +136,7 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV, const } else if (argument_name == "--gpus" || argument_name == "--GPUsNumbers" || argument_name == "--gpu_number" || argument_name == "--ngpus") { SetGPUsNumbers(CheckNumericalValue(argument_value)); - } else if (argument_name == "--DTS" || argument_name == "--dts" || argument_name == "--Dts" || argument_name == "--NB") { + } else if (argument_name == "--DTS" || argument_name == "--dts" || argument_name == "--Dts") { SetDenseTileSize(CheckNumericalValue(argument_value)); } else if (argument_name == "--LTS" || argument_name == "--lts" || argument_name == "--Lts") { SetLowTileSize(CheckNumericalValue(argument_value)); @@ -238,6 +241,16 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV, const if (GetKernelName().empty()) { throw domain_error("You need to set the Kernel, before starting"); } + if(GetMaxRank() == -1){ + SetMaxRank(1); + } +#else + if(GetMaxRank() == -1){ + SetMaxRank(GetDenseTileSize() / 2); + } + if(GetTolerance() >= 0){ + SetTolerance(8); + } #endif size_t found = GetKernelName().find("NonGaussian"); @@ -308,11 +321,19 @@ void Configurations::InitializeDataGenerationArguments() { } if (GetDimension() != DimensionST) { if (GetTimeSlot() != 1) { +#if DEFAULT_RUNTIME throw std::runtime_error("Time Slot can only be greater than 1 if the dimensions are set to SpaceTime."); +#endif } } else if (GetTimeSlot() < 1) { throw std::runtime_error("Time Slot must be at least 1 if the dimensions are set to SpaceTime."); } + +#if !DEFAULT_RUNTIME + if (GetDataPath().empty()) { + throw domain_error("You need to set the data path, before starting"); + } +#endif } void Configurations::InitializeDataModelingArguments() { @@ -672,6 +693,7 @@ void Configurations::PrintSummary() { if (!mFirstInit) { LOGGER("********************SUMMARY**********************") +#if DEFAULT_RUNTIME if (this->GetIsSynthetic()) { LOGGER("#Synthetic Data generation") } else { @@ -716,6 +738,12 @@ void Configurations::PrintSummary() { if (this->GetIsOOC()) { LOGGER("#Out Of Core (OOC) technology is enabled") } +#else + LOGGER("\t#L: " << this->GetDenseTileSize() << "\t\t\t\t#T: " << this->GetTimeSlot()) + LOGGER("\t#NB: " << this->GetDenseTileSize() << "\t\t\t\t#gpus: " << this->GetGPUsNumbers()) + LOGGER("\t#Nodes: " << this->GetCoresNumber() << "\t\t\t#Time slot per file: " << GetTimeSlotPerFile()); + LOGGER("\t#Number of files: " << this->GetFileNumber() << "\t#File per node: " << ((this->GetFileNumber()%this->GetCoresNumber())? this->GetFileNumber()/this->GetCoresNumber()+1 : this->GetFileNumber()/this->GetCoresNumber())) +#endif LOGGER("*************************************************") mFirstInit = true; } diff --git a/src/data-analyzer/DataAnalyzer.cpp b/src/data-analyzer/DataAnalyzer.cpp index 942c9df8..f7e42149 100644 --- a/src/data-analyzer/DataAnalyzer.cpp +++ b/src/data-analyzer/DataAnalyzer.cpp @@ -9,19 +9,53 @@ * @version 2.0.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah + * @author Qinglei Cao * @date 2024-02-04 **/ #include -using namespace exageostat::configurations; +extern "C" { +#include +} + +using namespace exageostat::analyzer; +using namespace exageostat::common; template -static void AnalyzeMatrix(Configurations &aConfigurations, std::unique_ptr> &aData){ +void +DataAnalyzer::PreAnalyzeMatrix(std::unique_ptr> &aData){ + + auto *pParams = ExaGeoStatHardware::GetHicmaParams(); + auto *pHicma_data = ExaGeoStatHardware::GetHicmaData(); + auto *pAnalysis = ExaGeoStatHardware::GetAnalysis(); + auto *pStarsh_kernel = ExaGeoStatHardware::GetParamsKernel(); + auto *pContext = (parsec_context_t *) ExaGeoStatHardware::GetParsecContext(); + hicma_parsec_matrix_pre_analysis(pContext, pHicma_data, pParams, pStarsh_kernel, pAnalysis); } template -static double CompareMatDifference(Configurations &aConfigurations, std::unique_ptr> &aData){ +void +DataAnalyzer::PostAnalyzeMatrix(std::unique_ptr> &aData){ + + auto *pParams = ExaGeoStatHardware::GetHicmaParams(); + auto *pHicma_data = ExaGeoStatHardware::GetHicmaData(); + auto *pAnalysis = ExaGeoStatHardware::GetAnalysis(); + auto *pStarsh_kernel = ExaGeoStatHardware::GetParamsKernel(); + auto *pContext = (parsec_context_t *) ExaGeoStatHardware::GetParsecContext(); + + hicma_parsec_matrix_post_analysis(pContext, pHicma_data, pParams, pStarsh_kernel, pAnalysis); +} + +template +double +DataAnalyzer::CompareMatDifference(std::unique_ptr> &aData){ + + // Get parsec descriptors + auto flm_desc = aData->GetDescriptorData()->GetDescriptor(DescriptorType::PARSEC_DESCRIPTOR,DescriptorName::DESCRIPTOR_FLM).parsec_desc; + auto flm_era_desc = aData->GetDescriptorData()->GetDescriptor(DescriptorType::PARSEC_DESCRIPTOR,DescriptorName::DESCRIPTOR_FLMERA).parsec_desc; + // Call jdf generated function + DifferenceDouble((parsec_context_t *)ExaGeoStatHardware::GetParsecContext(), flm_desc, flm_era_desc); } diff --git a/src/data-generators/DataGenerator.cpp b/src/data-generators/DataGenerator.cpp index dd4bec8b..7ef8405e 100644 --- a/src/data-generators/DataGenerator.cpp +++ b/src/data-generators/DataGenerator.cpp @@ -13,44 +13,31 @@ #include #include -#include +#include +using namespace exageostat::common; using namespace exageostat::generators; -using namespace exageostat::dataLoader::csv; +using namespace exageostat::dataLoader; using namespace exageostat::generators::synthetic; -using namespace exageostat::common; -using namespace exageostat::results; template std::unique_ptr> DataGenerator::CreateGenerator(configurations::Configurations &apConfigurations) { - - //// TODO: In case of other file support, Then we can create another layer for the factory creation depending on the file size. - // Check the used Data generation method, whether it's synthetic or real. - aDataSourceType = apConfigurations.GetIsSynthetic() ? SYNTHETIC : CSV_FILE; - - // Return DataGenerator unique pointer of Synthetic type - if (aDataSourceType == SYNTHETIC) { - Results::GetInstance()->SetIsSynthetic(true); + if (apConfigurations.GetIsSynthetic()){ + aIsSynthetic = true; return std::unique_ptr>(SyntheticGenerator::GetInstance()); - } else if (aDataSourceType == CSV_FILE) { - Results::GetInstance()->SetIsSynthetic(false); - return std::unique_ptr>(CSVLoader::GetInstance()); } else { - throw std::runtime_error("Data Loading for this file type is unsupported for now"); + aIsSynthetic = false; + return DataLoader::CreateDataLoader(apConfigurations); } } template DataGenerator::~DataGenerator() { - // Return DataGenerator unique pointer of Synthetic type - if (aDataSourceType == SYNTHETIC) { + if (aIsSynthetic) { SyntheticGenerator::GetInstance()->ReleaseInstance(); - } else if (aDataSourceType == CSV_FILE) { - CSVLoader::GetInstance()->ReleaseInstance(); } else { - std::cerr << "Data Loading for this file type is unsupported for now" << std::endl; - std::exit(1); + DataLoader::ReleaseDataLoader(); } } -template DataSourceType DataGenerator::aDataSourceType = SYNTHETIC; +template bool DataGenerator::aIsSynthetic = true; diff --git a/src/data-generators/concrete/SyntheticGenerator.cpp b/src/data-generators/concrete/SyntheticGenerator.cpp index dea29b27..ef5b191b 100644 --- a/src/data-generators/concrete/SyntheticGenerator.cpp +++ b/src/data-generators/concrete/SyntheticGenerator.cpp @@ -14,8 +14,14 @@ #include #include +#if !DEFAULT_RUNTIME +#include +#else #include +#endif +//TODO: we need to make WriteData a function outside the csv, So it can be used whatever the runtime is. +// currently, it has an implementation for the CSVLoader and an empty body for the parsec loader using namespace exageostat::generators::synthetic; using namespace exageostat::common; using namespace exageostat::configurations; diff --git a/src/data-loader/DataLoader.cpp b/src/data-loader/DataLoader.cpp index 65874148..de566c2d 100644 --- a/src/data-loader/DataLoader.cpp +++ b/src/data-loader/DataLoader.cpp @@ -12,60 +12,41 @@ * @date 2023-02-14 **/ -#include +#if !DEFAULT_RUNTIME +#include +#else +#include +#endif using namespace std; using namespace exageostat::dataLoader; -using namespace exageostat::common; -using namespace exageostat::results; template std::unique_ptr> DataLoader::CreateData(configurations::Configurations &aConfigurations, exageostat::kernels::Kernel &aKernel) { - // create vectors that will be populated with read data. - vector measurements_vector; - vector x_locations; - vector y_locations; - vector z_locations; - - aKernel.SetPValue(aConfigurations.GetTimeSlot()); - int p = aKernel.GetVariablesNumber(); - - //Read the data out of the CSV file. - this->ReadData(aConfigurations, measurements_vector, x_locations, y_locations, z_locations, p); - - //create data object - auto data = std::make_unique>(aConfigurations.GetProblemSize() / p, - aConfigurations.GetDimension()); + auto data = this->LoadData(aConfigurations, aKernel); + return data; +} - //Initialize the descriptors. - auto linear_algebra_solver = linearAlgebra::LinearAlgebraFactory::CreateLinearAlgebraSolver(EXACT_DENSE); +template +std::unique_ptr> +DataLoader::CreateDataLoader(exageostat::configurations::Configurations &apConfigurations){ - // TODO: May need to get refactored to avoid the if/else guards #if DEFAULT_RUNTIME - linear_algebra_solver->InitiateDescriptors(aConfigurations, *data->GetDescriptorData(), p); - linear_algebra_solver->ExaGeoStatLaSetTile(EXAGEOSTAT_UPPER_LOWER, 0, 0, - data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, - DESCRIPTOR_C).chameleon_desc); - //populate data object with read data - for (int i = 0; i < aConfigurations.GetProblemSize() / p; i++) { - data->GetLocations()->GetLocationX()[i] = x_locations[i]; - data->GetLocations()->GetLocationY()[i] = y_locations[i]; - if (aConfigurations.GetDimension() != Dimension2D) { - data->GetLocations()->GetLocationZ()[i] = z_locations[i]; - } - } - for (int i = 0; i < aConfigurations.GetProblemSize(); i++) { - ((T *) data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, - DESCRIPTOR_Z).chameleon_desc->mat)[i] = measurements_vector[i]; - } + return std::unique_ptr>(csv::CSVLoader::GetInstance()); +#else + return std::unique_ptr>(parsec::ParsecLoader::GetInstance()); #endif +} - Results::GetInstance()->SetGeneratedLocationsNumber(aConfigurations.GetProblemSize() / p); - Results::GetInstance()->SetIsLogger(aConfigurations.GetLogger()); - Results::GetInstance()->SetLoggerPath(aConfigurations.GetLoggerPath()); +template +void DataLoader::ReleaseDataLoader() { - return data; -} +#if DEFAULT_RUNTIME + csv::CSVLoader::GetInstance()->ReleaseInstance(); +#else + parsec::ParsecLoader::GetInstance()->ReleaseInstance(); +#endif +} \ No newline at end of file diff --git a/src/data-loader/concrete/CMakeLists.txt b/src/data-loader/concrete/CMakeLists.txt index 88180c80..7792dea3 100644 --- a/src/data-loader/concrete/CMakeLists.txt +++ b/src/data-loader/concrete/CMakeLists.txt @@ -10,8 +10,16 @@ # @date 2023-02-14 # Add source files to the parent scope -set(SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/CSVLoader.cpp - ${SOURCES} - PARENT_SCOPE - ) \ No newline at end of file +if (RUNTIME_TYPE STREQUAL "STARPU") + set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/CSVLoader.cpp + ${SOURCES} + PARENT_SCOPE + ) +elseif (RUNTIME_TYPE STREQUAL "PARSEC") + set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/ParsecLoader.cpp + ${SOURCES} + PARENT_SCOPE + ) +endif() diff --git a/src/data-loader/concrete/CSVLoader.cpp b/src/data-loader/concrete/CSVLoader.cpp index bfd153cd..2c9266d8 100644 --- a/src/data-loader/concrete/CSVLoader.cpp +++ b/src/data-loader/concrete/CSVLoader.cpp @@ -4,8 +4,8 @@ // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** - * @file CSVDataGenerator.cpp - * @brief Implementation of the CSVDataGenerator class + * @file CSVLoader.cpp + * @brief Implementation of the CSVLoader class * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah @@ -21,6 +21,8 @@ using namespace std; using namespace exageostat::configurations; using namespace exageostat::common; using namespace exageostat::dataLoader::csv; +using namespace exageostat::results; +using namespace exageostat::dataunits; template CSVLoader *CSVLoader::GetInstance() { @@ -231,6 +233,52 @@ void CSVLoader::WriteData(const T &aMatrixPointer, const int &aProblemSize, c p_file_synthetic.close(); } +template +std::unique_ptr> +CSVLoader::LoadData(configurations::Configurations &aConfigurations, exageostat::kernels::Kernel &aKernel) { + // create vectors that will be populated with read data. + vector measurements_vector; + vector x_locations; + vector y_locations; + vector z_locations; + + aKernel.SetPValue(aConfigurations.GetTimeSlot()); + int p = aKernel.GetVariablesNumber(); + + //Read the data out of the CSV file. + this->ReadData(aConfigurations, measurements_vector, x_locations, y_locations, z_locations, p); + + //create data object + auto data = std::make_unique>(aConfigurations.GetProblemSize() / p, + aConfigurations.GetDimension()); + + //Initialize the descriptors. + auto linear_algebra_solver = linearAlgebra::LinearAlgebraFactory::CreateLinearAlgebraSolver(EXACT_DENSE); + + linear_algebra_solver->InitiateDescriptors(aConfigurations, *data->GetDescriptorData(), p); + linear_algebra_solver->ExaGeoStatLaSetTile(EXAGEOSTAT_UPPER_LOWER, 0, 0, + data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_C).chameleon_desc); + //populate data object with read data + for (int i = 0; i < aConfigurations.GetProblemSize() / p; i++) { + data->GetLocations()->GetLocationX()[i] = x_locations[i]; + data->GetLocations()->GetLocationY()[i] = y_locations[i]; + if (aConfigurations.GetDimension() != Dimension2D) { + data->GetLocations()->GetLocationZ()[i] = z_locations[i]; + } + } + for (int i = 0; i < aConfigurations.GetProblemSize(); i++) { + ((T *) data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_Z).chameleon_desc->mat)[i] = measurements_vector[i]; + } + + Results::GetInstance()->SetGeneratedLocationsNumber(aConfigurations.GetProblemSize() / p); + Results::GetInstance()->SetIsLogger(aConfigurations.GetLogger()); + Results::GetInstance()->SetLoggerPath(aConfigurations.GetLoggerPath()); + + return data; +} + template void CSVLoader::ReleaseInstance() { if (mpInstance != nullptr) { diff --git a/src/data-loader/concrete/ParsecLoader.cpp b/src/data-loader/concrete/ParsecLoader.cpp new file mode 100644 index 00000000..d3167b1e --- /dev/null +++ b/src/data-loader/concrete/ParsecLoader.cpp @@ -0,0 +1,284 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file SyntheticGenerator.cpp + * @brief Implementation of the SyntheticGenerator class + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @author Qinglei Cao + * @date 2023-02-14 +**/ + +#include +#include +extern "C"{ +#include +} + +using namespace std; + +using namespace exageostat::dataLoader::parsec; +using namespace exageostat::common; +using namespace exageostat::configurations; +using namespace exageostat::dataunits; +using namespace exageostat::transformers; + +template +ParsecLoader *ParsecLoader::GetInstance() { + + if (mpInstance == nullptr) { + mpInstance = new ParsecLoader(); + } + return mpInstance; +} + +template +std::unique_ptr> +ParsecLoader::LoadData(configurations::Configurations &aConfigurations, exageostat::kernels::Kernel &aKernel) { + + SYNC_TIME_START(); + //create data object + auto data = std::make_unique>(aConfigurations.GetProblemSize() / 1, + aConfigurations.GetDimension()); + + // Initiate Descriptors + int L = aConfigurations.GetDenseTileSize(); + int MB; + int NB; + int t = aConfigurations.GetTimeSlot(); + int P = aConfigurations.GetPGrid(); + int nodes = aConfigurations.GetCoresNumber(); + int rank = ExaGeoStatHardware::GetParsecMPIRank(); + int verbose = configurations::Configurations::GetVerbosity() == DETAILED_MODE? 1: 0; + int gpus = aConfigurations.GetGPUsNumbers(); + string files_directory_path = aConfigurations.GetDataPath(); + int path_length = files_directory_path.length(); + char filename[path_length + 50]; + char directory_path[path_length]; + sprintf(directory_path, "%s", files_directory_path.c_str()); + + MB = L + 1; + NB = L * 2; + VERBOSE_PRINT(rank, verbose, ("Reading f_data\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_F_DATA); + parsec_matrix_block_cyclic_t *pF_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_F_DATA).parsec_desc; + ReadCSVToComplexTimeSlot((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pF_data_desc, MB, NB, nodes, t, directory_path, rank, verbose, gpus); + + MB = 2*L-1; + NB = L+1; + VERBOSE_PRINT(rank, verbose, ("Reading Et1\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ET1); + parsec_matrix_block_cyclic_t *pEt1_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ET1).parsec_desc; + sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Et1.csv"); + ReadCSVComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pEt1_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); + + MB = 2*L-1; + NB = L-1; + VERBOSE_PRINT(rank, verbose, ("Reading Et2\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ET2); + parsec_matrix_block_cyclic_t *pEt2_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ET2).parsec_desc; + sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Et2.csv"); + ReadCSVComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pEt2_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); + + MB = 2*L; + NB = 2*L-1; + VERBOSE_PRINT(rank, verbose, ("Reading Ep\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_EP); + parsec_matrix_block_cyclic_t *pEp_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_EP).parsec_desc; + sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Ep.csv"); + ReadCSVComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pEp_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); + + MB = (L*L+L)/2; + NB = L; + VERBOSE_PRINT(rank, verbose, ("Reading Slmn\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_SLMN); + parsec_matrix_block_cyclic_t *pSlum_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_SLMN).parsec_desc; + sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Slmn.csv"); + ReadCSVComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pSlum_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); + + MB = L; + NB = 2*L-1; + VERBOSE_PRINT(rank, verbose, ("Reading Ie\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_IE); + parsec_matrix_block_cyclic_t *pIe_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_IE).parsec_desc; + sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Ie.csv"); + ReadCSVToComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pIe_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); + + MB = L; + NB = 2*L-1; + VERBOSE_PRINT(rank, verbose, ("Reading Io\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_IO); + parsec_matrix_block_cyclic_t *pIo_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_IO).parsec_desc; + sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Io.csv"); + ReadCSVToComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pIo_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); + + MB = L-1; + NB = L+1; + VERBOSE_PRINT(rank, verbose, ("Reading P\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_P); + parsec_matrix_block_cyclic_t *pP_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_P).parsec_desc; + sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_P.csv"); + ReadCSVToComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pP_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); + + MB = 2*L-1; + NB = 2*L-1; + VERBOSE_PRINT(rank, verbose, ("Reading D\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_D); + parsec_matrix_block_cyclic_t *pD_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_D).parsec_desc; + sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_D.csv"); + ReadCSVToComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pD_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); + + MB = L; + NB = L; + VERBOSE_PRINT(rank, verbose, ("Reading flm\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_FLM); + parsec_matrix_block_cyclic_t *pFlm_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_FLM).parsec_desc; + ReadCSVTimeSlot((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pFlm_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); + + VERBOSE_PRINT(rank, verbose, ("Reading flmERA\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_FLMERA); + parsec_matrix_block_cyclic_t *pFlmera_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_FLMERA).parsec_desc; + sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_flmERA.csv"); + ReadCSVTimeSlot((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pFlmera_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); + + // Backward + if(aConfigurations.GetEnableInverse()){ + + MB = L+1; + NB = (L*L+L)/2; + VERBOSE_PRINT(rank, verbose, ("Reading Zlm\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ZLM); + parsec_matrix_block_cyclic_t *PZlm_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ZLM).parsec_desc; + sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Zlm.csv"); + ReadCSV((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), PZlm_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); + + MB = 2*L-1; + NB = 2*L; + VERBOSE_PRINT(rank, verbose, ("Reading SC\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_SC); + parsec_matrix_block_cyclic_t *pSc_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_SC).parsec_desc; + sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_SC.csv"); + ReadCSV((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pSc_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); + + MB = L+1; + NB = 2*L; + VERBOSE_PRINT(rank, verbose, ("f_spatial\n")); + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_F_SPATIAL); + parsec_matrix_block_cyclic_t *pF_spatial_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_F_SPATIAL).parsec_desc; + ReadCSV((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pF_spatial_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); + } + + // Init and allocate memory for desc_flmT + MB = L * L; + NB = t; + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_FLMT); + parsec_matrix_block_cyclic_t *pFlmt_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_FLMT).parsec_desc; + parsec_matrix_block_cyclic_init(pFlmt_data_desc, PARSEC_MATRIX_DOUBLE, PARSEC_MATRIX_TILE, rank, L*((MB/nodes%L) ? MB/nodes/L+1 : MB/nodes/L), + NB, MB, NB, 0, 0, MB, NB, nodes, 1, 1, 1, 0, 0); + + pFlmt_data_desc->mat = parsec_data_allocate((size_t)pFlmt_data_desc->super.nb_local_tiles * + (size_t)pFlmt_data_desc->super.bsiz * + (size_t)parsec_datadist_getsizeoftype(pFlmt_data_desc->super.mtype)); + parsec_data_collection_set_key((parsec_data_collection_t*)&desc_flmT, "desc_flmT"); + + // Init and allocate memory for pA_data_desc + MB = L * L; + NB = t; + data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_A); + parsec_matrix_block_cyclic_t *pA_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_A).parsec_desc; + parsec_matrix_block_cyclic_init(pA_data_desc, PARSEC_MATRIX_DOUBLE, PARSEC_MATRIX_TILE, rank, L, L, MB, NB, 0, 0, + pFlmt_data_desc->super.mb, pFlmt_data_desc->super.nb, P, nodes/P, 1, 1, 0, 0); + pA_data_desc->mat = parsec_data_allocate((size_t)pA_data_desc->super.nb_local_tiles * + (size_t)pA_data_desc->super.bsiz * + (size_t)parsec_datadist_getsizeoftype(pA_data_desc->super.mtype)); + parsec_data_collection_set_key((parsec_data_collection_t*)&pA_data_desc, "desc_A"); + + if(aConfigurations.GetEnableInverse()){ + int ts_test_M = 2000; + int ts_test_N = 1; + // Allocate memory + double *pFileContent = (double *)malloc(ts_test_M * ts_test_N * sizeof(double)); + sprintf(filename, "%s/%s", files_directory_path.c_str(), "ts_test.csv"); + ReadCSVFileHelper(filename, pFileContent, ts_test_M, ts_test_N); + } + + SYNC_TIME_PRINT(ExaGeoStatHardware::GetParsecMPIRank(), ("Load Data\n")); + // Forward SHT + DataTransformer::ForwardSphericalHarmonicsTransform(L, data); + // Forward SHT Reshape + DataTransformer::ForwardReshape(aConfigurations, data); + // Generate matrix + CompressMatrixHelper(aConfigurations, data); + + return data; +} + +template +int ParsecLoader::ReadCSVFileHelper(const char* apFilename, double *apFileContent, int aM, int aN) { + + FILE *pFile = fopen(apFilename, "r"); + if (!pFile) { + printf("File opening failed: %s", apFilename); + return -1; + } + + int status = 0; + for (int i = 0; i < aM; i++) { + for (int j = 0; j < aN; j++) { + status = fscanf(pFile, "%lf,", &apFileContent[i * aN + j]); + if (status != 1) { + fprintf(stderr, "Error reading file at row %d, column %d\n", i, j); + fclose(pFile); + return 1; + } + } + } + fclose(pFile); + + return 0; +} + +template +void ParsecLoader::CompressMatrixHelper(configurations::Configurations &aConfigurations, std::unique_ptr> &aData) { + + int max_rank = aConfigurations.GetMaxRank(); + int n = aConfigurations.GetProblemSize(); + int adaptive_decision = aConfigurations.GetAdaptiveDecision(); + int tol = aConfigurations.GetTolerance(); + int send_full_tile = 0; + int auto_band = 0; + int gpus = aConfigurations.GetGPUsNumbers(); + double upper_lower = EXAGEOSTAT_LOWER; + int L = aConfigurations.GetDenseTileSize(); + int N = aConfigurations.GetProblemSize(); + int NT = (N % L == 0) ? (N/L) : (N/L + 1); + + SYNC_TIME_START(); + MatrixCompress((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), &ExaGeoStatHardware::GetHicmaParams()->norm_global, upper_lower, L, NT, max_rank, n, + adaptive_decision, tol, send_full_tile, auto_band, gpus, ExaGeoStatHardware::GetHicmaData(), ExaGeoStatHardware::GetParamsKernel()); + + SYNC_TIME_PRINT(ExaGeoStatHardware::GetParsecMPIRank(), ("Matrix genneration Matrix norm: norm_global= %le\n", ExaGeoStatHardware::GetHicmaParams()->norm_global)); +} + +template +void ParsecLoader::ReadData(Configurations &aConfigurations, vector &aMeasurementsMatrix, vector &aXLocations, + vector &aYLocations, vector &aZLocations, const int &aP) { +} + +template +void ParsecLoader::WriteData(const T &aMatrixPointer, const int &aProblemSize, const int &aP, std::string &aLoggerPath, Locations &aLocations) { + +} + +template +void ParsecLoader::ReleaseInstance() { + if (mpInstance != nullptr) { + mpInstance = nullptr; + } +} + +template ParsecLoader *ParsecLoader::mpInstance = nullptr; diff --git a/src/data-transformer/DataTransformer.cpp b/src/data-transformer/DataTransformer.cpp index 2145204e..bbca781b 100644 --- a/src/data-transformer/DataTransformer.cpp +++ b/src/data-transformer/DataTransformer.cpp @@ -9,24 +9,105 @@ * @version 2.0.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah + * @author Qinglei Cao * @date 2024-02-04 **/ #include +extern "C"{ + #include +} +using namespace exageostat::common; using namespace exageostat::configurations; +using namespace exageostat::transformers; + +template void DataTransformer::ForwardSphericalHarmonicsTransform(const int &aLSize, std::unique_ptr> &aData){ + + SYNC_TIME_START(); + parsec_tiled_matrix_t *pFDataDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_F_DATA).parsec_desc; + parsec_tiled_matrix_t *pFLMDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_FLM).parsec_desc; + parsec_tiled_matrix_t *pFLMTDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_FLMT).parsec_desc; + parsec_tiled_matrix_t *pET1Desc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ET1).parsec_desc; + parsec_tiled_matrix_t *pET2Desc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ET2).parsec_desc; + parsec_tiled_matrix_t *pEPDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_EP).parsec_desc; + parsec_tiled_matrix_t *pSLMNDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_SLMN).parsec_desc; + parsec_tiled_matrix_t *pIEDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_IE).parsec_desc; + parsec_tiled_matrix_t *pIODesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_IO).parsec_desc; + parsec_tiled_matrix_t *pPDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_P).parsec_desc; + parsec_tiled_matrix_t *pDDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_D).parsec_desc; + + int f_desc_M = pFDataDesc->mb; + int ep_desc_N = pEPDesc->nb; + int et1_desc_M = pET1Desc->mb; + int et2_desc_M = pET2Desc->mb; + int p_desc_N = pPDesc->nb; + int flm_desc_M = pFLMDesc->mb; + int flm_desc_N = pFLMDesc->nb; + + ForwardSHT((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pFDataDesc, pFLMDesc, + pFLMTDesc, pET1Desc, pET2Desc, pEPDesc, pSLMNDesc, pIEDesc, pIODesc, pPDesc, + pDDesc, f_desc_M, ep_desc_N, et1_desc_M, et2_desc_M, p_desc_N, flm_desc_M, flm_desc_N, aLSize); -template -static void ForwardSHT(Configurations &aConfigurations, std::unique_ptr> &aData){ + int flops_forward = 2.0*(aLSize+1)*(2*aLSize-1)*(2*aLSize) // Gmtheta_r = f_data*Ep + + 2.0*(2*aLSize-1)*(2*aLSize-1)*(aLSize+1) // Fmnm = Et1*Gmtheta_r + + 2.0*(2*aLSize-1)*(aLSize-1)*(aLSize+1) // tmp1 = Et2*P + + 2.0*(2*aLSize-1)*(2*aLSize-1)*(aLSize+1) // tmp2 = tmp1 * Gmtheta_r + + 2.0*(2*aLSize-1)*(2*aLSize-1)*(2*aLSize-1) // Fmnm += tmp2 * D + + 2.0*aLSize*aLSize/2*(aLSize*(2*aLSize-1)+aLSize); // flmn_matrix(ell+1,m+1) = Slmn(climate_emulator_getSingleIndex(ell, m),:)*Ie*Fmnm(:,L+m) + + SYNC_TIME_PRINT(ExaGeoStatHardware::GetParsecMPIRank(), ("Forward SHT: %.2lf Gflop/s\n", flops_forward/sync_time_elapsed/1.0e9)); } -template -static void ForwardReshape(Configurations &aConfigurations, std::unique_ptr> &aData){ +template void DataTransformer::ForwardReshape(Configurations &aConfigurations, std::unique_ptr> &aData){ + + SYNC_TIME_START(); + int rank = ExaGeoStatHardware::GetParsecMPIRank(); + int verbose = configurations::Configurations::GetVerbosity() == DETAILED_MODE? 1: 0; + int L = aConfigurations.GetDenseTileSize(); + int t = aConfigurations.GetTimeSlot(); + + parsec_tiled_matrix_t *pFDataDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_F_DATA).parsec_desc; + parsec_tiled_matrix_t *pFLMDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_FLM).parsec_desc; + parsec_tiled_matrix_t *pFLMTDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_FLMT).parsec_desc; + parsec_tiled_matrix_t *pET1Desc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ET1).parsec_desc; + parsec_tiled_matrix_t *pET2Desc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ET2).parsec_desc; + parsec_tiled_matrix_t *pEPDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_EP).parsec_desc; + parsec_tiled_matrix_t *pSLMNDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_SLMN).parsec_desc; + parsec_tiled_matrix_t *pIEDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_IE).parsec_desc; + parsec_tiled_matrix_t *pIODesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_IO).parsec_desc; + parsec_tiled_matrix_t *pPDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_P).parsec_desc; + parsec_tiled_matrix_t *pDDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_D).parsec_desc; + parsec_tiled_matrix_t *pADesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_A).parsec_desc; + int f_desc_M = pFDataDesc->mb; + int ep_desc_N = pEPDesc->nb; + int et1_desc_M = pET1Desc->mb; + int et2_desc_M = pET2Desc->mb; + int p_desc_N = pPDesc->nb; + int flmt_desc_M = pFLMTDesc->mb; + int nodes = aConfigurations.GetCoresNumber(); + int flmt_desc_nb = (flmt_desc_M / nodes % L) ? flmt_desc_M / nodes / L + 1 : flmt_desc_M / nodes / L; + + int N = aConfigurations.GetProblemSize(); + int NT = (N % L == 0) ? (N/L) : (N/L + 1); + double upper_lower = EXAGEOSTAT_LOWER; + ForwardSHTReshape((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), rank, verbose, pFDataDesc, pFLMDesc, + pFLMTDesc, pET1Desc, pET2Desc, pEPDesc, pSLMNDesc, pIEDesc, pIODesc, pPDesc, + pDDesc, pADesc, f_desc_M, ep_desc_N, et1_desc_M, et2_desc_M, p_desc_N, flmt_desc_nb, t, L, &ExaGeoStatHardware::GetHicmaParams()->norm_global, NT, upper_lower); + SYNC_TIME_PRINT(ExaGeoStatHardware::GetParsecMPIRank(), ("Forward SHT Reshape\n")); + } -template -static void InverseSHT(Configurations &aConfigurations, std::unique_ptr> &aData){ +template void DataTransformer::InverseSphericalHarmonicsTransform(const int &aLSize, std::unique_ptr> &aData){ + + SYNC_TIME_START(); + parsec_tiled_matrix_t *pFSpatialDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_F_SPATIAL).parsec_desc; + parsec_tiled_matrix_t *pFLMDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_FLM).parsec_desc; + parsec_tiled_matrix_t *pZLMDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ZLM).parsec_desc; + parsec_tiled_matrix_t *pSCDesc = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_SC).parsec_desc; + InverseSHT((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pFSpatialDesc, pFLMDesc, pZLMDesc, pSCDesc, aLSize); + SYNC_TIME_PRINT(ExaGeoStatHardware::GetParsecMPIRank(), ("Inverse SHT\n")); } diff --git a/src/data-units/CMakeLists.txt b/src/data-units/CMakeLists.txt index 43a185ae..d7de6d14 100644 --- a/src/data-units/CMakeLists.txt +++ b/src/data-units/CMakeLists.txt @@ -9,10 +9,8 @@ # @author Sameh Abdulah # @date 2023-02-27 -if (RUNTIME_TYPE STREQUAL "STARPU") - # Include the concrete implementations of the ExaGeoStat Descriptor class - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/descriptor) -endif() +# Include the concrete implementations of the ExaGeoStat Descriptor class +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/descriptor) # Initialize SOURCES variable if not already initialized set(SOURCES diff --git a/src/data-units/DescriptorData.cpp b/src/data-units/DescriptorData.cpp index 34efa842..70f79b0b 100644 --- a/src/data-units/DescriptorData.cpp +++ b/src/data-units/DescriptorData.cpp @@ -21,14 +21,14 @@ using namespace exageostat::dataunits::descriptor; template DescriptorData::~DescriptorData() { -#if DEFAULT_RUNTIME - ExaGeoStatDescriptor exaGeoStatDescriptor; + ExaGeoStatDescriptor exageostat_descriptor; // Destroy descriptors. const std::string &chameleon = "_CHAMELEON"; for (const auto &pair: this->mDictionary) { const std::string &key = pair.first; +#if DEFAULT_RUNTIME if (key.find("CHAMELEON") != std::string::npos && pair.second != nullptr) { - exaGeoStatDescriptor.DestroyDescriptor(CHAMELEON_DESCRIPTOR, pair.second); + exageostat_descriptor.DestroyDescriptor(CHAMELEON_DESCRIPTOR, pair.second); #ifdef USE_HICMA // Since there are converted descriptors from Chameleon to Hicma, which have the same memory address. // So, by deleting the owner which is Chameleon, no need to delete hicma. Therefore, we remove the row of that descriptor. @@ -41,10 +41,20 @@ DescriptorData::~DescriptorData() { } #endif } else if (key.find("HICMA") != std::string::npos && pair.second != nullptr) { - exaGeoStatDescriptor.DestroyDescriptor(HICMA_DESCRIPTOR, pair.second); + exageostat_descriptor.DestroyDescriptor(HICMA_DESCRIPTOR, pair.second); } +#else + if (key.find("PARSEC") != std::string::npos && pair.second != nullptr) { + if(key == "DESCRIPTOR_FLMT_PARSEC") { + continue; + } + exageostat_descriptor.DestroyDescriptor(PARSEC_DESCRIPTOR, pair.second); + } +#endif + } this->mDictionary.clear(); +#if DEFAULT_RUNTIME if (this->mpSequence) { CHAMELEON_Sequence_Destroy((RUNTIME_sequence_t *) this->mpSequence); } @@ -123,6 +133,14 @@ DescriptorData::GetDescriptor(const DescriptorType &aDescriptorType, const De throw std::runtime_error("To use HiCMA descriptor you need to enable USE_HICMA!"); #endif } +#else + if (aDescriptorType == PARSEC_DESCRIPTOR) { + if (this->mDictionary.find(GetDescriptorName(aDescriptorName) + "_PARSEC") == this->mDictionary.end()) { + descriptor.parsec_desc = nullptr; + } + descriptor.parsec_desc = (parsec_matrix_block_cyclic_t *) this->mDictionary[GetDescriptorName(aDescriptorName) + + "_PARSEC"]; + } #endif return descriptor; } @@ -136,18 +154,18 @@ void DescriptorData::SetDescriptor(const DescriptorType &aDescriptorType, con void *descriptor; std::string type; - ExaGeoStatDescriptor exaGeoStatDescriptor; + ExaGeoStatDescriptor exageostat_descriptor; #if DEFAULT_RUNTIME if (aDescriptorType == CHAMELEON_DESCRIPTOR) { - descriptor = exaGeoStatDescriptor.CreateDescriptor((CHAM_desc_t *) descriptor, aDescriptorType, aIsOOC, + descriptor = exageostat_descriptor.CreateDescriptor((CHAM_desc_t *) descriptor, aDescriptorType, aIsOOC, apMatrix, aFloatPoint, aMB, aNB, aSize, aLM, aLN, aI, aJ, aM, aN, aP, aQ, aValidOOC); type = "_CHAMELEON"; } else { #ifdef USE_HICMA - descriptor = exaGeoStatDescriptor.CreateDescriptor((HICMA_desc_t *) descriptor, aDescriptorType, aIsOOC, + descriptor = exageostat_descriptor.CreateDescriptor((HICMA_desc_t *) descriptor, aDescriptorType, aIsOOC, apMatrix, aFloatPoint, aMB, aNB, aSize, aLM, aLN, aI, aJ, aM, aN, aP, aQ, aValidOOC); type = "_HICMA"; @@ -155,12 +173,21 @@ void DescriptorData::SetDescriptor(const DescriptorType &aDescriptorType, con throw std::runtime_error("To create HiCMA descriptor you need to enable USE_HICMA!"); #endif } - if (aConverted) { type = "_CHAM_HIC"; } - this->mDictionary[GetDescriptorName(aDescriptorName) + type] = descriptor; +#else + if (aDescriptorType == PARSEC_DESCRIPTOR) { + descriptor = exageostat_descriptor.CreateDescriptor((parsec_matrix_block_cyclic_t *) descriptor, aDescriptorType, aIsOOC, + apMatrix, aFloatPoint, aMB, aNB, aSize, aLM, aLN, aI, aJ, aM, + aN, aP, aQ, aValidOOC); + type = "_PARSEC"; + } + else { + throw std::runtime_error("While using PaRSEC as a runtime, only PaRSEC descriptors are enabled!"); + } #endif + this->mDictionary[GetDescriptorName(aDescriptorName) + type] = descriptor; } template @@ -293,6 +320,36 @@ std::string DescriptorData::GetDescriptorName(const DescriptorName &aDescript return "DESCRIPTOR_R"; case DESCRIPTOR_R_COPY : return "DESCRIPTOR_R_COPY"; + case DESCRIPTOR_F_DATA: + return "DESCRIPTOR_F_DATA"; + case DESCRIPTOR_ET1: + return "DESCRIPTOR_ET1"; + case DESCRIPTOR_ET2: + return "DESCRIPTOR_ET2"; + case DESCRIPTOR_EP: + return "DESCRIPTOR_EP"; + case DESCRIPTOR_SLMN: + return "DESCRIPTOR_SLMN"; + case DESCRIPTOR_IE: + return "DESCRIPTOR_IE"; + case DESCRIPTOR_IO: + return "DESCRIPTOR_IO"; + case DESCRIPTOR_P: + return "DESCRIPTOR_P"; + case DESCRIPTOR_D: + return "DESCRIPTOR_D"; + case DESCRIPTOR_FLMERA: + return "DESCRIPTOR_FLMERA"; + case DESCRIPTOR_ZLM: + return "DESCRIPTOR_ZLM"; + case DESCRIPTOR_SC: + return "DESCRIPTOR_SC"; + case DESCRIPTOR_F_SPATIAL: + return "DESCRIPTOR_F_SPATIAL"; + case DESCRIPTOR_FLM: + return "DESCRIPTOR_FLM"; + case DESCRIPTOR_FLMT: + return "DESCRIPTOR_FLMT"; default: throw std::invalid_argument( "The name of descriptor you provided is undefined, Please read the user manual to know the available descriptors"); diff --git a/src/data-units/descriptor/CMakeLists.txt b/src/data-units/descriptor/CMakeLists.txt index 608bbf07..352aec33 100644 --- a/src/data-units/descriptor/CMakeLists.txt +++ b/src/data-units/descriptor/CMakeLists.txt @@ -10,9 +10,7 @@ # @date 2023-08-15 # Include the concrete implementations of the ExaGeoStat Descriptor class -if (RUNTIME_TYPE STREQUAL "STARPU") - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/concrete) -endif () +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/concrete) set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/ExaGeoStatDescriptor.cpp diff --git a/src/data-units/descriptor/ExaGeoStatDescriptor.cpp b/src/data-units/descriptor/ExaGeoStatDescriptor.cpp index 5d6cd730..829684b3 100644 --- a/src/data-units/descriptor/ExaGeoStatDescriptor.cpp +++ b/src/data-units/descriptor/ExaGeoStatDescriptor.cpp @@ -15,12 +15,16 @@ #include #include + +#if DEFAULT_RUNTIME + #include #ifdef USE_HICMA - #include - +#endif +#else +#include #endif using namespace exageostat::common; @@ -28,34 +32,49 @@ using namespace exageostat::dataunits::descriptor; template void * -ExaGeoStatDescriptor::CreateDescriptor(void *apDescriptor, const common::DescriptorType &aDescriptorType, - const bool &aIsOOC, void *apMatrix, const common::FloatPoint &aFloatPoint, +ExaGeoStatDescriptor::CreateDescriptor(void *apDescriptor, const DescriptorType &aDescriptorType, + const bool &aIsOOC, void *apMatrix, const FloatPoint &aFloatPoint, const int &aMB, const int &aNB, const int &aSize, const int &aLM, const int &aLN, const int &aI, const int &aJ, const int &aM, const int &aN, const int &aP, const int &aQ, const bool &aValidOOC) { +#if DEFAULT_RUNTIME if (aDescriptorType == CHAMELEON_DESCRIPTOR) { return ChameleonDescriptor::CreateChameleonDescriptor(apDescriptor, aIsOOC, apMatrix, aFloatPoint, aMB, aNB, aSize, aLM, aLN, aI, aJ, aM, aN, aP, aQ, aValidOOC); - } else if (aDescriptorType == HICMA_DESCRIPTOR) { + } #ifdef USE_HICMA + if (aDescriptorType == HICMA_DESCRIPTOR) { return HicmaDescriptor::CreateHicmaDescriptor(apDescriptor, aIsOOC, apMatrix, aFloatPoint, aMB, aNB, aSize, aLM, aLN, aI, aJ, aM, aN, aP, aQ, aValidOOC); + } #endif +#else + if (aDescriptorType == PARSEC_DESCRIPTOR) { + return ParsecDescriptor::CreateParsecDescriptor(apDescriptor); } +#endif std::cerr << "Error, please select the correct descriptor type!" << std::endl; return nullptr; } template int ExaGeoStatDescriptor::DestroyDescriptor(const DescriptorType &aDescriptorType, void *apDesc) { + +#if DEFAULT_RUNTIME if (aDescriptorType == CHAMELEON_DESCRIPTOR) { return ChameleonDescriptor::DestroyChameleonDescriptor(apDesc); - } else if (aDescriptorType == HICMA_DESCRIPTOR) { + } #ifdef USE_HICMA + if (aDescriptorType == HICMA_DESCRIPTOR) { return HicmaDescriptor::DestroyHicmaDescriptor(apDesc); + } #endif +#else + if (aDescriptorType == PARSEC_DESCRIPTOR) { + return ParsecDescriptor::DestroyParsecDescriptor(apDesc); } +#endif std::cerr << "Error, please select the correct descriptor type!" << std::endl; return -1; } \ No newline at end of file diff --git a/src/data-units/descriptor/concrete/CMakeLists.txt b/src/data-units/descriptor/concrete/CMakeLists.txt index 6bb197d4..961cd150 100644 --- a/src/data-units/descriptor/concrete/CMakeLists.txt +++ b/src/data-units/descriptor/concrete/CMakeLists.txt @@ -12,14 +12,20 @@ # @date 2023-03-20 # Include the concrete implementations of the Descriptor class based on the enabled libraries (HiCMA or Chameleon) -set(SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/ChameleonDescriptor.cpp - ${SOURCES} - ) - -if (USE_HICMA) - list(APPEND SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/HicmaDescriptor.cpp +if (RUNTIME_TYPE STREQUAL "STARPU") + set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/ChameleonDescriptor.cpp + ${SOURCES} + ) + if (USE_HICMA) + list(APPEND SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/HicmaDescriptor.cpp + ) + endif () +else () + set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/ParsecDescriptor.cpp + ${SOURCES} ) endif () diff --git a/src/data-units/descriptor/concrete/ParsecDescriptor.cpp b/src/data-units/descriptor/concrete/ParsecDescriptor.cpp new file mode 100644 index 00000000..63ac2283 --- /dev/null +++ b/src/data-units/descriptor/concrete/ParsecDescriptor.cpp @@ -0,0 +1,34 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ParsecDescriptor.cpp + * @brief Defines the ParsecDescriptor class for creating matrix descriptors using the PaRSEC library. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @author Qinglei Cao + * @date 2024-10-18 +**/ + +#include + +using namespace exageostat::dataunits::descriptor; + +template +parsec_matrix_block_cyclic_t * +ParsecDescriptor::CreateParsecDescriptor(void *apDescriptor) { + + parsec_matrix_block_cyclic_t *parsec_desc = new parsec_matrix_block_cyclic_t(); + return parsec_desc; +} + +template +int ParsecDescriptor::DestroyParsecDescriptor(void *apDesc) { + auto Parsec_desc = (parsec_matrix_block_cyclic_t *) apDesc; + parsec_data_free(Parsec_desc->mat); + parsec_tiled_matrix_destroy((parsec_tiled_matrix_t *) Parsec_desc); + return 0; +} \ No newline at end of file diff --git a/src/hardware/ExaGeoStatHardware.cpp b/src/hardware/ExaGeoStatHardware.cpp index d17631aa..d09105ad 100644 --- a/src/hardware/ExaGeoStatHardware.cpp +++ b/src/hardware/ExaGeoStatHardware.cpp @@ -22,7 +22,7 @@ #include #include #else -#include +#include #endif #include @@ -83,16 +83,15 @@ ExaGeoStatHardware::ExaGeoStatHardware(exageostat::configurations::Configuration int iparam[IPARAM_SIZEOF] = {0}; double dparam[DPARAM_SIZEOF]; char *cparam[CPARAM_SIZEOF]; - hicma_parsec_params_t params; - starsh_params_t params_kernel; - hicma_parsec_data_t data; - hicma_parsec_matrix_analysis_t analysis; - this->mpParsecContext = hicma_parsec_init( new_argc, new_argv, iparam, dparam, cparam, ¶ms, ¶ms_kernel, &data ); -#endif + this->mpHicmaParams = make_unique(); + this->mpParamsKernel = make_unique(); + this->mpHicmaData = make_unique(); + this->mpAnalysis = make_unique(); - LOGGER("Climate Emulator Parameters") - LOGGER("L: " << t << "\tT: " << J << "\tNB: " << t << "\tgpus: " << g) - LOGGER("nodes: " << c << "\ttime_slot_per_file: " << time_slot_per_file << "\tnum_file: " << num_file << "\tfile_per_node: " << ((num_file%c)? num_file/c+1 : num_file/c)) + this->mpParsecContext = hicma_parsec_init(new_argc, new_argv, iparam, dparam, cparam, this->mpHicmaParams.get(), this->mpParamsKernel.get(), this->mpHicmaData.get()); + SetParsecMPIRank(this->mpHicmaParams->rank); +#endif + exageostat::helpers::CommunicatorMPI::GetInstance()->SetHardwareInitialization(); } ExaGeoStatHardware::ExaGeoStatHardware(const Computation &aComputation, const int &aCoreNumber, const int &aGpuNumber, @@ -156,27 +155,35 @@ void ExaGeoStatHardware::InitHardware(const Computation &aComputation, const int void ExaGeoStatHardware::FinalizeHardware() { - #if DEFAULT_RUNTIME +#if DEFAULT_RUNTIME // finalize hardware using HiCMA -#ifdef USE_HICMA + #ifdef USE_HICMA if (mpHicmaContext) { HICMA_Finalize(); mpHicmaContext = nullptr; } -#endif + #endif // finalize hardware using Chameleon if (mpChameleonContext) { -#if defined(USE_MPI) && defined(USE_HICMA) + #if defined(USE_MPI) && defined(USE_HICMA) // Since already HiCMA do so, then no need to remove empty cache. starpu_mpi_cache_set(0); -#endif + #endif CHAMELEON_Finalize() mpChameleonContext = nullptr; } +#else + if (mpParsecContext) { -#endif + int iparam[IPARAM_SIZEOF] = {0}; + double dparam[DPARAM_SIZEOF]; + char *cparam[CPARAM_SIZEOF]; + hicma_parsec_fini((parsec_context_t *) mpParsecContext, 0, NULL, iparam, dparam, cparam, this->mpHicmaParams.get(), this->mpParamsKernel.get(), this->mpHicmaData.get(), this->mpAnalysis.get()); + mpParsecContext = nullptr; + } +#endif exageostat::helpers::CommunicatorMPI::GetInstance()->RemoveHardwareInitialization(); } @@ -217,6 +224,14 @@ void *ExaGeoStatHardware::GetContext(Computation aComputation) { return nullptr; } +void ExaGeoStatHardware::SetParsecMPIRank(int aRank){ + mParsecMPIRank = aRank; +} + +int ExaGeoStatHardware::GetParsecMPIRank() { + return mParsecMPIRank; +} + int ExaGeoStatHardware::GetPGrid() { return mPGrid; } @@ -233,9 +248,34 @@ void ExaGeoStatHardware::SetQGrid(int aQ) { mQGrid = aQ; } +#if !DEFAULT_RUNTIME +hicma_parsec_params_t* ExaGeoStatHardware::GetHicmaParams() { + return mpHicmaParams.get(); +} + +starsh_params_t* ExaGeoStatHardware::GetParamsKernel() { + return mpParamsKernel.get(); +} + +hicma_parsec_data_t* ExaGeoStatHardware::GetHicmaData() { + return mpHicmaData.get(); +} + +hicma_parsec_matrix_analysis_t* ExaGeoStatHardware::GetAnalysis() { + return mpAnalysis.get(); +} +#endif + void *ExaGeoStatHardware::mpChameleonContext = nullptr; void *ExaGeoStatHardware::mpHicmaContext = nullptr; void *ExaGeoStatHardware::mpParsecContext = nullptr; +int ExaGeoStatHardware::mParsecMPIRank = 0; int ExaGeoStatHardware::mPGrid = 1; int ExaGeoStatHardware::mQGrid = 1; bool ExaGeoStatHardware::mIsMPIInit = false; +#if !DEFAULT_RUNTIME +unique_ptr ExaGeoStatHardware::mpHicmaParams = nullptr; +unique_ptr ExaGeoStatHardware::mpParamsKernel = nullptr; +unique_ptr ExaGeoStatHardware::mpHicmaData = nullptr; +unique_ptr ExaGeoStatHardware::mpAnalysis = nullptr; +#endif \ No newline at end of file diff --git a/src/helpers/CommunicatorMPI.cpp b/src/helpers/CommunicatorMPI.cpp index b4227e26..b2d6b891 100644 --- a/src/helpers/CommunicatorMPI.cpp +++ b/src/helpers/CommunicatorMPI.cpp @@ -10,11 +10,13 @@ * @author Sameh Abdulah * @date 2023-11-10 **/ - +#include #include #if DEFAULT_RUNTIME #include #endif +#include + using namespace exageostat::helpers; CommunicatorMPI *CommunicatorMPI::GetInstance() { @@ -33,6 +35,10 @@ int CommunicatorMPI::GetRank() const { else { return CHAMELEON_Comm_rank(); } + #else + else { + return ExaGeoStatHardware::GetParsecMPIRank(); + } #endif #endif return 0; diff --git a/src/linear-algebra-solvers/LinearAlgebraFactory.cpp b/src/linear-algebra-solvers/LinearAlgebraFactory.cpp index 5a1fef26..0d72dbad 100644 --- a/src/linear-algebra-solvers/LinearAlgebraFactory.cpp +++ b/src/linear-algebra-solvers/LinearAlgebraFactory.cpp @@ -15,14 +15,13 @@ #include -#if DEFAULT_RUNTIME #include #include #ifdef USE_HICMA + #include -#endif #endif @@ -32,7 +31,6 @@ using namespace exageostat::common; template std::unique_ptr> LinearAlgebraFactory::CreateLinearAlgebraSolver(Computation aComputation) { -#if DEFAULT_RUNTIME // Check the used Linear Algebra solver library, whether it's HiCMA or Chameleon. if (aComputation == EXACT_DENSE) { @@ -51,7 +49,6 @@ std::unique_ptr> LinearAlgebraFactory::CreateLinearAl return std::make_unique>(); } -#endif // Return nullptr if no computation is selected throw std::runtime_error("You need to enable whether HiCMA or Chameleon"); } diff --git a/src/linear-algebra-solvers/LinearAlgebraMethods.cpp b/src/linear-algebra-solvers/LinearAlgebraMethods.cpp index 8a083d72..31931325 100644 --- a/src/linear-algebra-solvers/LinearAlgebraMethods.cpp +++ b/src/linear-algebra-solvers/LinearAlgebraMethods.cpp @@ -22,7 +22,6 @@ #include #include -#include using namespace std; @@ -1340,6 +1339,37 @@ LinearAlgebraMethods::ExaGeoStatGetZObs(Configurations &aConfigurations, T *a this->ExaGeoStatDesc2Lap(apZ, aSize, z_desc, UpperLower::EXAGEOSTAT_UPPER_LOWER); } +#ifdef USE_HICMA + +template +void LinearAlgebraMethods::CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, + const common::CopyDirection &aDirection) { + auto *z = new T[aSize]; + int status; + if (aDirection == common::CHAMELEON_TO_HICMA) { + status = CHAMELEON_Desc2Lap((cham_uplo_t) EXAGEOSTAT_UPPER_LOWER, (CHAM_desc_t *) apSourceDesc, z, aSize); + if (status != CHAMELEON_SUCCESS) { + throw std::runtime_error("CHAMELEON_Desc2Lap Failed!"); + } + status = HICMA_Lapack_to_Tile(z, aSize, (HICMA_desc_t *) apDestinationDesc); + if (status != HICMA_SUCCESS) { + throw std::runtime_error("HICMA_Lapack_to_Tile Failed!"); + } + } else if (aDirection == common::HICMA_TO_CHAMELEON) { + status = HICMA_Tile_to_Lapack((HICMA_desc_t *) apSourceDesc, z, aSize); + if (status != HICMA_SUCCESS) { + throw std::runtime_error("HICMA_Tile_to_Lapack Failed!"); + } + status = CHAMELEON_Lap2Desc((cham_uplo_t) EXAGEOSTAT_UPPER_LOWER, z, aSize, (CHAM_desc_t *) apDestinationDesc); + if (status != CHAMELEON_SUCCESS) { + throw std::runtime_error("CHAMELEON_Lap2Desc Failed!"); + } + } + delete[] z; +} + +#endif + template void LinearAlgebraMethods::ExaGeoStatDesc2Lap(T *apA, const int &aLDA, void *apDescA, const UpperLower &aUpperLower) { diff --git a/src/linear-algebra-solvers/concrete/CMakeLists.txt b/src/linear-algebra-solvers/concrete/CMakeLists.txt index f1989e2b..e0017fb7 100644 --- a/src/linear-algebra-solvers/concrete/CMakeLists.txt +++ b/src/linear-algebra-solvers/concrete/CMakeLists.txt @@ -25,11 +25,6 @@ if (RUNTIME_TYPE STREQUAL "STARPU") ${CMAKE_CURRENT_SOURCE_DIR}/tlr/HicmaImplementation.cpp ) endif () -elseif (RUNTIME_TYPE STREQUAL "PARSEC") - set(SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/parsec/ParsecImplementation.cpp - ${SOURCES} - ) endif () set(SOURCES ${SOURCES} PARENT_SCOPE) diff --git a/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp b/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp index 5c3dd8ef..8ec6abe8 100644 --- a/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp +++ b/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp @@ -33,9 +33,9 @@ using namespace exageostat::configurations; using namespace exageostat::linearAlgebra; template -T ChameleonImplementation::ModelingOperations(std::unique_ptr > &aData, - configurations::Configurations &aConfigurations, const double *theta, - T *apMeasurementsMatrix, const kernels::Kernel &aKernel) { +T ChameleonImplementation::ExaGeoStatMLETile(std::unique_ptr> &aData, + configurations::Configurations &aConfigurations, const double *theta, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) { if (!aData->GetDescriptorData()->GetIsDescriptorInitiated()) { this->InitiateDescriptors(aConfigurations, *aData->GetDescriptorData(), aKernel.GetVariablesNumber(), @@ -361,34 +361,3 @@ void ChameleonImplementation::ExaGeoStatCreateSequence(void *apSequence) { throw std::runtime_error("CHAMELEON_Sequence_Create Failed!"); } } - -template -void ChameleonImplementation::CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, - const common::CopyDirection &aDirection) { - -} - -template -void -ChameleonImplementation::ExaGeoStatSYRK(Configurations &aConfigurations, unique_ptr > &aData) { - -} - -template -void ChameleonImplementation::ExaGeoStatTLRCholesky(Configurations &aConfigurations, - unique_ptr > &aData) { - -} - -template -void -ChameleonImplementation::ExaGeoStatNorm(Configurations &aConfigurations, unique_ptr > &aData) { - -} - -template -double -ChameleonImplementation::CalculateMSE(Configurations &aConfigurations, unique_ptr > &aData) { - - return 0; -} \ No newline at end of file diff --git a/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp b/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp index f5f843a7..f08c8c3b 100644 --- a/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp +++ b/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp @@ -15,7 +15,6 @@ #include #include -#include using namespace std; diff --git a/src/linear-algebra-solvers/concrete/parsec/ParsecImplementation.cpp b/src/linear-algebra-solvers/concrete/parsec/ParsecImplementation.cpp deleted file mode 100644 index 60a5f8fd..00000000 --- a/src/linear-algebra-solvers/concrete/parsec/ParsecImplementation.cpp +++ /dev/null @@ -1,90 +0,0 @@ - -// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, -// All rights reserved. -// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). - -/** - * @file ParsecImplementation.cpp - * @brief This file contains the implementation of ParsecImplementation class. - * @details ParsecImplementation is a concrete implementation of the LinearAlgebraMethods class. - * @version 2.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @date 2024-10-15 -**/ - -#include - -using namespace exageostat::linearAlgebra; -using namespace exageostat::configurations; - -template -void ParsecImplementation::ExaGeoStatSYRK(Configurations &aConfigurations, std::unique_ptr> &aData){ - -} - -template -void ParsecImplementation::ExaGeoStatTLRCholesky(Configurations &aConfigurations, std::unique_ptr> &aData){ - -} - -template -void -ParsecImplementation::ExaGeoStatNorm(Configurations &aConfigurations, std::unique_ptr> &aData) { - -} - -template -double -ParsecImplementation::CalculateMSE(Configurations &aConfigurations, std::unique_ptr> &aData) { - - return 0; -} - -template -T ParsecImplementation::ModelingOperations(std::unique_ptr> &aData, - configurations::Configurations &aConfigurations, const double *apTheta, - T *apMeasurementsMatrix, const kernels::Kernel &aKernel) { - -} - -template -void ParsecImplementation::ExaGeoStatLapackCopyTile(const common::UpperLower &aUpperLower, void *apA, void *apB) { - -} - - -template -void ParsecImplementation::ExaGeoStatSequenceWait(void *apSequence) { - -} - - -template -void ParsecImplementation::ExaGeoStatCreateSequence(void *apSequence) { - -} - - -template -void -ParsecImplementation::ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, void *apCD, - void *apCrk, const int &aMaxRank, const int &aAcc) { - -} - - -template -void ParsecImplementation::ExaGeoStatTrsmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, - const common::Trans &aTrans, const common::Diag &aDiag, - const T &aAlpha, void *apA, void *apCD, void *apCrk, void *apZ, - const int &aMaxRank) { - -} - - -template -void ParsecImplementation::CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, - const common::CopyDirection &aDirection) { - -} \ No newline at end of file diff --git a/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp b/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp index a466ea4e..c297bb01 100644 --- a/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp +++ b/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp @@ -31,15 +31,14 @@ using namespace exageostat::dataunits; using namespace exageostat::kernels; using namespace exageostat::helpers; using namespace exageostat::results; -using namespace exageostat::configurations; int store_only_diagonal_tiles = 1; int use_scratch = 1; int global_check = 0; //used to create dense matrix for accuracy check template -void HicmaImplementation::SetModelingDescriptors(std::unique_ptr > &aData, - Configurations &aConfigurations, const int &aP) { +void HicmaImplementation::SetModelingDescriptors(std::unique_ptr> &aData, + configurations::Configurations &aConfigurations, const int &aP) { int full_problem_size = aConfigurations.GetProblemSize() * aP; int lts = aConfigurations.GetLowTileSize(); @@ -115,9 +114,9 @@ void HicmaImplementation::SetModelingDescriptors(std::unique_ptr -T HicmaImplementation::ModelingOperations(std::unique_ptr > &aData, - Configurations &aConfigurations, const double *theta, - T *apMeasurementsMatrix, const Kernel &aKernel) { +T HicmaImplementation::ExaGeoStatMLETile(std::unique_ptr> &aData, + configurations::Configurations &aConfigurations, const double *theta, + T *apMeasurementsMatrix, const Kernel &aKernel) { if (!aData->GetDescriptorData()->GetIsDescriptorInitiated()) { this->InitiateDescriptors(aConfigurations, *aData->GetDescriptorData(), aKernel.GetVariablesNumber(), @@ -403,55 +402,3 @@ void HicmaImplementation::ExaGeoStatTrsmTile(const common::Side &aSide, const throw std::runtime_error("HICMA_dtrsmd_Tile Failed!"); } } - - -template -void HicmaImplementation::CopyDescriptors(void *apSourceDesc, void *apDestinationDesc, const int &aSize, - const common::CopyDirection &aDirection) { - - auto *z = new T[aSize]; - int status; - if (aDirection == common::CHAMELEON_TO_HICMA) { - status = CHAMELEON_Desc2Lap((cham_uplo_t) EXAGEOSTAT_UPPER_LOWER, (CHAM_desc_t *) apSourceDesc, z, aSize); - if (status != CHAMELEON_SUCCESS) { - throw std::runtime_error("CHAMELEON_Desc2Lap Failed!"); - } - status = HICMA_Lapack_to_Tile(z, aSize, (HICMA_desc_t *) apDestinationDesc); - if (status != HICMA_SUCCESS) { - throw std::runtime_error("HICMA_Lapack_to_Tile Failed!"); - } - } else if (aDirection == common::HICMA_TO_CHAMELEON) { - status = HICMA_Tile_to_Lapack((HICMA_desc_t *) apSourceDesc, z, aSize); - if (status != HICMA_SUCCESS) { - throw std::runtime_error("HICMA_Tile_to_Lapack Failed!"); - } - status = CHAMELEON_Lap2Desc((cham_uplo_t) EXAGEOSTAT_UPPER_LOWER, z, aSize, (CHAM_desc_t *) apDestinationDesc); - if (status != CHAMELEON_SUCCESS) { - throw std::runtime_error("CHAMELEON_Lap2Desc Failed!"); - } - } - delete[] z; -} - - -template -void HicmaImplementation::ExaGeoStatSYRK(Configurations &aConfigurations, unique_ptr > &aData) { - -} - -template -void -HicmaImplementation::ExaGeoStatTLRCholesky(Configurations &aConfigurations, unique_ptr > &aData) { - -} - -template -void HicmaImplementation::ExaGeoStatNorm(Configurations &aConfigurations, unique_ptr > &aData) { - -} - -template -double HicmaImplementation::CalculateMSE(Configurations &aConfigurations, unique_ptr > &aData) { - - return 0; -} \ No newline at end of file diff --git a/src/runtime-solver/CMakeLists.txt b/src/runtime-solver/CMakeLists.txt new file mode 100644 index 00000000..17e296d0 --- /dev/null +++ b/src/runtime-solver/CMakeLists.txt @@ -0,0 +1,19 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 2.0.0 +# @brief CMake build script for the runtime-solvers library, which includes the RuntimeSolversMethods base class and the RuntimeSolversFactory +# @author Mahmoud ElKarargy +# @date 2024-11-04 + +# Include the concrete implementations of the RuntimeSolversMethods class +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/concrete) +# Define the sources for the library +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/RuntimeSolverFactory.cpp + ${SOURCES} + PARENT_SCOPE + ) diff --git a/src/runtime-solver/RuntimeSolverFactory.cpp b/src/runtime-solver/RuntimeSolverFactory.cpp new file mode 100644 index 00000000..1eed2ddc --- /dev/null +++ b/src/runtime-solver/RuntimeSolverFactory.cpp @@ -0,0 +1,36 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file RuntimeSolverFactory.cpp + * @brief Implementation of the RuntimeSolverFactory class for creating runtime solvers for different runtime systems using StarPU or PaRSEC libraries. + * The factory creates a unique pointer to a concrete implementation of the RuntimeSolverMethods class based on the runtime specified. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @date 2024-11-04 +**/ + +#include + +#if DEFAULT_RUNTIME +#include +#else +#include +#endif + +using namespace exageostat::runtimesolver; +using namespace exageostat::common; + +template +std::unique_ptr> RuntimeSolverFactory::CreateRuntimeSolver() { + + // Check which Runtime is used +#if DEFAULT_RUNTIME + return std::make_unique>(); +#else + return std::make_unique>(); +#endif + +} diff --git a/src/runtime-solver/concrete/CMakeLists.txt b/src/runtime-solver/concrete/CMakeLists.txt new file mode 100644 index 00000000..d3d75c77 --- /dev/null +++ b/src/runtime-solver/concrete/CMakeLists.txt @@ -0,0 +1,27 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 2.0.0 +# @brief CMake build script for the runtime-solvers library, which includes the concrete implementations of the +# RuntimeSolversMethods class based on the enabled runtime (StarPU or PaRSEC). +# @author Mahmoud ElKarargy +# @author Sameh Abdulah +# @date 2024-11-04 + +# Include the concrete implementations of the RuntimeSolversMethods class based on the enabled runtime (StarPU or PaRSEC) +if (RUNTIME_TYPE STREQUAL "STARPU") + set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/StarpuRuntimeSolver.cpp + ${SOURCES} + ) +elseif (RUNTIME_TYPE STREQUAL "PARSEC") + set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/ParsecRuntimeSolver.cpp; + ${SOURCES} + ) +endif () +set(SOURCES ${SOURCES} PARENT_SCOPE) + diff --git a/src/runtime-solver/concrete/ParsecRuntimeSolver.cpp b/src/runtime-solver/concrete/ParsecRuntimeSolver.cpp new file mode 100644 index 00000000..75410f18 --- /dev/null +++ b/src/runtime-solver/concrete/ParsecRuntimeSolver.cpp @@ -0,0 +1,105 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ParsecRuntimeSolver.cpp + * @brief This file contains the implementation of ParsecRuntimeSolver class. + * @details ParsecRuntimeSolver is a concrete implementation of the RuntimeSolversMethods class. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @author Qinglei Cao + * @date 2024-11-04 +**/ + +#include +#include +#include + +extern "C"{ +#include +} + +using namespace exageostat::common; +using namespace exageostat::configurations; +using namespace exageostat::analyzer; +using namespace exageostat::runtimesolver; + +template +void ParsecRuntimeSolver::ExaGeoStatSYRK(std::unique_ptr> &aData){ + auto* pContext = (parsec_context_t *) ExaGeoStatHardware::GetParsecContext(); + auto* pDesc_A = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(DescriptorType::PARSEC_DESCRIPTOR, DescriptorName::DESCRIPTOR_A).parsec_desc; + + SYNC_TIME_START(); + dplasma_dsyrk(pContext, dplasmaLower, dplasmaNoTrans, 1.0, pDesc_A, 0.0, (parsec_tiled_matrix_t *) &ExaGeoStatHardware::GetHicmaData()->dcA); + SYNC_TIME_PRINT(ExaGeoStatHardware::GetParsecMPIRank(),("SYRK\n")); +} + +template +void ParsecRuntimeSolver::ExaGeoStatTLRCholesky(std::unique_ptr> &aData){ + + auto *pParams = ExaGeoStatHardware::GetHicmaParams(); + auto *pHicma_data = ExaGeoStatHardware::GetHicmaData(); + auto *pAnalysis = ExaGeoStatHardware::GetAnalysis(); + auto *pContext = (parsec_context_t *) ExaGeoStatHardware::GetParsecContext(); + for( int i= 0; i < pParams->nruns; i++ ) { + hicma_parsec_potrf(pContext, pHicma_data, pParams, pAnalysis); + } +} + +template +double ParsecRuntimeSolver::ExaGeoStatNorm(Configurations &aConfigurations, std::unique_ptr> &aData){ + + int L = aConfigurations.GetDenseTileSize(); + int N = aConfigurations.GetProblemSize(); + double aNT = (N % L == 0) ? (N/L) : (N/L + 1); + int aUpperLower = EXAGEOSTAT_LOWER; + auto* pContext = (parsec_context_t *) ExaGeoStatHardware::GetParsecContext(); + auto* pDescA = (parsec_tiled_matrix_t *) aData->GetDescriptorData()->GetDescriptor(DescriptorType::PARSEC_DESCRIPTOR, DescriptorName::DESCRIPTOR_A).parsec_desc; + + SYNC_TIME_START(); + GetMatrixNorm(pContext, &ExaGeoStatHardware::GetHicmaParams()->norm_global, (parsec_tiled_matrix_t *) &ExaGeoStatHardware::GetHicmaData()->dcA, aNT, aUpperLower, 1); + SYNC_TIME_PRINT(ExaGeoStatHardware::GetParsecMPIRank(), ("Matrix norm: norm_global= %le\n", ExaGeoStatHardware::GetHicmaParams()->norm_global)); + return ExaGeoStatHardware::GetHicmaParams()->norm_global; +} + +template +double ParsecRuntimeSolver::CalculateMSE(Configurations &aConfigurations, std::unique_ptr> &aData) { + + auto* pContext = (parsec_context_t * )ExaGeoStatHardware::GetParsecContext(); + auto* pDesc_f_data = aData->GetDescriptorData()->GetDescriptor(DescriptorType::PARSEC_DESCRIPTOR, + DescriptorName::DESCRIPTOR_F_DATA).parsec_desc; + auto* pDesc_f_spatial = aData->GetDescriptorData()->GetDescriptor(DescriptorType::PARSEC_DESCRIPTOR, + DescriptorName::DESCRIPTOR_F_SPATIAL).parsec_desc; + + SYNC_TIME_START(); + auto mse_result = MeanSquaredError(pContext, pDesc_f_data, pDesc_f_spatial, aConfigurations.GetDenseTileSize()); + SYNC_TIME_PRINT(ExaGeoStatHardware::GetParsecMPIRank(),("mse\n")); + return mse_result; +} + +template +T ParsecRuntimeSolver::ModelingOperations(std::unique_ptr> &aData, Configurations &aConfigurations, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) { + + // SYRK + ExaGeoStatSYRK(aData); + // Calculate norm + ExaGeoStatNorm(aConfigurations, aData); + // Analyze matrix before Cholesky + DataAnalyzer::PreAnalyzeMatrix(aData); + // HiCMA Cholesky + ExaGeoStatTLRCholesky(aData); + // Analyze matrix after Cholesky + DataAnalyzer::PostAnalyzeMatrix(aData); + // Diff to matlab result + DataAnalyzer::CompareMatDifference(aData); + + if(aConfigurations.GetEnableInverse()){ + transformers::DataTransformer::InverseSphericalHarmonicsTransform(aConfigurations.GetDenseTileSize(), aData); + // TODO: results in a seg fault in C + CalculateMSE(aConfigurations, aData); + } +} diff --git a/src/runtime-solver/concrete/StarpuRuntimeSolver.cpp b/src/runtime-solver/concrete/StarpuRuntimeSolver.cpp new file mode 100644 index 00000000..39dae64c --- /dev/null +++ b/src/runtime-solver/concrete/StarpuRuntimeSolver.cpp @@ -0,0 +1,79 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file StarpuRuntimeSolver.cpp + * @brief This file contains the implementation of StarpuRuntimeSolver class. + * @details StarpuRuntimeSolver is a concrete implementation of the RuntimeSolversMethods class. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @author Qinglei Cao + * @date 2024-11-04 +**/ + +#include +#include +#include +#include + +using namespace exageostat::common; +using namespace exageostat::configurations; +using namespace exageostat::runtimesolver; +using namespace exageostat::dataunits; +using namespace nlopt; + +template +T StarpuRuntimeSolver::ModelingOperations(std::unique_ptr> &aData, Configurations &aConfigurations, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel) { + + int parameters_number = aKernel.GetParametersNumbers(); + int max_number_of_iterations = aConfigurations.GetMaxMleIterations(); + // Setting struct of data to pass to the modeling. + auto modeling_data = new mModelingData(aData, aConfigurations, *apMeasurementsMatrix, aKernel); + // Create nlopt + double opt_f; + opt optimizing_function(nlopt::LN_BOBYQA, parameters_number); + // Initialize problem's bound. + optimizing_function.set_lower_bounds(aConfigurations.GetLowerBounds()); + optimizing_function.set_upper_bounds(aConfigurations.GetUpperBounds()); + optimizing_function.set_ftol_abs(aConfigurations.GetTolerance()); + // Set max iterations value. + optimizing_function.set_maxeval(max_number_of_iterations); + optimizing_function.set_max_objective(DataModelingAPI, (void *) modeling_data); + + // Optimize mle using nlopt. + optimizing_function.optimize(aConfigurations.GetStartingTheta(), opt_f); + aConfigurations.SetEstimatedTheta(aConfigurations.GetStartingTheta()); + + auto theta = aConfigurations.GetStartingTheta(); + + LOGGER("--> Final Theta Values (", true) + for (int i = 0; i < parameters_number; i++) { + LOGGER_PRECISION(theta[i]) + if (i != parameters_number - 1) { + LOGGER_PRECISION(", ") + } + } + LOGGER_PRECISION(")") + LOGGER("") + + delete modeling_data; + return optimizing_function.last_optimum_value(); + +} + +template +double StarpuRuntimeSolver::DataModelingAPI(const std::vector &aTheta, std::vector &aGrad, void *apInfo) { + + auto config = ((mModelingData *) apInfo)->mpConfiguration; + auto data = ((mModelingData *) apInfo)->mpData; + auto measurements = ((mModelingData *) apInfo)->mpMeasurementsMatrix; + auto kernel = ((mModelingData *) apInfo)->mpKernel; + + // We do Date Modeling with any computation. + auto linear_algebra_solver = linearAlgebra::LinearAlgebraFactory::CreateLinearAlgebraSolver(config->GetComputation()); + return linear_algebra_solver->ExaGeoStatMLETile(*data, *config, aTheta.data(), measurements, *kernel); +} diff --git a/src/runtime/CMakeLists.txt b/src/runtime/CMakeLists.txt index e4d999e5..afeef659 100644 --- a/src/runtime/CMakeLists.txt +++ b/src/runtime/CMakeLists.txt @@ -12,6 +12,10 @@ # Include runtime directory,based on runtime flag. if ("${RUNTIME_TYPE}" STREQUAL "PARSEC") add_subdirectory(parsec) + set(JDF_GENERATED_SOURCES + ${JDF_GENERATED_SOURCES} + PARENT_SCOPE + ) else () #by default use StarPu runtime. add_subdirectory(starpu) @@ -22,4 +26,3 @@ set(SOURCES ${SOURCES} PARENT_SCOPE ) - diff --git a/src/runtime/parsec/CMakeLists.txt b/src/runtime/parsec/CMakeLists.txt index f1b427db..8c8e25a9 100644 --- a/src/runtime/parsec/CMakeLists.txt +++ b/src/runtime/parsec/CMakeLists.txt @@ -5,13 +5,24 @@ # @file CMakeLists.txt # @version 1.1.0 -# @brief CMake build script for Parsec runtime +# @brief CMake build script for Parsec directory. # @author Mahmoud ElKarargy # @date 2024-03-10 -# Define the sources for the library +# Add subdirectory for JDF files +add_subdirectory(jdf) + +# Set source files for ClimateEmulator set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/ParsecFunctions.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/JDFHelperFunctions.c ${SOURCES} PARENT_SCOPE - ) \ No newline at end of file +) + +# Set JDF generated source files for Climate Emulator +set(JDF_GENERATED_SOURCES + ${JDF_GENERATED_SOURCES} + PARENT_SCOPE +) + diff --git a/src/runtime/parsec/JDFHelperFunctions.c b/src/runtime/parsec/JDFHelperFunctions.c new file mode 100644 index 00000000..06b54135 --- /dev/null +++ b/src/runtime/parsec/JDFHelperFunctions.c @@ -0,0 +1,185 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file JDFHelperFunctions.c + * @brief Implementation of JDF helper functions. + * @version 2.0.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @author Qinglei Cao + * @date 2024-10-20 +**/ + +#include + +int CalculateSingleIndex(int aN, int aM) { + return aN * (aN + 1) / 2 + aM; +} + +double SumDoubleData(double *apData, int aColumn, int aRow) { + double sum = 0.0; + for (int j = 0; j < aRow; j++) { + for (int i = 0; i < aColumn; i++) { + sum += apData[j * aColumn + i]; + } + } + return sum; +} + +complex double SumComplexData(complex double *apData, int aColumn, int aRow) { + complex double sum = 0.0; + for (int j = 0; j < aRow; j++) { + for (int i = 0; i < aColumn; i++) { + sum += apData[j * aColumn + i]; + } + } + return sum; +} + +void ForwardSHTHelper(double *apFlm, complex double *apF_data, int aFDataM, int aFDataN, + complex double *apEt1, int aEt1M, complex double *apEt2, int aEt2M, + complex double *apEp, int aEpM, int aEpN, complex double *apSlmn, + int aSlmnM, int aSlmnN, complex double *apIe, int aIeM, int aIeN, + complex double *apIo, int aIoM, int aIoN, complex double *apP, + int aPM, int aPN, complex double *apD, complex double *apGmtheta_r, + complex double *apFmnm, complex double *apTmp1, + complex double *apTmp2, int aL){ + + complex double alpha_complex, beta_complex; + double alpha_double, beta_double; + + assert(aFDataN == aEpM); + alpha_complex = (complex double) 1.0; + beta_complex = (complex double) 0.0; + + int gmtheta_r_M = aFDataM; + int gmtheta_r_N = aEpN; + int gmtheta_r_K = aFDataN; + + cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, + gmtheta_r_M, gmtheta_r_N, gmtheta_r_K, + &alpha_complex, apF_data, gmtheta_r_M, + apEp, gmtheta_r_K, &beta_complex, + apGmtheta_r, gmtheta_r_M); + + int fmnm_M = aEt1M; + int fmnm_N = gmtheta_r_N; + int fmnm_K = gmtheta_r_M; + + cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, + fmnm_M, fmnm_N, fmnm_K, + &alpha_complex,apEt1, fmnm_M, + apGmtheta_r, fmnm_K, + &beta_complex, apFmnm, fmnm_M); + + int tmp1_M = aEt2M; + int tmp1_N = aPN; + int tmp1_K = aPM; + cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, + tmp1_M, tmp1_N, tmp1_K, + &alpha_complex, apEt2, tmp1_M, + apP, tmp1_K, + &beta_complex, apTmp1, tmp1_M); + + assert(tmp1_N == gmtheta_r_M); + int tmp2_M = tmp1_M; + int tmp2_N = gmtheta_r_N; + int tmp2_K = gmtheta_r_M; + + cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, + tmp2_M, tmp2_N, tmp2_K, + &alpha_complex, apTmp1, tmp2_M, + apGmtheta_r, tmp2_K, + &beta_complex, apTmp2, tmp2_M); + + assert(fmnm_M == tmp2_M); + fmnm_K = tmp2_N; + beta_complex = (complex double) 1.0; + cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, + fmnm_M, fmnm_N, fmnm_K, + &alpha_complex, apTmp2, fmnm_M, + apD, fmnm_K, + &beta_complex, apFmnm, fmnm_M); + + assert(aSlmnN == aIeM); + assert(aIeN == fmnm_M); + + int flmn_matrix_M = aL; + + complex double *pFlmn_matrix = apTmp1; + complex double *pFmnm_tmp; + complex double *pSlmn_tmp; + complex double *multipy_tmp = apTmp2 + fmnm_M + aSlmnN; + + for (int m = 0; m < aL; m++) { + pFmnm_tmp = apFmnm + (aL + m - 1) * fmnm_M; + if (0 == m % 2) { + for (int n = m; n < aL; n++) { + pSlmn_tmp = apSlmn + CalculateSingleIndex(n, m); + + alpha_complex = (complex double) 1.0; + beta_complex = (complex double) 0.0; + cblas_zgemv(CblasColMajor, CblasNoTrans, + aIeM, aIeN, + &alpha_complex, apIe, aIeM, + pFmnm_tmp, 1, + &beta_complex, multipy_tmp, 1); + cblas_zdotu_sub(aSlmnN, pSlmn_tmp, aSlmnM, multipy_tmp, 1, &pFlmn_matrix[m * flmn_matrix_M + n]); + } + } else { + for (int n = m; n < aL; n++) { + pSlmn_tmp = apSlmn + CalculateSingleIndex(n, m); + + alpha_complex = (complex double) 1.0; + beta_complex = (complex double) 0.0; + cblas_zgemv(CblasColMajor, CblasNoTrans, + aIoM, aIoN, + &alpha_complex, apIo, aIoM, + pFmnm_tmp, 1, + &beta_complex, multipy_tmp, 1); + + cblas_zdotu_sub(aSlmnN, pSlmn_tmp, aSlmnM, multipy_tmp, 1, &pFlmn_matrix[m * flmn_matrix_M + n]); + } + } + + } + for (int n = 0; n < aL; n++) { + for (int m = 0; m <= n; m++) { + apFlm[n * n + n + m] = creal(pFlmn_matrix[m * flmn_matrix_M + n]); + if (m != 0) { + apFlm[n * n + n - m] = cimag(pFlmn_matrix[m * flmn_matrix_M + n]); + } + } + } +} + +void InverseSHTHelper(double *apFlm, double *apFspatial, double *apZlm, double *apSC, double *apSmt, int aL) { + + int index_Zlm, index_flm; + int Smt_M = aL + 1; + int Smt_N = 2 * aL - 1; + + memset(apSmt, 0, Smt_M * Smt_N * sizeof(double)); + + for (int m = -(aL - 1); m < aL; m++) { + for (int n = abs(m); n < aL; n++) { + index_Zlm = CalculateSingleIndex(n, abs(m)); + index_flm = n * n + n + m; + cblas_daxpy(Smt_M, apFlm[index_flm], apZlm + index_Zlm * aL + 1, 1, apSmt + (m + aL - 1) * Smt_M, 1); + } + } + + int f_spatial_M = Smt_M; + int f_spatial_N = 2 * aL; + int f_spatial_K = Smt_N; + + cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, + f_spatial_M, f_spatial_N, f_spatial_K, + (double) 1.0, apSmt, f_spatial_M, + apSC, f_spatial_K, + (double) 0.0, apFspatial, f_spatial_M); + +} diff --git a/src/runtime/parsec/jdf/CMakeLists.txt b/src/runtime/parsec/jdf/CMakeLists.txt new file mode 100644 index 00000000..1463fb93 --- /dev/null +++ b/src/runtime/parsec/jdf/CMakeLists.txt @@ -0,0 +1,50 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 1.1.0 +# @brief CMake build script for jdf directory +# @author Mahmoud ElKarargy +# @date 2024-10-17 + +# Add .jdf files +set(JDF_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/ReadCSVTimeSlot.jdf + ${CMAKE_CURRENT_SOURCE_DIR}/ReadCSVComplex.jdf + ${CMAKE_CURRENT_SOURCE_DIR}/ReadCSVToComplex.jdf + ${CMAKE_CURRENT_SOURCE_DIR}/ReadCSVToComplexTimeSlot.jdf + ${CMAKE_CURRENT_SOURCE_DIR}/ReadCSV.jdf + ${CMAKE_CURRENT_SOURCE_DIR}/ForwardSHT.jdf + ${CMAKE_CURRENT_SOURCE_DIR}/MeanSquaredError.jdf + ${CMAKE_CURRENT_SOURCE_DIR}/DifferenceDouble.jdf + ${CMAKE_CURRENT_SOURCE_DIR}/ForwardSHTReshape.jdf + ${CMAKE_CURRENT_SOURCE_DIR}/GetMatrixNorm.jdf + ${CMAKE_CURRENT_SOURCE_DIR}/InverseSHT.jdf + ${CMAKE_CURRENT_SOURCE_DIR}/MatrixCompress.jdf +) + +# Output directory for generated sources +set(JDF_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated_jdf") + +# Make sure the output directory exists +file(MAKE_DIRECTORY ${JDF_OUTPUT_DIR}) + +foreach (jdf_file ${JDF_FILES}) + get_filename_component(jdf_name ${jdf_file} NAME_WE) + execute_process( + COMMAND ${HICMA_X_BIN_DIR}/parsec-ptgpp -i ${jdf_file} -o ${jdf_name} + ERROR_QUIET + ) + execute_process( + COMMAND mv ${jdf_name}.c ${CMAKE_CURRENT_BINARY_DIR}/generated_jdf/${jdf_name}.c + COMMAND mv ${jdf_name}.h ${CMAKE_CURRENT_BINARY_DIR}/generated_jdf/${jdf_name}.h + ) + list(APPEND JDF_GENERATED_SOURCES ${JDF_OUTPUT_DIR}/${jdf_name}.c) +endforeach () + +set(JDF_GENERATED_SOURCES + ${JDF_GENERATED_SOURCES} + PARENT_SCOPE +) diff --git a/src/runtime/parsec/jdf/DifferenceDouble.jdf b/src/runtime/parsec/jdf/DifferenceDouble.jdf new file mode 100644 index 00000000..76e49e79 --- /dev/null +++ b/src/runtime/parsec/jdf/DifferenceDouble.jdf @@ -0,0 +1,92 @@ +extern "C" %{ +/* + * @copyright (c) 2023 King Abdullah University of Science and Technology (KAUST). + * @copyright (c) 2023 The Universiy of Tennessee and The Universiy of Tennessee Research Foundation. + * All rights reserved. + */ + +#include +#include + +static double DifferenceDouble_core(double *apDataA, double *apDataB, int aM, int aN) { + double result = 0.0; + for (int j = 0; j < aN; j++) { + for (int i = 0; i < aM; i++) { + result = fmax(result, fabs(apDataA[j*aM+i]-apDataB[j*aM+i])); + if( result > 1.0e-4 ) { + return result; + } + } + } + return result; +} + +%} + +apDescA [ type = "parsec_tiled_matrix_t*" ] +apDescB [ type = "parsec_tiled_matrix_t*" aligned = apDescA ] + +task(m, n) + +m = 0 .. apDescA->lmt-1 +n = 0 .. apDescA->lnt-1 + +: apDescA(m, n) + +READ apDataA <- apDescA(m, n) +READ apDataB <- apDescB(m, n) + +BODY +{ + double diff = DifferenceDouble_core(apDataA, apDataB, apDescA->mb, apDescA->nb); +} +END + +extern "C" %{ + +/** + * @return the parsec object to schedule. + */ +parsec_taskpool_t* +DifferenceDoubleConstructor(parsec_matrix_block_cyclic_t *apDescA, parsec_matrix_block_cyclic_t *apDescB) +{ + assert(apDescA->super.mb == apDescB->super.mb); + assert(apDescA->super.nb == apDescB->super.nb); + parsec_DifferenceDouble_taskpool_t *taskpool = parsec_DifferenceDouble_new(&apDescA->super, &apDescB->super); + parsec_add2arena(&taskpool->arenas_datatypes[PARSEC_DifferenceDouble_DEFAULT_ADT_IDX], + parsec_datatype_double_t, PARSEC_MATRIX_FULL, + 1, apDescA->super.mb, apDescA->super.nb, apDescA->super.mb, + PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + return (parsec_taskpool_t*)taskpool; +} + +/** + * @param [inout] the parsec object to destroy +*/ +void DifferenceDouble_destructor(parsec_taskpool_t *pTaskpool) +{ + parsec_DifferenceDouble_taskpool_t *difference_double_taskpool = (parsec_DifferenceDouble_taskpool_t *)pTaskpool; + parsec_del2arena(&difference_double_taskpool->arenas_datatypes[PARSEC_DifferenceDouble_DEFAULT_ADT_IDX]); + parsec_taskpool_free(pTaskpool); +} + +/** + */ +int DifferenceDouble(parsec_context_t *apContext, + parsec_matrix_block_cyclic_t *apDescA, + parsec_matrix_block_cyclic_t *apDescB) +{ + parsec_taskpool_t *parsec_difference_double = NULL; + parsec_difference_double = DifferenceDoubleConstructor(apDescA, apDescB); + if(parsec_difference_double != NULL ){ + parsec_context_add_taskpool(apContext, parsec_difference_double); + parsec_context_start(apContext); + parsec_context_wait(apContext); + DifferenceDouble_destructor(parsec_difference_double); + } + + return 0; +} + +%} diff --git a/src/runtime/parsec/jdf/ForwardSHT.jdf b/src/runtime/parsec/jdf/ForwardSHT.jdf new file mode 100644 index 00000000..af674f1b --- /dev/null +++ b/src/runtime/parsec/jdf/ForwardSHT.jdf @@ -0,0 +1,290 @@ +extern "C" %{ +/* + * @copyright (c) 2023 King Abdullah University of Science and Technology (KAUST). + * @copyright (c) 2023 The Universiy of Tennessee and The Universiy of Tennessee Research Foundation. + * All rights reserved. + */ + +#include +#include + +static void FlmToFlmT(double *apFlmT, double *apFlm, parsec_matrix_block_cyclic_t *apFLMTDesc, int aFlmM, int aFlmN, int aM, int aN) { + int flm_offset = aM * apFLMTDesc->super.mb; + int flmT_offset = aN * apFLMTDesc->super.mb; + int size = (aM == apFLMTDesc->super.lmt - 1) ? (aFlmM * aFlmN) - flm_offset : apFLMTDesc->super.mb; + memcpy(apFlmT + flmT_offset, apFlm + flm_offset, size*sizeof(double)); +} + + +%} + +/* Globals + */ +apFDataDesc [ type = "parsec_tiled_matrix_t*" ] +apFLMDesc [ type = "parsec_tiled_matrix_t*" aligned = apFDataDesc] +apFLMTDesc [ type = "parsec_tiled_matrix_t*" ] +apET1Desc [ type = "parsec_tiled_matrix_t*" ] +apET2Desc [ type = "parsec_tiled_matrix_t*" ] +apEPDesc [ type = "parsec_tiled_matrix_t*" ] +apSLMNDesc [ type = "parsec_tiled_matrix_t*" ] +apIEDesc [ type = "parsec_tiled_matrix_t*" ] +apIODesc [ type = "parsec_tiled_matrix_t*" ] +apPDesc [ type = "parsec_tiled_matrix_t*" ] +apDDesc [ type = "parsec_tiled_matrix_t*" ] +aFlmM [ type = "int" ] +aFlmN [ type = "int" ] +aLSize [ type = "int" ] + +/* Temporary buffer used for convert */ +apGmtheta_r [ type = "parsec_memory_pool_t *" hidden = on default = NULL ] +apFmnm [ type = "parsec_memory_pool_t *" hidden = on default = NULL ] +apWork1 [ type = "parsec_memory_pool_t *" hidden = on default = NULL ] +apWork2 [ type = "parsec_memory_pool_t *" hidden = on default = NULL ] + +/* GPU workspace */ +ws_gpu [ type = "void *" hidden = on default = NULL ] + +/* GPU number and index */ +nb_cuda_devices [ type = "int" hidden = on default = 0 ] +cuda_device_index [ type = "int *" hidden = on default = "NULL"] + +bind_gpu(n) + +n = 0 .. apFDataDesc->lnt-1 + +: apFDataDesc(0, n) + +READ apFlm <- apFLMDesc(0, n) + -> apFlm task(n) [ type_remote = apFlm ] + +READ apF_data <- apFDataDesc(0, n) + -> apF_data task(n) [ type_remote = apF_data ] + + +BODY +{ +#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) || defined(PARSEC_HAVE_DEV_HIP_SUPPORT) + if( nb_cuda_devices > 0 ) { + int g = climate_emualtor_gpu_load_balance( n, gb->nodes, nb_cuda_devices ); + parsec_advise_data_on_device( _f_apFlm->original, + cuda_device_index[g], + PARSEC_DEV_DATA_ADVICE_PREFERRED_DEVICE ); + parsec_advise_data_on_device( _f_apF_data->original, + cuda_device_index[g], + PARSEC_DEV_DATA_ADVICE_PREFERRED_DEVICE ); + } +#endif +} +END + + + +task(n) + +n = 0 .. apFDataDesc->lnt-1 + +my_rank = %{ return apFDataDesc->super.rank_of(&apFDataDesc->super, 0, n); %} + +: apFDataDesc(0, n) + +// TODO: check whether this will evict apF_data first on GPU +READ apF_data <- apF_data bind_gpu(n) [ type_remote = apF_data ] +RW apFlm <- apFlm bind_gpu(n) [ type_remote = apFlm ] + -> apFlm task_apFlmT(0..apFLMTDesc->lmt-1, n) [ type_remote = apFlm ] + -> apFLMDesc(0, n) + +READ apEt1 <- apET1Desc(0, my_rank) +READ apEt2 <- apET2Desc(0, my_rank) +READ apEp <- apEPDesc(0, my_rank) +READ apSlmn <- apSLMNDesc(0, my_rank) +READ apIe <- apIEDesc(0, my_rank) +READ apIo <- apIODesc(0, my_rank) +READ apP <- apPDesc(0, my_rank) +READ apD <- apDDesc(0, my_rank) + + +BODY[type=CUDA] +{ +#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) + ForwardSHT_gpu_core(apFlm, apF_data, apEt1, apEt2, apEp, apSlmn, apIe, apIo, apP, apD, cuda_device, gpu_task, cuda_stream, gb); +#endif +} +END + +BODY[type=HIP] +{ +#if defined(PARSEC_HAVE_DEV_HIP_SUPPORT) + ForwardSHT_gpu_core(apFlm, apF_data, apEt1, apEt2, apEp, apSlmn, apIe, apIo, apP, apD, cuda_device, gpu_task, cuda_stream, gb); +#endif +} +END + +BODY +{ + complex double *pGmtheta_r = (complex double *) parsec_private_memory_pop(apGmtheta_r); + complex double *pFmnm = (complex double *) parsec_private_memory_pop(apFmnm); + complex double *pTmp1 = (complex double *) parsec_private_memory_pop(apWork1); + complex double *pTmp2 = (complex double *) parsec_private_memory_pop(apWork2); + + ForwardSHTHelper(apFlm, apF_data, apFDataDesc->mb, apFDataDesc->nb, apEt1, apET1Desc->mb, + apEt2, apET2Desc->mb, apEp, apEPDesc->mb, apEPDesc->nb, apSlmn, + apSLMNDesc->mb, apSLMNDesc->nb, apIe, apIEDesc->mb, apIEDesc->nb, apIo, + apIODesc->mb, apIODesc->nb, apP, apPDesc->mb, apPDesc->nb, apD, + pGmtheta_r, pFmnm, pTmp1, pTmp2, aLSize); + + parsec_private_memory_push(apGmtheta_r, pGmtheta_r); + parsec_private_memory_push(apFmnm, pFmnm); + parsec_private_memory_push(apWork1, pTmp1); + parsec_private_memory_push(apWork2, pTmp2); + +} +END + + +task_apFlmT(m, n) + +m = 0 .. apFLMTDesc->lmt-1 +n = 0 .. apFLMDesc->lnt-1 + +: apFLMTDesc(m, 0) + +READ apFlm <- apFlm task(n) [ type_remote = apFlm ] + +READ apFlmT <- apFLMTDesc(m, 0) + + +BODY +{ + FlmToFlmT(apFlmT, apFlm, (parsec_matrix_block_cyclic_t *) apFLMTDesc, aFlmM, aFlmN, m, n); +} +END + + + +extern "C" %{ + + +#if 0 +void *gb_forward_create_workspace(void *obj, void *user) +{ + parsec_device_module_t *mod = (parsec_device_module_t *)obj; + zone_malloc_t *memory = ((parsec_device_cuda_module_t*)mod)->super.memory; + parsec_ForwardSHT_taskpool_t *tp = (parsec_ForwardSHT_taskpool_t*)user; + gb_forward_workspace_t *wp = NULL; + int nb = tp->_g_descA->nb; + int workspace_size = tp->_g_gb->apF_data_M * tp->_g_gb->apEp_N + + tp->_g_gb->apEt1_M * tp->_g_gb->apEp_N + + tp->_g_gb->apEt2_M * tp->_g_gb->apP_N + + tp->_g_gb->apEt2_M * tp->_g_gb->apEp_N; + size_t elt_size = sizeof(complex double); + + wp = (gb_forward_workspace_t*)malloc(sizeof(gb_forward_workspace_t)); + wp->tmpmem = zone_malloc(memory, workspace_size * elt_size + sizeof(int)); + assert(NULL != wp->tmpmem); + wp->lwork = workspace_size; + wp->memory = memory; + + return wp; +} + +static void destroy_workspace(void *apWorkSpace, void *aN) +{ + gb_forward_workspace_t *ws = (gb_forward_workspace_t*) apWorkSpace; + zone_free((zone_malloc_t*)ws->memory, ws->tmpmem); + free(ws); + (void)aN; +} +#endif + + +/** + * @return the parsec object to schedule. + */ +parsec_taskpool_t* +ForwardSHTConstructor(parsec_tiled_matrix_t *apFDataDesc, parsec_tiled_matrix_t *apFLMDesc, + parsec_tiled_matrix_t *apFLMTDesc, parsec_tiled_matrix_t *apET1Desc, + parsec_tiled_matrix_t *apET2Desc, parsec_tiled_matrix_t *apEPDesc, + parsec_tiled_matrix_t *apSLMNDesc, parsec_tiled_matrix_t *apIEDesc, + parsec_tiled_matrix_t *apIODesc, parsec_tiled_matrix_t *apPDesc, + parsec_tiled_matrix_t *apDDesc, int aFDataM, int aEPN, int aET1M, + int aET2M, int aPN, int aFlmM, int aFlmN, int aLSize) +{ + + parsec_ForwardSHT_taskpool_t *pTaskpool = + parsec_ForwardSHT_new(apFDataDesc, apFLMDesc, apFLMTDesc, apET1Desc, apET2Desc, apEPDesc, + apSLMNDesc, apIEDesc,apIODesc, apPDesc, apDDesc, aFlmM, aFlmN, aLSize); + + pTaskpool->_g_apGmtheta_r = (parsec_memory_pool_t*) malloc(sizeof(parsec_memory_pool_t)); + parsec_private_memory_init(pTaskpool->_g_apGmtheta_r, aFDataM * aEPN * sizeof(complex double)); + + pTaskpool->_g_apFmnm = (parsec_memory_pool_t*) malloc(sizeof(parsec_memory_pool_t)); + parsec_private_memory_init(pTaskpool->_g_apFmnm, aET1M * aEPN * sizeof(complex double)); + + pTaskpool->_g_apWork1 = (parsec_memory_pool_t*) malloc(sizeof(parsec_memory_pool_t)); + parsec_private_memory_init(pTaskpool->_g_apWork1, aET2M * aPN * sizeof(complex double)); + + pTaskpool->_g_apWork2 = (parsec_memory_pool_t*)malloc(sizeof(parsec_memory_pool_t)); + parsec_private_memory_init( pTaskpool->_g_apWork2, aET2M * aEPN * sizeof(complex double)); + +#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) || defined(PARSEC_HAVE_DEV_HIP_SUPPORT) + int nb = 0, *dev_index; + + /** Find all CUDA devices */ + hicma_parsec_find_cuda_devices( parsec, &dev_index, &nb); + + pTaskpool->_g_ws_gpu = (void *)gb->ws; + pTaskpool->_g_nb_cuda_devices = nb; + pTaskpool->_g_cuda_device_index = dev_index; +#endif + + parsec_add2arena(&pTaskpool->arenas_datatypes[PARSEC_ForwardSHT_apF_data_ADT_IDX], + parsec_datatype_double_complex_t, PARSEC_MATRIX_FULL, + 1, apFDataDesc->mb, apFDataDesc->nb, apFDataDesc->mb, + PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + parsec_add2arena(&pTaskpool->arenas_datatypes[PARSEC_ForwardSHT_apFlm_ADT_IDX], + parsec_datatype_double_t, PARSEC_MATRIX_FULL, + 1, apFLMTDesc->mb, apFLMTDesc->nb, apFLMTDesc->mb, + PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + return (parsec_taskpool_t*)pTaskpool; +} + +/** + * @param [inout] the parsec object to destroy +*/ +void ForwardSHTDestructor(parsec_taskpool_t *apTaskpool) +{ + parsec_ForwardSHT_taskpool_t *pTaskpool = (parsec_ForwardSHT_taskpool_t *)apTaskpool; + parsec_del2arena(&pTaskpool->arenas_datatypes[PARSEC_ForwardSHT_apF_data_ADT_IDX]); + parsec_del2arena(&pTaskpool->arenas_datatypes[PARSEC_ForwardSHT_apFlm_ADT_IDX]); + parsec_private_memory_fini(pTaskpool->_g_apGmtheta_r); + parsec_private_memory_fini(pTaskpool->_g_apFmnm); + parsec_private_memory_fini(pTaskpool->_g_apWork1); + parsec_private_memory_fini(pTaskpool->_g_apWork2); + parsec_taskpool_free(apTaskpool); +} + +/** + */ +int ForwardSHT(parsec_context_t *apContext, parsec_tiled_matrix_t *apFDataDesc, parsec_tiled_matrix_t *apFLMDesc, + parsec_tiled_matrix_t *apFLMTDesc, parsec_tiled_matrix_t *apET1Desc, + parsec_tiled_matrix_t *apET2Desc, parsec_tiled_matrix_t *apEPDesc, + parsec_tiled_matrix_t *apSLMNDesc, parsec_tiled_matrix_t *apIEDesc, + parsec_tiled_matrix_t *apIODesc, parsec_tiled_matrix_t *apPDesc, + parsec_tiled_matrix_t *apDDesc, int aFDataM, int aEPN, int aET1M, + int aET2M, int aPN, int aFlmM, int aFlmN, int aLSize) { + + parsec_taskpool_t *pTaskpool = ForwardSHTConstructor(apFDataDesc, apFLMDesc, apFLMTDesc, apET1Desc, apET2Desc, + apEPDesc, apSLMNDesc, apIEDesc, apIODesc, apPDesc, apDDesc, + aFDataM, aEPN, aET1M, aET2M, aPN, aFlmM, aFlmN, aLSize); + if( pTaskpool != NULL ){ + parsec_context_add_taskpool(apContext, pTaskpool); + parsec_context_start(apContext); + parsec_context_wait(apContext); + ForwardSHTDestructor(pTaskpool); + } + return 0; +} + +%} diff --git a/src/runtime/parsec/jdf/ForwardSHTReshape.jdf b/src/runtime/parsec/jdf/ForwardSHTReshape.jdf new file mode 100644 index 00000000..7874ba14 --- /dev/null +++ b/src/runtime/parsec/jdf/ForwardSHTReshape.jdf @@ -0,0 +1,236 @@ +extern "C" %{ +/* + * @copyright (c) 2023 King Abdullah University of Science and Technology (KAUST). + * @copyright (c) 2023 The Universiy of Tennessee and The Universiy of Tennessee Research Foundation. + * All rights reserved. + */ + +#include +#include + +static void FlmTReshape(double *apFlmT, int aM, double *apTemp, parsec_matrix_block_cyclic_t *apFlmTDesc, int aT) { + + int flmT_offset = aM * apFlmTDesc->super.mb; + int M = (aM == apFlmTDesc->super.lmt - 1)? apFlmTDesc->super.mb - flmT_offset : apFlmTDesc->super.mb; + if( aT-3 <= 0 ) return; + int N = aT-3; + int lda_flmT = apFlmTDesc->super.mb; + + // N * 1 + double *Y = apTemp; + // N * 3 + double *X = apTemp + N; + // 3 * 3 + double *XtX = apTemp + 4 * N; + // 3 * 1 + double *XtY = apTemp + 4 * N + 10; + double *phi = apTemp + 4 * N + 14; + + for(int i = 0; i < M; i++) { + // Get Y + for(int j = 0; j < N; j++) { + Y[j] = apFlmT[(j+3) * lda_flmT + i]; + } + + // Get X + for(int j = 0; j < N; j++) { + X[3*j+0] = apFlmT[(j+2) * lda_flmT + i]; + X[3*j+1] = apFlmT[(j+1) * lda_flmT + i]; + X[3*j+2] = apFlmT[(j+0) * lda_flmT + i]; + } + + // X transpose times X + double alpha = 1.0; + double beta = 0.0; + + cblas_dgemm(CblasRowMajor, CblasTrans, CblasNoTrans, + 3, 3, N, + alpha, X, 3, + X, 3, + beta, XtX, 3); + + // X transpose times y + cblas_dgemv(CblasRowMajor, CblasTrans, + N, 3, + alpha, X, 3, + Y, 1, + beta, XtY, 1); + + // Solve + LAPACKE_dposv(LAPACK_ROW_MAJOR, 'U', 3, 1, XtX, 3, XtY, 1); + + // Use phi to compute eps_out + cblas_dgemv(CblasRowMajor, CblasNoTrans, + N, 3, + -1.0, X, 3, + XtY, 1, + 1.0, &apFlmT[3*lda_flmT+i], lda_flmT); + } +} + + +%} + +/* Globals + */ +apFDataDesc [ type = "parsec_tiled_matrix_t*" ] +apFLMDesc [ type = "parsec_tiled_matrix_t*" aligned = apFDataDesc] +apFLMTDesc [ type = "parsec_tiled_matrix_t*" ] +apET1Desc [ type = "parsec_tiled_matrix_t*" ] +apET2Desc [ type = "parsec_tiled_matrix_t*" ] +apEPDesc [ type = "parsec_tiled_matrix_t*" ] +apSLMNDesc [ type = "parsec_tiled_matrix_t*" ] +apIEDesc [ type = "parsec_tiled_matrix_t*" ] +apIODesc [ type = "parsec_tiled_matrix_t*" ] +apPDesc [ type = "parsec_tiled_matrix_t*" ] +apDDesc [ type = "parsec_tiled_matrix_t*" ] +apADesc [ type = "parsec_tiled_matrix_t*" ] + +aFlmTNB [ type = "int" ] +aLSize [ type = "int" ] +aT [ type = "int" ] + +/* Temporary buffer used for convert */ +apGmtheta_r [ type = "parsec_memory_pool_t *" hidden = on default = NULL ] +apFmnm [ type = "parsec_memory_pool_t *" hidden = on default = NULL ] +apWork1 [ type = "parsec_memory_pool_t *" hidden = on default = NULL ] +apWork2 [ type = "parsec_memory_pool_t *" hidden = on default = NULL ] + +/* GPU workspace */ +ws_gpu [ type = "void *" hidden = on default = NULL ] + +/* GPU number and index */ +nb_cuda_devices [ type = "int" hidden = on default = 0 ] +cuda_device_index [ type = "int *" hidden = on default = "NULL"] + + + +task(m) + +m = 0 .. apFLMTDesc->lmt-1 +m_s = %{ return m*aFlmTNB; %} +m_e = %{ return parsec_imin((m+1)*aFlmTNB-1, apADesc->lmt-1); %} + +: apFLMTDesc(m, 0) + +RW apFlmT <- apFLMTDesc(m, 0) + -> apFLMTDesc(m, 0) + + +BODY +{ + + double *pTemp = (double *) parsec_private_memory_pop(apWork1); + FlmTReshape(apFlmT, m, pTemp, (parsec_matrix_block_cyclic_t *) apFLMTDesc, aT); + parsec_private_memory_push(apWork1, pTemp); +} +END + +extern "C" %{ + + +/** + * @return the parsec object to schedule. + */ +parsec_taskpool_t* +ForwardSHTReshape_constructor(parsec_tiled_matrix_t *apFDataDesc, parsec_tiled_matrix_t *apFLMDesc, + parsec_tiled_matrix_t *apFLMTDesc, parsec_tiled_matrix_t *apET1Desc, + parsec_tiled_matrix_t *apET2Desc, parsec_tiled_matrix_t *apEPDesc, + parsec_tiled_matrix_t *apSLMNDesc, parsec_tiled_matrix_t *apIEDesc, + parsec_tiled_matrix_t *apIODesc, parsec_tiled_matrix_t *apPDesc, + parsec_tiled_matrix_t *apDDesc, parsec_tiled_matrix_t *apADesc, + int aFDataM, int aEPN, int aET1M, int aET2M, int aPN, + int aFlmTNB, int aT, int aLSize) +{ + + parsec_ForwardSHTReshape_taskpool_t + *pTaskpool = parsec_ForwardSHTReshape_new(apFDataDesc, apFLMDesc, apFLMTDesc, apET1Desc, apET2Desc, apEPDesc, + apSLMNDesc, apIEDesc, apIODesc, apPDesc, apDDesc, apADesc, aFlmTNB, aLSize, aT); + + pTaskpool->_g_apGmtheta_r = (parsec_memory_pool_t*)malloc(sizeof(parsec_memory_pool_t)); + parsec_private_memory_init(pTaskpool->_g_apGmtheta_r, aFDataM * aEPN * sizeof(complex double) ); + + pTaskpool->_g_apFmnm = (parsec_memory_pool_t*)malloc(sizeof(parsec_memory_pool_t)); + parsec_private_memory_init(pTaskpool->_g_apFmnm, aET1M * aEPN * sizeof(complex double) ); + + pTaskpool->_g_apWork1 = (parsec_memory_pool_t*)malloc(sizeof(parsec_memory_pool_t)); + parsec_private_memory_init(pTaskpool->_g_apWork1, aET2M * aPN * sizeof(complex double) ); + + pTaskpool->_g_apWork2 = (parsec_memory_pool_t*)malloc(sizeof(parsec_memory_pool_t)); + parsec_private_memory_init(pTaskpool->_g_apWork2, aET2M * aEPN * sizeof(complex double) ); + +#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) || defined(PARSEC_HAVE_DEV_HIP_SUPPORT) + int nb = 0, *dev_index; + + /** Find all CUDA devices */ + hicma_parsec_find_cuda_devices( parsec, &dev_index, &nb); + + pTaskpool->_g_ws_gpu = (void *)gb->ws; + pTaskpool->_g_nb_cuda_devices = nb; + pTaskpool->_g_cuda_device_index = dev_index; +#endif + + parsec_add2arena(&pTaskpool->arenas_datatypes[PARSEC_ForwardSHTReshape_DEFAULT_ADT_IDX], + parsec_datatype_double_t, PARSEC_MATRIX_FULL, + 1, apFLMTDesc->mb, apFLMTDesc->nb, apFLMTDesc->mb, + PARSEC_ARENA_ALIGNMENT_SSE, -1); + + return (parsec_taskpool_t*) pTaskpool; +} + +/** + * @param [inout] the parsec object to destroy +*/ +void ForwardSHTReshape_destructor(parsec_taskpool_t *apTaskpool) +{ + parsec_ForwardSHTReshape_taskpool_t *pTaskpool = (parsec_ForwardSHTReshape_taskpool_t *)apTaskpool; + parsec_del2arena(&pTaskpool->arenas_datatypes[PARSEC_ForwardSHTReshape_DEFAULT_ADT_IDX]); + parsec_private_memory_fini(pTaskpool->_g_apGmtheta_r); + parsec_private_memory_fini(pTaskpool->_g_apFmnm); + parsec_private_memory_fini(pTaskpool->_g_apWork1); + parsec_private_memory_fini(pTaskpool->_g_apWork2); + parsec_taskpool_free(apTaskpool); +} + +/** + */ +int ForwardSHTReshape(parsec_context_t *apContext, int aRank, int aVerbose, parsec_tiled_matrix_t *apFDataDesc, + parsec_tiled_matrix_t *apFLMDesc, parsec_tiled_matrix_t *apFLMTDesc, parsec_tiled_matrix_t *apET1Desc, + parsec_tiled_matrix_t *apET2Desc, parsec_tiled_matrix_t *apEPDesc, parsec_tiled_matrix_t *apSLMNDesc, + parsec_tiled_matrix_t *apIEDesc, parsec_tiled_matrix_t *apIODesc, parsec_tiled_matrix_t *apPDesc, + parsec_tiled_matrix_t *apDDesc, parsec_tiled_matrix_t *apADesc, int aFDataM, int aEPN, int aET1M, int aET2M, + int aPN, int aFlmTNB, int aT, int aLSize, double *apNormGlobal, int aNT, int aUpperLower) +{ + parsec_taskpool_t *pTaskpool = ForwardSHTReshape_constructor(apFDataDesc, apFLMDesc, apFLMTDesc, apET1Desc, apET2Desc, + apEPDesc, apSLMNDesc, apIEDesc, apIODesc, apPDesc, apDDesc, + apADesc, aFDataM, aEPN, aET1M, aET2M, aPN, aFlmTNB, aT, aLSize); + + if( pTaskpool != NULL ){ + parsec_context_add_taskpool(apContext, pTaskpool); + parsec_context_start(apContext); + parsec_context_wait(apContext); + ForwardSHTReshape_destructor(pTaskpool); + } + // Reshape + VERBOSE_PRINT(aRank, aVerbose, ("Redistribute apFLMTDesc -> desc_A\n")); + parsec_redistribute(apContext, apFLMTDesc, apADesc, apADesc->m, apADesc->n, 0, 0, 0, 0); + + double norm_flmT = 0.0; + GetMatrixNorm(apContext, apNormGlobal, apFLMTDesc, aNT, aUpperLower, 0); + norm_flmT = *apNormGlobal; + double norm_A = 0.0; + GetMatrixNorm(apContext, apNormGlobal, apADesc, aNT, aUpperLower, 0); + norm_A = *apNormGlobal; + + if( 0 == aRank ) { + fprintf(stderr, RED "norm_flmT %lf norm_A %lf\n" RESET, norm_flmT, norm_A); + } + + // Free memory + parsec_data_free(((parsec_matrix_block_cyclic_t *)apFLMTDesc)->mat); + parsec_tiled_matrix_destroy((parsec_tiled_matrix_t*)apFLMTDesc); + + return 0; +} + +%} diff --git a/src/runtime/parsec/jdf/GetMatrixNorm.jdf b/src/runtime/parsec/jdf/GetMatrixNorm.jdf new file mode 100644 index 00000000..705eaa40 --- /dev/null +++ b/src/runtime/parsec/jdf/GetMatrixNorm.jdf @@ -0,0 +1,139 @@ +extern "C" %{ +/** + * @copyright (c) 2023 King Abdullah University of Science and Technology (KAUST). + * @copyright (c) 2023 The Universiy of Tennessee and The Universiy of Tennessee Research Foundation. + * All rights reserved. + **/ + +#include +#include + +%} + +/* Globals + */ +apADesc [ type = "parsec_tiled_matrix_t*" ] +aNT [ type = "int" ] +aUpperLower [ type = "int" ] +apNorm [ type = "double *" ] +apNormTile [ type = "double *" ] +aIsSymmetric [ type = "int" ] + +/************************************************** + * generate diagonal tiles * + **************************************************/ +task(m, n) + +// Execution space +m = 0 .. apADesc->mt-1 +n = 0 .. (aIsSymmetric ? m : apADesc->nt-1) // Adjust based on matrix symmetry + +// Parallel partitioning +:apADesc(m, n) + +// Parameters +READ D <- apADesc(m, n) + +BODY +{ + int ldd = BLKLDD(apADesc, m); + int tempmm = m == apADesc->mt-1 ? apADesc->m - m * apADesc->mb : apADesc->mb; + int tempnn = tempmm; + + /* Calcuate the global norm */ + int tid = es->th_id; + double current_value = 0.0; + apNormTile[n * aNT + m] = 0.0; + + // Diagonal modification for symmetric matrices + if (aIsSymmetric && m == n) { + for(int i = 0; i < apADesc->mb; i++) { + ((double *)D)[i * apADesc->mb + i] += 1.0e-6; + } + } + + // Norm calculation + for (int j = 0; j < apADesc->nb; j++) { + for (int i = 0; i < apADesc->mb; i++) { + current_value = ((double *) D)[j * apADesc->mb + i]; + apNormTile[n * aNT + m] += current_value * current_value; + } + } + + apNorm[tid] += apNormTile[n * aNT + m]; + apNormTile[n * aNT + m] = sqrt(apNormTile[n * aNT + m]); + + if(m - n >= aNT * PORTION_NORM ){ + apNorm[tid] = 0.0; + } +} +END + +extern "C" %{ + +/** + * Generate matrix + * @return the parsec object to schedule + */ +parsec_taskpool_t* +GetMatrixNormConstructor(parsec_tiled_matrix_t *apADesc, int aUpperLower, int aNT, + double *apNormTmp, double *apNormTile, int aIsSymmetric) +{ + + /* Check input arguments */ + if (aUpperLower != PlasmaLower) { + dplasma_error("STARSH_appr_New", "illegal value of uplo, should be PlasmaLower\n"); + return NULL; + } + + parsec_GetMatrixNorm_taskpool_t *pTaskpool = parsec_GetMatrixNorm_new(apADesc, aNT, aUpperLower, + apNormTmp, apNormTile, aIsSymmetric); + + return (parsec_taskpool_t*) pTaskpool; +} + +/* Destructor */ +void GetMatrixNormDestructor(parsec_taskpool_t *apTaskpool) +{ + parsec_taskpool_free(apTaskpool); +} + +/** + * Generate matrix + */ +void GetMatrixNorm(parsec_context_t *apContext, double *apNormGlobal, parsec_tiled_matrix_t *apADesc, + int aNT, int aUpperLower, int aIsSymmetric) +{ + + /* Only for 1 vp */ + assert(apContext->nb_vp == 1); + int nb_threads = apContext->virtual_processes[0]->nb_cores; + double *pNormTmp = (double *) calloc(nb_threads, sizeof(double)); + + /* Make sure norm_tile and norm_global is fresh */ + double* pNormTile = (double*) malloc(aNT * aNT * sizeof(double)); + memset(pNormTile, 0, aNT * aNT * sizeof(double)); + *apNormGlobal = 0.0; + parsec_taskpool_t *pTaskpool = GetMatrixNormConstructor(apADesc, aUpperLower, aNT, + pNormTmp, pNormTile, aIsSymmetric); + + parsec_context_add_taskpool(apContext, pTaskpool); + parsec_context_start(apContext); + parsec_context_wait(apContext); + GetMatrixNormDestructor(pTaskpool); + + /* Reduce to the global norm */ + double norm_process = 0.0; + for(int i = 0; i < nb_threads; i++) { + norm_process += pNormTmp[i]; + } + + MPI_Allreduce(MPI_IN_PLACE, pNormTile, aNT * aNT, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(&norm_process, apNormGlobal, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + *apNormGlobal = sqrt(*apNormGlobal); + + free(pNormTile); + free(pNormTmp); +} + +%} diff --git a/src/runtime/parsec/jdf/InverseSHT.jdf b/src/runtime/parsec/jdf/InverseSHT.jdf new file mode 100644 index 00000000..5fc52e17 --- /dev/null +++ b/src/runtime/parsec/jdf/InverseSHT.jdf @@ -0,0 +1,162 @@ +extern "C" %{ +/* + * @copyright (c) 2023 King Abdullah University of Science and Technology (KAUST). + * @copyright (c) 2023 The Universiy of Tennessee and The Universiy of Tennessee Research Foundation. + * All rights reserved. + */ + +#include +#include + +static void FlmToFlmT(double *apFlmT, double *apFlm, parsec_matrix_block_cyclic_t *apFLMTDesc, int aFlmM, int aFlmN, int aM, int aN) { + int flm_offset = aM * apFLMTDesc->super.mb; + int flmT_offset = aN * apFLMTDesc->super.mb; + int size = (aM == apFLMTDesc->super.lmt - 1) ? (aFlmM * aFlmN) - flm_offset : apFLMTDesc->super.mb; + memcpy(apFlmT + flmT_offset, apFlm + flm_offset, size*sizeof(double)); +} + + +%} + +/* Globals + */ +apFSpatialDesc [ type = "parsec_tiled_matrix_t*" ] +apFLMDesc [ type = "parsec_tiled_matrix_t*" aligned = apFDataDesc] +apZLMDesc [ type = "parsec_tiled_matrix_t*" ] +apSCDesc [ type = "parsec_tiled_matrix_t*" ] +aLSize [ type = "int" ] + +/* Temporary buffer used for convert */ +apWork [ type = "parsec_memory_pool_t *" hidden = on default = NULL ] + +/* GPU workspace */ +ws_gpu [ type = "void *" hidden = on default = NULL ] + +/* GPU number and index */ +nb_cuda_devices [ type = "int" hidden = on default = 0 ] +cuda_device_index [ type = "int *" hidden = on default = "NULL"] + +bind_gpu(n) + +n = 0 .. apFSpatialDesc->lnt-1 + +: apFSpatialDesc(0, n) + +READ flm <- apFLMDesc(0, n) + -> flm task(n) [ type_remote = flm ] + +READ f_spatial <- apFSpatialDesc(0, n) + -> f_spatial task(n) [ type_remote = f_spatial ] + + +BODY +{ +#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) || defined(PARSEC_HAVE_DEV_HIP_SUPPORT) + if( nb_cuda_devices > 0 ) { + int g = climate_emulator_gpu_load_balance( n, gb->nodes, nb_cuda_devices ); + parsec_advise_data_on_device( _f_flm->original, + cuda_device_index[g], + PARSEC_DEV_DATA_ADVICE_PREFERRED_DEVICE ); + parsec_advise_data_on_device( _f_f_spatial->original, + cuda_device_index[g], + PARSEC_DEV_DATA_ADVICE_PREFERRED_DEVICE ); + } +#endif +} +END + + +task(n) + +n = 0 .. apFSpatialDesc->lnt-1 + +: apFSpatialDesc(0, n) + +// TODO: check whether this will evict f_spatial first on GPU +RW f_spatial <- f_spatial bind_gpu(n) [ type_remote = f_spatial ] + -> apFSpatialDesc(0, n) + +READ flm <- flm bind_gpu(n) [ type_remote = flm ] +READ Zlm <- apZLMDesc(0, %{ return apFSpatialDesc->super.rank_of(&apFSpatialDesc->super, 0, n); %}) +READ SC <- apSCDesc(0, %{ return apFSpatialDesc->super.rank_of(&apFSpatialDesc->super, 0, n); %}) + +BODY +{ + double *pSmt = (double *) parsec_private_memory_pop(apWork); + InverseSHTHelper(flm, f_spatial, Zlm, SC, pSmt, aLSize); + parsec_private_memory_push(apWork, pSmt); + +} +END + + +extern "C" %{ + +/** + * @return the parsec object to schedule. + */ +parsec_taskpool_t* +InverseSHTConstructor(parsec_tiled_matrix_t *apFSpatialDesc, parsec_tiled_matrix_t *apFLMDesc, + parsec_tiled_matrix_t *apZLMDesc, parsec_tiled_matrix_t *apSCDesc, + int aLSize) +{ + + parsec_InverseSHT_taskpool_t *pTaskpool = parsec_InverseSHT_new(apFSpatialDesc, apFLMDesc, apZLMDesc, apSCDesc, aLSize); + + pTaskpool->_g_apWork = (parsec_memory_pool_t*) malloc(sizeof(parsec_memory_pool_t)); + parsec_private_memory_init(pTaskpool->_g_apWork, (aLSize + 1) * (2 * aLSize - 1) * sizeof(double) ); + +#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) || defined(PARSEC_HAVE_DEV_HIP_SUPPORT) + int nb = 0, *dev_index; + + /** Find all CUDA devices */ + + hicma_parsec_find_cuda_devices( parsec, &dev_index, &nb); + + pTaskpool->_g_ws_gpu = (void *)gb->ws; + pTaskpool->_g_nb_cuda_devices = nb; + pTaskpool->_g_cuda_device_index = dev_index; +#endif + + parsec_add2arena(&pTaskpool->arenas_datatypes[PARSEC_InverseSHT_f_spatial_ADT_IDX], + parsec_datatype_double_t, PARSEC_MATRIX_FULL, + 1, apFSpatialDesc->mb, apFSpatialDesc->nb, apFSpatialDesc->mb, + PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + parsec_add2arena(&pTaskpool->arenas_datatypes[PARSEC_InverseSHT_flm_ADT_IDX], + parsec_datatype_double_t, PARSEC_MATRIX_FULL, + 1, apFLMDesc->mb, apFLMDesc->nb, apFLMDesc->mb, + PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + return (parsec_taskpool_t*)pTaskpool; +} + +/** + * @param [inout] the parsec object to destroy +*/ +void InverseSHTDestructor(parsec_taskpool_t *apTaskpool) +{ + parsec_InverseSHT_taskpool_t *pTaskpool = (parsec_InverseSHT_taskpool_t *) apTaskpool; + parsec_del2arena(&pTaskpool->arenas_datatypes[PARSEC_InverseSHT_f_spatial_ADT_IDX]); + parsec_del2arena(&pTaskpool->arenas_datatypes[PARSEC_InverseSHT_flm_ADT_IDX]); + parsec_private_memory_fini(pTaskpool->_g_apWork); + parsec_taskpool_free(apTaskpool); +} + +/** + */ +int InverseSHT(parsec_context_t *apContext, parsec_tiled_matrix_t *apFSpatialDesc, parsec_tiled_matrix_t *apFLMDesc, + parsec_tiled_matrix_t *apZLMDesc, parsec_tiled_matrix_t *apSCDesc, int aLSize) { + + parsec_taskpool_t *pTaskpool = InverseSHTConstructor(apFSpatialDesc, apFLMDesc, apZLMDesc, apSCDesc, aLSize); + + if( pTaskpool != NULL ){ + parsec_context_add_taskpool(apContext, pTaskpool); + parsec_context_start(apContext); + parsec_context_wait(apContext); + InverseSHTDestructor(pTaskpool); + } + return 0; +} + +%} diff --git a/src/runtime/parsec/jdf/MatrixCompress.jdf b/src/runtime/parsec/jdf/MatrixCompress.jdf new file mode 100644 index 00000000..c64a7c93 --- /dev/null +++ b/src/runtime/parsec/jdf/MatrixCompress.jdf @@ -0,0 +1,409 @@ +extern "C" %{ +/** + * @copyright (c) 2023 King Abdullah University of Science and Technology (KAUST). + * @copyright (c) 2023 The Universiy of Tennessee and The Universiy of Tennessee Research Foundation. + * All rights reserved. + **/ + +#include +#include +#define GENERATE_RANDOM_DATA 0 + +%} + +/** Generate matrix + */ + +/* Globals + */ +apADesc [ type = "parsec_tiled_matrix_t*" ] +apArDesc [ type = "parsec_tiled_matrix_t*" ] +aBandSizeDense [ type = "int" ] +aNT [ type = "int" ] +aMaxRank [ type = "int" ] +aN [ type = "int" ] +apNorm [ type = "double *" ] +apNormTile [ type = "double *" ] +aAdaptiveDecision [ type = "int" ] +aTolerance [ type = "double" ] +aSendFullTile [ type = "int" ] +aAutoBand [ type = "int" ] +aGpus [ type = "int" ] +params_kernel [ type = "starsh_params_t *" ] + +aRsvd_oversample [ type = "int" hidden = on ] +aRsvd_lwork [ type = "size_t" hidden = on ] +aRsvd_liwork [ type = "size_t" hidden = on ] +aUv_work [ type = "parsec_memory_pool_t *" hidden = on default = NULL] +aD_work [ type = "parsec_memory_pool_t *" hidden = on default = NULL] +aRsvaD_work [ type = "parsec_memory_pool_t *" hidden = on default = NULL] +aRsvd_iwork [ type = "parsec_memory_pool_t *" hidden = on default = NULL] + +/************************************************** + * generate diagonal tiles * + **************************************************/ +generate_band(m, n) [high_priority = on] + +// Execution space +m = 0 .. apADesc->mt-1 +n = %{ return parsec_imax(m-aBandSizeDense+1, 0); %} .. m + +// Parallel partitioning +:apADesc(m, n) + +// Parameters +READ D <- apADesc(m, n) +READ D1 <- NULL [ type_remote = FULL ] + +BODY +{ + int ldd = BLKLDD(apADesc, m); + int tempmm = m == apADesc->mt-1 ? apADesc->m - m * apADesc->mb : apADesc->mb; + int tempnn = tempmm; + + /* New data_copy and allocate memory on band if not allocated */ +#if !BAND_MEMORY_CONTIGUOUS + if( aBandSizeDense < aNT || aAutoBand == 1 || !MEMORY_IN_CHOLEKSY_DP ) { + this_task->data._f_D.data_out = parsec_data_copy_new(data_of_apADesc(m, n), 0, PARSEC_MatrixCompress_FULL_ADT->opaque_dtt, PARSEC_DATA_FLAG_PARSEC_MANAGED); + if( aGpus > 0 ) { +#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) + cudaMallocHost((void**)&this_task->data._f_D.data_out->device_private, apADesc->mb * apADesc->mb * sizeof(double)); +#endif + +#if defined(PARSEC_HAVE_DEV_HIP_SUPPORT) + // TODO A better way + hipHostMalloc((void**)&this_task->data._f_D.data_out->device_private, apADesc->mb * apADesc->mb * sizeof(double), hipHostMallocDefault); +#endif + } else { + this_task->data._f_D.data_out->device_private = calloc(apADesc->mb * apADesc->mb, sizeof(double)); + } + } +#endif + + /* Calcuate the global norm */ + if( 1 || aAdaptiveDecision ) { + int tid = es->th_id; + double current_value = 0.0; + apNormTile[n*aNT+m] = 0.0; + + for(int j = 0; j < apADesc->nb; j++) { + for(int i = 0; i < apADesc->mb; i++) { + current_value = ((double *)this_task->data._f_D.data_out->device_private)[j*apADesc->mb+i]; + apNormTile[n * aNT + m] += current_value * current_value; + } + } + + apNorm[tid] += apNormTile[n * aNT + m]; + apNormTile[n * aNT + m] = sqrt(apNormTile[n * aNT + m]); + + if( m - n >= aNT * PORTION_NORM ) + apNorm[tid] = 0.0; + } +} +END + + +/************************************************** + **************************************************/ +READ_R(m, n) + +// Execution space +m = aBandSizeDense .. apADesc->mt-1 +n = 0 .. m-aBandSizeDense + +:apArDesc(m, n) + +READ R <- apArDesc(m, n) + -> R generate_approximate_L(m, n) [ type_remote = AR ] + +BODY +{ +} +END + + +/************************************************** + **************************************************/ +WRITE_R(m, n) + +// Execution space +m = aBandSizeDense .. apADesc->mt-1 +n = 0 .. m-aBandSizeDense + +:apArDesc(m, n) + +RW R <- R generate_approximate_L(m, n) [ type_remote = AR ] + -> apArDesc(m, n) + +BODY +{ +} +END + + +/************************************************** + * generate and approximate lower triangular part * + **************************************************/ +generate_approximate_L(m, n) [high_priority = on] + +// Execution space +m = aBandSizeDense .. apADesc->mt-1 +n = 0 .. m-aBandSizeDense + +// Parallel partitioning +:apADesc(m, n) + +// Parameters +RW R <- R READ_R(m, n) [ type_remote = AR ] + -> R WRITE_R(m, n) [ type_remote = AR ] + +READ A <- NULL [ type_remote = UV ] + +BODY +{ + int size = 0; + int ldU = BLKLDD(apADesc, m); + int ldV = BLKLDD(apADesc, m); + int tempmm = m == apADesc->mt-1 ? apADesc->m - m * apADesc->mb : apADesc->mb; + int tempnn = n == apADesc->mt-1 ? apADesc->m - m * apADesc->mb : apADesc->mb; + void *U = parsec_private_memory_pop(aUv_work); + void *tmp_D = parsec_private_memory_pop(aD_work); + void *work = parsec_private_memory_pop(aRsvaD_work); + void *iwork = parsec_private_memory_pop(aRsvd_iwork); + int rank = -1; + void *V = (void *)U + apADesc->mb * aMaxRank * sizeof(double); + +#if GENERATE_RANDOM_DATA + CORE_dplgsy( + aN, tempmm, tempnn, tmp_D, ldU, + apADesc->m, m*apADesc->mb, n*apADesc->nb, 3872 ); +#else + params_kernel->kernel(tempmm, tempnn, params_kernel->index + m*apADesc->mb, + params_kernel->index + n*apADesc->mb, params_kernel->data, params_kernel->data, tmp_D, + tempmm); +#endif + + /* Calcuate the global norm */ + if( 1 || aAdaptiveDecision ) { + int tid = es->th_id; + double current_value = 0.0; + apNormTile[n*aNT+m] = 0.0; + + for(int j = 0; j < apADesc->nb; j++) { + for(int i = 0; i < apADesc->mb; i++) { + current_value = ((double *)tmp_D)[j*apADesc->mb+i]; + //norm[tid] += current_value * current_value; + apNormTile[n*aNT+m] += current_value * current_value; + } + } + + apNorm[tid] += apNormTile[n*aNT+m]; + apNormTile[n*aNT+m] = sqrt(apNormTile[n*aNT+m]); + + if( m - n >= aNT*PORTION_NORM ) + apNorm[tid] = 0.0; + } + +#if 1 + starsh_dense_dlrrsdd(tempmm, tempnn, tmp_D, tempmm, U, ldU, V, ldV, &rank, + aMaxRank, aRsvd_oversample, aTolerance, work, aRsvd_lwork, iwork); +#else + int maxrank_used = hicma_parsec_min(100, aMaxRank); + while( 1 ) { + starsh_dense_dlrrsdd(tempmm, tempnn, tmp_D, tempmm, U, ldU, V, ldV, &rank, + maxrank_used, aRsvd_oversample, aTolerance, work, aRsvd_lwork, iwork); + maxrank_used *= 2; + maxrank_used = hicma_parsec_min( apADesc->nb / 2, maxrank_used ); + if( rank != -1 || maxrank_used > apADesc->nb / 2 ) break; + + params_kernel->kernel(tempmm, tempnn, params_kernel->index + m*apADesc->mb, + params_kernel->index + n*apADesc->mb, params_kernel->data, params_kernel->data, tmp_D, + tempmm); + } +#endif + + if(rank == -1) { + printf("Tile(%d, %d) is dense, try increasing NB or aMaxRank \n", m, n); + } else { + /* Update R and size */ + *(int *)R = rank; + + if(aSendFullTile == 1){ /* Storage of UV tiles is MB by maxrank by 2 */ + size = apADesc->mb * aMaxRank * 2; + } else { + size = apADesc->mb * parsec_imin(aMaxRank, rank) * 2; + } + + /* New data_copy and allocate memory for apADesc(m, n); + * For off band, if send_full_tile, allocate mb * maxrank * 2, + * else, size = mb * min(maxrank, rank) * 2 + */ + this_task->data._f_A.data_out = parsec_data_copy_new(data_of_apADesc(m, n), 0, PARSEC_MatrixCompress_UV_ADT->opaque_dtt, PARSEC_DATA_FLAG_PARSEC_MANAGED); + this_task->data._f_A.data_out->device_private = calloc(size, sizeof(double)); + + /* New nb_elts for data_of(m, n) */ + (data_of_apADesc(m, n))->nb_elts = size * sizeof(double); + + /* Copy U to A */ + memcpy((void *)this_task->data._f_A.data_out->device_private, + (void *)U, apADesc->mb * rank * sizeof(double)); + + /* Copy V to A */ + memcpy((void *)this_task->data._f_A.data_out->device_private + apADesc->mb * rank * sizeof(double), + (void *)V, apADesc->mb * rank * sizeof(double)); + } + + parsec_private_memory_push(aUv_work, U); + parsec_private_memory_push(aD_work, tmp_D); + parsec_private_memory_push(aRsvaD_work, work); + parsec_private_memory_push(aRsvd_iwork, iwork); +} +END + +extern "C" %{ + +/** + * Generate matrix + * @return the parsec object to schedule + */ +parsec_taskpool_t* +MatrixCompress_constructor(int aUpperLower, int aBandSizeDense, int aNT, int aMaxRank, int aN, double *apNormTmp, double *apNormTile, + int aAdaptiveDecision, int aTolerance, int aSendFullTile, int aAutoBand, int aGpus, + hicma_parsec_data_t *data, starsh_params_t *params_kernel) +{ + + parsec_tiled_matrix_t *apADesc = (parsec_tiled_matrix_t *)&data->dcA; + // TODO: get */params_tlr->auto_band == 0 &&*/ + if(aBandSizeDense >= aNT && MEMORY_IN_CHOLEKSY_DP ) { + apADesc = (parsec_tiled_matrix_t *)&data->dcAd; + } + parsec_tiled_matrix_t *apArDesc = (parsec_tiled_matrix_t *)&data->dcAr; + + /* Check input arguments */ + if (aUpperLower != PlasmaLower) { + dplasma_error("STARSH_appr_New", "illegal value of uplo, should be PlasmaLower\n"); + return NULL; + } + + /* Check aBandSizeDense */ + if(aBandSizeDense < 1 ) { + if(0 == apADesc->super.myrank ) + fprintf(stderr, "\nERROR: band_size_dense should be not less that 1 : %d\n\n", aBandSizeDense); + exit(1); + } + + /* Calculate workspace */ + int rsvd_oversample = 10; + int mn = rsvd_oversample + aMaxRank; + if(mn > apADesc->mb) { + mn = apADesc->mb; + } + size_t rsvd_lwork = (4*mn+7) * mn; + + if(rsvd_lwork < apADesc->mb){ + rsvd_lwork = apADesc->mb; + } + rsvd_lwork += mn*(3*apADesc->mb+mn+1); + size_t rsvd_liwork = 8*mn; + + parsec_MatrixCompress_taskpool_t *pTaskpool = + parsec_MatrixCompress_new(apADesc, apArDesc, aBandSizeDense, aNT, aMaxRank, aN, + apNormTmp, apNormTile, aAdaptiveDecision, aTolerance, aSendFullTile, + aAutoBand, aGpus, params_kernel); + + pTaskpool->_g_apNorm = apNormTmp; + pTaskpool->_g_aRsvd_oversample = rsvd_oversample; + pTaskpool->_g_aRsvd_lwork = rsvd_lwork; + pTaskpool->_g_aRsvd_liwork = rsvd_liwork; + + /* Memery pool */ + pTaskpool->_g_aUv_work = malloc(sizeof(parsec_memory_pool_t)); + parsec_private_memory_init(pTaskpool->_g_aUv_work, (apADesc->mb*aMaxRank*2)*sizeof(double)); + + pTaskpool->_g_aD_work = malloc(sizeof(parsec_memory_pool_t)); + parsec_private_memory_init(pTaskpool->_g_aD_work, (apADesc->mb*apADesc->mb)*sizeof(double)); + + pTaskpool->_g_aRsvaD_work = malloc(sizeof(parsec_memory_pool_t)); + parsec_private_memory_init(pTaskpool->_g_aRsvaD_work, rsvd_lwork*sizeof(double)); + + pTaskpool->_g_aRsvd_iwork = malloc(sizeof(parsec_memory_pool_t)); + parsec_private_memory_init(pTaskpool->_g_aRsvd_iwork, rsvd_liwork*sizeof(int)); + + /* Arena */ + parsec_add2arena(&pTaskpool->arenas_datatypes[PARSEC_MatrixCompress_FULL_ADT_IDX], + parsec_datatype_double_t, PARSEC_MATRIX_FULL, + 1, apADesc->mb, apADesc->mb, apADesc->mb, + PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + parsec_add2arena(&pTaskpool->arenas_datatypes[PARSEC_MatrixCompress_UV_ADT_IDX], + parsec_datatype_double_t, PARSEC_MATRIX_FULL, + 1, apADesc->mb, aMaxRank*2, apADesc->mb, + PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + parsec_add2arena(&pTaskpool->arenas_datatypes[PARSEC_MatrixCompress_AR_ADT_IDX], + parsec_datatype_int_t, PARSEC_MATRIX_FULL, + 1, 1, 1, 1, + PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + return (parsec_taskpool_t*)pTaskpool; +} + +/* Destructor */ +void MatrixCompress_destructor(parsec_taskpool_t *apTaskpool) +{ + parsec_MatrixCompress_taskpool_t *pTaskpool = (parsec_MatrixCompress_taskpool_t *)apTaskpool; + + parsec_del2arena(&pTaskpool->arenas_datatypes[PARSEC_MatrixCompress_FULL_ADT_IDX]); + parsec_del2arena(&pTaskpool->arenas_datatypes[PARSEC_MatrixCompress_UV_ADT_IDX]); + parsec_del2arena(&pTaskpool->arenas_datatypes[PARSEC_MatrixCompress_AR_ADT_IDX]); + + parsec_private_memory_fini(pTaskpool->_g_aUv_work ); + parsec_private_memory_fini(pTaskpool->_g_aD_work ); + parsec_private_memory_fini(pTaskpool->_g_aRsvaD_work ); + parsec_private_memory_fini(pTaskpool->_g_aRsvd_iwork ); + + parsec_taskpool_free(apTaskpool); +} + +/** + * Generate matrix + */ +void MatrixCompress(parsec_context_t *apContext, double *apNormGlobal, int aUpperLower, int aBandSizeDense, int aNT, + int aMaxRank, int aN, int aAdaptiveDecision, int aTolerance, int aSendFullTile, int aAutoBand, + int aGpus, hicma_parsec_data_t *data, starsh_params_t *params_kernel) +{ + + /* Only for 1 vp */ + assert(apContext->nb_vp == 1); + int nb_threads = apContext->virtual_processes[0]->nb_cores; + double *pNormTmp = (double *) calloc(sizeof(double), nb_threads); + + /* Make sure norm_tile and norm_global is fresh */ + double* pNormTile = (double*) malloc(aNT * aNT * sizeof(double)); + memset(pNormTile, 0, aNT * aNT * sizeof(double)); + // Make sure norm_tile and norm_global is fresh + *apNormGlobal = 0.0; + parsec_taskpool_t *pTaskpool = + MatrixCompress_constructor(aUpperLower, aBandSizeDense, aNT, aMaxRank, aN, pNormTmp, pNormTile, + aAdaptiveDecision, aTolerance, aSendFullTile, aAutoBand, aGpus, data, params_kernel); + + parsec_context_add_taskpool(apContext, pTaskpool); + parsec_context_start(apContext); + parsec_context_wait(apContext); + MatrixCompress_destructor(pTaskpool); + + /* Reduce to the global norm */ + double norm_process = 0.0; + for( int i = 0; i < nb_threads; i++ ) { + norm_process += pNormTmp[i]; + } + + MPI_Allreduce(MPI_IN_PLACE, pNormTile, aNT * aNT, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(&norm_process, apNormGlobal, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + *apNormGlobal = sqrt(*apNormGlobal); + + free(pNormTmp); + free(pNormTile); +} + +%} diff --git a/src/runtime/parsec/jdf/MeanSquaredError.jdf b/src/runtime/parsec/jdf/MeanSquaredError.jdf new file mode 100644 index 00000000..c925aff7 --- /dev/null +++ b/src/runtime/parsec/jdf/MeanSquaredError.jdf @@ -0,0 +1,96 @@ +extern "C" %{ +/* + * @copyright (c) 2023 King Abdullah University of Science and Technology (KAUST). + * @copyright (c) 2023 The Universiy of Tennessee and The Universiy of Tennessee Research Foundation. + * All rights reserved. + */ + +#include +#include + +static double NormCore(complex double *apDataA, double *apDataB, int aM, int aN, int aLSize) { + double result = 0.0, diff; + for(int j = 0; j < aN; j++) { + for(int i = 0; i < aM; i++) { + double diff = creal(apDataA[j*aM+i]) - apDataB[j*aM+i]; + result += diff * diff; + } + } + return sqrt(result) / (2*aLSize*(aLSize+1)); +} + +%} + +apFDataDesc [ type = "parsec_tiled_matrix_t*" ] +apFSpatialDesc [ type = "parsec_tiled_matrix_t*" aligned = apFDataDesc ] +aLSize [type="int"] + +task(n) + +n = 0 .. apFDataDesc->lnt-1 + +: apFDataDesc(0, n) + +READ f_data <- apFDataDesc(0, n) [ type = f_data ] +READ f_spatial <- apFSpatialDesc(0, n) [ type = f_spatial ] + +BODY +{ + double norm = NormCore(f_data, f_spatial, apFDataDesc->mb, apFDataDesc->nb, aLSize); +} +END + +extern "C" %{ + +/** + * @return the parsec object to schedule. + */ +parsec_taskpool_t* +MeanSquaredErrorConstructor( parsec_matrix_block_cyclic_t * apDataDesc, parsec_matrix_block_cyclic_t * apSpatialDesc, int aLSize) +{ + int mb = apDataDesc->super.mb; + int nb = apDataDesc->super.nb; + parsec_MeanSquaredError_taskpool_t *pTaskpool = parsec_MeanSquaredError_new(&apDataDesc->super, &apSpatialDesc->super, aLSize); + + parsec_add2arena(&pTaskpool->arenas_datatypes[PARSEC_MeanSquaredError_f_data_ADT_IDX], + parsec_datatype_double_complex_t, PARSEC_MATRIX_FULL, + 1, mb, nb, mb, + PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + parsec_add2arena(&pTaskpool->arenas_datatypes[PARSEC_MeanSquaredError_f_spatial_ADT_IDX], + parsec_datatype_double_t, PARSEC_MATRIX_FULL, + 1, mb, nb, mb, + PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + return (parsec_taskpool_t*)pTaskpool; +} + +/** + * @param [inout] the parsec object to destroy +*/ +void MeanSquaredErrorDestructor(parsec_taskpool_t *apTaskpool) +{ + parsec_MeanSquaredError_taskpool_t *pTaskpool = (parsec_MeanSquaredError_taskpool_t *)apTaskpool; + parsec_del2arena(&pTaskpool->arenas_datatypes[PARSEC_MeanSquaredError_f_data_ADT_IDX]); + parsec_del2arena(&pTaskpool->arenas_datatypes[PARSEC_MeanSquaredError_f_spatial_ADT_IDX]); + parsec_taskpool_free(apTaskpool); +} + +/** + */ +int MeanSquaredError(parsec_context_t *apContext, parsec_matrix_block_cyclic_t* apDataDesc, + parsec_matrix_block_cyclic_t* apSpatialDesc, int aLSize) +{ + parsec_taskpool_t *pParsec_MeanSquaredError = NULL; + pParsec_MeanSquaredError = MeanSquaredErrorConstructor(apDataDesc, apSpatialDesc, aLSize); + if( pParsec_MeanSquaredError != NULL ){ + parsec_context_add_taskpool(apContext, pParsec_MeanSquaredError); + parsec_context_start(apContext); + parsec_context_wait(apContext); + MeanSquaredErrorDestructor(pParsec_MeanSquaredError); + } + + return 0; +} + +%} diff --git a/src/runtime/parsec/jdf/ReadCSV.jdf b/src/runtime/parsec/jdf/ReadCSV.jdf new file mode 100644 index 00000000..475f27de --- /dev/null +++ b/src/runtime/parsec/jdf/ReadCSV.jdf @@ -0,0 +1,123 @@ + +extern "C" %{ +/* + * @copyright (c) 2023 King Abdullah University of Science and Technology (KAUST). + * @copyright (c) 2023 The Universiy of Tennessee and The Universiy of Tennessee Research Foundation. + * All rights reserved. + */ + +#include +#include + +static int ReadCSVCore(const char* apFilename, double *apData, int aM, int aN, int aGpus) { + + FILE *pFile = fopen(apFilename, "r"); + if (!pFile) { + printf("File opening failed: %s", apFilename); + return -1; + } + + int status = 0; + if( 0 == aGpus ) { + complex double *pData = (complex double *)apData; + for (int i = 0; i < aM; i++) { + for (int j = 0; j < aN; j++) { + // Assuming the CSV data is separated by commas, + // fscanf can be used to read directly into the array. + status = fscanf(pFile, "%lf,", &apData[j*aM+i]); +#if DEBUG_INFO_GB24 + if (status != 1) { + fprintf(stderr, "Error reading file at row %d, column %d\n", i, j); + fclose(pFile); + return 1; + } +#endif + } + } + } + fclose(pFile); + return 0; +} + +%} + +pDescA [ type = "parsec_tiled_matrix_t*" ] +pFilename [ type = "char *" ] +nb_gpus [ type = "int" ] + +task(m, n) + +m = 0 .. pDescA->lmt-1 +n = 0 .. pDescA->lnt-1 + +: pDescA(m, n) + +RW A <- pDescA(m, n) + -> pDescA(m, n) + +BODY +{ + ReadCSVCore(pFilename, A, pDescA->mb, pDescA->nb, nb_gpus); + if(0 == nb_gpus) SumDoubleData(A, pDescA->mb, pDescA->nb); +} +END + +extern "C" %{ + +/** + * @return the parsec object to schedule. + */ +parsec_taskpool_t* ReadCSVConstructor(parsec_matrix_block_cyclic_t *apDesc, int aMB, int aNB, int aNodes, + int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus) { + + // Init and allocate memory + int kq = (aTimeSlot%aNodes)? aTimeSlot/aNodes+1 : aTimeSlot/aNodes; + parsec_matrix_block_cyclic_init(apDesc, PARSEC_MATRIX_DOUBLE, PARSEC_MATRIX_TILE, aRank, aMB, aNB, aMB, + aNB*aNodes, 0, 0, aMB, aNB*aNodes, 1, aNodes, 1, kq, 0, 0); + + apDesc->mat = parsec_data_allocate((size_t)apDesc->super.nb_local_tiles * + (size_t)apDesc->super.bsiz * + (size_t)parsec_datadist_getsizeoftype(apDesc->super.mtype)); + + if(NULL == apFilename) { + parsec_data_collection_set_key((parsec_data_collection_t*)apDesc, "desc"); + VERBOSE_PRINT(aRank, aVerbose, ("FileName is NULL\n")); + return NULL; + } + parsec_data_collection_set_key((parsec_data_collection_t*)apDesc, apFilename); + parsec_ReadCSV_taskpool_t *taskpool = parsec_ReadCSV_new(&apDesc->super, apFilename, aGpus); + + parsec_add2arena(&taskpool->arenas_datatypes[PARSEC_ReadCSV_DEFAULT_ADT_IDX], + parsec_datatype_double_complex_t, PARSEC_MATRIX_FULL, + 1, aMB, aNB, aMB, PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + return (parsec_taskpool_t*)taskpool; +} + +/** + * @param [inout] the parsec object to destroy +*/ +void ReadCSVDestructor(parsec_taskpool_t *pTaskpool) +{ + parsec_ReadCSV_taskpool_t *ReadCSV_taskpool = (parsec_ReadCSV_taskpool_t *)pTaskpool; + parsec_del2arena(&ReadCSV_taskpool->arenas_datatypes[PARSEC_ReadCSV_DEFAULT_ADT_IDX]); + parsec_taskpool_free(pTaskpool); +} + +int ReadCSV(parsec_context_t *apContext, parsec_matrix_block_cyclic_t *apDesc, int aMB, int aNB, int aNodes, + int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus) +{ + VERBOSE_PRINT(aRank, aVerbose, ("Reading %s\n", apFilename)); + parsec_taskpool_t *pTaskpool = ReadCSVConstructor(apDesc, aMB, aNB, aNodes, aTimeSlot, + apFilename, aRank, aVerbose, aGpus); + + if(pTaskpool != NULL ){ + parsec_context_add_taskpool(apContext, pTaskpool); + parsec_context_start(apContext); + parsec_context_wait(apContext); + ReadCSVDestructor(pTaskpool); + } + return 0; +} + +%} diff --git a/src/runtime/parsec/jdf/ReadCSVComplex.jdf b/src/runtime/parsec/jdf/ReadCSVComplex.jdf new file mode 100644 index 00000000..5d4196c2 --- /dev/null +++ b/src/runtime/parsec/jdf/ReadCSVComplex.jdf @@ -0,0 +1,133 @@ + +extern "C" %{ +/* + * @copyright (c) 2023 King Abdullah University of Science and Technology (KAUST). + * @copyright (c) 2023 The Universiy of Tennessee and The Universiy of Tennessee Research Foundation. + * All rights reserved. + */ + +#include +#include + +static int ReadCSVComplexCore(const char* apFilename, complex double *apData, int aM, int aN, int aGpus) { + + FILE *pFile = fopen(apFilename, "r"); + if (!pFile) { + printf("File opening failed: %s", apFilename); + return -1; + } + + size_t len = 0, row = 0; + ssize_t read; + double real, imag; + int status; + + if( 0 == aGpus ) { + complex double *pData = (complex double *)apData; + for (int i = 0; i < aM; i++) { + for (int j = 0; j < aN; j++) { + status = fscanf(pFile, "%lf%lfi,", &real, &imag); + pData[j*aM+i] = real + imag * I; + } + } + } else { + +#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) || defined(PARSEC_HAVE_DEV_HIP_SUPPORT) + cuDoubleComplex *pData = (cuDoubleComplex *)apData; + for (int i = 0; i < aM; i++) { + for (int j = 0; j < aN; j++) { + // Assuming the CSV data is separated by commas, + // fscanf can be used to read directly into the array. + status = fscanf(pFile, "%lf%lfi,", &real, &imag); + pData[j*aM+i] = make_cuDoubleComplex(real, imag); + } + } +#endif + } + + + fclose(pFile); + return 0; +} + +%} + +pDescA [ type = "parsec_tiled_matrix_t*" ] +pFilename [ type = "char *" ] +nb_gpus [ type = "int" ] + +task(m, n) + +m = 0 .. pDescA->lmt-1 +n = 0 .. pDescA->lnt-1 + +: pDescA(m, n) + +RW A <- pDescA(m, n) + -> pDescA(m, n) + +BODY +{ + ReadCSVComplexCore(pFilename, A, pDescA->mb, pDescA->nb, nb_gpus); + if(0 == nb_gpus) SumComplexData(A, pDescA->mb, pDescA->nb); +} +END + +extern "C" %{ + +/** + * @return the parsec object to schedule. + */ +parsec_taskpool_t* ReadCSVComplexConstructor(parsec_matrix_block_cyclic_t *apDesc, int aMB, + int aNB, int aNodes, int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus) { + + // Init and allocate memory + parsec_matrix_block_cyclic_init(apDesc, PARSEC_MATRIX_COMPLEX_DOUBLE, PARSEC_MATRIX_TILE, aRank, aMB, aNB, aMB, + aNB*aNodes, 0, 0, aMB, aNB*aNodes, 1, aNodes, 1, 1, 0, 0); + + apDesc->mat = parsec_data_allocate((size_t)apDesc->super.nb_local_tiles * + (size_t)apDesc->super.bsiz * + (size_t)parsec_datadist_getsizeoftype(apDesc->super.mtype)); + + if(NULL == apFilename) { + parsec_data_collection_set_key((parsec_data_collection_t*)apDesc, "desc"); + VERBOSE_PRINT(aRank, aVerbose, ("FileName is NULL\n")); + return NULL; + } + parsec_data_collection_set_key((parsec_data_collection_t*)apDesc, apFilename); + parsec_ReadCSVComplex_taskpool_t *taskpool = parsec_ReadCSVComplex_new(&apDesc->super, apFilename, aGpus); + + parsec_add2arena(&taskpool->arenas_datatypes[PARSEC_ReadCSVComplex_DEFAULT_ADT_IDX], + parsec_datatype_double_complex_t, PARSEC_MATRIX_FULL, + 1, aMB, aNB, aMB, PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + return (parsec_taskpool_t*)taskpool; +} + +/** + * @param [inout] the parsec object to destroy +*/ +void ReadCSVComplexDestructor(parsec_taskpool_t *pTaskpool) +{ + parsec_ReadCSVComplex_taskpool_t *ReadCSVComplex_taskpool = (parsec_ReadCSVComplex_taskpool_t *)pTaskpool; + parsec_del2arena(&ReadCSVComplex_taskpool->arenas_datatypes[PARSEC_ReadCSVComplex_DEFAULT_ADT_IDX]); + parsec_taskpool_free(pTaskpool); +} + +int ReadCSVComplex(parsec_context_t *apContext, parsec_matrix_block_cyclic_t *apDesc, int aMB, int aNB, int aNodes, + int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus) +{ + VERBOSE_PRINT(aRank, aVerbose, ("Reading %s\n", apFilename)); + parsec_taskpool_t *pTaskpool = ReadCSVComplexConstructor(apDesc, aMB, aNB, aNodes, aTimeSlot, + apFilename, aRank, aVerbose, aGpus); + + if(pTaskpool != NULL ){ + parsec_context_add_taskpool(apContext, pTaskpool); + parsec_context_start(apContext); + parsec_context_wait(apContext); + ReadCSVComplexDestructor(pTaskpool); + } + return 0; +} + +%} diff --git a/src/runtime/parsec/jdf/ReadCSVTimeSlot.jdf b/src/runtime/parsec/jdf/ReadCSVTimeSlot.jdf new file mode 100644 index 00000000..eeba2c8c --- /dev/null +++ b/src/runtime/parsec/jdf/ReadCSVTimeSlot.jdf @@ -0,0 +1,123 @@ + +extern "C" %{ +/* + * @copyright (c) 2023 King Abdullah University of Science and Technology (KAUST). + * @copyright (c) 2023 The Universiy of Tennessee and The Universiy of Tennessee Research Foundation. + * All rights reserved. + */ + +#include +#include + +static int ReadCSVTimeSlotCore(const char* apFilename, double *apData, int aM, int aN, int aGpus) { + + FILE *pFile = fopen(apFilename, "r"); + if (!pFile) { + printf("File opening failed: %s", apFilename); + return -1; + } + + int status = 0; + if( 0 == aGpus ) { + complex double *pData = (complex double *)apData; + for (int i = 0; i < aM; i++) { + for (int j = 0; j < aN; j++) { + // Assuming the CSV data is separated by commas, + // fscanf can be used to read directly into the array. + status = fscanf(pFile, "%lf,", &apData[j*aM+i]); +#if DEBUG_INFO_GB24 + if (status != 1) { + fprintf(stderr, "Error reading file at row %d, column %d\n", i, j); + fclose(pFile); + return 1; + } +#endif + } + } + } + fclose(pFile); + return 0; +} + +%} + +pDescA [ type = "parsec_tiled_matrix_t*" ] +pFilename [ type = "char *" ] +nb_gpus [ type = "int" ] + +task(m, n) + +m = 0 .. pDescA->lmt-1 +n = 0 .. pDescA->lnt-1 + +: pDescA(m, n) + +RW A <- pDescA(m, n) + -> pDescA(m, n) + +BODY +{ + ReadCSVTimeSlotCore(pFilename, A, pDescA->mb, pDescA->nb, nb_gpus); + if(0 == nb_gpus) SumDoubleData(A, pDescA->mb, pDescA->nb); +} +END + +extern "C" %{ + +/** + * @return the parsec object to schedule. + */ +parsec_taskpool_t* ReadCSVTimeSlotConstructor(parsec_matrix_block_cyclic_t *apDesc, int aMB, int aNB, int aNodes, + int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus) { + + // Init and allocate memory + int kq = (aTimeSlot%aNodes)? aTimeSlot/aNodes+1 : aTimeSlot/aNodes; + parsec_matrix_block_cyclic_init(apDesc, PARSEC_MATRIX_DOUBLE, PARSEC_MATRIX_TILE, aRank, aMB, aNB, aMB, + aNB*aTimeSlot, 0, 0, aMB, aNB*aTimeSlot, 1, aNodes, 1, kq, 0, 0); + + apDesc->mat = parsec_data_allocate((size_t)apDesc->super.nb_local_tiles * + (size_t)apDesc->super.bsiz * + (size_t)parsec_datadist_getsizeoftype(apDesc->super.mtype)); + + if(NULL == apFilename) { + parsec_data_collection_set_key((parsec_data_collection_t*)apDesc, "desc"); + VERBOSE_PRINT(aRank, aVerbose, ("FileName is NULL\n")); + return NULL; + } + parsec_data_collection_set_key((parsec_data_collection_t*)apDesc, apFilename); + parsec_ReadCSVTimeSlot_taskpool_t *taskpool = parsec_ReadCSVTimeSlot_new(&apDesc->super, apFilename, aGpus); + + parsec_add2arena(&taskpool->arenas_datatypes[PARSEC_ReadCSVTimeSlot_DEFAULT_ADT_IDX], + parsec_datatype_double_complex_t, PARSEC_MATRIX_FULL, + 1, aMB, aNB, aMB, PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + return (parsec_taskpool_t*)taskpool; +} + +/** + * @param [inout] the parsec object to destroy +*/ +void ReadCSVTimeSlotDestructor(parsec_taskpool_t *pTaskpool) +{ + parsec_ReadCSVTimeSlot_taskpool_t *ReadCSVTimeSlot_taskpool = (parsec_ReadCSVTimeSlot_taskpool_t *)pTaskpool; + parsec_del2arena(&ReadCSVTimeSlot_taskpool->arenas_datatypes[PARSEC_ReadCSVTimeSlot_DEFAULT_ADT_IDX]); + parsec_taskpool_free(pTaskpool); +} + +int ReadCSVTimeSlot(parsec_context_t *apContext, parsec_matrix_block_cyclic_t *apDesc, int aMB, int aNB, int aNodes, + int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus) +{ + VERBOSE_PRINT(aRank, aVerbose, ("Reading %s\n", apFilename)); + parsec_taskpool_t *pTaskpool = ReadCSVTimeSlotConstructor(apDesc, aMB, aNB, aNodes, aTimeSlot, + apFilename, aRank, aVerbose, aGpus); + + if(pTaskpool != NULL ){ + parsec_context_add_taskpool(apContext, pTaskpool); + parsec_context_start(apContext); + parsec_context_wait(apContext); + ReadCSVTimeSlotDestructor(pTaskpool); + } + return 0; +} + +%} diff --git a/src/runtime/parsec/jdf/ReadCSVToComplex.jdf b/src/runtime/parsec/jdf/ReadCSVToComplex.jdf new file mode 100644 index 00000000..2aa68c3d --- /dev/null +++ b/src/runtime/parsec/jdf/ReadCSVToComplex.jdf @@ -0,0 +1,130 @@ + +extern "C" %{ +/* + * @copyright (c) 2023 King Abdullah University of Science and Technology (KAUST). + * @copyright (c) 2023 The Universiy of Tennessee and The Universiy of Tennessee Research Foundation. + * All rights reserved. + */ + +#include +#include + +static int ReadCSVToComplexCore(const char* apFilename, void *apData, int aM, int aN, int aGpus) { + + FILE *pFile = fopen(apFilename, "r"); + if (!pFile) { + printf("File opening failed: %s", apFilename); + return -1; + } + + double real; + int status; + if( 0 == aGpus ) { + complex double *pData = (complex double *)apData; + for (int i = 0; i < aM; i++) { + for (int j = 0; j < aN; j++) { + status = fscanf(pFile, "%lf,", &real); + pData[j*aM+i] = (complex double)real; + } + } + } else { + +#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) || defined(PARSEC_HAVE_DEV_HIP_SUPPORT) + cuDoubleComplex *pData = (cuDoubleComplex *)apData; + for (int i = 0; i < aM; i++) { + for (int j = 0; j < aN; j++) { + // Assuming the CSV data is separated by commas, + // fscanf can be used to read directly into the array. + status = fscanf(pFile, "%lf,", &real); + pData[j*aM+i] = make_cuDoubleComplex(real, 0); + } + } +#endif + } + + + fclose(pFile); + return 0; +} + +%} + +pDescA [ type = "parsec_tiled_matrix_t*" ] +pFilename [ type = "char *" ] +nb_gpus [ type = "int" ] + +task(m, n) + +m = 0 .. pDescA->lmt-1 +n = 0 .. pDescA->lnt-1 + +: pDescA(m, n) + +RW A <- pDescA(m, n) + -> pDescA(m, n) + +BODY +{ + ReadCSVToComplexCore(pFilename, A, pDescA->mb, pDescA->nb, nb_gpus); + if(0 == nb_gpus) SumComplexData(A, pDescA->mb, pDescA->nb); +} +END + +extern "C" %{ + +/** + * @return the parsec object to schedule. + */ +parsec_taskpool_t* ReadCSVToComplexConstructor(parsec_matrix_block_cyclic_t *apDesc, int aMB, + int aNB, int aNodes, int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus) { + + // Init and allocate memory + parsec_matrix_block_cyclic_init(apDesc, PARSEC_MATRIX_COMPLEX_DOUBLE, PARSEC_MATRIX_TILE, aRank, aMB, aNB, aMB, + aNB*aNodes, 0, 0, aMB, aNB*aNodes, 1, aNodes, 1, 1, 0, 0); + + apDesc->mat = parsec_data_allocate((size_t)apDesc->super.nb_local_tiles * + (size_t)apDesc->super.bsiz * + (size_t)parsec_datadist_getsizeoftype(apDesc->super.mtype)); + + if(NULL == apFilename) { + parsec_data_collection_set_key((parsec_data_collection_t*)apDesc, "desc"); + VERBOSE_PRINT(aRank, aVerbose, ("FileName is NULL\n")); + return NULL; + } + parsec_data_collection_set_key((parsec_data_collection_t*)apDesc, apFilename); + parsec_ReadCSVToComplex_taskpool_t *taskpool = parsec_ReadCSVToComplex_new(&apDesc->super, apFilename, aGpus); + + parsec_add2arena(&taskpool->arenas_datatypes[PARSEC_ReadCSVToComplex_DEFAULT_ADT_IDX], + parsec_datatype_double_complex_t, PARSEC_MATRIX_FULL, + 1, aMB, aNB, aMB, PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + return (parsec_taskpool_t*)taskpool; +} + +/** + * @param [inout] the parsec object to destroy +*/ +void ReadCSVToComplexDestructor(parsec_taskpool_t *pTaskpool) +{ + parsec_ReadCSVToComplex_taskpool_t *ReadCSVToComplex_taskpool = (parsec_ReadCSVToComplex_taskpool_t *)pTaskpool; + parsec_del2arena(&ReadCSVToComplex_taskpool->arenas_datatypes[PARSEC_ReadCSVToComplex_DEFAULT_ADT_IDX]); + parsec_taskpool_free(pTaskpool); +} + +int ReadCSVToComplex(parsec_context_t *apContext, parsec_matrix_block_cyclic_t *apDesc, int aMB, int aNB, int aNodes, + int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus) +{ + VERBOSE_PRINT(aRank, aVerbose, ("Reading %s\n", apFilename)); + parsec_taskpool_t *pTaskpool = ReadCSVToComplexConstructor(apDesc, aMB, aNB, aNodes, aTimeSlot, + apFilename, aRank, aVerbose, aGpus); + + if(pTaskpool != NULL ){ + parsec_context_add_taskpool(apContext, pTaskpool); + parsec_context_start(apContext); + parsec_context_wait(apContext); + ReadCSVToComplexDestructor(pTaskpool); + } + return 0; +} + +%} diff --git a/src/runtime/parsec/jdf/ReadCSVToComplexTimeSlot.jdf b/src/runtime/parsec/jdf/ReadCSVToComplexTimeSlot.jdf new file mode 100644 index 00000000..dc3cb4a3 --- /dev/null +++ b/src/runtime/parsec/jdf/ReadCSVToComplexTimeSlot.jdf @@ -0,0 +1,154 @@ + +extern "C" %{ +/* + * @copyright (c) 2023 King Abdullah University of Science and Technology (KAUST). + * @copyright (c) 2023 The Universiy of Tennessee and The Universiy of Tennessee Research Foundation. + * All rights reserved. + */ + +#include +#include + +static int ReadCSVToComplexTimeSlotCore(const char* apFilename, void *apData, int aM, int aN, int aGpus) { + + FILE *pFile = fopen(apFilename, "r"); + if (!pFile) { + printf("File opening failed: %s", apFilename); + return -1; + } + + int status = 0; + double real; + if( 0 == aGpus ) { + complex double *pData = (complex double *)apData; + for (int i = 0; i < aM; i++) { + for (int j = 0; j < aN; j++) { + // Assuming the CSV data is separated by commas, + // fscanf can be used to read directly into the array. + status = fscanf(pFile, "%lf\n", &real); + pData[j*aM+i] = (complex double)real; +#if DEBUG_INFO_GB24 + if (status != 1) { + fprintf(stderr, "Error reading file at row %d, column %d\n", i, j); + fclose(pFile); + return 1; + } +#endif + } + } + +#if DEBUG_INFO_GB24 + climate_emulator_print_matrix_col_complex(pData, 10, 10, aM); +#endif + + + } else { + +#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) || defined(PARSEC_HAVE_DEV_HIP_SUPPORT) + cuDoubleComplex *pData = (cuDoubleComplex *)apData; + for (int i = 0; i < aM; i++) { + for (int j = 0; j < aN; j++) { + // Assuming the CSV data is separated by commas, + // fscanf can be used to read directly into the array. + status = fscanf(pFile, "%lf,", &real); + pData[j*aM+i] = make_cuDoubleComplex(real, 0); +#if DEBUG_INFO_GB24 + if (status != 1) { + fprintf(stderr, "Error reading file at row %d, column %d\n", i, j); + fclose(pFile); + return 1; + } +#endif + } + } +#endif + + } + fclose(pFile); + return 0; +} + +%} + +pDescA [ type = "parsec_tiled_matrix_t*" ] +pFilename [ type = "char *" ] +nb_gpus [ type = "int" ] + +task(m, n) + +m = 0 .. pDescA->lmt-1 +n = 0 .. pDescA->lnt-1 + +: pDescA(m, n) + +RW A <- pDescA(m, n) + -> pDescA(m, n) + +BODY +{ + char *pFileZ_data = (char *) malloc(200 * sizeof(char)); + snprintf(pFileZ_data, 200, "%s%s%d%s", pFilename,"/z_", n, ".csv"); + ReadCSVToComplexTimeSlotCore(pFileZ_data, A, pDescA->mb, pDescA->nb, nb_gpus); + if(0 == nb_gpus) SumComplexData(A, pDescA->mb, pDescA->nb); +} +END + +extern "C" %{ + +/** + * @return the parsec object to schedule. + */ +parsec_taskpool_t* ReadCSVToComplexTimeSlotConstructor(parsec_matrix_block_cyclic_t *apDesc, int aMB, int aNB, int aNodes, + int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus) { + + // Init and allocate memory + int kq = (aTimeSlot%aNodes)? aTimeSlot/aNodes+1 : aTimeSlot/aNodes; + parsec_matrix_block_cyclic_init(apDesc, PARSEC_MATRIX_COMPLEX_DOUBLE, PARSEC_MATRIX_TILE, aRank, aMB, aNB, aMB, + aNB*aTimeSlot, 0, 0, aMB, aNB*aTimeSlot, 1, aNodes, 1, kq, 0, 0); + + apDesc->mat = parsec_data_allocate((size_t)apDesc->super.nb_local_tiles * + (size_t)apDesc->super.bsiz * + (size_t)parsec_datadist_getsizeoftype(apDesc->super.mtype)); + + if(NULL == apFilename) { + parsec_data_collection_set_key((parsec_data_collection_t*)apDesc, "desc"); + VERBOSE_PRINT(aRank, aVerbose, ("FileName is NULL\n")); + return NULL; + } + parsec_data_collection_set_key((parsec_data_collection_t*)apDesc, apFilename); + parsec_ReadCSVToComplexTimeSlot_taskpool_t *taskpool = parsec_ReadCSVToComplexTimeSlot_new(&apDesc->super, apFilename, aGpus); + + parsec_add2arena(&taskpool->arenas_datatypes[PARSEC_ReadCSVToComplexTimeSlot_DEFAULT_ADT_IDX], + parsec_datatype_double_complex_t, PARSEC_MATRIX_FULL, + 1, aMB, aNB, aMB, PARSEC_ARENA_ALIGNMENT_SSE, -1 ); + + return (parsec_taskpool_t*)taskpool; +} + +/** + * @param [inout] the parsec object to destroy +*/ +void ReadCSVToComplexTimeSlotDestructor(parsec_taskpool_t *pTaskpool) +{ + parsec_ReadCSVToComplexTimeSlot_taskpool_t *ReadCSVToComplexTimeSlot_taskpool = (parsec_ReadCSVToComplexTimeSlot_taskpool_t *)pTaskpool; + parsec_del2arena(&ReadCSVToComplexTimeSlot_taskpool->arenas_datatypes[PARSEC_ReadCSVToComplexTimeSlot_DEFAULT_ADT_IDX]); + parsec_taskpool_free(pTaskpool); +} + +int ReadCSVToComplexTimeSlot(parsec_context_t *apContext, parsec_matrix_block_cyclic_t *apDesc, int aMB, int aNB, int aNodes, + int aTimeSlot, char *apFilename, int aRank, int aVerbose, int aGpus) +{ + VERBOSE_PRINT(aRank, aVerbose, ("Reading %s\n", apFilename)); + parsec_taskpool_t *pTaskpool = ReadCSVToComplexTimeSlotConstructor(apDesc, aMB, aNB, aNodes, aTimeSlot, + apFilename, aRank, aVerbose, aGpus); + + if(pTaskpool != NULL ){ + parsec_context_add_taskpool(apContext, pTaskpool); + parsec_context_start(apContext); + parsec_context_wait(apContext); + ReadCSVToComplexTimeSlotDestructor(pTaskpool); + } + return 0; +} + +%} diff --git a/tests/cpp-tests/configurations/TestConfigurations.cpp b/tests/cpp-tests/configurations/TestConfigurations.cpp index cfe0afa8..2ce15865 100644 --- a/tests/cpp-tests/configurations/TestConfigurations.cpp +++ b/tests/cpp-tests/configurations/TestConfigurations.cpp @@ -63,7 +63,6 @@ void TEST_ARGUMENT_INITIALIZATION() { // No data modeling arguments initialized REQUIRE_THROWS(configurations.GetMaxMleIterations()); - REQUIRE_THROWS(configurations.GetTolerance()); // No data prediction arguments initialized REQUIRE(configurations.GetIsMSPE() == false); @@ -133,6 +132,10 @@ void TEST_ARGUMENT_INITIALIZATION_PARSEC() { // No data generation arguments initialized REQUIRE(configurations.GetDataPath() == string("")); + + // Passing an empty data path throws an exception + REQUIRE_THROWS(configurations.InitializeDataGenerationArguments()); + } @@ -208,7 +211,7 @@ void TEST_COPY_CONSTRUCTOR() { Configurations synthetic_data_configurations; synthetic_data_configurations.SetProblemSize(10); synthetic_data_configurations.SetKernelName("BivariateSpacetimeMaternStationary"); - synthetic_data_configurations.SetPrecision(exageostat::common::MIXED); + synthetic_data_configurations.SetPrecision(MIXED); synthetic_data_configurations.SetLoggerPath("any/path"); vector lb{0.1, 0.1, 0.1}; synthetic_data_configurations.SetLowerBounds(lb); From fca2af0923ae833ff4f939e7910429a88f5accdc Mon Sep 17 00:00:00 2001 From: Mahmoud ElKarargy Date: Tue, 18 Mar 2025 16:30:45 +0200 Subject: [PATCH 4/5] update climate emulator --- .gitlab-ci.yml | 26 + CMakeLists.txt | 19 +- README.md | 128 +++- USER_MANUAL.md | 15 +- cmake/ImportNlohmannJSON.cmake | 39 ++ configurations/config.json | 47 ++ configure | 22 +- .../SyntheticDataGeneration.cpp | 1 - examples/data-loader/CSVLoader.cpp | 1 - .../Rcpp-adapters/FunctionsAdapter.hpp | 3 +- .../include/configurations/Configurations.hpp | 356 ++++------- inst/include/configurations/Parser.hpp | 61 ++ inst/include/configurations/Validator.hpp | 141 +++++ inst/include/results/Results.hpp | 132 ++-- man/model_data.Rd | 3 +- src/Rcpp-adapters/FunctionsAdapter.cpp | 29 +- src/Rcpp-adapters/RcppModules.cpp | 2 +- src/api/ExaGeoStat.cpp | 12 +- src/configurations/CMakeLists.txt | 2 + src/configurations/Configurations.cpp | 592 +++--------------- src/configurations/Parser.cpp | 81 +++ src/configurations/Validator.cpp | 320 ++++++++++ src/data-loader/concrete/ParsecLoader.cpp | 23 +- src/data-units/Locations.cpp | 6 +- .../chameleon/dense/ChameleonDense.cpp | 4 + .../concrete/tlr/HicmaImplementation.cpp | 1 + src/prediction/Prediction.cpp | 5 + src/results/Results.cpp | 183 +++--- src/runtime/parsec/jdf/ForwardSHT.jdf | 8 +- src/runtime/parsec/jdf/ForwardSHTReshape.jdf | 2 +- src/runtime/parsec/jdf/InverseSHT.jdf | 4 +- tests/R-tests/TestExaGeoStatAPI.R | 17 +- .../configurations/TestConfigurations.cpp | 74 +-- tests/cpp-tests/prediction/TestPrediction.cpp | 11 +- 34 files changed, 1317 insertions(+), 1053 deletions(-) create mode 100644 .gitlab-ci.yml create mode 100644 cmake/ImportNlohmannJSON.cmake create mode 100644 configurations/config.json create mode 100644 inst/include/configurations/Parser.hpp create mode 100644 inst/include/configurations/Validator.hpp create mode 100644 src/configurations/Parser.cpp create mode 100644 src/configurations/Validator.cpp diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..91585aba --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,26 @@ +stages: + - compile + +variables: + GIT_STRATEGY: clone + GIT_SUBMODULE_STRATEGY: normal + ARTIFACTS_NAME: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" + ARTIFACTS_PATH: bin.tar + +.compile-job: &compile-job + stage: compile + artifacts: + when: on_success + name: $ARTIFACTS_NAME + expire_in: 1h + paths: + - bin.tar + script: + - echo -e "Script Arguments:\t $CONFIG_ARGS" + +compile:cpp: + <<: *compile-job + image: acai-oneapi + tags: + - acai-cpu + diff --git a/CMakeLists.txt b/CMakeLists.txt index d08c78c6..2815745a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,11 @@ project(ExaGeoStatCPP VERSION 2.0.0 DESCRIPTION "ExaGeoStatCPP is a parallel hig set(CMAKE_CXX_EXTENSIONS OFF) string(TOUPPER ${RUNTIME_TYPE} RUNTIME_TYPE) +# Default path for default configuration json file +add_definitions( + -DDEFAULT_CONFIGURATION_PATH="${PROJECT_SOURCE_DIR}/configurations/config.json" +) + if(RUNTIME_TYPE STREQUAL "PARSEC") message(STATUS "MPI is required to be enabled in order to use PaRSEC") set(USE_MPI ON) @@ -107,6 +112,11 @@ list(APPEND LIBS ${LAPACKE_LIBRARIES}) link_directories(${LAPACKE_LIBRARY_DIRS_DEP}) include_directories(${LAPACKE_INCLUDE_DIRS}) +if (${BLA_VENDOR} MATCHES "Intel10_64lp" OR ${BLA_VENDOR} MATCHES "Intel" OR ${BLA_VENDOR} MATCHES "Intel10_64lp_seq") + message(STATUS "Linked to MKL") + add_compile_definitions(USE_MKL) +endif() + # Add all dependencies for ExaGeoStatCPP #----------------------------- @@ -119,6 +129,10 @@ include(ImportHwloc) list(APPEND STARPU_COMPONENT_LIST "HWLOC") string(REPLACE ";" " " STARPU_COMPONENT_STRING "${STARPU_COMPONENT_LIST}") +# ExaGeoStatCPP depends on NLOHMANN +# ------------------------------- +include(ImportNlohmannJSON) + # ExaGeoStatCPP depends on NLOPT # ------------------------------- include(ImportNLOPT) @@ -185,7 +199,7 @@ if (USE_R) if (${R_FOUND}) message(STATUS "Using R technology") list(APPEND LIBS R) - add_definitions(-DUSING_R) + add_definitions(-DUSE_R) endif () endif () @@ -240,6 +254,7 @@ endif () message(" \n \t ** Configurations of ExaGeoStatCPP and installation of dependence is done successfully ** ") message("\t - Export the following line to avoid re-install dependencies each time. -") message("\t ----------------------------------------------------------------------------------------------------------------------------------- ") +message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/NLOHMANN_JSON/share/pkgconfig:$PKG_CONFIG_PATH") message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/HWLOC/lib/pkgconfig:$PKG_CONFIG_PATH") message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/NLOPT/lib/pkgconfig:${CMAKE_INSTALL_PREFIX}/NLOPT/lib64/pkgconfig:$PKG_CONFIG_PATH") message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/GSL/lib/pkgconfig:$PKG_CONFIG_PATH") @@ -254,7 +269,7 @@ if(RUNTIME_TYPE STREQUAL "STARPU") elseif(RUNTIME_TYPE STREQUAL "PARSEC") message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/STARSH/lib/pkgconfig:$PKG_CONFIG_PATH") message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/HCORE/lib/pkgconfig:$PKG_CONFIG_PATH") - message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/HICMA-X/lib/pkgconfig:${CMAKE_INSTALL_PREFIX}/HICMA-X/lib64:$PKG_CONFIG_PATH") + message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/HICMA-X/lib/pkgconfig:${CMAKE_INSTALL_PREFIX}/HICMA-X/lib64/pkgconfig:${CMAKE_INSTALL_PREFIX}/HICMA-X/lib64:$PKG_CONFIG_PATH") endif() message("\t ----------------------------------------------------------------------------------------------------------------------------------- \n") diff --git a/README.md b/README.md index 3f699598..8c5636fe 100644 --- a/README.md +++ b/README.md @@ -55,10 +55,18 @@ statisticians with modest computational resources. ## Installation -> Note: Installation requires at least **CMake of version 3.2**. to build ExaGeoStatCPP. +### Requirements +To build and run this software, you will need: + +1. [CMake](https://cmake.org/download/) (version 3.2 or higher) +2. [wget](https://www.gnu.org/software/wget/) +3. **gcc** and **g++** compilers +4. **autoconf** and **automake** +5. [libtool](https://www.gnu.org/software/libtool/) +6. [R](https://cran.r-project.org/bin/windows/base/) (only if you plan on using the R functionality) ### C++ source code installation -To install the `ExaGeoStat` project locally, run the following commands in your terminal: +To install the `ExaGeoStatCPP` project locally (C++ version), run the following commands in your terminal: 1. Clone the project repository to your local machine: ```bash @@ -70,14 +78,14 @@ To install the `ExaGeoStat` project locally, run the following commands in your cd ExaGeoStatCPP ``` -3. Run `configure` script with the flag `-h` for help, to know the supported options and their corresponding flags. +3. Run `configure` script (use the `-h` flag for help, to know the supported options and their corresponding flags). This step is **not required** when using R. ```bash - ./configure -h + ./configure -e ``` -4. Run `clean_build.sh` script with the flag `-h` for help, to know the needed arguments to run with your specific options. +4. Run `clean_build.sh` (use the `-h` flag for help, to know the needed arguments to run with your specific options). This step is **not required** when using R. ```bash - ./clean_build.sh -h + ./clean_build.sh ``` 5. Export the installation paths of the dependencies to your `.bashrc` file, e.g. @@ -92,11 +100,11 @@ ExaGeoStatCPP. ### R package installation 1. Open the R prompt window by simply running `R` command in the terminal, inside the prompt, we will install needed packages by running the following commands: ```R - install.packages(Rcpp) - install.packages("assert") + install.packages("Rcpp") + install.packages("assertthat") ``` -2. close the R prompt and return to the terminal. Run the following command, make sure your current path is the ExaGeoStat project directory +2. close the R prompt and return to the terminal. Run the following command, make sure your current path is the ExaGeoStatCPP project directory ```commandline R CMD INSTALL . --configure-args="-r" @@ -104,6 +112,44 @@ ExaGeoStatCPP. > For more detailed information on installing ExaGeoStat with different configurations and enabling technologies such as CUDA, MPI, R, etc., please refer to the [User Manual](USER_MANUAL.md) +## Common Installation Errors and Solutions + +### 1. Missing CMake +The installation requires **CMake** version 3.2 or higher. Ensure it is installed on your system before proceeding with the installation of **ExaGeoStatCPP**. + +To install CMake, use: +```sh +sudo apt install cmake +``` + +### 2. Missing Libtool +If you encounter the following error during installation: +``` +./autogen.sh: line 17: libtool: command not found +./autogen.sh: line 20: glibtool: command not found +``` +This indicates that **Libtool** is missing. You can install it using: +```sh +sudo apt install libtool libtool-bin +``` + +Alternatively, you can install **Libtool** locally: +```sh +wget http://ftpmirror.gnu.org/libtool/libtool-2.4.7.tar.gz +tar -xvzf libtool-2.4.7.tar.gz +cd libtool-2.4.7 +./configure --prefix=$HOME/local +make +make install +``` +Then, update your environment variables: +```sh +export PATH=$HOME/local/bin:$PATH +export LD_LIBRARY_PATH=$HOME/local/lib:$LD_LIBRARY_PATH +export PKG_CONFIG_PATH=$HOME/local/lib/pkgconfig:$PKG_CONFIG_PATH +``` +After this, restart your terminal or run `source ~/.bashrc` to apply the changes. + ## Usage #### C++ Example @@ -128,14 +174,66 @@ int main(int argc, char **argv) { return 0; } ``` -### R Example: -```R +## R Example +Here is an example demonstrating how to use **ExaGeoStatCPP** in R: + +```r +# Load the ExaGeoStatCPP library +library(ExaGeoStatCPP) + +# Set parameters for the simulation +ncores <- 30 +ngpus <- 0 +problem_size <- 1600 +dts <- 320 +lts <- 0 +computation <- "exact" +dimension <- "2D" +kernel <- "univariate_matern_stationary" +initial_theta <- c(1,0.1,0.5) +lower_bound <- c(0.1,0.1,0.1) +upper_bound <- c(5,5,5) +p <- 1 +q <- 1 +opt_itrs <- 100 + +# Initialize hardware configuration hardware <- new(Hardware, computation, ncores, ngpus, p, q) -exageostat_data <- simulate_data(kernel=kernel, initial_theta=initial_theta, problem_size=problem_size, dts=dts, dimension=dimension) -estimated_theta <- model_data(data=exageostat_data, kernel=kernel, dts=dts, dimension=dimension,lb=lower_bound, ub=upper_bound, mle_itr=10) -predict_data(train_data=list(x, y, z_measurement), test_data=list(test_x, test_y), kernel=kernel, dts=dts, estimated_theta=estimated_theta) + +# Simulate spatial data based on the specified kernel and parameters +exageostat_data <- simulate_data( + kernel = kernel, + initial_theta = initial_theta, + problem_size = problem_size, + dts = dts, + dimension = dimension +) + +# Estimate model parameters using MLE +estimated_theta <- model_data( + matrix=exageostat_data$m, + x=exageostat_data$x, + y=exageostat_data$y, + kernel=kernel, dts=dts, + dimension=dimension, + lb=lower_bound, + ub=upper_bound, + mle_itr=opt_itrs) + +# Perform spatial prediction using the estimated parameters +test_x <- c(0.2, 0.330) +test_y <- c(0.104, 0.14) +predict_data( + train_data=list(x=exageostat_data$x, y=exageostat_data$y, exageostat_data$m), + test_data=list(test_x, test_y), + kernel=kernel, + dts=dts, + estimated_theta=estimated_theta) + ``` +This example walks through initializing hardware, simulating spatial data, estimating model parameters, and making predictions using **ExaGeoStatCPP** in R. + > Please take a look at the end-to-end examples as a reference for using all the operations. ## Contributing @@ -189,4 +287,4 @@ Find detailed information on how to contribute to ExaGeoStatCPP [here](CONTRIBUT [BSD 3-Clause](LICENSE) ## Handout -![ExaGeoStatCPP-handout.png](docs/ExaGeoStatCPP-handout.png) \ No newline at end of file +![ExaGeoStatCPP-handout.png](docs/ExaGeoStatCPP-handout.png) diff --git a/USER_MANUAL.md b/USER_MANUAL.md index 7f7bfcfb..fb79d39f 100644 --- a/USER_MANUAL.md +++ b/USER_MANUAL.md @@ -99,7 +99,10 @@ ## Arguments -These are the arguments that you can specify when running any C++ example. +These are the arguments that you can specify when running any C++ example. +**Please note that the arguments are not case-sensitive**, and you can use variations such as `-`, `_`, or capitalized forms for the same argument name. +For example, `MaxRank`, `max-rank`, `max_rank`, `Max_Rank` ,`Maxrank` , `MaxrAnk` and `Max-Rank` are all considered equivalent. + * {Mandatory} To set the problem size (N) --N= @@ -153,13 +156,13 @@ These are the arguments that you can specify when running any C++ example. --oub= * {Optional} To set the initial theta - --itheta= + --initial_theta= * {Optional} To set the target theta --ttheta= * {Optional} To set the estimated theta - --etheta= + --estimated_theta= * {Optional} To set the seed value, the default is 0 --seed= @@ -224,10 +227,12 @@ These are the arguments that you can specify when running any C++ example. ### Provide Arguments To use any operations, you must initially supply the necessary arguments -to the operation via the Configurations module. There are two methods available +to the operation via the Configurations module. +This program is configured by default through a json file of default values. You can either change the configuration arguments +in the json file or provide them through command line. There are two methods available for setting your arguments: -1. Provide your arguments with the command line. +1. Provide your arguments with the command line, this overwrites the json configuration. ```c++ // Create a new configuration object. Configurations configurations; diff --git a/cmake/ImportNlohmannJSON.cmake b/cmake/ImportNlohmannJSON.cmake new file mode 100644 index 00000000..67227b9e --- /dev/null +++ b/cmake/ImportNlohmannJSON.cmake @@ -0,0 +1,39 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file ImportNlohmannJSON.cmake +# @brief Checks for the nlohmann library and includes it in the project if it is not already present. +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @date 2024-12-25 + +# Configurations for integrating the nlohmann +# 'name' is assigned "NlohmannJSON" to identify the nlohmann Library within this script. +set(name "nlohmann_json") +# 'tag' specifies the version tag "v3.11.2" for the nlohmann library, indicating the exact version to be used. +set(tag "v3.11.2") +# 'version' sets "3.11.2" as the version of the nlohmann library, ensuring compatibility with project requirements. +set(version "3.11.2") +# 'flag' is available for additional configuration options during build or installation, but remains empty here. +set(flag "") +# 'is_cmake' indicates whether nlohmann uses CMake for building. +set(is_cmake ON) +# 'is_git' denotes if nlohmann's source code is hosted in a Git repository. +set(is_git ON) +# 'auto_gen' signifies the need for autogen scripts in the build process. Here, it is set to OFF, indicating they are not needed. +set(auto_gen OFF) +# 'url' provides the download location for the nlohmann source code. +set(url "https://github.com/nlohmann/json.git") + +# Include the 'ImportDependency' macro, responsible for managing the GSL library's import and setup process. +include(macros/ImportDependency) +# Execute the 'ImportDependency' macro with the previously established parameters to handle the detection, downloading, and integration of nlohmann. +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) + +# Add nlohmann_json to the project's list of linked libraries, making its functionality accessible within the project. +list(APPEND LIBS nlohmann_json::nlohmann_json) + +# Output a message signaling the successful integration of the nlohmann library into the project. +message(STATUS "${name} done") diff --git a/configurations/config.json b/configurations/config.json new file mode 100644 index 00000000..0a0a76cd --- /dev/null +++ b/configurations/config.json @@ -0,0 +1,47 @@ +{ + "N": "16", + "Kernel": "UnivariateMaternStationary", + "P": "1", + "Q": "1", + "Timeslot": "1", + "Computation": "exact", + "Precision": "double", + "Cores": "1", + "Gpus": "0", + "Dts": "8", + "Lts": "0", + "Band": "0", + "MaxRank": "0", + "ObservationsFile": "./configurations/observations.dat", + "Seed": "0", + "LogPath": "configurations", + "Ooc": "false", + "ApproximationMode": "1", + "Log": "true", + "IsNonGaussian": "false", + "Verbose": "standard", + "BandDense": "0", + "ObjectsNumber": "0", + "AdaptiveDecision": "0", + "AddDiagonal": "0", + "FileTimeSlot": "1", + "FileNumber": "0", + "EnableInverse": "false", + "Mpiio": "true", + "Dimension": "2D", + "IsSynthetic": "true", + "DataPath": "", + "RecoveryFile": "", + "FileLogPath": "logs.log", + "FileLogName": "logs.log", + "DistanceMetric": "euclidean", + "MaxMleIterations": "1", + "Accuracy": "0", + "Tolerance": "1", + "ZMiss": "1", + "Mspe": "false", + "Idw": "false", + "MloeMmom": "false", + "Fisher": "false", + "ObservationNumber": "0" +} diff --git a/configure b/configure index 5e6a92f2..6f95f233 100755 --- a/configure +++ b/configure @@ -17,6 +17,7 @@ BLUE='\033[0;34m' NC='\033[0m' INSTALL_PREFIX=$PWD/installdir/_deps +BASE_DIR=$PWD # Function to install CMake from source install_cmake() { @@ -36,12 +37,11 @@ install_cmake() { cd cmake-3.28.1 || exit 1 # Configure, build, and install CMake to the specified location - ./bootstrap --prefix="$INSTALL_PREFIX" --parallel=2 -- -DCMAKE_USE_OPENSSL=OFF + ./bootstrap --prefix="$INSTALL_PREFIX/CMAKE" --parallel=2 -- -DCMAKE_USE_OPENSSL=OFF make -j 2 - sudo make install - + make install # Clean up - cd "$temp_dir" || exit 1 + cd "$BASE_DIR" || exit 1 rm -rf "$temp_dir" } @@ -59,7 +59,7 @@ fi BUILDING_TESTS="OFF" BUILDING_HEAVY_TESTS="OFF" BUILDING_EXAMPLES="OFF" -USING_HiCMA="OFF" +USE_HiCMA="OFF" VERBOSE="OFF" USE_CUDA="OFF" USE_MPI="OFF" @@ -112,7 +112,7 @@ while getopts ":tevhHi:cmpTwr" opt; do ;; H) ##### Using HiCMA ##### echo "${GREEN}Using HiCMA.${NC}" - USING_HiCMA="ON" + USE_HiCMA="ON" ;; c) ##### Using cuda enabled ##### echo "${GREEN}Cuda enabled ${NC}" @@ -179,7 +179,7 @@ if [ -z "$BUILDING_EXAMPLES" ]; then echo "${RED}Building examples disabled.${NC}" fi -if [ -z "$USING_HiCMA" ]; then +if [ -z "$USE_HiCMA" ]; then echo "${RED}Using HiCMA is disabled.${NC}" fi @@ -226,10 +226,8 @@ elif [ -x "/Applications/CMake.app/Contents/bin/cmake" ]; then cmake_command_bin="${cmake_install_dir}/cmake" else echo "Installing CMake from source" - mkdir "${ABSOLUTE_PATH}/inst/_deps/" - install_dir="${ABSOLUTE_PATH}/inst/_deps/" - install_cmake "$install_dir" - cmake_command_bin="${ABSOLUTE_PATH}/inst/_deps/bin/cmake" + install_cmake + cmake_command_bin="${INSTALL_PREFIX}/CMAKE/bin/cmake" fi "$cmake_command_bin" "$DEVELOPER_WARNINGS" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ @@ -238,7 +236,7 @@ fi -DBUILD_TESTS="${BUILDING_TESTS}" \ -DBUILD_HEAVY_TESTS="${BUILDING_HEAVY_TESTS}" \ -DBUILD_EXAMPLES="${BUILDING_EXAMPLES}" \ - -DUSE_HICMA="${USING_HiCMA}" \ + -DUSE_HICMA="${USE_HiCMA}" \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=${VERBOSE} \ -DUSE_CUDA="${USE_CUDA}" \ -DUSE_MPI="${USE_MPI}" \ diff --git a/examples/data-generators/SyntheticDataGeneration.cpp b/examples/data-generators/SyntheticDataGeneration.cpp index e4df4645..f5eae7b0 100644 --- a/examples/data-generators/SyntheticDataGeneration.cpp +++ b/examples/data-generators/SyntheticDataGeneration.cpp @@ -32,7 +32,6 @@ int main(int argc, char **argv) { // Create a new synthetic_data_configurations object with the provided command line arguments Configurations synthetic_data_configurations; synthetic_data_configurations.InitializeArguments(argc, argv); - synthetic_data_configurations.InitializeDataGenerationArguments(); // initialize ExaGeoStat Hardware. ExaGeoStatHardware hardware(synthetic_data_configurations.GetComputation(), diff --git a/examples/data-loader/CSVLoader.cpp b/examples/data-loader/CSVLoader.cpp index d3776fb6..cf61aeb6 100644 --- a/examples/data-loader/CSVLoader.cpp +++ b/examples/data-loader/CSVLoader.cpp @@ -40,7 +40,6 @@ int main(int argc, char **argv) { // Generate Data and Log it into file configurations.SetLogger(true); - configurations.InitializeDataGenerationArguments(); // Initialize ExaGeoStat Hardware and Kernel. auto hardware = ExaGeoStatHardware(configurations.GetComputation(), configurations.GetCoresNumber(), diff --git a/inst/include/Rcpp-adapters/FunctionsAdapter.hpp b/inst/include/Rcpp-adapters/FunctionsAdapter.hpp index 336b037f..7d65974f 100644 --- a/inst/include/Rcpp-adapters/FunctionsAdapter.hpp +++ b/inst/include/Rcpp-adapters/FunctionsAdapter.hpp @@ -65,6 +65,7 @@ namespace exageostat::adapters { * @param[in] aDimension Dimensionality of the problem ("2D" or "3D"). * @param[in] aBand Bandwidth for band matrices, applicable in certain computational kernels. * @param[in] aMaxRank Maximum rank for low-rank approximations. + * @param[in] aAccuracy Accuracy value for low-rank approximations, The final value is computed as 10^(-1.0 * aAccuracy) * @param[in] apData Pointer to ExaGeoStatData object to be modeled. * @param[in] aMeasurementsVector Optional vector of measurements to enhance modeling, can be nullable. * @param[in] aLocationsX Optional vector of X coordinates for locations, can be nullable. @@ -79,7 +80,7 @@ namespace exageostat::adapters { const std::vector &aUpperBound, const int &aTolerance, const int &aMleIterations, const int &aDenseTileSize, const int &aLowTileSize, const std::string &aDimension, const int &aBand, - const int &aMaxRank, SEXP apData, + const int &aMaxRank, const int &aAccuracy, SEXP apData, Rcpp::Nullable aMeasurementsVector = R_NilValue, Rcpp::Nullable aLocationsX = R_NilValue, Rcpp::Nullable aLocationsY = R_NilValue, diff --git a/inst/include/configurations/Configurations.hpp b/inst/include/configurations/Configurations.hpp index 3821a34d..46ab3b43 100644 --- a/inst/include/configurations/Configurations.hpp +++ b/inst/include/configurations/Configurations.hpp @@ -95,137 +95,97 @@ namespace exageostat::configurations { * */ void InitializeAllTheta(); - /** - * @brief Initialize data generation arguments.. - * @return void - * - */ - void InitializeDataGenerationArguments(); - - /** - * @brief Initialize data Modeling arguments. + * @brief Print the usage and accepted Arguments. * @return void * */ - void InitializeDataModelingArguments(); + static void PrintUsage(); /** - * @brief Initialize data Prediction arguments. + * @brief Validate the config through a set of if/else. + * @throw exception in case some if/else conditions are not met. * @return void * */ - void InitializeDataPredictionArguments(); - - /** - * @brief Print the usage and accepted Arguments. - * @return void - * - */ - static void PrintUsage(); + void ValidateConfiguration(); /** START OF THE COMMON ARGUMENTS BETWEEN ALL MODULES. **/ - CREATE_SETTER_FUNCTION(ProblemSize, int, aProblemSize, "ProblemSize") - - CREATE_GETTER_FUNCTION(ProblemSize, int, "ProblemSize") - - CREATE_SETTER_FUNCTION(KernelName, const std::string&, aKernel, "Kernel") - - CREATE_GETTER_FUNCTION(KernelName, const std::string&, "Kernel") - - CREATE_SETTER_FUNCTION(PGrid, int, aPGrid, "PGrid") - - CREATE_GETTER_FUNCTION(PGrid, int, "PGrid") - - CREATE_SETTER_FUNCTION(QGrid, int, aQGrid, "QGrid") - - CREATE_GETTER_FUNCTION(QGrid, int, "QGrid") - - CREATE_SETTER_FUNCTION(TimeSlot, int, aTimeSlot, "TimeSlot") - - CREATE_GETTER_FUNCTION(TimeSlot, int, "TimeSlot") - - CREATE_SETTER_FUNCTION(Computation, common::Computation, aComputation, "Computation") - - CREATE_GETTER_FUNCTION(Computation, common::Computation, "Computation") - - CREATE_SETTER_FUNCTION(Precision, common::Precision, aPrecision, "Precision") + CREATE_SETTER_FUNCTION(ProblemSize, int, aProblemSize, "n") + CREATE_GETTER_FUNCTION(ProblemSize, int, "n") - CREATE_GETTER_FUNCTION(Precision, common::Precision, "Precision") + CREATE_SETTER_FUNCTION(KernelName, const std::string&, aKernel, "kernel") + CREATE_GETTER_FUNCTION(KernelName, const std::string&, "kernel") - CREATE_SETTER_FUNCTION(CoresNumber, int, aCoresNumbers, "CoresNumbers") + CREATE_SETTER_FUNCTION(PGrid, int, aPGrid, "p") + CREATE_GETTER_FUNCTION(PGrid, int, "p") - CREATE_GETTER_FUNCTION(CoresNumber, int, "CoresNumbers") + CREATE_SETTER_FUNCTION(QGrid, int, aQGrid, "q") + CREATE_GETTER_FUNCTION(QGrid, int, "q") - CREATE_SETTER_FUNCTION(GPUsNumbers, int, aGPUsNumber, "GPUsNumbers") + CREATE_SETTER_FUNCTION(TimeSlot, int, aTimeSlot, "timeslot") + CREATE_GETTER_FUNCTION(TimeSlot, int, "timeslot") - CREATE_GETTER_FUNCTION(GPUsNumbers, int, "GPUsNumbers") + CREATE_SETTER_FUNCTION(Computation, common::Computation, aComputation, "computation") + CREATE_GETTER_FUNCTION(Computation, common::Computation, "computation") - CREATE_SETTER_FUNCTION(DenseTileSize, int, aTileSize, "DTS") + CREATE_SETTER_FUNCTION(Precision, common::Precision, aPrecision, "precision") + CREATE_GETTER_FUNCTION(Precision, common::Precision, "precision") - CREATE_GETTER_FUNCTION(DenseTileSize, int, "DTS") + CREATE_SETTER_FUNCTION(CoresNumber, int, aCoresNumbers, "cores") + CREATE_GETTER_FUNCTION(CoresNumber, int, "cores") - CREATE_SETTER_FUNCTION(LowTileSize, int, aTileSize, "LTS") + CREATE_SETTER_FUNCTION(GPUsNumbers, int, aGPUsNumber, "gpus") + CREATE_GETTER_FUNCTION(GPUsNumbers, int, "gpus") - CREATE_GETTER_FUNCTION(LowTileSize, int, "LTS") + CREATE_SETTER_FUNCTION(DenseTileSize, int, aTileSize, "dts") + CREATE_GETTER_FUNCTION(DenseTileSize, int, "dts") - CREATE_SETTER_FUNCTION(Band, int, aBand, "Band") + CREATE_SETTER_FUNCTION(LowTileSize, int, aTileSize, "lts") + CREATE_GETTER_FUNCTION(LowTileSize, int, "lts") - CREATE_GETTER_FUNCTION(Band, int, "Band") + CREATE_SETTER_FUNCTION(Band, int, aBand, "band") + CREATE_GETTER_FUNCTION(Band, int, "band") - CREATE_SETTER_FUNCTION(MaxRank, int, aMaxRank, "MaxRank") + CREATE_SETTER_FUNCTION(MaxRank, int, aMaxRank, "maxrank") + CREATE_GETTER_FUNCTION(MaxRank, int, "maxrank") - CREATE_GETTER_FUNCTION(MaxRank, int, "MaxRank") + CREATE_SETTER_FUNCTION(ActualObservationsFilePath, const std::string&, aActualObservationsFilePath, "observationsfile") + CREATE_GETTER_FUNCTION(ActualObservationsFilePath, std::string, "observationsfile") - CREATE_SETTER_FUNCTION(ActualObservationsFilePath, const std::string &, aActualObservationsFilePath, - "ActualObservationsFilePath") + CREATE_SETTER_FUNCTION(Seed, int, aSeed, "seed") + CREATE_GETTER_FUNCTION(Seed, int, "seed") - CREATE_GETTER_FUNCTION(ActualObservationsFilePath, std::string, "ActualObservationsFilePath") + CREATE_SETTER_FUNCTION(LoggerPath, const std::string&, aLoggerPath, "logpath") + CREATE_GETTER_FUNCTION(LoggerPath, std::string, "logpath") - CREATE_SETTER_FUNCTION(Seed, int, aSeed, "Seed") + CREATE_SETTER_FUNCTION(InitialTheta, const std::vector&, apTheta, "initialtheta") + CREATE_GETTER_FUNCTION(InitialTheta, std::vector&, "initialtheta") - CREATE_GETTER_FUNCTION(Seed, int, "Seed") + CREATE_SETTER_FUNCTION(IsOOC, bool, aIsOOC, "ooc") + CREATE_GETTER_FUNCTION(IsOOC, bool, "ooc") - CREATE_SETTER_FUNCTION(LoggerPath, const std::string&, aLoggerPath, "LoggerPath") + CREATE_SETTER_FUNCTION(ApproximationMode, int, aApproximationMode, "approximationmode") + CREATE_GETTER_FUNCTION(ApproximationMode, int, "approximationmode") - CREATE_GETTER_FUNCTION(LoggerPath, std::string, "LoggerPath") + CREATE_SETTER_FUNCTION(Logger, bool, aLogger, "log") + CREATE_GETTER_FUNCTION(Logger, bool, "log") - CREATE_SETTER_FUNCTION(InitialTheta, const std::vector &, apTheta, "InitialTheta") + CREATE_SETTER_FUNCTION(LowerBounds, const std::vector&, apTheta, "lb") + CREATE_GETTER_FUNCTION(LowerBounds, std::vector&, "lb") - CREATE_GETTER_FUNCTION(InitialTheta, std::vector &, "InitialTheta") + CREATE_SETTER_FUNCTION(UpperBounds, const std::vector&, apTheta, "ub") + CREATE_GETTER_FUNCTION(UpperBounds, std::vector&, "ub") - CREATE_SETTER_FUNCTION(IsOOC, bool, aIsOOC, "OOC") + CREATE_SETTER_FUNCTION(EstimatedTheta, const std::vector&, apTheta, "estimatedtheta") + CREATE_GETTER_FUNCTION(EstimatedTheta, std::vector&, "estimatedtheta") - CREATE_GETTER_FUNCTION(IsOOC, bool, "OOC") + CREATE_SETTER_FUNCTION(StartingTheta, const std::vector&, apTheta, "startingtheta") + CREATE_GETTER_FUNCTION(StartingTheta, std::vector&, "startingtheta") - CREATE_SETTER_FUNCTION(ApproximationMode, int, aApproximationMode, "ApproximationMode") - - CREATE_GETTER_FUNCTION(ApproximationMode, int, "ApproximationMode") - - CREATE_SETTER_FUNCTION(Logger, bool, aLogger, "Logger") - - CREATE_GETTER_FUNCTION(Logger, bool, "Logger") - - CREATE_SETTER_FUNCTION(LowerBounds, const std::vector &, apTheta, "LowerBounds") - - CREATE_GETTER_FUNCTION(LowerBounds, std::vector &, "LowerBounds") - - CREATE_SETTER_FUNCTION(UpperBounds, const std::vector &, apTheta, "UpperBounds") - - CREATE_GETTER_FUNCTION(UpperBounds, std::vector &, "UpperBounds") - - CREATE_SETTER_FUNCTION(EstimatedTheta, const std::vector &, apTheta, "EstimatedTheta") - - CREATE_GETTER_FUNCTION(EstimatedTheta, std::vector &, "EstimatedTheta") - - CREATE_SETTER_FUNCTION(StartingTheta, const std::vector &, apTheta, "StartingTheta") - - CREATE_GETTER_FUNCTION(StartingTheta, std::vector &, "StartingTheta") - - CREATE_SETTER_FUNCTION(IsNonGaussian, bool, aIsNonGaussian, "IsNonGaussian") - - CREATE_GETTER_FUNCTION(IsNonGaussian, bool, "IsNonGaussian") + CREATE_SETTER_FUNCTION(IsNonGaussian, bool, aIsNonGaussian, "isnongaussian") + CREATE_GETTER_FUNCTION(IsNonGaussian, bool, "isnongaussian") /** * @brief Getter for the verbosity. @@ -240,159 +200,88 @@ namespace exageostat::configurations { /** START OF THE HICMA-PARSEC SPECIFIC ARGUEMNTS. **/ - CREATE_SETTER_FUNCTION(DenseBandDP, int, aDenseBandDP, "DenseBandDoublePrecision") - - CREATE_GETTER_FUNCTION(DenseBandDP, int, "DenseBandDoublePrecision") - - CREATE_SETTER_FUNCTION(ObjectsNumber, int, aObjectsNumber, "ObjectsNumber") - - CREATE_GETTER_FUNCTION(ObjectsNumber, int, "ObjectsNumber") - - CREATE_SETTER_FUNCTION(AdaptiveDecision, int, aAdaptiveDecision, "AdaptiveDecision") - - CREATE_GETTER_FUNCTION(AdaptiveDecision, int, "AdaptiveDecision") - - CREATE_SETTER_FUNCTION(DiagonalAddition, int, aDiagonalAddition, "DiagonalAddition") - - CREATE_GETTER_FUNCTION(DiagonalAddition, int, "DiagonalAddition") - - CREATE_SETTER_FUNCTION(TimeSlotPerFile, int, aTimeSlotPerFile, "TimeSlotPerFile") - - CREATE_GETTER_FUNCTION(TimeSlotPerFile, int, "TimeSlotPerFile") - - CREATE_SETTER_FUNCTION(FileNumber, int, aFileNumber, "FileNumber") - - CREATE_GETTER_FUNCTION(FileNumber, int, "FileNumber") - - CREATE_SETTER_FUNCTION(EnableInverse, bool , aEnableInverse, "EnableInverse") - - CREATE_GETTER_FUNCTION(EnableInverse, bool , "EnableInverse") + CREATE_SETTER_FUNCTION(DenseBandDP, int, aDenseBandDP, "banddense") + CREATE_GETTER_FUNCTION(DenseBandDP, int, "banddense") - CREATE_SETTER_FUNCTION(MPIIO, bool, aMPIIO, "MPIIO") + CREATE_SETTER_FUNCTION(ObjectsNumber, int, aObjectsNumber, "objectsnumber") + CREATE_GETTER_FUNCTION(ObjectsNumber, int, "objectsnumber") - CREATE_GETTER_FUNCTION(MPIIO, bool, "MPIIO") + CREATE_SETTER_FUNCTION(AdaptiveDecision, int, aAdaptiveDecision, "adaptivedecision") + CREATE_GETTER_FUNCTION(AdaptiveDecision, int, "adaptivedecision") - /** END OF THE HICMA-PARSEC SPECIFIC ARGUEMNTS. **/ - /** START OF THE DATA GENERATION MODULES. **/ + CREATE_SETTER_FUNCTION(DiagonalAddition, int, aDiagonalAddition, "adddiagonal") + CREATE_GETTER_FUNCTION(DiagonalAddition, int, "adddiagonal") - CREATE_SETTER_FUNCTION(Dimension, exageostat::common::Dimension, aDimension, "Dimension") + CREATE_SETTER_FUNCTION(TimeSlotPerFile, int, aTimeSlotPerFile, "filetimeslot") + CREATE_GETTER_FUNCTION(TimeSlotPerFile, int, "filetimeslot") - CREATE_GETTER_FUNCTION(Dimension, exageostat::common::Dimension, "Dimension") + CREATE_SETTER_FUNCTION(FileNumber, int, aFileNumber, "filenumber") + CREATE_GETTER_FUNCTION(FileNumber, int, "filenumber") - CREATE_SETTER_FUNCTION(IsSynthetic, bool, aIsSynthetic, "IsSynthetic") + CREATE_SETTER_FUNCTION(EnableInverse, bool, aEnableInverse, "enableinverse") + CREATE_GETTER_FUNCTION(EnableInverse, bool, "enableinverse") - CREATE_GETTER_FUNCTION(IsSynthetic, bool, "IsSynthetic") + CREATE_SETTER_FUNCTION(MPIIO, bool, aMPIIO, "mpiio") + CREATE_GETTER_FUNCTION(MPIIO, bool, "mpiio") - CREATE_SETTER_FUNCTION(DataPath, const std::string&, aDataPath, "DataPath") +/** END OF THE HICMA-PARSEC SPECIFIC ARGUMENTS. **/ +/** START OF THE DATA GENERATION MODULES. **/ - CREATE_GETTER_FUNCTION(DataPath, std::string, "DataPath") + CREATE_SETTER_FUNCTION(Dimension, exageostat::common::Dimension, aDimension, "dimension") + CREATE_GETTER_FUNCTION(Dimension, exageostat::common::Dimension, "dimension") - /** END OF THE DATA GENERATION MODULES. **/ - /** START OF THE DATA MODELING MODULES. **/ + CREATE_SETTER_FUNCTION(IsSynthetic, bool, aIsSynthetic, "issynthetic") + CREATE_GETTER_FUNCTION(IsSynthetic, bool, "issynthetic") - CREATE_SETTER_FUNCTION(RecoveryFile, const std::string&, aRecoveryFile, "RecoveryFile") + CREATE_SETTER_FUNCTION(DataPath, const std::string&, aDataPath, "datapath") + CREATE_GETTER_FUNCTION(DataPath, std::string, "datapath") - CREATE_GETTER_FUNCTION(RecoveryFile, std::string, "RecoveryFile") +/** END OF THE DATA GENERATION MODULES. **/ +/** START OF THE DATA MODELING MODULES. **/ - CREATE_SETTER_FUNCTION(FileLogPath, FILE *, apFileLogPath, "FileLogPath") + CREATE_SETTER_FUNCTION(RecoveryFile, const std::string&, aRecoveryFile, "recoveryfile") + CREATE_GETTER_FUNCTION(RecoveryFile, std::string, "recoveryfile") - CREATE_GETTER_FUNCTION(FileLogPath, FILE *, "FileLogPath") + CREATE_SETTER_FUNCTION(FileLogPath, FILE *, apFileLogPath, "filelogpath") + CREATE_GETTER_FUNCTION(FileLogPath, FILE *, "filelogpath") - CREATE_SETTER_FUNCTION(FileLogName, const std::string&, aFileLogName, "FileLogName") + CREATE_SETTER_FUNCTION(FileLogName, const std::string&, aFileLogName, "filelogname") - CREATE_SETTER_FUNCTION(DistanceMetric, common::DistanceMetric, aDistanceMetric, "DistanceMetric") + CREATE_SETTER_FUNCTION(DistanceMetric, common::DistanceMetric, aDistanceMetric, "distancemetric") + CREATE_GETTER_FUNCTION(DistanceMetric, common::DistanceMetric, "distancemetric") - CREATE_GETTER_FUNCTION(DistanceMetric, common::DistanceMetric, "DistanceMetric") + CREATE_SETTER_FUNCTION(MaxMleIterations, int, aMaxMleIterations, "maxmleiterations") + CREATE_GETTER_FUNCTION(MaxMleIterations, int, "maxmleiterations") - CREATE_SETTER_FUNCTION(MaxMleIterations, int, aMaxMleIterations, "MaxMleIterations") - - CREATE_GETTER_FUNCTION(MaxMleIterations, int, "MaxMleIterations") - - CREATE_SETTER_FUNCTION(Accuracy, int, aAccuracy, "Accuracy") - - CREATE_GETTER_FUNCTION(Accuracy, int, "Accuracy") + CREATE_SETTER_FUNCTION(Accuracy, int, aAccuracy, "accuracy") + CREATE_GETTER_FUNCTION(Accuracy, int, "accuracy") void SetTolerance(double aTolerance); - - CREATE_GETTER_FUNCTION(Tolerance, double, "Tolerance") + CREATE_GETTER_FUNCTION(Tolerance, double, "tolerance") /** END OF THE DATA MODELING MODULES. **/ /** START OF THE DATA PREDICTION MODULES. **/ - CREATE_SETTER_FUNCTION(UnknownObservationsNb, int, aUnknownObservationsNumber, "UnknownObservationsNb") - - CREATE_GETTER_FUNCTION(UnknownObservationsNb, int, "UnknownObservationsNb") - - CREATE_SETTER_FUNCTION(IsMSPE, bool, aIsMSPE, "IsMSPE") - - CREATE_GETTER_FUNCTION(IsMSPE, bool, "IsMSPE") + CREATE_SETTER_FUNCTION(UnknownObservationsNb, int, aUnknownObservationsNumber, "zmiss") + CREATE_GETTER_FUNCTION(UnknownObservationsNb, int, "zmiss") - CREATE_SETTER_FUNCTION(IsIDW, bool, aIsIDW, "IsIDW") + CREATE_SETTER_FUNCTION(IsMSPE, bool, aIsMSPE, "mspe") + CREATE_GETTER_FUNCTION(IsMSPE, bool, "mspe") - CREATE_GETTER_FUNCTION(IsIDW, bool, "IsIDW") + CREATE_SETTER_FUNCTION(IsIDW, bool, aIsIDW, "idw") + CREATE_GETTER_FUNCTION(IsIDW, bool, "idw") - CREATE_SETTER_FUNCTION(IsMLOEMMOM, bool, aIsMLOEMMOM, "IsMLOEMMOM") + CREATE_SETTER_FUNCTION(IsMLOEMMOM, bool, aIsMLOEMMOM, "mloemmom") + CREATE_GETTER_FUNCTION(IsMLOEMMOM, bool, "mloemmom") - CREATE_GETTER_FUNCTION(IsMLOEMMOM, bool, "IsMLOEMMOM") + CREATE_SETTER_FUNCTION(IsFisher, bool, aIsFisher, "fisher") + CREATE_GETTER_FUNCTION(IsFisher, bool, "fisher") - CREATE_SETTER_FUNCTION(IsFisher, bool, aIsFisher, "IsFisher") - - CREATE_GETTER_FUNCTION(IsFisher, bool, "IsFisher") - - CREATE_SETTER_FUNCTION(ObservationNumber, int, aObservationsNumber, "ObservationNumber") - - CREATE_GETTER_FUNCTION(ObservationNumber, int, "ObservationNumber") + CREATE_SETTER_FUNCTION(ObservationNumber, int, aObservationsNumber, "observationnumber") + CREATE_GETTER_FUNCTION(ObservationNumber, int, "observationnumber") /** END OF THE DATA PREDICTION MODULES. **/ - /** - * @brief Check if input value is numerical. - * @param[in] aValue The input from the user side. - * @return The int casted value. - * - */ - static int CheckNumericalValue(const std::string &aValue); - - /** - * @brief Checks the value of the dimension parameter. - * @param[in] aDimension A string represents the dimension. - * @return The corresponding dimension value. - * - */ - static exageostat::common::Dimension CheckDimensionValue(const std::string &aDimension); - - /** - * @brief Checks if the kernel value is valid. - * @param[in] aKernel The kernel to check. - * @return void - * - */ - void CheckKernelValue(const std::string &aKernel); - - /** - * @brief Check input computation value. - * @param[in] aValue The input from the user side. - * @return Enum with the selected computation, Error if not exist. - * - */ - static common::Computation CheckComputationValue(const std::string &aValue); - - /** - * @brief Check input precision value. - * @param[in] aValue The input from the user side. - * @return Enum with the selected Precision, Error if not exist. - * - */ - static common::Precision CheckPrecisionValue(const std::string &aValue); - - /** - * @brief Checks the value of the unknown observations parameter. - * @param[in] aValue A string represents the number of unknown observations. - * @return The corresponding integer value. - * - */ - int CheckUnknownObservationsValue(const std::string &aValue); - /** * @brief Initialize a vector with a given size to contain zeros. * @param[in, out] aTheta A reference to the vector to initialize. @@ -416,42 +305,7 @@ namespace exageostat::configurations { */ int CalculateZObsNumber(); - /** - * @brief Parses a string of theta values and returns an array of doubles. - * @param[in] aInputValues The input string of theta values. - * @return A vector of parsed theta values. - * - */ - static std::vector ParseTheta(const std::string &aInputValues); - - - /** - * @brief parse user's input to distance metric. - * @param[in] aDistanceMetric string specifying the used distance metric. - * @return void - * - */ - void ParseDistanceMetric(const std::string &aDistanceMetric); - private: - - /** - * @brief Checks the run mode and sets the verbosity level. - * @param[in] aVerbosity A string represents the desired run mode ("verbose" or "standard"). - * @throws std::range_error if the input string is not "verbose" or "standard". - * @return void - * - */ - static void ParseVerbose(const std::string &aVerbosity); - - /** - * @brief Checks if a given string is in camel case format. - * @param[in] aString The string to check. - * @return true if the string is in camel case format, false otherwise. - * - */ - static bool IsCamelCase(const std::string &aString); - /// Used Dictionary std::unordered_map mDictionary; /// Used Argument counter diff --git a/inst/include/configurations/Parser.hpp b/inst/include/configurations/Parser.hpp new file mode 100644 index 00000000..0d465de6 --- /dev/null +++ b/inst/include/configurations/Parser.hpp @@ -0,0 +1,61 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** +* @file Parser.hpp +* @version 1.1.0 +* @brief Contains the declaration of the Parser class and its member functions for configuration parsing. +* @details Provides static methods to parse command-line arguments and JSON configuration files, as well as utility functions for string transformations. +* @author Mahmoud ElKarargy +* @date 2024-12-11 +**/ + +#ifndef EXAGEOSTAT_CPP_PARSER_HPP +#define EXAGEOSTAT_CPP_PARSER_HPP + +#include +#include + +#include + +namespace exageostat::configurations::parser { + + /** + * @class Parser + * @brief A class containing static methods for parsing configurations and utility functions. + */ + class Parser { + public: + + /** + * @brief Parses command-line arguments and extracts them into a key-value map. + * @param[in] aArgC The number of command-line arguments. + * @param[in] apArgV The array of command-line arguments. + * @param[in] apConfigurationMap The configuration map to fill. + * @return void. + * + */ + static void ParseCLI(const int &aArgC, char **apArgV, std::unordered_map &apConfigurationMap); + + /** + * @brief Parses a JSON configuration file and extracts its contents into a key-value map. + * @param[in] aJSONFile The path to the JSON file. + * @param[in] apConfigurationMap The configuration map to fill. + * @return void. + * + */ + static void ParseJSON(const std::string &aJSONFile, std::unordered_map &apConfigurationMap); + + /** + * @brief Converts a given string to all-small characters format. + * @param[in] arg The input string to convert. + * @return The converted string. + */ + static std::string ProcessKeyString(const std::string &arg); + + }; +}// namespace exageostat::configurations::parser + +#endif // EXAGEOSTAT_CPP_PARSER_HPP diff --git a/inst/include/configurations/Validator.hpp b/inst/include/configurations/Validator.hpp new file mode 100644 index 00000000..3e649afa --- /dev/null +++ b/inst/include/configurations/Validator.hpp @@ -0,0 +1,141 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** +* @file Validator.hpp +* @version 1.1.0 +* @brief Contains the declaration of the Validator class and its member functions for configuration validation. +* @details Provides a set of static methods to validate the input configuration parsed from CLI or JSON for the ExaGeoStat software package. +* @author Mahmoud ElKarargy +* @date 2024-12-11 +**/ + +#ifndef EXAGEOSTAT_CPP_VALIDATOR_HPP +#define EXAGEOSTAT_CPP_VALIDATOR_HPP + +#include + +namespace exageostat::configurations::validator { + + /** + * @class Validator + * @brief A class containing static methods for validating configuration parameters. + */ + class Validator { + public: + + /** + * @brief Validates the configuration parameters parsed from the CLI or JSON input. + * @param[in,out] apArgsMap A map containing configuration parameters and their values. + * @return void + * + */ + static void Validate(std::unordered_map &apArgsMap); + + /** + * @brief Parses a string of theta values and converts them to a vector of doubles. + * @param[in] aInputValues The input string containing theta values. + * @return A vector of parsed theta values as doubles. + * + */ + static std::vector CheckThetaValue(const std::string &aInputValues); + + /** + * @brief Validates and converts a string representing a tolerance value into a double. + * @param[in] aTolerance The input string for the tolerance value. + * @return The validated and converted tolerance value as a double. + * + */ + static double CheckToleranceValue(const std::string& aTolerance); + + /** + * @brief Validates a string representing a file name and returns file handler. + * @param[in] aFileLogPath The input string for the file name. + * @return The file handler of the validated file name. + * + */ + static FILE *CheckLogFileValue(const std::string &aFileLogPath); + + /** + * @brief Validates a string representing a kernel name. + * @param[in] aKernel The input string for the kernel name. + * @return The validated kernel name as a string. + * + */ + static std::string CheckKernelValue(const std::string &aKernel); + + /** + * @brief Checks if the input string is in camel case format. + * @param[in] aString The input string to validate. + * @return True if the string is in camel case; otherwise, false. + * + */ + bool static IsCamelCase(const std::string &aString); + + /** + * @brief Validates and converts a verbosity level string into a Verbose enum. + * @param[in] aVerbosity The input string for the verbosity level. + * @return The validated Verbose enum value. + * + */ + static common::Verbose CheckVerboseValue(const std::string &aVerbosity); + + /** + * @brief Validates and converts a string into a Precision enum. + * @param[in] aValue The input string representing precision. + * @return The validated Precision enum value. + * + */ + static common::Precision CheckPrecisionValue(const std::string &aValue); + + /** + * @brief Validates and converts a string into a Computation enum. + * @param[in] aValue The input string representing computation type. + * @return The validated Computation enum value. + * + */ + static common::Computation CheckComputationValue(const std::string &aValue); + + /** + * @brief Validates and converts a string into a boolean value. + * @param[in] aBooleanValue The input string representing a boolean value. + * @return The validated boolean value. + * + */ + static bool CheckBoolValue(const std::string& aBooleanValue); + + /** + * @brief Validates and converts a string into a DistanceMetric enum. + * @param[in] aDistanceMetric The input string representing the distance metric. + * @return The validated DistanceMetric enum value. + * + */ + static common::DistanceMetric CheckDistanceMetricValue(const std::string &aDistanceMetric); + + /** + * @brief Validates and converts a string into an integer. + * @param[in] aValue The input string representing a numerical value. + * @return The validated integer value. + * + */ + static int CheckNumericalValue(const std::string &aValue); + + /** + * @brief Validates and converts a string into a Dimension enum. + * @param[in] aDimension The input string representing the dimension. + * @return The validated Dimension enum value. + * + */ + static common::Dimension CheckDimensionValue(const std::string &aDimension); + + private: + /// A map of validation functions for different parameter types. + static const std::unordered_map> mCheckersMap; + /// A map linking arguments to their categories. + static const std::unordered_map mArgumentToCategoryMap; + }; +}// namespace exageostat::configurations::validator + +#endif // EXAGEOSTAT_CPP_VALIDATOR_HPP diff --git a/inst/include/results/Results.hpp b/inst/include/results/Results.hpp index 1f21c6b9..73c25020 100644 --- a/inst/include/results/Results.hpp +++ b/inst/include/results/Results.hpp @@ -16,6 +16,7 @@ #include #include +#include namespace exageostat::results { @@ -31,79 +32,78 @@ namespace exageostat::results { static Results *GetInstance(); /** - * @brief Set the flag indicating whether the results are synthetic or not. - * @param[in] aIsSynthetic True if the results are synthetic, false otherwise. - * + * @brief Set whether the dataset is synthetic or not. + * @param aIsSynthetic Boolean indicating if the dataset is synthetic. + * @param aKey Custom dictionary key (optional). */ - void SetIsSynthetic(bool aIsSynthetic); + void SetIsSynthetic(bool aIsSynthetic, const std::string &aKey = ""); /** * @brief Set the number of generated locations. - * @param[in] aNumLocations The number of generated locations. - * + * @param aNumLocations Integer representing the number of locations. + * @param aKey Custom dictionary key (optional). */ - void SetGeneratedLocationsNumber(int aNumLocations); + void SetGeneratedLocationsNumber(int aNumLocations, const std::string &aKey = ""); /** - * @brief Set the flag indicating whether the logger is active or not. - * @param[in] aIsLogger True if the logger is active, false otherwise. - * + * @brief Enable or disable logging. + * @param aIsLogger Boolean indicating if logging is enabled. + * @param aKey Custom dictionary key (optional). */ - void SetIsLogger(bool aIsLogger); + void SetIsLogger(bool aIsLogger, const std::string &aKey = ""); /** - * @brief Set the path for the logger. - * @param[in] aLoggerPath The path for the logger. - * + * @brief Set the logger's file path. + * @param aLoggerPath String representing the logger file path. + * @param aKey Custom dictionary key (optional). */ - void SetLoggerPath(const std::string &aLoggerPath); + void SetLoggerPath(const std::string &aLoggerPath, const std::string &aKey = ""); /** - * @brief Set the Total Data Generation execution time. - * @param[in] aTime The execution time. - * + * @brief Set the total data generation execution time. + * @param aTime Double representing the execution time. + * @param aKey Custom dictionary key (optional). */ - void SetTotalDataGenerationExecutionTime(double aTime); + void SetTotalDataGenerationExecutionTime(double aTime, const std::string &aKey = ""); /** - * @brief Set the Data Generation floating-point operations (FLOPs). - * @param[in] aFlops The number of FLOPs. - * + * @brief Set the total data generation FLOPS. + * @param aFlops Double representing the FLOPS. + * @param aKey Custom dictionary key (optional). */ - void SetTotalDataGenerationFlops(double aFlops); + void SetTotalDataGenerationFlops(double aFlops, const std::string &aKey = ""); /** * @brief Set the log-likelihood value. - * @param[in] aLogLikValue The log-likelihood value. - * + * @param aLogLikValue Double representing the log-likelihood value. + * @param aKey Custom dictionary key (optional). */ - void SetLogLikValue(double aLogLikValue); + void SetLogLikValue(double aLogLikValue, const std::string &aKey = ""); /** - * @brief Set the number of maximum likelihood estimation (MLE) iterations. - * @param[in] aIterationsNumber The number of MLE iterations. - * + * @brief Set the number of MLE iterations. + * @param aIterationsNumber Integer representing the number of iterations. + * @param aKey Custom dictionary key (optional). */ - void SetMLEIterations(int aIterationsNumber); + void SetMLEIterations(int aIterationsNumber, const std::string &aKey = ""); /** - * @brief Set the vector of maximum theta values. - * @param[in] aMaximumTheta The vector of maximum theta values. - * + * @brief Set the maximum theta vector. + * @param aMaximumTheta Vector of doubles representing the theta values. + * @param aKey Custom dictionary key (optional). */ - void SetMaximumTheta(const std::vector &aMaximumTheta); + void SetMaximumTheta(const std::vector &aMaximumTheta, const std::string &aKey = ""); /** * @brief Set the total modeling execution time. - * @param[in] aTime The total execution time for data modeling. - * + * @param aTime Double representing the execution time. + * @param aKey Custom dictionary key (optional). */ - void SetTotalModelingExecutionTime(double aTime); + void SetTotalModelingExecutionTime(double aTime, const std::string &aKey = ""); /** * @brief Get the total modeling execution time. - * @return The total execution time for data modeling. - * + * @return Double representing the total modeling execution time. */ [[nodiscard]] double GetTotalModelingExecutionTime() const; @@ -150,16 +150,15 @@ namespace exageostat::results { [[nodiscard]] std::vector GetPredictedMissedValues() const; /** - * @brief Set the total modeling FLOPs. - * @param[in] aTime The total number of FLOPs for data modeling. - * + * @brief Set the total modeling FLOPS. + * @param aTime Double representing the FLOPS. + * @param aKey Custom dictionary key (optional). */ - void SetTotalModelingFlops(double aTime); + void SetTotalModelingFlops(double aTime, const std::string &aKey = ""); /** - * @brief Get the total modeling FLOPs. - * @return The total number of FLOPs for data modeling. - * + * @brief Get the total modeling FLOPS. + * @return Double representing the total modeling FLOPS. */ [[nodiscard]] double GetTotalModelingFlops() const; @@ -182,105 +181,105 @@ namespace exageostat::results { * @param[in] aZMiss The value of ZMiss. * */ - void SetZMiss(int aZMiss); + void SetZMiss(int aZMiss, const std::string &aKey = ""); /** * @brief Set the value of MSPEError. * @param[in] aMSPEError The value of MSPEError. * */ - void SetMSPEError(double aMSPEError); + void SetMSPEError(double aMSPEError, const std::string &aKey = ""); /** * @brief Set the MSPE execution time. * @param[in] aTime The execution time. * */ - void SetMSPEExecutionTime(double aTime); + void SetMSPEExecutionTime(double aTime, const std::string &aKey = ""); /** * @brief Set the MSPE number of floating-point operations (FLOPs). * @param[in] aFlops The number of FLOPs. * */ - void SetMSPEFlops(double aFlops); + void SetMSPEFlops(double aFlops, const std::string &aKey = ""); /** * @brief Set the vector of IDW errors. * @param[in] aIDWError The vector of IDW errors. * */ - void SetIDWError(const std::vector &aIDWError); + void SetIDWError(const std::vector &aIDWError, const std::string &aKey = ""); /** * @brief Set the value of MLOE. * @param[in] aMLOE The value of MLOE. * */ - void SetMLOE(double aMLOE); + void SetMLOE(double aMLOE, const std::string &aKey = ""); /** * @brief Set the value of MMOM. * @param[in] aMMOM The value of MMOM. * */ - void SetMMOM(double aMMOM); + void SetMMOM(double aMMOM, const std::string &aKey = ""); /** * @brief Set the MLOE-MMOM execution time. * @param[in] aTime The execution time. * */ - void SetExecutionTimeMLOEMMOM(double aTime); + void SetExecutionTimeMLOEMMOM(double aTime, const std::string &aKey = ""); /** * @brief Set the MLOE-MMOM matrix generation time. * @param[in] aTime The execution time. * */ - void SetMatrixGenerationTimeMLOEMMOM(double aTime); + void SetMatrixGenerationTimeMLOEMMOM(double aTime, const std::string &aKey = ""); /** * @brief Set the MLOE-MMOM cholesky factorization time. * @param[in] aTime The execution time. * */ - void SetFactoTimeMLOEMMOM(double aTime); + void SetFactoTimeMLOEMMOM(double aTime, const std::string &aKey = ""); /** * @brief Set the MLOE-MMOM loop time. * @param[in] aTime The execution time. * */ - void SetLoopTimeMLOEMMOM(double aTime); + void SetLoopTimeMLOEMMOM(double aTime, const std::string &aKey = ""); /** * @brief Set the MLOE-MMOM number of floating-point operations (FLOPs). * @param[in] aFlops The number of FLOPs. * */ - void SetFlopsMLOEMMOM(double aFlops); + void SetFlopsMLOEMMOM(double aFlops, const std::string &aKey = ""); /** * @brief Set The total execution time of the fisher tile computation. * @param[in] aTime The total execution time for fisher tile computation. * */ - void SetTotalFisherTime(double aTime); + void SetTotalFisherTime(double aTime, const std::string &aKey = ""); /** * @brief Set the elements of the fisher matrix. * @param aFisherMatrix Elements of the fisher matrix. * */ - void SetFisherMatrix(std::vector aFisherMatrix); + void SetFisherMatrix(std::vector aFisherMatrix, const std::string &aKey = ""); /** * @brief Set the elements of the Z missed matrix. * @param aPredictedValues Elements of the Predicted Z missed matrix. * */ - void SetPredictedMissedValues(std::vector aPredictedValues); + void SetPredictedMissedValues(std::vector aPredictedValues, const std::string &aKey = ""); /** * @brief Print the end summary of the results. @@ -288,6 +287,15 @@ namespace exageostat::results { */ void PrintEndSummary(); + private: + /** + * @brief Add result to dictionary + * @param[in] aKey string used as title + * @param[in] aValue string value of result + * + */ + void UpdateDictionary(const std::string &aKey, const std::string &aValue); + private: /** * @brief Pointer to the singleton instance of the SyntheticGenerator class. @@ -345,6 +353,8 @@ namespace exageostat::results { std::vector mFisherMatrix; /// Z miss values std::vector mPredictedMissedValues; + /// Map that holds results + std::map mSummaryDictionary; }; }//namespace exageostat diff --git a/man/model_data.Rd b/man/model_data.Rd index b49a3665..32e63a49 100644 --- a/man/model_data.Rd +++ b/man/model_data.Rd @@ -15,7 +15,7 @@ \usage{ model_data(computation = "exact", kernel, distance_matrix = "euclidean", lb, -ub, tol = 4, mle_itr, dts, lts = 0, dimension = "2D", band = 0, max_rank = 500, +ub, tol = 4, mle_itr, dts, lts = 0, dimension = "2D", band = 0, max_rank = 500, acc = 0, data = NULL, matrix = NULL, x = NULL, y = NULL, z = NULL) } @@ -54,6 +54,7 @@ data = NULL, matrix = NULL, x = NULL, y = NULL, z = NULL) \item{dimension}{A string specifies the data dimension, either "2D" or "3D". Default is "2D".} \item{band}{A numeric value Bandwidth for band matrices, applicable in certain computational kernels, Default is 0.} \item{max_rank}{A numeric value specifies the Maximum rank for low-rank approximations, Default is 500.} +\item{acc}{A numeric value specifies the accuracy for low-rank approximations, The final value is computed as 10^(-1.0 * acc). Default is 0.} \item{data}{A list of data vectors. Default is `R_NilValue`.} \item{matrix}{A matrix object. Default is `R_NilValue`.} \item{x}{A numeric vector. Default is `R_NilValue`.} diff --git a/src/Rcpp-adapters/FunctionsAdapter.cpp b/src/Rcpp-adapters/FunctionsAdapter.cpp index 99560eca..02d9f0af 100644 --- a/src/Rcpp-adapters/FunctionsAdapter.cpp +++ b/src/Rcpp-adapters/FunctionsAdapter.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using namespace std; using namespace Rcpp; @@ -34,14 +35,14 @@ namespace exageostat::adapters { // manually set the configurations values with the user input from R. Configurations configurations; configurations.SetProblemSize(aProblemSize); - configurations.CheckKernelValue(aKernelName); - configurations.ParseDistanceMetric(aDistanceMatrix); + configurations.SetKernelName(validator::Validator::CheckKernelValue(aKernelName)); + configurations.SetDistanceMetric(validator::Validator::CheckDistanceMetricValue(aDistanceMatrix)); configurations.SetSeed(aSeed); configurations.SetDenseTileSize(aDenseTileSize); configurations.SetLowTileSize(aLowTileSize); configurations.SetComputation(EXACT_DENSE); configurations.SetInitialTheta(aInitialTheta); - configurations.SetDimension(Configurations::CheckDimensionValue(aDimension)); + configurations.SetDimension(validator::Validator::CheckDimensionValue(aDimension)); if (!aLogPath.empty()) { configurations.SetLogger(true); @@ -116,9 +117,10 @@ namespace exageostat::adapters { R_ExaGeoStatModelData(const string &aComputation, const string &aKernelName, const string &aDistanceMatrix, const vector &aLowerBound, const vector &aUpperBound, const int &aTolerance, const int &aMleIterations, const int &aDenseTileSize, const int &aLowTileSize, - const string &aDimension, const int &aBand, const int &aMaxRank, SEXP apData, - Nullable aMeasurementsVector, Nullable aLocationsX, - Nullable aLocationsY, Nullable aLocationsZ) { + const string &aDimension, const int &aBand, const int &aMaxRank, const int &aAccuracy, + SEXP apData, Nullable aMeasurementsVector, + Nullable aLocationsX, Nullable aLocationsY, + Nullable aLocationsZ) { Configurations configurations; bool is_initialized = ((SEXP) apData == R_NilValue); @@ -136,7 +138,7 @@ namespace exageostat::adapters { double *pMeasurementsVectorPtr = GetDataFromArguments(aMeasurementsVector, aLocationsX, aLocationsY, aLocationsZ, data, configurations, aKernelName, aDistanceMatrix, aDenseTileSize, aLowTileSize, aDimension, - Configurations::CheckComputationValue(aComputation)); + validator::Validator::CheckComputationValue(aComputation)); configurations.SetLowerBounds(aLowerBound); configurations.SetUpperBounds(aUpperBound); @@ -144,6 +146,7 @@ namespace exageostat::adapters { configurations.SetTolerance(aTolerance); configurations.SetBand(aBand); configurations.SetMaxRank(aMaxRank); + configurations.SetAccuracy(aAccuracy); ExaGeoStat::ExaGeoStatDataModeling(configurations, data, pMeasurementsVectorPtr); // Take back ownership, to avoid deleting apData when the unique_ptr goes out of scope. @@ -275,11 +278,11 @@ namespace exageostat::adapters { } // Set common configurations. aConfigurations.SetComputation(aComputation); - aConfigurations.CheckKernelValue(aKernelName); - aConfigurations.ParseDistanceMetric(aDistanceMatrix); + aConfigurations.SetKernelName(validator::Validator::CheckKernelValue(aKernelName)); + aConfigurations.SetDistanceMetric(validator::Validator::CheckDistanceMetricValue(aDistanceMatrix)); aConfigurations.SetDenseTileSize(aDenseTileSize); aConfigurations.SetLowTileSize(aLowTileSize); - aConfigurations.SetDimension(Configurations::CheckDimensionValue(aDimension)); + aConfigurations.SetDimension(validator::Validator::CheckDimensionValue(aDimension)); aConfigurations.SetProblemSize(aData->GetLocations()->GetSize()); return pMeasurementsVectorPtr; } @@ -352,11 +355,11 @@ namespace exageostat::adapters { } // Set common configurations. - aConfigurations.CheckKernelValue(aKernelName); - aConfigurations.ParseDistanceMetric(aDistanceMatrix); + aConfigurations.SetKernelName(validator::Validator::CheckKernelValue(aKernelName)); + aConfigurations.SetDistanceMetric(validator::Validator::CheckDistanceMetricValue(aDistanceMatrix)); aConfigurations.SetDenseTileSize(aDenseTileSize); aConfigurations.SetLowTileSize(aLowTileSize); - aConfigurations.SetDimension(Configurations::CheckDimensionValue(aDimension)); + aConfigurations.SetDimension(validator::Validator::CheckDimensionValue(aDimension)); aConfigurations.SetProblemSize(data->GetLocations()->GetSize()); aConfigurations.SetEstimatedTheta(aEstimatedTheta); diff --git a/src/Rcpp-adapters/RcppModules.cpp b/src/Rcpp-adapters/RcppModules.cpp index 17c9036d..55eb19ff 100644 --- a/src/Rcpp-adapters/RcppModules.cpp +++ b/src/Rcpp-adapters/RcppModules.cpp @@ -47,7 +47,7 @@ RCPP_MODULE(ExaGeoStatCPP) { function("model_data", &exageostat::adapters::R_ExaGeoStatModelData, List::create(_["computation"] = "exact", _["kernel"], _["distance_matrix"] = "euclidean", _["lb"], _["ub"], _["tol"] = 4, _["mle_itr"], _["dts"], _["lts"] = 0, _["dimension"] = "2D", _["band"] = 0, - _["max_rank"] = 500, _["data"] = R_NilValue, _["matrix"] = R_NilValue, _["x"] = R_NilValue, + _["max_rank"] = 500, _["acc"] = 0, _["data"] = R_NilValue, _["matrix"] = R_NilValue, _["x"] = R_NilValue, _["y"] = R_NilValue, _["z"] = R_NilValue)); function("predict_data", &exageostat::adapters::R_ExaGeoStatPredictData, diff --git a/src/api/ExaGeoStat.cpp b/src/api/ExaGeoStat.cpp index b9dc6a2d..8d666114 100644 --- a/src/api/ExaGeoStat.cpp +++ b/src/api/ExaGeoStat.cpp @@ -26,13 +26,13 @@ using namespace exageostat::configurations; template void ExaGeoStat::ExaGeoStatLoadData(Configurations &aConfigurations, std::unique_ptr> &aData) { + int seed = 0; + std::srand(seed); aConfigurations.PrintSummary(); LOGGER("** ExaGeoStat data generation/loading **") // Register and create a kernel object kernels::Kernel *pKernel = plugins::PluginRegistry>::Create(aConfigurations.GetKernelName(), aConfigurations.GetTimeSlot()); - // Add the data generation arguments. - aConfigurations.InitializeDataGenerationArguments(); // Create a unique pointer to a DataGenerator object unique_ptr> data_generator = DataGenerator::CreateGenerator(aConfigurations); aData = data_generator->CreateData(aConfigurations, *pKernel); @@ -50,8 +50,8 @@ T ExaGeoStat::ExaGeoStatDataModeling(Configurations &aConfigurations, std::un // Register and create a kernel object kernels::Kernel *pKernel = plugins::PluginRegistry>::Create(aConfigurations.GetKernelName(), aConfigurations.GetTimeSlot()); - // Add the data modeling arguments. - aConfigurations.InitializeDataModelingArguments(); + // Initialize all theta: starting, estimated, lower and upper bounds. + aConfigurations.InitializeAllTheta(); // We do Date Modeling with any computation. auto runtime_solver = runtimesolver::RuntimeSolverFactory::CreateRuntimeSolver(); @@ -71,8 +71,8 @@ void ExaGeoStat::ExaGeoStatPrediction(Configurations &aConfigurations, std::u // Register and create a kernel object kernels::Kernel *pKernel = plugins::PluginRegistry>::Create(aConfigurations.GetKernelName(), aConfigurations.GetTimeSlot()); - // Add the data prediction arguments. - aConfigurations.InitializeDataPredictionArguments(); + // Initialize all theta: starting, estimated, lower and upper bounds. + aConfigurations.InitializeAllTheta(); prediction::Prediction::PredictMissingData(aData, aConfigurations, apMeasurementsMatrix, *pKernel, apTrainLocations, apTestLocations); delete pKernel; diff --git a/src/configurations/CMakeLists.txt b/src/configurations/CMakeLists.txt index 3575e1a3..02ffb480 100644 --- a/src/configurations/CMakeLists.txt +++ b/src/configurations/CMakeLists.txt @@ -13,6 +13,8 @@ # Add the Configurations.cpp file to the list of source files. set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Configurations.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Parser.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Validator.cpp ${SOURCES} PARENT_SCOPE ) \ No newline at end of file diff --git a/src/configurations/Configurations.cpp b/src/configurations/Configurations.cpp index cc0d790d..6e14e3a4 100644 --- a/src/configurations/Configurations.cpp +++ b/src/configurations/Configurations.cpp @@ -12,15 +12,17 @@ * @date 2024-02-04 **/ -#include - #include +#include +#include #include #include using namespace std; using namespace exageostat::configurations; +using namespace exageostat::configurations::parser; +using namespace exageostat::configurations::validator; using namespace exageostat::common; Verbose Configurations::mVerbosity = Verbose::STANDARD_MODE; @@ -30,56 +32,20 @@ bool Configurations::mFirstInit = false; Configurations::Configurations() { - // Set default values for arguments! - SetComputation(EXACT_DENSE); - SetCoresNumber(1); - SetGPUsNumbers(0); - SetPGrid(1); - SetQGrid(1); - SetMaxRank(-1); - SetIsOOC(false); - SetKernelName(""); - SetDimension(Dimension2D); - SetTimeSlot(1); - SetProblemSize(0); - SetDenseTileSize(0); -#ifdef USE_HICMA - SetLowTileSize(0); -#endif - SetBand(0); - SetLoggerPath(""); - SetIsSynthetic(true); + // Set default values from the json file + Parser::ParseJSON(DEFAULT_CONFIGURATION_PATH, this->mDictionary); + Validator::Validate(this->mDictionary); + + // initialize thetas with empty vectors vector theta; SetInitialTheta(theta); SetLowerBounds(theta); SetUpperBounds(theta); SetEstimatedTheta(theta); - SetSeed(0); - SetLogger(false); - SetUnknownObservationsNb(0); - SetApproximationMode(1); - SetActualObservationsFilePath(""); - SetRecoveryFile(""); - SetPrecision(DOUBLE); - SetIsMSPE(false); - SetIsFisher(false); - SetIsIDW(false); - SetIsMLOEMMOM(false); - SetDataPath(""); - SetDistanceMetric(EUCLIDEAN_DISTANCE); - SetAccuracy(0); - SetIsNonGaussian(false); mIsThetaInit = false; + #if !DEFAULT_RUNTIME // Set default values for Hicma-Parsec params - SetDenseBandDP(0); - SetObjectsNumber(0); - SetAdaptiveDecision(0); - SetDiagonalAddition(0); - SetTimeSlotPerFile(1); - SetFileNumber(1); - SetEnableInverse(false); - SetMPIIO(true); SetTolerance(0); // TODO: currently, we support real data only in parsec. In the future, we should support synthetic and real data for both runtimes SetIsSynthetic(false); @@ -92,140 +58,13 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV, const this->mpArgV = apArgV; mHeapAllocated = aEnableR; - // Get the example name - string example_name = apArgV[0]; - // Remove the './' - example_name.erase(0, 2); - string argument; - string argument_name; - string argument_value; - int equal_sign_Idx; - - // Loop through the arguments - for (int i = 1; i < aArgC; ++i) { - argument = apArgV[i]; - equal_sign_Idx = static_cast(argument.find('=')); - argument_name = argument.substr(0, equal_sign_Idx); - - // Check if argument has an equal sign. - if (equal_sign_Idx != string::npos) { - argument_value = argument.substr(equal_sign_Idx + 1); - - // Check the argument name and set the corresponding value - if (argument_name == "--N" || argument_name == "--n") { - SetProblemSize(CheckNumericalValue(argument_value)); - } else if (argument_name == "--Kernel" || argument_name == "--kernel") { - CheckKernelValue(argument_value); - } else if (argument_name == "--P" || argument_name == "--p") { - SetPGrid(max(CheckNumericalValue(argument_value), GetPGrid())); - } else if (argument_name == "--Q" || argument_name == "--q") { - SetQGrid(max(CheckNumericalValue(argument_value), GetQGrid())); - } else if (argument_name == "--Dimension" || argument_name == "--dimension" || argument_name == "--dim" || - argument_name == "--Dim") { - SetDimension(CheckDimensionValue(argument_value)); - } else if (argument_name == "--TimeSlot" || argument_name == "--timeslot" || - argument_name == "--time_slot") { - SetTimeSlot(CheckNumericalValue(argument_value)); - } else if (argument_name == "--Computation" || argument_name == "--computation") { - SetComputation(CheckComputationValue(argument_value)); - } else if (argument_name == "--precision" || argument_name == "--Precision") { - SetPrecision(CheckPrecisionValue(argument_value)); - } else if (argument_name == "--cores" || argument_name == "--coresNumber" || - argument_name == "--cores_number" || argument_name == "--ncores") { - SetCoresNumber(CheckNumericalValue(argument_value)); - } else if (argument_name == "--gpus" || argument_name == "--GPUsNumbers" || - argument_name == "--gpu_number" || argument_name == "--ngpus") { - SetGPUsNumbers(CheckNumericalValue(argument_value)); - } else if (argument_name == "--DTS" || argument_name == "--dts" || argument_name == "--Dts") { - SetDenseTileSize(CheckNumericalValue(argument_value)); - } else if (argument_name == "--LTS" || argument_name == "--lts" || argument_name == "--Lts") { - SetLowTileSize(CheckNumericalValue(argument_value)); - } else if (argument_name == "--maxRank" || argument_name == "--maxrank" || argument_name == "--max_rank") { - SetMaxRank(CheckNumericalValue(argument_value)); - } else if (argument_name == "--initial_theta" || argument_name == "--itheta" || - argument_name == "--iTheta") { - vector theta = ParseTheta(argument_value); - SetInitialTheta(theta); - } else if (argument_name == "--lb" || argument_name == "--olb" || argument_name == "--lower_bounds") { - vector theta = ParseTheta(argument_value); - SetLowerBounds(theta); - SetStartingTheta(theta); - } else if (argument_name == "--ub" || argument_name == "--oub" || argument_name == "--upper_bounds") { - vector theta = ParseTheta(argument_value); - SetUpperBounds(theta); - } else if (argument_name == "--estimated_theta" || argument_name == "--etheta" || - argument_name == "--eTheta") { - vector theta = ParseTheta(argument_value); - SetEstimatedTheta(theta); - } else if (argument_name == "--ObservationsFile" || argument_name == "--observationsfile" || - argument_name == "--observations_file") { - SetActualObservationsFilePath(argument_value); - } else if (argument_name == "--Seed" || argument_name == "--seed") { - SetSeed(CheckNumericalValue(argument_value)); - } else if (argument_name == "--verbose" || argument_name == "--Verbose") { - ParseVerbose(argument_value); - } else if (argument_name == "--distance_metric" || argument_name == "--distanceMetric") { - ParseDistanceMetric(argument_value); - } else if (argument_name == "--logpath" || argument_name == "--log_path" || argument_name == "--logPath") { - SetLoggerPath(argument_value); - } else if(argument_name == "--band_dense" || argument_name == "--bandDense"){ - SetDenseBandDP(CheckNumericalValue(argument_value)); - } else if(argument_name == "--numobj" || argument_name == "--obj-num" || argument_name == "--objnum"){ - SetObjectsNumber(CheckNumericalValue(argument_value)); - } else if(argument_name == "--adaptive_decision"){ - SetAdaptiveDecision(CheckNumericalValue(argument_value)); - } else if(argument_name == "--add_diag" || argument_name == "--add-diag" || argument_name == "--add-diagonal" - || argument_name == "--add-diag-elements"){ - SetDiagonalAddition(CheckNumericalValue(argument_value)); - } else if(argument_name == "--file_time_slot" || argument_name == "--fileTimeSlot"){ - SetTimeSlotPerFile(CheckNumericalValue(argument_value)); - } else if(argument_name == "--numFiles" || argument_name == "--file-num"){ - SetFileNumber(CheckNumericalValue(argument_value)); - } else { - if (!(argument_name == "--ZmissNumber" || argument_name == "--Zmiss" || - argument_name == "--ZMiss" || argument_name == "--predict" || argument_name == "--Predict" || - argument_name == "--iterations" || - argument_name == "--Iterations" || argument_name == "--max_mle_iterations" || - argument_name == "--maxMleIterations" || argument_name == "--opt_iters" || - argument_name == "--tolerance" || argument_name == "--opt_tol" || - argument_name == "--distanceMetric" || argument_name == "--distance_metric" || - argument_name == "--log_file_name" || argument_name == "--logFileName" || - argument_name == "--Band" || argument_name == "--band" || - argument_name == "--DataPath" || argument_name == "--dataPath" || - argument_name == "--data_path" || - argument_name == "--acc" || argument_name == "--Acc")) { - LOGGER("!! " << argument_name << " !!") - throw invalid_argument( - "This argument is undefined, Please use --help to print all available arguments"); - } - } - } else { - if (argument_name == "--help") { - PrintUsage(); - } - if (argument_name == "--OOC" || argument_name == "--ooc") { - SetIsOOC(true); - } else if (argument_name == "--ApproximationMode" || argument_name == "--approximationmode" || - argument_name == "--approximation_mode") { - SetApproximationMode(true); - } else if (argument_name == "--log" || argument_name == "--Log") { - SetLogger(true); - } else if(argument_name == "--enable-inverse" || argument_name == "--enable_inverse"){ - SetEnableInverse(true); - } else if(argument_name == "--mpiio"){ - SetMPIIO(true); - } else { - if (!(argument_name == "--mspe" || argument_name == "--MSPE" || - argument_name == "--idw" || argument_name == "--IDW" || - argument_name == "--mloe-mmom" || argument_name == "--mloe_mmom" || - argument_name == "--fisher" || argument_name == "--Fisher")) { - LOGGER("!! " << argument_name << " !!") - throw invalid_argument( - "This argument is undefined, Please use --help to print all available arguments"); - } - } - } - } + // the CLI arguments overwrite the arguments of the constructor + Parser::ParseCLI(aArgC, apArgV, this->mDictionary); + Validator::Validate(this->mDictionary); + ValidateConfiguration(); +} + +void Configurations::ValidateConfiguration() { // Throw Errors if any of these arguments aren't given by the user. if (GetProblemSize() == 0 && GetIsSynthetic()) { @@ -236,12 +75,37 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV, const throw domain_error("You need to set the Dense tile size, before starting"); } + if (!GetDataPath().empty()) { + SetIsSynthetic(false); + } + + if (GetIsMSPE() || GetIsMLOEMMOM() || GetIsIDW()) { + if (GetUnknownObservationsNb() <= 1) { + throw domain_error( + "You need to set ZMiss number, as the number of missing values should be bigger than one"); + } + } + + if (!GetLoggerPath().empty() && !GetLogger()) { + throw domain_error("To enable logging, please utilize the '--log' option in order to specify a log file."); + } + + if (GetUnknownObservationsNb() >= GetProblemSize()) { + throw range_error("Invalid value for ZmissNumber. Please make sure it's smaller than Problem size"); + } + + if (GetComputation() == DIAGONAL_APPROX) { + if (GetBand() == 0) { + throw domain_error("You need to set the tile band thickness, before starting"); + } + } + #if DEFAULT_RUNTIME // Throw Errors if any of these arguments aren't given by the user. if (GetKernelName().empty()) { throw domain_error("You need to set the Kernel, before starting"); } - if(GetMaxRank() == -1){ + if (GetMaxRank() == -1) { SetMaxRank(1); } #else @@ -251,6 +115,9 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV, const if(GetTolerance() >= 0){ SetTolerance(8); } + if (GetDataPath().empty()) { + throw domain_error("You need to set the data path, before starting"); + } #endif size_t found = GetKernelName().find("NonGaussian"); @@ -258,6 +125,25 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV, const if (found != std::string::npos) { SetIsNonGaussian(true); } + + if (GetDimension() != DimensionST) { + if (GetTimeSlot() != 1) { +#if DEFAULT_RUNTIME + throw std::runtime_error("Time Slot can only be greater than 1 if the dimensions are set to SpaceTime."); +#endif + } + } else if (GetTimeSlot() < 1) { + throw std::runtime_error("Time Slot must be at least 1 if the dimensions are set to SpaceTime."); + } + + + if (GetComputation() == TILE_LOW_RANK) { +#ifdef USE_HICMA + if (GetLowTileSize() == 0) { + throw domain_error("You need to set the Low tile size, before starting"); + } +#endif + } } void Configurations::InitializeAllTheta() { @@ -293,153 +179,8 @@ void Configurations::InitializeAllTheta() { } } -void Configurations::InitializeDataGenerationArguments() { - - this->InitializeAllTheta(); - string argument; - string argument_name; - string argument_value; - int equal_sign_Idx; - - // Loop through the arguments that are specific for data generation. - for (int i = 1; i < this->mArgC; ++i) { - argument = this->mpArgV[i]; - equal_sign_Idx = static_cast(argument.find('=')); - argument_name = argument.substr(0, equal_sign_Idx); - - // Check if argument has an equal sign. - if (equal_sign_Idx != string::npos) { - argument_value = argument.substr(equal_sign_Idx + 1); - - // Check the argument name and set the corresponding value - if (argument_name == "--DataPath" || argument_name == "--dataPath" || - argument_name == "--data_path") { - SetDataPath(argument_value); - SetIsSynthetic(false); - } - } - } - if (GetDimension() != DimensionST) { - if (GetTimeSlot() != 1) { -#if DEFAULT_RUNTIME - throw std::runtime_error("Time Slot can only be greater than 1 if the dimensions are set to SpaceTime."); -#endif - } - } else if (GetTimeSlot() < 1) { - throw std::runtime_error("Time Slot must be at least 1 if the dimensions are set to SpaceTime."); - } - -#if !DEFAULT_RUNTIME - if (GetDataPath().empty()) { - throw domain_error("You need to set the data path, before starting"); - } -#endif -} - -void Configurations::InitializeDataModelingArguments() { - - this->InitializeAllTheta(); - string argument; - string argument_name; - string argument_value; - int equal_sign_Idx; - - // Loop through the arguments that are specific for data modeling. - for (int i = 1; i < this->mArgC; ++i) { - argument = this->mpArgV[i]; - equal_sign_Idx = static_cast(argument.find('=')); - argument_name = argument.substr(0, equal_sign_Idx); - - // Check if argument has an equal sign. - if (equal_sign_Idx != string::npos) { - argument_value = argument.substr(equal_sign_Idx + 1); - - // Check the argument name and set the corresponding value - if (argument_name == "--max_mle_iterations" || argument_name == "--maxMleIterations" || - argument_name == "--opt_iters") { - SetMaxMleIterations(CheckNumericalValue(argument_value)); - } else if (argument_name == "--tolerance" || argument_name == "--opt_tol") { - SetTolerance(CheckNumericalValue(argument_value)); - } else if (argument_name == "--Band" || argument_name == "--band") { - SetBand(CheckNumericalValue(argument_value)); - } else if (argument_name == "--acc" || argument_name == "--Acc") { - SetAccuracy(CheckNumericalValue(argument_value)); - } else if (argument_name == "--log_file_name" || argument_name == "--logFileName") { - if (!GetLogger()) { - throw domain_error( - "To enable logging, please utilize the '--log' option in order to specify a log file."); - } - SetFileLogName(argument_value); - } - } - } - if (GetComputation() == DIAGONAL_APPROX) { - if (GetBand() == 0) { - throw domain_error("You need to set the tile band thickness, before starting"); - } - } - if (GetComputation() == TILE_LOW_RANK) { -#ifdef USE_HICMA - if (GetLowTileSize() == 0) { - throw domain_error("You need to set the Low tile size, before starting"); - } -#endif - } -} - -void Configurations::InitializeDataPredictionArguments() { - - this->InitializeAllTheta(); - string argument; - string argument_name; - string argument_value; - int equal_sign_Idx; - - for (int i = 1; i < this->mArgC; ++i) { - argument = this->mpArgV[i]; - equal_sign_Idx = static_cast(argument.find('=')); - argument_name = argument.substr(0, equal_sign_Idx); - if (equal_sign_Idx != string::npos) { - argument_value = argument.substr(equal_sign_Idx + 1); - if (argument_name == "--ZmissNumber" || argument_name == "--Zmiss" || argument_name == "--ZMiss" || - argument_name == "--predict" || argument_name == "--Predict") { - SetUnknownObservationsNb(CheckUnknownObservationsValue(argument_value)); - } - } - } - - // Loop through the arguments that are specific for Prediction. - for (int i = 1; i < this->mArgC; ++i) { - argument = this->mpArgV[i]; - equal_sign_Idx = static_cast(argument.find('=')); - argument_name = argument.substr(0, equal_sign_Idx); - - if (argument_name == "--mspe" || argument_name == "--MSPE") { - if (GetUnknownObservationsNb() <= 1) { - throw domain_error( - "You need to set ZMiss number, as the number of missing values should be bigger than one"); - } - SetIsMSPE(true); - } else if (argument_name == "--idw" || argument_name == "--IDW") { - if (GetUnknownObservationsNb() <= 1) { - throw domain_error( - "You need to set ZMiss number, as the number of missing values should be bigger than one"); - } - SetIsIDW(true); - } else if (argument_name == "--mloe-mmom" || argument_name == "--MLOE_MMOM" || argument_name == "--mloe_mmom") { - if (GetUnknownObservationsNb() <= 1) { - throw domain_error( - "You need to set ZMiss number, as the number of missing values should be bigger than one"); - } - SetIsMLOEMMOM(true); - } else if (argument_name == "--Fisher" || argument_name == "--fisher") { - //Fisher can be performed without zmiss. - SetIsFisher(true); - } - } -} - void Configurations::PrintUsage() { + LOGGER("\n\t*** Available Arguments For ExaGeoStat Configurations ***") LOGGER("--N=value : Problem size.") LOGGER("--kernel=value : Used Kernel.") @@ -457,10 +198,8 @@ void Configurations::PrintUsage() { LOGGER("--Zmiss=value : Used to set number of unknown observation to be predicted.") LOGGER("--observations_file=PATH/TO/File : Used to pass the observations file path.") LOGGER("--max_rank=value : Used to the max rank value.") - LOGGER("--olb=value : Lower bounds for optimization.") - LOGGER("--oub=value : Upper bounds for optimization.") - LOGGER("--itheta=value : Initial theta parameters for optimization.") - LOGGER("--etheta=value : Estimated kernel parameters for optimization.") + LOGGER("--initial_theta=value : Initial theta parameters for optimization.") + LOGGER("--estimated_theta=value : Estimated kernel parameters for optimization.") LOGGER("--seed=value : Seed value for random number generation.") LOGGER("--verbose=value : Run mode whether quiet/standard/detailed.") LOGGER("--log_path=value : Path to log file.") @@ -475,15 +214,16 @@ void Configurations::PrintUsage() { LOGGER("--OOC : Used to enable Out of core technology.") LOGGER("--approximation_mode : Used to enable Approximation mode.") LOGGER("--log : Enable logging.") - LOGGER("--acc : Used to set the accuracy when using tlr.") + LOGGER("--accuracy : Used to set the accuracy when using tlr.") LOGGER("--band_dense=value : Used to set the dense band double precision, Used with PaRSEC runtime only.") - LOGGER("--numobj=value : Used to set the number of objects (number of viruses within a population), Used with PaRSEC runtime only.") + LOGGER("--objects_number=value : Used to set the number of objects (number of viruses within a population), Used with PaRSEC runtime only.") LOGGER("--adaptive_decision=value : Used to set the adaptive decision of each tile's format using norm approach, if enabled, otherwise 0, Used with PaRSEC runtime only.") - LOGGER("--add_diag=value : Used to add this number to diagonal elements to make the matrix positive definite in electrodynamics problem, Used with PaRSEC runtime only.") + LOGGER("--add_diagonal=value : Used to add this number to diagonal elements to make the matrix positive definite in electrodynamics problem, Used with PaRSEC runtime only.") LOGGER("--file_time_slot=value : Used to set time slot per file, Used with PaRSEC runtime only.") - LOGGER("--numFiles=value : Used to set file number, Used with PaRSEC runtime only.") + LOGGER("--file_number=value : Used to set file number, Used with PaRSEC runtime only.") LOGGER("--enable-inverse : Used to enable inverse spherical harmonics transform, Used with PaRSEC runtime only.") LOGGER("--mpiio : Used to enable MPI IO, Used with PaRSEC runtime only.") + LOGGER("--log-file-path: Used to set path of file where events and results are logged.") LOGGER("\n\n") exit(0); @@ -497,178 +237,6 @@ void Configurations::SetVerbosity(const Verbose &aVerbose) { Configurations::mVerbosity = aVerbose; } -int Configurations::CheckNumericalValue(const string &aValue) { - - int numericalValue; - try { - numericalValue = stoi(aValue); - } - catch (...) { - throw range_error("Invalid value. Please use Numerical values only."); - } - - if (numericalValue < 0) { - throw range_error("Invalid value. Please use positive values"); - } - return numericalValue; -} - -Computation Configurations::CheckComputationValue(const std::string &aValue) { - - if (aValue != "exact" and aValue != "Exact" and aValue != "Dense" and aValue != "dense" and - aValue != "diag_approx" and aValue != "diagonal_approx" and aValue != "lr_approx" and aValue != "tlr" and - aValue != "TLR") { - throw range_error("Invalid value for Computation. Please use Exact, diagonal_approx or TLR."); - } - if (aValue == "exact" or aValue == "Exact" or aValue == "Dense" or aValue == "dense") { - return EXACT_DENSE; - } else if (aValue == "diag_approx" or aValue == "diagonal_approx") { - return DIAGONAL_APPROX; - } - return TILE_LOW_RANK; -} - -Precision Configurations::CheckPrecisionValue(const std::string &aValue) { - - if (aValue != "single" and aValue != "Single" and aValue != "double" and aValue != "Double" and aValue != "mix" and - aValue != "Mix" and aValue != "Mixed" and aValue != "mixed") { - throw range_error("Invalid value for Computation. Please use Single, Double or Mixed."); - } - if (aValue == "single" or aValue == "Single") { - return SINGLE; - } else if (aValue == "double" or aValue == "Double") { - return DOUBLE; - } - return MIXED; -} - -void Configurations::ParseVerbose(const std::string &aVerbosity) { - if (aVerbosity == "quiet" || aVerbosity == "Quiet") { - mVerbosity = Verbose::QUIET_MODE; - } else if (aVerbosity == "standard" || aVerbosity == "Standard") { - mVerbosity = Verbose::STANDARD_MODE; - } else if (aVerbosity == "detailed" || aVerbosity == "Detailed" || aVerbosity == "detail") { - mVerbosity = Verbose::DETAILED_MODE; - } else { - LOGGER("Error: " << aVerbosity << " is not valid ") - throw range_error("Invalid value. Please use verbose or standard values only."); - } -} - - -void Configurations::CheckKernelValue(const string &aKernel) { - - // Check if the kernel name exists in the availableKernels set. - if (availableKernels.count(aKernel) <= 0) { - throw range_error("Invalid value for Kernel. Please check manual."); - } - // Check if the string is already in CamelCase format - if (IsCamelCase(aKernel)) { - this->SetKernelName(aKernel); - return; - } - string str = aKernel; - // Replace underscores with spaces and split the string into words - std::replace(str.begin(), str.end(), '_', ' '); - std::istringstream iss(str); - std::string word, result; - while (iss >> word) { - // Capitalize the first letter of each word and append it to the result - word[0] = static_cast(toupper(word[0])); - result += word; - } - this->SetKernelName(result); -} - -bool Configurations::IsCamelCase(const std::string &aString) { - // If the string contains an underscore, it is not in CamelCase format - if (aString.find('_') != std::string::npos) { - return false; - } - // If the string starts with a lowercase letter, it is not in CamelCase format - if (islower(aString[0])) { - return false; - } - // If none of the above conditions hold, the string is in CamelCase format - return true; -} - -vector Configurations::ParseTheta(const std::string &aInputValues) { - // Count the number of values in the string - int num_values = 1; - for (char aInputValue: aInputValues) { - if (aInputValue == ':') { - num_values++; - } - } - // Allocate memory for the array of doubles - vector theta; - - // Split the string into tokens using strtok() - const char *delim = ":"; - char *token = strtok((char *) aInputValues.c_str(), delim); - int i = 0; - while (token != nullptr) { - // Check if the token is a valid double or "?" - if (!strcmp(token, "?")) { - theta.push_back(-1); - } else { - try { - theta.push_back(stod(token)); - } - catch (...) { - LOGGER("Error: " << token << " is not a valid double or '?' ") - throw range_error("Invalid value. Please use Numerical values only."); - } - } - - // Get the next token - token = strtok(nullptr, delim); - i++; - } - - // Check if the number of values in the array is correct - if (i != num_values) { - throw range_error( - "Error: the number of values in the input string is invalid, please use this example format as a reference 1:?:0.1"); - } - - return theta; -} - -Dimension Configurations::CheckDimensionValue(const string &aDimension) { - - if (aDimension != "2D" and aDimension != "2d" and aDimension != "3D" and aDimension != "3d" and - aDimension != "st" and aDimension != "ST") { - throw range_error("Invalid value for Dimension. Please use 2D, 3D or ST."); - } - if (aDimension == "2D" or aDimension == "2d") { - return Dimension2D; - } else if (aDimension == "3D" or aDimension == "3d") { - return Dimension3D; - } - return DimensionST; -} - -int Configurations::CheckUnknownObservationsValue(const string &aValue) { - int value = CheckNumericalValue(aValue); - if (value >= GetProblemSize()) { - throw range_error("Invalid value for ZmissNumber. Please make sure it's smaller than Problem size"); - } - return value; -} - -void Configurations::ParseDistanceMetric(const std::string &aDistanceMetric) { - if (aDistanceMetric == "eg" || aDistanceMetric == "EG" || aDistanceMetric == "euclidean") { - SetDistanceMetric(EUCLIDEAN_DISTANCE); - } else if (aDistanceMetric == "gcd" || aDistanceMetric == "GCD" || aDistanceMetric == "great_circle") { - SetDistanceMetric(GREAT_CIRCLE_DISTANCE); - } else { - throw range_error("Invalid value. Please use eg or gcd values only."); - } -} - - void Configurations::InitTheta(vector &aTheta, const int &size) { // If null, this mean user have not passed the values arguments, Make values equal -1 @@ -686,8 +254,8 @@ void Configurations::InitTheta(vector &aTheta, const int &size) { void Configurations::PrintSummary() { -#ifndef USING_R - Verbose temp = this->GetVerbosity(); +#ifndef USE_R + Verbose temp = Configurations::GetVerbosity(); mVerbosity = STANDARD_MODE; if (!mFirstInit) { @@ -739,10 +307,10 @@ void Configurations::PrintSummary() { LOGGER("#Out Of Core (OOC) technology is enabled") } #else - LOGGER("\t#L: " << this->GetDenseTileSize() << "\t\t\t\t#T: " << this->GetTimeSlot()) - LOGGER("\t#NB: " << this->GetDenseTileSize() << "\t\t\t\t#gpus: " << this->GetGPUsNumbers()) - LOGGER("\t#Nodes: " << this->GetCoresNumber() << "\t\t\t#Time slot per file: " << GetTimeSlotPerFile()); - LOGGER("\t#Number of files: " << this->GetFileNumber() << "\t#File per node: " << ((this->GetFileNumber()%this->GetCoresNumber())? this->GetFileNumber()/this->GetCoresNumber()+1 : this->GetFileNumber()/this->GetCoresNumber())) + LOGGER("\t#L: " << this->GetDenseTileSize() << "\t\t\t\t#T: " << this->GetTimeSlot()) + LOGGER("\t#NB: " << this->GetDenseTileSize() << "\t\t\t\t#gpus: " << this->GetGPUsNumbers()) + LOGGER("\t#Nodes: " << this->GetCoresNumber() << "\t\t\t#Time slot per file: " << GetTimeSlotPerFile()); + LOGGER("\t#Number of files: " << this->GetFileNumber() << "\t#File per node: " << ((this->GetFileNumber()%this->GetCoresNumber())? this->GetFileNumber()/this->GetCoresNumber()+1 : this->GetFileNumber()/this->GetCoresNumber())) #endif LOGGER("*************************************************") mFirstInit = true; @@ -768,5 +336,5 @@ Configurations::~Configurations() { } void Configurations::SetTolerance(double aTolerance) { - mDictionary["Tolerance"] = pow(10, -1 * aTolerance); + mDictionary["tolerance"] = pow(10, -1 * aTolerance); } diff --git a/src/configurations/Parser.cpp b/src/configurations/Parser.cpp new file mode 100644 index 00000000..7f8687b3 --- /dev/null +++ b/src/configurations/Parser.cpp @@ -0,0 +1,81 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** +* @file Parser.cpp +* @version 1.1.0 +* @brief Contains the implementation of the Parser class and its member functions for configuration parsing. +* @details Provides static methods to parse command-line arguments and JSON configuration files, as well as utility functions for string transformations. +* @author Mahmoud ElKarargy +* @date 2024-12-11 +**/ + +#include +#include + +#include + +using namespace std; +using namespace exageostat::configurations::parser; + +void Parser::ParseCLI(const int &aArgC, char **apArgV, unordered_map &apConfigurationMap) { + + string example_name = apArgV[0]; + // Remove the './' + example_name.erase(0, 2); + string argument; + string argument_name; + string argument_value; + int equal_sign_Idx; + + for (int i = 1; i < aArgC; ++i) { + argument = apArgV[i]; + argument = argument.substr(2); + equal_sign_Idx = static_cast(argument.find('=')); + argument_name = argument.substr(0, equal_sign_Idx); + + string converted_name = ProcessKeyString(argument_name); + + if (equal_sign_Idx != string::npos) { + // Store value as a string + argument_value = argument.substr(equal_sign_Idx + 1); + apConfigurationMap[converted_name] = argument_value; + } else { + // For flags, store "true" as a string + apConfigurationMap[converted_name] = string("true"); + } + } +} + +void Parser::ParseJSON(const string &aJSONFile, unordered_map &apConfigurationMap) { + + const auto &config_path = aJSONFile; + ifstream json_file_stream(config_path); + if (!json_file_stream.is_open()) { + throw runtime_error("Could not open JSON configuration file."); + } + + nlohmann::json json_config; + json_file_stream >> json_config; + + for (auto &[key, value]: json_config.items()) { + auto converted_name = ProcessKeyString(key); + apConfigurationMap[converted_name] = value.get(); + + } +} + +string Parser::ProcessKeyString(const string &arg) { + + // Process the string to remove dashes/underscores and handle capitalization + std::string result; + for (char ch : arg) { + // Ignore hyphens, underscores, and other non-alphanumeric characters + if (std::isalnum(ch)) { // Keep only alphanumeric characters + result += static_cast(std::tolower(ch)); // Convert to lowercase + } + } + return result; +} diff --git a/src/configurations/Validator.cpp b/src/configurations/Validator.cpp new file mode 100644 index 00000000..0805a037 --- /dev/null +++ b/src/configurations/Validator.cpp @@ -0,0 +1,320 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file Validator.cpp + * @brief This file defines the Validator class which validates configuration string input. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-12-11 +**/ + +#include + +#include +#include + +using namespace std; +using namespace exageostat::common; +using namespace exageostat::configurations::validator; + +const unordered_map> Validator::mCheckersMap = { + {"Theta", [](const string &value) -> any { return CheckThetaValue(value); }}, + {"Tolerance", [](const string &value) -> any { return CheckToleranceValue(value); }}, + {"FileHandler", [](const string &value) -> any { return CheckLogFileValue(value); }}, + {"Bool", [](const string &value) -> any { return CheckBoolValue(value); }}, + {"Numerical", [](const string &value) -> any { return CheckNumericalValue(value); }}, + {"Dimension", [](const string &value) -> any { return CheckDimensionValue(value); }}, + {"DistanceMetric", [](const string &value) -> any { return CheckDistanceMetricValue(value); }}, + {"Kernel", [](const string &value) -> any { return CheckKernelValue(value); }}, + {"Verbose", [](const string &value) -> any { return CheckVerboseValue(value); }}, + {"Precision", [](const string &value) -> any { return CheckPrecisionValue(value); }}, + {"Computation", [](const string &value) -> any { return CheckComputationValue(value); }} +}; + +const std::unordered_map Validator::mArgumentToCategoryMap = { + {"n", "Numerical"}, + {"kernel", "Kernel"}, + {"p", "Numerical"}, + {"q", "Numerical"}, + {"timeslot", "Numerical"}, + {"computation", "Computation"}, + {"precision", "Precision"}, + {"cores", "Numerical"}, + {"gpus", "Numerical"}, + {"dts", "Numerical"}, + {"lts", "Numerical"}, + {"band", "Numerical"}, + {"maxrank", "Numerical"}, + {"observationnumber", "Numerical"}, + {"observationsfile", "Path"}, + {"filelogname", "Path"}, + {"filelogpath", "FileHandler"}, + {"seed", "Numerical"}, + {"logpath", "Path"}, + {"initialtheta", "Theta"}, + {"ooc", "Bool"}, + {"approximationmode", "Numerical"}, + {"mspe", "Bool"}, + {"fisher", "Bool"}, + {"idw", "Bool"}, + {"log", "Bool"}, + {"lb", "Theta"}, + {"ub", "Theta"}, + {"estimatedtheta", "Theta"}, + {"startingtheta", "Theta"}, + {"isnongaussian", "Bool"}, + {"verbose", "Verbose"}, + {"banddense", "Numerical"}, + {"objectsnumber", "Numerical"}, + {"adaptivedecision", "Numerical"}, + {"adddiagonal", "Numerical"}, + {"filetimeslot", "Numerical"}, + {"filenumber", "Numerical"}, + {"enableinverse", "Bool"}, + {"mpiio", "Bool"}, + {"mloemmom", "Bool"}, + {"dimension", "Dimension"}, + {"issynthetic", "Bool"}, + {"datapath", "Path"}, + {"recoveryfile", "Path"}, + {"distancemetric", "DistanceMetric"}, + {"maxmleiterations", "Numerical"}, + {"accuracy", "Numerical"}, + {"tolerance", "Tolerance"}, + {"zmiss", "Numerical"}, + {"missingpattern", "Theta"}, +}; + +Computation Validator::CheckComputationValue(const string &aValue) { + + if (aValue != "exact" and aValue != "Exact" and aValue != "Dense" and aValue != "dense" and + aValue != "diag_approx" and aValue != "diagonal_approx" and aValue != "lr_approx" and aValue != "tlr" and + aValue != "TLR") { + throw range_error("Invalid value for Computation. Please use Exact, diagonal_approx or TLR."); + } + if (aValue == "exact" or aValue == "Exact" or aValue == "Dense" or aValue == "dense") { + return EXACT_DENSE; + } else if (aValue == "diag_approx" or aValue == "diagonal_approx") { + return DIAGONAL_APPROX; + } + return TILE_LOW_RANK; +} + +Precision Validator::CheckPrecisionValue(const string &aValue) { + + if (aValue != "single" and aValue != "Single" and aValue != "double" and aValue != "Double" and aValue != "mix" and + aValue != "Mix" and aValue != "Mixed" and aValue != "mixed") { + throw range_error("Invalid value for Computation. Please use Single, Double or Mixed."); + } + if (aValue == "single" or aValue == "Single") { + return SINGLE; + } else if (aValue == "double" or aValue == "Double") { + return DOUBLE; + } + return MIXED; +} + +string Validator::CheckKernelValue(const string &aKernel) { + + // Check if the kernel name exists in the availableKernels set. + if (availableKernels.count(aKernel) <= 0) { + throw range_error("Invalid value for Kernel. Please check manual."); + } + // Check if the string is already in CamelCase format + if (IsCamelCase(aKernel)) { + return aKernel; + } + string str = aKernel; + // Replace underscores with spaces and split the string into words + replace(str.begin(), str.end(), '_', ' '); + istringstream iss(str); + string word, result; + while (iss >> word) { + // Capitalize the first letter of each word and append it to the result + word[0] = static_cast(toupper(word[0])); + result += word; + } + return result; +} + +bool Validator::IsCamelCase(const string &aString) { + + // If the string contains an underscore, it is not in CamelCase format + if (aString.find('_') != string::npos) { + return false; + } + // If the string starts with a lowercase letter, it is not in CamelCase format + if (islower(aString[0])) { + return false; + } + // If none of the above conditions hold, the string is in CamelCase format + return true; +} + +Verbose Validator::CheckVerboseValue(const string &aVerbosity) { + + if (aVerbosity == "quiet" || aVerbosity == "Quiet") { + Configurations::SetVerbosity(Verbose::QUIET_MODE); + return Verbose::QUIET_MODE; + } else if (aVerbosity == "standard" || aVerbosity == "Standard") { + Configurations::SetVerbosity(Verbose::STANDARD_MODE); + return Verbose::STANDARD_MODE; + } else if (aVerbosity == "detailed" || aVerbosity == "Detailed" || aVerbosity == "detail") { + Configurations::SetVerbosity(Verbose::DETAILED_MODE); + return Verbose::DETAILED_MODE; + } else { + LOGGER("Error: " << aVerbosity << " is not valid ") + throw range_error("Invalid value. Please use verbose or standard values only."); + } +} + + +int Validator::CheckNumericalValue(const string &aValue) { + + int numerical_value; + try { + numerical_value = stoi(aValue); + } + catch (...) { + throw range_error("Invalid value. Please use Numerical values only."); + } + + if (numerical_value < 0) { + throw range_error("Invalid value. Please use positive values"); + } + return numerical_value; +} + + +vector Validator::CheckThetaValue(const string &aInputValues) { + + // Count the number of values in the string + int num_values = 1; + for (char input_value_char: aInputValues) { + if (input_value_char == ':') { + num_values++; + } + } + // Allocate memory for the array of doubles + vector theta; + + if (aInputValues.empty()) { + return theta; + } + + // Split the string into tokens using strtok() + const char *delim = ":"; + char *token = strtok((char *) aInputValues.c_str(), delim); + int i = 0; + while (token != nullptr) { + // Check if the token is a valid double or "?" + if (!strcmp(token, "?")) { + theta.push_back(-1); + } else { + try { + theta.push_back(stod(token)); + } + catch (...) { + LOGGER("Error: " << token << " is not a valid double or '?' ") + throw range_error("Invalid value. Please use Numerical values only."); + } + } + + // Get the next token + token = strtok(nullptr, delim); + i++; + } + + // Check if the number of values in the array is correct + if (i != num_values) { + throw range_error( + "Error: the number of values in the input string is invalid, please use this example format as a reference 1:?:0.1"); + } + + return theta; +} + +Dimension Validator::CheckDimensionValue(const string &aDimension) { + + if (aDimension != "2D" and aDimension != "2d" and aDimension != "3D" and aDimension != "3d" and + aDimension != "st" and aDimension != "ST") { + throw range_error("Invalid value for Dimension. Please use 2D, 3D or ST."); + } + if (aDimension == "2D" or aDimension == "2d") { + return Dimension2D; + } else if (aDimension == "3D" or aDimension == "3d") { + return Dimension3D; + } + return DimensionST; +} + +bool Validator::CheckBoolValue(const string &aBooleanValue) { + + // Convert input to lowercase for case-insensitive comparison + std::string lower_case_value = aBooleanValue; + std::transform(lower_case_value.begin(), lower_case_value.end(), lower_case_value.begin(), ::tolower); + + // Check if the value matches "true" in any case + if (lower_case_value == "true") + return true; + else + return false; +} + + +DistanceMetric Validator::CheckDistanceMetricValue(const string &aDistanceMetric) { + + if (aDistanceMetric == "eg" || aDistanceMetric == "EG" || aDistanceMetric == "euclidean") { + return EUCLIDEAN_DISTANCE; + } else if (aDistanceMetric == "gcd" || aDistanceMetric == "GCD" || aDistanceMetric == "great_circle") { + return GREAT_CIRCLE_DISTANCE; + } else { + throw range_error("Invalid value. Please use eg or gcd values only."); + } +} + +double Validator::CheckToleranceValue(const string &aTolerancePower) { + + auto val = Validator::CheckNumericalValue(aTolerancePower); + return pow(10, -1 * val); +} + +FILE *Validator::CheckLogFileValue(const std::string &apFileLogPath) { + + if (apFileLogPath.empty()) { + throw std::invalid_argument("Path cannot be empty."); + } + + auto file_handler = fopen(apFileLogPath.c_str(), "w"); + + if (file_handler == nullptr) { + throw std::domain_error("Failed to open file at path " + apFileLogPath + "."); + } + return file_handler; +} + +void Validator::Validate(unordered_map &apArgsMap) { + + for (auto &[key, value]: apArgsMap) { + // Find the appropriate checker based on key + auto category_map_key = mArgumentToCategoryMap.find(key); + if (category_map_key == mArgumentToCategoryMap.end()) { // throw exception if no category + throw invalid_argument("No category for the following argument name: " + key); + } else if (category_map_key->second != "Path") { + auto it = mCheckersMap.find(category_map_key->second); + if (it != mCheckersMap.end()) { + if (value.type() == typeid(std::string)) { + // Apply the checker function + auto checker_function = it->second; + auto checked_value = checker_function(any_cast(value)); + apArgsMap[key] = checked_value; + } + } else { + throw invalid_argument("Unknown key in the args map: " + key); + } + } + } +} diff --git a/src/data-loader/concrete/ParsecLoader.cpp b/src/data-loader/concrete/ParsecLoader.cpp index d3167b1e..b5daa893 100644 --- a/src/data-loader/concrete/ParsecLoader.cpp +++ b/src/data-loader/concrete/ParsecLoader.cpp @@ -55,6 +55,7 @@ ParsecLoader::LoadData(configurations::Configurations &aConfigurations, exage int rank = ExaGeoStatHardware::GetParsecMPIRank(); int verbose = configurations::Configurations::GetVerbosity() == DETAILED_MODE? 1: 0; int gpus = aConfigurations.GetGPUsNumbers(); + int tile_size = aConfigurations.GetDenseTileSize(); string files_directory_path = aConfigurations.GetDataPath(); int path_length = files_directory_path.length(); char filename[path_length + 50]; @@ -73,7 +74,7 @@ ParsecLoader::LoadData(configurations::Configurations &aConfigurations, exage VERBOSE_PRINT(rank, verbose, ("Reading Et1\n")); data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ET1); parsec_matrix_block_cyclic_t *pEt1_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ET1).parsec_desc; - sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Et1.csv"); + sprintf(filename, "%s/%d%s", files_directory_path.c_str(), tile_size, "_Et1.csv"); ReadCSVComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pEt1_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); MB = 2*L-1; @@ -81,7 +82,7 @@ ParsecLoader::LoadData(configurations::Configurations &aConfigurations, exage VERBOSE_PRINT(rank, verbose, ("Reading Et2\n")); data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ET2); parsec_matrix_block_cyclic_t *pEt2_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ET2).parsec_desc; - sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Et2.csv"); + sprintf(filename, "%s/%d%s", files_directory_path.c_str(), tile_size, "_Et2.csv"); ReadCSVComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pEt2_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); MB = 2*L; @@ -89,7 +90,7 @@ ParsecLoader::LoadData(configurations::Configurations &aConfigurations, exage VERBOSE_PRINT(rank, verbose, ("Reading Ep\n")); data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_EP); parsec_matrix_block_cyclic_t *pEp_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_EP).parsec_desc; - sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Ep.csv"); + sprintf(filename, "%s/%d%s", files_directory_path.c_str(), tile_size, "_Ep.csv"); ReadCSVComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pEp_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); MB = (L*L+L)/2; @@ -97,7 +98,7 @@ ParsecLoader::LoadData(configurations::Configurations &aConfigurations, exage VERBOSE_PRINT(rank, verbose, ("Reading Slmn\n")); data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_SLMN); parsec_matrix_block_cyclic_t *pSlum_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_SLMN).parsec_desc; - sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Slmn.csv"); + sprintf(filename, "%s/%d%s", files_directory_path.c_str(), tile_size, "_Slmn.csv"); ReadCSVComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pSlum_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); MB = L; @@ -105,7 +106,7 @@ ParsecLoader::LoadData(configurations::Configurations &aConfigurations, exage VERBOSE_PRINT(rank, verbose, ("Reading Ie\n")); data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_IE); parsec_matrix_block_cyclic_t *pIe_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_IE).parsec_desc; - sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Ie.csv"); + sprintf(filename, "%s/%d%s", files_directory_path.c_str(), tile_size, "_Ie.csv"); ReadCSVToComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pIe_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); MB = L; @@ -113,7 +114,7 @@ ParsecLoader::LoadData(configurations::Configurations &aConfigurations, exage VERBOSE_PRINT(rank, verbose, ("Reading Io\n")); data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_IO); parsec_matrix_block_cyclic_t *pIo_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_IO).parsec_desc; - sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Io.csv"); + sprintf(filename, "%s/%d%s", files_directory_path.c_str(), tile_size, "_Io.csv"); ReadCSVToComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pIo_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); MB = L-1; @@ -121,7 +122,7 @@ ParsecLoader::LoadData(configurations::Configurations &aConfigurations, exage VERBOSE_PRINT(rank, verbose, ("Reading P\n")); data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_P); parsec_matrix_block_cyclic_t *pP_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_P).parsec_desc; - sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_P.csv"); + sprintf(filename, "%s/%d%s", files_directory_path.c_str(), tile_size, "_P.csv"); ReadCSVToComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pP_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); MB = 2*L-1; @@ -129,7 +130,7 @@ ParsecLoader::LoadData(configurations::Configurations &aConfigurations, exage VERBOSE_PRINT(rank, verbose, ("Reading D\n")); data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_D); parsec_matrix_block_cyclic_t *pD_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_D).parsec_desc; - sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_D.csv"); + sprintf(filename, "%s/%d%s", files_directory_path.c_str(), tile_size, "_D.csv"); ReadCSVToComplex((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pD_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); MB = L; @@ -142,7 +143,7 @@ ParsecLoader::LoadData(configurations::Configurations &aConfigurations, exage VERBOSE_PRINT(rank, verbose, ("Reading flmERA\n")); data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_FLMERA); parsec_matrix_block_cyclic_t *pFlmera_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_FLMERA).parsec_desc; - sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_flmERA.csv"); + sprintf(filename, "%s/%d%s", files_directory_path.c_str(), tile_size, "_flmERA.csv"); ReadCSVTimeSlot((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pFlmera_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); // Backward @@ -153,7 +154,7 @@ ParsecLoader::LoadData(configurations::Configurations &aConfigurations, exage VERBOSE_PRINT(rank, verbose, ("Reading Zlm\n")); data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ZLM); parsec_matrix_block_cyclic_t *PZlm_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_ZLM).parsec_desc; - sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_Zlm.csv"); + sprintf(filename, "%s/%d%s", files_directory_path.c_str(), tile_size, "_Zlm.csv"); ReadCSV((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), PZlm_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); MB = 2*L-1; @@ -161,7 +162,7 @@ ParsecLoader::LoadData(configurations::Configurations &aConfigurations, exage VERBOSE_PRINT(rank, verbose, ("Reading SC\n")); data->GetDescriptorData()->SetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_SC); parsec_matrix_block_cyclic_t *pSc_data_desc = data->GetDescriptorData()->GetDescriptor(PARSEC_DESCRIPTOR, DESCRIPTOR_SC).parsec_desc; - sprintf(filename, "%s/%s", files_directory_path.c_str(), "720_SC.csv"); + sprintf(filename, "%s/%d%s", files_directory_path.c_str(), tile_size, "_SC.csv"); ReadCSV((parsec_context_t *) ExaGeoStatHardware::GetParsecContext(), pSc_data_desc, MB, NB, nodes, t, filename, rank, verbose, gpus); MB = L+1; diff --git a/src/data-units/Locations.cpp b/src/data-units/Locations.cpp index abe0572c..701730e9 100644 --- a/src/data-units/Locations.cpp +++ b/src/data-units/Locations.cpp @@ -22,7 +22,7 @@ using namespace exageostat::common; template void Locations::SetLocationX(T &aLocationX, const int &aSize) { - if (aLocationX && aSize == this->mSize) { + if (&aLocationX != nullptr && aSize == this->mSize) { memcpy(this->mpLocationX, &aLocationX, this->mSize * sizeof(T)); } else { throw std::runtime_error("Invalid value for setting Locations X"); @@ -41,7 +41,7 @@ T *Locations::GetLocationX() { template void Locations::SetLocationY(T &aLocationY, const int &aSize) { - if (aLocationY && aSize == this->mSize) { + if (&aLocationY != nullptr && aSize == this->mSize) { memcpy(this->mpLocationY, &aLocationY, this->mSize * sizeof(T)); } else { throw std::runtime_error("Invalid value for setting Locations Y"); @@ -59,7 +59,7 @@ T *Locations::GetLocationY() { template void Locations::SetLocationZ(T &aLocationZ, const int &aSize) { - if (aLocationZ && aSize == this->mSize) { + if (&aLocationZ != nullptr && aSize == this->mSize) { memcpy(this->mpLocationZ, &aLocationZ, this->mSize * sizeof(T)); } else { throw std::runtime_error("Invalid value for setting Locations Z"); diff --git a/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp b/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp index f08c8c3b..4b822886 100644 --- a/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp +++ b/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp @@ -12,7 +12,9 @@ * @date 2023-03-20 **/ +#ifdef USE_MKL #include +#endif #include @@ -29,5 +31,7 @@ ChameleonDense::ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, vo throw std::runtime_error("CHAMELEON_dpotrf_Tile Failed, Matrix is not positive definite"); } // Due to a leak in dense mode in Chameleon, We had to free the buffer manually. +#ifdef USE_MKL mkl_free_buffers(); +#endif } \ No newline at end of file diff --git a/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp b/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp index c297bb01..da7e378e 100644 --- a/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp +++ b/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp @@ -232,6 +232,7 @@ T HicmaImplementation::ExaGeoStatMLETile(std::unique_ptr> & //Calculate Cholesky Factorization (C=LL-1) VERBOSE("LR: Cholesky factorization of Sigma...") START_TIMING(time_facto); + this->ExaGeoStatPotrfTile(EXAGEOSTAT_LOWER, HICMA_descCUV, 0, HICMA_descCD, HICMA_descCrk, max_rank, pow(10, -1.0 * acc)); diff --git a/src/prediction/Prediction.cpp b/src/prediction/Prediction.cpp index 943fc8b1..f0e6a7df 100644 --- a/src/prediction/Prediction.cpp +++ b/src/prediction/Prediction.cpp @@ -13,7 +13,10 @@ **/ #include + +#ifdef USE_MKL #include +#endif #include #include @@ -195,7 +198,9 @@ void Prediction::PredictMissingData(unique_ptr> &aData, Con // Due to a leak in Chameleon, exactly trsm We had to free the buffer manually. +#ifdef USE_MKL mkl_free_buffers(); +#endif delete[] z_obs; delete[] z_miss; diff --git a/src/results/Results.cpp b/src/results/Results.cpp index 3637fe66..82ccef22 100644 --- a/src/results/Results.cpp +++ b/src/results/Results.cpp @@ -21,6 +21,8 @@ using namespace exageostat::configurations; using namespace std; +Results *Results::mpInstance = nullptr; + Results *Results::GetInstance() { if (mpInstance == nullptr) { @@ -29,20 +31,28 @@ Results *Results::GetInstance() { return mpInstance; } -void Results::SetIsSynthetic(bool aIsSynthetic) { +void Results::UpdateDictionary(const string &key, const string &value) { + mSummaryDictionary[key] = value; +} + +void Results::SetIsSynthetic(bool aIsSynthetic, const std::string &aKey) { this->mIsSynthetic = aIsSynthetic; + UpdateDictionary(aKey.empty() ? "Data is Synthetic" : aKey, aIsSynthetic ? "Yes" : "No"); } -void Results::SetGeneratedLocationsNumber(int aNumLocations) { +void Results::SetGeneratedLocationsNumber(int aNumLocations, const std::string &aKey) { this->mGeneratedLocationsNumber = aNumLocations; + UpdateDictionary(aKey.empty() ? "Number of Locations" : aKey, to_string(aNumLocations)); } -void Results::SetIsLogger(bool aIsLogger) { +void Results::SetIsLogger(bool aIsLogger, const std::string &aKey) { this->mIsLogger = aIsLogger; + UpdateDictionary(aKey.empty() ? "Logger Enabled" : aKey, aIsLogger ? "Yes" : "No"); } -void Results::SetLoggerPath(const string &aLoggerPath) { +void Results::SetLoggerPath(const string &aLoggerPath, const std::string &aKey) { this->mLoggerPath = aLoggerPath; + UpdateDictionary(aKey.empty() ? "Logger Path" : aKey, aLoggerPath.empty() ? LOG_PATH : aLoggerPath); } void Results::PrintEndSummary() { @@ -50,112 +60,84 @@ void Results::PrintEndSummary() { Verbose temp = Configurations::GetVerbosity(); Configurations::SetVerbosity(STANDARD_MODE); LOGGER("********************SUMMARY**********************") - - auto locations_number = this->mGeneratedLocationsNumber; - if (locations_number > 0) { - LOGGER("#Number of Locations: " << locations_number) - if (this->mIsLogger && this->mIsSynthetic) { - LOGGER(" #Data is written to file (", true) - if (this->mLoggerPath.empty()) { - this->mLoggerPath = LOG_PATH; - } - LOGGER_PRECISION(this->mLoggerPath << ").") - LOGGER("") - } - VERBOSE("#Total Data Generation Execution Time: " << this->mExecutionTimeDataGeneration) - VERBOSE("#Total Data Generation Gflop/s: " << this->mFlopsDataGeneration) - } - if (this->mMLEIterations > 0) { - LOGGER("#Number of MLE Iterations: " << this->mMLEIterations) - LOGGER("#Found Maximum Theta at: ", true) - for (double i: this->mMaximumTheta) { - LOGGER_PRECISION(i << " ", 8) - } - LOGGER("") - LOGGER("#Final Log Likelihood value: " << this->mLogLikValue) - VERBOSE("#Average Time Modeling per Iteration: " << this->GetAverageModelingExecutionTime()) - VERBOSE("#Average Flops per Iteration: " << this->GetAverageModelingFlops()) - VERBOSE("#Total MLE Execution time: " << this->mTotalModelingExecutionTime) - VERBOSE("#Total MLE GFlop/s: " << this->mTotalModelingFlops) - } - - if (this->mZMiss > 0) { - LOGGER("#Number of Missing Observations: " << this->mZMiss) - if (this->mMSPEError > 0) { - VERBOSE("#MSPE Prediction Execution Time: " << this->mExecutionTimeMSPE) - VERBOSE("#MSPE Gflop/s: " << this->mFlopsMSPE) - LOGGER("#Mean Square Error MSPE: " << this->mMSPEError) - - } - if (!this->mIDWError.empty()) { - LOGGER("#IDW Error: ( ", true) - for (int i = 0; i < 3; i++) { - LOGGER_PRECISION(this->mIDWError[i] << " ", 8) - } - LOGGER_PRECISION(").") - LOGGER("") - } - if (this->mMLOE > 0 || this->mMMOM > 0) { - LOGGER("#MLOE: " << this->mMLOE << "\t\t#MMOM: " << this->mMMOM) - VERBOSE("#MLOE-MMOM Execution Time: " << this->mExecutionTimeMLOEMMOM) - VERBOSE("#MLOE-MMOM Matrix Generation Time: " << this->mGenerationTimeMLOEMMOM) - VERBOSE("#MLOE-MMOM Cholesky Factorization Time: " << this->mFactoTimeMLOEMMOM) - VERBOSE("#MLOE-MMOM Loop Time: " << this->mLoopTimeMLOEMMOM) - VERBOSE("#MLOE-MMOM Number of flops: " << this->mFlopsMLOEMMOM) - } - } - if (!this->mFisherMatrix.empty()) { - LOGGER("#Sd For Sigma2: " << this->mFisherMatrix[0]) - LOGGER("#Sd For Alpha: " << this->mFisherMatrix[1]) - LOGGER("#Sd For Nu: " << this->mFisherMatrix[2]) - VERBOSE("#Fisher Execution Time: " << this->mTotalFisherTime) + for (const auto &entry: mSummaryDictionary) { + LOGGER("#" << entry.first << ": " << entry.second) } LOGGER("*************************************************") Configurations::SetVerbosity(temp); } -void Results::SetMLEIterations(int aIterationsNumber) { +void Results::SetMLEIterations(int aIterationsNumber, const std::string& aKey) { this->mMLEIterations = aIterationsNumber; + UpdateDictionary(aKey.empty() ? "Number of MLE Iterations" : aKey, to_string(aIterationsNumber)); } -void Results::SetMaximumTheta(const vector &aMaximumTheta) { +void Results::SetMaximumTheta(const vector &aMaximumTheta, const std::string& aKey) { this->mMaximumTheta = aMaximumTheta; + + ostringstream oss; + oss << "[ "; + for (double val: aMaximumTheta) { + oss << fixed << setprecision(8) << val << " "; + } + oss << "]"; + UpdateDictionary(aKey.empty() ? "Found Maximum Theta at" : aKey, oss.str()); } -void Results::SetLogLikValue(double aLogLikValue) { +void Results::SetLogLikValue(double aLogLikValue, const std::string& aKey) { this->mLogLikValue = aLogLikValue; + UpdateDictionary(aKey.empty() ? "Final Log Likelihood Value" : aKey, to_string(aLogLikValue)); } -void Results::SetZMiss(int aZMiss) { +void Results::SetZMiss(int aZMiss, const std::string& aKey) { this->mZMiss = aZMiss; + UpdateDictionary(aKey.empty() ? "Number of Missing Observations" : aKey, to_string(aZMiss)); } -void Results::SetMSPEError(double aMSPEError) { +void Results::SetMSPEError(double aMSPEError, const std::string& aKey) { this->mMSPEError = aMSPEError; + UpdateDictionary(aKey.empty() ? "Mean Square Error MSPE" : aKey, to_string(aMSPEError)); } -void Results::SetIDWError(const vector &aIDWError) { +void Results::SetIDWError(const vector &aIDWError, const std::string& aKey) { this->mIDWError = aIDWError; + + ostringstream oss; + oss << "[ "; + for (double val: aIDWError) { + oss << fixed << setprecision(8) << val << " "; + } + oss << "]"; + UpdateDictionary(aKey.empty() ? "IDW Error" : aKey, oss.str()); } -void Results::SetMLOE(double aMLOE) { +void Results::SetMLOE(double aMLOE, const std::string& aKey) { this->mMLOE = aMLOE; + UpdateDictionary(aKey.empty() ? "MLOE" : aKey, to_string(aMLOE)); } -void Results::SetMMOM(double aMMOM) { +void Results::SetMMOM(double aMMOM, const std::string& aKey) { this->mMMOM = aMMOM; + UpdateDictionary(aKey.empty() ? "MMOM" : aKey, to_string(aMMOM)); } -void Results::SetMSPEExecutionTime(double aTime) { +void Results::SetMSPEExecutionTime(double aTime, const std::string& aKey) { this->mExecutionTimeMSPE = aTime; + UpdateDictionary(aKey.empty() ? "MSPE Prediction Execution Time" : aKey, to_string(aTime)); } -void Results::SetMSPEFlops(double aFlops) { +void Results::SetMSPEFlops(double aFlops, const std::string& aKey) { this->mFlopsMSPE = aFlops; + UpdateDictionary(aKey.empty() ? "MSPE Gflop/s" : aKey, to_string(aFlops)); } -void Results::SetTotalModelingExecutionTime(double aTime) { +void Results::SetTotalModelingExecutionTime(double aTime, const std::string& aKey) { this->mTotalModelingExecutionTime = aTime; + UpdateDictionary(aKey.empty() ? "Total Modeling Execution Time" : aKey, to_string(aTime)); + if (this->mMLEIterations) { + UpdateDictionary("Average Time Modeling per Iteration", to_string( + this->mTotalModelingExecutionTime / this->mMLEIterations)); + } } double Results::GetTotalModelingExecutionTime() const { @@ -176,54 +158,81 @@ double Results::GetAverageModelingFlops() const { throw runtime_error("Number of MLE Iterations is not set!"); } -void Results::SetTotalModelingFlops(double aTime) { +void Results::SetTotalModelingFlops(double aTime, const std::string& aKey) { this->mTotalModelingFlops = aTime; + UpdateDictionary(aKey.empty() ? "Total Modeling Flops" : aKey, to_string(aTime)); + if (this->mMLEIterations) { + UpdateDictionary("Average Flops per Iteration", to_string(this->mTotalModelingFlops / this->mMLEIterations)); + } } double Results::GetTotalModelingFlops() const { return this->mTotalModelingFlops; } -Results *Results::mpInstance = nullptr; - -void Results::SetExecutionTimeMLOEMMOM(double aTime) { +void Results::SetExecutionTimeMLOEMMOM(double aTime, const std::string& aKey) { this->mExecutionTimeMLOEMMOM = aTime; + UpdateDictionary(aKey.empty() ? "MLOE-MMOM Execution Time" : aKey, to_string(aTime)); } -void Results::SetMatrixGenerationTimeMLOEMMOM(double aTime) { +void Results::SetMatrixGenerationTimeMLOEMMOM(double aTime, const std::string& aKey) { this->mGenerationTimeMLOEMMOM = aTime; + UpdateDictionary(aKey.empty() ? "MLOE-MMOM Matrix Generation Time" : aKey, to_string(aTime)); + } -void Results::SetFactoTimeMLOEMMOM(double aTime) { +void Results::SetFactoTimeMLOEMMOM(double aTime, const std::string& aKey) { this->mFactoTimeMLOEMMOM = aTime; + UpdateDictionary(aKey.empty() ? "MLOE-MMOM Cholesky Factorization Time" : aKey, to_string(aTime)); } -void Results::SetLoopTimeMLOEMMOM(double aTime) { +void Results::SetLoopTimeMLOEMMOM(double aTime, const std::string& aKey) { this->mLoopTimeMLOEMMOM = aTime; + UpdateDictionary(aKey.empty() ? "MLOE-MMOM Loop Time" : aKey, to_string(aTime)); } -void Results::SetFlopsMLOEMMOM(double aFlops) { +void Results::SetFlopsMLOEMMOM(double aFlops, const std::string& aKey) { this->mFlopsMLOEMMOM = aFlops; + UpdateDictionary(aKey.empty() ? "MLOE-MMOM Number of flops" : aKey, to_string(aFlops)); } -void Results::SetTotalDataGenerationExecutionTime(double aTime) { +void Results::SetTotalDataGenerationExecutionTime(double aTime, const std::string& aKey) { this->mExecutionTimeDataGeneration = aTime; + UpdateDictionary(aKey.empty() ? "Total Data Generation Execution Time" : aKey, to_string(aTime)); } -void Results::SetTotalDataGenerationFlops(double aFlops) { +void Results::SetTotalDataGenerationFlops(double aFlops, const std::string& aKey) { this->mFlopsDataGeneration = aFlops; + UpdateDictionary(aKey.empty() ? "Total Data Generation Gflop/s" : aKey, to_string(aFlops)); } -void Results::SetTotalFisherTime(double aTime) { +void Results::SetTotalFisherTime(double aTime, const std::string& aKey) { this->mTotalFisherTime = aTime; + UpdateDictionary(aKey.empty() ? "Fisher Execution Time" : aKey, to_string(aTime)); } -void Results::SetFisherMatrix(vector aFisherMatrix) { +void Results::SetFisherMatrix(vector aFisherMatrix, const std::string& aKey) { this->mFisherMatrix = std::move(aFisherMatrix); + + ostringstream oss; + if (this->mFisherMatrix.size() >= 3) { + oss << "Sd For Sigma2: " << this->mFisherMatrix[0] << ", " + << "Sd For Alpha: " << this->mFisherMatrix[1] << ", " + << "Sd For Nu: " << this->mFisherMatrix[2]; + } + UpdateDictionary(aKey.empty() ? "Fisher Matrix" : aKey, oss.str()); } -void Results::SetPredictedMissedValues(vector aPredictedValues) { +void Results::SetPredictedMissedValues(vector aPredictedValues, const std::string& aKey) { this->mPredictedMissedValues = std::move(aPredictedValues); + + ostringstream oss; + if (this->mPredictedMissedValues.size() >= 3) { + oss << this->mPredictedMissedValues[0] << ", " + << this->mPredictedMissedValues[1] << ", " + << this->mPredictedMissedValues[2]; + } + UpdateDictionary(aKey.empty() ? "Predicted Values" : aKey, oss.str()); } double Results::GetMLOE() const { diff --git a/src/runtime/parsec/jdf/ForwardSHT.jdf b/src/runtime/parsec/jdf/ForwardSHT.jdf index af674f1b..26c30687 100644 --- a/src/runtime/parsec/jdf/ForwardSHT.jdf +++ b/src/runtime/parsec/jdf/ForwardSHT.jdf @@ -63,7 +63,7 @@ READ apF_data <- apFDataDesc(0, n) BODY { -#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) || defined(PARSEC_HAVE_DEV_HIP_SUPPORT) +#if defined(USE_CUDA) if( nb_cuda_devices > 0 ) { int g = climate_emualtor_gpu_load_balance( n, gb->nodes, nb_cuda_devices ); parsec_advise_data_on_device( _f_apFlm->original, @@ -105,7 +105,7 @@ READ apD <- apDDesc(0, my_rank) BODY[type=CUDA] { -#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) +#if defined(USE_CUDA) ForwardSHT_gpu_core(apFlm, apF_data, apEt1, apEt2, apEp, apSlmn, apIe, apIo, apP, apD, cuda_device, gpu_task, cuda_stream, gb); #endif } @@ -113,7 +113,7 @@ END BODY[type=HIP] { -#if defined(PARSEC_HAVE_DEV_HIP_SUPPORT) +#if defined(USE_CUDA) ForwardSHT_gpu_core(apFlm, apF_data, apEt1, apEt2, apEp, apSlmn, apIe, apIo, apP, apD, cuda_device, gpu_task, cuda_stream, gb); #endif } @@ -226,7 +226,7 @@ ForwardSHTConstructor(parsec_tiled_matrix_t *apFDataDesc, parsec_tiled_matrix_t pTaskpool->_g_apWork2 = (parsec_memory_pool_t*)malloc(sizeof(parsec_memory_pool_t)); parsec_private_memory_init( pTaskpool->_g_apWork2, aET2M * aEPN * sizeof(complex double)); -#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) || defined(PARSEC_HAVE_DEV_HIP_SUPPORT) +#if defined(USE_CUDA) int nb = 0, *dev_index; /** Find all CUDA devices */ diff --git a/src/runtime/parsec/jdf/ForwardSHTReshape.jdf b/src/runtime/parsec/jdf/ForwardSHTReshape.jdf index 7874ba14..35cef935 100644 --- a/src/runtime/parsec/jdf/ForwardSHTReshape.jdf +++ b/src/runtime/parsec/jdf/ForwardSHTReshape.jdf @@ -159,7 +159,7 @@ ForwardSHTReshape_constructor(parsec_tiled_matrix_t *apFDataDesc, parsec_tiled_m pTaskpool->_g_apWork2 = (parsec_memory_pool_t*)malloc(sizeof(parsec_memory_pool_t)); parsec_private_memory_init(pTaskpool->_g_apWork2, aET2M * aEPN * sizeof(complex double) ); -#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) || defined(PARSEC_HAVE_DEV_HIP_SUPPORT) +#if defined(USE_CUDA) int nb = 0, *dev_index; /** Find all CUDA devices */ diff --git a/src/runtime/parsec/jdf/InverseSHT.jdf b/src/runtime/parsec/jdf/InverseSHT.jdf index 5fc52e17..86eb11c7 100644 --- a/src/runtime/parsec/jdf/InverseSHT.jdf +++ b/src/runtime/parsec/jdf/InverseSHT.jdf @@ -51,7 +51,7 @@ READ f_spatial <- apFSpatialDesc(0, n) BODY { -#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) || defined(PARSEC_HAVE_DEV_HIP_SUPPORT) +#if defined(USE_CUDA) if( nb_cuda_devices > 0 ) { int g = climate_emulator_gpu_load_balance( n, gb->nodes, nb_cuda_devices ); parsec_advise_data_on_device( _f_flm->original, @@ -106,7 +106,7 @@ InverseSHTConstructor(parsec_tiled_matrix_t *apFSpatialDesc, parsec_tiled_matrix pTaskpool->_g_apWork = (parsec_memory_pool_t*) malloc(sizeof(parsec_memory_pool_t)); parsec_private_memory_init(pTaskpool->_g_apWork, (aLSize + 1) * (2 * aLSize - 1) * sizeof(double) ); -#if defined(PARSEC_HAVE_DEV_CUDA_SUPPORT) || defined(PARSEC_HAVE_DEV_HIP_SUPPORT) +#if defined(USE_CUDA) int nb = 0, *dev_index; /** Find all CUDA devices */ diff --git a/tests/R-tests/TestExaGeoStatAPI.R b/tests/R-tests/TestExaGeoStatAPI.R index 9d1328fe..fdb5c7be 100644 --- a/tests/R-tests/TestExaGeoStatAPI.R +++ b/tests/R-tests/TestExaGeoStatAPI.R @@ -18,7 +18,6 @@ ncores <- 1 ngpus <- 0 problem_size <- 16 dts <- 8 -lts <- 0 computation <- "exact" dimension = "2D" kernel <- "univariate_matern_stationary" @@ -75,3 +74,19 @@ test_x <- c(0.2, 0.330) test_y <- c(0.104, 0.14) predict_data(train_data=list(locations_x, locations_y, z_value), test_data=list(test_x, test_y), kernel=kernel, dts=dts, estimated_theta=estimated_theta) + +paste("---------------------------------------------------------------") +paste("ExaGeoStat with all Modules - tile low rank") + +problem_size <- 1600 +computation <- "tlr" +lts <- 400 +dts <- 400 +max_rank <- 200 +# The final value is computed as 10^(-1.0 * aAccuracy) +acc <- 5 + +hardware <- new(Hardware, computation, ncores, ngpus, p, q) +exageostat_data <- simulate_data(kernel=kernel, initial_theta=initial_theta, problem_size=problem_size, dts=dts, dimension=dimension) +estimated_theta <- model_data(matrix=exageostat_data$m, x=exageostat_data$x, y=exageostat_data$y, kernel=kernel, dts=dts, lts = lts, dimension=dimension,lb=lower_bound, ub=upper_bound, mle_itr=10, computation=computation, max_rank=max_rank, acc=acc) + diff --git a/tests/cpp-tests/configurations/TestConfigurations.cpp b/tests/cpp-tests/configurations/TestConfigurations.cpp index 2ce15865..5c34397d 100644 --- a/tests/cpp-tests/configurations/TestConfigurations.cpp +++ b/tests/cpp-tests/configurations/TestConfigurations.cpp @@ -15,15 +15,15 @@ * @date 2023-01-31 **/ -#include - #include #include +#include using namespace std; using namespace exageostat::common; using namespace exageostat::configurations; +using namespace exageostat::configurations::validator; void TEST_ARGUMENT_INITIALIZATION() { @@ -39,7 +39,7 @@ void TEST_ARGUMENT_INITIALIZATION() { const_cast("--ub=5:5:5"), const_cast("--lb=0.1:0.1:0.1"), const_cast("--max_mle_iterations=5"), - const_cast("--tolerance=4"), + const_cast("--tolerance=8"), const_cast("--ZMiss=6"), const_cast("--mspe"), const_cast("--idw"), @@ -49,8 +49,6 @@ void TEST_ARGUMENT_INITIALIZATION() { }; Configurations configurations; - - // Initialize configuration dictionary with only common arguments configurations.InitializeArguments(argc, argv); REQUIRE(configurations.GetProblemSize() == 16); @@ -58,32 +56,10 @@ void TEST_ARGUMENT_INITIALIZATION() { REQUIRE(configurations.GetDenseTileSize() == 8); REQUIRE(configurations.GetPrecision() == DOUBLE); - // No data generation arguments initialized - REQUIRE(configurations.GetDataPath() == string("")); - - // No data modeling arguments initialized - REQUIRE_THROWS(configurations.GetMaxMleIterations()); - - // No data prediction arguments initialized - REQUIRE(configurations.GetIsMSPE() == false); - REQUIRE(configurations.GetIsIDW() == false); - REQUIRE(configurations.GetIsFisher() == false); - REQUIRE(configurations.GetIsMLOEMMOM() == false); - REQUIRE(configurations.GetUnknownObservationsNb() == 0); - - // Data generation arguments initialized - configurations.InitializeDataGenerationArguments(); - REQUIRE(configurations.GetDataPath() == string("./dummy-path")); - // Data modelling arguments initialized - configurations.InitializeDataModelingArguments(); - REQUIRE(configurations.GetMaxMleIterations() == 5); - REQUIRE(configurations.GetTolerance() == pow(10, -4)); - - // Data prediction arguments initialized - configurations.InitializeDataPredictionArguments(); + REQUIRE(configurations.GetTolerance() == pow(10, -8)); REQUIRE(configurations.GetIsMSPE() == true); REQUIRE(configurations.GetIsIDW() == true); @@ -96,20 +72,21 @@ void TEST_ARGUMENT_INITIALIZATION() { void TEST_ARGUMENT_INITIALIZATION_PARSEC() { - const int argc = 12; + const int argc = 13; char *argv[] = { const_cast("program_name"), const_cast("--N=16"), const_cast("--dts=8"), const_cast("--precision=double"), const_cast("--band_dense=100"), - const_cast("--numobj=72"), + const_cast("--objects-number=72"), const_cast("--adaptive_decision=1"), - const_cast("--add_diag=10"), + const_cast("--add_diagonal=10"), const_cast("--file_time_slot=1"), - const_cast("--file-num=1"), + const_cast("--file-number=1"), const_cast("--enable-inverse"), - const_cast("--mpiio") + const_cast("--mpiio"), + const_cast("--data_path=./dummy-path"), }; Configurations configurations; @@ -130,12 +107,7 @@ void TEST_ARGUMENT_INITIALIZATION_PARSEC() { REQUIRE(configurations.GetEnableInverse() == true); REQUIRE(configurations.GetMPIIO() == true); - // No data generation arguments initialized - REQUIRE(configurations.GetDataPath() == string("")); - - // Passing an empty data path throws an exception - REQUIRE_THROWS(configurations.InitializeDataGenerationArguments()); - + REQUIRE(configurations.GetDataPath() == string("./dummy-path")); } @@ -151,9 +123,9 @@ void TEST_SYNTHETIC_CONFIGURATIONS() { }SECTION("Dimensions value checker test") { REQUIRE_THROWS_WITH( - synthetic_data_configurations.CheckDimensionValue("4D"), + Validator::CheckDimensionValue("4D"), "Invalid value for Dimension. Please use 2D, 3D or ST."); - Configurations::CheckDimensionValue("2D"); + Validator::CheckDimensionValue("2D"); } SECTION("P-GRID setter/getter test") @@ -164,42 +136,40 @@ void TEST_SYNTHETIC_CONFIGURATIONS() { }SECTION("P-GRID value checker test") { REQUIRE_THROWS_WITH( - synthetic_data_configurations.CheckNumericalValue("K"), + Validator::CheckNumericalValue("K"), "Invalid value. Please use Numerical values only."); REQUIRE_THROWS_WITH( - synthetic_data_configurations.CheckNumericalValue("-100"), + Validator::CheckNumericalValue("-100"), "Invalid value. Please use positive values"); - int test_nb = Configurations::CheckNumericalValue("512"); + int test_nb = Validator::CheckNumericalValue("512"); synthetic_data_configurations.SetPGrid(test_nb); REQUIRE(synthetic_data_configurations.GetPGrid() == 512); }SECTION("Kernel setter/getter test") { - REQUIRE(synthetic_data_configurations.GetKernelName().empty()); synthetic_data_configurations.SetKernelName("univariate_matern_stationary"); REQUIRE(synthetic_data_configurations.GetKernelName() == "univariate_matern_stationary"); }SECTION("Kernel checker value test") { REQUIRE_THROWS_WITH( - synthetic_data_configurations.CheckKernelValue("100"), + Validator::CheckKernelValue("100"), "Invalid value for Kernel. Please check manual."); REQUIRE_THROWS_WITH( - synthetic_data_configurations.CheckKernelValue("univariate_matern_dnu%"), + Validator::CheckKernelValue("univariate_matern_dnu%"), "Invalid value for Kernel. Please check manual."); - synthetic_data_configurations.CheckKernelValue("univariate_matern_dnu"); + Validator::CheckKernelValue("univariate_matern_dnu"); }SECTION("Problem size setter/getter test") { - REQUIRE(synthetic_data_configurations.GetProblemSize() == 0); synthetic_data_configurations.SetProblemSize(random_number); REQUIRE(synthetic_data_configurations.GetProblemSize() == random_number); }SECTION("Problem size checker value test") { REQUIRE_THROWS_WITH( - synthetic_data_configurations.CheckNumericalValue("K"), + Validator::CheckNumericalValue("K"), "Invalid value. Please use Numerical values only."); REQUIRE_THROWS_WITH( - synthetic_data_configurations.CheckNumericalValue("-100"), + Validator::CheckNumericalValue("-100"), "Invalid value. Please use positive values"); - int test_nb = Configurations::CheckNumericalValue("512"); + int test_nb = Validator::CheckNumericalValue("512"); synthetic_data_configurations.SetProblemSize(test_nb); REQUIRE(synthetic_data_configurations.GetProblemSize() == 512); } diff --git a/tests/cpp-tests/prediction/TestPrediction.cpp b/tests/cpp-tests/prediction/TestPrediction.cpp index 49605ed7..f108887e 100644 --- a/tests/cpp-tests/prediction/TestPrediction.cpp +++ b/tests/cpp-tests/prediction/TestPrediction.cpp @@ -89,8 +89,6 @@ void TEST_PREDICTION_MISSING_DATA() { configurations.GetKernelName(), configurations.GetTimeSlot()); - // Add the data prediction arguments. - configurations.InitializeDataPredictionArguments(); Prediction::PredictMissingData(data, configurations, z_matrix, *pKernel); REQUIRE(Results::GetInstance()->GetMSPEError() == Catch::Approx(0.552448)); @@ -109,8 +107,6 @@ void TEST_PREDICTION_MISSING_DATA() { exageostat::kernels::Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create( configurations.GetKernelName(), configurations.GetTimeSlot()); - // Add the data prediction arguments. - configurations.InitializeDataPredictionArguments(); Prediction::PredictMissingData(data, configurations, z_matrix, *pKernel); for (int i = 0; i < 3; i++) { REQUIRE(Results::GetInstance()->GetIDWError()[i] == Catch::Approx(idw_error[i])); @@ -129,8 +125,6 @@ void TEST_PREDICTION_MISSING_DATA() { exageostat::kernels::Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create( configurations.GetKernelName(), configurations.GetTimeSlot()); - // Add the data prediction arguments. - configurations.InitializeDataPredictionArguments(); Prediction::PredictMissingData(data, configurations, z_matrix, *pKernel); REQUIRE(Results::GetInstance()->GetMLOE() == Catch::Approx(0.004467).margin(0.001)); REQUIRE(Results::GetInstance()->GetMMOM() == Catch::Approx(-0.0812376).margin(0.001)); @@ -149,8 +143,6 @@ void TEST_PREDICTION_MISSING_DATA() { configurations.GetKernelName(), configurations.GetTimeSlot()); - // Add the data prediction arguments. - configurations.InitializeDataPredictionArguments(); Prediction::PredictMissingData(data, configurations, z_matrix, *pKernel); REQUIRE(Results::GetInstance()->GetMLOE() == Catch::Approx(0).margin(0.001)); REQUIRE(Results::GetInstance()->GetMMOM() == Catch::Approx(0).margin(0.001)); @@ -169,8 +161,7 @@ void TEST_PREDICTION_MISSING_DATA() { exageostat::kernels::Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create( configurations.GetKernelName(), configurations.GetTimeSlot()); - // Add the data prediction arguments. - configurations.InitializeDataPredictionArguments(); + Prediction::PredictMissingData(data, configurations, z_matrix, *pKernel); vector required_fisher = {0.1045891821, 0.0005116817, 0.0409307011, 0.0005116817, 0.1873553354, From 06fe4f4001b5b81465d6e7d0c8b4093d26d5e277 Mon Sep 17 00:00:00 2001 From: Mahmoud ElKarargy Date: Tue, 18 Mar 2025 16:50:28 +0200 Subject: [PATCH 5/5] resolve conflicts --- src/api/ExaGeoStat.cpp | 2 -- src/results/Results.cpp | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/api/ExaGeoStat.cpp b/src/api/ExaGeoStat.cpp index ca81ec6b..8d666114 100644 --- a/src/api/ExaGeoStat.cpp +++ b/src/api/ExaGeoStat.cpp @@ -26,8 +26,6 @@ using namespace exageostat::configurations; template void ExaGeoStat::ExaGeoStatLoadData(Configurations &aConfigurations, std::unique_ptr> &aData) { - int seed = 0; - std::srand(seed); int seed = 0; std::srand(seed); aConfigurations.PrintSummary(); diff --git a/src/results/Results.cpp b/src/results/Results.cpp index 48b88ee4..82ccef22 100644 --- a/src/results/Results.cpp +++ b/src/results/Results.cpp @@ -257,6 +257,4 @@ std::vector Results::GetFisherMatrix() const { std::vector Results::GetPredictedMissedValues() const { return this->mPredictedMissedValues; -} - -Results *Results::mpInstance = nullptr; +} \ No newline at end of file