diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..d23b41d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,686 @@ +# Created by https://www.toptal.com/developers/gitignore/api/clion,intellij,eclipse,sublimetext,cmake,c++,c,cuda,codeblocks,opencv,jetbrains,python,pycharm +# Edit at https://www.toptal.com/developers/gitignore?templates=clion,intellij,eclipse,sublimetext,cmake,c++,c,cuda,codeblocks,opencv,jetbrains,python,pycharm + +# synthetic data for testing +tests/cpp-tests/data-generators/concrete/synthetic_ds +synthetic_ds/ + +# intallation directory +installdir/ + +# R files +.Rhistory +.RData +.RDataTmp + +# tar.gz files +*.tar.gz + +### C ### +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +### C++ ### +# Prerequisites + +# Compiled Object files +*.slo + +# Precompiled Headers + +# Compiled Dynamic libraries + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai + +# Executables + +### CLion ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### CLion Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +# https://plugins.jetbrains.com/plugin/7973-sonarlint +.idea/**/sonarlint/ + +# SonarQube Plugin +# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator-enh.xml +.idea/**/markdown-navigator/ + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 +.idea/$CACHE_FILE$ + +# CodeStream plugin +# https://plugins.jetbrains.com/plugin/12206-codestream +.idea/codestream.xml + +### CMake ### +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps + +### CMake Patch ### +# External projects +*-prefix/ + +### CodeBlocks ### +# specific to CodeBlocks IDE +*.layout +*.depend +# generated directories +bin/ +obj/ + +### CUDA ### +*.i +*.ii +*.gpu +*.ptx +*.cubin +*.fatbin + +### Eclipse ### +.metadata +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ +.apt_generated_test/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +# Uncomment this line if you wish to ignore the project description file. +# Typically, this file would be tracked if it contains build/dependency configurations: +#.project + +### Eclipse Patch ### +# Spring Boot Tooling +.sts4-cache/ + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff + +# Generated files + +# Sensitive or high-churn files + +# Gradle + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake + +# Mongo Explorer plugin + +# File-based project format + +# IntelliJ + +# mpeltonen/sbt-idea plugin + +# JIRA plugin + +# Cursive Clojure plugin + +# Crashlytics plugin (for Android Studio and IntelliJ) + +# Editor-based Rest Client + +# Android studio 3.1+ serialized cache file + +### Intellij Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +# https://plugins.jetbrains.com/plugin/7973-sonarlint + +# SonarQube Plugin +# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin + +# Markdown Navigator plugin +# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 + +# CodeStream plugin +# https://plugins.jetbrains.com/plugin/12206-codestream + +### JetBrains ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff + +# Generated files + +# Sensitive or high-churn files + +# Gradle + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake + +# Mongo Explorer plugin + +# File-based project format + +# IntelliJ + +# mpeltonen/sbt-idea plugin + +# JIRA plugin + +# Cursive Clojure plugin + +# Crashlytics plugin (for Android Studio and IntelliJ) + +# Editor-based Rest Client + +# Android studio 3.1+ serialized cache file + +### JetBrains Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +# https://plugins.jetbrains.com/plugin/7973-sonarlint + +# SonarQube Plugin +# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin + +# Markdown Navigator plugin +# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 + +# CodeStream plugin +# https://plugins.jetbrains.com/plugin/12206-codestream + +### OpenCV ### +#OpenCV for Mac and Linux +#build and release folders +*/CMakeFiles +*/CMakeCache.txt +*/Makefile +*/cmake_install.cmake +.DS_Store + +### PyCharm ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff + +# Generated files + +# Sensitive or high-churn files + +# Gradle + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake + +# Mongo Explorer plugin + +# File-based project format + +# IntelliJ + +# mpeltonen/sbt-idea plugin + +# JIRA plugin + +# Cursive Clojure plugin + +# Crashlytics plugin (for Android Studio and IntelliJ) + +# Editor-based Rest Client + +# Android studio 3.1+ serialized cache file + +### PyCharm Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +# https://plugins.jetbrains.com/plugin/7973-sonarlint + +# SonarQube Plugin +# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin + +# Markdown Navigator plugin +# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 + +# CodeStream plugin +# https://plugins.jetbrains.com/plugin/12206-codestream + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +pytestdebug.log + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ +doc/_build/ +docs/html/ +docs/latex/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +### SublimeText ### +# Cache files for Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# Workspace files are user-specific +*.sublime-workspace + +# Project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using Sublime Text +# *.sublime-project + +# SFTP configuration file +sftp-config.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +Package Control.merged-ca-bundle +Package Control.user-ca-bundle +oscrypto-ca-bundle.crt +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings + +# Sesimic Toolbox Results Specifics +*.trace +*.segy +*.sgy +*.png +*.bin +data/*.segy +data/*.sgy +data/ +.idea/ +*.tar.bz2 +boost**/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..41fc89f0 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,39 @@ +# Changelog + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] - Version 1.0.1 (YYYY-MM-DD) +### Added +- Implemented a new changelog. +- Introduced a benchmarking script. +- .gitignore file. +- More examples. +- Add tests for all src files. + +### Fixed +- Resolved issues with MPI installation. +- Fixed the printing of configuration summaries with MPI. +- Automated the process of adding a new kernel. +- Improved packaging of software with CPack. +- Addressed installation issues. +- Fixed bivariate and trivariate kernels functionality. +- Corrected time-space kernel issues. + +### Changed +- Updated the installation process for dependencies. +- Modified the calculation of P for all kernels. +- Adjusted CMake variables. +- Revised the process of finding BLASPP and Catch2 libraries. +- Updated doxygen documentation. +- Split the synthetic generator functions into BitHelper class and Locations generator class. +- Created a Bassel Function helper for kernels. +- Cleaned the code base for better readability. + +### Removed +- Eliminated non-stationary kernel support. +- Removed Find OpenMP, LAPACKPP, and CuSOLVER. + +## [1.0.0] - 2023-11-12 +### Added +- Integrated all features present in [ExaGeoStat C version](https://github.com/ecrc/exageostat). diff --git a/CMakeLists.txt b/CMakeLists.txt index 6740d8a5..b34b08c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ # The project is a parallel high performance unified framework for geographical statistics on manycore systems. # The file sets up variables and finds dependencies required for the project. # It also provides options to enable building tests, building examples, building documentation, and enabling a packaging system for distribution. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-01-30 @@ -20,16 +20,19 @@ 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(EXAGEOSTAT_BUILD_TESTS "Option to enable building tests" ON) -option(EXAGEOSTAT_BUILD_EXAMPLES "Option to enable building examples" ON) -option(EXAGEOSTAT_BUILD_DOCS "Build documentation in docs directory" ON) -option(EXAGEOSTAT_PACKAGE "Enable a packaging system for distribution" 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) +option(BUILD_DOCS "Build documentation in docs directory" ON) +option(CREATE_PACKAGE "Enable a packaging system for distribution" OFF) # Cmake Module Paths set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}") # Select toolchain based on whether CUDA is enabled or not if (USE_CUDA) + message("") + message("---------------------------------------- CUDA") # Enable CUDA and include CudaToolchain add_definitions(-DUSE_CUDA=TRUE) enable_language(CUDA) @@ -44,21 +47,24 @@ else () endif () # Project Name and Version -project(exageostatcpp VERSION 1.0.0 DESCRIPTION "ExaGeoStat is a parallel high performance unified framework for geostatistics on manycore systems.") +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 enable_language(CXX) - +# Get the current path of the project. add_compile_definitions(PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}/") - +# Add Paths definitions add_definitions( -DLOG_PATH="${PROJECT_SOURCE_DIR}/synthetic_ds/" -DKERNELS_PATH="${PROJECT_SOURCE_DIR}/inst/include/kernels/concrete/" ) -# Add all dependencies for ExaGeoStat PP + + +# ExaGeoStatCPP depends on a CUDA +# ------------------------------- if (USE_CUDA) message("-- Build CUDA Support") else () @@ -67,73 +73,74 @@ else () unset(BLA_VENDOR) endif () -# EXAGEOSTAT depends on a MPI +# ExaGeoStatCPP depends on a MPI # ------------------------------- if (USE_MPI) + message("") + message("---------------------------------------- MPI") # Enable MPI and include MPI add_definitions(-DUSE_MPI=TRUE) message(STATUS "Trying to find MPI") find_package(MPI REQUIRED) + include_directories(${MPI_INCLUDE_PATH}) + list(APPEND LIBS ${MPI_LIBRARIES}) list(APPEND STARPU_COMPONENT_LIST "MPI") endif () -# EXAGEOSTAT depends on LAPACKE +# ExaGeoStatCPP depends on LAPACKE #----------------------------- +message("") +message("---------------------------------------- LAPACKE") find_package(LAPACKE) list(APPEND LIBS ${LAPACKE_LIBRARIES}) link_directories(${LAPACKE_LIBRARY_DIRS_DEP}) include_directories(${LAPACKE_INCLUDE_DIRS}) -# Check if no path is set for installation -if (NOT EXAGEOSTAT_INSTALL_PREFIX) - message(FATAL_ERROR "Installation path not set! Please use -DEXAGEOSTAT_INSTALL_PREFIX=path/to/install or use ./config.sh") -endif () -# Print installation path of Exageostat. -message(STATUS "Installation path : ${EXAGEOSTAT_INSTALL_PREFIX}") +# Add all dependencies for ExaGeoStatCPP +#----------------------------- + +# Print installation path of ExaGeoStatCPP. +message(STATUS "Installation path : ${CMAKE_INSTALL_PREFIX}") -# EXAGEOSTAT depends on a Hwloc +# ExaGeoStatCPP depends on a HWLoc # ------------------------------- include(ImportHwloc) list(APPEND STARPU_COMPONENT_LIST "HWLOC") - string(REPLACE ";" " " STARPU_COMPONENT_STRING "${STARPU_COMPONENT_LIST}") -# EXAGEOSTAT depends on a runtime +# ExaGeoStatCPP depends on a StarPu runtime # ------------------------------- include(ImportStarPu) -# EXAGEOSTAT depends on a GSL +# ExaGeoStatCPP depends on a GSL # ------------------------------- include(ImportGSL) -# EXAGEOSTAT depends on a NLOPT +# ExaGeoStatCPP depends on a NLOPT # ------------------------------- include(ImportNLOPT) -# EXAGEOSTAT depends on HiCMA +# ExaGeoStatCPP depends on HiCMA # ------------------------------- -if (EXAGEOSTAT_USE_HICMA) - add_definitions(-DEXAGEOSTAT_USE_HICMA=TRUE) - message(STATUS "Add Hcore, Dependency needed for HiCMA") - include(ImportHcore) - message(STATUS "Add StarsH, Dependency needed for HiCMA") +if (USE_HICMA) + add_definitions(-DUSE_HICMA=TRUE) + include(ImportHCore) include(ImportStarsH) include(ImportHiCMA) endif () -# EXAGEOSTAT depends on CHAMELEON +# ExaGeoStatCPP depends on Chameleon # ------------------------------- include(ImportChameleon) -# EXAGEOSTAT depends on a LAPACK/BLASPP +# ExaGeoStatCPP depends on a LAPACK/BLASPP # ------------------------------- -include(ImportBlasPP) +include(ImportBLASPP) include(ImportLapack) -# EXAGEOSTAT DOCUMENTATIONS -if (EXAGEOSTAT_BUILD_DOCS) +# ExaGeoStatCPP Documentation +if (BUILD_DOCS) find_package(Doxygen) - if (DOXYGEN_FOUND) add_subdirectory("docs") else () @@ -141,7 +148,7 @@ if (EXAGEOSTAT_BUILD_DOCS) endif () endif () -# Include directories for Exageostat-cpp +# Include directories for ExaGeoStatCPP include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inst/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/prerequisites) set(MY_LOGGER_PATH ${CMAKE_CURRENT_SOURCE_DIR}) @@ -158,14 +165,8 @@ target_link_libraries(${PROJECT_NAME}_INTERFACE INTERFACE ${PROJECT_NAME}) # Add linker options to the target target_link_options(${PROJECT_NAME}_INTERFACE INTERFACE "SHELL:-Wl,--whole-archive $ -Wl,--no-whole-archive") -# Install headers -install(TARGETS exageostatcpp - DESTINATION lib/ - PUBLIC_HEADER DESTINATION include/ - ) - # Add tests if enabled -if (${EXAGEOSTAT_BUILD_TESTS}) +if (${BUILD_TESTS}) message(STATUS "Building Tests") include(ImportCatch2) include(Catch) @@ -174,55 +175,85 @@ if (${EXAGEOSTAT_BUILD_TESTS}) enable_testing() endif () +# Add heavy tests if enabled +if (${BUILD_HEAVY_TESTS}) + message(STATUS "Building Heavy Tests") + include(ImportCatch2) + include(Catch) + include(CTest) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests/heavy-tests) + enable_testing() + message(STATUS "Building heavy tests will enable examples too") + set(BUILD_EXAMPLES ON) +endif () -if (EXAGEOSTAT_BUILD_EXAMPLES) - message(STATUS "Building Examples is Enabled") +# Add examples if enabled +if (BUILD_EXAMPLES) + message(STATUS "Building Examples is Enabled") add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/examples) endif () -# Installation actions -install(DIRECTORY include/${PROJECT_NAME} DESTINATION include) +# ExaGeoStatCPP Dependence export messages for users +# ------------------------------- +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}/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() +message("\t ----------------------------------------------------------------------------------------------------------------------------------- \n") + +# Installation of ExaGeoStatCPP +install(DIRECTORY inst/include/ DESTINATION ${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/include) + ## Install cmake find package. include(CMakePackageConfigHelpers) -write_basic_package_version_file("${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" COMPATIBILITY ExactVersion) +write_basic_package_version_file("${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/${PROJECT_NAME}ConfigVersion.cmake" COMPATIBILITY ExactVersion) install( FILES - "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" - DESTINATION lib/cmake/${PROJECT_NAME} + "${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION ${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/lib/cmake/${PROJECT_NAME} ) configure_file(${PROJECT_NAME}Config.cmake.in - ${PROJECT_NAME}Config.cmake @ONLY) + ${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/${PROJECT_NAME}Config.cmake @ONLY) install( FILES - "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" - DESTINATION lib/cmake/${PROJECT_NAME} + "${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/${PROJECT_NAME}Config.cmake" + DESTINATION ${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/lib/cmake/${PROJECT_NAME} ) install( DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/cmake" - DESTINATION lib/cmake/${PROJECT_NAME}/Modules + DESTINATION ${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/Modules ) ## Generate pkg-config file configure_file(package.pc.in - lib/pkgconfig/${PROJECT_NAME}.pc @ONLY) + ${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/lib/pkgconfig/${PROJECT_NAME}.pc @ONLY) install( FILES - "${PROJECT_BINARY_DIR}/lib/pkgconfig/${PROJECT_NAME}.pc" - DESTINATION lib/pkgconfig/ + "${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/lib/pkgconfig/${PROJECT_NAME}.pc" + DESTINATION ${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/lib/pkgconfig/ ) -if (EXAGEOSTAT_PACKAGE) +if (CREATE_PACKAGE) ################## # Release source # ################## set(CPACK_SOURCE_GENERATOR "TGZ") set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/README.md) - set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "ExaGeoStat is a parallel high performance unified framework for geostatistics on manycore systems. Its abbreviation stands for 'Exascale Geostatistics'.") + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "ExaGeoStatCPP is a parallel high performance unified framework for geostatistics on manycore systems. Its abbreviation stands for 'Exascale Geostatistics'.") set(CPACK_PACKAGE_VERSION "${${PROJECT_NAME}_VERSION}") set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") @@ -230,16 +261,11 @@ if (EXAGEOSTAT_PACKAGE) set(CPACK_PACKAGE_CONTACT "sameh.abdulah@kaust.edu.sa") set(CPACK_RESOURCE_FILE_README ${CMAKE_CURRENT_SOURCE_DIR}/README.md) set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE) - set(CPACK_SOURCE_IGNORE_FILES "bin;.git;.gitmodules;Jenkinsfile") + set(CPACK_SOURCE_IGNORE_FILES "bin;.git;Jenkinsfile") include(CPack) -endif () -message(" \n \t ** Configurations of ExaGeoStat and installation of dependence is done successfully ** ") -message("\t Export the following line to avoid re-install dependencies each time, This line assume that you haven't changed the installation path. ") -message("\t If not, Please change the following paths with your installation path. \n") -message("\t ------------------------------------------------------------------------------------------------------------------------------- ") -message("\t export PKG_CONFIG_PATH=${EXAGEOSTAT_INSTALL_PREFIX}/CHAMELEON/lib/pkgconfig:${EXAGEOSTAT_INSTALL_PREFIX}/GSL/lib/pkgconfig:$PKG_CONFIG_PATH") -message("\t export PKG_CONFIG_PATH=${EXAGEOSTAT_INSTALL_PREFIX}/HCORE/lib/pkgconfig:${EXAGEOSTAT_INSTALL_PREFIX}/HICMA/lib/pkgconfig:$PKG_CONFIG_PATH") -message("\t export PKG_CONFIG_PATH=${EXAGEOSTAT_INSTALL_PREFIX}/HWLOC/lib/pkgconfig:${EXAGEOSTAT_INSTALL_PREFIX}/NLOPT/lib64/pkgconfig:$PKG_CONFIG_PATH") -message("\t export PKG_CONFIG_PATH=${EXAGEOSTAT_INSTALL_PREFIX}/STARPU/lib/pkgconfig:${EXAGEOSTAT_INSTALL_PREFIX}/STARSH/lib/pkgconfig:$PKG_CONFIG_PATH") -message("\t ------------------------------------------------------------------------------------------------------------------------------- \n") + message("\t - Export the following line if you want to use ExaGeoStatCPP in another software. -") + message("\t ----------------------------------------------------------------------------------------------------------------------------------------------------- ") + message("\t export PKG_CONFIG_PATH=${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/lib/pkgconfig:$PKG_CONFIG_PATH") + message("\t ----------------------------------------------------------------------------------------------------------------------------------------------------- ") +endif () \ No newline at end of file diff --git a/ExaGeoStatCPPConfig.cmake.in b/ExaGeoStatCPPConfig.cmake.in new file mode 100644 index 00000000..ef8a1c2c --- /dev/null +++ b/ExaGeoStatCPPConfig.cmake.in @@ -0,0 +1,142 @@ + +# Copyright (c) 2017-2023 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 ExaGeoStatCPPConfig.cmake.in +# @version 1.0.1 +# @author Mahmoud ElKarargy +# @date 2023-01-30 + + +# relocatable package +@PACKAGE_INIT@ + +# defined since 2.8.3 +if (CMAKE_VERSION VERSION_LESS 2.8.3) + get_filename_component(CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) +endif () + +include("${CMAKE_CURRENT_LIST_DIR}/lib/cmake/ExaGeoStatCPPCoreConfig.cmake") +# Compute the installation prefix relative to this file. +get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) +if (_IMPORT_PREFIX STREQUAL "/") + set(_IMPORT_PREFIX "") +endif () + + +# Cmake Module Paths +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH};${CMAKE_CURRENT_LIST_DIR}/Modules/cmake) + +set(ENV{PKG_CONFIG_PATH} "${_IMPORT_PREFIX}/lib/pkgconfig:$ENV{PKG_CONFIG_PATH}") +include_directories(${_IMPORT_PREFIX}/include) +link_directories(${_IMPORT_PREFIX}/lib) +set(BLA_PREFER_PKGCONFIG "ON") + +set(EXAGEOSTATCPP_LIBRARIES ExaGeoStatCPP) +set(EXAGEOSTATCPP_LIBRARY_DIRS "${_IMPORT_PREFIX}/lib") +set(EXAGEOSTATCPP_INCLUDE_DIRS "${_IMPORT_PREFIX}/include") + +set(USE_CUDA "@USE_CUDA@") + +# Select toolchain based on whether CUDA is enabled or not +if (USE_CUDA) + # Enable CUDA and include CudaToolchain + add_definitions(-DUSE_CUDA=TRUE) + enable_language(CUDA) + include(toolchains/CudaToolchain) + # Set BLA_VENDOR to NVHPC for CUDA-enabled builds + set(BLA_VENDOR NVHPC) + list(APPEND STARPU_COMPONENT_LIST "CUDA") +else () + message("-- Build x86 Support") + # Include GccToolchain for non-CUDA builds - Gcc + include(toolchains/GccToolchain) +endif () + +add_definitions( + -DLOG_PATH="${PROJECT_SOURCE_DIR}/synthetic_ds/" + -DKERNELS_PATH="${PROJECT_SOURCE_DIR}/inst/include/kernels/concrete/" +) + + +# EXAGEOSTAT depends on a MPI +# ------------------------------- +if (USE_MPI) + # Enable MPI and include MPI + add_definitions(-DUSE_MPI=TRUE) + message(STATUS "Trying to find MPI") + find_package(MPI REQUIRED) + include_directories(${MPI_INCLUDE_PATH}) + list(APPEND LIBS ${MPI_LIBRARIES}) + list(APPEND STARPU_COMPONENT_LIST "MPI") +endif () + +# EXAGEOSTAT depends on LAPACKE +#----------------------------- +find_package(LAPACKE) +list(APPEND LIBS ${LAPACKE_LIBRARIES}) +link_directories(${LAPACKE_LIBRARY_DIRS_DEP}) +include_directories(${LAPACKE_INCLUDE_DIRS}) + + +# EXAGEOSTAT depends on a Hwloc +# ------------------------------- +include(ImportHwloc) +list(APPEND STARPU_COMPONENT_LIST "HWLOC") + +string(REPLACE ";" " " STARPU_COMPONENT_STRING "${STARPU_COMPONENT_LIST}") + +# EXAGEOSTAT depends on a runtime +# ------------------------------- +include(ImportStarPu) + +# EXAGEOSTAT depends on a GSL +# ------------------------------- +include(ImportGSL) + +# EXAGEOSTAT depends on a NLOPT +# ------------------------------- +include(ImportNLOPT) + + +# EXAGEOSTAT depends on HiCMA +# ------------------------------- +if (USE_HICMA) + add_definitions(-DUSE_HICMA=TRUE) + message(STATUS "Add Hcore, Dependency needed for HiCMA") + include(ImportHCore) + message(STATUS "Add StarsH, Dependency needed for HiCMA") + include(ImportStarsH) + include(ImportHiCMA) +endif () + +# EXAGEOSTAT depends on CHAMELEON +# ------------------------------- +include(ImportChameleon) + +# EXAGEOSTAT depends on a LAPACK/BLASPP +# ------------------------------- +include(ImportBLASPP) +include(ImportLapack) + +# Add all dependencies for ExaGeoStatCPP +if (USE_CUDA) + message("-- Build CUDA Support") +else () + message("-- Build x86 Support") + set(gpu_backend CACHE STRING "none" FORCE) + unset(BLA_VENDOR) +endif () + +find_package_handle_standard_args(ExaGeoStatCPP + NAME_MISMATCHED + REQUIRED_VARS EXAGEOSTATCPP_INCLUDE_DIRS EXAGEOSTATCPP_LIBRARY_DIRS EXAGEOSTATCPP_LIBRARIES + VERSION_VAR EXAGEOSTATCPP_VERSION + ) + +# Cleanup temporary variables. +set(_IMPORT_PREFIX) +if (CMAKE_VERSION VERSION_LESS 2.8.3) + set(CMAKE_CURRENT_LIST_DIR) +endif () diff --git a/Jenkinsfile b/Jenkinsfile index 297d51c2..353913a8 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -20,12 +20,12 @@ pipeline { module purge module load gcc/10.2.0 module load cmake/3.21.2 + module load doxygen/1.8.20 #################################################### # BLAS/LAPACK #################################################### module load mkl/2020.0.166 #################################################### - set -x ./config.sh -t -e ./clean_build.sh @@ -43,6 +43,7 @@ pipeline { module purge module load gcc/10.2.0 module load cmake/3.21.2 + module load doxygen/1.8.20 #################################################### # BLAS/LAPACK #################################################### @@ -61,12 +62,12 @@ pipeline { module purge module load gcc/10.2.0 module load cmake/3.21.2 + module load doxygen/1.8.20 #################################################### # BLAS/LAPACK #################################################### module load mkl/2020.0.166 #################################################### - set -x ./config.sh -t -e -H ./clean_build.sh @@ -84,11 +85,11 @@ pipeline { module purge module load gcc/10.2.0 module load cmake/3.21.2 + module load doxygen/1.8.20 #################################################### # BLAS/LAPACK #################################################### module load mkl/2020.0.166 - module load gsl/2.6-gcc-10.2.0 cd bin/ ctest --no-compress-output --verbose ''' @@ -101,12 +102,12 @@ pipeline { module purge module load gcc/10.2.0 module load cmake/3.21.2 + module load doxygen/1.8.20 #################################################### # BLAS/LAPACK #################################################### module load mkl/2020.0.166 - module load gsl/2.6-gcc-10.2.0 - ./config.sh -t -e + ./config.sh -e ./clean_build.sh cd bin make docs diff --git a/USER_MANUAL.md b/USER_MANUAL.md index e8a35059..e9d1e456 100644 --- a/USER_MANUAL.md +++ b/USER_MANUAL.md @@ -3,47 +3,49 @@ ExaGeoStatCPP User Manual # Content -1. Configurations of the software. -2. Building ExaGeoStatCPP. -3. Supported Covariance kernels. -4. Arguments. -5. List of Descriptors. -6. Supported operations. -7. Contributing +1. [Configurations of the software](#configurations) +2. [Building ExaGeoStatCPP](#building) +3. [Supported Covariance kernels](#supported-covariance-functions-kernels-) +4. [Arguments](#arguments) +5. [List of Descriptors](#list-of-descriptors) +6. [Supported operations](#supported-operations) +7. [Contributing](#contributing) ## Configurations -* Run help of config.sh to know the needed arguments to run with your specific options. +* Run the help of `config.sh` to know the needed arguments for your specific options. + ```commandline ./config.sh -h ``` -* To Enable support of HiCMA add **```-H```** -* To enable examples add **```-e```** - -* To enable tests add **```-t```** - -* To enable CUDA add **```-c```** - -* To enable MPI add **```-m```** - -* To enable Verbose add **```-v```** - -* To enable debug mode add **```-d```** -* To change the installation path of the dependencies use **```-i ```** +* To Enable support of HiCMA, add `-H` disabled by default. +* To enable examples, add `-e` enabled by default. +* To enable tests, add `-t` disabled by default. +* To enable heavy tests, add `-T` disabled by default. +* To enable CUDA, add `-c` disabled by default. +* To enable MPI, add `-m` disabled by default. +* To enable verbose output, add `-v` disabled by default. +* To change the installation path of the dependencies, use `-i ` project_path/installdir/_deps/ by default on Unix systems. +* To enable manually passing mkl as BLA vendor, add `-s` MKL by default. +* To enable packaging system for distribution, add `-p` disabled by default. -Please be aware that we currently offer support for either HiCMA or Chameleon, or both. ## Building -* Run help of clean_build.sh to know the additional arguments options. +* Run the help of `clean_build.sh` to know additional argument options. + ```commandline ./clean_build.sh -h ``` -* Run clean_build.sh to clean, Build and Install the project. +* Run clean_build.sh to build the project. ```commandline ./clean_build.sh ``` -* To enable verbose printing, Run the following command. +* To build and install the project, Run the following command. +```commandline +./clean_build.sh -i +``` +* To build and enable verbose printing, Run the following command. ```commandline ./clean_build.sh -v ``` @@ -67,14 +69,12 @@ Supported Covariance Functions/ Kernels: 10. univariate_matern_dnu 11. univariate_matern_dsigma_square 12. univariate_matern_non_gaussian -13. univariate_matern_non_sta -14. univariate_matern_non_stationary -15. univariate_matern_nuggets_stationary -16. univariate_spacetime_matern_stationary -17. bivariate_matern_flexible -18. bivariate_matern_parsimonious -19. bivariate_spacetime_matern_stationary -20. trivariate_matern_parsimonious +13. univariate_matern_nuggets_stationary +14. univariate_spacetime_matern_stationary +15. bivariate_matern_flexible +16. bivariate_matern_parsimonious +17. bivariate_spacetime_matern_stationary +18. trivariate_matern_parsimonious ## Arguments @@ -87,18 +87,18 @@ Supported Covariance Functions/ Kernels: * {Mandatory} To set the dense tile size in the case of Chameleon --dts= -* {Mandatory} To set the low tile size in case of HiCMA +* {Mandatory} To set the low tile size in case of HiCMA --lts= * {Optional} To set the dimension, the default is 2D --dimension=<2D/3D/ST> -* {Optional} To set the p grid +* {Optional} To set the p grid, the default is 1 - --p_grid= -* {Optional} To set the q grid + --p= +* {Optional} To set the q grid, the default is 1 - --q_grid= + --q= * {Optional} To set the time slot, the default is 1 --time_slot= @@ -107,7 +107,7 @@ Supported Covariance Functions/ Kernels: --computation= * {Optional} To set the precision, the default is double - --precision= + --precision= * {Optional} To set the number of cores, the default is 1 --cores= @@ -135,12 +135,15 @@ Supported Covariance Functions/ Kernels: * {Optional} To set the target theta --ttheta= +* {Optional} To set the estimated theta + + --etheta= * {Optional} To set the seed value, the default is 0 --seed= -* {Optional} To set the run mode value, the default is standard +* {Optional} To set the verbose value, the default is standard - --run_mode= + --verbose= * {Optional} To set the path of log files to be written, the default is ./exageostat-cpp/synthetic_ds/ --log_path= @@ -239,7 +242,7 @@ can be used to train the software to predict the values of new data better. After you provide your arguments with the Configurations module, you must do the following two steps: ```c++ // Create a new ExaGeoStat data that holds the locations and descriptors data. -ExaGeoStatData data; +std::unique_ptr> data; // Generate data by passing your arguments through the configurations, hardware, and container of the data, which will be filled with the newly generated data. ExaGeoStat::ExaGeoStatLoadData(hardware, configurations, data); @@ -253,7 +256,7 @@ ExaGeoStat::ExaGeoStatLoadData(hardware, configurations, data); - Then do the following two steps. ```c++ // Create a new ExaGeoStat data that holds the locations data and descriptors data. -ExaGeoStatData data; +std::unique_ptr> data; // Generate data by passing your arguments through the configurations, your hardware and your container of the data which will be filled with the new generated data. ExaGeoStat::ExaGeoStatLoadData(hardware, configurations, data); ``` @@ -298,4 +301,7 @@ ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data, z_matri ```c++ // you have to pass your arguments through the configurations, your hardware and your data. ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data, z_matrix); -``` \ No newline at end of file +``` + +## Contributing +[Contribution Guidelines](CONTRIBUTING.md) diff --git a/clean_build.sh b/clean_build.sh index 8d56b8a9..d1f1a1d2 100755 --- a/clean_build.sh +++ b/clean_build.sh @@ -5,16 +5,17 @@ # @file clean_build.sh # @brief This script cleans and builds a software package called ExaGeoStat. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @date 2023-01-30 # Define variables. verbose="" num_proc="-j $(nproc)" # Use the number of available processors by default. +installation=0 # Parse command-line arguments. -while getopts "vj:h" opt; do +while getopts "vj:hi" opt; do case $opt in v) verbose="VERBOSE=1" @@ -24,6 +25,9 @@ while getopts "vj:h" opt; do num_proc="-j $OPTARG" echo "Using $OPTARG threads to build" ;; + i) + installation=1 + ;; h) # Print help information and exit. echo "Usage: $(basename "$0") [-v] [-j ] [-h]" @@ -31,8 +35,9 @@ while getopts "vj:h" opt; do echo "" echo "Options:" echo " -v Use verbose output." - echo " -j Build with a specific number of threads." + echo " -i To install the software" echo " -h Show this help message." + echo " -j Build with a specific number of threads." exit 0 ;; *) @@ -50,5 +55,15 @@ cd bin/ || { } # Clean the directory and build the code with the specified options. -make clean -make all $num_proc $verbose \ No newline at end of file +cmake --build . $num_proc $verbose + +# Install the software if the -i option is provided. +if [ "$installation" -eq 1 ]; then + cmake --install . +fi + +# Check the value of EXAGEOSTAT_PACKAGE variable in CMakeCache.txt +if grep -q "EXAGEOSTAT_PACKAGE:BOOL=ON" CMakeCache.txt; then + echo "CPack is enabled. Packaging the project." + cpack +fi \ No newline at end of file diff --git a/cmake/ImportBLAS.cmake b/cmake/ImportBLAS.cmake new file mode 100644 index 00000000..72e6d460 --- /dev/null +++ b/cmake/ImportBLAS.cmake @@ -0,0 +1,23 @@ +# Copyright (c) 2017-2023 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 ImportBLAS.cmake +# @brief This file searches for the BLAS library and includes it if not already included. +# @version 1.0.1 +# @author Mahmoud ElKarargy +# @date 2023-03-12 + +#Configurations +set(name "BLAS") +set(tag "v0.3.21") +set(version "0.3.21") +set(flag "") +set(is_cmake ON) +set(is_git ON) +set(auto_gen OFF) +set(url "https://github.com/xianyi/OpenBLAS") + +include(macros/ImportDependency) +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) +message(STATUS "${name} done") diff --git a/cmake/ImportBLASPP.cmake b/cmake/ImportBLASPP.cmake new file mode 100644 index 00000000..1b2f7e29 --- /dev/null +++ b/cmake/ImportBLASPP.cmake @@ -0,0 +1,24 @@ +# Copyright (c) 2017-2023 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 ImportBLASPP.cmake +# @brief This file searches for the BLAS++ library and includes it if not already included. +# @version 1.0.1 +# @author Mahmoud ElKarargy +# @date 2023-03-12 + +include(ImportBLAS) + +#Configurations +set(name blaspp) +set(tag "v2023.01.00") +set(url "https://github.com/icl-utk-edu/blaspp") +set(${name}_DIR "${CMAKE_INSTALL_PREFIX}/${capital_name}/lib/cmake/${name}") + +include(FetchContent) +FetchContent_Declare(${name} GIT_REPOSITORY "${url}" GIT_TAG "${tag}") +FetchContent_MakeAvailable(${name}) + +set(LIBS ${name} ${LIBS}) +message(STATUS "${name} done") \ No newline at end of file diff --git a/cmake/ImportBlas.cmake b/cmake/ImportBlas.cmake deleted file mode 100644 index 2df0a6c9..00000000 --- a/cmake/ImportBlas.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (c) 2017-2023 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 ImportBlas.cmake -# @brief This file searches for the BLAS library and includes it if not already included. -# @version 1.0.0 -# @author Mahmoud ElKarargy -# @author Sameh Abdulah -# @date 2023-03-12 - -# search for BLAS library, if not already included -message("") -message("---------------------------------------- BLAS") -message(STATUS "Checking for BLAS") -include(macros/BuildDependency) - -if (NOT TARGET BLAS) - include(FindPkgConfig) - find_package(PkgConfig QUIET) - find_package(BLAS QUIET) - - if (BLAS_FOUND) - message(" Found BLAS: ${BLAS_LIBRARIES}") - else () - message(" Can't find Blas, Installing it instead ..") - # Set installation flags - set(FLAGS "") - set(ISCMAKE ON) - set(ISGIT ON) - set(AUTO_GEN OFF) - set(build_tests "false") - BuildDependency(BLAS "https://github.com/xianyi/OpenBLAS" "v0.3.21" ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) - find_package(BLAS REQUIRED) - endif () - -else () - message(" BLAS already included") -endif () - -message(STATUS "BLAS done") diff --git a/cmake/ImportBlasPP.cmake b/cmake/ImportBlasPP.cmake deleted file mode 100644 index 32f25b0b..00000000 --- a/cmake/ImportBlasPP.cmake +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (c) 2017-2023 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 ImportBlasPP.cmake -# @brief This file searches for the BLAS++ library and includes it if not already included. -# @version 1.0.0 -# @author Mahmoud ElKarargy -# @author Sameh Abdulah -# @date 2023-03-12 - -# search for BLAS library, if not already included -message("") -message("---------------------------------------- BLAS++") -message(STATUS "Checking for BLAS++") - -if (NOT TARGET blaspp) - - include(FindPkgConfig) - find_package(PkgConfig QUIET) - include(ImportBlas) - - find_package(blaspp QUIET) - - if (blaspp_FOUND) - message("Found BLAS++: ${blaspp_DIR}") - elseif (EXISTS "${CMAKE_SOURCE_DIR}/blaspp/CMakeLists.txt") - set(build_tests_save "${build_tests}") - set(build_tests "false") - add_subdirectory("blaspp") - - set(build_tests "${build_tests_save}") - set(blaspp_DIR "${CMAKE_BINARY_DIR}/blaspp") - else () - set(build_tests_save "${build_tests}") - set(build_tests "false") - set(url "https://github.com/icl-utk-edu/blaspp") - set(tag "v2023.01.00") - message(STATUS "Fetching BLAS++ ${tag} from ${url}") - include(FetchContent) - FetchContent_Declare( - blaspp GIT_REPOSITORY "${url}" GIT_TAG "${tag}") - FetchContent_MakeAvailable(blaspp) - set(build_tests "${build_tests_save}") - endif () -else () - message(" BLAS++ already included") -endif () - -set(LIBS - blaspp - ${LIBS} - ) -message(STATUS "BLAS++ done") diff --git a/cmake/ImportCatch2.cmake b/cmake/ImportCatch2.cmake index 5e70e789..1d255902 100644 --- a/cmake/ImportCatch2.cmake +++ b/cmake/ImportCatch2.cmake @@ -5,36 +5,20 @@ # @file ImportChameleon.cmake # @brief This script checks for Chameleon and includes it in the project if it is not already a target. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy -# @author Sameh Abdulah # @date 2023-03-13 -message("") -message("---------------------------------------- Catch2") -message(STATUS "Checking for Catch2") -include(macros/BuildDependency) +#Configurations +set(name "Catch2") +set(tag "v3.3.2") +set(version "3.3.2") +set(flag "") +set(is_cmake ON) +set(is_git ON) +set(auto_gen OFF) +set(url "https://github.com/catchorg/Catch2.git") -IF (NOT TARGET Catch2) - include(FindPkgConfig) - find_package(PkgConfig QUIET) - find_package(Catch2 QUIET) - - # If Catch2 is not found, fetch and build it - if (Catch2_FOUND) - message(" Found Catch2") - else () - message(" Can't find catch2, Installing it instead ..") - include(FetchContent) - set(FETCHCONTENT_QUIET OFF) - FetchContent_Declare( - Catch2 - GIT_REPOSITORY https://github.com/catchorg/Catch2.git - GIT_TAG v3.3.2 # Replace with the version of Catch2 you want to use for v3 - GIT_SHALLOW TRUE - ) - FetchContent_MakeAvailable(Catch2) - endif () -else () - message(STATUS "Catch2 already included") -endif () +include(macros/ImportDependency) +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) +message(STATUS "${name} done") diff --git a/cmake/ImportChameleon.cmake b/cmake/ImportChameleon.cmake index 4d19a5ea..a71ae88c 100644 --- a/cmake/ImportChameleon.cmake +++ b/cmake/ImportChameleon.cmake @@ -5,61 +5,25 @@ # @file ImportChameleon.cmake # @brief This script checks for Chameleon and includes it in the project if it is not already a target. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-13 -message("") -message("---------------------------------------- Chameleon") -message(STATUS "Checking for Chameleon") -include(macros/BuildDependency) +#Configurations +set(name "CHAMELEON") +set(tag "v1.1.0") +set(version "1.1.0") +set(flag -DCHAMELEON_USE_CUDA=${USE_CUDA} \-DBLA_VENDOR=${BLA_VENDOR} \-DCHAMELEON_USE_MPI=${USE_MPI} \-DCHAMELEON_SCHED_STARPU=ON \-DCHAMELEON_ENABLE_TESTING=OFF) +set(is_cmake ON) +set(is_git ON) +set(auto_gen OFF) +set(url "https://gitlab.inria.fr/solverstack/chameleon.git") -if (NOT TARGET CHAMELEON_FOUND) - include(FindPkgConfig) - find_package(PkgConfig QUIET) - find_package(CHAMELEON QUIET) +include(macros/ImportDependency) +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) - # If Chameleon is found, include it - if (CHAMELEON_FOUND) - message(" Found Chameleon: ${CHAMELEON_LIBDIR}") - # If Chameleon is not found, install it - else () - message(" Can't find Chameleon, Installing it instead ..") - # Set installation flags - set(FLAGS -DCHAMELEON_USE_CUDA=${USE_CUDA} \-DBLA_VENDOR=${BLA_VENDOR} \-DCHAMELEON_USE_MPI=${USE_MPI} \-DCHAMELEON_SCHED_STARPU=ON \-DCHAMELEON_ENABLE_TESTING=OFF) - set(ISCMAKE ON) - set(ISGIT ON) - set(AUTO_GEN OFF) - # Install Chameleon - BuildDependency(CHAMELEON "https://gitlab.inria.fr/solverstack/chameleon.git" "v1.1.0" ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) - # Reset flags - set(FLAGS "") - find_package(CHAMELEON REQUIRED) - endif () -else() - message(" CHAMELEON already included") -endif() - -link_directories(${CHAMELEON_LIBRARY_DIRS_DEP}) - -include_directories(AFTER ${CHAMELEON_INCLUDE_DIRS_DEP}) include_directories(AFTER ${CHAMELEON_DIR_FOUND}/include/coreblas) include_directories(${CHAMELEON_DIR_FOUND}/chameleon-src) -if (CHAMELEON_LINKER_FLAGS) - list(APPEND CMAKE_EXE_LINKER_FLAGS "${CHAMELEON_LINKER_FLAGS} ") -endif () -if (CHAMELEON_LIBRARY_DIRS) - # the RPATH to be used when installing - list(APPEND CMAKE_INSTALL_RPATH "${CHAMELEON_LIBRARY_DIRS}") -endif () -if (CHAMELEON_LIBRARIES) - if (CHAMELEON_LIBRARIES_DEP) - list(APPEND LIBS ${CHAMELEON_LIBRARIES_DEP}) - else () - list(APPEND LIBS ${CHAMELEON_LIBRARIES}) - endif () -endif () - -message(STATUS "Chameleon done") +message(STATUS "${name} done") diff --git a/cmake/ImportCuSolver.cmake b/cmake/ImportCuSolver.cmake deleted file mode 100644 index bdaa0978..00000000 --- a/cmake/ImportCuSolver.cmake +++ /dev/null @@ -1,20 +0,0 @@ - -# Copyright (c) 2017-2023 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 ImportCuSolver.cmake -# @brief This script sets CUDA libraries and adds CuSolver, CuBlas, and CuBlasLt to the list of libraries. -# @version 1.0.0 -# @author Mahmoud ElKarargy -# @author Sameh Abdulah -# @date 2023-03-13 - -set(cudart_lib CUDA::cudart) -set(cublas_lib CUDA::cublas) -set(LIBS - CUDA::cusolver - CUDA::cublas - CUDA::cublasLt - ${LIBS} - ) diff --git a/cmake/ImportGFortran.cmake b/cmake/ImportGFortran.cmake deleted file mode 100644 index a57f0517..00000000 --- a/cmake/ImportGFortran.cmake +++ /dev/null @@ -1,17 +0,0 @@ - -# Copyright (c) 2017-2023 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 ImportGFortran.cmake -# @brief Defines the gfortran library for use in the project. -# @version 1.0.0 -# @author Mahmoud ElKarargy -# @author Sameh Abdulah -# @date 2023-03-14 - -# Export the list of libraries, including gfortran, for use in the project. -set(LIBS - gfortran - ${LIBS} - ) diff --git a/cmake/ImportGSL.cmake b/cmake/ImportGSL.cmake index 3c111a1b..f6ebd0ff 100644 --- a/cmake/ImportGSL.cmake +++ b/cmake/ImportGSL.cmake @@ -5,47 +5,25 @@ # @file ImportGSL.cmake # @brief Checks for the GSL library and includes it in the project if it is not already present. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-16 -message("") -message("---------------------------------------- GSL") -message(STATUS "Checking for GSL") +#Configurations +set(name "GSL") +set(tag "v2.7.1") +set(version "2.7.1") +set(flag "") +set(is_cmake OFF) +set(is_git OFF) +set(auto_gen OFF) +set(url "https://ftp.gnu.org/gnu/gsl/gsl-2.7.1.tar.gz") -include(macros/BuildDependency) - -# Check if the GSL library is already included in the project. -if (NOT TARGET GSL_FOUND) - - # If not, attempt to find it with PkgConfig and CMake's find_package function. - include(FindPkgConfig) - find_package(PkgConfig QUIET) - find_package(GSL QUIET) - - # If the GSL library is found, add it to the project's libraries. - if (GSL_FOUND) - message(" Found GSL: ${GSL_INCLUDE_DIRS}") - else () - - # If the GSL library is not found, install it and add it to the project's libraries. - message(" Can't find GSL, Installing it instead ..") - set(FLAGS "") - set(ISCMAKE OFF) - set(ISGIT OFF) - set(AUTO_GEN OFF) - BuildDependency(GSL "https://ftp.gnu.org/gnu/gsl/gsl-2.7.1.tar.gz" "v2.7.1" ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) - find_package(GSL REQUIRED) - endif () -else () - message(" GSL already included") -endif () +include(macros/ImportDependency) +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) # Add the GSL library to the project's list of libraries. list(APPEND LIBS gsl) -include_directories(${GSL_INCLUDE_DIRS}) -link_directories(${GSL_LIBRARY_DIRS}) -message("${GSL_LIBRARIES}") -message(STATUS "GSL done") +message(STATUS "${name} done") diff --git a/cmake/ImportHCore.cmake b/cmake/ImportHCore.cmake new file mode 100644 index 00000000..5f1c53cf --- /dev/null +++ b/cmake/ImportHCore.cmake @@ -0,0 +1,26 @@ + +# Copyright (c) 2017-2023 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 ImportHCore.cmake +# @brief Checks for the Hcore library and includes it in the project if it is not already present. +# @version 1.0.1 +# @author Mahmoud ElKarargy +# @author Sameh Abdulah +# @date 2023-03-15 + +#Configurations +set(name "HCORE") +set(tag "v0.1.3") +set(version "0.1.3") +set(flag "") +set(is_cmake ON) +set(is_git ON) +set(auto_gen OFF) +set(url "https://github.com/ecrc/hcore.git") + +include(macros/ImportDependency) +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) + +message(STATUS "${name} done") diff --git a/cmake/ImportHcore.cmake b/cmake/ImportHcore.cmake deleted file mode 100644 index 0c5fe43f..00000000 --- a/cmake/ImportHcore.cmake +++ /dev/null @@ -1,50 +0,0 @@ - -# Copyright (c) 2017-2023 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 ImportHcore.cmake -# @brief Checks for the Hcore library and includes it in the project if it is not already present. -# @version 1.0.0 -# @author Mahmoud ElKarargy -# @author Sameh Abdulah -# @date 2023-03-15 - -message("") -message("---------------------------------------- Hcore") -message(STATUS "Checking for Hcore") - -include(macros/BuildDependency) - -# Check if the Hcore library is already included in the project. -if (NOT TARGET HCORE_FOUND) - - # If not, attempt to find it with PkgConfig and CMake's find_package function. - include(FindPkgConfig) - find_package(PkgConfig QUIET) - find_package(HCORE QUIET) - - # If the Hcore library is found, add it to the project's libraries. - if (HCORE_FOUND) - message(" Found Hcore: ${HCORE_LIBDIR}") - else() - - # If the Hcore library is not found, install it and add it to the project's libraries. - message(" Can't find Hcore, Installing it instead ..") - set(FLAGS "") - set(ISCMAKE ON) - set(ISGIT ON) - set(AUTO_GEN OFF) - BuildDependency(HCORE "https://github.com/ecrc/hcore.git" "v0.1.3" ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) - find_package(HCORE REQUIRED) - endif() -else() - message(" HCORE already included") -endif() - -# Add the Hcore library to the project's list of libraries. -list(APPEND LIBS ${HCORE_LIBRARIES}) -link_directories(${HCORE_LIBRARY_DIRS_DEP}) -include_directories(${HCORE_INCLUDE_DIRS}) - -message(STATUS "Hcore done") \ No newline at end of file diff --git a/cmake/ImportHiCMA.cmake b/cmake/ImportHiCMA.cmake index 025ce48f..7257ee15 100644 --- a/cmake/ImportHiCMA.cmake +++ b/cmake/ImportHiCMA.cmake @@ -5,62 +5,24 @@ # @file ImportHiCMA.cmake # @brief Find and include HiCMA library as a dependency. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-13 -message("") -message("---------------------------------------- Hicma") -message(STATUS "Checking for HiCMA") -include(macros/BuildDependency) +#Configurations +set(name "HICMA") +set(tag "v1.0.0") +set(version "1.0.0") +set(flag -DHICMA_USE_MPI=${USE_MPI}) +set(is_cmake ON) +set(is_git ON) +set(auto_gen OFF) +set(url "https://github.com/ecrc/hicma.git") -if (NOT TARGET HICMA_FOUND) - include(FindPkgConfig) - find_package(PkgConfig QUIET) - find_package(HICMA QUIET) - - # If HiCMA is found, print its location. - if (HICMA_FOUND) - message(" Found HiCMA: ${HICMA_LIBDIR}") - # If not found, install it. - else () - message(" Can't find HiCMA, Installing it instead ..") - - # Set the flags to be passed to the build command. - set(FLAGS \-DHICMA_USE_MPI=${USE_MPI}) - set(ISCMAKE ON) - set(ISGIT ON) - set(AUTO_GEN OFF) - # Build HiCMA from source. - BuildDependency(HiCMA "https://github.com/ecrc/hicma.git" "v1.0.0" ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) - # Clear the flags. - set(FLAGS "") - # Find HiCMA after installation. - find_package(HICMA REQUIRED) - endif () -else () - message(" HiCMA already included") -endif () +include(macros/ImportDependency) +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) # Include HiCMA headers in the project. -include_directories(${HICMA_INCLUDE_DIRS_DEP}) include_directories(${HICMA_LIBDIR}/../hicma-src/hicma_ext) - -# Include HiCMA libraries in the project. -if (HICMA_LINKER_FLAGS) - list(APPEND CMAKE_EXE_LINKER_FLAGS "${HICMA_LINKER_FLAGS}") -endif () -if (HICMA_LIBRARY_DIRS) - list(APPEND CMAKE_INSTALL_RPATH "${HICMA_LIBRARY_DIRS}") - link_directories(${HICMA_LIBRARY_DIRS}) -endif () - -# Add HiCMA libraries to the dependencies of the project. -if (HICMA_LIBRARIES_DEP) - list(APPEND LIBS ${HICMA_LIBRARIES_DEP}) -else () - list(APPEND LIBS ${HICMA_LIBRARIES}) -endif () - -message(STATUS "HiCMA done") \ No newline at end of file +message(STATUS "HiCMA done") diff --git a/cmake/ImportHwloc.cmake b/cmake/ImportHwloc.cmake index 019f8c82..a4f71525 100644 --- a/cmake/ImportHwloc.cmake +++ b/cmake/ImportHwloc.cmake @@ -5,52 +5,22 @@ # @file ImportHwloc.cmake # @brief Find and include Hwloc library as a dependency. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-15 +#Configurations +set(name "HWLOC") +set(tag "hwloc-2.4.0") +set(version "2.4.0") +set(flag "") +set(is_cmake OFF) +set(is_git ON) +set(auto_gen ON) +set(url "https://github.com/open-mpi/hwloc") -message("") -message("---------------------------------------- Hwloc") -message(STATUS "Checking for Hwloc") +include(macros/ImportDependency) +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) -include(macros/BuildDependency) - -# If Hwloc library is not already included as a target, try to find it. -if (NOT TARGET HWLOC) - include(FindPkgConfig) - find_package(PkgConfig QUIET) - find_package(HWLOC 2.4.0 REQUIRED QUIET) - - # If Hwloc is found, print its location. - if (HWLOC_FOUND) - message(" Found HWLOC: ${HWLOC_INCLUDE_DIRS}") - # If not found, install it. - else () - message(" Can't find Hwloc, Installing it instead ..") - - # Set the flags to be passed to the build command. - set(FLAGS "") - set(ISCMAKE OFF) - set(ISGIT ON) - set(AUTO_GEN ON) - - # Build Hwloc from source. - BuildDependency(HWLOC "https://github.com/open-mpi/hwloc" "hwloc-2.4.0" ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) - - # Find Hwloc after installation. - find_package(HWLOC 2.4.0 REQUIRED) - endif () -else () - message(" HWLOC already included") -endif () - -# Include Hwloc libraries in the project. -list(APPEND LIBS ${HWLOC_LIBRARIES}) -link_directories(${HWLOC_LIBRARY_DIRS_DEP}) - -# Include Hwloc headers in the project. -include_directories(${HWLOC_INCLUDE_DIRS}) - -message(STATUS "HWLOC done") +message(STATUS "${name} done") diff --git a/cmake/ImportLapack.cmake b/cmake/ImportLapack.cmake index c0e77417..5a6a6c64 100644 --- a/cmake/ImportLapack.cmake +++ b/cmake/ImportLapack.cmake @@ -5,38 +5,22 @@ # @file ImportLapack.cmake # @brief Find and include LAPACK library as a dependency. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-12 -# search for LAPACK library, if not already included -message("") -message("---------------------------------------- LAPACK") -message(STATUS "Checking for LAPACK") +#Configurations +set(name "LAPACK") +set(tag "v0.3.21") +set(version "0.3.21") +set(flag "") +set(is_cmake ON) +set(is_git ON) +set(auto_gen OFF) +set(url "https://github.com/xianyi/OpenBLAS") -include(macros/BuildDependency) +include(macros/ImportDependency) +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) -if (NOT TARGET LAPACK) - include(FindPkgConfig) - find_package(PkgConfig QUIET) - find_package(LAPACK QUIET) - - if (LAPACK_FOUND) - message(" Found LAPACK: ${LAPACK_LIBRARIES}") - else () - message(" Can't find Blas, Installing it instead ..") - # Set installation flags - set(FLAGS "") - set(ISCMAKE ON) - set(ISGIT ON) - set(AUTO_GEN OFF) - set(build_tests "false") - BuildDependency(LAPACK "https://github.com/xianyi/OpenBLAS" "v0.3.21" ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) - find_package(LAPACK REQUIRED) - endif () -else () - message(" LAPACK already included") -endif () - -message(STATUS "LAPACK done") +message(STATUS "${name} done") diff --git a/cmake/ImportLapackPP.cmake b/cmake/ImportLapackPP.cmake deleted file mode 100644 index 543c3cd7..00000000 --- a/cmake/ImportLapackPP.cmake +++ /dev/null @@ -1,60 +0,0 @@ - -# Copyright (c) 2017-2023 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 ImportLapackPP.cmake -# @brief Find and include LAPACK++ library as a dependency. -# @version 1.0.0 -# @author Mahmoud ElKarargy -# @author Sameh Abdulah -# @date 2023-03-12 - -# search for LAPACK library, if not already included -message("") -message("---------------------------------------- LAPACK++") -message(STATUS "Checking for LAPACK++") -if (NOT TARGET lapackpp) - include(ImportLapack) - - find_package(lapackpp QUIET) - if (lapackpp_FOUND) - message(" Found LAPACK++: ${lapackpp_DIR}") - elseif (EXISTS "${CMAKE_SOURCE_DIR}/lapackpp/CMakeLists.txt") - set(build_tests_save "${build_tests}") - set(build_tests "false") - - add_subdirectory("lapackpp") - - set(build_tests "${build_tests_save}") - set(lapackpp_DIR "${CMAKE_BINARY_DIR}/lapackpp") - else () - set(build_tests_save "${build_tests}") - set(build_tests "false") - - set(url "https://github.com/icl-utk-edu/lapackpp") - set(tag "v2023.01.00") - message(STATUS "Fetching LAPACK++ ${tag} from ${url}") - include(FetchContent) - FetchContent_Declare( - lapackpp GIT_REPOSITORY "${url}" GIT_TAG "${tag}") - FetchContent_MakeAvailable(lapackpp) - - set(build_tests "${build_tests_save}") - endif () -else () - message(" LAPACK++ already included") -endif () - -# Add to linking libs. -set(LIBS - lapackpp - ${LIBS} - ) - -# Add definition indicating version. -if ("${lapackpp_defines}" MATCHES "LAPACK_ILP64") - set(COMPILE_DEFINITIONS "${COMPILE_DEFINITIONS} -DHCORE_HAVE_LAPACK_WITH_ILP64") -endif () - -message(STATUS "LAPACK++ done") diff --git a/cmake/ImportNLOPT.cmake b/cmake/ImportNLOPT.cmake index 3a510b8b..ac796b44 100644 --- a/cmake/ImportNLOPT.cmake +++ b/cmake/ImportNLOPT.cmake @@ -5,52 +5,22 @@ # @file ImportNLOPT.cmake # @brief Find and include NLOPT library as a dependency. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-26 -message("") -message("---------------------------------------- NLOPT") -message(STATUS "Checking for NLOPT") -include(macros/BuildDependency) -if (NOT TARGET NLOPT_FOUND) - # Try to find NLOPT. - include(FindPkgConfig) - find_package(PkgConfig QUIET) - find_package(NLOPT 2.4.2 QUIET) +#Configurations +set(name "NLOPT") +set(tag "v2.7.1") +set(version "2.7.1") +set(flag " ") +set(is_cmake ON) +set(is_git ON) +set(auto_gen OFF) +set(url "https://github.com/stevengj/nlopt") - # If NLOPT is found, print its location. - if (NLOPT_FOUND) - message(" Found NLOPT: ${NLOPT_LIBRARIES}") - # If not found, install it. - else () - message(" Can't find NLOPT, Installing it instead ..") +include(macros/ImportDependency) +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) - # Set installation flags. - set(FLAGS "") - set(ISCMAKE ON) - set(ISGIT ON) - set(AUTO_GEN OFF) - # Build NLOPT from source. - BuildDependency(NLOPT "https://github.com/stevengj/nlopt" "v2.7.1" ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) - - # Set the location of NLOPT. - set(NLOPT_LIBRARY_DIRS= ${EXAGEOSTAT_INSTALL_PREFIX}/NLOPT/lib:$NLOPT_LIBRARY_DIRS) - set(NLOPT_INCLUDE_DIRS= ${EXAGEOSTAT_INSTALL_PREFIX}/NLOPT/include:$NLOPT_INCLUDE_DIRS) - - # Try to find NLOPT again. - find_package(NLOPT 2.4.2 REQUIRED) - endif () -else () - message(" NLOPT already included") -endif () - -# Include NLOPT headers. -include_directories(${NLOPT_INCLUDE_DIRS}) - -# Link NLOPT libraries. -link_directories(${NLOPT_LIBRARY_DIRS}) -list(APPEND LIBS ${NLOPT_LIBRARIES}) - -message(STATUS "NLOPT done") \ No newline at end of file +message(STATUS "${name} done") diff --git a/cmake/ImportOpenMP.cmake b/cmake/ImportOpenMP.cmake deleted file mode 100644 index 4ec5aec9..00000000 --- a/cmake/ImportOpenMP.cmake +++ /dev/null @@ -1,27 +0,0 @@ - -# Copyright (c) 2017-2023 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 ImportOpenMP.cmake -# @brief Find and include OpenMP library as a dependency. -# @version 1.0.0 -# @author Mahmoud ElKarargy -# @author Sameh Abdulah -# @date 2023-03-13 - -# Add OpenMP if requested. -option(USE_OPENMP "Use OpenMP, if available" true) -if (NOT USE_OPENMP) - message(STATUS "User has requested to NOT use OpenMP") -else () - find_package(OpenMP QUIET) - IF (OPENMP_FOUND) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - set(LIBS - OpenMP::OpenMP_CXX - ${LIBS} - ) - ENDIF () -endif () diff --git a/cmake/ImportStarPu.cmake b/cmake/ImportStarPu.cmake index 42e6c47e..b160c574 100644 --- a/cmake/ImportStarPu.cmake +++ b/cmake/ImportStarPu.cmake @@ -5,74 +5,32 @@ # @file ImportSTARPU.cmake # @brief Find and include STARPU library as a dependency. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-13 -message("") -message("---------------------------------------- StarPU") -message(STATUS "Checking for StarPU") - -include(macros/BuildDependency) - -if (NOT TARGET STARPU) - # Try to find STARPU. - include(FindPkgConfig) - find_package(PkgConfig QUIET) - find_package(STARPU 1.3.9 QUIET COMPONENTS ${STARPU_COMPONENT_LIST}) - - - # If STARPU is found, print its location. - if (STARPU_FOUND) - message(" Found StarPU: ${STARPU_LIBRARIES}") - # If not found, install it. - else () - # Set the flags to be passed to the build command. - set(ISCMAKE OFF) - set(ISGIT ON) - set(AUTO_GEN ON) - - if (USE_CUDA AND USE_MPI) - message(STATUS "Downloading STARPU - MPI CUDA" ) - set(FLAGS \--enable-cuda \--disable-opencl \--enable-shared \--disable-build-doc \--disable-export-dynamic \--enable-mpi) - elseif(USE_CUDA) - message(STATUS "Downloading STARPU - CUDA" ) - set(FLAGS \--enable-cuda \--disable-opencl \--enable-shared \--disable-build-doc \--disable-export-dynamic \--disable-mpi) - elseif(USE_MPI) - message(STATUS "Downloading STARPU - MPI" ) - set(FLAGS \--disable-cuda \--disable-opencl \--enable-shared \--disable-build-doc \--disable-export-dynamic \--enable-mpi) - else() - message(STATUS "Downloading STARPU - SERIAL" ) - set(FLAGS \--disable-cuda \--disable-opencl \--enable-shared \--disable-build-doc \--disable-export-dynamic \--disable-mpi) - endif() - - BuildDependency(STARPU "https://gitlab.inria.fr/starpu/starpu.git" "starpu-1.3.9" ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) - # Clear the flags. - set(FLAGS "") - # Find StarPU after installation. - find_package(STARPU 1.3.9 QUIET COMPONENTS ${STARPU_COMPONENT_LIST}) - - endif () -else () - message(" STARPU already included") -endif () - -# Include STARPU headers. -list(APPEND LIBS ${STARPU_LIBRARIES}) -link_directories(${STARPU_LIBRARY_DIRS_DEP}) -include_directories(${STARPU_INCLUDE_DIRS}) -include_directories(${STARPU_INCLUDE_DIRS}/runtime/starpu) -include_directories(${STARPU_INCLUDE_DIRS_DEP}) - -# Set linker flags. -if (STARPU_LINKER_FLAGS) - list(APPEND CMAKE_EXE_LINKER_FLAGS "${STARPU_LINKER_FLAGS}") -endif () -set(CMAKE_REQUIRED_INCLUDES "${STARPU_INCLUDE_DIRS_DEP}") -foreach (libdir ${STARPU_LIBRARY_DIRS_DEP}) - list(APPEND CMAKE_REQUIRED_FLAGS "-L${libdir}") -endforeach () -set(CMAKE_REQUIRED_LIBRARIES "${STARPU_LIBRARIES_DEP}") - -message(STATUS "starpu done") +#Configurations +set(name "STARPU") +set(tag "starpu-1.3.9") +set(version "1.3.9") + +if (USE_CUDA AND USE_MPI) + set(flag \--enable-cuda \--disable-opencl \--enable-shared \--disable-build-doc \--disable-export-dynamic \--enable-mpi) +elseif(USE_CUDA) + set(flag \--enable-cuda \--disable-opencl \--enable-shared \--disable-build-doc \--disable-export-dynamic \--disable-mpi) +elseif(USE_MPI) + set(flag \--disable-cuda \--disable-opencl \--enable-shared \--disable-build-doc \--disable-export-dynamic \--enable-mpi) +else() + set(flag \--disable-cuda \--disable-opencl \--enable-shared \--disable-build-doc \--disable-export-dynamic \--disable-mpi) +endif() + +set(is_cmake OFF) +set(is_git ON) +set(auto_gen ON) +set(url "https://gitlab.inria.fr/starpu/starpu.git") + +include(macros/ImportDependency) +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "${STARPU_COMPONENT_LIST}" ${is_cmake} ${is_git} ${auto_gen}) + +message(STATUS "${name} done") diff --git a/cmake/ImportStarsH.cmake b/cmake/ImportStarsH.cmake index 585fecbb..b7c842b6 100644 --- a/cmake/ImportStarsH.cmake +++ b/cmake/ImportStarsH.cmake @@ -5,82 +5,22 @@ # @file CMakeLists.txt # @brief Find and include STARSH library as a dependency. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-13 -message("") -message("---------------------------------------- Stars-H") -message(STATUS "Checking for STARSH") -include(macros/BuildDependency) +#Configurations +set(name "STARSH") +set(tag "v0.3.1") +set(version "0.3.1") +set(flag \-DSTARPU=OFF \-DMPI=${USE_MPI}) +set(is_cmake ON) +set(is_git ON) +set(auto_gen OFF) +set(url "https://github.com/ecrc/stars-h.git") -if (NOT TARGET STARSH_FOUND) - # Try to find STARSH. - include(FindPkgConfig) - find_package(PkgConfig QUIET) - find_package(STARSH QUIET) +include(macros/ImportDependency) +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) - # If STARSH is found, print its location. - if (STARSH_FOUND) - message(" Found STARSH: ${STARSH_INCLUDE_DIRS}") - # If not found, install it. - else () - message(" Can't find STARSH, Installing it instead ..") - set(FLAGS \-DSTARPU=OFF \-DMPI=${USE_MPI}) - set(ISCMAKE ON) - set(ISGIT ON) - set(AUTO_GEN OFF) - BuildDependency(STARSH "https://github.com/ecrc/stars-h.git" "v0.3.1" ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) - set(FLAGS "") - find_package(STARSH REQUIRED) - endif () -else () - message(" STARSH already included") -endif () - -# Include STARSH headers. -include_directories(${STARSH_INCLUDE_DIRS_DEP}) - -# Set linker flags and library directories. -if (STARSH_LINKER_FLAGS) - list(APPEND CMAKE_EXE_LINKER_FLAGS "${STARSH_LINKER_FLAGS}") -endif () -if (STARSH_LIBRARY_DIRS) - list(APPEND CMAKE_INSTALL_RPATH "${STARSH_LIBRARY_DIRS}") -endif () - -# Check if GSL is a dependency of STARSH and add it if needed. -if (STARSH_LIBRARIES) - find_library(_STARSH_LIB NAME starsh PATHS ${STARSH_LIBRARY_DIRS}) - if (_STARSH_LIB AND NOT "${STARSH_LIBRARIES_DEP}" MATCHES "gsl") - execute_process(COMMAND nm ${_STARSH_LIB} COMMAND grep gsl RESULT_VARIABLE GSL_IN_STARSH) - if (${GSL_IN_STARSH} EQUAL 0) - message(STATUS "STARSH depends on gsl. Adding it to dependency list") - find_package(GSL REQUIRED) - if (GSL_FOUND) - if (STARSH_LIBRARIES_DEP) - list(APPEND STARSH_LIBRARIES_DEP ${GSL_LIBRARIES}) - else () - list(APPEND STARSH_LIBRARIES ${GSL_LIBRARIES}) - endif () - endif () - endif () - endif () - - # Add STARSH libraries to the project. - if (STARSH_LIBRARIES_DEP) - list(APPEND LIBS ${STARSH_LIBRARIES_DEP}) - link_directories(${STARSH_LIBRARY_DIRS_DEP}) - link_directories(${STARSH_LIBRARIES_DEP}) - else () - list(APPEND LIBS ${STARSH_LIBRARIES}) - link_directories(${STARSH_LIBRARIES}) - endif () - - list(APPEND LIBS ${STARSH_LIBRARIES}) - link_directories(${STARSH_LIBRARY_DIRS_DEP}) - include_directories(${STARSH_INCLUDE_DIRS}) -endif () - -message(STATUS "StarsH Done") \ No newline at end of file +message(STATUS "${name} done") diff --git a/cmake/macros/BuildDependency.cmake b/cmake/macros/BuildDependency.cmake index 5edee634..825db78b 100644 --- a/cmake/macros/BuildDependency.cmake +++ b/cmake/macros/BuildDependency.cmake @@ -4,25 +4,31 @@ # @file BuildDependency.cmake # @brief Fetches, builds, and installs a dependency. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy -# @author Sameh Abdulah # @date 2023-03-12 -# @param raw_name The name of the dependency. -# @param url The URL from which to fetch the dependency. -# @param tag The version or tag of the dependency to fetch. -# @param ${FLAGS} Additional flags to pass to the configure/make commands. -# @param ${ISCMAKE} A boolean flag indicating whether the dependency uses CMake as its build system. -# @param ${ISGIT} A boolean flag indicating whether the dependency is hosted on a git repository. -# @param ${AUTO_GEN} A boolean flag indicating whether to use autogen scripts or not. +# After building and installing the dependency, the macro installs the lib, include, and share directories +# in the current directory. -# This macro fetches the dependency using CMake's FetchContent module, and then builds and installs it. -# It also sets several environment variables (LD_LIBRARY_PATH, LIBRARY_PATH, CPATH, PKG_CONFIG_PATH, -# and ${capital_name}_DIR) and includes and links to the installation directory of the dependency. +# BuildDependency Macro: +# This macro is designed to fetch, configure, build, and install a dependency. +# It takes the following parameters: +# - raw_name: The name of the dependency. +# - url: The URL of the repository or source tarball. +# - tag: The version or tag of the dependency to fetch. +# - flags: Additional flags to pass to the configure/make commands. +# - is_using_cmake: A boolean flag indicating whether the dependency uses CMake as its build system. +# - is_using_git: A boolean flag indicating whether the dependency is hosted on a git repository. +# - auto_generation: A boolean flag indicating whether to use autogen scripts or not. + +# The macro fetches the dependency using CMake's FetchContent module, depending on whether it's a git repo or not. +# It sets up build paths and creates a directory for build artifacts. The subproject is then configured using +# CMake or autotools, and finally, it's built and installed. Environment variables are set, and the dependency's +# lib, include, and share directories are installed in the current directory. + +macro(BuildDependency raw_name url tag flags is_using_cmake is_using_git auto_generation) -# After building and installing the dependency, the macro installs the lib, include, and share directories in the current directory. -macro(BuildDependency raw_name url tag ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) # Set the name of the dependency. string(TOLOWER ${raw_name} name) string(TOUPPER ${raw_name} capital_name) @@ -30,8 +36,9 @@ macro(BuildDependency raw_name url tag ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) # Fetch the dependency, depending on whether it's a git repo or not. message(STATUS "Fetching ${name} ${tag} from ${url}") include(FetchContent) - set(FETCHCONTENT_BASE_DIR ${EXAGEOSTAT_INSTALL_PREFIX}/${capital_name}/) - if (ISGIT) + set(FETCHCONTENT_BASE_DIR ${CMAKE_INSTALL_PREFIX}/${capital_name}) + + if (${is_using_git}) FetchContent_Declare(${name} GIT_REPOSITORY "${url}" GIT_TAG "${tag}" @@ -41,27 +48,27 @@ macro(BuildDependency raw_name url tag ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) else () FetchContent_Declare(${name} URL "${url}") endif () + FetchContent_Populate(${name}) - # Set up build paths and create directory for build artifacts. - set(${name}_srcpath ${EXAGEOSTAT_INSTALL_PREFIX}/${capital_name}/${name}-src) + # Set up build paths and create a directory for build artifacts. + set(${name}_srcpath ${CMAKE_INSTALL_PREFIX}/${capital_name}/${name}-src) set(${name}_binpath ${${name}_srcpath}/bin) - set(${name}_installpath ${EXAGEOSTAT_INSTALL_PREFIX}/${capital_name}/) + set(${name}_installpath ${CMAKE_INSTALL_PREFIX}/${capital_name}) file(MAKE_DIRECTORY ${${name}_binpath}) # Configure subproject. - if (ISCMAKE) - execute_process(COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${EXAGEOSTAT_INSTALL_PREFIX}/${capital_name}/ ${FLAGS} + if (${is_using_cmake}) + execute_process(COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}/${capital_name} ${flags} ${${name}_srcpath} - WORKING_DIRECTORY - ${${name}_binpath}) + WORKING_DIRECTORY ${${name}_binpath}) else () - if (AUTO_GEN) + if (${auto_generation}) execute_process(COMMAND ./autogen.sh WORKING_DIRECTORY ${${name}_srcpath} COMMAND_ERROR_IS_FATAL ANY) endif () - execute_process(COMMAND ./configure --prefix=${EXAGEOSTAT_INSTALL_PREFIX}/${capital_name}/ ${FLAGS} + execute_process(COMMAND ./configure --prefix=${CMAKE_INSTALL_PREFIX}/${capital_name} ${flags} WORKING_DIRECTORY ${${name}_srcpath} COMMAND_ERROR_IS_FATAL ANY) endif () @@ -69,7 +76,7 @@ macro(BuildDependency raw_name url tag ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) # Build and install subproject. include(ProcessorCount) ProcessorCount(N) - if (ISCMAKE) + if (${is_using_cmake}) execute_process(COMMAND make -j ${N} WORKING_DIRECTORY ${${name}_binpath} COMMAND_ERROR_IS_FATAL ANY) @@ -90,7 +97,8 @@ macro(BuildDependency raw_name url tag ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) set(ENV{LIBRARY_PATH} "${${name}_installpath}/lib:${${name}_installpath}/lib64:$ENV{LIBRARY_PATH}") set(ENV{CPATH} "${${name}_installpath}/include:$ENV{CPATH}") set(ENV{PKG_CONFIG_PATH} "${${name}_installpath}/lib/pkgconfig:${${name}_installpath}/lib64/pkgconfig:$ENV{PKG_CONFIG_PATH}") - set(${capital_name}_DIR "${${name}_installpath}") + + # Include and link to the installation directory of the dependency include_directories(${${name}_installpath}/include) link_directories(${${name}_installpath}/lib) @@ -113,4 +121,4 @@ macro(BuildDependency raw_name url tag ${FLAGS} ${ISCMAKE} ${ISGIT} ${AUTO_GEN}) DESTINATION . ) -endmacro() +endmacro() \ No newline at end of file diff --git a/cmake/macros/ImportDependency.cmake b/cmake/macros/ImportDependency.cmake new file mode 100644 index 00000000..c2de92f8 --- /dev/null +++ b/cmake/macros/ImportDependency.cmake @@ -0,0 +1,70 @@ +# Copyright (c) 2017-2023 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 ImportDependency.cmake +# @brief CMake script for importing and building external dependencies. +# @version 1.0.1 +# @author Mahmoud ElKarargy +# @date 2023-12-28 + +# ImportDependency Macro: +# This macro is designed to check for the presence of an external dependency and install it if not found. +# It takes the following parameters: +# - raw_name: The name of the dependency. +# - tag: The tag of the dependency to fetch. +# - version: The version of the dependency. +# - url: The URL of the repository or source tarball. +# - flag: Additional flags to pass to the configure/make commands. +# - is_cmake: A boolean flag indicating whether the dependency uses CMake as its build system. +# - is_git: A boolean flag indicating whether the dependency is hosted on a git repository. +# - auto_gen: A boolean flag indicating whether to use autogen scripts or not. + +# The macro checks whether the dependency is already included. If not, it attempts to find the package. +# If the package is found, it prints a message. If not, it calls the BuildDependency macro to fetch, +# configure, build, and install the dependency. Finally, it attempts to find the package again to validate the installation. + +macro(ImportDependency name tag version url flag components is_cmake is_git auto_gen) + + # First, Check if no path is set for installation. + if (CMAKE_INSTALL_PREFIX MATCHES "/usr/") + message(WARNING "Installation path not specified. Please set the installation path using -DCMAKE_INSTALL_PREFIX=path/to/install or execute ./config.sh. Otherwise, please note that administrative privileges may be required to install in system paths.") + endif () + + # Convert name to uppercase for consistency + string(TOUPPER ${name} capital_name) + message("") + message("---------------------------------------- ${capital_name}") + message(STATUS "Checking for ${capital_name} with Version ${version}") + + # Include the BuildDependency macro + include(macros/BuildDependency) + + # Check if the target is already included + IF (NOT TARGET ${name}) + include(FindPkgConfig) + find_package(PkgConfig QUIET) + find_package(${name} ${version} QUIET COMPONENTS ${components}) + + # If the package is found, print a message + if (${name}_FOUND) + message(" Found ${capital_name}; ${${name}_DIR} ${${name}_LIBRARIES}") + else () + # If the package is not found, install it using BuildDependency + message(" Can't find ${capital_name}, Installing it instead ..") + BuildDependency(${name} ${url} ${tag} "${flag}" ${is_cmake} ${is_git} ${auto_gen}) + find_package(${name} ${version} REQUIRED COMPONENTS ${components}) + endif () + else () + message(STATUS "${capital_name} already included") + endif () + + # Include and link to the installation directory of the dependency + link_directories(${${name}_LIBRARY_DIRS_DEP}) + link_directories(${${name}_LIBRARY_DIRS}) + include_directories(${${name}_INCLUDE_DIRS}) + include_directories(AFTER ${${name}_INCLUDE_DIRS_DEP}) + list(APPEND LIBS ${${name}_LIBRARIES}) + list(APPEND LIBS ${${name}_LIBRARIES_DEP}) + +endmacro() \ No newline at end of file diff --git a/cmake/toolchains/CudaToolchain.cmake b/cmake/toolchains/CudaToolchain.cmake index f9edaa67..aaf7ae59 100644 --- a/cmake/toolchains/CudaToolchain.cmake +++ b/cmake/toolchains/CudaToolchain.cmake @@ -5,7 +5,7 @@ # @file CudaToolchain.cmake # @brief This file is used to set up the CUDA toolchain for compilation. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-12 @@ -19,5 +19,4 @@ set(CUDA_ARCHITECTURES "35;50;72") # Find the CUDA toolkit find_package(CUDAToolkit REQUIRED) -# TODO: Cuda linking set(ENV{LDFLAGS} "-L$ENV{CUDA_DIR}/lib64") diff --git a/config.sh b/config.sh index 1f7d390b..04ac419e 100755 --- a/config.sh +++ b/config.sh @@ -4,7 +4,7 @@ # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file config.sh -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @date 2023-01-30 @@ -18,15 +18,32 @@ NC='\033[0m' INSTALL_PREFIX=$PWD/installdir/_deps PROJECT_SOURCE_DIR=$(dirname "$0") BUILDING_TESTS="OFF" +BUILDING_HEAVY_TESTS="OFF" BUILDING_EXAMPLES="OFF" USING_HiCMA="OFF" -VERBOSE=OFF +VERBOSE="OFF" USE_CUDA="OFF" USE_MPI="OFF" BLAS_VENDOR="" +PACKAGE="OFF" +SHOW_WARNINGS="OFF" +COMPILE_FLAGS="-Wl,--no-as-needed" +DEVELOPER_WARNINGS="-Wno-dev" + + +for arg in "$@" +do + case $arg in + --use-mkl) + echo -e "${GREEN}MKL as a BLA vendor${NC}" + BLAS_VENDOR="Intel10_64lp" + shift # Remove --use-mkl from processing + ;; + esac +done # Parse command line options -while getopts ":tevhHi:cms" opt; do +while getopts ":tevhHi:cmpTw" opt; do case $opt in i) ##### Define installation path ##### echo -e "${YELLOW}Installation path set to $OPTARG.${NC}" @@ -36,6 +53,10 @@ while getopts ":tevhHi:cms" opt; do echo -e "${GREEN}Building tests enabled.${NC}" BUILDING_TESTS="ON" ;; + T) ##### Building heavy tests enabled ##### + echo -e "${GREEN}Building heavy tests enabled.${NC}" + BUILDING_HEAVY_TESTS="ON" + ;; e) ##### Building examples enabled ##### echo -e "${GREEN}Building examples enabled.${NC}" BUILDING_EXAMPLES="ON" @@ -46,19 +67,23 @@ while getopts ":tevhHi:cms" opt; do ;; c)##### Using cuda enabled ##### echo -e "${GREEN}Cuda enabled ${NC}" - USE_CUDA=ON + USE_CUDA="ON" ;; m)##### Using MPI enabled ##### echo -e "${GREEN}MPI enabled ${NC}" - USE_MPI=ON + USE_MPI="ON" ;; v) ##### printing full output of make ##### - echo -e "${YELLOW}printing make with details.${NC}" - VERBOSE=ON + echo -e "${GREEN}printing make with details.${NC}" + VERBOSE="ON" + ;; + p) ##### Enabling packaging system for distribution ##### + echo -e "${GREEN}CPACK enabled${NC}" + PACKAGE=ON ;; - s) ##### Passing Blas vendor with mkl ##### - echo -e "${YELLOW}MKL as a Blas vendor${NC}" - BLAS_VENDOR="Intel10_64lp" + w) ##### Enable showing all the warnings ##### + echo -e "${GREEN}Showing Warnings is enabled${NC}" + SHOW_WARNINGS="ON" ;; \?) ##### Error unknown option ##### echo "Option $OPTARG parameter is unknown, please -h for help" @@ -73,13 +98,15 @@ while getopts ":tevhHi:cms" opt; do echo "" printf "%20s %s\n" "-i [path] :" "specify installation path, default = ${PWD}/installdir/_deps/" printf "%20s %s\n" "-t :" "to enable building tests." + printf "%20s %s\n" "-T :" "to enable building heavy tests." printf "%20s %s\n" "-e :" "to enable building examples." printf "%20s %s\n" "-H :" "to enable using HiCMA." printf "%20s %s\n" "-c :" "to enable using CUDA." printf "%20s %s\n" "-m :" "to enable using MPI." printf "%20s %s\n" "-v :" "to enable verbose printings." printf "%20s %s\n" "-d :" "to enable debug mode." - printf "%20s %s\n" "-s :" "to manually pass MKL as your blas vendor." + printf "%20s %s\n" "-s :" "to manually pass MKL as your bla vendor." + printf "%20s %s\n" "-p :" "to enable a packaging system for distribution." printf "%20s %s\n" "-h :" "Help." echo "" exit 1 @@ -113,21 +140,33 @@ if [ -z "$USE_MPI" ]; then echo -e "${RED}Using MPI disabled${NC}" fi +if [ "$SHOW_WARNINGS" = "ON" ]; then + COMPILE_FLAGS+=" -W" + DEVELOPER_WARNINGS="" +elif [ "$SHOW_WARNINGS" = "OFF" ]; then + COMPILE_FLAGS+=" -w" +fi + echo "" echo -e "${YELLOW}Use -h to print the usages of exageostat-cpp flags.${NC}" echo "" rm -rf bin/ -mkdir -p bin/installdir +mkdir -p bin/ -cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ - -DEXAGEOSTAT_INSTALL_PREFIX="${INSTALL_PREFIX}" \ - -DEXAGEOSTAT_BUILD_TESTS="${BUILDING_TESTS}" \ - -DEXAGEOSTAT_BUILD_EXAMPLES="${BUILDING_EXAMPLES}" \ - -DEXAGEOSTAT_USE_HICMA="${USING_HiCMA}" \ +cmake "$DEVELOPER_WARNINGS" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ + -DCMAKE_BUILD_TYPE=RELEASE \ + -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" \ + -DBUILD_TESTS="${BUILDING_TESTS}" \ + -DBUILD_HEAVY_TESTS="${BUILDING_HEAVY_TESTS}" \ + -DBUILD_EXAMPLES="${BUILDING_EXAMPLES}" \ + -DUSE_HICMA="${USING_HiCMA}" \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=${VERBOSE} \ -DUSE_CUDA="${USE_CUDA}" \ -DUSE_MPI="${USE_MPI}" \ -DBLA_VENDOR="${BLAS_VENDOR}" \ + -DCREATE_PACKAGE="${PACKAGE}" \ -H"${PROJECT_SOURCE_DIR}" \ -B"${PROJECT_SOURCE_DIR}/bin" \ - -G "Unix Makefiles" + -G "Unix Makefiles" \ + -DCMAKE_CXX_FLAGS_DEBUG="$COMPILE_FLAGS"\ + -DCMAKE_CXX_FLAGS_RELEASE="$COMPILE_FLAGS" diff --git a/docs/config.in b/docs/config.in index 0cafddd5..70c8be38 100644 --- a/docs/config.in +++ b/docs/config.in @@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "ExaGeoStat CPP" +PROJECT_NAME = "ExaGeoStatCPP" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version @@ -44,7 +44,7 @@ PROJECT_NUMBER = # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = "ExaGeoStat is a parallel high performance unified framework for geostatistics on manycore systems." +PROJECT_BRIEF = "ExaGeoStatCPP is a parallel high performance unified framework for geostatistics on manycore systems." # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 @@ -68,7 +68,7 @@ OUTPUT_DIRECTORY = "bin" # performance problems for the file system. # The default value is: NO. -CREATE_SUBDIRS = NO +CREATE_SUBDIRS = YES # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII @@ -162,7 +162,7 @@ FULL_PATH_NAMES = NO # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. -STRIP_FROM_PATH = "@CMAKE_SOURCE_DIR@" +STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which @@ -367,7 +367,7 @@ DISTRIBUTE_GROUP_DOC = NO # is disabled and one has to add nested compounds explicitly via \ingroup. # The default value is: NO. -GROUP_NESTED_COMPOUNDS = YES +GROUP_NESTED_COMPOUNDS = NO # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that @@ -524,7 +524,7 @@ INTERNAL_DOCS = NO # and Mac users are advised to set this option to NO. # The default value is: system dependent. -CASE_SENSE_NAMES = NO +CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the @@ -790,10 +790,7 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = ../src/ \ ../inst/ - - - +INPUT = "../inst/include" + ../README.md # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -946,7 +943,7 @@ FILTER_SOURCE_PATTERNS = # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = "@CMAKE_CURRENT_SOURCE_DIR@/index.md" +USE_MDFILE_AS_MAINPAGE = ../README.md #--------------------------------------------------------------------------- # Configuration options related to source browsing @@ -959,7 +956,7 @@ USE_MDFILE_AS_MAINPAGE = "@CMAKE_CURRENT_SOURCE_DIR@/index.md" # also VERBATIM_HEADERS is set to NO. # The default value is: NO. -SOURCE_BROWSER = YES +SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. diff --git a/exageostatcppConfig.cmake.in b/exageostatcppConfig.cmake.in deleted file mode 100644 index b36a3e51..00000000 --- a/exageostatcppConfig.cmake.in +++ /dev/null @@ -1,67 +0,0 @@ - -# Copyright (c) 2017-2023 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). - -# defined since 2.8.3 -if (CMAKE_VERSION VERSION_LESS 2.8.3) - get_filename_component(CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) -endif () - -# Compute the installation prefix relative to this file. -get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) -get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) -get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) -get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) -if (_IMPORT_PREFIX STREQUAL "/") - set(_IMPORT_PREFIX "") -endif () - -set(USE_CUDA "@USE_CUDA@") -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Modules/cmake) - -set(ENV{PKG_CONFIG_PATH} "${_IMPORT_PREFIX}/lib/pkgconfig:$ENV{PKG_CONFIG_PATH}") -include_directories(${_IMPORT_PREFIX}/include) -link_directories(${_IMPORT_PREFIX}/lib) -set(BLA_PREFER_PKGCONFIG "ON") - -if (USE_CUDA) - message("-- Exageostat-cpp built CUDA Support") - find_package(CUDAToolkit REQUIRED) - find_package(BLAS REQUIRED) - find_package(blaspp REQUIRED) - unset(BLA_VENDOR) - find_package(LAPACK REQUIRED) -else () - message("-- Exageostat-cpp built x86 Support") - set(gpu_backend CACHE "none" FORCE) - find_package(blaspp REQUIRED) - find_package(lapackpp REQUIRED) -endif () - -# Add component-configs. -include("${CMAKE_CURRENT_LIST_DIR}/exageostat-cppConfig.cmake") - -# Compute the installation prefix relative to this file. -get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH) -get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) -get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) -get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH) -if (_IMPORT_PREFIX STREQUAL "/") - set(_IMPORT_PREFIX "") -endif () -set(exageostatcpp_LIBRARIES exageostatcpp) -set(exageostatcpp_LIBRARY_DIRS "${_IMPORT_PREFIX}/lib") -set(exageostatcpp_INCLUDE_DIRS "${_IMPORT_PREFIX}/include") - -find_package_handle_standard_args(exageostatcpp - NAME_MISMATCHED - REQUIRED_VARS exageostatcpp_INCLUDE_DIRS exageostatcpp_LIBRARY_DIRS exageostatcpp_LIBRARIES - VERSION_VAR exageostatcpp_VERSION - ) - -# Cleanup temporary variables. -set(_IMPORT_PREFIX) -if (CMAKE_VERSION VERSION_LESS 2.8.3) - set(CMAKE_CURRENT_LIST_DIR) -endif () diff --git a/examples/configurations/CMakeLists.txt b/examples/configurations/CMakeLists.txt index 769ba295..7c68b9ee 100644 --- a/examples/configurations/CMakeLists.txt +++ b/examples/configurations/CMakeLists.txt @@ -5,12 +5,14 @@ # @file CMakeLists.txt # @brief Defines an executable and links it with the ExaGeoStat library and other libraries. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @date 2023-01-31 -# Define an executable named "Example_Synthetic_Data_Configurations". -add_executable(Example_Synthetic_Data_Configurations ${CMAKE_CURRENT_SOURCE_DIR}/ConfigurationModule.cpp) +# Define an executable named "Example_Configurations". +add_executable(Example_Configurations_Setup ${CMAKE_CURRENT_SOURCE_DIR}/SetupConfigurations.cpp) +add_executable(Example_Different_Configurations_Running ${CMAKE_CURRENT_SOURCE_DIR}/RunningWithDifferentConfigurations.cpp) # Link the executable with the ExaGeoStat library and other libraries. -target_link_libraries(Example_Synthetic_Data_Configurations ${PROJECT_NAME}_INTERFACE) \ No newline at end of file +target_link_libraries(Example_Configurations_Setup ${PROJECT_NAME}_INTERFACE) +target_link_libraries(Example_Different_Configurations_Running ${PROJECT_NAME}_INTERFACE) \ No newline at end of file diff --git a/examples/configurations/RunningWithDifferentConfigurations.cpp b/examples/configurations/RunningWithDifferentConfigurations.cpp new file mode 100644 index 00000000..f8d8c94f --- /dev/null +++ b/examples/configurations/RunningWithDifferentConfigurations.cpp @@ -0,0 +1,75 @@ + +// Copyright (c) 2017-2023 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 RunningWithDifferentConfigurations.cpp + * @brief Demonstrates running ExaGeoStat with various configurations. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @date 2024-01-04 +**/ + +#include +#include + +using namespace exageostat::configurations; +using namespace exageostat::api; +using namespace exageostat::hardware; +using namespace exageostat::dataunits; + +/** + * @brief Main entry point for the Data Generation & Data Modeling program. + * @details + * @return An integer indicating the success or failure of the program. + */ +int main() { + + // Create a new configurations object. + Configurations configurations; + int N = 16; + configurations.SetProblemSize(N); + configurations.SetKernelName("UnivariateMaternStationary"); + configurations.SetDenseTileSize(9); + configurations.SetMaxMleIterations(10); + configurations.SetTolerance(4); + std::vector lb{0.1, 0.1, 0.1}; + configurations.SetLowerBounds(lb); + + std::vector ub{5, 5, 5}; + configurations.SetUpperBounds(ub); + + std::vector initial_theta{1, 0.1, 0.5}; + configurations.SetInitialTheta(initial_theta); + + // Initialize the ExaGeoStat Hardware + auto hardware = ExaGeoStatHardware(configurations.GetComputation(), configurations.GetCoresNumber(), + configurations.GetGPUsNumbers()); + // Load data by either read from file or create synthetic data. + std::unique_ptr> data; + ExaGeoStat::ExaGeoStatLoadData(hardware, configurations, data); + // Modeling module. + ExaGeoStat::ExaGeoStatDataModeling(hardware, configurations, data); + + LOGGER("") + LOGGER("ANOTHER CONFIGURATIONS\n") + // Create a new configurations object. + Configurations configurations2; + N = 10; + configurations2.SetProblemSize(N); + configurations2.SetKernelName("UnivariateMaternStationary"); + configurations2.SetDenseTileSize(5); + configurations2.SetMaxMleIterations(2); + configurations2.SetTolerance(3); + configurations2.SetLowerBounds(lb); + configurations2.SetUpperBounds(ub); + configurations2.SetInitialTheta(initial_theta); + + // Load data by either read from file or create synthetic data. + ExaGeoStat::ExaGeoStatLoadData(hardware, configurations2, data); + // Modeling module. + ExaGeoStat::ExaGeoStatDataModeling(hardware, configurations2, data); + + return 0; +} diff --git a/examples/configurations/ConfigurationModule.cpp b/examples/configurations/SetupConfigurations.cpp similarity index 88% rename from examples/configurations/ConfigurationModule.cpp rename to examples/configurations/SetupConfigurations.cpp index 975b0897..bb1f3c4e 100644 --- a/examples/configurations/ConfigurationModule.cpp +++ b/examples/configurations/SetupConfigurations.cpp @@ -4,10 +4,10 @@ // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** -* @file ConfigurationsMain.cpp +* @file SetupConfigurations.cpp * @brief Demonstrates how to use the Configurations class from the ExaGeoStat software package. * @details This file demonstrates how to use the Configurations class from the ExaGeoStat software package -* to obtain user-defined configurations for generating synthetic data. +* to obtain user-defined configurations. * @version 1.0.0 * @author Mahmoud ElKarargy * @date 2023-01-31 @@ -27,8 +27,8 @@ using namespace exageostat::configurations; /** * @brief The main function of the program. * - * This function demonstrates how to use the SyntheticDataConfigurations class from the ExaGeoStat software package - * to obtain user-defined configurations for generating synthetic data. + * This function demonstrates how to use the Configurations class from the ExaGeoStat software package + * to obtain user-defined configurations. * * @param[in] argc The number of command line arguments. * @param[in] argv The command line arguments. @@ -36,12 +36,11 @@ using namespace exageostat::configurations; */ int main(int argc, char **argv) { - // Create an instance of the SyntheticDataConfigurations class with user-defined configurations. + // Create an instance of the Configurations class with user-defined configurations. Configurations configurations; configurations.InitializeArguments(argc, argv); LOGGER("** These are some examples of the common arguments needed between all modules of ExaGeoStat **") - // Obtain user-defined configurations and print them to the console. int n = configurations.GetProblemSize(); if (n != 0) { @@ -101,5 +100,6 @@ int main(int argc, char **argv) { } VERBOSE("VERBOSE ACTIVATED") + return 0; } \ No newline at end of file diff --git a/examples/data-generators/SyntheticDataGeneration.cpp b/examples/data-generators/SyntheticDataGeneration.cpp index 1c4323df..e9fa1465 100644 --- a/examples/data-generators/SyntheticDataGeneration.cpp +++ b/examples/data-generators/SyntheticDataGeneration.cpp @@ -6,7 +6,7 @@ /** * @file SyntheticLocationsGeneration.cpp * @brief This file contains the main function for generating synthetic Locations for ExaGeoStat - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-03-04 **/ @@ -43,14 +43,15 @@ int main(int argc, char **argv) { synthetic_data_configurations.GetCoresNumber(), synthetic_data_configurations.GetGPUsNumbers()); - Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create(synthetic_data_configurations.GetKernelName()); + Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create( + synthetic_data_configurations.GetKernelName(), synthetic_data_configurations.GetTimeSlot()); // Create a unique pointer to a DataGenerator object unique_ptr> synthetic_generator = DataGenerator::CreateGenerator( synthetic_data_configurations); // Initialize the locations of the generated data - auto data = *synthetic_generator->CreateData(synthetic_data_configurations, hardware, *pKernel); + auto data = synthetic_generator->CreateData(synthetic_data_configurations, hardware, *pKernel); // Define a struct to hold pointers to the x, y, and z coordinates of the generated data struct DataPointers { double *x; @@ -59,9 +60,9 @@ int main(int argc, char **argv) { } data_pointers{}; // Set the pointers in the DataPointers struct to the location coordinates of the generated data - data_pointers.x = data.GetLocations()->GetLocationX(); - data_pointers.y = data.GetLocations()->GetLocationY(); - data_pointers.z = data.GetLocations()->GetLocationZ(); + data_pointers.x = data->GetLocations()->GetLocationX(); + data_pointers.y = data->GetLocations()->GetLocationY(); + data_pointers.z = data->GetLocations()->GetLocationZ(); // Print the generated location coordinates LOGGER("Generated Data ...") @@ -76,7 +77,9 @@ int main(int argc, char **argv) { if (synthetic_data_configurations.GetDimension() != Dimension2D) { LOGGER_PRECISION(" Z: " << data_pointers.z[i], 18) } - LOGGER_PRECISION(" Measurements: " << ((double *)data.GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, exageostat::common::DESCRIPTOR_Z).chameleon_desc->mat)[i] << "\n" , 18) + LOGGER_PRECISION(" Measurements: " << ((double *) data->GetDescriptorData()->GetDescriptor( + exageostat::common::CHAMELEON_DESCRIPTOR, exageostat::common::DESCRIPTOR_Z).chameleon_desc->mat)[i] + << "\n", 18) } delete pKernel; diff --git a/examples/data-generators/SyntheticLocationsGeneration.cpp b/examples/data-generators/SyntheticLocationsGeneration.cpp deleted file mode 100644 index cb9b7880..00000000 --- a/examples/data-generators/SyntheticLocationsGeneration.cpp +++ /dev/null @@ -1,80 +0,0 @@ - -// Copyright (c) 2017-2023 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 SyntheticLocationsGeneration.cpp - * @brief This file contains the main function for generating synthetic Locations for ExaGeoStat - * @version 1.0.0 - * @author Mahmoud ElKarargy - * @date 2023-03-04 -**/ - -#include - -#include -#include - -using namespace std; - -using namespace exageostat::configurations; -using namespace exageostat::generators; -using namespace exageostat::common; -using namespace exageostat::hardware; - -/** - * @brief The main function of the program. - * @details This function generates synthetic data for ExaGeoStat using the provided command line arguments. - * @param[in] argc The number of command line arguments. - * @param[in] argv The command line arguments. - * @return The status code of the program. - */ - -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); - - // initialize ExaGeoStat Hardware. - auto hardware = ExaGeoStatHardware(synthetic_data_configurations.GetComputation(), - synthetic_data_configurations.GetCoresNumber(), - synthetic_data_configurations.GetGPUsNumbers()); - - // Create a unique pointer to a DataGenerator object - unique_ptr> synthetic_generator = DataGenerator::CreateGenerator( - synthetic_data_configurations); - - // Initialize the locations of the generated data - auto *locations = synthetic_generator->CreateLocationsData(synthetic_data_configurations); - - // Define a struct to hold pointers to the x, y, and z coordinates of the generated data - struct DataPointers { - double *x; - double *y; - double *z; - } data_pointers{}; - - // Set the pointers in the DataPointers struct to the location coordinates of the generated data - data_pointers.x = locations->GetLocationX(); - data_pointers.y = locations->GetLocationY(); - data_pointers.z = locations->GetLocationZ(); - - // Print the generated location coordinates - LOGGER("Generated Locations are .. ") - int timeSlot; - if (synthetic_data_configurations.GetDimension() != DimensionST) { - timeSlot = 1; - } else { - timeSlot = synthetic_data_configurations.GetTimeSlot(); - } - for (auto i = 0; i < synthetic_data_configurations.GetProblemSize() * timeSlot; i++) { - LOGGER_PRECISION("X: " << data_pointers.x[i] << " Y: " << data_pointers.y[i], 18) - if (synthetic_data_configurations.GetDimension() != Dimension2D) { - LOGGER_PRECISION(" Z: " << data_pointers.z[i], 18) - } - LOGGER("\n") - } - return 0; -} \ No newline at end of file diff --git a/examples/end-to-end/DataGeneration.cpp b/examples/end-to-end/DataGeneration.cpp index 5d3ad6b0..cc454722 100644 --- a/examples/end-to-end/DataGeneration.cpp +++ b/examples/end-to-end/DataGeneration.cpp @@ -7,7 +7,7 @@ * @file DataGeneration.cpp * @brief This program either generates synthetic data using the ExaGeoStat library, or reads an CSV file containing real data. * @details The program takes command line arguments to configure the data generation. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-05-30 **/ @@ -33,14 +33,12 @@ int main(int argc, char **argv) { Configurations configurations; // Initialize the arguments with the provided command line arguments configurations.InitializeArguments(argc, argv); - LOGGER("** initialize ExaGeoStat hardware ** ") + // Initialize the ExaGeoStat Hardware auto hardware = ExaGeoStatHardware(configurations.GetComputation(), configurations.GetCoresNumber(), configurations.GetGPUsNumbers()); - LOGGER("** Create ExaGeoStat data **") - ExaGeoStatData data; - LOGGER("** Generate ExaGeoStat data ** ") + // Load data by either read from file or create synthetic data. + std::unique_ptr> data; ExaGeoStat::ExaGeoStatLoadData(hardware, configurations, data); - LOGGER("** All example stages have been completed successfully ** ") return 0; } \ No newline at end of file diff --git a/examples/end-to-end/DataGenerationAndModeling.cpp b/examples/end-to-end/DataGenerationAndModeling.cpp index 0b70d8a3..caf00a63 100644 --- a/examples/end-to-end/DataGenerationAndModeling.cpp +++ b/examples/end-to-end/DataGenerationAndModeling.cpp @@ -7,7 +7,7 @@ * @file DataGenerationAndModeling.cpp * @brief This program either generates synthetic data using the ExaGeoStat library, or reads an CSV file. * @details The program takes command line arguments to configure the data generation. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-06-21 **/ @@ -33,16 +33,14 @@ int main(int argc, char **argv) { Configurations configurations; // Initialize the arguments with the provided command line arguments configurations.InitializeArguments(argc, argv); - LOGGER("** initialize ExaGeoStat hardware ** ") + // Initialize the ExaGeoStat Hardware auto hardware = ExaGeoStatHardware(configurations.GetComputation(), configurations.GetCoresNumber(), configurations.GetGPUsNumbers()); - LOGGER("** Create ExaGeoStat data **") - ExaGeoStatData data; - LOGGER("** ExaGeoStat data generation ** ") + // Load data by either read from file or create synthetic data. + std::unique_ptr> data; ExaGeoStat::ExaGeoStatLoadData(hardware, configurations, data); - LOGGER("** ExaGeoStat data Modeling ** ") + // Modeling module. ExaGeoStat::ExaGeoStatDataModeling(hardware, configurations, data); - LOGGER("** All example stages have been completed successfully ** ") return 0; } diff --git a/examples/end-to-end/DataGenerationModelingAndPrediction.cpp b/examples/end-to-end/DataGenerationModelingAndPrediction.cpp index a1ec90ea..ef39d133 100644 --- a/examples/end-to-end/DataGenerationModelingAndPrediction.cpp +++ b/examples/end-to-end/DataGenerationModelingAndPrediction.cpp @@ -7,7 +7,7 @@ * @file DataGenerationModelingAndPrediction.cpp * @brief This program This program either generates synthetic data using the ExaGeoStat library, or reads an CSV file containing real data, performs data modeling on loaded data, then predicts missing measurements using the ExaGeoStat library. * @details The program takes command line arguments to configure the data generation. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-06-21 **/ @@ -31,19 +31,18 @@ int main(int argc, char **argv) { // Create a new configurations object. Configurations configurations; - // Initialize the arguments with the provided command line arguments + // Initialize the arguments with the provided command line arguments configurations.InitializeArguments(argc, argv); - LOGGER("** Initialise ExaGeoStat hardware **") + // Initialize the ExaGeoStat Hardware auto hardware = ExaGeoStatHardware(configurations.GetComputation(), configurations.GetCoresNumber(), configurations.GetGPUsNumbers()); - LOGGER("** Create ExaGeoStat data **") - ExaGeoStatData data; - LOGGER("** ExaGeoStat data generation **") + // Load data by either read from file or create synthetic data. + std::unique_ptr> data; ExaGeoStat::ExaGeoStatLoadData(hardware, configurations, data); - LOGGER("** ExaGeoStat data Modeling **") + // Modeling module. ExaGeoStat::ExaGeoStatDataModeling(hardware, configurations, data); - LOGGER("** ExaGeoStat data Prediction **") + // Prediction module ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data); - LOGGER("** All example stages have been completed successfully ** ") + return 0; } diff --git a/examples/end-to-end/DataModeling.cpp b/examples/end-to-end/DataModeling.cpp index 76706ea8..6a4b3fb2 100644 --- a/examples/end-to-end/DataModeling.cpp +++ b/examples/end-to-end/DataModeling.cpp @@ -7,7 +7,7 @@ * @file DataModeling.cpp * @brief This program models data using the ExaGeoStat library. * @details The program takes command line arguments and example variables to configure the data modeling. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-06-21 **/ @@ -47,13 +47,11 @@ int main(int argc, char **argv) { configurations.SetDenseTileSize(dts); // initialize ExaGeoStat hardware with the selected number of cores and gpus. - LOGGER("** initialize ExaGeoStat hardware ** ") auto hardware = ExaGeoStatHardware(configurations.GetComputation(), configurations.GetCoresNumber(), configurations.GetGPUsNumbers()); //Data Setup - LOGGER("** Create ExaGeoStat data ** ") - ExaGeoStatData data(configurations.GetProblemSize(), configurations.GetDimension()); + std::unique_ptr> data = std::make_unique>(configurations.GetProblemSize(), configurations.GetDimension()); // Initiating the matrix of the CHAMELEON Descriptor Z. auto *z_matrix = new double[N]{-1.272336140360187606, -2.590699695867695773, 0.512142584178685967, @@ -77,15 +75,16 @@ int main(int argc, char **argv) { 0.573571374074921758, 0.568657969024185528, 0.935835812924391552, 0.942824444953078489}; - data.GetLocations()->SetLocationX(*location_x, N); - data.GetLocations()->SetLocationY(*location_y, N); + data->GetLocations()->SetLocationX(*location_x, N); + data->GetLocations()->SetLocationY(*location_y, N); - LOGGER("** ExaGeoStat Data Modeling ** ") + // Modeling module. ExaGeoStat::ExaGeoStatDataModeling(hardware, configurations, data, z_matrix); - LOGGER("** All example stages have been completed successfully ** ") + // Freeing the allocated memory. delete[] z_matrix; delete[] location_x; delete[] location_y; + return 0; } diff --git a/examples/end-to-end/DataPrediction.cpp b/examples/end-to-end/DataPrediction.cpp index 9e51f737..2f681566 100644 --- a/examples/end-to-end/DataPrediction.cpp +++ b/examples/end-to-end/DataPrediction.cpp @@ -7,7 +7,7 @@ * @file DataPrediction.cpp * @brief This program predicts missing measurements using the ExaGeoStat library. * @details The program takes command line arguments to configure the data prediction module. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-09-11 **/ @@ -44,13 +44,11 @@ int main(int argc, char **argv) { configurations.SetDenseTileSize(dts); // initialize ExaGeoStat hardware with the selected number of cores and gpus. - LOGGER("** Initialise ExaGeoStat hardware **") auto hardware = ExaGeoStatHardware(configurations.GetComputation(), configurations.GetCoresNumber(), configurations.GetGPUsNumbers()); //Data Setup - LOGGER("** Create ExaGeoStat data **") - ExaGeoStatData data(configurations.GetProblemSize(), configurations.GetDimension()); + std::unique_ptr> data = std::make_unique>(configurations.GetProblemSize(), configurations.GetDimension()); //creating locations x and y. auto *location_x = new double[N]{0.193041886015106440, 0.330556191348134576, 0.181612878614480805, @@ -75,15 +73,15 @@ int main(int argc, char **argv) { 0.971213790000161170, 0.538973474182433021, -0.752828466476077041, 0.290822066007430102}; - data.GetLocations()->SetLocationX(*location_x, N); - data.GetLocations()->SetLocationY(*location_y, N); + data->GetLocations()->SetLocationX(*location_x, N); + data->GetLocations()->SetLocationY(*location_y, N); - LOGGER("** ExaGeoStat data Prediction **") + // Prediction module ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data, z_matrix); - LOGGER("** All example stages have been completed successfully **") delete[] location_x; delete[] location_y; delete[] z_matrix; + return 0; } \ No newline at end of file diff --git a/inst/include/api/ExaGeoStat.hpp b/inst/include/api/ExaGeoStat.hpp index 7de91beb..338713be 100644 --- a/inst/include/api/ExaGeoStat.hpp +++ b/inst/include/api/ExaGeoStat.hpp @@ -6,7 +6,7 @@ /** * @file ExaGeoStat.hpp * @brief High-Level Wrapper class containing the static API for ExaGeoStat operations. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-05-30 **/ @@ -41,7 +41,7 @@ namespace exageostat::api { */ static void ExaGeoStatLoadData(const hardware::ExaGeoStatHardware &aHardware, configurations::Configurations &aConfigurations, - dataunits::ExaGeoStatData &aData); + std::unique_ptr> &aData); /** * @brief Models Data whether it's synthetic data or real. @@ -49,12 +49,12 @@ namespace exageostat::api { * @param[in] aConfigurations Reference to Configurations object containing user input data. * @param[in] aData Reference to an ExaGeoStatData object containing needed descriptors, and locations. * @param[in] apMeasurementsMatrix Pointer to the user input measurements matrix. - * @return void + * @return the last optimum value of MLE. * */ static T ExaGeoStatDataModeling(const hardware::ExaGeoStatHardware &aHardware, configurations::Configurations &aConfigurations, - exageostat::dataunits::ExaGeoStatData &aData, + std::unique_ptr> &aData, T *apMeasurementsMatrix = nullptr); @@ -77,7 +77,7 @@ namespace exageostat::api { */ static void ExaGeoStatPrediction(const hardware::ExaGeoStatHardware &aHardware, configurations::Configurations &aConfigurations, - exageostat::dataunits::ExaGeoStatData &aData, + std::unique_ptr> &aData, T *apMeasurementsMatrix = nullptr); private: diff --git a/inst/include/common/Definitions.hpp b/inst/include/common/Definitions.hpp index 406e44c4..e7507436 100644 --- a/inst/include/common/Definitions.hpp +++ b/inst/include/common/Definitions.hpp @@ -5,7 +5,7 @@ /** * @file Definitions.hpp - * @version 1.0.0 + * @version 1.0.1 * @brief This file contains common definitions used in ExaGeoStat software package. * @details These definitions include enums for dimension, computation, precision, and floating point arithmetic; * A macro for instantiating template classes with supported types; and a set of available kernels. @@ -127,6 +127,15 @@ namespace exageostat::common { HICMA_DESCRIPTOR = 1 }; + /** + * @enum Data source Type + * @brief Enum denoting the data source Type. + */ + enum DataSourceType { + SYNTHETIC = 0, + CSV_FILE = 1 + }; + /** * @enum Descriptor Name * @brief Enum denoting all Descriptors Names. @@ -184,6 +193,9 @@ namespace exageostat::common { DESCRIPTOR_C_DIAG = 49, DESCRIPTOR_A = 50, DESCRIPTOR_RESULTS = 51, + DESCRIPTOR_SUM = 52, + DESCRIPTOR_R = 53, + DESCRIPTOR_R_COPY = 54, }; /** @@ -246,6 +258,16 @@ namespace exageostat::common { EXAGEOSTAT_UPPER_LOWER = 123 /**< Use the full A */ }; + /** + * @enum CopyDirection + * @brief Enum denoting the copy descriptors flow + * + */ + enum CopyDirection : int { + CHAMELEON_TO_HICMA = 0, + HICMA_TO_CHAMELEON = 1 + }; + /** * @var availableKernels * @brief Set denoting the available kernels supported in matrix generation. diff --git a/inst/include/common/PluginRegistry.hpp b/inst/include/common/PluginRegistry.hpp index b0ba4f6e..23df532f 100644 --- a/inst/include/common/PluginRegistry.hpp +++ b/inst/include/common/PluginRegistry.hpp @@ -6,7 +6,7 @@ /** * @file PluginRegistry.hpp * @brief Defines a template class for registering and creating plugins. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-04-30 **/ @@ -25,6 +25,8 @@ #include #include +#include + namespace exageostat::plugins { /** * @brief Template class for registering and creating plugins. @@ -68,13 +70,17 @@ namespace exageostat::plugins { * @return A pointer to the created plugin, or nullptr if the plugin could not be created. * */ - static T *Create(const std::string &aName) { + static T *Create(const std::string &aName, const int& aTimeSlot) { auto map = GetFactoryMap(); if (map.find(aName) == map.end()) { return nullptr; } - return map[aName](); + // Get the object from the map. + T* object = map[aName](); + // Automatically set the new P value which will get updated with the user input of P. + object->SetPValue(aTimeSlot); + return object; } private: diff --git a/inst/include/configurations/Configurations.hpp b/inst/include/configurations/Configurations.hpp index 4c69a9b1..1c7658a4 100644 --- a/inst/include/configurations/Configurations.hpp +++ b/inst/include/configurations/Configurations.hpp @@ -5,7 +5,7 @@ /** * @file Configurations.hpp -* @version 1.0.0 +* @version 1.0.1 * @brief Contains the declaration of the Configurations class and its member functions. * @author Sameh Abdulah * @author Mahmoud ElKarargy @@ -75,10 +75,10 @@ namespace exageostat::configurations { Configurations(); /** - * @brief Virtual destructor to allow calls to the correct concrete destructor. + * @brief destructor to allow calls to the correct concrete destructor. * */ - virtual ~Configurations() = default; + ~Configurations() = default; /** * @brief Initialize the module arguments. @@ -206,10 +206,6 @@ namespace exageostat::configurations { CREATE_GETTER_FUNCTION(Logger, bool, "Logger") - CREATE_SETTER_FUNCTION(P, int, aP, "P") - - CREATE_GETTER_FUNCTION(P, int, "P") - CREATE_SETTER_FUNCTION(MeanSquareError, double, aMeanSquareError, "MeanSquareError") CREATE_GETTER_FUNCTION(MeanSquareError, double, "MeanSquareError") @@ -230,6 +226,10 @@ namespace exageostat::configurations { CREATE_GETTER_FUNCTION(StartingTheta, std::vector &, "StartingTheta") + CREATE_SETTER_FUNCTION(IsNonGaussian, bool, aIsNonGaussian, "IsNonGaussian") + + CREATE_GETTER_FUNCTION(IsNonGaussian, bool, "IsNonGaussian") + /** * @brief Getter for the verbosity. * @return The verbosity mode. @@ -393,9 +393,6 @@ namespace exageostat::configurations { private: - /// static bool to make sure that print summary is only performed once. - static bool mIsPrinted; - /** * @brief Checks the run mode and sets the verbosity level. * @param[in] aVerbosity A string representing the desired run mode ("verbose" or "standard"). diff --git a/inst/include/data-generators/DataGenerator.hpp b/inst/include/data-generators/DataGenerator.hpp index e0c167cb..14cdf110 100644 --- a/inst/include/data-generators/DataGenerator.hpp +++ b/inst/include/data-generators/DataGenerator.hpp @@ -6,7 +6,7 @@ /** * @file DataGenerator.hpp * @brief Contains definition for abstract Data Generator Class. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-02-14 **/ @@ -14,8 +14,6 @@ #ifndef EXAGEOSTAT_CPP_DATAGENERATOR_HPP #define EXAGEOSTAT_CPP_DATAGENERATOR_HPP -#include - #include #include @@ -37,10 +35,11 @@ namespace exageostat::generators { * @details This method generates the X, Y, and Z variables used to define the locations of the data points. * @param[in] aConfigurations Reference to the data configurations. * @param[in] aHardware Reference to the used hardware. - * @return Pointer to a populated data. + * @param[in] aKernel Reference to the used Kernel. + * @return unique Pointer to a populated data. * */ - virtual dataunits::ExaGeoStatData * + virtual std::unique_ptr> CreateData(exageostat::configurations::Configurations &aConfigurations, const exageostat::hardware::ExaGeoStatHardware &aHardware, exageostat::kernels::Kernel &aKernel) = 0; @@ -63,10 +62,8 @@ namespace exageostat::generators { virtual ~DataGenerator(); protected: - /// Used bool identifying type of generation. - static bool mIsSynthetic; - /// Used bool identifying type of generation. - static bool mIsCSV; + /// Used enum for data generators types. + static common::DataSourceType aDataSourceType; }; /** diff --git a/inst/include/data-generators/LocationGenerator.hpp b/inst/include/data-generators/LocationGenerator.hpp new file mode 100644 index 00000000..a041e1e6 --- /dev/null +++ b/inst/include/data-generators/LocationGenerator.hpp @@ -0,0 +1,73 @@ + +// Copyright (c) 2017-2023 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 LocationGenerator.hpp + * @brief Generates and manages spatial locations for ExaGeoStat. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @date 2024-02-04 +**/ + +#ifndef EXAGEOSTATCPP_LOCATIONGENERATOR_HPP +#define EXAGEOSTATCPP_LOCATIONGENERATOR_HPP + +#include +#include + +namespace exageostat::generators { + + /** + * @class LocationGenerator + * @brief Generates spatial locations based on given parameters. + * @tparam T Data Type: float or double + * + */ + template + class LocationGenerator { + + public: + + /** + * @brief Generates the data locations. + * @details This method generates the X, Y, and Z variables used to define the locations of the data points. + * @param[in] aN The number of data points. + * @param[in] aTimeSlot The time slot. + * @param[in] aDimension The dimension of the locations. + * @param[out] aLocations Reference to the Locations object where the generated data will be stored. + * @return void + * + */ + static void GenerateLocations(const int &aN, const int &aTimeSlot, const common::Dimension &aDimension, dataunits::Locations &aLocations); + + /** + * @brief Generate uniform distribution between rangeLow , rangeHigh. + * @param[in] aRangeLow The Lower range. + * @param[in] aRangeHigh The Higher range. + * @return The scaled uniform distribution between the two bounds. + * + */ + static T UniformDistribution(const T &aRangeLow, const T &aRangeHigh); + + /** + * @brief Sort locations in Morton order (input points must be in [0;1]x[0;1] square]). + * @param[in] aN The problem size divided by P-Grid. + * @param[in] aDimension Dimension of locations. + * @param[in,out] aLocations Locations to be sorted. + * @return void + * + */ + static void SortLocations(const int &aN, const common::Dimension &aDimension, dataunits::Locations &aLocations); + }; + + /** + * @brief Instantiates the Data Generator class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(LocationGenerator) +}//namespace exageostat + +#endif //EXAGEOSTATCPP_LOCATIONGENERATOR_HPP diff --git a/inst/include/data-generators/concrete/CSVDataGenerator.hpp b/inst/include/data-generators/concrete/CSVDataGenerator.hpp deleted file mode 100644 index 5ad3e266..00000000 --- a/inst/include/data-generators/concrete/CSVDataGenerator.hpp +++ /dev/null @@ -1,98 +0,0 @@ - -// Copyright (c) 2017-2023 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 CSVDataGenerator.hpp - * @brief A class for generating synthetic data. - * @version 1.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @date 2023-02-14 -**/ - -#ifndef EXAGEOSTAT_CPP_CSVDATAGENERATOR_HPP -#define EXAGEOSTAT_CPP_CSVDATAGENERATOR_HPP - -#include - -namespace exageostat::generators::csv { - - /** - * @class CSVDataGenerator - * @brief A class for creating data by reading CSV files. - * @tparam T Data Type: float or double - */ - template - class CSVDataGenerator : public DataGenerator { - public: - - /** - * @brief Get a pointer to the singleton instance of the CSVDataGenerator class. - * @return A pointer to the instance of the CSVDataGenerator class. - * - */ - static CSVDataGenerator *GetInstance(); - - /** - * @brief Creates the data by reading a CSV file. - * @copydoc DataGenerator::CreateData() - * - */ - dataunits::ExaGeoStatData * - CreateData(exageostat::configurations::Configurations &, - const exageostat::hardware::ExaGeoStatHardware &aHardware, - exageostat::kernels::Kernel &aKernel) override; - - /** - * @brief Reads CSV files containing 2D, 3D, or ST locations, and measurements vector. - * @param aConfigurations Reference to the Configurations object. - * @param aMeasurementsMatrix Reference to the Measurement matrix to be filled with read data. - * @param aXLocations Reference to the location's x coordinates matrix to be filled with read data. - * @param aYLocations Reference to the location's y coordinates matrix to be filled with read data. - * @param aZLocations Reference to the location's z coordinates matrix to be filled with read data. - * @return void - */ - void - ReadData(exageostat::configurations::Configurations &aConfigurations, std::vector &aMeasurementsMatrix, - std::vector &aXLocations, - std::vector &aYLocations, std::vector &aZLocations); - - /** - * @brief Release the singleton instance of the CSVDataGenerator class. - * @return void - * - */ - static void ReleaseInstance(); - - private: - /** - * @brief Constructor for the CSVDataGenerator class. - * @return void - * - */ - CSVDataGenerator() = default; - - /** - * @brief Default destructor. - * - */ - ~CSVDataGenerator() override = default; - - /** - * @brief Pointer to the singleton instance of the CSVDataGenerator class. - * - */ - static CSVDataGenerator *mpInstance; - - }; - - /** - * @brief Instantiates the CSV Data Generator class for float and double types. - * @tparam T Data Type: float or double - * - */ - EXAGEOSTAT_INSTANTIATE_CLASS(CSVDataGenerator) -} -#endif //EXAGEOSTAT_CPP_CSVDATAGENERATOR_HPP \ No newline at end of file diff --git a/inst/include/data-generators/concrete/SyntheticGenerator.hpp b/inst/include/data-generators/concrete/SyntheticGenerator.hpp index a4d0aeae..fc9b507d 100644 --- a/inst/include/data-generators/concrete/SyntheticGenerator.hpp +++ b/inst/include/data-generators/concrete/SyntheticGenerator.hpp @@ -6,7 +6,7 @@ /** * @file SyntheticGenerator.hpp * @brief A class for generating synthetic data. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-02-14 @@ -38,74 +38,16 @@ namespace exageostat::generators::synthetic { */ static SyntheticGenerator *GetInstance(); - /** - * @brief Generates the data locations. - * @details This method generates the X, Y, and Z variables used to define the locations of the data points. - * @param[in] aN The number of data points. - * @param[in] aTimeSlot The time slot. - * @param[in] aDimension The dimension of the locations. - * @param[out] aLocations Reference to the Locations object where the generated data will be stored. - * @return void - * - */ - void GenerateLocations(const int &aN, const int &aTimeSlot, const common::Dimension &aDimension, - dataunits::Locations &aLocations); - /** * @brief Creates the data by synthetically generating it. * @copydoc DataGenerator::CreateData() * */ - dataunits::ExaGeoStatData * + std::unique_ptr> CreateData(exageostat::configurations::Configurations &aConfigurations, const exageostat::hardware::ExaGeoStatHardware &aHardware, exageostat::kernels::Kernel &aKernel) override; - /** - * @brief Generate uniform distribution between rangeLow , rangeHigh. - * @param[in] aRangeLow The Lower range. - * @param[in] aRangeHigh The Higher range. - * @return The scaled uniform distribution between the two bounds. - * - */ - static double UniformDistribution(const double &aRangeLow, const double &aRangeHigh); - - /** - * @brief Sort locations in Morton order (input points must be in [0;1]x[0;1] square]). - * @param[in] aN The problem size divided by P-Grid. - * @param[in] aDimension Dimension of locations. - * @param[in,out] aLocations Locations to be sorted. - * @return void - * - */ - void - SortLocations(const int &aN, const common::Dimension &aDimension, dataunits::Locations &aLocations); - - /** - * @brief Spread bits by three spaces. - * @param[in] aInputByte The input 64 bit to be spread. - * @return The byte after being spread. - * - */ - static uint64_t SpreadBits(uint64_t aInputByte); - - /** - * @brief Reverse Spread bits operation. - * @param[in] aInputByte The input spread 64 bit to be compacted. - * @return The byte after being compacted. - * - */ - static uint64_t ReverseSpreadBits(uint64_t aInputByte); - - /** - * @brief Compares two Unit64 values - * @param[in] aFirstValue Constant reference to the first input 64 bit value. - * @param[in] aSecondValue Constant reference to the second input 64 bit value. - * @return True if the second value is bigger than the first value, false otherwise. - * - */ - static bool CompareUint64(const uint64_t &aFirstValue, const uint64_t &aSecondValue); - /** * @brief Release the singleton instance of the SyntheticGenerator class. * @return void diff --git a/inst/include/data-loader/DataLoader.hpp b/inst/include/data-loader/DataLoader.hpp new file mode 100644 index 00000000..d9bd5d26 --- /dev/null +++ b/inst/include/data-loader/DataLoader.hpp @@ -0,0 +1,67 @@ + +// Copyright (c) 2017-2023 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 DataLoader.hpp + * @brief Manages data loading operations for ExaGeoStat. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-04 +**/ + +#ifndef EXAGEOSTATCPP_DATALOADER_HPP +#define EXAGEOSTATCPP_DATALOADER_HPP + +#include + +namespace exageostat::dataLoader { + + /** + * @class DataLoader + * @brief Extends DataGenerator to include data loading functionalities. + * @tparam T Data Type: float or double + * + */ + template + class DataLoader : public generators::DataGenerator { + + public: + + /** + * @brief Creates the data by synthetically generating it. + * @copydoc DataGenerator::CreateData() + * + */ + std::unique_ptr> + CreateData(exageostat::configurations::Configurations &aConfigurations, + const exageostat::hardware::ExaGeoStatHardware &aHardware, + exageostat::kernels::Kernel &aKernel) override; + + /** + * @brief Reads data from external sources into ExaGeoStat format. + * @param aConfigurations Configuration settings for data loading. + * @param aMeasurementsMatrix Vector to store measurement values. + * @param aXLocations Vector to store X coordinates of locations. + * @param aYLocations Vector to store Y coordinates of locations. + * @param aZLocations Vector to store Z coordinates of locations (if applicable). + * @param aP Partition index for distributed data loading. + */ + virtual void + ReadData(exageostat::configurations::Configurations &aConfigurations, std::vector &aMeasurementsMatrix, + std::vector &aXLocations, std::vector &aYLocations, std::vector &aZLocations, + const int &aP) = 0; + + }; + + /** + * @brief Instantiates the Synthetic Data Generator class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(DataLoader) +} // namespace exageostat + +#endif //EXAGEOSTATCPP_DATALOADER_HPP diff --git a/inst/include/data-loader/concrete/CSVLoader.hpp b/inst/include/data-loader/concrete/CSVLoader.hpp new file mode 100644 index 00000000..f2411178 --- /dev/null +++ b/inst/include/data-loader/concrete/CSVLoader.hpp @@ -0,0 +1,84 @@ + +// Copyright (c) 2017-2023 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 CSVLoader.hpp + * @brief A class for generating synthetic data. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-04 +**/ + +#ifndef EXAGEOSTAT_CPP_CSVDATALOADER_HPP +#define EXAGEOSTAT_CPP_CSVDATALOADER_HPP + +#include +#include + +namespace exageostat::dataLoader::csv { + + /** + * @class CSVLoader + * @brief A class for creating data by reading CSV files. + * @tparam T Data Type: float or double + */ + template + class CSVLoader : public DataLoader { + public: + + /** + * @brief Get a pointer to the singleton instance of the CSVLoader class. + * @return A pointer to the instance of the CSVLoader class. + * + */ + static CSVLoader *GetInstance(); + + /** + * @brief Reads data from external sources into ExaGeoStat format. + * @copydoc DataLoader::ReadData() + * + */ + void ReadData(exageostat::configurations::Configurations &aConfigurations, std::vector &aMeasurementsMatrix, + std::vector &aXLocations, std::vector &aYLocations, std::vector &aZLocations, + const int &aP) override; + + /** + * @brief Release the singleton instance of the CSVLoader class. + * @return void + * + */ + static void ReleaseInstance(); + + private: + /** + * @brief Constructor for the CSVLoader class. + * @return void + * + */ + CSVLoader() = default; + + /** + * @brief Default destructor. + * + */ + ~CSVLoader() override = default; + + /** + * @brief Pointer to the singleton instance of the CSVLoader class. + * + */ + static CSVLoader *mpInstance; + + }; + + /** + * @brief Instantiates the CSV Data Generator class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(CSVLoader) +} +#endif //EXAGEOSTAT_CPP_CSVDATALOADER_HPP \ No newline at end of file diff --git a/inst/include/data-units/DescriptorData.hpp b/inst/include/data-units/DescriptorData.hpp index 242f2ec1..cb5f549d 100644 --- a/inst/include/data-units/DescriptorData.hpp +++ b/inst/include/data-units/DescriptorData.hpp @@ -6,7 +6,7 @@ /** * @file DescriptorData.hpp * @brief Contains the definition of the DescriptorData class. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-07-18 @@ -26,7 +26,7 @@ namespace exageostat::dataunits { */ union BaseDescriptor { CHAM_desc_t *chameleon_desc; -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA HICMA_desc_t *hicma_desc; #endif }; @@ -49,14 +49,14 @@ namespace exageostat::dataunits { /** * @brief Destructor for DescriptorData. */ - virtual ~DescriptorData(); + ~DescriptorData(); /** * @brief Get the base descriptor. * @param[in] aDescriptorType The type of the descriptor. * @param[in] aDescriptorName The name of the descriptor. * @return The base descriptor. - * @throws std::runtime_error if the corresponding library is not enabled (EXAGEOSTAT_USE_CHAMELEON or EXAGEOSTAT_USE_HICMA). + * @throws std::runtime_error if the corresponding library is not enabled (USE_HICMA). */ BaseDescriptor GetDescriptor(const common::DescriptorType &aDescriptorType, const common::DescriptorName &aDescriptorName); @@ -89,7 +89,7 @@ namespace exageostat::dataunits { */ void SetRequest(void *apRequest); -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA /** * @brief Converts a CHAMELEON descriptor to a HICMA descriptor. @@ -118,20 +118,21 @@ namespace exageostat::dataunits { * @param[in] aN The number of columns in the sub-matrix. * @param[in] aP The number of rows in the complete matrix. * @param[in] aQ The number of columns in the complete matrix. + * @param[in] aValidOOC Boolean refer to whether this descriptor can be created with OOC technology or not, default is true * @return void - * @throws std::runtime_error if the corresponding library is not enabled (EXAGEOSTAT_USE_CHAMELEON or EXAGEOSTAT_USE_HICMA). + * @throws std::runtime_error if the corresponding library is not enabled (USE_HICMA). */ 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 int &aJ, const int &aM, const int &aN, const int &aP, const int &aQ, const bool &aValidOOC = true); /** * @brief Getter for the Descriptor matrix. * @param[in] aDescriptorType Type of the descriptor, whether it's CHAMELEON or HiCMA. * @param[in] apDescriptor Pointer to the descriptor. * @return pointer to the Descriptor matrix. - * @throws std::runtime_error if the corresponding library is not enabled (EXAGEOSTAT_USE_CHAMELEON or EXAGEOSTAT_USE_HICMA). + * @throws std::runtime_error if the corresponding library is not enabled (USE_HICMA). */ T *GetDescriptorMatrix(const common::DescriptorType &aDescriptorType, void *apDescriptor); diff --git a/inst/include/data-units/Locations.hpp b/inst/include/data-units/Locations.hpp index 032be1f9..ebfb558b 100644 --- a/inst/include/data-units/Locations.hpp +++ b/inst/include/data-units/Locations.hpp @@ -43,10 +43,10 @@ namespace exageostat::dataunits { Locations(const Locations &aLocations) = default; /** - * @brief Virtual destructor to allow calls to the correct concrete destructor. + * @brief destructor for Locations. * */ - virtual ~Locations(); + ~Locations(); /** * @brief Setter for LocationX. diff --git a/inst/include/data-units/ModelingDataHolders.hpp b/inst/include/data-units/ModelingDataHolders.hpp index b0efc0f7..a6f932ea 100644 --- a/inst/include/data-units/ModelingDataHolders.hpp +++ b/inst/include/data-units/ModelingDataHolders.hpp @@ -1,7 +1,7 @@ /** * @file ModelingDataHolders.hpp * @brief This file contains the definition of the mModelingData struct, which contains all the data needed for modeling. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-08-24 **/ @@ -18,7 +18,7 @@ namespace exageostat::dataunits { template struct mModelingData { /// ExaGeoStatData object containing needed descriptors, and locations. - dataunits::ExaGeoStatData *mpData; + std::unique_ptr> *mpData; /// Configurations object containing user input data. configurations::Configurations *mpConfiguration; /// Hardware configuration for the ExaGeoStat solver. @@ -36,7 +36,7 @@ namespace exageostat::dataunits { * @param aHardware The hardware configuration object. * @param aKernel The Kernel object. */ - mModelingData(dataunits::ExaGeoStatData &aData, configurations::Configurations &aConfiguration, + mModelingData(std::unique_ptr> &aData, configurations::Configurations &aConfiguration, const hardware::ExaGeoStatHardware &aHardware, T &aMatrix, const kernels::Kernel &aKernel) : mpData(std::move(&aData)), mpConfiguration(&aConfiguration), mpHardware(&aHardware), mpMeasurementsMatrix(&aMatrix), mpKernel(&aKernel) {} diff --git a/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp b/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp index ab82aeb5..bfc85a6e 100644 --- a/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp +++ b/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp @@ -6,7 +6,7 @@ /** * @file ExaGeoStatDescriptor.hpp * @brief Class for creating matrix descriptors used in CHAMELEON and HiCMA libraries. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-07-16 @@ -69,13 +69,14 @@ namespace exageostat::dataunits::descriptor { * @param[in] aN The number of columns of the sub-matrix. * @param[in] aP The number of rows of the 2D distribution grid. * @param[in] aQ The number of columns of the 2D distribution grid. + * @param[in] aValidOOC Boolean refer to whether this descriptor can be created with OOC technology or not. * @return A pointer to the newly created descriptor. * */ void *CreateDescriptor(void *apDescriptor, const common::DescriptorType &aDescriptorType, 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 int &aM, const int &aN, const int &aP, const int &aQ, const bool &aValidOOC); /** * @brief destroys and finalize a descriptor diff --git a/inst/include/data-units/descriptor/concrete/ChameleonDescriptor.hpp b/inst/include/data-units/descriptor/concrete/ChameleonDescriptor.hpp index 1d8ce866..0f0f5560 100644 --- a/inst/include/data-units/descriptor/concrete/ChameleonDescriptor.hpp +++ b/inst/include/data-units/descriptor/concrete/ChameleonDescriptor.hpp @@ -6,7 +6,7 @@ /** * @file ChameleonDescriptor.hpp * @brief Defines the ChameleonDescriptor class for creating matrix descriptors using the CHAMELEON library. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-08-15 @@ -47,6 +47,7 @@ namespace exageostat::dataunits::descriptor { * @param[in] aN The number of columns of the sub-matrix. * @param[in] aP The number of rows of the 2D distribution grid. * @param[in] aQ The number of columns of the 2D distribution grid. + * @param[in] aValidOOC Boolean refer to whether this descriptor can be created with OOC technology or not. * @return A pointer to the newly created CHAM_desc_t descriptor. * */ @@ -54,7 +55,7 @@ namespace exageostat::dataunits::descriptor { 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 int &aP, const int &aQ, const bool &aValidOOC); /** * @brief destroys and finalize a descriptor diff --git a/inst/include/data-units/descriptor/concrete/HicmaDescriptor.hpp b/inst/include/data-units/descriptor/concrete/HicmaDescriptor.hpp index 7d62663d..d3513252 100644 --- a/inst/include/data-units/descriptor/concrete/HicmaDescriptor.hpp +++ b/inst/include/data-units/descriptor/concrete/HicmaDescriptor.hpp @@ -6,7 +6,7 @@ /** * @file HicmaDescriptor.hpp * @brief Defines the Hicma Descriptor class for creating matrix descriptors using the HICMA library. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-08-15 @@ -47,6 +47,7 @@ namespace exageostat::dataunits::descriptor { * @param[in] aN The number of columns of the sub-matrix. * @param[in] aP The number of rows of the 2D distribution grid. * @param[in] aQ The number of columns of the 2D distribution grid. + * @param[in] aValidOOC Boolean refer to whether this descriptor can be created with OOC technology or not. * @return A pointer to the newly created HICMA_desc_t descriptor. * */ @@ -54,7 +55,7 @@ namespace exageostat::dataunits::descriptor { 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 int &aP, const int &aQ, const bool &aValidOOC); /** * @brief destroys and finalize a descriptor diff --git a/inst/include/hardware/ExaGeoStatHardware.hpp b/inst/include/hardware/ExaGeoStatHardware.hpp index a5daf00b..c272c65d 100644 --- a/inst/include/hardware/ExaGeoStatHardware.hpp +++ b/inst/include/hardware/ExaGeoStatHardware.hpp @@ -6,10 +6,10 @@ /** * @file ExaGeoStatHardware.hpp * @brief Contains the definition of the ExaGeoStatHardware class. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-08-07 + * @date 2024-01-24 **/ #ifndef EXAGEOSTATCPP_EXAGEOSTATHARDWARE_HPP @@ -37,25 +37,21 @@ namespace exageostat::hardware { /** * @brief Destructor for ExaGeoStatHardware. */ - virtual ~ExaGeoStatHardware(); + ~ExaGeoStatHardware(); /** * @brief Get the Chameleon hardware context. * @return Pointer to the hardware context. * */ - [[nodiscard]] void *GetChameleonContext() const; + [[nodiscard]] static void *GetChameleonContext() ; -#ifdef EXAGEOSTAT_USE_HICMA - -/** - * @brief Get the Hicma hardware context. - * @return Pointer to the hardware context. - * - */ - [[nodiscard]] void *GetHicmaContext() const; - -#endif + /** + * @brief Get the Hicma hardware context. + * @return Pointer to the hardware context. + * + */ + [[nodiscard]] static void *GetHicmaContext(); /** * @brief Get the hardware context. @@ -63,15 +59,13 @@ namespace exageostat::hardware { * @return Pointer to the hardware context. * */ - [[nodiscard]] void *GetContext(common::Computation aComputation) const; + [[nodiscard]] static void *GetContext(common::Computation aComputation) ; private: //// Used Pointer to the Chameleon hardware context. - void *mpChameleonContext = nullptr; -#ifdef EXAGEOSTAT_USE_HICMA + static void *mpChameleonContext; //// Used Pointer to the Hicma hardware context. - void *mpHicmaContext = nullptr; -#endif + static void *mpHicmaContext; //// Used Computation mode for the solver. common::Computation mComputation; }; diff --git a/inst/include/helpers/BasselFunction.hpp b/inst/include/helpers/BasselFunction.hpp new file mode 100644 index 00000000..62430f2a --- /dev/null +++ b/inst/include/helpers/BasselFunction.hpp @@ -0,0 +1,69 @@ + +// Copyright (c) 2017-2023 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 BasselFunction.hpp + * @brief This file contains the BasselFunction class which provides methods for computing derivatives of the modified Bessel function of the second kind. These functions are crucial in statistical and mathematical computations, especially in fields such as geostatistics and spatial analysis. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2023-01-24 +**/ + +#ifndef EXAGEOSTATCPP_BASSELFUNCTION_HPP +#define EXAGEOSTATCPP_BASSELFUNCTION_HPP + +#include + +namespace exageostat::helpers { + + /** + * @class BasselFunction + * @brief The BasselFunction class provides methods for computing various derivatives of the modified Bessel function of the second kind, \( K_{\nu} \). This class is templated to support both float and double data types, enabling precision-based computations as required by different applications. + * @tparam T Data Type: float or double + * + */ + template + class BasselFunction { + + public: + /** + * @brief Calculates the derivative of the modified Bessel function of the second kind (K_nu) with respect to its order, evaluated at input_value and order aOrder. + * @param[in] aOrder The order of the Bessel function. + * @param[in] aInputValue The input value at which to evaluate the derivative. + * @return The value of the derivative of K_nu with respect to its order, evaluated at input_value and order aOrder. + * + */ + static T CalculateDerivativeBesselNu(const T &aOrder, const T &aInputValue); + + /** + * @brief Calculates the second derivative of the modified Bessel function of the second kind (K_nu) with respect to its input, evaluated at input_value and order aOrder. + * @param[in] aOrder The order of the Bessel function. + * @param[in] aInputValue The input value at which to evaluate the second derivative. + * @return The value of the second derivative of K_nu with respect to its input, evaluated at input_value and order aOrder. + * + */ + static T CalculateSecondDerivativeBesselNu(const T &aOrder, const T &aInputValue); + + /** + * @brief Calculates the second derivative of the modified Bessel function of the second kind (K_nu) with respect to its input, evaluated at input_value and order aOrder. + * @param[in] aOrder The order of the Bessel function. + * @param[in] aInputValue The input value at which to evaluate the derivative. + * @return The value of the derivative of K_nu with respect to its input, evaluated at input_value and order aOrder. + * + */ + static T CalculateSecondDerivativeBesselNuInput(const T &aOrder, const T &aInputValue); + + }; + + /** + * @brief Instantiates the DiskWriter class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(BasselFunction) +} + +#endif //EXAGEOSTATCPP_BASSELFUNCTION_HPP diff --git a/inst/include/helpers/ByteHandler.hpp b/inst/include/helpers/ByteHandler.hpp new file mode 100644 index 00000000..cb071f4c --- /dev/null +++ b/inst/include/helpers/ByteHandler.hpp @@ -0,0 +1,48 @@ + +// Copyright (c) 2017-2023 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 ByteHandler.hpp + * @brief Implementation of byte manipulation functions for ExaGeoStat. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-01-24 +**/ + +#ifndef EXAGEOSTATCPP_BYTEHANDLER_HPP +#define EXAGEOSTATCPP_BYTEHANDLER_HPP + +#include + +namespace exageostat::helpers { + + /** + * @brief Spread bits by three spaces. + * @param[in] aInputByte The input 64 bit to be spread. + * @return The byte after being spread. + * + */ + uint64_t SpreadBits(uint64_t aInputByte); + + /** + * @brief Reverse Spread bits operation. + * @param[in] aInputByte The input spread 64 bit to be compacted. + * @return The byte after being compacted. + * + */ + uint64_t ReverseSpreadBits(uint64_t aInputByte); + + /** + * @brief Compares two Unit64 values + * @param[in] aFirstValue Constant reference to the first input 64 bit value. + * @param[in] aSecondValue Constant reference to the second input 64 bit value. + * @return True if the second value is bigger than the first value, false otherwise. + * + */ + bool CompareUint64(const uint64_t &aFirstValue, const uint64_t &aSecondValue); + +} +#endif //EXAGEOSTATCPP_BYTEHANDLER_HPP diff --git a/inst/include/helpers/DiskWriter.hpp b/inst/include/helpers/DiskWriter.hpp index 822e86a4..4e4a0f12 100644 --- a/inst/include/helpers/DiskWriter.hpp +++ b/inst/include/helpers/DiskWriter.hpp @@ -6,10 +6,10 @@ /** * @file DiskWriter.hpp * @brief Contains the definition of the DiskWriter class for writing data to disk. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-06-08 + * @date 2023-01-24 **/ #ifndef EXAGEOSTATCPP_DISKWRITER_HPP diff --git a/inst/include/helpers/DistanceCalculationHelpers.hpp b/inst/include/helpers/DistanceCalculationHelpers.hpp index c8c5e44f..b297be6f 100644 --- a/inst/include/helpers/DistanceCalculationHelpers.hpp +++ b/inst/include/helpers/DistanceCalculationHelpers.hpp @@ -6,7 +6,7 @@ /** * @file DistanceCalculationHelpers.hpp * @brief Contains the definition of the DistanceCalculationHelpers class. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-06-08 @@ -52,6 +52,14 @@ namespace exageostat::helpers { */ static T DistanceEarth(T &aLatitude1, T &aLongitude1, T &aLatitude2, T &aLongitude2); + /** + * @brief Converts an angle from degrees to radians. + * @details This function converts an angle from degrees to radians using the conversion factor Ï€/180. + * @param[in] aDegree The angle in degrees. + * @return The angle converted to radians. + */ + static T DegreeToRadian(T aDegree); + }; /** * @brief Instantiates the PredictionHelpers class for float and double types. diff --git a/inst/include/kernels/Kernel.hpp b/inst/include/kernels/Kernel.hpp index 0ee2d1d2..6fa85fa6 100644 --- a/inst/include/kernels/Kernel.hpp +++ b/inst/include/kernels/Kernel.hpp @@ -7,7 +7,7 @@ /** * @file Kernels.hpp * @brief Header file for the Kernels class, which contains the main kernel functions. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -30,6 +30,7 @@ extern "C" { #include #include #include +#include /** * @def EARTH_RADIUS @@ -100,55 +101,20 @@ namespace exageostat::kernels { dataunits::Locations &aLocation2, dataunits::Locations &aLocation3, T *apLocalTheta, const int &aDistanceMetric) = 0; - /** - * @brief Calculates the derivative of the modified Bessel function of the second kind (K_nu) with respect to its input, evaluated at input_value and order aOrder. - * @param[in] aOrder The order of the Bessel function. - * @param[in] aInputValue The input value at which to evaluate the derivative. - * @return The value of the derivative of K_nu with respect to its input, evaluated at input_value and order aOrder. - */ - static T CalculateDerivativeBesselInputNu(const T &aOrder, const T &aInputValue); - - /** - * @brief Calculates the derivative of the modified Bessel function of the second kind (K_nu) with respect to its order, evaluated at input_value and order aOrder. - * @param[in] aOrder The order of the Bessel function. - * @param[in] aInputValue The input value at which to evaluate the derivative. - * @return The value of the derivative of K_nu with respect to its order, evaluated at input_value and order aOrder. - * - */ - static T CalculateDerivativeBesselNu(const T &aOrder, const T &aInputValue); - - /** - * @brief Calculates the second derivative of the modified Bessel function of the second kind (K_nu) with respect to its input, evaluated at input_value and order aOrder. - * @param[in] aOrder The order of the Bessel function. - * @param[in] aInputValue The input value at which to evaluate the second derivative. - * @return The value of the second derivative of K_nu with respect to its input, evaluated at input_value and order aOrder. - * - */ - static T CalculateSecondDerivativeBesselNu(const T &aOrder, const T &aInputValue); - - /** - * @brief Calculates the second derivative of the modified Bessel function of the second kind (K_nu) with respect to its input, evaluated at input_value and order aOrder. - * @param[in] aOrder The order of the Bessel function. - * @param[in] aInputValue The input value at which to evaluate the derivative. - * @return The value of the derivative of K_nu with respect to its input, evaluated at input_value and order aOrder. - * - */ - static T CalculateSecondDerivativeBesselNuInput(const T &aOrder, const T &aInputValue); - /** * @brief Returns the value of the parameter P used by the kernel function. - * @return The value of P. + * @return The value of P (Variables Number). * */ - [[nodiscard]] int GetPValue() const; + [[nodiscard]] int GetVariablesNumber() const; /** * @brief Sets the value of the parameter P used by the kernel function. - * @param[in] aP Value to set `mP` with. + * @param[in] aTimeSlot Value to set `mP` with. * @return void * */ - void SetPValue(int aP); + void SetPValue(int aTimeSlot); /** * @brief Returns the number of the parameters used by the kernel function. @@ -160,6 +126,8 @@ namespace exageostat::kernels { protected: //// Used P. int mP = 1; + //// Used Variable number which is P multiplied by timeslot + int mVariablesNumber = 1; //// Used number of parameters. int mParametersNumber = 3; }; diff --git a/inst/include/kernels/concrete/UnivariateMaternNonStat.hpp b/inst/include/kernels/concrete/UnivariateMaternNonStat.hpp deleted file mode 100644 index 4509c13f..00000000 --- a/inst/include/kernels/concrete/UnivariateMaternNonStat.hpp +++ /dev/null @@ -1,141 +0,0 @@ - -// Copyright (c) 2017-2023 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 UnivariateMaternNonStat.hpp - * @brief Defines the UnivariateMaternNonStat class, a Univariate Matern Non Stat kernel. - * @version 1.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @author Suhas Shankar - * @author Mary Lai Salvana - * @date 2023-04-14 -**/ - -#ifndef EXAGEOSTATCPP_UNIVARIATEMATERNNONSTAT_HPP -#define EXAGEOSTATCPP_UNIVARIATEMATERNNONSTAT_HPP - -#include - -namespace exageostat::kernels { - - /** - * @class UnivariateMaternNonStat - * @brief A class representing a Univariate Matern Non Stat kernel. - * @details This class represents a Univariate Matern Non Stat,which is a subclass of the Kernel class. - * It provides a method for generating a covariance matrix using a set of input locations and kernel parameters. - * - */ - template - class UnivariateMaternNonStat : public Kernel { - - public: - - /** - * @brief Constructs a new UnivariateMaternNonStat object. - * @details Initializes a new UnivariateMaternNonStat object with default values. - */ - UnivariateMaternNonStat(); - - /** - * @brief Virtual destructor to allow calls to the correct concrete destructor. - * - */ - ~UnivariateMaternNonStat() override = default; - - /** - * @brief Generates a covariance matrix using a set of locations and kernel parameters. - * @copydoc Kernel::GenerateCovarianceMatrix() - */ - void - GenerateCovarianceMatrix(T *apMatrixA, const int &aRowsNumber, const int &aColumnsNumber, const int &aRowOffset, - const int &aColumnOffset, dataunits::Locations &aLocation1, - dataunits::Locations &aLocation2, dataunits::Locations &aLocation3, - T *apLocalTheta, const int &aDistanceMetric) override; - - /** - * @brief Creates a new UnivariateMaternNonStat object. - * @details This method creates a new UnivariateMaternNonStat object and returns a pointer to it. - * @return A pointer to the new UnivariateMaternNonStat object. - * - */ - static Kernel *Create(); - - /** - * Function for smoothness parameter - * @param[in] aX x co-ordinate - * @param[in] aY y co-ordinate - * @param[in] aG parameter for function - * @param[in] aH parameter for function - * @param[in] aTi parameter for function - * @return The function ge^(h(x+y)) + ti - * - */ - static double Neu(double aX, double aY, double aG, double aH, double aTi); - - /** - * Function for partial sill - * @param[in] aX x co-ordinate - * @param[in] aY y co-ordinate - * @param[in] aD parameter for function - * @param[in] aE parameter for function - * @param[in] aF parameter for function - * @return The function de^(e(x+y)) + f - * - */ - static double Sigma(double aX, double aY, double aD, double aE, double aF); - - /** - * Function for spatial range - * @param[in] aX x co-ordinate - * @param[in] aY y co-ordinate - * @param[in] aA parameter for function - * @param[in] aB parameter for function - * @return The function ae^(sin bx + sin by) - * - */ - static double Lambda(double aX, double aY, double aA, double aB); - - /** - * Returns the Mahalanobis distance between two points to account for anisotropy - * @param[in] aX1 x co-ordinate of first point - * @param[in] aY1 y co-ordinate of first point - * @param[in] aX2 x co-ordinate of second point - * @param[in] aY2 y co-ordinate of second point - * @param[in] aA11 First element of the positive definite matrix that defines the Mahalanobis Distance - * @param[in] aA12 Second element of the positive definite matrix that defines the Mahalanobis Distance - * @param[in] aA21 Third element of the positive definite matrix that defines the Mahalanobis Distance - * @param[in] aA22 Fourth element of the positive definite matrix that defines the Mahalanobis Distance - * @return The Mahalanobis Distance - * - */ - static double - CalculateMahalanobisDistanceSquared(double aX1, double aY1, double aX2, double aY2, double aA11, double aA12, - double aA21, double aA22); - - /** - * Utility function that evaluates the matern. Similar to (https://www.rdocumentation.org/packages/PrevMap/versions/1.5.3/topics/matern.kernel) in R - * @param[in] aRange Spatial Range parameter (Also known as rho) - * @param[in] aSmoothness Smoothness parameter (Also known as neu) - * @param[in] aDistance Distance between the two locations - * @return Matern function evaluation - * - */ - static double MaternUtil(double aRange, double aSmoothness, double aDistance); - - private: - //// Used plugin name for static registration - static bool plugin_name; - }; - - /** - * @brief Instantiates the Data Generator class for float and double types. - * @tparam T Data Type: float or double - * - */ - EXAGEOSTAT_INSTANTIATE_CLASS(UnivariateMaternNonStat) -}//namespace exageostat - -#endif //EXAGEOSTATCPP_UNIVARIATEMATERNNONSTAT_HPP diff --git a/inst/include/kernels/concrete/UnivariateMaternNonStationary.hpp b/inst/include/kernels/concrete/UnivariateMaternNonStationary.hpp deleted file mode 100644 index e2422f59..00000000 --- a/inst/include/kernels/concrete/UnivariateMaternNonStationary.hpp +++ /dev/null @@ -1,72 +0,0 @@ - -// Copyright (c) 2017-2023 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 UnivariateMaternNonStationary.hpp - * @brief Defines the UnivariateMaternNonStationary class, a Univariate Matern Non Stationary kernel. - * @version 1.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @author Suhas Shankar - * @author Mary Lai Salvana - * @date 2023-04-13 -**/ - -#ifndef EXAGEOSTATCPP_UNIVARIATEMATERNNONSTATIONARY_HPP -#define EXAGEOSTATCPP_UNIVARIATEMATERNNONSTATIONARY_HPP - -#include - -namespace exageostat::kernels { - - /** - * @class UnivariateMaternNonStationary - * @brief A class representing a Univariate Matern Non Stationary kernel. - * @details This class represents a Univariate Matern Non Stationary, which is a subclass of the Kernel class. - * It provides a method for generating a covariance matrix using a set of input locations and kernel parameters. - * - */ - template - class UnivariateMaternNonStationary : public Kernel { - - public: - - /** - * @brief Constructs a new UnivariateMaternNonStationary object. - * @details Initializes a new UnivariateMaternNonStationary object with default values. - */ - UnivariateMaternNonStationary(); - - /** - * @brief Virtual destructor to allow calls to the correct concrete destructor. - * - */ - ~UnivariateMaternNonStationary() override = default; - - /** - * @brief Generates a covariance matrix using a set of locations and kernel parameters. - * @copydoc Kernel::GenerateCovarianceMatrix() - */ - void - GenerateCovarianceMatrix(T *apMatrixA, const int &aRowsNumber, const int &aColumnsNumber, const int &aRowOffset, - const int &aColumnOffset, dataunits::Locations &aLocation1, - dataunits::Locations &aLocation2, dataunits::Locations &aLocation3, - T *apLocalTheta, const int &aDistanceMetric) override; - - /** - * @brief Creates a new UnivariateMaternNonStationary object. - * @details This method creates a new UnivariateMaternNonStationary object and returns a pointer to it. - * @return A pointer to the new UnivariateMaternNonStationary object. - * - */ - static Kernel *Create(); - - private: - //// Used plugin name for static registration - static bool plugin_name; - }; -}//namespace exageostat - -#endif //EXAGEOSTATCPP_UNIVARIATEMATERNNONSTATIONARY_HPP diff --git a/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp b/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp index 9790b352..679acf12 100644 --- a/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp +++ b/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp @@ -6,7 +6,7 @@ /** * @file LinearAlgebraMethods.hpp * @brief Header file for the LinearAlgebraMethods class, which defines the interface for linear algebra solvers. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-03-20 @@ -54,12 +54,14 @@ namespace exageostat::linearAlgebra { * @details This method initializes the descriptors necessary for the linear algebra solver. * @param[in] aConfigurations Configurations object containing relevant settings. * @param[in,out] aDescriptorData Descriptor Data object to be populated with descriptors and data. + * @param[in] aP the P value of the kernel multiplied by time slot. * @param[in] apMeasurementsMatrix Pointer to the measurement matrix. * @return void * */ void InitiateDescriptors(configurations::Configurations &aConfigurations, - dataunits::DescriptorData &aDescriptorData, T *apMeasurementsMatrix = nullptr); + dataunits::DescriptorData &aDescriptorData, + const int &aP, T *apMeasurementsMatrix = nullptr); /** * @brief Initializes the descriptors necessary for the Fisher prediction function. @@ -69,27 +71,29 @@ namespace exageostat::linearAlgebra { void InitiateFisherDescriptors(configurations::Configurations &aConfigurations, dataunits::DescriptorData &aDescriptorData); - /** + /** * @brief Initializes the descriptors necessary for the Prediction. * @details This method initializes the descriptors necessary for the linear algebra solver. * @param[in] aConfigurations Configurations object containing relevant settings. * @param[in,out] aData DescriptorData object to be populated with descriptors and data. + * @param[in] aP the P value of the kernel multiplied by time slot. * @return void * */ void InitiatePredictionDescriptors(configurations::Configurations &aConfigurations, - dataunits::ExaGeoStatData &aData); + std::unique_ptr> &aData, const int &aP); /** * @brief Initializes the descriptors necessary for the Prediction Auxiliary function MLE-MLOE-MMOM. * @details This method initializes the descriptors necessary for the linear algebra solver. * @param[in] aConfigurations Configurations object containing relevant settings. * @param[in,out] aData DescriptorData object to be populated with descriptors and data. + * @param[in] aP the P value of the kernel multiplied by time slot. * @return void * */ void InitiateMLOEMMOMDescriptors(configurations::Configurations &aConfigurations, - dataunits::ExaGeoStatData &aData); + std::unique_ptr> &aData, const int &aP); /** * @brief Generates synthetic data. @@ -101,7 +105,8 @@ namespace exageostat::linearAlgebra { * */ void GenerateSyntheticData(configurations::Configurations &aConfigurations, - const hardware::ExaGeoStatHardware &aHardware, dataunits::ExaGeoStatData &aData, + const hardware::ExaGeoStatHardware &aHardware, + std::unique_ptr> &aData, const kernels::Kernel &aKernel); /** @@ -147,7 +152,8 @@ namespace exageostat::linearAlgebra { * */ void - GenerateObservationsVector(configurations::Configurations &aConfigurations, dataunits::ExaGeoStatData &aData, + GenerateObservationsVector(configurations::Configurations &aConfigurations, + std::unique_ptr> &aData, dataunits::Locations *apLocation1, dataunits::Locations *apLocation2, dataunits::Locations *apLocation3, const int &aDistanceMetric, const kernels::Kernel &aKernel); @@ -163,7 +169,8 @@ namespace exageostat::linearAlgebra { * @return log likelihood value * */ - virtual T ExaGeoStatMLETile(const hardware::ExaGeoStatHardware &aHardware, dataunits::ExaGeoStatData &aData, + virtual T ExaGeoStatMLETile(const hardware::ExaGeoStatHardware &aHardware, + std::unique_ptr> &aData, configurations::Configurations &aConfigurations, const double *apTheta, T *apMeasurementsMatrix, const kernels::Kernel &aKernel) = 0; @@ -276,7 +283,7 @@ namespace exageostat::linearAlgebra { ExaGeoStatMLETraceTileAsync(void *apDescA, void *apSequence, void *apRequest, void *apDescNum, void *apDescTrace); - /** + /** * @brief Calculate determinant for triangular matrix. * @param[in] apDescA Exageostat descriptor. * @param[in] apSequence Identifies the sequence of function calls that this call belongs to. @@ -307,7 +314,7 @@ namespace exageostat::linearAlgebra { * @return Returns 0 for success, error code otherwise. */ int ExaGeoStatMLEMSPETileAsync(void *apDescZPredict, void *apDescZMiss, void *apDescError, void *apSequence, - void *apRequest); + void *apRequest); /** * Predict missing values base on a set of given values and covariance matrix/ @@ -325,12 +332,39 @@ namespace exageostat::linearAlgebra { * @param[in] aKernel Reference to the kernel object to use. * @return the prediction Mean Square Error (MSPE). */ - T * ExaGeoStatMLEPredictTile(exageostat::dataunits::ExaGeoStatData &aData, T *apTheta, const int &aZMissNumber, - const int &aZObsNumber, T *apZObs, T *apZActual, T *apZMiss, - const hardware::ExaGeoStatHardware &aHardware, - configurations::Configurations &aConfiguration, - exageostat::dataunits::Locations &aMissLocations, - exageostat::dataunits::Locations &aObsLocations, const kernels::Kernel &aKernel); + T *ExaGeoStatMLEPredictTile(std::unique_ptr> &aData, T *apTheta, + const int &aZMissNumber, + const int &aZObsNumber, T *apZObs, T *apZActual, T *apZMiss, + const hardware::ExaGeoStatHardware &aHardware, + configurations::Configurations &aConfiguration, + exageostat::dataunits::Locations &aMissLocations, + exageostat::dataunits::Locations &aObsLocations, + const kernels::Kernel &aKernel); + + /** + * Predict missing values base on a set of given values and Non-Gaussian covariance matrix/ + * @param[in] aData Reference to Data containing different MLE inputs. + * @param[in] apTheta theta Vector with three parameter (Variance, Range, Smoothness) that is used to to generate the Covariance Matrix. + * @param[in] aZMissNumber number of missing values (unknown observations). + * @param[in] aZObsNumber number of observed values (known observations). + * @param[in] apZObs observed values vector (known observations). + * @param[in] apZActual actual missing values vector (in the case of testing MSPE). + * @param[in] apZMiss missing values vector (unknown observations). + * @param[in] aHardware ExaGeoStatHardware object representing the hardware. + * @param[in] aConfigurations Configurations object containing relevant settings. + * @param[in] aMissLocations Reference to Locations object containing missed locations. + * @param[in] aObsLocations Reference to Locations object containing observed locations. + * @param[in] aKernel Reference to the kernel object to use. + * @return the prediction Mean Square Error (MSPE). + */ + T *ExaGeoStatMLENonGaussianPredictTile(std::unique_ptr> &aData, T *apTheta, + const int &aZMissNumber, + const int &aZObsNumber, T *apZObs, T *apZActual, T *apZMiss, + const hardware::ExaGeoStatHardware &aHardware, + configurations::Configurations &aConfiguration, + exageostat::dataunits::Locations &aMissLocations, + exageostat::dataunits::Locations &aObsLocations, + const kernels::Kernel &aKernel); /** * @brief Copy Lapack matrix to Descriptor Matrix. @@ -340,8 +374,7 @@ namespace exageostat::linearAlgebra { * @param[in] aUpperLower Specifies Specifies whether the upper or lower triangular part of the covariance matrix is stored. * @return void */ - virtual void - ExaGeoStatLap2Desc(T *apA, const int &aLDA, void *apDescA, const common::UpperLower &aUpperLower) = 0; + void ExaGeoStatLap2Desc(T *apA, const int &aLDA, void *apDescA, const common::UpperLower &aUpperLower); /** * @brief Copy Descriptor Matrix to Lapack matrix. @@ -353,6 +386,21 @@ 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. @@ -368,9 +416,10 @@ namespace exageostat::linearAlgebra { * @param[out] apZ Pointer to an array to copy Z matrix into. * @param[in] aSize Size of the matrix. * @param[in] aDescData Descriptor data containing required Z matrix Descriptor. + * @param[in] aP the P value of the kernel multiplied by time slot. */ void ExaGeoStatGetZObs(exageostat::configurations::Configurations &aConfigurations, T *apZ, const int &aSize, - exageostat::dataunits::DescriptorData &aDescData, T *apMeasurementsMatrix); + exageostat::dataunits::DescriptorData &aDescData, T *apMeasurementsMatrix, const int &aP); /** * @brief Predict missing values based on a set of given values and covariance matrix. @@ -387,7 +436,7 @@ namespace exageostat::linearAlgebra { * @return void */ void ExaGeoStatMLETileMLOEMMOM(exageostat::configurations::Configurations &aConfigurations, - exageostat::dataunits::ExaGeoStatData &aData, + std::unique_ptr> &aData, const exageostat::hardware::ExaGeoStatHardware &aHardware, T *apTruthTheta, T *apEstimatedTheta, dataunits::Locations &aMissLocations, dataunits::Locations &aObsLocations, const kernels::Kernel &aKernel); @@ -402,9 +451,10 @@ namespace exageostat::linearAlgebra { * @return Fisher Matrix */ T * - ExaGeoStatFisherTile(configurations::Configurations &aConfigurations, dataunits::ExaGeoStatData &aData, + ExaGeoStatFisherTile(configurations::Configurations &aConfigurations, + std::unique_ptr> &aData, const hardware::ExaGeoStatHardware &aHardware, T *apTheta, - const kernels::Kernel &aKernel); + const kernels::Kernel &aKernel); /** * @brief Perform an asynchronous computation of MLE, MLOE, and MMOM for a tile. @@ -460,6 +510,47 @@ namespace exageostat::linearAlgebra { */ virtual void *ExaGeoStatDataGetAddr(void *apA, int aAm, int aAn) = 0; + /** + * @brief Calculate mean square error (MSE) scalar value for Bivariate kernels. + * @param[in] apDescZPre Observed measurements descZpre. + * @param[in] apDescZMiss Missing measurements descZpre + * @param[out] apDescsError1 Mean Square Error (MSE) 1. + * @param[out] apDescsError2 Mean Square Error (MSE) 2. + * @param[out] apDescsError Mean Square Error (MSE). + * @param[in] apSequence Sequence for the computation. + * @param[in] apRequest Request for the computation. + * @return successful exit + */ + int ExaGeoStatMLEMSPEBivariateTileAsync(void *apDescZPre, void *apDescZMiss, void *apDescsError1, + void *apDescsError2, void *apDescsError, + void *apSequence, void *apRequest); + + /** + * @brief Transform the measurements vector inside the non-Gaussian MLE function. + * @param[in] apDescZ pointer to the Observed Measurements descriptor. + * @param[in] apDescFlag Pointer to flag descriptor. + * @param[in] apTheta Pointer to Model parameters. + * @param[in] apSequence Identifies the sequence of function calls that this call belongs to. + * @param[in] apRequest Identifies this function call (for exception handling purposes). + * @return Returns 0 for success, error code otherwise. + */ + virtual int + ExaGeoStatNonGaussianTransformTileAsync(void *apDescZ, void *apDescFlag, const T *apTheta, void *apSequence, + void *apRequest) = 0; + + /** + * @brief Calculate the log likelihood of non-Gaussian MLE. + * @param[in] apDescZ pointer to the Observed Measurements descriptor. + * @param[in] apDescSum The log-likelihood Sum of descriptor Z. + * @param[in] apTheta Pointer to Model parameters. + * @param[in] apSequence Identifies the sequence of function calls that this call belongs to. + * @param[out] apRequest Identifies this function call (for exception handling purposes). + * @return Returns 0 for success, error code otherwise. + */ + virtual int + ExaGeoStatNonGaussianLogLikeTileAsync(void *apDescZ, void *apDescSum, const T *apTheta, void *apSequence, + void *apRequest) = 0; + /** * @brief Sets the context. * @param[in] apContext The context. @@ -469,7 +560,7 @@ namespace exageostat::linearAlgebra { this->mpContext = apContext; } - //// TODO: Create a Factory for Runtime system. This is a solution fix for now + //// TODO: Create a Factory for Runtime system. HiCMAPP Model will be applied. struct starpu_codelet cl_gaussian_to_non = { .where = STARPU_CPU, @@ -544,133 +635,143 @@ namespace exageostat::linearAlgebra { struct starpu_codelet cl_dtrace = { - .where = STARPU_CPU, - .cpu_funcs = {CORE_dtrace_starpu}, - .nbuffers = 3, - .modes = {STARPU_R, STARPU_RW, STARPU_W}, - .name = "dtrace" + .where = STARPU_CPU, + .cpu_funcs = {CORE_dtrace_starpu}, + .nbuffers = 3, + .modes = {STARPU_R, STARPU_RW, STARPU_W}, + .name = "dtrace" }; struct starpu_codelet cl_ddotp = { - .where = STARPU_CPU, - .cpu_funcs = {CORE_ddotp_starpu}, - .nbuffers = 2, - .modes = {STARPU_RW,STARPU_R}, - .name = "ddotp" + .where = STARPU_CPU, + .cpu_funcs = {CORE_ddotp_starpu}, + .nbuffers = 2, + .modes = {STARPU_RW, STARPU_R}, + .name = "ddotp" + }; + + struct starpu_codelet cl_dmse_bivariate = + { + .where = STARPU_CPU, + .cpu_funcs = {CORE_dmse_bivariate_starpu}, + .nbuffers = 5, + .modes = {STARPU_RW, STARPU_RW, STARPU_RW, STARPU_R, STARPU_R}, + .name = "dmse_bivariate" + }; + struct starpu_codelet cl_non_gaussian_transform = + { + .where = STARPU_CPU, + .cpu_funcs = {CORE_non_gaussian_transform_starpu}, + .nbuffers = 2, + .modes = {STARPU_RW, STARPU_W}, + .name = "non_gaussian_transform" }; + struct starpu_codelet cl_non_gaussian_loglike = + { + .where = STARPU_CPU, + .cpu_funcs = {CORE_non_gaussian_loglike_starpu}, + .nbuffers = 2, + .modes = {STARPU_R, STARPU_RW}, //Read access to Z and Read/Write access to the sum. + .name = "non_gaussian_loglike" + }; + struct starpu_codelet cl_non_gaussian_loglike_lr = + { + .where = STARPU_CPU, + .cpu_funcs = {CORE_non_gaussian_loglike_lr_starpu}, + .nbuffers = 2, + .modes = {STARPU_R, STARPU_RW}, //Read access to Z and Read/Write access to the sum. + .name = "non_gaussian_loglike_lr" + }; + + struct starpu_codelet cl_non_gaussian_transform_lr = + { + .where = STARPU_CPU, + .cpu_funcs = {CORE_non_gaussian_transform_lr_starpu}, + .nbuffers = 1, + .modes = {STARPU_RW}, + .name = "non_gaussian_transform_lr" + }; static void CORE_dcmg_starpu(void *apBuffers[], void *apCodeletArguments) { int m, n, m0, n0; exageostat::dataunits::Locations *location1; exageostat::dataunits::Locations *location2; exageostat::dataunits::Locations *location3; - T *theta; - T *A; + T *pTheta; + T *pA; int distance_metric; - kernels::Kernel *kernel; + kernels::Kernel *pKernel; - A = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); - starpu_codelet_unpack_args(apCodeletArguments, &m, &n, &m0, &n0, &location1, &location2, &location3, &theta, - &distance_metric, &kernel); - kernel->GenerateCovarianceMatrix(A, m, n, m0, n0, *location1, *location2, *location3, theta, - distance_metric); + pA = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + starpu_codelet_unpack_args(apCodeletArguments, &m, &n, &m0, &n0, &location1, &location2, &location3, + &pTheta, &distance_metric, &pKernel); + pKernel->GenerateCovarianceMatrix(pA, m, n, m0, n0, *location1, *location2, *location3, pTheta, + distance_metric); } static void CORE_gaussian_to_non_starpu(void *apBuffers[], void *apCodeletArguments) { int m, m0; - T *z; - T *theta; - theta = new T[6]; - z = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + T *pZ; + T *pTheta; + pTheta = new T[6]; + pZ = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); - starpu_codelet_unpack_args(apCodeletArguments, &m, &m0, &theta[0], &theta[1], &theta[2], &theta[3], - &theta[4], &theta[5]); + starpu_codelet_unpack_args(apCodeletArguments, &m, &m0, &pTheta[0], &pTheta[1], &pTheta[2], &pTheta[3], + &pTheta[4], &pTheta[5]); //core function to convert Z tile from Gaussian to non-Gaussian. - core_gaussian_to_non(z, theta, m); - delete[] theta; - } - - static void core_gaussian_to_non(T *Z, T *apLocalTheta, int aSize) { - - double xi = apLocalTheta[2]; - double omega = apLocalTheta[3]; - double g = apLocalTheta[4]; - double h = apLocalTheta[5]; - - int i; - if (h < 0) { - LOGGER("The kurtosis parameter cannot be negative") - return; - } - if (g == 0) { - for (i = 0; i < aSize; i++) - Z[i] = xi + omega * Z[i] * (exp(0.5 * h * pow(Z[i], 2))); - } else { - for (i = 0; i < aSize; i++) - Z[i] = xi + omega * (exp(g * Z[i]) - 1) * (exp(0.5 * h * pow(Z[i], 2))) / g; - } + core_gaussian_to_non(pZ, pTheta, m); + delete[] pTheta; } static void CORE_dzcpy_Starpu(void *apBuffers[], void *apCodeletArguments) { int m; - T *A; + T *pA; int m0; - T *r; + T *pR; - A = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); - starpu_codelet_unpack_args(apCodeletArguments, &m, &m0, &r); - memcpy(A, &r[m0], m * sizeof(T)); + pA = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + starpu_codelet_unpack_args(apCodeletArguments, &m, &m0, &pR); + memcpy(pA, &pR[m0], m * sizeof(T)); } static void CORE_dmdet_starpu(void *apBuffers[], void *apCodeletArguments) { int m; int n; - T *A; + T *pA; int m0; int n0; T det = 0; - T *determinant = &det; + T *pDeterminant = &det; - *determinant = 0; - A = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); - determinant = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + *pDeterminant = 0; + pA = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pDeterminant = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); starpu_codelet_unpack_args(apCodeletArguments, &m, &n, &m0, &n0); - T local_det = Core_dmdet(A, m); - *determinant += local_det; - } - - static T Core_dmdet(T *apA, int aSize) { - - int i; - T res = 0.0; - for (i = 0; i < aSize; i++) { - if (apA[i + i * aSize] > 0) - res += log(apA[i + i * aSize]); - } - return res; + T local_det = Core_dmdet(pA, m); + *pDeterminant += local_det; } static void CORE_stride_vector_starpu(void *apBuffers[], void *apCodeletArguments) { int m; int temp; - T *A; - T *B; - T *C; + T *pA; + T *pB; + T *pC; int m0; int i; int j = 0; - A = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); - B = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); - C = (T *) STARPU_MATRIX_GET_PTR(apBuffers[2]); + pA = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pB = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + pC = (T *) STARPU_MATRIX_GET_PTR(apBuffers[2]); starpu_codelet_unpack_args(apCodeletArguments, &temp, &m0, &m); for (i = 0; i < temp - 1; i += 2) { - B[j] = A[i]; - C[j] = A[i + 1]; + pB[j] = pA[i]; + pC[j] = pA[i + 1]; j++; } } @@ -678,41 +779,41 @@ namespace exageostat::linearAlgebra { static void CORE_tri_stride_vector_starpu(void *apBuffers[], void *apCodeletArguments) { int m; int temp; - double *A; - double *B; - double *C; - double *D; + T *pA; + T *pB; + T *pC; + T *pD; int m0; int i; int j; - A = (double *) STARPU_MATRIX_GET_PTR(apBuffers[0]); - B = (double *) STARPU_MATRIX_GET_PTR(apBuffers[1]); - C = (double *) STARPU_MATRIX_GET_PTR(apBuffers[2]); - D = (double *) STARPU_MATRIX_GET_PTR(apBuffers[3]); + pA = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pB = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + pC = (T *) STARPU_MATRIX_GET_PTR(apBuffers[2]); + pD = (T *) STARPU_MATRIX_GET_PTR(apBuffers[3]); starpu_codelet_unpack_args(apCodeletArguments, &temp, &m0, &m); //accept only temp divided by three (should be optimized) j = 0; for (i = 0; i < temp - 1; i += 3) { - B[j] = A[i]; - C[j] = A[i + 1]; - D[j] = A[i + 2]; + pB[j] = pA[i]; + pC[j] = pA[i + 1]; + pD[j] = pA[i + 2]; j++; } } static void CORE_dmse_starpu(void *apBuffers[], void *apCodeletArguments) { int m, m0, i; - double *pZPredict; - double *pZMiss; - double *pError; - double local_error = 0.0; + T *pZPredict; + T *pZMiss; + T *pError; + T local_error = 0.0; - pError = (double *) STARPU_MATRIX_GET_PTR(apBuffers[0]); - pZPredict = (double *) STARPU_MATRIX_GET_PTR(apBuffers[1]); - pZMiss = (double *) STARPU_MATRIX_GET_PTR(apBuffers[2]); + pError = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pZPredict = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + pZMiss = (T *) STARPU_MATRIX_GET_PTR(apBuffers[2]); starpu_codelet_unpack_args(apCodeletArguments, &m, &m0); for (i = 0; i < m; i++) { @@ -725,78 +826,284 @@ namespace exageostat::linearAlgebra { int m; int n; int i; - double *expr2; - double *expr3; - double *expr4; - double *mloe; - double *mmom; + T *pExpr2; + T *pExpr3; + T *pExpr4; + T *pMloe; + T *pMmom; int m0; int n0; - expr2 = (double *) STARPU_MATRIX_GET_PTR(apBuffers[0]); - expr3 = (double *) STARPU_MATRIX_GET_PTR(apBuffers[1]); - expr4 = (double *) STARPU_MATRIX_GET_PTR(apBuffers[2]); - mloe = (double *) STARPU_MATRIX_GET_PTR(apBuffers[3]); - mmom = (double *) STARPU_MATRIX_GET_PTR(apBuffers[4]); + pExpr2 = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pExpr3 = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + pExpr4 = (T *) STARPU_MATRIX_GET_PTR(apBuffers[2]); + pMloe = (T *) STARPU_MATRIX_GET_PTR(apBuffers[3]); + pMmom = (T *) STARPU_MATRIX_GET_PTR(apBuffers[4]); + starpu_codelet_unpack_args(apCodeletArguments, &m, &n, &m0, &n0); - double expr2_ = 0, expr3_ = 0, expr4_ = 0; + T expr2_ = 0, expr3_ = 0, expr4_ = 0; + for (i = 0; i < m * n; i += 2) { - expr2_ += expr2[i]; - expr3_ += expr3[i]; - expr4_ += expr4[i]; + expr2_ += pExpr2[i]; + expr3_ += pExpr3[i]; + expr4_ += pExpr4[i]; } if (expr3_ == 0.0) { - *mloe -= 1.0; + *pMloe -= 1.0; } else { - *mloe += (expr2_ / expr3_) - 1.0; + *pMloe += (expr2_ / expr3_) - 1.0; } if (expr2_ == 0.0) { - *mmom -= 1.0; + *pMmom -= 1.0; } else { - *mmom += (expr4_ / expr2_) - 1.0; + *pMmom += (expr4_ / expr2_) - 1.0; } } - static void CORE_dtrace_starpu(void *buffers[], void *cl_arg) { + static void CORE_dtrace_starpu(void *apBuffers[], void *apCodeletArguments) { + int m; - double *A; - double s = 0; - double *sum = &s; - double *trace; - - *sum = 0; - A = (double *) STARPU_MATRIX_GET_PTR(buffers[0]); - sum = (double *) STARPU_MATRIX_GET_PTR(buffers[1]); - trace = (double *) STARPU_MATRIX_GET_PTR(buffers[2]); - starpu_codelet_unpack_args(cl_arg, &m); - - double local_s = core_dtrace(A, m, trace); - *sum+= local_s; + T *pA; + T s = 0; + T *pSum = &s; + T *pTrace; + + *pSum = 0; + pA = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pSum = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + pTrace = (T *) STARPU_MATRIX_GET_PTR(apBuffers[2]); + starpu_codelet_unpack_args(apCodeletArguments, &m); + + T local_s = core_dtrace(pA, m, pTrace); + *pSum += local_s; + } + + static void CORE_ddotp_starpu(void *apBuffers[], void *apCodeletArguments) { + int m, m0; + T *pA; + T *pDot_product; + + pDot_product = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pA = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + starpu_codelet_unpack_args(apCodeletArguments, &m, &m0); + T local_dot = cblas_ddot(m, (double *) pA, 1, (double *) pA, 1); + *pDot_product += local_dot; + } + + static void CORE_non_gaussian_transform_starpu(void *apBuffers[], void *apCodeletArguments) { + int m, m0; + T *pZ; + T *pTheta; + T flag = 0; + T *pAll_flags = &flag; + *pAll_flags = 0; + + pTheta = new T[6]; + pZ = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + + starpu_codelet_unpack_args(apCodeletArguments, &m, &m0, /*&flag,*/ + &pTheta[0], &pTheta[1], &pTheta[2], + &pTheta[3], &pTheta[4], &pTheta[5]); + + //Transform the measurements vector inside the non-Gaussian MLE function. + core_non_gaussian_transform(pZ, pTheta, m); + delete[] pTheta; + } + + static void CORE_non_gaussian_loglike_starpu(void *apBuffers[], void *apCodeletArguments) { + int m, m0; + T *pZ; + T sum = 0; + T *pA = ∑ + + *pA = 0; + auto *pTheta = new T[6]; + pZ = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pA = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + + starpu_codelet_unpack_args(apCodeletArguments, &m, &m0, + &pTheta[0], &pTheta[1], &pTheta[2], + &pTheta[3], &pTheta[4], &pTheta[5]); + + T local_sum = core_non_gaussian_loglike(pZ, pTheta, m); + *pA += local_sum; + delete[] pTheta; } - static double core_dtrace (double *A, int m, double* trace) { + static void CORE_non_gaussian_loglike_lr_starpu(void *apBuffers[], void *apCodeletArguments) { + int m, m0; + T *pZ; + T *pTheta; + T sum; + T *pS; + + pTheta = (T *) new T[6]; + pZ = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pS = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + + starpu_codelet_unpack_args(apCodeletArguments, &m, &m0, + &pTheta[0], &pTheta[1], &pTheta[2], + &pTheta[3], &pTheta[4], &pTheta[5]); + + T local_sum = core_non_gaussian_loglike(pZ, pTheta, m); + *pS += local_sum; + } + + static void CORE_non_gaussian_transform_lr_starpu(void *apBuffers[], void *apCodeletArguments) { + int m, m0; + T *pZ; + T *pTheta; + T flag = 0; + T *pAll_flags = &flag; + *pAll_flags = 0; + + pTheta = (T *) new T[6]; + pZ = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + starpu_codelet_unpack_args(apCodeletArguments, &m, &m0, /*&flag,*/ + &pTheta[0], &pTheta[1], &pTheta[2], + &pTheta[3], &pTheta[4], &pTheta[5]); + + //Transform the measurements vector inside the non-Gaussian MLE function. + core_non_gaussian_transform(pZ, pTheta, m); + } + + static void core_gaussian_to_non(T *pZ, T *apLocalTheta, int aSize) { + + T xi = apLocalTheta[2]; + T omega = apLocalTheta[3]; + T g = apLocalTheta[4]; + T h = apLocalTheta[5]; + int i; - double res = 0.0; - for (i = 0; i < m; i++) - { - res += A[i + i * m]; - trace[i] = A[i + i * m]; + if (h < 0) { + throw std::runtime_error("The kurtosis parameter cannot be negative"); + } + if (g == 0) { + for (i = 0; i < aSize; i++) + pZ[i] = xi + omega * pZ[i] * (exp(0.5 * h * pow(pZ[i], 2))); + } else { + for (i = 0; i < aSize; i++) + pZ[i] = xi + omega * (exp(g * pZ[i]) - 1) * (exp(0.5 * h * pow(pZ[i], 2))) / g; + } + } + + static T Core_dmdet(T *apA, int aSize) { + + int i; + T res = 0.0; + for (i = 0; i < aSize; i++) { + if (apA[i + i * aSize] > 0) + res += log(apA[i + i * aSize]); } return res; } - static void CORE_ddotp_starpu(void *buffers[], void *cl_arg){ - int m, m0; - double * A; - double * dotproduct; - - dotproduct = (double *)STARPU_MATRIX_GET_PTR(buffers[0]); - A = (double *)STARPU_MATRIX_GET_PTR(buffers[1]); - starpu_codelet_unpack_args(cl_arg, &m, &m0); - double local_dot=cblas_ddot(m, A, 1, A, 1); - *dotproduct += local_dot; + static double core_dtrace(T *pA, int m, T *pTrace) { + int i; + T res = 0.0; + for (i = 0; i < m; i++) { + res += pA[i + i * m]; + pTrace[i] = pA[i + i * m]; + } + return res; + } + + static double tukeyGHTransfor(T aZ_non, T aZ, T aXi, T aOmega, T aG, T aH) { + if (aG == 0) + return aZ_non - aXi - aOmega * aZ * exp(0.5 * aH * aZ * aZ); + else + return aZ_non - aXi - (aOmega * (exp(aG * aZ) - 1) * (exp(0.5 * aH * aZ * aZ)) / aG); + } + + static double tukeyGHDiferencial(T aZ, T aOmega, T aG, T aH) { + if (aG == 0) + return -aOmega * exp((aH * aZ * aZ) / 2.0) - aOmega * aH * aZ * aZ * exp((aH * aZ * aZ) / 2.0); + else + return -aOmega * exp(aG * aZ) * exp((aH * aZ * aZ) / 2.0) - + (aH * aZ * exp((aH * aZ * aZ) / 2.0) * (aOmega * exp(aG * aZ) - aOmega)) / aG; + } + + static double newton_raphson(T aZ, T aXi, T aOmega, T aG, T aH, T aEps) { + int itr, max_itr; + T x0, x1, all_err; + x0 = 0; + T diff; + all_err = aEps; + max_itr = 1000; + for (itr = 1; itr <= max_itr; itr++) { + diff = tukeyGHTransfor(aZ, x0, aXi, aOmega, aG, aH) / tukeyGHDiferencial(x0, aOmega, aG, aH); + x1 = x0 - diff; + if (fabs(diff) < all_err) + return x1; + x0 = x1; + } + + return x1; + } + + static void core_non_gaussian_transform(T *apZ, T *apLocalTheta, int m) { + + T xi = apLocalTheta[2]; + T omega = apLocalTheta[3]; + T g = apLocalTheta[4]; + T h = apLocalTheta[5]; + + T eps = 1.0e-5; + for (int i = 0; i < m; i++) + apZ[i] = newton_raphson(apZ[i], xi, omega, g, h, eps); + } + + static double core_non_gaussian_loglike(T *apZ, T *apLocalTheta, int m) { + T g = apLocalTheta[4]; + T h = apLocalTheta[5]; + + int i; + T sum = 0.0; + if (h < 0) { + throw std::runtime_error("The kurtosis parameter cannot be negative"); + + } + for (i = 0; i < m; i++) { + if (g == 0) + sum += log(1 + h * pow(apZ[i], 2)) + 0.5 * h * pow(apZ[i], 2); + else { + sum += log(exp(g * apZ[i]) + (exp(g * apZ[i]) - 1) * h * apZ[i] / g) + 0.5 * h * pow(apZ[i], 2); + } + } + return sum; + } + + static void CORE_dmse_bivariate_starpu(void *apBuffers[], void *apCodeletArguments) { + int m, m0, i; + T *pZpre; + T *pZmiss; + T *pSerror1; + T *pSerror2; + T *pSerror; + T local_serror1 = 0.0; + T local_serror2 = 0.0; + T local_serror = 0.0; + + pSerror1 = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pSerror2 = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + pSerror = (T *) STARPU_MATRIX_GET_PTR(apBuffers[2]); + pZpre = (T *) STARPU_MATRIX_GET_PTR(apBuffers[3]); + pZmiss = (T *) STARPU_MATRIX_GET_PTR(apBuffers[4]); + + starpu_codelet_unpack_args(apCodeletArguments, &m, &m0); + + for (i = 0; i < m; i++) { + if (i % 2 == 0) { + local_serror1 += pow((pZpre[i] - pZmiss[i]), 2); + } else + local_serror2 += pow((pZpre[i] - pZmiss[i]), 2); + local_serror += pow((pZpre[i] - pZmiss[i]), 2); + } + *pSerror1 += local_serror1; + *pSerror2 += local_serror2; + *pSerror += local_serror; } bool recover(char *apPath, int aIterationCount, T *apTheta, T *apLogLik, int aNumParams) { @@ -809,8 +1116,7 @@ namespace exageostat::linearAlgebra { char *pch; fp = fopen(apPath, "r"); if (fp == nullptr) { - LOGGER("cannot open observations file\n") - exit(EXIT_FAILURE); + throw std::runtime_error("Cannot open observations file"); } while (getline(&line, &len, fp) != -1) { pch = strtok(line, " "); diff --git a/inst/include/linear-algebra-solvers/concrete/HicmaHeaders.hpp b/inst/include/linear-algebra-solvers/concrete/HicmaHeaders.hpp index 159c9c87..9d216bbe 100644 --- a/inst/include/linear-algebra-solvers/concrete/HicmaHeaders.hpp +++ b/inst/include/linear-algebra-solvers/concrete/HicmaHeaders.hpp @@ -1,7 +1,7 @@ /** * @file HicmaHeaders.hpp * @brief This file contains the necessary includes for using the Chameleon library. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-08-24 **/ @@ -9,7 +9,7 @@ #ifndef EXAGEOSTATCPP_HICMAHEADERS_HPP #define EXAGEOSTATCPP_HICMAHEADERS_HPP -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA extern "C" { #include #include diff --git a/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp b/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp index 99ebf86e..6c2d5c61 100644 --- a/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp +++ b/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp @@ -33,16 +33,10 @@ namespace exageostat::linearAlgebra { * @brief Calculates the log likelihood value of a given value theta. * @copydoc LinearAlgebraMethods::ExaGeoStatMLETile() */ - T ExaGeoStatMLETile(const hardware::ExaGeoStatHardware &aHardware, dataunits::ExaGeoStatData &aData, + T ExaGeoStatMLETile(const hardware::ExaGeoStatHardware &aHardware, std::unique_ptr> &aData, configurations::Configurations &aConfigurations, const double *theta, T *apMeasurementsMatrix, const kernels::Kernel &aKernel) override; - /** - * @brief Copy Lapack matrix to Descriptor Matrix - * @copydoc LinearAlgebraMethods::ExaGeoStatLap2Desc() - */ - void ExaGeoStatLap2Desc(T *apA, const int &aLDA, void *apDescA, const common::UpperLower &aUpperLower) override; - /** * @brief Copies a matrix in the tile layout from source to destination * @copydoc LinearAlgebraMethods::ExaGeoStatLapackCopyTile() @@ -143,6 +137,22 @@ namespace exageostat::linearAlgebra { int ExaGeoStatDoubleDotProduct(void *apDescA, void *apDescProduct, void *apSequence, void *apRequest); + /** + * @brief Calculate the loglikelihood of non-Gaussian MLE. + * @copydoc LinearAlgebraMethods::ExaGeoStatNonGaussianLogLikeTileAsync() + */ + int + ExaGeoStatNonGaussianLogLikeTileAsync(void *apDescZ, void *apDescSum, const T *apTheta, void *apSequence, + void *apRequest) override; + + /** + * @brief Calculate the loglikelihood of non-Gaussian MLE. + * @copydoc LinearAlgebraMethods::ExaGeoStatNonGaussianLogLikeTileAsync() + */ + int + ExaGeoStatNonGaussianTransformTileAsync(void *apDescZ, void *apDescFlag, const T *apTheta, void *apSequence, + void *apRequest) override; + }; EXAGEOSTAT_INSTANTIATE_CLASS(ChameleonImplementation) diff --git a/inst/include/linear-algebra-solvers/concrete/chameleon/dense/ChameleonImplementationDense.hpp b/inst/include/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.hpp similarity index 78% rename from inst/include/linear-algebra-solvers/concrete/chameleon/dense/ChameleonImplementationDense.hpp rename to inst/include/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.hpp index 8b3edb18..b902e8ab 100644 --- a/inst/include/linear-algebra-solvers/concrete/chameleon/dense/ChameleonImplementationDense.hpp +++ b/inst/include/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.hpp @@ -7,14 +7,14 @@ * @file ChameleonImplementationDense.hpp * @brief This file contains the declaration of ChameleonImplementationDense class. * @details ChameleonImplementationDense is a concrete implementation of ChameleonImplementation class for dense matrices. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-03-20 **/ -#ifndef EXAGEOSTATCPP_CHAMELEONIMPLEMENTATIONDENSE_HPP -#define EXAGEOSTATCPP_CHAMELEONIMPLEMENTATIONDENSE_HPP +#ifndef EXAGEOSTATCPP_CHAMELEONDENSE_HPP +#define EXAGEOSTATCPP_CHAMELEONDENSE_HPP #include @@ -26,18 +26,18 @@ namespace exageostat::linearAlgebra::dense { * */ template - class ChameleonImplementationDense : public ChameleonImplementation { + class ChameleonDense : public ChameleonImplementation { public: /** * @brief Default constructor. */ - explicit ChameleonImplementationDense() = default; + explicit ChameleonDense() = default; /** * @brief Virtual destructor to allow calls to the correct concrete destructor. */ - ~ChameleonImplementationDense() override = default; + ~ChameleonDense() override = default; /** * @brief Computes the Cholesky factorization of a symmetric positive definite or Symmetric positive definite matrix. @@ -54,8 +54,8 @@ namespace exageostat::linearAlgebra::dense { * @tparam T Data Type: float or double * */ - EXAGEOSTAT_INSTANTIATE_CLASS(ChameleonImplementationDense) + EXAGEOSTAT_INSTANTIATE_CLASS(ChameleonDense) }//namespace exageostat -#endif //EXAGEOSTATCPP_CHAMELEONIMPLEMENTATIONDENSE_HPP \ No newline at end of file +#endif //EXAGEOSTATCPP_CHAMELEONDENSE_HPP \ No newline at end of file diff --git a/inst/include/linear-algebra-solvers/concrete/chameleon/diagonal-super-tile/ChameleonImplementationDST.hpp b/inst/include/linear-algebra-solvers/concrete/chameleon/dst/ChameleonDST.hpp similarity index 87% rename from inst/include/linear-algebra-solvers/concrete/chameleon/diagonal-super-tile/ChameleonImplementationDST.hpp rename to inst/include/linear-algebra-solvers/concrete/chameleon/dst/ChameleonDST.hpp index a7991f3b..544dbb97 100644 --- a/inst/include/linear-algebra-solvers/concrete/chameleon/diagonal-super-tile/ChameleonImplementationDST.hpp +++ b/inst/include/linear-algebra-solvers/concrete/chameleon/dst/ChameleonDST.hpp @@ -7,14 +7,14 @@ * @file ChameleonImplementationDST.hpp * @brief This file contains the declaration of ChameleonImplementationDST class. * @details ChameleonImplementationDST is a concrete implementation of LinearAlgebraMethods class for diagonal super tile matrices. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-03-26 **/ -#ifndef EXAGEOSTATCPP_CHAMELEONIMPLEMENTATIONDST_HPP -#define EXAGEOSTATCPP_CHAMELEONIMPLEMENTATIONDST_HPP +#ifndef EXAGEOSTATCPP_CHAMELEONDST_HPP +#define EXAGEOSTATCPP_CHAMELEONDST_HPP #include @@ -26,19 +26,19 @@ namespace exageostat::linearAlgebra::diagonalSuperTile { * */ template - class ChameleonImplementationDST : public ChameleonImplementation { + class ChameleonDST : public ChameleonImplementation { public: /** * @brief Default constructor. */ - explicit ChameleonImplementationDST() = default; + explicit ChameleonDST() = default; /** * @brief Virtual destructor to allow calls to the correct concrete destructor. */ - ~ChameleonImplementationDST() override = default; + ~ChameleonDST() override = default; /** * @brief Computes the Cholesky factorization of a symmetric positive definite or Symmetric positive definite matrix. @@ -79,8 +79,8 @@ namespace exageostat::linearAlgebra::diagonalSuperTile { * @tparam T Data Type: float or double * */ - EXAGEOSTAT_INSTANTIATE_CLASS(ChameleonImplementationDST) + EXAGEOSTAT_INSTANTIATE_CLASS(ChameleonDST) }//namespace exageostat -#endif //EXAGEOSTATCPP_CHAMELEONIMPLEMENTATIONDST_HPP \ No newline at end of file +#endif //EXAGEOSTATCPP_CHAMELEONDST_HPP \ No newline at end of file diff --git a/inst/include/linear-algebra-solvers/concrete/hicma/tile-low-rank/HicmaImplementation.hpp b/inst/include/linear-algebra-solvers/concrete/hicma/tlr/HicmaImplementation.hpp similarity index 82% rename from inst/include/linear-algebra-solvers/concrete/hicma/tile-low-rank/HicmaImplementation.hpp rename to inst/include/linear-algebra-solvers/concrete/hicma/tlr/HicmaImplementation.hpp index 4520a807..22fdf9bf 100644 --- a/inst/include/linear-algebra-solvers/concrete/hicma/tile-low-rank/HicmaImplementation.hpp +++ b/inst/include/linear-algebra-solvers/concrete/hicma/tlr/HicmaImplementation.hpp @@ -7,7 +7,7 @@ * @file HicmaImplementation.hpp * @brief This file contains the declaration of HicmaImplementation class. * @details HicmaImplementation is a concrete implementation of LinearAlgebraMethods class for tile low-rank matrices. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-03-26 @@ -43,15 +43,17 @@ namespace exageostat::linearAlgebra::tileLowRank { * @brief Set the modeling descriptors for HiCMA implementation. * @param[in,out] aData Reference to the ExaGeoStatData object. * @param[in] aConfigurations Reference to the Configurations object. + * @param[in] aP the P value of the kernel multiplied by time slot. */ - void - SetModelingDescriptors(dataunits::ExaGeoStatData &aData, configurations::Configurations &aConfigurations); + void SetModelingDescriptors(std::unique_ptr> &aData, + configurations::Configurations &aConfigurations, const int &aP); /** * @brief Calculates the log likelihood value of a given value theta. * @copydoc LinearAlgebraMethods::ExaGeoStatMLETile() */ - T ExaGeoStatMLETile(const hardware::ExaGeoStatHardware &apHardware, dataunits::ExaGeoStatData &aData, + T ExaGeoStatMLETile(const hardware::ExaGeoStatHardware &apHardware, + std::unique_ptr> &aData, configurations::Configurations &aConfigurations, const double *theta, T *apMeasurementsMatrix, const kernels::Kernel &aKernel) override; @@ -115,17 +117,25 @@ namespace exageostat::linearAlgebra::tileLowRank { */ int ExaGeoStatMeasureDetTileAsync(void *apDescA, void *apSequence, void *apRequest, void *apDescDet) override; - /** - * @brief Copy Lapack matrix to Descriptor Matrix - * @copydoc LinearAlgebraMethods::ExaGeoStatLap2Desc() - */ - void ExaGeoStatLap2Desc(T *apA, const int &aLDA, void *apDescA, const common::UpperLower &aUpperLower) override; - /** * @brief Get the pointer to the data or the runtime handler associated to the piece of data (m, n) in desc. * @copydoc LinearAlgebraMethods::ExaGeoStatDataGetAddr() */ void *ExaGeoStatDataGetAddr(void *apA, int aAm, int aAn) override; + + /** + * @brief Calculate the loglikelihood of non-Gaussian MLE. + * @copydoc LinearAlgebraMethods::ExaGeoStatNonGaussianLogLikeTileAsync() + */ + int ExaGeoStatNonGaussianLogLikeTileAsync(void *apDescZ, void *apDescSum, const T *apTheta, + void *apSequence, void *apRequest) override; + + /** + * @brief Calculate the loglikelihood of non-Gaussian MLE. + * @copydoc LinearAlgebraMethods::ExaGeoStatNonGaussianTransformTileAsync() + */ + int ExaGeoStatNonGaussianTransformTileAsync(void *apDescZ, void *apDescFlag, const T *apTheta, + void *apSequence, void *apRequest) override; }; /** diff --git a/inst/include/prediction/Prediction.hpp b/inst/include/prediction/Prediction.hpp index 87b33f16..5e7a42fb 100644 --- a/inst/include/prediction/Prediction.hpp +++ b/inst/include/prediction/Prediction.hpp @@ -6,7 +6,7 @@ /** * @file Prediction.hpp * @brief Contains the definition of the Prediction class. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-06-08 @@ -29,16 +29,6 @@ namespace exageostat::prediction { class Prediction { public: - /** - * @brief Default constructor for Prediction class. - */ - Prediction() = default; - - /** - * @brief Default destructor for Prediction class. - */ - ~Prediction() = default; - /** * @brief Takes care of calling the MSPE function, and the appropriate auxiliary function. * @param[in] aHardware Reference to Hardware configuration for the ExaGeoStat solver. @@ -48,10 +38,10 @@ namespace exageostat::prediction { * @param[in] aKernel Reference to the kernel object to use. * @return */ - void PredictMissingData(const exageostat::hardware::ExaGeoStatHardware &aHardware, - exageostat::dataunits::ExaGeoStatData &aData, - exageostat::configurations::Configurations &aConfigurations, T *apMeasurementsMatrix, - const kernels::Kernel &aKernel); + static void PredictMissingData(const exageostat::hardware::ExaGeoStatHardware &aHardware, + std::unique_ptr> &aData, + exageostat::configurations::Configurations &aConfigurations, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel); /** * @brief Initializes needed pointers for prediction. @@ -63,13 +53,16 @@ namespace exageostat::prediction { * @param[out] aMissLocation Location object to be filled with missed locations. * @param[out] aObsLocation Location object to be filled with missed locations. * @param[in] apMeasurementsMatrix Pointer to the user input measurements matrix. + * @param[in] aP the P value of the kernel multiplied by time slot. * @return void */ - void InitializePredictionArguments(exageostat::configurations::Configurations &aConfigurations, - exageostat::dataunits::ExaGeoStatData &aData, - std::unique_ptr> &aLinearAlgebraSolver, - T *apZObs, T *apZActual, exageostat::dataunits::Locations &aMissLocation, - exageostat::dataunits::Locations &aObsLocation, T *apMeasurementsMatrix); + static void InitializePredictionArguments(exageostat::configurations::Configurations &aConfigurations, + std::unique_ptr> &aData, + std::unique_ptr> &aLinearAlgebraSolver, + T *apZObs, T *apZActual, + exageostat::dataunits::Locations &aMissLocation, + exageostat::dataunits::Locations &aObsLocation, + T *apMeasurementsMatrix, const int &aP); }; diff --git a/inst/include/prediction/PredictionAuxiliaryFunctions.hpp b/inst/include/prediction/PredictionAuxiliaryFunctions.hpp index ad07828f..d9ebf857 100644 --- a/inst/include/prediction/PredictionAuxiliaryFunctions.hpp +++ b/inst/include/prediction/PredictionAuxiliaryFunctions.hpp @@ -28,16 +28,6 @@ namespace exageostat::prediction { class PredictionAuxiliaryFunctions { public: - /** - * @brief Default constructor for PredictionAuxiliaryFunctions - */ - PredictionAuxiliaryFunctions() = default; - - /** - * @brief Default destructor for PredictionAuxiliaryFunctions - */ - ~PredictionAuxiliaryFunctions() = default; - /** * @brief implements the Inverse Distance Weighting (IDW) interpolation method * for predicting missing values based on available observed values. diff --git a/inst/include/prediction/PredictionHelpers.hpp b/inst/include/prediction/PredictionHelpers.hpp index 7955357e..9a684390 100644 --- a/inst/include/prediction/PredictionHelpers.hpp +++ b/inst/include/prediction/PredictionHelpers.hpp @@ -6,7 +6,7 @@ /** * @file PredictionHelpers.hpp * @brief Contains the definition of the PredictionHelpers.hpp class. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-06-08 @@ -38,12 +38,13 @@ namespace exageostat::prediction { * @param[in] apZ Pointer to a copy of the measurements matrix. * @param[out] aMissLocation Location object to be filled with missed locations. * @param[out] aObsLocation Location object to be filled with missed locations. + * @param[in] aP the P value of the kernel multiplied by time slot. * @return void */ static void PickRandomPoints(exageostat::configurations::Configurations &aConfigurations, - exageostat::dataunits::ExaGeoStatData &aData, T *apZObs, T *apZActual, T *apZ, + std::unique_ptr> &aData, T *apZObs, T *apZActual, T *apZ, exageostat::dataunits::Locations &aMissLocation, - exageostat::dataunits::Locations &aObsLocation); + exageostat::dataunits::Locations &aObsLocation, const int &aP); /** * @brief Shuffle array. diff --git a/inst/include/results/Results.hpp b/inst/include/results/Results.hpp index b112284c..8037dd48 100644 --- a/inst/include/results/Results.hpp +++ b/inst/include/results/Results.hpp @@ -95,6 +95,48 @@ namespace exageostat::results { */ [[nodiscard]] double GetTotalModelingExecutionTime() const; + /** + * @brief Get the MLOE. + * @return The MLOE. + */ + [[nodiscard]] double GetMLOE() const; + + /** + * @brief Get the MSPEError. + * @return The MSPEError. + */ + [[nodiscard]] double GetMSPEError() const; + + /** + * @brief Get the IDW error. + * @return The the IDW error vector. + */ + [[nodiscard]] std::vector GetIDWError() const; + + /** + * @brief Get the MMOM. + * @return The MMOM. + */ + [[nodiscard]] double GetMMOM() const; + + /** + * @brief Get the Fisher matrix element 00. + * @return the Fisher matrix element 00. + */ + [[nodiscard]] double GetFisher00() const; + + /** + * @brief Get the Fisher matrix element 11. + * @return the Fisher matrix element 11. + */ + [[nodiscard]] double GetFisher11() const; + + /** + * @brief Get the Fisher matrix element 22. + * @return the Fisher matrix element 22. + */ + [[nodiscard]] double GetFisher22() const; + /** * @brief Set the total modeling FLOPs. * @param[in] aTime The total number of FLOPs for data modeling. diff --git a/package.pc.in b/package.pc.in index 014e8173..86ccc3b5 100644 --- a/package.pc.in +++ b/package.pc.in @@ -8,4 +8,4 @@ Description: @CMAKE_PROJECT_DESCRIPTION@ Version: @PROJECT_VERSION@ Cflags: -I${includedir} Libs: -L${libdir} -l@PROJECT_NAME@ -URL: http://github.com/ecrc/exageostat-cpp \ No newline at end of file +URL: https://github.com/ecrc/ExaGeoStatCPP \ No newline at end of file diff --git a/scripts/Benchmarking.sh b/scripts/Benchmarking.sh new file mode 100644 index 00000000..1bd12b0b --- /dev/null +++ b/scripts/Benchmarking.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# Copyright (c) 2017-2023 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 config.sh +# @version 1.0.1 +# @author Mahmoud ElKarargy +# @date 2023-10-10 + +# Set the output file name +output_file="VULTURE_40CORE_EXACT.csv" + +# Create or truncate the output file +echo "N,computation,kernel,ncores,ngpus,dts,Zmiss,maximum_likelihood,maximum_theta,mspe_value,time_generation,time_modeling,time_prediction,time_modeling_per_iter,Gflops_data_generation,Gflops_data_modeling,Gflops_data_modeling_iter,Gflops_data_mspe" > "$output_file" + +CORES=40 +GPUS=0 +MLE_ITERATIONS=1 +DTS=960 + +# Define the desired values for N +desired_N=(55225 63001 71289 79524 87616 96100 104329 112225 120081 130889 150000 200000) + +# Loop over N values +for N in "${desired_N[@]}"; do + # Repeat each iteration 10 times + for iteration in {1..10}; do + # Run the command and capture the output + command_output=$(./bin/examples/end-to-end/Example_Data_Generation_Modeling_and_Prediction --ncores=$CORES --gpus=$GPUS --computation=exact --itheta=1:0.1:0.5 --etheta=1:0.1:\? --olb=0.1:0.1:0.1 --oub=5:5:5 --dts="$DTS" --verbose=detailed --N="$N" --max_mle_iterations=$MLE_ITERATIONS --kernel=univariate_matern_stationary --tolerance=4 --Zmiss="$(($N/10))" --mspe) + # Extract the desired values from the command output + COMPUTATION=$(echo "$command_output" | awk -F "#Computation:" '{print $2}' | awk -F "," '{print $1}') + COMPUTATION=$(echo "$COMPUTATION" | tr -d '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + KERNEL=$(echo "$command_output" | awk -F "#Kernel:" '{print $2}' | awk -F "," '{print $1}') + KERNEL=$(echo "$KERNEL" | tr -d '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + logli_result=$(echo "$command_output" | awk -F "#Final Log Likelihood value: " '{print $2}' | awk -F "," '{print $1}') + logli_result=$(echo "$logli_result" | tr -d '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + maximum_theta=$(echo "$command_output" | awk -F "#Found Maximum Theta at: " '{print $2}' | awk -F "," '{print $1}') + maximum_theta=$(echo "$maximum_theta" | tr -d '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + mspe_value=$(echo "$command_output" | awk -F "#Mean Square Error MSPE: " '{print $2}' | awk -F "," '{print $1}') + mspe_value=$(echo "$mspe_value" | tr -d '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + time_generation=$(echo "$command_output" | awk -F "#Total Data Generation Execution Time: " '{print $2}' | awk -F "," '{print $1}') + time_generation=$(echo "$time_generation" | tr -d '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + time_modeling=$(echo "$command_output" | awk -F "#Total MLE Execution time: " '{print $2}' | awk -F "," '{print $1}') + time_modeling=$(echo "$time_modeling" | tr -d '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + time_prediction=$(echo "$command_output" | awk -F "#MSPE Prediction Execution Time: " '{print $2}' | awk -F "," '{print $1}') + time_prediction=$(echo "$time_prediction" | tr -d '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + time_modeling_iteration=$(echo "$command_output" | awk -F "#Average Time Modeling per Iteration: " '{print $2}' | awk -F "," '{print $1}') + time_modeling_iteration=$(echo "$time_modeling_iteration" | tr -d '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + flops_generation=$(echo "$command_output" | awk -F "#Total Data Generation Gflop/s: " '{print $2}' | awk -F "," '{print $1}') + flops_generation=$(echo "$flops_generation" | tr -d '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + flops_modeling=$(echo "$command_output" | awk -F "#Total MLE Gflop/s: " '{print $2}' | awk -F "," '{print $1}') + flops_modeling=$(echo "$flops_modeling" | tr -d '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + flops_modeling_iteration=$(echo "$command_output" | awk -F "#Average Flops per Iteration: " '{print $2}' | awk -F "," '{print $1}') + flops_modeling_iteration=$(echo "$flops_modeling_iteration" | tr -d '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + flops_mspe=$(echo "$command_output" | awk -F "#MSPE Gflop/s: " '{print $2}' | awk -F "," '{print $1}') + flops_mspe=$(echo "$flops_mspe" | tr -d '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') + + echo "$command_output" + echo "Iteration number $iteration done." + # Append the values to the output file + echo '**Results**' + echo "$N,$COMPUTATION,$KERNEL,$CORES,$GPUS,$DTS,$(($N/10)),$logli_result,$maximum_theta,$mspe_value,$time_generation,$time_modeling,$time_prediction,$time_modeling_iteration,$flops_generation,$flops_modeling,$flops_modeling_iteration,$flops_mspe" + echo '' + echo "$N,$COMPUTATION,$KERNEL,$CORES,$GPUS,$DTS,$(($N/10)),$logli_result,$maximum_theta,$mspe_value,$time_generation,$time_modeling,$time_prediction,$time_modeling_iteration,$flops_generation,$flops_modeling,$flops_modeling_iteration,$flops_mspe" >> "$output_file" + done +done diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 94d4645f..6fde05af 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,7 +5,7 @@ # @file CMakeLists.txt # @brief This file contains the CMake configuration for the ExaGeoStat library. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-01-30 @@ -21,6 +21,7 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/helpers) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/hardware) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/prediction) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/results) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/data-loader) # Set the name of the library to be created. set(LIB_NAME ${PROJECT_NAME}) @@ -46,7 +47,8 @@ target_include_directories(${LIB_NAME} ) install(TARGETS ${LIB_NAME} EXPORT ${LIB_NAME}CoreConfig - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib + LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/lib + ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/lib ) -install(EXPORT ${LIB_NAME}CoreConfig DESTINATION lib/cmake/${PROJECT_NAME}) \ No newline at end of file + +install(EXPORT ${LIB_NAME}CoreConfig DESTINATION ${CMAKE_INSTALL_PREFIX}/EXAGEOSTATCPP/lib/cmake/) \ No newline at end of file diff --git a/src/api/ExaGeoStat.cpp b/src/api/ExaGeoStat.cpp index 11cc407e..7a03121f 100644 --- a/src/api/ExaGeoStat.cpp +++ b/src/api/ExaGeoStat.cpp @@ -6,7 +6,7 @@ /** * @file ExaGeoStat.cpp * @brief High-Level Wrapper class containing the static API for ExaGeoStat operations. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-05-30 **/ @@ -29,24 +29,28 @@ using namespace exageostat::prediction; template void ExaGeoStat::ExaGeoStatLoadData(const ExaGeoStatHardware &aHardware, configurations::Configurations &aConfigurations, - dataunits::ExaGeoStatData &aData) { + std::unique_ptr> &aData) { + + LOGGER("** ExaGeoStat data generation **") // Register and create a kernel object - kernels::Kernel *pKernel = plugins::PluginRegistry>::Create(aConfigurations.GetKernelName()); + 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 - //hehe unique_ptr> data_generator = DataGenerator::CreateGenerator(aConfigurations); - aData = *data_generator->CreateData(aConfigurations, aHardware, *pKernel); + aData = data_generator->CreateData(aConfigurations, aHardware, *pKernel); delete pKernel; } template T ExaGeoStat::ExaGeoStatDataModeling(const ExaGeoStatHardware &aHardware, Configurations &aConfigurations, - ExaGeoStatData &aData, T *apMeasurementsMatrix) { + std::unique_ptr> &aData, T *apMeasurementsMatrix) { + LOGGER("** ExaGeoStat data Modeling **") // Register and create a kernel object - kernels::Kernel *pKernel = plugins::PluginRegistry>::Create(aConfigurations.GetKernelName()); + kernels::Kernel *pKernel = plugins::PluginRegistry>::Create(aConfigurations.GetKernelName(), + aConfigurations.GetTimeSlot()); // Add the data modeling arguments. aConfigurations.InitializeDataModelingArguments(); @@ -66,6 +70,7 @@ T ExaGeoStat::ExaGeoStatDataModeling(const ExaGeoStatHardware &aHardware, Con optimizing_function.set_max_objective(ExaGeoStatMLETileAPI, (void *) modeling_data); // Optimize mle using nlopt. optimizing_function.optimize(aConfigurations.GetStartingTheta(), opt_f); + aConfigurations.SetEstimatedTheta(aConfigurations.GetStartingTheta()); delete pKernel; delete modeling_data; @@ -90,13 +95,15 @@ ExaGeoStat::ExaGeoStatMLETileAPI(const std::vector &aTheta, std::vect template void ExaGeoStat::ExaGeoStatPrediction(const ExaGeoStatHardware &aHardware, Configurations &aConfigurations, - ExaGeoStatData &aData, T *apMeasurementsMatrix) { + std::unique_ptr> &aData, + T *apMeasurementsMatrix) { - Prediction predictor; + LOGGER("** ExaGeoStat data Prediction **") // Register and create a kernel object - kernels::Kernel *pKernel = plugins::PluginRegistry>::Create(aConfigurations.GetKernelName()); + kernels::Kernel *pKernel = plugins::PluginRegistry>::Create(aConfigurations.GetKernelName(), + aConfigurations.GetTimeSlot()); // Add the data prediction arguments. aConfigurations.InitializeDataPredictionArguments(); - predictor.PredictMissingData(aHardware, aData, aConfigurations, apMeasurementsMatrix, *pKernel); + Prediction::PredictMissingData(aHardware, aData, aConfigurations, apMeasurementsMatrix, *pKernel); delete pKernel; } \ No newline at end of file diff --git a/src/configurations/Configurations.cpp b/src/configurations/Configurations.cpp index f7a0ada3..1b8ab14d 100644 --- a/src/configurations/Configurations.cpp +++ b/src/configurations/Configurations.cpp @@ -6,7 +6,7 @@ /** * @file Configurations.cpp * @brief This file defines the Configurations class which stores the configuration parameters for ExaGeoStat. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-01-31 @@ -39,7 +39,7 @@ Configurations::Configurations() { SetTimeSlot(1); SetProblemSize(0); SetDenseTileSize(0); -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA SetLowTileSize(0); #endif SetBand(0); @@ -51,7 +51,6 @@ Configurations::Configurations() { SetLowerBounds(theta); SetUpperBounds(theta); SetEstimatedTheta(theta); - SetP(1); SetSeed(0); SetLogger(false); SetUnknownObservationsNb(0); @@ -67,6 +66,8 @@ Configurations::Configurations() { SetDataPath(""); SetDistanceMetric(common::EUCLIDEAN_DISTANCE); SetAccuracy(0); + SetIsNonGaussian(false); + mIsThetaInit = false; } @@ -103,6 +104,9 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV) { SetPGrid(CheckNumericalValue(argument_value)); } else if (argument_name == "--Q" || argument_name == "--q") { SetQGrid(CheckNumericalValue(argument_value)); + } 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)); @@ -118,6 +122,8 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV) { 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" || @@ -142,19 +148,20 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV) { 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 == "--Dimension" || argument_name == "--dimension" || argument_name == "--dim" || - argument_name == "--Dim" || argument_name == "--ZmissNumber" || argument_name == "--Zmiss" || + 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 == "--tolerance" || + 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 == "--LTS" || argument_name == "--lts" || argument_name == "--Lts" || argument_name == "--DataPath" || argument_name == "--dataPath" || argument_name == "--data_path" || argument_name == "--acc" || argument_name == "--Acc")) { @@ -167,7 +174,7 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV) { if (argument_name == "--help") { PrintUsage(); } - if (argument_name == "--OOC") { + if (argument_name == "--OOC" || argument_name == "--ooc") { SetIsOOC(true); } else if (argument_name == "--ApproximationMode" || argument_name == "--approximationmode" || argument_name == "--approximation_mode") { @@ -177,7 +184,7 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV) { } else { if (!(argument_name == "--mspe" || argument_name == "--MSPE" || argument_name == "--idw" || argument_name == "--IDW" || - argument_name == "--mloe-mmom" || argument_name == "--mloe-mmom" || argument_name == "--mloe_mmom" || + argument_name == "--mloe-mmom" || argument_name == "--mloe_mmom" || argument_name == "--fisher" || argument_name == "--Fisher")) { LOGGER("!! " << argument_name << " !!") throw invalid_argument( @@ -199,19 +206,34 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV) { throw domain_error("You need to set the Kernel, before starting"); } + size_t found = GetKernelName().find("NonGaussian"); + // Check if the substring was found + if (found != std::string::npos) { + SetIsNonGaussian(true); + } + if (GetLogger()) { //initlog InitLog(); } this->PrintSummary(); + } void Configurations::InitializeAllTheta() { if (!mIsThetaInit) { + int parameters_number = kernels::KernelsConfigurations::GetParametersNumberKernelMap()[this->GetKernelName()]; InitTheta(GetInitialTheta(), parameters_number); SetInitialTheta(GetInitialTheta()); + + + if (this->GetIsNonGaussian()) { + GetInitialTheta()[GetInitialTheta().size() - 1] = 0.2; + GetInitialTheta()[GetInitialTheta().size() - 2] = 0.2; + } + InitTheta(GetLowerBounds(), parameters_number); SetLowerBounds(GetLowerBounds()); InitTheta(GetUpperBounds(), parameters_number); @@ -250,11 +272,8 @@ void Configurations::InitializeDataGenerationArguments() { argument_value = argument.substr(equal_sign_Idx + 1); // Check the argument name and set the corresponding value - if (argument_name == "--Dimension" || argument_name == "--dimension" || argument_name == "--dim" || - argument_name == "--Dim") { - SetDimension(CheckDimensionValue(argument_value)); - } else if (argument_name == "--DataPath" || argument_name == "--dataPath" || - argument_name == "--data_path") { + if (argument_name == "--DataPath" || argument_name == "--dataPath" || + argument_name == "--data_path") { SetDataPath(argument_value); SetIsSynthetic(false); SetIsCSV(true); @@ -262,7 +281,7 @@ void Configurations::InitializeDataGenerationArguments() { } } if (GetDimension() != DimensionST) { - if (GetTimeSlot() > 1) { + if (GetTimeSlot() != 1) { throw std::runtime_error("Time Slot can only be greater than 1 if the dimensions are set to SpaceTime."); } } else if (GetTimeSlot() < 1) { @@ -289,16 +308,13 @@ void Configurations::InitializeDataModelingArguments() { argument_value = argument.substr(equal_sign_Idx + 1); // Check the argument name and set the corresponding value - if (argument_name == "--distance_metric" || argument_name == "--distanceMetric") { - ParseDistanceMetric(argument_value); - } else if (argument_name == "--max_mle_iterations" || argument_name == "--maxMleIterations") { + if (argument_name == "--max_mle_iterations" || argument_name == "--maxMleIterations" || + argument_name == "--opt_iters") { SetMaxMleIterations(CheckNumericalValue(argument_value)); - } else if (argument_name == "--tolerance") { + } 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 == "--LTS" || argument_name == "--lts" || argument_name == "--Lts") { - SetLowTileSize(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") { @@ -316,7 +332,7 @@ void Configurations::InitializeDataModelingArguments() { } } if (GetComputation() == TILE_LOW_RANK) { -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA if (GetLowTileSize() == 0) { throw domain_error("You need to set the Low tile size, before starting"); } @@ -352,21 +368,21 @@ void Configurations::InitializeDataPredictionArguments() { argument_name = argument.substr(0, equal_sign_Idx); if (argument_name == "--mspe" || argument_name == "--MSPE") { - if (GetUnknownObservationsNb() <= 0) { + if (GetUnknownObservationsNb() <= 1) { throw domain_error( - "You need to set ZMiss number, as the number of missing values should be positive value"); + "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() <= 0) { + if (GetUnknownObservationsNb() <= 1) { throw domain_error( - "You need to set ZMiss number, as the number of missing values should be positive value"); + "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() <= 0) { + if (GetUnknownObservationsNb() <= 1) { throw domain_error( - "You need to set ZMiss number, as the number of missing values should be positive value"); + "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") { @@ -390,7 +406,7 @@ void Configurations::PrintUsage() { LOGGER("--gpus=value : Used to set the number of GPUs.") LOGGER("--dts=value : Used to set the Dense Tile size.") LOGGER("--lts=value : Used to set the Low Tile size.") - LOGGER("--diag_thick=value : Used to set the Tile diagonal thickness.") + LOGGER("--band=value : Used to set the Tile diagonal thickness.") 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.") @@ -490,24 +506,23 @@ 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."); - } else { - // 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); } + // 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) { @@ -628,45 +643,56 @@ void Configurations::PrintSummary() { Verbose temp = this->GetVerbosity(); mVerbosity = STANDARD_MODE; - if (!mIsPrinted) { - LOGGER("********************SUMMARY**********************") - if (this->GetIsSynthetic()) { - LOGGER("#Synthetic Dataset") - } else { - LOGGER("#Real Dataset") - } - LOGGER("#Number of Locations: " << this->GetProblemSize()) - LOGGER("#Threads per node: " << this->GetCoresNumber()) - LOGGER("#GPUs: " << this->GetGPUsNumbers()) - if (this->GetPrecision() == 1) { - LOGGER("#Precision: Double") - } else if (this->GetPrecision() == 0) { - LOGGER("#Precision: Single") - } else if (this->GetPrecision() == 2) { - LOGGER("#Precision: Single/Double") - } - LOGGER("#Dense Tile Size: " << this->GetDenseTileSize()) -#ifdef EXAGEOSTAT_USE_HICMA - LOGGER("#Low Tile Size: " << this->GetLowTileSize()) + LOGGER("********************SUMMARY**********************") + if (this->GetIsSynthetic()) { + LOGGER("#Synthetic Dataset") + } else { + LOGGER("#Real Dataset") + } + LOGGER("#Number of Locations: " << this->GetProblemSize()) + LOGGER("#Threads per node: " << this->GetCoresNumber()) + LOGGER("#GPUs: " << this->GetGPUsNumbers()) + if (this->GetPrecision() == 1) { + LOGGER("#Precision: Double") + } else if (this->GetPrecision() == 0) { + LOGGER("#Precision: Single") + } else if (this->GetPrecision() == 2) { + LOGGER("#Precision: Single/Double") + } + LOGGER("#Dense Tile Size: " << this->GetDenseTileSize()) +#ifdef USE_HICMA + LOGGER("#Low Tile Size: " << this->GetLowTileSize()) #endif - if (this->GetComputation() == TILE_LOW_RANK) { - LOGGER("#Computation: Tile Low Rank") - } else if (this->GetComputation() == EXACT_DENSE) { - LOGGER("#Computation: Exact") - } else if (this->GetComputation() == DIAGONAL_APPROX) { - LOGGER("#Computation: Diagonal Approx") - } - LOGGER("#Kernel: " << this->GetKernelName()) - LOGGER("#p: " << this->GetPGrid() << "\t\t #q: " << this->GetQGrid()) - LOGGER("*************************************************") - mIsPrinted = true; + if (this->GetComputation() == TILE_LOW_RANK) { + LOGGER("#Computation: Tile Low Rank") + } else if (this->GetComputation() == EXACT_DENSE) { + LOGGER("#Computation: Exact") + } else if (this->GetComputation() == DIAGONAL_APPROX) { + LOGGER("#Computation: Diagonal Approx") + } + + if (this->GetDimension() == Dimension2D) { + LOGGER("#Dimension: 2D") + } else if (this->GetDimension() == Dimension3D) { + LOGGER("#Dimension: 3D") + } else if (this->GetDimension() == DimensionST) { + LOGGER("#Dimension: ST") + } + LOGGER("#Kernel: " << this->GetKernelName()) + if (this->GetDistanceMetric() == EUCLIDEAN_DISTANCE) { + LOGGER("#Distance Metric: Euclidean distance") + } else { + LOGGER("#Distance Metric: Great Circle Distance") + } + LOGGER("#p: " << this->GetPGrid() << "\t\t #q: " << this->GetQGrid()) + if (this->GetIsOOC()) { + LOGGER("#Out Of Core (OOC) technology is enabled") } + LOGGER("*************************************************") mVerbosity = temp; } -bool Configurations::mIsPrinted = false; - int Configurations::CalculateZObsNumber() { - return this->GetProblemSize() - GetUnknownObservationsNb(); + return (this->GetProblemSize()) - this->GetUnknownObservationsNb(); } \ No newline at end of file diff --git a/src/data-generators/CMakeLists.txt b/src/data-generators/CMakeLists.txt index 67966b9e..4deb9b32 100644 --- a/src/data-generators/CMakeLists.txt +++ b/src/data-generators/CMakeLists.txt @@ -8,7 +8,7 @@ # @version 1.0.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah -# @date 2023-02-14 +# @date 2024-02-04 # Add subdirectories for concrete implementations add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/concrete) @@ -16,6 +16,7 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/concrete) # Add source files to the parent scope set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/DataGenerator.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/LocationGenerator.cpp ${SOURCES} PARENT_SCOPE ) diff --git a/src/data-generators/DataGenerator.cpp b/src/data-generators/DataGenerator.cpp index 548185a0..8344241a 100644 --- a/src/data-generators/DataGenerator.cpp +++ b/src/data-generators/DataGenerator.cpp @@ -13,28 +13,40 @@ #include #include -#include +#include #include using namespace exageostat::generators; +using namespace exageostat::dataLoader::csv; using namespace exageostat::generators::synthetic; -using namespace exageostat::generators::csv; using namespace exageostat::dataunits; using namespace exageostat::configurations; +using namespace exageostat::common; template std::unique_ptr> DataGenerator::CreateGenerator(Configurations &apConfigurations) { // Check the used Data generation method, whether it's synthetic or real. - mIsSynthetic = apConfigurations.GetIsSynthetic(); - mIsCSV = apConfigurations.GetIsCSV(); - results::Results::GetInstance()->SetIsSynthetic(mIsSynthetic); + if(apConfigurations.GetIsSynthetic() && apConfigurations.GetIsCSV()){ + throw std::domain_error("Please activate either the synthetic or the CSV file for data generation, but not both."); + } + if(!apConfigurations.GetIsSynthetic() && !apConfigurations.GetIsCSV()){ + throw std::domain_error("Please activate either the synthetic or the CSV file for data generation"); + } + if(apConfigurations.GetIsSynthetic()){ + aDataSourceType = SYNTHETIC; + } + else if(apConfigurations.GetIsCSV()){ + aDataSourceType = CSV_FILE; + } + results::Results::GetInstance()->SetIsSynthetic(apConfigurations.GetIsSynthetic()); // Return DataGenerator unique pointer of Synthetic type - if (mIsSynthetic) { + //// TODO: In case of other file support, Then we can create another layer for the factory creation depending on the file size. + if (aDataSourceType == SYNTHETIC) { return std::unique_ptr>(SyntheticGenerator::GetInstance()); - } else if (mIsCSV) { - return std::unique_ptr>(CSVDataGenerator::GetInstance()); + } else if (aDataSourceType == CSV_FILE) { + return std::unique_ptr>(CSVLoader::GetInstance()); } else { throw std::runtime_error("Data Loading for this file type is unsupported for now"); } @@ -43,15 +55,14 @@ std::unique_ptr> DataGenerator::CreateGenerator(Configuratio template DataGenerator::~DataGenerator() { // Return DataGenerator unique pointer of Synthetic type - if (mIsSynthetic) { + if (aDataSourceType == SYNTHETIC) { SyntheticGenerator::GetInstance()->ReleaseInstance(); - } else if (mIsCSV) { - CSVDataGenerator::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); } } -template bool DataGenerator::mIsSynthetic = true; -template bool DataGenerator::mIsCSV = false; +template DataSourceType DataGenerator::aDataSourceType = common::SYNTHETIC; diff --git a/src/data-generators/LocationGenerator.cpp b/src/data-generators/LocationGenerator.cpp new file mode 100644 index 00000000..47acd7fe --- /dev/null +++ b/src/data-generators/LocationGenerator.cpp @@ -0,0 +1,122 @@ + +// Copyright (c) 2017-2023 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 LocationGenerator.cpp + * @brief Generates and manages spatial locations for ExaGeoStat. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @date 2024-02-04 +**/ + +#include +#include + +#include +#include + +using namespace exageostat::generators; +using namespace exageostat::common; +using namespace exageostat::dataunits; +using namespace exageostat::helpers; + +template void LocationGenerator::GenerateLocations(const int &aN, const int &aTimeSlot, const Dimension &aDimension, Locations &aLocations) { + + aLocations.SetSize(aN); + int index = 0; + aLocations.SetDimension(aDimension); + + int rootN; + if (aDimension == Dimension3D) { + //Cubic root. + rootN = ceil(cbrt(aN)); + } else { + //Square root. + rootN = ceil(sqrt(aN)); + } + + int *grid = new int[rootN](); + for (auto i = 0; i < rootN; i++) { + grid[i] = i + 1; + } + T range_low = -0.4, range_high = 0.4; + + for (auto i = 0; i < rootN && index < aN; i++) { + for (auto j = 0; j < rootN && index < aN; j++) { + if (aDimension == Dimension3D) { + for (auto k = 0; k < rootN && index < aN; k++) { + aLocations.GetLocationX()[index] = + (grid[i] - 0.5 + UniformDistribution(range_low, range_high)) / rootN; + aLocations.GetLocationY()[index] = + (grid[j] - 0.5 + UniformDistribution(range_low, range_high)) / rootN; + aLocations.GetLocationZ()[index] = + (grid[k] - 0.5 + UniformDistribution(range_low, range_high)) / rootN; + index++; + } + } else { + aLocations.GetLocationX()[index] = + (grid[i] - 0.5 + UniformDistribution(range_low, range_high)) / rootN; + aLocations.GetLocationY()[index] = + (grid[j] - 0.5 + UniformDistribution(range_low, range_high)) / rootN; + if (aDimension == DimensionST) { + aLocations.GetLocationZ()[index] = 1.0; + } + index++; + } + } + } + delete[] grid; + if (aDimension != DimensionST) { + SortLocations(aN, aDimension, aLocations); + } else { + for (auto i = 0; i < aN; i++) { + aLocations.GetLocationX()[i] = aLocations.GetLocationX()[i]; + aLocations.GetLocationY()[i] = aLocations.GetLocationY()[i]; + aLocations.GetLocationZ()[i] = (T) (i / aTimeSlot + 1); + } + } +} + +template +T LocationGenerator::UniformDistribution(const T &aRangeLow, const T &aRangeHigh) { + T myRand = (T) rand() / (T) (1.0 + RAND_MAX); + T range = aRangeHigh - aRangeLow; + return (myRand * range) + aRangeLow; +} + +template +void +LocationGenerator::SortLocations(const int &aN, const Dimension &aDimension, Locations &aLocations) { + + // Some sorting, required by spatial statistics code + uint16_t x, y, z; + uint64_t vectorZ[aN]; + + // Encode data into vector z + for (auto i = 0; i < aN; i++) { + x = (uint16_t)(aLocations.GetLocationX()[i] * (double) UINT16_MAX + .5); + y = (uint16_t)(aLocations.GetLocationY()[i] * (double) UINT16_MAX + .5); + if (aDimension != Dimension2D) { + z = (uint16_t)(aLocations.GetLocationZ()[i] * (double) UINT16_MAX + .5); + } else { + z = (uint16_t) 0.0; + } + vectorZ[i] = (SpreadBits(z) << 2) + (SpreadBits(y) << 1) + SpreadBits(x); + } + // Sort vector z + std::sort(vectorZ, vectorZ + aN, CompareUint64); + + // Decode data from vector z + for (auto i = 0; i < aN; i++) { + x = ReverseSpreadBits(vectorZ[i] >> 0); + y = ReverseSpreadBits(vectorZ[i] >> 1); + z = ReverseSpreadBits(vectorZ[i] >> 2); + aLocations.GetLocationX()[i] = (double) x / (double) UINT16_MAX; + aLocations.GetLocationY()[i] = (double) y / (double) UINT16_MAX; + if (aDimension == Dimension3D) { + aLocations.GetLocationZ()[i] = (double) z / (double) UINT16_MAX; + } + } +} \ No newline at end of file diff --git a/src/data-generators/concrete/CMakeLists.txt b/src/data-generators/concrete/CMakeLists.txt index 55d821bb..5be7a228 100644 --- a/src/data-generators/concrete/CMakeLists.txt +++ b/src/data-generators/concrete/CMakeLists.txt @@ -13,8 +13,6 @@ # Add source files to the parent scope set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/SyntheticGenerator.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/CSVDataGenerator.cpp - ${SOURCES} PARENT_SCOPE ) \ No newline at end of file diff --git a/src/data-generators/concrete/SyntheticGenerator.cpp b/src/data-generators/concrete/SyntheticGenerator.cpp index 2f21aa6a..0ae3acd5 100644 --- a/src/data-generators/concrete/SyntheticGenerator.cpp +++ b/src/data-generators/concrete/SyntheticGenerator.cpp @@ -6,22 +6,19 @@ /** * @file SyntheticGenerator.cpp * @brief Implementation of the SyntheticGenerator class - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-02-14 **/ #include +#include using namespace exageostat::generators::synthetic; using namespace exageostat::dataunits; -using namespace exageostat::hardware; using namespace exageostat::common; using namespace exageostat::configurations; -using namespace exageostat::kernels; -using namespace exageostat::helpers; -using namespace exageostat::linearAlgebra; template SyntheticGenerator *SyntheticGenerator::GetInstance() { @@ -33,34 +30,29 @@ SyntheticGenerator *SyntheticGenerator::GetInstance() { } template -ExaGeoStatData *SyntheticGenerator::CreateData(exageostat::configurations::Configurations &aConfigurations, - const exageostat::hardware::ExaGeoStatHardware &aHardware, - exageostat::kernels::Kernel &aKernel) { - - auto *data = new ExaGeoStatData(aConfigurations.GetProblemSize(), aConfigurations.GetDimension()); +std::unique_ptr> +SyntheticGenerator::CreateData(exageostat::configurations::Configurations &aConfigurations, + const exageostat::hardware::ExaGeoStatHardware &aHardware, + exageostat::kernels::Kernel &aKernel) { + int n = aConfigurations.GetProblemSize() * aConfigurations.GetTimeSlot(); + auto data = std::make_unique>(n, aConfigurations.GetDimension()); // Allocated new Locations object. - auto *locations = new Locations((aConfigurations.GetProblemSize() * aConfigurations.GetTimeSlot()), - aConfigurations.GetDimension()); - - // Set some kernel and arguments values. - aKernel.SetPValue(aConfigurations.GetTimeSlot()); - int N = aConfigurations.GetProblemSize(); - aConfigurations.SetProblemSize( - aConfigurations.GetProblemSize() * aKernel.GetPValue() / aConfigurations.GetTimeSlot()); + auto *locations = new Locations(n, aConfigurations.GetDimension()); - aConfigurations.SetP(aKernel.GetPValue()); int parameters_number = aKernel.GetParametersNumbers(); // Set initial theta values. Configurations::InitTheta(aConfigurations.GetInitialTheta(), parameters_number); aConfigurations.SetInitialTheta(aConfigurations.GetInitialTheta()); - GenerateLocations(N, aConfigurations.GetTimeSlot(), aConfigurations.GetDimension(), *locations); + // Generate Locations phase + LocationGenerator::GenerateLocations(n, aConfigurations.GetTimeSlot(), aConfigurations.GetDimension(), *locations); data->SetLocations(*locations); - auto linear_algebra_solver = LinearAlgebraFactory::CreateLinearAlgebraSolver(EXACT_DENSE); - linear_algebra_solver->GenerateSyntheticData(aConfigurations, aHardware, *data, aKernel); + // Generate Descriptors phase + auto linear_algebra_solver = linearAlgebra::LinearAlgebraFactory::CreateLinearAlgebraSolver(EXACT_DENSE); + linear_algebra_solver->GenerateSyntheticData(aConfigurations, aHardware, data, aKernel); if (aConfigurations.GetLogger()) { VERBOSE("Writing generated data to the disk (Synthetic Dataset Generation Phase) .....") @@ -71,166 +63,28 @@ ExaGeoStatData *SyntheticGenerator::CreateData(exageostat::configurations: CHAMELEON_Desc2Lap(ChamUpperLower, data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc, pMatrix, aConfigurations.GetProblemSize()); if ( CHAMELEON_Comm_rank == 0 ){ - DiskWriter::WriteVectorsToDisk(*((T *) data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + helpers::DiskWriter::WriteVectorsToDisk(*((T *) data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc->mat), - aConfigurations.GetProblemSize(), aConfigurations.GetP(), path, + aConfigurations.GetProblemSize(), aConfigurations.GetVariablesNumber(), path, *data->GetLocations()); } delete[] pMatrix; #else std::string path = aConfigurations.GetLoggerPath(); - DiskWriter::WriteVectorsToDisk(*((T *) data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + helpers::DiskWriter::WriteVectorsToDisk(*((T *) data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc->mat), - aConfigurations.GetProblemSize(), aConfigurations.GetP(), path, + aConfigurations.GetProblemSize(), aKernel.GetVariablesNumber(), path, *data->GetLocations()); #endif VERBOSE("Done.") } - results::Results::GetInstance()->SetGeneratedLocationsNumber(aConfigurations.GetProblemSize()); + results::Results::GetInstance()->SetGeneratedLocationsNumber(n); results::Results::GetInstance()->SetIsLogger(aConfigurations.GetLogger()); results::Results::GetInstance()->SetLoggerPath(aConfigurations.GetLoggerPath()); return data; } -template -void SyntheticGenerator::GenerateLocations(const int &aN, const int &aTimeSlot, const Dimension &aDimension, - Locations &aLocations) { - - aLocations.SetSize(aN); - int index = 0; - aLocations.SetDimension(aDimension); - - int rootN; - if (aDimension == Dimension3D) { - //Cubic root. - rootN = ceil(cbrt(aN)); - } else { - //Square root. - rootN = ceil(sqrt(aN)); - } - - int *grid = new int[rootN](); - for (auto i = 0; i < rootN; i++) { - grid[i] = i + 1; - } - - double range_low = -0.4, range_high = 0.4; - - for (auto i = 0; i < rootN && index < aN; i++) { - for (auto j = 0; j < rootN && index < aN; j++) { - if (aDimension == Dimension3D) { - for (auto k = 0; k < rootN && index < aN; k++) { - aLocations.GetLocationX()[index] = - (grid[i] - 0.5 + UniformDistribution(range_low, range_high)) / rootN; - aLocations.GetLocationY()[index] = - (grid[j] - 0.5 + UniformDistribution(range_low, range_high)) / rootN; - aLocations.GetLocationZ()[index] = - (grid[k] - 0.5 + UniformDistribution(range_low, range_high)) / rootN; - index++; - } - } else { - aLocations.GetLocationX()[index] = (grid[i] - 0.5 + UniformDistribution(range_low, range_high)) / rootN; - aLocations.GetLocationY()[index] = (grid[j] - 0.5 + UniformDistribution(range_low, range_high)) / rootN; - if (aDimension == DimensionST) { - aLocations.GetLocationZ()[index] = 1.0; - } - index++; - } - } - } - delete[] grid; - if (aDimension != DimensionST) { - SortLocations(aN, aDimension, aLocations); - } else { - for (auto j = 1; j < aTimeSlot; j++) { - for (auto i = 0; i < aN; i++) { - aLocations.GetLocationX()[i + j * aN] = aLocations.GetLocationX()[i]; - aLocations.GetLocationY()[i + j * aN] = aLocations.GetLocationY()[i]; - aLocations.GetLocationZ()[i + j * aN] = (double) (j + 1); - } - } - } -} - -template -double SyntheticGenerator::UniformDistribution(const double &aRangeLow, const double &aRangeHigh) { - double myRand = (double) rand() / (double) (1.0 + RAND_MAX); - double range = aRangeHigh - aRangeLow; - return (myRand * range) + aRangeLow; -} - -template -void SyntheticGenerator::SortLocations(const int &aN, const Dimension &aDimension, Locations &aLocations) { - - // Some sorting, required by spatial statistics code - uint16_t x, y, z; - uint64_t vectorZ[aN]; - - // Encode data into vector z - for (auto i = 0; i < aN; i++) { - x = (uint16_t) (aLocations.GetLocationX()[i] * (double) UINT16_MAX + .5); - y = (uint16_t) (aLocations.GetLocationY()[i] * (double) UINT16_MAX + .5); - if (aDimension != Dimension2D) { - z = (uint16_t) (aLocations.GetLocationZ()[i] * (double) UINT16_MAX + .5); - } else { - z = (uint16_t) 0.0; - } - vectorZ[i] = (SpreadBits(z) << 2) + (SpreadBits(y) << 1) + SpreadBits(x); - } - // Sort vector z - std::sort(vectorZ, vectorZ + aN, CompareUint64); - - // Decode data from vector z - for (auto i = 0; i < aN; i++) { - x = ReverseSpreadBits(vectorZ[i] >> 0); - y = ReverseSpreadBits(vectorZ[i] >> 1); - z = ReverseSpreadBits(vectorZ[i] >> 2); - aLocations.GetLocationX()[i] = (double) x / (double) UINT16_MAX; - aLocations.GetLocationY()[i] = (double) y / (double) UINT16_MAX; - if (aDimension == Dimension3D) { - aLocations.GetLocationZ()[i] = (double) z / (double) UINT16_MAX; - } - } -} - -template -uint64_t SyntheticGenerator::SpreadBits(uint64_t aInputByte) { - aInputByte &= 0x000000000000ffff; - // aInputByte = ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- fedc ba98 7654 3210 - aInputByte = (aInputByte ^ (aInputByte << 24)) & 0x000000ff000000ff; - // aInputByte = ---- ---- ---- ---- ---- ---- fedc ba98 ---- ---- ---- ---- ---- ---- 7654 3210 - aInputByte = (aInputByte ^ (aInputByte << 12)) & 0x000f000f000f000f; //000 7000f000f000f - // aInputByte = ---- ---- ---- fedc ---- ---- ---- ba98 ---- ---- ---- 7654 ---- ---- ---- 3210 - aInputByte = (aInputByte ^ (aInputByte << 6)) & 0x0303030303030303; //0 0001 0 0011 0 0011 0 0011 0 - // aInputByte = ---- --fe ---- --dc ---- --ba ---- --98 ---- --76 ---- --54 ---- --32 ---- --10 - aInputByte = (aInputByte ^ (aInputByte << 3)) & 0x1111111111111111; - // aInputByte = ---f ---e ---d ---c ---b ---a ---9 ---8 ---7 ---6 ---5 ---4 ---3 ---2 ---1 ---0 - return aInputByte; -} - -template -uint64_t SyntheticGenerator::ReverseSpreadBits(uint64_t aInputByte) { - - aInputByte &= 0x1111111111111111; - // aInputByte = ---f ---e ---d ---c ---b ---a ---9 ---8 ---7 ---6 ---5 ---4 ---3 ---2 ---1 ---0 - aInputByte = (aInputByte ^ (aInputByte >> 3)) & 0x0303030303030303; - // aInputByte = ---- --fe ---- --dc ---- --ba ---- --98 ---- --76 ---- --54 ---- --32 ---- --10 - aInputByte = (aInputByte ^ (aInputByte >> 6)) & 0x000f000f000f000f; - // aInputByte = ---- ---- ---- fedc ---- ---- ---- ba98 ---- ---- ---- 7654 ---- ---- ---- 3210 - aInputByte = (aInputByte ^ (aInputByte >> 12)) & 0x000000ff000000ff; - // aInputByte = ---- ---- ---- ---- ---- ---- fedc ba98 ---- ---- ---- ---- ---- ---- 7654 3210 - aInputByte = (aInputByte ^ (aInputByte >> 24)) & 0x000000000000ffff; - // aInputByte = ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- fedc ba98 7654 3210 - return aInputByte; - -} - -template -bool SyntheticGenerator::CompareUint64(const uint64_t &aFirstValue, const uint64_t &aSecondValue) { - return aFirstValue < aSecondValue; -} - template void SyntheticGenerator::ReleaseInstance() { if (mpInstance != nullptr) { diff --git a/src/data-loader/CMakeLists.txt b/src/data-loader/CMakeLists.txt new file mode 100644 index 00000000..1c5d2e4c --- /dev/null +++ b/src/data-loader/CMakeLists.txt @@ -0,0 +1,20 @@ + +# Copyright (c) 2017-2023 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 loader module +# @version 1.0.0 +# @author Mahmoud ElKarargy +# @date 2023-02-14 + +# Add subdirectories for concrete implementations +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/concrete) + +# Add source files to the parent scope +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/DataLoader.cpp + ${SOURCES} + PARENT_SCOPE + ) diff --git a/src/data-loader/DataLoader.cpp b/src/data-loader/DataLoader.cpp new file mode 100644 index 00000000..6fc7dffa --- /dev/null +++ b/src/data-loader/DataLoader.cpp @@ -0,0 +1,70 @@ + +// Copyright (c) 2017-2023 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.0.1 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2023-02-14 +**/ + +#include + +using namespace std; + +using namespace exageostat::dataLoader; +using namespace exageostat::dataunits; +using namespace exageostat::common; + +template +std::unique_ptr> +DataLoader::CreateData(exageostat::configurations::Configurations &aConfigurations, + const exageostat::hardware::ExaGeoStatHardware &aHardware, + 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->SetContext(aHardware.GetChameleonContext()); + 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::Results::GetInstance()->SetGeneratedLocationsNumber(aConfigurations.GetProblemSize() / p); + results::Results::GetInstance()->SetIsLogger(aConfigurations.GetLogger()); + results::Results::GetInstance()->SetLoggerPath(aConfigurations.GetLoggerPath()); + + return data; +} diff --git a/src/data-loader/concrete/CMakeLists.txt b/src/data-loader/concrete/CMakeLists.txt new file mode 100644 index 00000000..6bc7013a --- /dev/null +++ b/src/data-loader/concrete/CMakeLists.txt @@ -0,0 +1,17 @@ + +# Copyright (c) 2017-2023 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 the data loader module +# @version 1.0.1 +# @author Mahmoud ElKarargy +# @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 diff --git a/src/data-generators/concrete/CSVDataGenerator.cpp b/src/data-loader/concrete/CSVLoader.cpp similarity index 58% rename from src/data-generators/concrete/CSVDataGenerator.cpp rename to src/data-loader/concrete/CSVLoader.cpp index 820a9fab..32a79331 100644 --- a/src/data-generators/concrete/CSVDataGenerator.cpp +++ b/src/data-loader/concrete/CSVLoader.cpp @@ -6,7 +6,7 @@ /** * @file CSVDataGenerator.cpp * @brief Implementation of the CSVDataGenerator class - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-02-14 @@ -14,78 +14,30 @@ #include -#include +#include using namespace std; -using namespace exageostat::generators::csv; using namespace exageostat::configurations; using namespace exageostat::hardware; using namespace exageostat::dataunits; using namespace exageostat::kernels; using namespace exageostat::common; using namespace exageostat::linearAlgebra; +using namespace exageostat::dataLoader::csv; template -CSVDataGenerator *CSVDataGenerator::GetInstance() { +CSVLoader *CSVLoader::GetInstance() { if (mpInstance == nullptr) { - mpInstance = new CSVDataGenerator(); + mpInstance = new CSVLoader(); } return mpInstance; } template -ExaGeoStatData *CSVDataGenerator::CreateData(exageostat::configurations::Configurations &aConfigurations, - const exageostat::hardware::ExaGeoStatHardware &aHardware, - 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()); - aConfigurations.SetP(aKernel.GetPValue()); - int p = aConfigurations.GetP(); - - //Read the data out of the CSV file. - ReadData(aConfigurations, measurements_vector, x_locations, y_locations, z_locations); - - //create data object - auto *data = new ExaGeoStatData(aConfigurations.GetProblemSize() / p, aConfigurations.GetDimension()); - - //Initialize the descriptors. - auto linear_algebra_solver = LinearAlgebraFactory::CreateLinearAlgebraSolver(EXACT_DENSE); - linear_algebra_solver->SetContext(aHardware.GetChameleonContext()); - linear_algebra_solver->InitiateDescriptors(aConfigurations, *data->GetDescriptorData()); - 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::Results::GetInstance()->SetGeneratedLocationsNumber(aConfigurations.GetProblemSize()); - results::Results::GetInstance()->SetIsLogger(aConfigurations.GetLogger()); - results::Results::GetInstance()->SetLoggerPath(aConfigurations.GetLoggerPath()); - - return data; -} - -template -void -CSVDataGenerator::ReadData(Configurations &aConfigurations, - vector &aMeasurementsMatrix, vector &aXLocations, - vector &aYLocations, vector &aZLocations) { +void CSVLoader::ReadData(Configurations &aConfigurations, vector &aMeasurementsMatrix, vector &aXLocations, + vector &aYLocations, vector &aZLocations, const int &aP) { //Check if the user entered a valid path for the CSV file. if (aConfigurations.GetDataPath().empty()) { @@ -94,7 +46,6 @@ CSVDataGenerator::ReadData(Configurations &aConfigurations, string data_path = aConfigurations.GetDataPath(); Dimension dimension = aConfigurations.GetDimension(); - int p = aConfigurations.GetP(); ifstream file; file.open(data_path, ios::in); @@ -120,13 +71,13 @@ CSVDataGenerator::ReadData(Configurations &aConfigurations, aYLocations.push_back(stod(token)); } if (getline(iss, token, ',')) { - //If it's a 2D locations data, the last values of the lines should be the measurement values. - //If it's 3D locations data, the third value of the line should be the Z coordinate. - //If it's ST location data, the third value of the line should be the Time coordinate + //If its a 2D locations' data, the last values of the lines should be the measurement values. + //If its 3D locations' data, the third value of the line should be the Z coordinate. + //If its ST location data, the third value of the line should be the Time coordinate if (dimension == Dimension2D) { aMeasurementsMatrix.push_back(stod(token)); //if p == 2, the third and fourth values of each line are saved in the Measurements Matrix. - if (p == 2) { + if (aP == 2) { if (getline(iss, token, ',')) { aMeasurementsMatrix.push_back(stod(token)); } else { @@ -134,7 +85,7 @@ CSVDataGenerator::ReadData(Configurations &aConfigurations, "The data P in the provided file isn't consistent with the Kernel's P."); } } - if (p == 3) { + if (aP == 3) { //if p == 3, the third, fourth, and fifth values of each line are saved in the Measurements Matrix. if (getline(iss, token, ',')) { aMeasurementsMatrix.push_back(stod(token)); @@ -155,7 +106,7 @@ CSVDataGenerator::ReadData(Configurations &aConfigurations, if (dimension != Dimension2D) { aMeasurementsMatrix.push_back(stod(token)); //if p == 2, the fourth and fifth values of each line are saved in the Measurements Matrix. - if (p == 2) { + if (aP == 2) { if (getline(iss, token, ',')) { aMeasurementsMatrix.push_back(stod(token)); } else { @@ -163,7 +114,7 @@ CSVDataGenerator::ReadData(Configurations &aConfigurations, "The data P in the provided file isn't consistent with the Kernel's P."); } } - if (p == 3) { + if (aP == 3) { //if p == 3, the fourth, fifth, and sixth values of each line are saved in the Measurements Matrix. if (getline(iss, token, ',')) { aMeasurementsMatrix.push_back(stod(token)); @@ -186,16 +137,16 @@ CSVDataGenerator::ReadData(Configurations &aConfigurations, } //problem size is equal to the number of the CSV lines * P / aConfigurations.GetTimeSlot(). - aConfigurations.SetProblemSize(index * p / aConfigurations.GetTimeSlot()); + aConfigurations.SetProblemSize(index * aP / aConfigurations.GetTimeSlot()); file.close(); } template -void CSVDataGenerator::ReleaseInstance() { +void CSVLoader::ReleaseInstance() { if (mpInstance != nullptr) { mpInstance = nullptr; } } -template CSVDataGenerator *CSVDataGenerator::mpInstance = nullptr; +template CSVLoader *CSVLoader::mpInstance = nullptr; diff --git a/src/data-units/DescriptorData.cpp b/src/data-units/DescriptorData.cpp index b64f9d03..c74ee931 100644 --- a/src/data-units/DescriptorData.cpp +++ b/src/data-units/DescriptorData.cpp @@ -6,7 +6,7 @@ /** * @file DescriptorData.cpp * @brief Contains the definition of the DescriptorData class. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-07-18 @@ -29,7 +29,7 @@ DescriptorData::~DescriptorData() { const std::string &key = pair.first; if (key.find("CHAMELEON") != std::string::npos && pair.second != nullptr) { exaGeoStatDescriptor.DestroyDescriptor(common::CHAMELEON_DESCRIPTOR, pair.second); -#ifdef EXAGEOSTAT_USE_HICMA +#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. std::string converted_chameleon = key.substr(0, key.length() - chameleon.length()); @@ -70,7 +70,7 @@ void *DescriptorData::GetRequest() { return this->mpRequest; } -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA template HICMA_desc_t *DescriptorData::ConvertChameleonToHicma(CHAM_desc_t *apChameleonDesc) { @@ -115,7 +115,7 @@ DescriptorData::GetDescriptor(const DescriptorType &aDescriptorType, const De descriptor.chameleon_desc = (CHAM_desc_t *) this->mDictionary[GetDescriptorName(aDescriptorName) + "_CHAMELEON"]; } else { -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA if (this->mDictionary.find(GetDescriptorName(aDescriptorName) + "_HICMA") != this->mDictionary.end()) { descriptor.hicma_desc = (HICMA_desc_t *) this->mDictionary[GetDescriptorName(aDescriptorName) + "_HICMA"]; @@ -132,7 +132,7 @@ DescriptorData::GetDescriptor(const DescriptorType &aDescriptorType, const De descriptor.hicma_desc = nullptr; } #else - throw std::runtime_error("To use HiCMA descriptor you need to enable EXAGEOSTAT_USE_HICMA!"); + throw std::runtime_error("To use HiCMA descriptor you need to enable USE_HICMA!"); #endif } return descriptor; @@ -143,7 +143,7 @@ void DescriptorData::SetDescriptor(const DescriptorType &aDescriptorType, con 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 int &aQ, const bool &aValidOOC) { void *descriptor; std::string type; @@ -151,17 +151,17 @@ void DescriptorData::SetDescriptor(const DescriptorType &aDescriptorType, con if (aDescriptorType == CHAMELEON_DESCRIPTOR) { descriptor = exaGeoStatDescriptor.CreateDescriptor((CHAM_desc_t *) descriptor, aDescriptorType, aIsOOC, apMatrix, aFloatPoint, aMB, aNB, aSize, aLM, aLN, aI, aJ, aM, - aN, aP, aQ); + aN, aP, aQ, aValidOOC); type = "_CHAMELEON"; } else { -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA descriptor = exaGeoStatDescriptor.CreateDescriptor((HICMA_desc_t *) descriptor, aDescriptorType, aIsOOC, apMatrix, aFloatPoint, aMB, aNB, aSize, aLM, aLN, aI, aJ, aM, - aN, aP, aQ); + aN, aP, aQ, aValidOOC); type = "_HICMA"; #else - throw std::runtime_error("To create HiCMA descriptor you need to enable EXAGEOSTAT_USE_HICMA!"); + throw std::runtime_error("To create HiCMA descriptor you need to enable USE_HICMA!"); #endif } @@ -173,10 +173,10 @@ T *DescriptorData::GetDescriptorMatrix(const common::DescriptorType &aDescrip if (aDescriptorType == common::CHAMELEON_DESCRIPTOR) { return (T *) ((CHAM_desc_t *) apDesc)->mat; } else { -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA return (T *) ((HICMA_desc_t *) apDesc)->mat; #else - throw std::runtime_error("To use Hicma descriptor you need to enable EXAGEOSTAT_USE_HICMA!"); + throw std::runtime_error("To use Hicma descriptor you need to enable USE_HICMA!"); #endif } } @@ -289,6 +289,12 @@ std::string DescriptorData::GetDescriptorName(const DescriptorName &aDescript return "DESCRIPTOR_C_TRACE"; case DESCRIPTOR_C_DIAG : return "DESCRIPTOR_C_DIAG"; + case DESCRIPTOR_SUM : + return "DESCRIPTOR_SUM"; + case DESCRIPTOR_R : + return "DESCRIPTOR_R"; + case DESCRIPTOR_R_COPY : + return "DESCRIPTOR_R_COPY"; 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/ExaGeoStatDescriptor.cpp b/src/data-units/descriptor/ExaGeoStatDescriptor.cpp index 38e104d9..19eeb6ab 100644 --- a/src/data-units/descriptor/ExaGeoStatDescriptor.cpp +++ b/src/data-units/descriptor/ExaGeoStatDescriptor.cpp @@ -6,7 +6,7 @@ /** * @file ExaGeoStatDescriptor.cpp * @brief Implementation of creating matrix descriptors used in CHAMELEON and HiCMA libraries. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-07-17 @@ -14,7 +14,7 @@ #include -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA #include @@ -27,19 +27,19 @@ using namespace exageostat::dataunits::descriptor; template void * -ExaGeoStatDescriptor::CreateDescriptor(void *apDescriptor, const DescriptorType &aDescriptorType, 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) { +ExaGeoStatDescriptor::CreateDescriptor(void *apDescriptor, const common::DescriptorType &aDescriptorType, + 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) { if (aDescriptorType == CHAMELEON_DESCRIPTOR) { return ChameleonDescriptor::CreateChameleonDescriptor(apDescriptor, aIsOOC, apMatrix, aFloatPoint, aMB, aNB, - aSize, aLM, aLN, aI, aJ, aM, aN, aP, aQ); + aSize, aLM, aLN, aI, aJ, aM, aN, aP, aQ, aValidOOC); } else if (aDescriptorType == HICMA_DESCRIPTOR) { -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA return HicmaDescriptor::CreateHicmaDescriptor(apDescriptor, aIsOOC, apMatrix, aFloatPoint, aMB, aNB, aSize, - aLM, aLN, aI, aJ, aM, aN, aP, aQ); + aLM, aLN, aI, aJ, aM, aN, aP, aQ, aValidOOC); #endif } std::cerr << "Error, please select the correct descriptor type!" << std::endl; @@ -51,7 +51,7 @@ int ExaGeoStatDescriptor::DestroyDescriptor(const DescriptorType &aDescriptor if (aDescriptorType == CHAMELEON_DESCRIPTOR) { return ChameleonDescriptor::DestroyChameleonDescriptor(apDesc); } else if (aDescriptorType == HICMA_DESCRIPTOR) { -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA return HicmaDescriptor::DestroyHicmaDescriptor(apDesc); #endif } diff --git a/src/data-units/descriptor/concrete/CMakeLists.txt b/src/data-units/descriptor/concrete/CMakeLists.txt index 291edada..af483ee9 100644 --- a/src/data-units/descriptor/concrete/CMakeLists.txt +++ b/src/data-units/descriptor/concrete/CMakeLists.txt @@ -4,7 +4,7 @@ # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.0.1 # @brief CMake build script for the descriptors library, which includes the concrete implementations of the # Descriptors class based on the enabled libraries (HiCMA or Chameleon). # @author Mahmoud ElKarargy @@ -17,7 +17,7 @@ set(SOURCES ${SOURCES} ) -if (EXAGEOSTAT_USE_HICMA) +if (USE_HICMA) list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/HicmaDescriptor.cpp ) diff --git a/src/data-units/descriptor/concrete/ChameleonDescriptor.cpp b/src/data-units/descriptor/concrete/ChameleonDescriptor.cpp index 75984603..bb62abc8 100644 --- a/src/data-units/descriptor/concrete/ChameleonDescriptor.cpp +++ b/src/data-units/descriptor/concrete/ChameleonDescriptor.cpp @@ -6,7 +6,7 @@ /** * @file ChameleonDescriptor.cpp * @brief Defines the ChameleonDescriptor class for creating matrix descriptors using the CHAMELEON library. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-08-15 @@ -22,9 +22,9 @@ CHAM_desc_t *ChameleonDescriptor::CreateChameleonDescriptor(void *apDescripto 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 int &aQ, const bool &aValidOOC) { auto chameleon_desc = (CHAM_desc_t *) apDescriptor; - if (aIsOOC && apMatrix == nullptr && aMB != 1 && aNB != 1) { + if (aIsOOC && apMatrix == nullptr && aMB != 1 && aNB != 1 && aValidOOC) { CHAMELEON_Desc_Create_OOC(&chameleon_desc, (cham_flttype_t) aFloatPoint, aMB, aNB, aSize, aLM, aLN, aI, aJ, aM, aN, aP, aQ); } else { diff --git a/src/data-units/descriptor/concrete/HicmaDescriptor.cpp b/src/data-units/descriptor/concrete/HicmaDescriptor.cpp index 8aa5f011..88650700 100644 --- a/src/data-units/descriptor/concrete/HicmaDescriptor.cpp +++ b/src/data-units/descriptor/concrete/HicmaDescriptor.cpp @@ -6,7 +6,7 @@ /** * @file HicmaDescriptor.cpp * @brief Defines the Hicma Descriptor class for creating matrix descriptors using the HICMA library. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-08-15 @@ -20,9 +20,9 @@ HICMA_desc_t *HicmaDescriptor::CreateHicmaDescriptor(void *apDescriptor, cons 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 int &aN, const int &aP, const int &aQ, const bool &aValidOOC) { auto hicma_desc = (HICMA_desc_t *) apDescriptor; - if (aIsOOC && apMatrix == nullptr && aMB != 1 && aNB != 1) { + if (aIsOOC && apMatrix == nullptr && aMB != 1 && aNB != 1 && aValidOOC) { HICMA_Desc_Create_OOC(&hicma_desc, (HICMA_enum) aFloatPoint, aMB, aNB, aSize, aLM, aLN, aI, aJ, aM, aN, aP, aQ); } else { HICMA_Desc_Create(&hicma_desc, apMatrix, (HICMA_enum) aFloatPoint, aMB, aNB, aSize, aLM, aLN, aI, aJ, aM, aN, diff --git a/src/hardware/ExaGeoStatHardware.cpp b/src/hardware/ExaGeoStatHardware.cpp index 7419c4dc..7f2c38e6 100644 --- a/src/hardware/ExaGeoStatHardware.cpp +++ b/src/hardware/ExaGeoStatHardware.cpp @@ -6,10 +6,10 @@ /** * @file ExaGeoStatHardware.cpp * @brief Contains the implementation of the ExaGeoStatHardware class. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-08-07 + * @date 2024-01-24 **/ #include @@ -17,55 +17,50 @@ #include #include #include +#include using namespace exageostat::hardware; ExaGeoStatHardware::ExaGeoStatHardware(const common::Computation &aComputation, const int &aCoreNumber, const int &aGpuNumber) { - + LOGGER("** Initialise ExaGeoStat hardware **") this->mComputation = aComputation; int tag_width = 31, tag_sep = 26; + // Init hardware using Chameleon - if (!this->mpChameleonContext) { + if (!mpChameleonContext) { CHAMELEON_user_tag_size(tag_width, tag_sep); CHAMELEON_Init(aCoreNumber, aGpuNumber) - this->mpChameleonContext = chameleon_context_self(); + mpChameleonContext = chameleon_context_self(); } // Init hardware using Hicma if (aComputation == common::TILE_LOW_RANK) { -#ifdef EXAGEOSTAT_USE_HICMA - if (!this->mpHicmaContext) { +#ifdef USE_HICMA + if (!mpHicmaContext) { HICMA_user_tag_size(tag_width, tag_sep); HICMA_Init(aCoreNumber, aGpuNumber); - this->mpHicmaContext = hicma_context_self(); + mpHicmaContext = hicma_context_self(); } #else - throw std::runtime_error("You need to enable Hicma to use TLR computation!"); + throw std::runtime_error("You need to enable HiCMA to use TLR computation!"); #endif } helpers::CommunicatorMPI::GetInstance()->SetHardwareInitialization(); } ExaGeoStatHardware::~ExaGeoStatHardware() { - // finalize hardware using Hicma // finalize hardware using Chameleon - if (!this->mpChameleonContext) { - std::cerr << "No initialized context of Chameleon, Please initialize a hardware first" << std::endl; - exit(1); - } else { + if (mpChameleonContext) { CHAMELEON_Finalize() - this->mpChameleonContext = nullptr; + mpChameleonContext = nullptr; } + // finalize hardware using HiCMA if (this->mComputation == common::TILE_LOW_RANK) { -#ifdef EXAGEOSTAT_USE_HICMA - if (!this->mpHicmaContext) { - std::cout - << "No initialized context of HiCMA, Please use 'ExaGeoStatHardware::ExaGeoStatHardware(aComputation, CoreNumber, aGpuNumber);'" - << std::endl; - } else { +#ifdef USE_HICMA + if (mpHicmaContext) { HICMA_Finalize(); - this->mpHicmaContext = nullptr; + mpHicmaContext = nullptr; } #endif } @@ -73,32 +68,29 @@ ExaGeoStatHardware::~ExaGeoStatHardware() { results::Results::GetInstance()->PrintEndSummary(); } -#ifdef EXAGEOSTAT_USE_HICMA - -void *ExaGeoStatHardware::GetHicmaContext() const { - if (!this->mpHicmaContext) { - throw std::runtime_error("Hardware is not initialized!"); +void *ExaGeoStatHardware::GetHicmaContext() { + if (!mpHicmaContext) { + throw std::runtime_error("HiCMA Hardware is not initialized!"); } - return this->mpHicmaContext; + return mpHicmaContext; } -#endif - -void *ExaGeoStatHardware::GetChameleonContext() const { - if (!this->mpChameleonContext) { - throw std::runtime_error("Hardware is not initialized!"); +void *ExaGeoStatHardware::GetChameleonContext() { + if (!mpChameleonContext) { + throw std::runtime_error("Chameleon Hardware is not initialized!"); } - return this->mpChameleonContext; + return mpChameleonContext; } -void *ExaGeoStatHardware::GetContext(common::Computation aComputation) const { +void *ExaGeoStatHardware::GetContext(common::Computation aComputation) { if (aComputation == common::EXACT_DENSE || aComputation == common::DIAGONAL_APPROX) { return GetChameleonContext(); } if (aComputation == common::TILE_LOW_RANK) { -#ifdef EXAGEOSTAT_USE_HICMA return GetHicmaContext(); -#endif } return nullptr; } + +void * ExaGeoStatHardware::mpChameleonContext = nullptr; +void * ExaGeoStatHardware::mpHicmaContext = nullptr; \ No newline at end of file diff --git a/src/helpers/BasselFunction.cpp b/src/helpers/BasselFunction.cpp new file mode 100644 index 00000000..79540be8 --- /dev/null +++ b/src/helpers/BasselFunction.cpp @@ -0,0 +1,44 @@ + +// Copyright (c) 2017-2023 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 BasselFunction + * @brief This file contains the BasselFunction class which provides methods for computing derivatives of the modified Bessel function of the second kind. These functions are crucial in statistical and mathematical computations, especially in fields such as geostatistics and spatial analysis. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-01-24 +**/ + +extern "C" { +#include +} + +#include + +using namespace exageostat::helpers; + +template +T BasselFunction::CalculateDerivativeBesselNu(const T &aOrder, const T &aInputValue) { + if (aOrder == 0) { + return 0; + } else { + // Use a small step size to calculate the derivative numerically + const T step_size = 0.000000001; + return (gsl_sf_bessel_Knu(aOrder + step_size, aInputValue) - gsl_sf_bessel_Knu(aOrder, aInputValue)) / + step_size; + } +} + +template +T BasselFunction::CalculateSecondDerivativeBesselNu(const T &aOrder, const T &aInputValue) { + return (-0.5 * (CalculateSecondDerivativeBesselNuInput(aOrder - 1, aInputValue) + + CalculateSecondDerivativeBesselNuInput(aOrder + 1, aInputValue))); +} + +template +T BasselFunction::CalculateSecondDerivativeBesselNuInput(const T &aOrder, const T &aInputValue) { + return (aOrder / aInputValue * gsl_sf_bessel_Knu(aOrder, aInputValue) - gsl_sf_bessel_Knu(aOrder + 1, aInputValue)); +} diff --git a/src/helpers/ByteHandler.cpp b/src/helpers/ByteHandler.cpp new file mode 100644 index 00000000..da38c2bb --- /dev/null +++ b/src/helpers/ByteHandler.cpp @@ -0,0 +1,52 @@ + +// Copyright (c) 2017-2023 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 ByteHandler.hpp + * @brief Implementation of byte manipulation functions for ExaGeoStat. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-01-24 +**/ + +#include + +namespace exageostat::helpers { + + uint64_t SpreadBits(uint64_t aInputByte) { + + aInputByte &= 0x000000000000ffff; + // aInputByte = ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- fedc ba98 7654 3210 + aInputByte = (aInputByte ^ (aInputByte << 24)) & 0x000000ff000000ff; + // aInputByte = ---- ---- ---- ---- ---- ---- fedc ba98 ---- ---- ---- ---- ---- ---- 7654 3210 + aInputByte = (aInputByte ^ (aInputByte << 12)) & 0x000f000f000f000f; //000 7000f000f000f + // aInputByte = ---- ---- ---- fedc ---- ---- ---- ba98 ---- ---- ---- 7654 ---- ---- ---- 3210 + aInputByte = (aInputByte ^ (aInputByte << 6)) & 0x0303030303030303; //0 0001 0 0011 0 0011 0 0011 0 + // aInputByte = ---- --fe ---- --dc ---- --ba ---- --98 ---- --76 ---- --54 ---- --32 ---- --10 + aInputByte = (aInputByte ^ (aInputByte << 3)) & 0x1111111111111111; + // aInputByte = ---f ---e ---d ---c ---b ---a ---9 ---8 ---7 ---6 ---5 ---4 ---3 ---2 ---1 ---0 + return aInputByte; + } + + uint64_t ReverseSpreadBits(uint64_t aInputByte) { + + aInputByte &= 0x1111111111111111; + // aInputByte = ---f ---e ---d ---c ---b ---a ---9 ---8 ---7 ---6 ---5 ---4 ---3 ---2 ---1 ---0 + aInputByte = (aInputByte ^ (aInputByte >> 3)) & 0x0303030303030303; + // aInputByte = ---- --fe ---- --dc ---- --ba ---- --98 ---- --76 ---- --54 ---- --32 ---- --10 + aInputByte = (aInputByte ^ (aInputByte >> 6)) & 0x000f000f000f000f; + // aInputByte = ---- ---- ---- fedc ---- ---- ---- ba98 ---- ---- ---- 7654 ---- ---- ---- 3210 + aInputByte = (aInputByte ^ (aInputByte >> 12)) & 0x000000ff000000ff; + // aInputByte = ---- ---- ---- ---- ---- ---- fedc ba98 ---- ---- ---- ---- ---- ---- 7654 3210 + aInputByte = (aInputByte ^ (aInputByte >> 24)) & 0x000000000000ffff; + // aInputByte = ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- fedc ba98 7654 3210 + return aInputByte; + } + + bool CompareUint64(const uint64_t &aFirstValue, const uint64_t &aSecondValue) { + return aFirstValue < aSecondValue; + } +} \ No newline at end of file diff --git a/src/helpers/CMakeLists.txt b/src/helpers/CMakeLists.txt index 5c01b62a..af5f9ae7 100644 --- a/src/helpers/CMakeLists.txt +++ b/src/helpers/CMakeLists.txt @@ -13,6 +13,8 @@ set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/DiskWriter.cpp ${CMAKE_CURRENT_SOURCE_DIR}/DistanceCalculationHelpers.cpp ${CMAKE_CURRENT_SOURCE_DIR}/CommunicatorMPI.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ByteHandler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/BasselFunction.cpp ${SOURCES} PARENT_SCOPE ) \ No newline at end of file diff --git a/src/helpers/CommunicatorMPI.cpp b/src/helpers/CommunicatorMPI.cpp index 488f386a..e9167c4b 100644 --- a/src/helpers/CommunicatorMPI.cpp +++ b/src/helpers/CommunicatorMPI.cpp @@ -6,7 +6,7 @@ /** * @file CommunicatorMPI.cpp * @brief Defines the CommunicatorMPI class for MPI rank communication. - * @version 1.0.0 + * @version 1.0.1 * @author Sameh Abdulah * @date 2023-11-10 **/ @@ -25,6 +25,7 @@ CommunicatorMPI *CommunicatorMPI::GetInstance() { bool CommunicatorMPI::GetRank() const { +#ifdef USE_MPI if(!this->mIsHardwareInitialized){ return false; } @@ -34,6 +35,9 @@ bool CommunicatorMPI::GetRank() const { } return false; } +#else + return true; +#endif } void CommunicatorMPI::SetHardwareInitialization() { diff --git a/src/helpers/DiskWriter.cpp b/src/helpers/DiskWriter.cpp index b168c634..99a3668f 100644 --- a/src/helpers/DiskWriter.cpp +++ b/src/helpers/DiskWriter.cpp @@ -12,11 +12,10 @@ * @date 2023-06-08 **/ -#include #include -#include #include + using namespace std; using namespace exageostat::helpers; @@ -111,4 +110,4 @@ void DiskWriter::WriteVectorsToDisk(const T &aMatrixPointer, const int &aProb } } p_file_synthetic.close(); -} +} \ No newline at end of file diff --git a/src/helpers/DistanceCalculationHelpers.cpp b/src/helpers/DistanceCalculationHelpers.cpp index 9ca5d61c..3ee132cb 100644 --- a/src/helpers/DistanceCalculationHelpers.cpp +++ b/src/helpers/DistanceCalculationHelpers.cpp @@ -6,7 +6,7 @@ /** * @file DistanceCalculationHelpers.cpp * @brief Contains the implementation of the DistanceCalculationHelpers class. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-06-08 @@ -18,14 +18,14 @@ using namespace exageostat::helpers; -//convert degree to radian -static double DegreeToRadian(double aDegree) { +template +T DistanceCalculationHelpers::DegreeToRadian(T aDegree) { return (aDegree * PI / 180); } template T DistanceCalculationHelpers::DistanceEarth(T &aLatitude1, T &aLongitude1, T &aLatitude2, T &aLongitude2) { - double lat1r, lon1r, lat2r, lon2r, u, v; + T lat1r, lon1r, lat2r, lon2r, u, v; lat1r = DegreeToRadian(aLatitude1); lon1r = DegreeToRadian(aLongitude1); lat2r = DegreeToRadian(aLatitude2); diff --git a/src/kernels/CMakeLists.txt b/src/kernels/CMakeLists.txt index 6b89f681..7a8a55da 100644 --- a/src/kernels/CMakeLists.txt +++ b/src/kernels/CMakeLists.txt @@ -5,34 +5,18 @@ # @file CMakeLists.txt # @brief This file contains the CMake configuration for the kernels directory. -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-04-11 +# Automatically add all kernels in the concrete directory. +file(GLOB ALL_KERNELS ${CMAKE_CURRENT_SOURCE_DIR}/concrete/*.cpp) + # Add the Configurations.cpp file to the list of source files. set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Kernel.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternStationary.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternNonStationary.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/BivariateMaternFlexible.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/BivariateMaternParsimonious.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternNuggetsStationary.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateSpacetimeMaternStationary.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternDsigmaSquare.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternDnu.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternDbeta.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternDdsigmaSquare.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternDdsigmaSquareBeta.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternDdsigmaSquareNu.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternDdbetaBeta.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternDdbetaNu.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternDdnuNu.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/BivariateSpacetimeMaternStationary.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternNonGaussian.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateExpNonGaussian.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TrivariateMaternParsimonious.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/UnivariateMaternNonStat.cpp + ${ALL_KERNELS} ${SOURCES} PARENT_SCOPE ) \ No newline at end of file diff --git a/src/kernels/Kernel.cpp b/src/kernels/Kernel.cpp index a238accb..193e3e04 100644 --- a/src/kernels/Kernel.cpp +++ b/src/kernels/Kernel.cpp @@ -6,69 +6,30 @@ /** * @file Kernel.cpp * @brief implementation file for the Kernels class, which contains the main kernel functions. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-12 **/ -extern "C" { -#include -} - #include using namespace std; -using namespace exageostat::dataunits; using namespace exageostat::kernels; template -T Kernel::CalculateDerivativeBesselInputNu(const T &aOrder, const T &aInputValue) { - if (aOrder < 1) { - T nu_new = abs(aOrder - 1); - return (-0.5 * (-CalculateDerivativeBesselNu(nu_new, aInputValue) + - CalculateDerivativeBesselNu(abs(aOrder + 1), aInputValue))); - } else { - return (-0.5 * (CalculateDerivativeBesselNu(aOrder - 1, aInputValue) + - CalculateDerivativeBesselNu(abs(aOrder + 1), aInputValue))); - } -} - -template -T Kernel::CalculateDerivativeBesselNu(const T &aOrder, const T &aInputValue) { - if (aOrder == 0) { - return 0; - } else { - // Use a small step size to calculate the derivative numerically - const T step_size = 0.000000001; - return (gsl_sf_bessel_Knu(aOrder + step_size, aInputValue) - gsl_sf_bessel_Knu(aOrder, aInputValue)) / - step_size; - } -} - -template -T Kernel::CalculateSecondDerivativeBesselNu(const T &aOrder, const T &aInputValue) { - return (-0.5 * (CalculateSecondDerivativeBesselNuInput(aOrder - 1, aInputValue) + - CalculateSecondDerivativeBesselNuInput(aOrder + 1, aInputValue))); -} - -template -T Kernel::CalculateSecondDerivativeBesselNuInput(const T &aOrder, const T &aInputValue) { - return (aOrder / aInputValue * gsl_sf_bessel_Knu(aOrder, aInputValue) - gsl_sf_bessel_Knu(aOrder + 1, aInputValue)); -} - -template -int Kernel::GetPValue() const { - return this->mP; +int Kernel::GetVariablesNumber() const { + return this->mVariablesNumber; } template -void Kernel::SetPValue(int aP) { - // Each kernel has its own initial P value, But in case of used spacetime kernels then aP won't be equal to 1. +void Kernel::SetPValue(int aTimeSlot) { + // Each kernel has its own initial P value, But in case of used spacetime kernels then Time Slot won't be equal to 1. // In case of uni-variate spacetime P = 1 * time slot // In case of Bi-variate spacetime P = 2 * time slot - this->mP = this->mP * aP; + // P and timeslot will be constant with each created kernel, overriding the Calculated P value to handle case of calling the function multiple times. + this->mVariablesNumber = this->mP * aTimeSlot; } template diff --git a/src/kernels/concrete/BivariateMaternFlexible.cpp b/src/kernels/concrete/BivariateMaternFlexible.cpp index 1e9aedad..d70c75aa 100644 --- a/src/kernels/concrete/BivariateMaternFlexible.cpp +++ b/src/kernels/concrete/BivariateMaternFlexible.cpp @@ -6,14 +6,14 @@ /** * @file BivariateMaternFlexible.cpp * @brief Implementation of the BivariateMaternFlexible kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -47,9 +47,9 @@ BivariateMaternFlexible::GenerateCovarianceMatrix(T *apMatrixA, const int &aR int i, j; int i0 = aRowOffset; int j0; - double expr1, expr2, expr12; - double con1, con2, con12, scale12, rho, nu12, sigma_square11, sigma_square22; - double scale1 = aLocalTheta[0], scale2 = aLocalTheta[1], nu1 = aLocalTheta[4], nu2 = aLocalTheta[5]; + T expr1, expr2, expr12; + T con1, con2, con12, scale12, rho, nu12, sigma_square11, sigma_square22; + T scale1 = aLocalTheta[0], scale2 = aLocalTheta[1], nu1 = aLocalTheta[4], nu2 = aLocalTheta[5]; //Remark 1 (c) of Apanasovich et al. (2012) scale12 = pow(0.5 * (pow(scale1, -2) + pow(scale2, -2)) + aLocalTheta[2] * (1 - aLocalTheta[3]), -0.5); @@ -76,7 +76,7 @@ BivariateMaternFlexible::GenerateCovarianceMatrix(T *apMatrixA, const int &aR con12 = rho * con12; i0 /= 2; - int flag = 0; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; for (i = 0; i < aRowsNumber; i += 2) { j0 = aColumnOffset / 2; diff --git a/src/kernels/concrete/BivariateMaternParsimonious.cpp b/src/kernels/concrete/BivariateMaternParsimonious.cpp index 123f3b92..f222fe46 100644 --- a/src/kernels/concrete/BivariateMaternParsimonious.cpp +++ b/src/kernels/concrete/BivariateMaternParsimonious.cpp @@ -6,14 +6,14 @@ /** * @file BivariateMaternParsimonious.cpp * @brief Implementation of the BivariateMaternParsimonious kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -46,8 +46,8 @@ void BivariateMaternParsimonious::GenerateCovarianceMatrix(T *apMatrixA, cons int i, j; int i0 = aRowOffset; int j0; - double expr; - double con1, con2, con12, rho, nu12; + T expr; + T con1, con2, con12, rho, nu12; con1 = pow(2, (aLocalTheta[3] - 1)) * tgamma(aLocalTheta[3]); con1 = 1.0 / con1; @@ -66,13 +66,13 @@ void BivariateMaternParsimonious::GenerateCovarianceMatrix(T *apMatrixA, cons con12 = rho * sqrt(aLocalTheta[0] * aLocalTheta[1]) * con12; i0 /= 2; - int flag = 0; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; for (i = 0; i < aRowsNumber; i += 2) { j0 = aColumnOffset / 2; for (j = 0; j < aColumnsNumber; j += 2) { expr = DistanceCalculationHelpers::CalculateDistance(aLocation1, aLocation2, i0, j0, aDistanceMetric, - flag) / aLocalTheta[2]; + 0) / aLocalTheta[2]; if (expr == 0) { apMatrixA[i + j * aRowsNumber] = aLocalTheta[0]; diff --git a/src/kernels/concrete/BivariateSpacetimeMaternStationary.cpp b/src/kernels/concrete/BivariateSpacetimeMaternStationary.cpp index 8ef95c6e..8209086f 100644 --- a/src/kernels/concrete/BivariateSpacetimeMaternStationary.cpp +++ b/src/kernels/concrete/BivariateSpacetimeMaternStationary.cpp @@ -6,14 +6,14 @@ /** * @file BivariateSpacetimeMaternStationary.cpp * @brief Implementation of the BivariateSpacetimeMaternStationary kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -47,9 +47,9 @@ BivariateSpacetimeMaternStationary::GenerateCovarianceMatrix(T *apMatrixA, co int i, j; int i0 = aRowOffset; int j0; - double z0, z1; - double expr, expr2, expr3, expr4; - double con1, con2, con12, rho, nu12; + T z0, z1; + T expr, expr2, expr3, expr4; + T con1, con2, con12, rho, nu12; con1 = pow(2, (aLocalTheta[3] - 1)) * tgamma(aLocalTheta[3]); con1 = 1.0 / con1; diff --git a/src/kernels/concrete/TrivariateMaternParsimonious.cpp b/src/kernels/concrete/TrivariateMaternParsimonious.cpp index a7de387b..6f833b6e 100644 --- a/src/kernels/concrete/TrivariateMaternParsimonious.cpp +++ b/src/kernels/concrete/TrivariateMaternParsimonious.cpp @@ -6,14 +6,14 @@ /** * @file TrivariateMaternParsimonious.cpp * @brief Implementation of the BivariateMaternParsimonious kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -46,8 +46,8 @@ void TrivariateMaternParsimonious::GenerateCovarianceMatrix(T *apMatrixA, con int i, j; int i0 = aRowOffset; int j0; - double expr; - double con1, con2, con3, con12, con13, con23, rho12, rho13, rho23, nu12, nu13, nu23; + T expr; + T con1, con2, con3, con12, con13, con23, rho12, rho13, rho23, nu12, nu13, nu23; con1 = pow(2, (aLocalTheta[4] - 1)) * tgamma(aLocalTheta[4]); con1 = 1.0 / con1; @@ -88,13 +88,13 @@ void TrivariateMaternParsimonious::GenerateCovarianceMatrix(T *apMatrixA, con i0 /= 3; int matrix_size = aRowsNumber * aColumnsNumber; int index; - int flag = 0; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; for (i = 0; i < aRowsNumber - 1; i += 3) { j0 = aColumnOffset / 3; for (j = 0; j < aColumnsNumber - 1; j += 3) { expr = DistanceCalculationHelpers::CalculateDistance(aLocation1, aLocation2, i0, j0, aDistanceMetric, - flag) / aLocalTheta[3]; + 0) / aLocalTheta[3]; if (expr == 0) { diff --git a/src/kernels/concrete/UnivariateExpNonGaussian.cpp b/src/kernels/concrete/UnivariateExpNonGaussian.cpp index c785cc7b..6be4bf66 100644 --- a/src/kernels/concrete/UnivariateExpNonGaussian.cpp +++ b/src/kernels/concrete/UnivariateExpNonGaussian.cpp @@ -6,14 +6,14 @@ /** * @file UnivariateExpNonGaussian.cpp * @brief Implementation of the UnivariateExpNonGaussian kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -47,16 +47,15 @@ UnivariateExpNonGaussian::GenerateCovarianceMatrix(T *apMatrixA, const int &a int i, j; int i0 = aRowOffset; int j0; - double expr; - double sigma_square = 1; - int flag = 0; + T expr; + T sigma_square = 1; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; for (i = 0; i < aRowsNumber; i++) { j0 = aColumnOffset; for (j = 0; j < aColumnsNumber; j++) { expr = DistanceCalculationHelpers::CalculateDistance(aLocation1, aLocation2, i0, j0, aDistanceMetric, flag) / aLocalTheta[0]; - if (expr == 0) { apMatrixA[i + j * aRowsNumber] = sigma_square; } else { diff --git a/src/kernels/concrete/UnivariateMaternDbeta.cpp b/src/kernels/concrete/UnivariateMaternDbeta.cpp index 27137dee..caa2041a 100644 --- a/src/kernels/concrete/UnivariateMaternDbeta.cpp +++ b/src/kernels/concrete/UnivariateMaternDbeta.cpp @@ -6,14 +6,14 @@ /** * @file UnivariateMaternDbeta.cpp * @brief Implementation of the UnivariateMaternDbeta kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -46,13 +46,13 @@ void UnivariateMaternDbeta::GenerateCovarianceMatrix(T *apMatrixA, const int int i, j; int i0 = aRowOffset; int j0; - double expr; - double beta_expr; - double con; - double sigma_square = aLocalTheta[0]; + T expr; + T beta_expr; + T con; + T sigma_square = aLocalTheta[0]; con = pow(2, (aLocalTheta[2] - 1)) * tgamma(aLocalTheta[2]); con = 1.0 / con; - int flag = 0; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; for (i = 0; i < aRowsNumber; i++) { j0 = aColumnOffset; diff --git a/src/kernels/concrete/UnivariateMaternDdbetaBeta.cpp b/src/kernels/concrete/UnivariateMaternDdbetaBeta.cpp index b2d4d4e7..140c5659 100644 --- a/src/kernels/concrete/UnivariateMaternDdbetaBeta.cpp +++ b/src/kernels/concrete/UnivariateMaternDdbetaBeta.cpp @@ -6,14 +6,14 @@ /** * @file UnivariateMaternDdbetaBeta.cpp * @brief Implementation of the UnivariateMaternDdbetaBeta kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -47,14 +47,14 @@ UnivariateMaternDdbetaBeta::GenerateCovarianceMatrix(T *apMatrixA, const int int i, j; int i0 = aRowOffset; int j0; - double expr; - double con; - double beta_expr; - double beta_expr_prime; - double sigma_square = aLocalTheta[0]; + T expr; + T con; + T beta_expr; + T beta_expr_prime; + T sigma_square = aLocalTheta[0]; con = pow(2, (aLocalTheta[2] - 1)) * tgamma(aLocalTheta[2]); con = 1.0 / con; - int flag = 0; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; for (i = 0; i < aRowsNumber; i++) { j0 = aColumnOffset; diff --git a/src/kernels/concrete/UnivariateMaternDdbetaNu.cpp b/src/kernels/concrete/UnivariateMaternDdbetaNu.cpp index 7d2b036e..ea9c173a 100644 --- a/src/kernels/concrete/UnivariateMaternDdbetaNu.cpp +++ b/src/kernels/concrete/UnivariateMaternDdbetaNu.cpp @@ -6,14 +6,13 @@ /** * @file UnivariateMaternDdbetaNu.cpp * @brief Implementation of the UnivariateMaternDdbetaNu kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -47,14 +46,14 @@ UnivariateMaternDdbetaNu::GenerateCovarianceMatrix(T *apMatrixA, const int &a int i, j; int i0 = aRowOffset; int j0; - double expr; - double con; - double nu_expr; - double nu_expr_prime; - double sigma_square = aLocalTheta[0]; + T expr; + T con; + T nu_expr; + T nu_expr_prime; + T sigma_square = aLocalTheta[0]; con = pow(2, (aLocalTheta[2] - 1)) * tgamma(aLocalTheta[2]); con = 1.0 / con; - int flag = 0; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; for (i = 0; i < aRowsNumber; i++) { j0 = aColumnOffset; @@ -98,7 +97,7 @@ UnivariateMaternDdbetaNu::GenerateCovarianceMatrix(T *apMatrixA, const int &a aLocalTheta[2] + 1, expr)) + pow(expr, aLocalTheta[2]) * - this->CalculateSecondDerivativeBesselNuInput( + BasselFunction::CalculateSecondDerivativeBesselNuInput( aLocalTheta[2], expr))); apMatrixA[i + j * aRowsNumber] = (-1 / aLocalTheta[1] * (con * pow(expr, aLocalTheta[2]) * gsl_sf_bessel_Knu(aLocalTheta[2], expr)) - diff --git a/src/kernels/concrete/UnivariateMaternDdnuNu.cpp b/src/kernels/concrete/UnivariateMaternDdnuNu.cpp index fd884838..a54a1ce4 100644 --- a/src/kernels/concrete/UnivariateMaternDdnuNu.cpp +++ b/src/kernels/concrete/UnivariateMaternDdnuNu.cpp @@ -6,14 +6,14 @@ /** * @file UnivariateMaternDdnuNu.cpp * @brief Implementation of the UnivariateMaternDdnuNu kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -47,14 +47,14 @@ UnivariateMaternDdnuNu::GenerateCovarianceMatrix(T *apMatrixA, const int &aRo int i, j; int i0 = aRowOffset; int j0; - double expr; - double con; - double nu_expr; - double nu_expr_dprime; - double sigma_square = aLocalTheta[0]; + T expr; + T con; + T nu_expr; + T nu_expr_dprime; + T sigma_square = aLocalTheta[0]; con = pow(2, (aLocalTheta[2] - 1)) * tgamma(aLocalTheta[2]); con = 1.0 / con; - int flag = 0; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; for (i = 0; i < aRowsNumber; i++) { j0 = aColumnOffset; @@ -72,22 +72,20 @@ UnivariateMaternDdnuNu::GenerateCovarianceMatrix(T *apMatrixA, const int &aRo (pow(expr, aLocalTheta[2]) * log(expr) * gsl_sf_bessel_Knu(aLocalTheta[2], expr) + pow(expr, aLocalTheta[2]) * - this->CalculateDerivativeBesselNu(aLocalTheta[2], + BasselFunction::CalculateDerivativeBesselNu(aLocalTheta[2], expr))); nu_expr_dprime = (1 - aLocalTheta[2]) * 1 / pow(2, aLocalTheta[2]) * 1 / tgamma(aLocalTheta[2]) * - pow(expr, aLocalTheta[2]) * this->CalculateDerivativeBesselNu(aLocalTheta[2], expr) + + pow(expr, aLocalTheta[2]) * BasselFunction::CalculateDerivativeBesselNu(aLocalTheta[2], expr) + pow(2, 1 - aLocalTheta[2]) * (-1 / tgamma(aLocalTheta[2]) * gsl_sf_psi(aLocalTheta[2]) * pow(expr, aLocalTheta[2]) * - this->CalculateDerivativeBesselNu(aLocalTheta[2], expr) + 1 / tgamma(aLocalTheta[2]) * + BasselFunction::CalculateDerivativeBesselNu(aLocalTheta[2], expr) + 1 / tgamma(aLocalTheta[2]) * (pow(expr, aLocalTheta[2]) * log(expr) * - this->CalculateDerivativeBesselNu( + BasselFunction::CalculateDerivativeBesselNu( aLocalTheta[2], expr) + pow(expr, aLocalTheta[2]) * - this->CalculateSecondDerivativeBesselNu( - aLocalTheta[2], - expr))); + BasselFunction::CalculateSecondDerivativeBesselNu(aLocalTheta[2],expr))); apMatrixA[i + j * aRowsNumber] = (-0.5 * con * pow(expr, aLocalTheta[2]) * gsl_sf_bessel_Knu(aLocalTheta[2], expr) + (1 - aLocalTheta[2]) / 2 * nu_expr - diff --git a/src/kernels/concrete/UnivariateMaternDdsigmaSquare.cpp b/src/kernels/concrete/UnivariateMaternDdsigmaSquare.cpp index af410d57..ee980159 100644 --- a/src/kernels/concrete/UnivariateMaternDdsigmaSquare.cpp +++ b/src/kernels/concrete/UnivariateMaternDdsigmaSquare.cpp @@ -6,7 +6,7 @@ /** * @file UnivariateMaternDdsigmaSquare.cpp * @brief Implementation of the UnivariateMaternDdsigmaSquare kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 @@ -44,8 +44,8 @@ void UnivariateMaternDdsigmaSquare::GenerateCovarianceMatrix(T *apMatrixA, co int i, j; int i0 = aRowOffset; int j0; - double expr; - double con; + T expr; + T con; con = pow(2, (aLocalTheta[2] - 1)) * tgamma(aLocalTheta[2]); con = 1.0 / con; diff --git a/src/kernels/concrete/UnivariateMaternDdsigmaSquareBeta.cpp b/src/kernels/concrete/UnivariateMaternDdsigmaSquareBeta.cpp index 579d1dcc..dc94d289 100644 --- a/src/kernels/concrete/UnivariateMaternDdsigmaSquareBeta.cpp +++ b/src/kernels/concrete/UnivariateMaternDdsigmaSquareBeta.cpp @@ -6,14 +6,14 @@ /** * @file UnivariateMaternDdsigmaSquareBeta.cpp * @brief Implementation of the UnivariateMaternDdsigmaSquareBeta kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -46,12 +46,12 @@ void UnivariateMaternDdsigmaSquareBeta::GenerateCovarianceMatrix(T *apMatrixA int i, j; int i0 = aRowOffset; int j0; - double expr; - double con; - double beta_expr; + T expr; + T con; + T beta_expr; con = pow(2, (aLocalTheta[2] - 1)) * tgamma(aLocalTheta[2]); con = 1.0 / con; - int flag = 0; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; for (i = 0; i < aRowsNumber; i++) { j0 = aColumnOffset; diff --git a/src/kernels/concrete/UnivariateMaternDdsigmaSquareNu.cpp b/src/kernels/concrete/UnivariateMaternDdsigmaSquareNu.cpp index 7563c676..f6e62a31 100644 --- a/src/kernels/concrete/UnivariateMaternDdsigmaSquareNu.cpp +++ b/src/kernels/concrete/UnivariateMaternDdsigmaSquareNu.cpp @@ -6,14 +6,14 @@ /** * @file UnivariateMaternDdsigmaSquareNu.cpp * @brief Implementation of the UnivariateMaternDdsigmaSquareNu kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -46,9 +46,9 @@ void UnivariateMaternDdsigmaSquareNu::GenerateCovarianceMatrix(T *apMatrixA, int i, j; int i0 = aRowOffset; int j0; - double expr; - double nu_expr; - int flag = 0; + T expr; + T nu_expr; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; for (i = 0; i < aRowsNumber; i++) { j0 = aColumnOffset; diff --git a/src/kernels/concrete/UnivariateMaternDnu.cpp b/src/kernels/concrete/UnivariateMaternDnu.cpp index 8830f0f8..e357826c 100644 --- a/src/kernels/concrete/UnivariateMaternDnu.cpp +++ b/src/kernels/concrete/UnivariateMaternDnu.cpp @@ -6,14 +6,14 @@ /** * @file UnivariateMaternDnu.cpp * @brief Implementation of the UnivariateMaternDnu kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -46,10 +46,10 @@ void UnivariateMaternDnu::GenerateCovarianceMatrix(T *apMatrixA, const int &a int i, j; int i0 = aRowOffset; int j0; - double expr; - double nu_expr; - double sigma_square = aLocalTheta[0]; - int flag = 0; + T expr; + T nu_expr; + T sigma_square = aLocalTheta[0]; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; for (i = 0; i < aRowsNumber; i++) { j0 = aColumnOffset; @@ -68,7 +68,7 @@ void UnivariateMaternDnu::GenerateCovarianceMatrix(T *apMatrixA, const int &a (pow(expr, aLocalTheta[2]) * log(expr) * gsl_sf_bessel_Knu(aLocalTheta[2], expr) + pow(expr, aLocalTheta[2]) * - Kernel::CalculateDerivativeBesselNu(aLocalTheta[2], expr))); + BasselFunction::CalculateDerivativeBesselNu(aLocalTheta[2], expr))); apMatrixA[i + j * aRowsNumber] = sigma_square * nu_expr; } j0++; diff --git a/src/kernels/concrete/UnivariateMaternDsigmaSquare.cpp b/src/kernels/concrete/UnivariateMaternDsigmaSquare.cpp index f48bd9b0..d6d55635 100644 --- a/src/kernels/concrete/UnivariateMaternDsigmaSquare.cpp +++ b/src/kernels/concrete/UnivariateMaternDsigmaSquare.cpp @@ -6,7 +6,7 @@ /** * @file UnivariateMaternDsigmaSquare.cpp * @brief Implementation of the UnivariateMaternDsigmaSquare kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -15,7 +15,7 @@ **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -47,12 +47,12 @@ void UnivariateMaternDsigmaSquare::GenerateCovarianceMatrix(T *apMatrixA, con int i, j; int i0 = aRowOffset; int j0; - double expr; - double con; + T expr; + T con; con = pow(2, (aLocalTheta[2] - 1)) * tgamma(aLocalTheta[2]); con = 1.0 / con; - int flag = 0; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; for (i = 0; i < aRowsNumber; i++) { j0 = aColumnOffset; for (j = 0; j < aColumnsNumber; j++) { diff --git a/src/kernels/concrete/UnivariateMaternNonGaussian.cpp b/src/kernels/concrete/UnivariateMaternNonGaussian.cpp index 2a10db0f..d18410af 100644 --- a/src/kernels/concrete/UnivariateMaternNonGaussian.cpp +++ b/src/kernels/concrete/UnivariateMaternNonGaussian.cpp @@ -6,14 +6,14 @@ /** * @file UnivariateMaternNonGaussian.cpp * @brief Implementation of the UnivariateMaternNonGaussian kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -46,14 +46,14 @@ void UnivariateMaternNonGaussian::GenerateCovarianceMatrix(T *apMatrixA, cons int i, j; int i0 = aRowOffset; int j0; - double expr; - double con; - double sigma_square = 1; + T expr; + T con; + T sigma_square = 1; con = pow(2, (aLocalTheta[1] - 1)) * tgamma(aLocalTheta[1]); con = 1.0 / con; con = sigma_square * con; - int flag = 0; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; for (i = 0; i < aRowsNumber; i++) { j0 = aColumnOffset; diff --git a/src/kernels/concrete/UnivariateMaternNonStat.cpp b/src/kernels/concrete/UnivariateMaternNonStat.cpp deleted file mode 100644 index b2ee916f..00000000 --- a/src/kernels/concrete/UnivariateMaternNonStat.cpp +++ /dev/null @@ -1,145 +0,0 @@ - -// Copyright (c) 2017-2023 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 UnivariateMaternNonStat.cpp - * @brief Implementation of the UnivariateMaternNonStat kernel. - * @version 1.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @date 2023-04-14 -**/ - -#include - -using namespace exageostat::kernels; -using namespace exageostat::dataunits; - -template -UnivariateMaternNonStat::UnivariateMaternNonStat() { - this->mP = 1; - this->mParametersNumber = 8; -} - -template -Kernel *UnivariateMaternNonStat::Create() { - KernelsConfigurations::GetParametersNumberKernelMap()["UnivariateMaternNonStat"] = 8; - return new UnivariateMaternNonStat(); -} - -namespace exageostat::kernels { - template bool UnivariateMaternNonStat::plugin_name = plugins::PluginRegistry>::Add( - "UnivariateMaternNonStat", UnivariateMaternNonStat::Create); -} - -template -void -UnivariateMaternNonStat::GenerateCovarianceMatrix(T *apMatrixA, const int &aRowsNumber, const int &aColumnsNumber, - const int &aRowOffset, const int &aColumnOffset, - Locations &aLocation1, Locations &aLocation2, - Locations &aLocation3, T *aLocalTheta, - const int &aDistanceMetric) { - - double l1x, l1y, l2x, l2y; - double a, b, d, e, f, g, h, ti; - a = aLocalTheta[0]; - b = aLocalTheta[1]; - d = aLocalTheta[2]; - e = aLocalTheta[3]; - f = aLocalTheta[4]; - g = aLocalTheta[5]; - h = aLocalTheta[6]; - ti = aLocalTheta[7]; - - double nu_arr_1[aRowsNumber]; - double sigma_arr_1[aRowsNumber]; - double lambda_arr_1[aRowsNumber]; - double nu_arr_2[aColumnsNumber]; - double sigma_arr_2[aColumnsNumber]; - double lambda_arr_2[aColumnsNumber]; - double term1; - double term2; - double neuij; - double Qij; - double prod1; - double term3; - - for (int i = 0; i < aRowsNumber; i++) { - l1x = aLocation1.GetLocationX()[i + aRowOffset]; - l1y = aLocation1.GetLocationY()[i + aRowOffset]; - nu_arr_1[i] = Neu(l1x, l1y, g, h, ti); - sigma_arr_1[i] = Sigma(l1x, l1y, d, e, f); - lambda_arr_1[i] = Lambda(l1x, l1y, a, b); - } - - for (int j = 0; j < aColumnsNumber; j++) { - l2x = aLocation2.GetLocationX()[j + aColumnOffset]; - l2y = aLocation2.GetLocationY()[j + aColumnOffset]; - - nu_arr_2[j] = Neu(l2x, l2y, g, h, ti); - sigma_arr_2[j] = Sigma(l2x, l2y, d, e, f); - lambda_arr_2[j] = Lambda(l2x, l2y, a, b); - } - - for (int i = 0; i < aRowsNumber; i++) { - l1x = aLocation1.GetLocationX()[i + aRowOffset]; - l1y = aLocation1.GetLocationY()[i + aRowOffset]; - - for (int j = 0; j < aColumnsNumber; j++) { - l2x = aLocation2.GetLocationX()[j + aColumnOffset]; - l2y = aLocation2.GetLocationY()[j + aColumnOffset]; - term1 = (sigma_arr_1[i]) * (sigma_arr_2[j]) * sqrt(lambda_arr_1[i]) * sqrt(lambda_arr_2[j]); - term2 = 2 / ((lambda_arr_1[i]) + (lambda_arr_2[j])); - neuij = ((nu_arr_1[i]) + (nu_arr_2[j])) / 2; - Qij = CalculateMahalanobisDistanceSquared(l1x, l1y, l2x, l2y, term2, 0, 0, term2); - prod1 = 2 * sqrt(neuij * Qij); - term3 = MaternUtil(1, neuij, prod1); - apMatrixA[i + j * aRowsNumber] = term1 * term2 * term3; - } - } -} - -template -double UnivariateMaternNonStat::Neu(double x, double y, double g, double h, double ti) { - return (g * pow(POW_e, h * (x + y)) + ti); -} - -template -double UnivariateMaternNonStat::Sigma(double x, double y, double d, double e, double f) { - return (d * pow(POW_e, e * (x + y)) + f); -} - -template -double UnivariateMaternNonStat::Lambda(double x, double y, double a, double b) { - return (a * pow(POW_e, sin(b * x) + sin(b * y))); -} - -template -double -UnivariateMaternNonStat::CalculateMahalanobisDistanceSquared(double x1, double y1, double x2, double y2, double a11, - double a12, double a21, double a22) { - - double diffx = x1 - x2; - double diffy = y1 - y2; - double el1 = a11 * diffx + a21 * diffy; - double el2 = a12 * diffx + a22 * diffy; - double ans = el1 * diffx + el2 * diffy; - - return ans; -} - -template -double UnivariateMaternNonStat::MaternUtil(double range, double smoothness, double distance) { - double con; - con = pow(2, (smoothness - 1)) * tgamma(smoothness); - con = 1.0 / con; - - if (distance == 0) { - return 1; - } else { - // Matern Function - return con * pow(distance / range, smoothness) * gsl_sf_bessel_Knu(smoothness, distance / range); - } -} \ No newline at end of file diff --git a/src/kernels/concrete/UnivariateMaternNonStationary.cpp b/src/kernels/concrete/UnivariateMaternNonStationary.cpp deleted file mode 100644 index 72b47001..00000000 --- a/src/kernels/concrete/UnivariateMaternNonStationary.cpp +++ /dev/null @@ -1,115 +0,0 @@ - -// Copyright (c) 2017-2023 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 UnivariateMaternNonStationary.cpp - * @brief Implementation of the UnivariateMaternNonStationary kernel. - * @version 1.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @date 2023-04-13 -**/ - -#include -#include - -using namespace exageostat::kernels; -using namespace exageostat::dataunits; -using namespace exageostat::helpers; - -template -UnivariateMaternNonStationary::UnivariateMaternNonStationary() { - this->mP = 1; - this->mParametersNumber = 9; -} - -template -Kernel *UnivariateMaternNonStationary::Create() { - KernelsConfigurations::GetParametersNumberKernelMap()["UnivariateMaternNonStationary"] = 9; - return new UnivariateMaternNonStationary(); -} - -namespace exageostat::kernels { - template bool UnivariateMaternNonStationary::plugin_name = plugins::PluginRegistry>::Add( - "UnivariateMaternNonStationary", UnivariateMaternNonStationary::Create); -} - -template -void UnivariateMaternNonStationary::GenerateCovarianceMatrix(T *apMatrixA, const int &aRowsNumber, - const int &aColumnsNumber, const int &aRowOffset, - const int &aColumnOffset, Locations &aLocation1, - Locations &aLocation2, Locations &aLocation3, - T *aLocalTheta, const int &aDistanceMetric) { - - double location1X, location1Y, location2X, location2Y, location3X, location3Y; - double theta_0i, theta_0j, theta_1i, theta_1j, theta_2i, theta_2j; - double dx, dy; - double dist; - double con, sigma_square, beta, nu; - int i, j; - - aLocation3 = aLocation1; - double x_max = aLocation1->GetLocationX()[0]; - double x_min = aLocation1->GetLocationX()[0]; - double y_max = aLocation1->GetLocationY()[0]; - double y_min = aLocation1->GetLocationY()[0]; - for (i = 1; i < 9; i++) { - if (x_max < aLocation1->GetLocationX()[i]) - x_max = aLocation1->GetLocationX()[i]; - if (x_min > aLocation1->GetLocationX()[i]) - x_min = aLocation1->GetLocationX()[i]; - if (y_max < aLocation1->GetLocationY()[i]) - y_max = aLocation1->GetLocationY()[i]; - if (y_max > aLocation1->GetLocationY()[i]) - y_max = aLocation1->GetLocationY()[i]; - } - - aLocation3->GetLocationX()[0] = x_min + (x_max - x_min) / 2; - aLocation3->GetLocationY()[0] = y_min + (y_max - y_min) / 2; - LOGGER(" The central point is ( %f, %f)\n", aLocation3->GetLocationX()[0], aLocation3->GetLocationY()[0]); - - // Compute the covariance matrix elements - for (j = 0; j < aColumnsNumber; j++) { - location1X = aLocation1->GetLocationX()[aColumnOffset + j]; - location1Y = aLocation1->GetLocationY()[aColumnOffset + j]; - location3X = aLocation3->GetLocationX()[j]; - location3Y = aLocation3->GetLocationY()[j]; - dx = abs(location1X - location3X); - dy = abs(location1Y - location3Y); - - theta_0i = aLocalTheta[0] + (aLocalTheta[1] * dx) + (aLocalTheta[2] * dy); - theta_1i = aLocalTheta[3] + (aLocalTheta[4] * dx) + (aLocalTheta[5] * dy); - theta_2i = aLocalTheta[6] + (aLocalTheta[7] * dx) + (aLocalTheta[8] * dy); - - for (i = 0; i < aRowsNumber; i++) { - location2X = aLocation2->GetLocationX()[aRowOffset + i]; - location2Y = aLocation2->GetLocationY()[aRowOffset + i]; - location3X = aLocation3->GetLocationX()[i]; - location3Y = aLocation3->GetLocationY()[i]; - dx = abs(location2X - location3X); - dy = abs(location2Y - location3Y); - - theta_0j = aLocalTheta[0] + (aLocalTheta[1] * dx) + (aLocalTheta[2] * dy); - theta_1j = aLocalTheta[3] + (aLocalTheta[4] * dx) + (aLocalTheta[5] * dy); - theta_2j = aLocalTheta[6] + (aLocalTheta[7] * dx) + (aLocalTheta[8] * dy); - - // Compute the Matérn parameters and distance metric - sigma_square = (theta_0i + theta_0j) / 2; - beta = (theta_1i + theta_1j) / 2; - nu = (theta_2i + theta_2j) / 2; - con = pow(2, (nu - 1)) / tgamma(nu); - - con = 1.0 / con; - con = sigma_square * con; - int flag = 0; - - //MLE calculation - dist = DistanceCalculationHelpers::CalculateDistance(aLocation1, aLocation2, i, j, aDistanceMetric, - flag) / beta; - *(apMatrixA + i + j * aRowsNumber) = (dist == 0.0) ? sigma_square : con * pow(dist, nu) * - gsl_sf_bessel_Knu(nu, dist); - } - } -} diff --git a/src/kernels/concrete/UnivariateMaternNuggetsStationary.cpp b/src/kernels/concrete/UnivariateMaternNuggetsStationary.cpp index d2729283..a4a1d7f6 100644 --- a/src/kernels/concrete/UnivariateMaternNuggetsStationary.cpp +++ b/src/kernels/concrete/UnivariateMaternNuggetsStationary.cpp @@ -6,14 +6,14 @@ /** * @file UnivariateMaternNuggetsStationary.cpp * @brief Implementation of the UnivariateMaternNuggetsStationary kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -46,14 +46,14 @@ void UnivariateMaternNuggetsStationary::GenerateCovarianceMatrix(T *apMatrixA int i, j; int i0 = aRowOffset; int j0; - double expr; - double con; - double sigma_square = aLocalTheta[0]; + T expr; + T con; + T sigma_square = aLocalTheta[0]; con = pow(2, (aLocalTheta[2] - 1)) * tgamma(aLocalTheta[2]); con = 1.0 / con; con = sigma_square * con; - int flag = 0; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; if (aLocation1.GetLocationZ() == nullptr || aLocation2.GetLocationZ() == nullptr) { for (i = 0; i < aRowsNumber; i++) { diff --git a/src/kernels/concrete/UnivariateMaternStationary.cpp b/src/kernels/concrete/UnivariateMaternStationary.cpp index 4fe9c1aa..9f576a8b 100644 --- a/src/kernels/concrete/UnivariateMaternStationary.cpp +++ b/src/kernels/concrete/UnivariateMaternStationary.cpp @@ -6,14 +6,14 @@ /** * @file UnivariateMaternStationary.cpp * @brief Implementation of the UnivariateMaternStationary kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 **/ #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -48,7 +48,7 @@ UnivariateMaternStationary::GenerateCovarianceMatrix(T *apMatrixA, const int const T nu = aLocalTheta[2]; const T inv_con = sigma_square * (1.0 / (pow(2, (nu - 1)) * tgamma((nu)))); int i0 = aRowOffset; - int flag = 0; + int flag = aLocation1.GetLocationZ() == nullptr ? 0 : 1; int j0; int i, j; T dist; diff --git a/src/kernels/concrete/UnivariateSpacetimeMaternStationary.cpp b/src/kernels/concrete/UnivariateSpacetimeMaternStationary.cpp index 1eb5d63f..b4631421 100644 --- a/src/kernels/concrete/UnivariateSpacetimeMaternStationary.cpp +++ b/src/kernels/concrete/UnivariateSpacetimeMaternStationary.cpp @@ -6,7 +6,7 @@ /** * @file UnivariateSpacetimeMaternStationary.cpp * @brief Implementation of the UnivariateSpacetimeMaternStationary kernel. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-14 @@ -17,7 +17,7 @@ #include #include -#include + using namespace exageostat::kernels; using namespace exageostat::dataunits; @@ -51,10 +51,10 @@ UnivariateSpacetimeMaternStationary::GenerateCovarianceMatrix(T *apMatrixA, c int i, j; int i0 = aRowOffset; int j0; - double z0, z1; - double expr, expr2, expr3, expr4; - double con; - double sigma_square = aLocalTheta[0]; + T z0, z1; + T expr, expr2, expr3, expr4; + T con; + T sigma_square = aLocalTheta[0]; con = pow(2, (aLocalTheta[2] - 1)) * tgamma(aLocalTheta[2]); con = 1.0 / con; diff --git a/src/linear-algebra-solvers/LinearAlgebraFactory.cpp b/src/linear-algebra-solvers/LinearAlgebraFactory.cpp index ec759d52..64949703 100644 --- a/src/linear-algebra-solvers/LinearAlgebraFactory.cpp +++ b/src/linear-algebra-solvers/LinearAlgebraFactory.cpp @@ -8,7 +8,7 @@ * @brief Implementation of the LinearAlgebraFactory class for creating linear algebra solvers for different computations using HiCMA or Chameleon libraries. * The factory creates a unique pointer to a concrete implementation of the LinearAlgebraMethods class based on the computation specified. * If the required library is not enabled, it throws a runtime_error exception. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-03-20 **/ @@ -16,12 +16,12 @@ #include -#include -#include +#include +#include -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA -#include +#include #endif @@ -35,19 +35,19 @@ std::unique_ptr> LinearAlgebraFactory::CreateLinearAl // Check the used Linear Algebra solver library, whether it's HiCMA or Chameleon. if (aComputation == EXACT_DENSE) { - return std::make_unique>(); + return std::make_unique>(); } // HiCMA Used else if (aComputation == TILE_LOW_RANK) { -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA return std::make_unique>(); #else throw std::runtime_error( - "Tile low rank generation isn't supported without enabling HiCMA. Use -DEXAGEOSTAT_USE_HICMA=ON"); + "Tile low rank generation isn't supported without enabling HiCMA. Use -DUSE_HICMA=ON"); #endif } else if (aComputation == DIAGONAL_APPROX) { - return std::make_unique>(); + return std::make_unique>(); } // Return nullptr if no computation is selected diff --git a/src/linear-algebra-solvers/LinearAlgebraMethods.cpp b/src/linear-algebra-solvers/LinearAlgebraMethods.cpp index 5cf36748..76af27ff 100644 --- a/src/linear-algebra-solvers/LinearAlgebraMethods.cpp +++ b/src/linear-algebra-solvers/LinearAlgebraMethods.cpp @@ -6,7 +6,7 @@ /** * @file LinearAlgebraMethods.cpp * @brief Implementation of linear algebra methods. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-03-20 @@ -15,6 +15,7 @@ #ifdef USE_MPI #include #endif + #include #include @@ -30,7 +31,7 @@ using namespace exageostat::hardware; // Define a method to set up the Chameleon descriptors template void LinearAlgebraMethods::InitiateDescriptors(Configurations &aConfigurations, DescriptorData &aDescriptorData, - T *apMeasurementsMatrix) { + const int &aP, T *apMeasurementsMatrix) { // Check for initialize the Chameleon context. if (!this->mpContext) { @@ -39,7 +40,7 @@ void LinearAlgebraMethods::InitiateDescriptors(Configurations &aConfiguration } // Get the problem size and other configuration parameters - int n = aConfigurations.GetProblemSize(); + int full_problem_size = aConfigurations.GetProblemSize() * aP; int dts = aConfigurations.GetDenseTileSize(); int p_grid = aConfigurations.GetPGrid(); int q_grid = aConfigurations.GetQGrid(); @@ -65,36 +66,48 @@ void LinearAlgebraMethods::InitiateDescriptors(Configurations &aConfiguration } aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_C, is_OOC, nullptr, float_point, dts, dts, - dts * dts, n, n, 0, 0, n, n, p_grid, q_grid); + dts * dts, full_problem_size, full_problem_size, 0, 0, full_problem_size, + full_problem_size, p_grid, q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z, is_OOC, apMeasurementsMatrix, float_point, - dts, dts, dts * dts, n, 1, 0, 0, n, 1, p_grid, q_grid); + dts, dts, dts * dts, full_problem_size, 1, 0, 0, full_problem_size, 1, p_grid, + q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z_COPY, is_OOC, nullptr, float_point, dts, - dts, dts * dts, n, 1, 0, 0, n, 1, p_grid, q_grid); + dts, dts * dts, full_problem_size, 1, 0, 0, full_problem_size, 1, p_grid, q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_DETERMINANT, is_OOC, nullptr, float_point, - dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); + dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid, false); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_PRODUCT, is_OOC, nullptr, float_point, dts, - dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); + dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid, false); if (float_point == EXAGEOSTAT_REAL_DOUBLE) { auto *CHAM_descC = aDescriptorData.GetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_C).chameleon_desc; aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_C11, is_OOC, nullptr, float_point, dts, - dts, dts * dts, n, n, 0, 0, CHAM_descC->m / 2, CHAM_descC->n / 2, p_grid, q_grid); + dts, dts * dts, full_problem_size, full_problem_size, 0, 0, CHAM_descC->m / 2, + CHAM_descC->n / 2, p_grid, q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_C12, is_OOC, nullptr, float_point, dts, - dts, dts * dts, n, n, CHAM_descC->m / 2, 0, CHAM_descC->m / 2, CHAM_descC->n / 2, + dts, dts * dts, full_problem_size, full_problem_size, CHAM_descC->m / 2, 0, + CHAM_descC->m / 2, CHAM_descC->n / 2, p_grid, q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_C22, is_OOC, nullptr, float_point, dts, - dts, dts * dts, n, n, CHAM_descC->m / 2, CHAM_descC->n / 2, CHAM_descC->m / 2, + dts, dts * dts, full_problem_size, full_problem_size, CHAM_descC->m / 2, + CHAM_descC->n / 2, CHAM_descC->m / 2, CHAM_descC->n / 2, p_grid, q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z_1, is_OOC, nullptr, float_point, dts, - dts, dts * dts, n / 2, 1, 0, 0, n / 2, 1, p_grid, q_grid); + dts, dts * dts, full_problem_size / 2, 1, 0, 0, full_problem_size / 2, 1, p_grid, + q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z_2, is_OOC, nullptr, float_point, dts, - dts, dts * dts, n / 2, 1, 0, 0, n / 2, 1, p_grid, q_grid); + dts, dts * dts, full_problem_size / 2, 1, 0, 0, full_problem_size / 2, 1, p_grid, + q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_PRODUCT_1, is_OOC, nullptr, float_point, dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_PRODUCT_2, is_OOC, nullptr, float_point, dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); } + if (aConfigurations.GetIsNonGaussian()) { + aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_SUM, is_OOC, nullptr, float_point, + dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); + } + //stop gsl error handler gsl_set_error_handler_off(); aDescriptorData.SetIsDescriptorInitiated(true); @@ -111,7 +124,7 @@ void LinearAlgebraMethods::InitiateFisherDescriptors(configurations::Configur } // Get the problem size and other configuration parameters - int n = aConfigurations.GetProblemSize(); + int full_problem_size = aConfigurations.GetProblemSize(); int num_params = kernels::KernelsConfigurations::GetParametersNumberKernelMap()[aConfigurations.GetKernelName()]; int dts = aConfigurations.GetDenseTileSize(); int p_grid = aConfigurations.GetPGrid(); @@ -139,31 +152,36 @@ void LinearAlgebraMethods::InitiateFisherDescriptors(configurations::Configur if (!aDescriptorData.GetIsDescriptorInitiated()) { aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_C, is_OOC, nullptr, float_point, dts, - dts, dts * dts, n, n, 0, 0, n, n, p_grid, q_grid); + dts, dts * dts, full_problem_size, full_problem_size, 0, 0, full_problem_size, + full_problem_size, p_grid, q_grid); } aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, common::DESCRIPTOR_A, is_OOC, nullptr, float_point, dts, dts, dts * dts, num_params, num_params, 0, 0, num_params, num_params, p_grid, q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, common::DESCRIPTOR_CJ, is_OOC, nullptr, float_point, - dts, dts, dts * dts, n, n, 0, 0, n, n, p_grid, q_grid); + dts, dts, dts * dts, full_problem_size, full_problem_size, 0, 0, full_problem_size, + full_problem_size, p_grid, q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, common::DESCRIPTOR_CK, is_OOC, nullptr, float_point, - dts, dts, dts * dts, n, n, 0, 0, n, n, p_grid, q_grid); + dts, dts, dts * dts, full_problem_size, full_problem_size, 0, 0, full_problem_size, + full_problem_size, p_grid, q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, common::DESCRIPTOR_RESULTS, is_OOC, nullptr, - float_point, dts, dts, dts * dts, n, n, 0, 0, n, n, p_grid, q_grid); + float_point, dts, dts, dts * dts, full_problem_size, full_problem_size, 0, 0, + full_problem_size, full_problem_size, p_grid, q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, common::DESCRIPTOR_C_TRACE, is_OOC, nullptr, float_point, dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); aDescriptorData.SetDescriptor(common::CHAMELEON_DESCRIPTOR, common::DESCRIPTOR_C_DIAG, is_OOC, nullptr, float_point, - dts, dts, dts * dts, n, 1, 0, 0, n, 1, p_grid, q_grid); + dts, dts, dts * dts, full_problem_size, 1, 0, 0, full_problem_size, 1, p_grid, + q_grid); } template void LinearAlgebraMethods::InitiatePredictionDescriptors( - Configurations &aConfigurations, ExaGeoStatData &aData) { + Configurations &aConfigurations, std::unique_ptr> &aData, const int &aP) { if (!this->mpContext) { throw std::runtime_error( @@ -186,44 +204,57 @@ void LinearAlgebraMethods::InitiatePredictionDescriptors( } else { throw runtime_error("Unsupported for now!"); } - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z_OBSERVATIONS, is_OOC, nullptr, - float_point, dts, dts, dts * dts, n_z_obs, 1, 0, 0, n_z_obs, 1, p_grid, - q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z_OBSERVATIONS, is_OOC, nullptr, + float_point, dts, dts, dts * dts, n_z_obs, 1, 0, 0, n_z_obs, 1, p_grid, + q_grid); if (aConfigurations.GetIsMSPE()) { - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z_Actual, is_OOC, nullptr, - float_point, dts, dts, dts * dts, z_miss_number, 1, 0, 0, - z_miss_number, 1, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_MSPE, is_OOC, nullptr, - float_point, dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_MSPE_1, is_OOC, nullptr, - float_point, dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_MSPE_2, is_OOC, nullptr, - float_point, dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); - } - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z_MISS, is_OOC, nullptr, - float_point, dts, dts, dts * dts, z_miss_number, 1, 0, 0, z_miss_number, 1, - p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z_Actual, is_OOC, nullptr, + float_point, dts, dts, dts * dts, z_miss_number, 1, 0, 0, + z_miss_number, 1, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_MSPE, is_OOC, nullptr, + float_point, dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_MSPE_1, is_OOC, nullptr, + float_point, dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_MSPE_2, is_OOC, nullptr, + float_point, dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); + } + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z_MISS, is_OOC, nullptr, + float_point, dts, dts, dts * dts, z_miss_number, 1, 0, 0, z_miss_number, + 1, p_grid, q_grid); descriptor::ExaGeoStatDescriptor exaGeoStatDescriptor; - auto *CHAM_descC12 = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C12).chameleon_desc; + auto *CHAM_descC12 = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C12).chameleon_desc; if (CHAM_descC12) { exaGeoStatDescriptor.DestroyDescriptor(CHAMELEON_DESCRIPTOR, CHAM_descC12); } - auto *CHAM_descC22 = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C22).chameleon_desc; + auto *CHAM_descC22 = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C22).chameleon_desc; if (CHAM_descC22) { exaGeoStatDescriptor.DestroyDescriptor(CHAMELEON_DESCRIPTOR, CHAM_descC22); } - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_C12, is_OOC, nullptr, float_point, - dts, dts, dts * dts, z_miss_number, n_z_obs, 0, 0, z_miss_number, n_z_obs, - p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_C22, is_OOC, nullptr, float_point, - dts, dts, dts * dts, n_z_obs, n_z_obs, 0, 0, n_z_obs, n_z_obs, p_grid, - q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_C22, is_OOC, nullptr, + float_point, dts, dts, dts * dts, n_z_obs, n_z_obs, 0, 0, n_z_obs, + n_z_obs, p_grid, q_grid); + if (aConfigurations.GetIsNonGaussian()) { + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_R, is_OOC, nullptr, + float_point, dts, dts, dts * dts, n_z_obs, z_miss_number, 0, 0, + n_z_obs, z_miss_number, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_R_COPY, is_OOC, nullptr, + float_point, dts, dts, dts * dts, n_z_obs, z_miss_number, 0, 0, + n_z_obs, z_miss_number, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_C12, is_OOC, nullptr, + float_point, dts, dts, dts * dts, z_miss_number, z_miss_number, 0, 0, + z_miss_number, z_miss_number, p_grid, q_grid); + } else { + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_C12, is_OOC, nullptr, + float_point, dts, dts, dts * dts, z_miss_number, n_z_obs, 0, 0, + z_miss_number, n_z_obs, p_grid, q_grid); + } } - template -void LinearAlgebraMethods::InitiateMLOEMMOMDescriptors(Configurations &aConfigurations, ExaGeoStatData &aData) { +void LinearAlgebraMethods::InitiateMLOEMMOMDescriptors(Configurations &aConfigurations, + std::unique_ptr> &aData, + const int &aP) { if (!this->mpContext) { throw std::runtime_error( @@ -235,7 +266,6 @@ void LinearAlgebraMethods::InitiateMLOEMMOMDescriptors(Configurations &aConfi int p_grid = aConfigurations.GetPGrid(); int q_grid = aConfigurations.GetQGrid(); bool is_OOC = aConfigurations.GetIsOOC(); - int P = aConfigurations.GetP(); FloatPoint float_point; if (sizeof(T) == SIZE_OF_FLOAT) { @@ -245,39 +275,42 @@ void LinearAlgebraMethods::InitiateMLOEMMOMDescriptors(Configurations &aConfi } else { throw runtime_error("Unsupported for now!"); } - - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_k_T, is_OOC, nullptr, float_point, - dts, dts, dts * dts, P * n_z_obs, P, 0, 0, P * n_z_obs, P, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_k_A, is_OOC, nullptr, float_point, - dts, dts, dts * dts, P * n_z_obs, P, 0, 0, P * n_z_obs, P, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_k_A_TMP, is_OOC, nullptr, - float_point, dts, dts, dts * dts, P * n_z_obs, P, 0, 0, P * n_z_obs, P, - p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_k_T_TMP, is_OOC, nullptr, - float_point, dts, dts, dts * dts, P * n_z_obs, P, 0, 0, P * n_z_obs, P, - p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_EXPR_1, is_OOC, nullptr, - float_point, dts, dts, dts * dts, P, P, 0, 0, P, P, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_EXPR_2, is_OOC, nullptr, - float_point, dts, dts, dts * dts, P, P, 0, 0, P, P, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_EXPR_3, is_OOC, nullptr, - float_point, dts, dts, dts * dts, P, P, 0, 0, P, P, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_EXPR_4, is_OOC, nullptr, - float_point, dts, dts, dts * dts, P, P, 0, 0, P, P, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_MLOE, is_OOC, nullptr, - float_point, dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_MMOM, is_OOC, nullptr, - float_point, dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_TRUTH_ALPHA, is_OOC, nullptr, - float_point, dts, dts, dts * dts, P, P, 0, 0, P, P, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_TIMATED_ALPHA, is_OOC, nullptr, - float_point, dts, dts, dts * dts, P, P, 0, 0, P, P, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_K_T, is_OOC, nullptr, float_point, - dts, dts, dts * dts, P * n_z_obs, P * n_z_obs, 0, 0, P * n_z_obs, - P * n_z_obs, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_K_A, is_OOC, nullptr, float_point, - dts, dts, dts * dts, P * n_z_obs, P * n_z_obs, 0, 0, P * n_z_obs, - P * n_z_obs, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_k_T, is_OOC, nullptr, + float_point, + dts, dts, dts * dts, n_z_obs, aP, 0, 0, n_z_obs, aP, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_k_A, is_OOC, nullptr, + float_point, + dts, dts, dts * dts, n_z_obs, aP, 0, 0, n_z_obs, aP, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_k_A_TMP, is_OOC, nullptr, + float_point, dts, dts, dts * dts, n_z_obs, aP, 0, 0, n_z_obs, aP, + p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_k_T_TMP, is_OOC, nullptr, + float_point, dts, dts, dts * dts, n_z_obs, aP, 0, 0, n_z_obs, aP, + p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_EXPR_1, is_OOC, nullptr, + float_point, dts, dts, dts * dts, aP, aP, 0, 0, aP, aP, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_EXPR_2, is_OOC, nullptr, + float_point, dts, dts, dts * dts, aP, aP, 0, 0, aP, aP, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_EXPR_3, is_OOC, nullptr, + float_point, dts, dts, dts * dts, aP, aP, 0, 0, aP, aP, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_EXPR_4, is_OOC, nullptr, + float_point, dts, dts, dts * dts, aP, aP, 0, 0, aP, aP, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_MLOE, is_OOC, nullptr, + float_point, dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_MMOM, is_OOC, nullptr, + float_point, dts, dts, dts * dts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_TRUTH_ALPHA, is_OOC, nullptr, + float_point, dts, dts, dts * dts, aP, aP, 0, 0, aP, aP, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_TIMATED_ALPHA, is_OOC, nullptr, + float_point, dts, dts, dts * dts, aP, aP, 0, 0, aP, aP, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_K_T, is_OOC, nullptr, + float_point, + dts, dts, dts * dts, n_z_obs, n_z_obs, 0, 0, n_z_obs, + n_z_obs, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::CHAMELEON_DESCRIPTOR, DESCRIPTOR_K_A, is_OOC, nullptr, + float_point, + dts, dts, dts * dts, n_z_obs, n_z_obs, 0, 0, n_z_obs, + n_z_obs, p_grid, q_grid); //stop gsl error handler gsl_set_error_handler_off(); } @@ -285,18 +318,19 @@ void LinearAlgebraMethods::InitiateMLOEMMOMDescriptors(Configurations &aConfi template void LinearAlgebraMethods::GenerateSyntheticData(configurations::Configurations &aConfigurations, const hardware::ExaGeoStatHardware &aHardware, - dataunits::ExaGeoStatData &aData, + std::unique_ptr> &aData, const kernels::Kernel &aKernel) { this->mpContext = aHardware.GetChameleonContext(); - this->InitiateDescriptors(aConfigurations, *aData.GetDescriptorData()); - auto median_locations = Locations(1, aData.GetLocations()->GetDimension()); - this->GenerateObservationsVector(aConfigurations, aData, aData.GetLocations(), aData.GetLocations(), - &median_locations, 0, aKernel); + this->InitiateDescriptors(aConfigurations, *aData->GetDescriptorData(), aKernel.GetVariablesNumber()); + auto median_locations = Locations(1, aData->GetLocations()->GetDimension()); + this->GenerateObservationsVector(aConfigurations, aData, aData->GetLocations(), aData->GetLocations(), + &median_locations, aConfigurations.GetDistanceMetric(), aKernel); } template -void LinearAlgebraMethods::GenerateObservationsVector(Configurations &aConfigurations, ExaGeoStatData &aData, +void LinearAlgebraMethods::GenerateObservationsVector(Configurations &aConfigurations, + std::unique_ptr> &aData, Locations *apLocation1, Locations *apLocation2, Locations *apLocation3, const int &aDistanceMetric, const kernels::Kernel &aKernel) { @@ -306,8 +340,8 @@ void LinearAlgebraMethods::GenerateObservationsVector(Configurations &aConfig throw std::runtime_error( "ExaGeoStat hardware is not initialized, please use 'ExaGeoStatHardware(computation, cores_number, gpu_numbers);'."); } - - const int n = aConfigurations.GetProblemSize(); + const int P = aKernel.GetVariablesNumber(); + const int full_problem_size = aConfigurations.GetProblemSize() * P; int seed = aConfigurations.GetSeed(); int initial_seed[4] = {seed, seed, seed, 1}; T time_facto = 0.0, time_trmm = 0.0, matrix_gen_time = 0.0, flops = 0; @@ -315,17 +349,17 @@ void LinearAlgebraMethods::GenerateObservationsVector(Configurations &aConfig // Create a Chameleon sequence, if not initialized before through the same descriptors RUNTIME_request_t request_array[2] = {RUNTIME_REQUEST_INITIALIZER, RUNTIME_REQUEST_INITIALIZER}; RUNTIME_sequence_t *sequence; - if (!aData.GetDescriptorData()->GetSequence()) { + if (!aData->GetDescriptorData()->GetSequence()) { ExaGeoStatCreateSequence(&sequence); - aData.GetDescriptorData()->SetSequence(sequence); - aData.GetDescriptorData()->SetRequest(request_array); + aData->GetDescriptorData()->SetSequence(sequence); + aData->GetDescriptorData()->SetRequest(request_array); } else { - sequence = (RUNTIME_sequence_t *) aData.GetDescriptorData()->GetSequence(); + sequence = (RUNTIME_sequence_t *) aData->GetDescriptorData()->GetSequence(); } - auto *CHAM_descC = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C).chameleon_desc; + auto *CHAM_descC = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C).chameleon_desc; //normal random generation of e -- ei~N(0, 1) to generate Z - auto *randomN = new T[n]; - LAPACKE_dlarnv(3, initial_seed, n, (double *) randomN); + auto *randomN = new T[full_problem_size]; + LAPACKE_dlarnv(3, initial_seed, full_problem_size, (double *) randomN); //Generate the co-variance matrix C auto *theta = new T[aConfigurations.GetInitialTheta().size()]; @@ -337,7 +371,7 @@ void LinearAlgebraMethods::GenerateObservationsVector(Configurations &aConfig int upper_lower = EXAGEOSTAT_LOWER; START_TIMING(matrix_gen_time); - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_descC, upper_lower, apLocation1, apLocation2, + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_descC, upper_lower, apLocation1, apLocation2, apLocation3, theta, aDistanceMetric, &aKernel); ExaGeoStatSequenceWait(sequence); STOP_TIMING(matrix_gen_time); @@ -345,16 +379,16 @@ void LinearAlgebraMethods::GenerateObservationsVector(Configurations &aConfig //Copy randomN to Z VERBOSE("Generate Normal Random Distribution Vector Z (Synthetic Dataset Generation Phase) .....") - auto *CHAM_descZ = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc; - CopyDescriptorZ(*aData.GetDescriptorData(), CHAM_descZ, randomN); + auto *CHAM_descZ = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc; + CopyDescriptorZ(*aData->GetDescriptorData(), CHAM_descZ, randomN); VERBOSE("Done.") //Cholesky factorization for the Co-variance matrix C VERBOSE("Cholesky factorization of Sigma (Synthetic Dataset Generation Phase) .....") START_TIMING(time_facto); - ExaGeoStatPotrfTile(EXAGEOSTAT_LOWER, CHAM_descC, aConfigurations.GetBand(), nullptr, nullptr, 0, 0); + ExaGeoStatPotrfTile(EXAGEOSTAT_LOWER, CHAM_descC, 0, nullptr, nullptr, 0, 0); STOP_TIMING(time_facto); - flops = flops + flops_dpotrf(n); + flops = flops + flops_dpotrf(full_problem_size); VERBOSE("Done.") //Triangular matrix-matrix multiplication @@ -363,17 +397,16 @@ void LinearAlgebraMethods::GenerateObservationsVector(Configurations &aConfig ExaGeoStatTrmmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_NO_TRANS, EXAGEOSTAT_NON_UNIT, 1, CHAM_descC, CHAM_descZ); STOP_TIMING(time_trmm); - flops = flops + flops_dtrmm(ChamLeft, n, CHAM_descZ->n); + flops = flops + flops_dtrmm(ChamLeft, full_problem_size, CHAM_descZ->n); VERBOSE("Done.") - if (aConfigurations.GetKernelName() == "UnivariateMaternNonGaussian") { + if (aConfigurations.GetIsNonGaussian()) { //Gaussian to non-gaussian transformation VERBOSE("Convert Z Gaussian to non-Gaussian (Synthetic Dataset Generation Phase) .....") - ExaGeoStatGaussianToNonTileAsync(*aData.GetDescriptorData(), CHAM_descZ, theta); + ExaGeoStatGaussianToNonTileAsync(*aData->GetDescriptorData(), CHAM_descZ, theta); VERBOSE("Done.") } delete[] theta; - const int P = aConfigurations.GetP(); if (aConfigurations.GetLogger()) { T *pMatrix; VERBOSE("Writing generated data to the disk (Synthetic Dataset Generation Phase) .....") @@ -388,7 +421,7 @@ void LinearAlgebraMethods::GenerateObservationsVector(Configurations &aConfig #else pMatrix = (T *) CHAM_descZ->mat; string path = aConfigurations.GetLoggerPath(); - helpers::DiskWriter::WriteVectorsToDisk(*pMatrix, n, P, path, *apLocation1); + helpers::DiskWriter::WriteVectorsToDisk(*pMatrix, full_problem_size, P, path, *apLocation1); #endif VERBOSE("Done.") } @@ -406,67 +439,66 @@ void LinearAlgebraMethods::GenerateObservationsVector(Configurations &aConfig results::Results::GetInstance()->SetTotalDataGenerationExecutionTime(time_facto + time_trmm); results::Results::GetInstance()->SetTotalDataGenerationFlops(total_flops); - results::Results::GetInstance()->SetGeneratedLocationsNumber(n); - results::Results::GetInstance()->SetGeneratedLocationsNumber(n); + results::Results::GetInstance()->SetGeneratedLocationsNumber(full_problem_size / aConfigurations.GetTimeSlot()); results::Results::GetInstance()->SetIsLogger(aConfigurations.GetLogger()); results::Results::GetInstance()->SetLoggerPath(aConfigurations.GetLoggerPath()); } template -T *LinearAlgebraMethods::ExaGeoStatMLEPredictTile(ExaGeoStatData &aData, T *apTheta, const int &aZMissNumber, - const int &aZObsNumber, T *apZObs, T *apZActual, T *apZMiss, - const ExaGeoStatHardware &aHardware, +T *LinearAlgebraMethods::ExaGeoStatMLEPredictTile(std::unique_ptr> &aData, T *apTheta, + const int &aZMissNumber, const int &aZObsNumber, T *apZObs, + T *apZActual, T *apZMiss, const ExaGeoStatHardware &aHardware, Configurations &aConfiguration, Locations &aMissLocations, Locations &aObsLocations, const kernels::Kernel &aKernel) { int i; this->SetContext(aHardware.GetChameleonContext()); - this->InitiatePredictionDescriptors(aConfiguration, aData); + this->InitiatePredictionDescriptors(aConfiguration, aData, aKernel.GetVariablesNumber()); double time_solve, mat_gen_time, time_gemm, time_mspe = 0.0, flops = 0.0; int num_params; - auto *CHAM_desc_Zmiss = aData.GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_Z_MISS).chameleon_desc; - auto *CHAM_desc_C12 = aData.GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_C12).chameleon_desc; - auto *CHAM_desc_C22 = aData.GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_C22).chameleon_desc; - auto *CHAM_desc_mspe = aData.GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_MSPE).chameleon_desc; - auto *CHAM_desc_mspe1 = aData.GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_MSPE_1).chameleon_desc; - auto *CHAM_desc_mspe2 = aData.GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_MSPE_2).chameleon_desc; - auto *CHAM_desc_Zactual = aData.GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_Z_Actual).chameleon_desc; - auto *CHAM_desc_Zobs = aData.GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_Z_OBSERVATIONS).chameleon_desc; - - T *mspe = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mspe); + auto *CHAM_desc_Zmiss = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_Z_MISS).chameleon_desc; + auto *CHAM_desc_C12 = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_C12).chameleon_desc; + auto *CHAM_desc_C22 = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_C22).chameleon_desc; + auto *CHAM_desc_mspe = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_MSPE).chameleon_desc; + auto *CHAM_desc_mspe1 = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_MSPE_1).chameleon_desc; + auto *CHAM_desc_mspe2 = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_MSPE_2).chameleon_desc; + auto *CHAM_desc_Zactual = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_Z_Actual).chameleon_desc; + auto *CHAM_desc_Zobs = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_Z_OBSERVATIONS).chameleon_desc; + + T *mspe = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mspe); *mspe = 0; - T *mspe_1 = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mspe1); + T *mspe_1 = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mspe1); *mspe_1 = 0; - T *mspe_2 = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mspe2); + T *mspe_2 = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mspe2); *mspe_2 = 0; auto kernel_name = aConfiguration.GetKernelName(); num_params = aKernel.GetParametersNumbers(); - auto median_locations = Locations(1, aData.GetLocations()->GetDimension()); - aData.CalculateMedianLocations(kernel_name, median_locations); + auto median_locations = Locations(1, aData->GetLocations()->GetDimension()); + aData->CalculateMedianLocations(kernel_name, median_locations); // Create a Chameleon sequence, if not initialized before through the same descriptors RUNTIME_request_t request_array[2] = {RUNTIME_REQUEST_INITIALIZER, RUNTIME_REQUEST_INITIALIZER}; RUNTIME_sequence_t *sequence; - if (!aData.GetDescriptorData()->GetSequence()) { + if (!aData->GetDescriptorData()->GetSequence()) { ExaGeoStatCreateSequence(&sequence); - aData.GetDescriptorData()->SetSequence(sequence); - aData.GetDescriptorData()->SetRequest(request_array); + aData->GetDescriptorData()->SetSequence(sequence); + aData->GetDescriptorData()->SetRequest(request_array); } else { - sequence = (RUNTIME_sequence_t *) aData.GetDescriptorData()->GetSequence(); + sequence = (RUNTIME_sequence_t *) aData->GetDescriptorData()->GetSequence(); } - void *request = aData.GetDescriptorData()->GetRequest(); + void *request = aData->GetDescriptorData()->GetRequest(); //Copy data to vectors VERBOSE("Copy measurements vector to descZobs descriptor...") @@ -493,12 +525,12 @@ T *LinearAlgebraMethods::ExaGeoStatMLEPredictTile(ExaGeoStatData &aData, T START_TIMING(mat_gen_time); VERBOSE("Generate C22 Covariance Matrix... (Prediction Stage)") int upper_lower = EXAGEOSTAT_LOWER; - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_desc_C22, upper_lower, &aObsLocations, + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_C22, upper_lower, &aObsLocations, &aObsLocations, &median_locations, apTheta, 0, &aKernel); ExaGeoStatSequenceWait(sequence); VERBOSE("Done.") VERBOSE("Generate C12 Covariance Matrix... (Prediction Stage)") - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_desc_C12, upper_lower, &aMissLocations, + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_C12, upper_lower, &aMissLocations, &aObsLocations, &median_locations, apTheta, 0, &aKernel); ExaGeoStatSequenceWait(sequence); VERBOSE("Done.") @@ -524,9 +556,9 @@ T *LinearAlgebraMethods::ExaGeoStatMLEPredictTile(ExaGeoStatData &aData, T if (apZActual) { START_TIMING(time_mspe); VERBOSE("Calculate Mean Square Prediction Error (MSPE) ... (Prediction Stage)") - if (kernel_name == "BivariateMaternParsimonious" || kernel_name == "BivariateMaternParsimonious2" || - kernel_name == "BivariateMaternParsimoniousProfile") { - throw runtime_error("Bivariate Kernels are not supported yet."); + if (kernel_name == "BivariateMaternParsimonious") { + ExaGeoStatMLEMSPEBivariateTileAsync(CHAM_desc_Zactual, CHAM_desc_Zmiss, CHAM_desc_mspe1, CHAM_desc_mspe2, + CHAM_desc_mspe, sequence, &request_array[0]); } else { this->ExaGeoStatMLEMSPETileAsync(CHAM_desc_Zactual, CHAM_desc_Zmiss, CHAM_desc_mspe, sequence, request); } @@ -547,9 +579,9 @@ T *LinearAlgebraMethods::ExaGeoStatMLEPredictTile(ExaGeoStatData &aData, T "\n\n# of missing observations :%d\n\nPrediction Execution Time: %.8f, ""Flops: %.8f, Mean Square Prediction Error (MSPE): %.8f\n\n", aZMissNumber, (mat_gen_time + time_solve + time_mspe), (flops / 1e9 / (time_solve)), *mspe); } - LOGGER("- Z Actual .. Z Miss") + VERBOSE("- Z Actual .. Z Miss") for (i = 0; i < aZMissNumber; i++) { - LOGGER(" (" << apZActual[i] << ", " << apZMiss[i] << ")") + VERBOSE(" (" << apZActual[i] << ", " << apZMiss[i] << ")") } results::Results::GetInstance()->SetMSPEExecutionTime(time_solve + time_gemm); @@ -565,17 +597,220 @@ T *LinearAlgebraMethods::ExaGeoStatMLEPredictTile(ExaGeoStatData &aData, T } template -void LinearAlgebraMethods::ExaGeoStatMLETileMLOEMMOM(Configurations &aConfigurations, ExaGeoStatData &aData, +T *LinearAlgebraMethods::ExaGeoStatMLENonGaussianPredictTile(std::unique_ptr> &aData, + T *apTheta, const int &aZMissNumber, + const int &aZObsNumber, T *apZObs, T *apZActual, + T *apZMiss, + const hardware::ExaGeoStatHardware &aHardware, + configurations::Configurations &aConfiguration, + dataunits::Locations &aMissLocations, + dataunits::Locations &aObsLocations, + const kernels::Kernel &aKernel) { + + int i; + this->SetContext(aHardware.GetChameleonContext()); + this->InitiatePredictionDescriptors(aConfiguration, aData, aKernel.GetVariablesNumber()); + + double time_solve, mat_gen_time, time_mse, mat_gen_time_2, dposv_time, gemms_time, time_trsm, time_gemm, time_mspe = 0.0, flops = 0.0; + int num_params; + + auto *CHAM_desc_Zmiss = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_Z_MISS).chameleon_desc; + auto *CHAM_desc_C12 = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_C12).chameleon_desc; + auto *CHAM_desc_C22 = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_C22).chameleon_desc; + auto *CHAM_desc_mspe = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_MSPE).chameleon_desc; + auto *CHAM_desc_mspe1 = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_MSPE_1).chameleon_desc; + auto *CHAM_desc_mspe2 = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_MSPE_2).chameleon_desc; + auto *CHAM_desc_Zactual = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_Z_Actual).chameleon_desc; + auto *CHAM_desc_Zobs = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_Z_OBSERVATIONS).chameleon_desc; + auto *CHAM_desc_R = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_R).chameleon_desc; + auto *CHAM_desc_Rcopy = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_R_COPY).chameleon_desc; + auto *CHAM_desc_product = aData->GetDescriptorData()->GetDescriptor(common::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_PRODUCT).chameleon_desc; + + T *mspe = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mspe); + *mspe = 0; + T *mspe_1 = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mspe1); + *mspe_1 = 0; + T *mspe_2 = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mspe2); + *mspe_2 = 0; + + auto kernel_name = aConfiguration.GetKernelName(); + num_params = aKernel.GetParametersNumbers(); + auto median_locations = Locations(1, aData->GetLocations()->GetDimension()); + aData->CalculateMedianLocations(kernel_name, median_locations); + + // Create a Chameleon sequence, if not initialized before through the same descriptors + RUNTIME_request_t request_array[2] = {RUNTIME_REQUEST_INITIALIZER, RUNTIME_REQUEST_INITIALIZER}; + RUNTIME_sequence_t *sequence; + if (!aData->GetDescriptorData()->GetSequence()) { + ExaGeoStatCreateSequence(&sequence); + aData->GetDescriptorData()->SetSequence(sequence); + aData->GetDescriptorData()->SetRequest(request_array); + } else { + sequence = (RUNTIME_sequence_t *) aData->GetDescriptorData()->GetSequence(); + } + void *request = aData->GetDescriptorData()->GetRequest(); + + //Copy data to vectors + VERBOSE("Copy measurements vector to descZobs descriptor...") + ExaGeoStatLap2Desc(apZObs, aZObsNumber, CHAM_desc_Zobs, UpperLower::EXAGEOSTAT_UPPER_LOWER); + VERBOSE("Done.") + + if (apZActual) { + //Copy data to vectors + VERBOSE("Copy actual measurements vector to descZactual descriptor...") + ExaGeoStatLap2Desc(apZActual, aZMissNumber, CHAM_desc_Zactual, UpperLower::EXAGEOSTAT_UPPER_LOWER); + VERBOSE("Done.") + } + + LOGGER("- Estimated Parameters (", true) + for (i = 0; i < num_params; i++) { + LOGGER_PRECISION(apTheta[i]) + if (i != num_params - 1) { + LOGGER_PRECISION(", ") + } + } + LOGGER_PRECISION(")") + LOGGER("") + + //Convert the non-Gaussian observation to Gaussian + this->ExaGeoStatNonGaussianTransformTileAsync(CHAM_desc_Zobs, CHAM_desc_product, apTheta, sequence, + &request_array[0]); + + START_TIMING(mat_gen_time); + VERBOSE("Generate R_theta Covariance Matrix... (Prediction Stage)") + int upper_lower = EXAGEOSTAT_LOWER; + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_C22, upper_lower, &aObsLocations, + &aObsLocations, &median_locations, apTheta, 0, &aKernel); + ExaGeoStatSequenceWait(sequence); + VERBOSE("Done.") + STOP_TIMING(mat_gen_time); + + START_TIMING(time_solve); + VERBOSE("Calculate dposv R_theta Covariance Matrix... (Prediction Stage)"); + ExaGeoStatPosvTile(EXAGEOSTAT_LOWER, CHAM_desc_C22, CHAM_desc_Zobs); + flops = flops + flops_dpotrf(aZObsNumber); + flops = flops + 2 * flops_dtrsm(ChamLeft, CHAM_desc_C22->m, CHAM_desc_Zobs->n); + VERBOSE("Done.") + STOP_TIMING(time_solve); + + START_TIMING(mat_gen_time_2); + VERBOSE("Generate R_theta Covariance Matrix... (Prediction Stage)") + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_R, upper_lower, &aObsLocations, + &aMissLocations, &median_locations, apTheta, 0, &aKernel); + ExaGeoStatSequenceWait(sequence); + VERBOSE("Done.") + STOP_TIMING(mat_gen_time_2); + + ExaGeoStatLapackCopyTile(EXAGEOSTAT_LOWER, CHAM_desc_R, CHAM_desc_Rcopy); + + START_TIMING(time_trsm); + VERBOSE("Calculate dposv r_theta Covariance Matrix... (Prediction Stage)"); + ExaGeoStatTrsmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_NO_TRANS, EXAGEOSTAT_NON_UNIT, 1, CHAM_desc_C22, + nullptr, nullptr, CHAM_desc_R, 0); + ExaGeoStatTrsmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_TRANS, EXAGEOSTAT_NON_UNIT, 1, CHAM_desc_C22, + nullptr, nullptr, CHAM_desc_R, 0); + flops = flops + 2 * flops_dtrsm(ChamLeft, CHAM_desc_C22->m, CHAM_desc_Zobs->n); + VERBOSE("Done.") + STOP_TIMING(time_trsm); + + START_TIMING(time_gemm); + VERBOSE("For each missing location, Generate correlation vector CHAMELEON_descr (Prediction Stage) ....."); + CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_desc_Rcopy, CHAM_desc_Zobs, 0, CHAM_desc_Zmiss); + CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_desc_Rcopy, CHAM_desc_R, 0, CHAM_desc_C12); + STOP_TIMING(time_gemm); + + auto r = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_C12); + auto Zmiss2 = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_Zmiss);; + + auto ng_nu = new T[aZMissNumber]; + auto ng_sigma_sq = new T[aZMissNumber]; + + double mu = -1; + double sigma_sq = -1; + + for (i = 0; i < aZMissNumber; i++) { + mu = Zmiss2[i]; + sigma_sq = 1 - r[i * aZMissNumber + i]; + ng_nu[i] = mu; + ng_sigma_sq[i] = sigma_sq; + //r^t X Z + apZMiss[i] = apTheta[2] + (apTheta[3] / (apTheta[4] * sqrt(1 - apTheta[5] * sigma_sq))) * + exp(apTheta[5] * pow(mu, 2) / (2 * (1 - apTheta[5] * sigma_sq))) * + (exp((pow(apTheta[4], 2) * sigma_sq + 2 * apTheta[4] * mu) / + (2 * (1 - apTheta[5] * sigma_sq))) - 1); + } + VERBOSE(" Done.") + + ExaGeoStatLap2Desc(apZMiss, aZMissNumber, CHAM_desc_Zmiss, EXAGEOSTAT_UPPER_LOWER); + + if (apZActual != nullptr) { + START_TIMING(time_mspe); + VERBOSE("Calculate Mean Square Error (MSE) ... (Prediction Stage) \n"); + this->ExaGeoStatMLEMSPETileAsync(CHAM_desc_Zactual, CHAM_desc_Zmiss, CHAM_desc_mspe, sequence, request); + ExaGeoStatSequenceWait(sequence); + VERBOSE(" Done.") + STOP_TIMING(time_mspe); + *mspe /= aZMissNumber; + } else { + *mspe = -1; + } + +#if defined(CHAMELEON_USE_MPI) + if(CHAMELEON_My_Mpi_Rank() == 0) + { +#endif + if (aConfiguration.GetLogger()) { + fprintf(aConfiguration.GetFileLogPath(), + "\n\n# of missing observations :%d\n\nPrediction Execution Time: %.8f, ""Flops: %.8f, Mean Square Prediction Error (MSPE): %.8f\n\n", + aZMissNumber, (mat_gen_time + mat_gen_time_2 + time_solve + time_mspe), (flops / 1e9 / (time_solve)), + *mspe); + } + VERBOSE("- Z Actual .. Z Miss") + for (i = 0; i < aZMissNumber; i++) { + VERBOSE(" (" << apZActual[i] << ", " << apZMiss[i] << ")") + } + + results::Results::GetInstance()->SetMSPEExecutionTime(time_solve + time_gemm + time_trsm); + results::Results::GetInstance()->SetMSPEFlops((flops / 1e9 / (time_solve + time_gemm))); + results::Results::GetInstance()->SetMSPEError(*mspe); + +#if defined(CHAMELEON_USE_MPI) + } +#endif + + T *all_mspe = new T[3]; + all_mspe[0] = *mspe; + all_mspe[1] = *mspe_1; + all_mspe[2] = *mspe_2; + delete[] ng_sigma_sq; + delete[] ng_nu; + return all_mspe; +} + +template +void LinearAlgebraMethods::ExaGeoStatMLETileMLOEMMOM(Configurations &aConfigurations, + std::unique_ptr> &aData, const ExaGeoStatHardware &aHardware, T *apTruthTheta, T *apEstimatedTheta, Locations &aMissLocations, Locations &aObsLocations, const kernels::Kernel &aKernel) { this->SetContext(aHardware.GetChameleonContext()); - this->InitiateMLOEMMOMDescriptors(aConfigurations, aData); + this->InitiateMLOEMMOMDescriptors(aConfigurations, aData, aKernel.GetVariablesNumber()); auto kernel_name = aConfigurations.GetKernelName(); - auto median_locations = Locations(1, aData.GetLocations()->GetDimension()); - aData.CalculateMedianLocations(kernel_name, median_locations); + auto median_locations = Locations(1, aData->GetLocations()->GetDimension()); + aData->CalculateMedianLocations(kernel_name, median_locations); int n_z_miss = aConfigurations.GetUnknownObservationsNb(); int num_par = aKernel.GetParametersNumbers(); @@ -595,49 +830,53 @@ void LinearAlgebraMethods::ExaGeoStatMLETileMLOEMMOM(Configurations &aConfigu auto loe = new T[n_z_miss]; auto mom = new T[n_z_miss]; - auto *CHAM_desc_k_t = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_k_T).chameleon_desc; - auto *CHAM_desc_k_a = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_k_A).chameleon_desc; - auto *CHAM_desc_K_t = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_K_T).chameleon_desc; - auto *CHAM_desc_K_a = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_K_A).chameleon_desc; - auto *CHAM_desc_k_a_tmp = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, - DESCRIPTOR_k_A_TMP).chameleon_desc; - auto *CHAM_desc_k_t_tmp = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, - DESCRIPTOR_k_T_TMP).chameleon_desc; - auto *CHAM_desc_expr1 = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, - DESCRIPTOR_EXPR_1).chameleon_desc; - auto *CHAM_desc_expr2 = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, - DESCRIPTOR_EXPR_2).chameleon_desc; - auto *CHAM_desc_expr3 = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, - DESCRIPTOR_EXPR_3).chameleon_desc; - auto *CHAM_desc_expr4 = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, - DESCRIPTOR_EXPR_4).chameleon_desc; - auto *CHAM_desc_mloe = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, - DESCRIPTOR_MLOE).chameleon_desc; - auto *CHAM_desc_mmom = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, - DESCRIPTOR_MMOM).chameleon_desc; - auto *CHAM_desc_estimated_alpha = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, - DESCRIPTOR_TIMATED_ALPHA).chameleon_desc; - auto *CHAM_desc_truth_alpha = aData.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, - DESCRIPTOR_TRUTH_ALPHA).chameleon_desc; - - T *mloe = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mloe); + auto *CHAM_desc_k_t = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_k_T).chameleon_desc; + auto *CHAM_desc_k_a = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_k_A).chameleon_desc; + auto *CHAM_desc_K_t = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_K_T).chameleon_desc; + auto *CHAM_desc_K_a = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_K_A).chameleon_desc; + auto *CHAM_desc_k_a_tmp = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_k_A_TMP).chameleon_desc; + auto *CHAM_desc_k_t_tmp = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_k_T_TMP).chameleon_desc; + auto *CHAM_desc_expr1 = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_EXPR_1).chameleon_desc; + auto *CHAM_desc_expr2 = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_EXPR_2).chameleon_desc; + auto *CHAM_desc_expr3 = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_EXPR_3).chameleon_desc; + auto *CHAM_desc_expr4 = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_EXPR_4).chameleon_desc; + auto *CHAM_desc_mloe = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_MLOE).chameleon_desc; + auto *CHAM_desc_mmom = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_MMOM).chameleon_desc; + auto *CHAM_desc_estimated_alpha = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_TIMATED_ALPHA).chameleon_desc; + auto *CHAM_desc_truth_alpha = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_TRUTH_ALPHA).chameleon_desc; + + T *mloe = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mloe); *mloe = 0; - T *mmom = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mmom); + T *mmom = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mmom); *mmom = 0; // Create a Chameleon sequence, if not initialized before through the same descriptors RUNTIME_request_t request_array[2] = {RUNTIME_REQUEST_INITIALIZER, RUNTIME_REQUEST_INITIALIZER}; RUNTIME_sequence_t *sequence; - if (!aData.GetDescriptorData()->GetSequence()) { + if (!aData->GetDescriptorData()->GetSequence()) { ExaGeoStatCreateSequence(&sequence); - aData.GetDescriptorData()->SetSequence(sequence); - aData.GetDescriptorData()->SetRequest(request_array); + aData->GetDescriptorData()->SetSequence(sequence); + aData->GetDescriptorData()->SetRequest(request_array); } else { - sequence = (RUNTIME_sequence_t *) aData.GetDescriptorData()->GetSequence(); + sequence = (RUNTIME_sequence_t *) aData->GetDescriptorData()->GetSequence(); } - void *request = aData.GetDescriptorData()->GetRequest(); + void *request = aData->GetDescriptorData()->GetRequest(); - auto lmiss = new Locations(n_z_miss, aData.GetLocations()->GetDimension()); + auto lmiss = new Locations(n_z_miss, aData->GetLocations()->GetDimension()); T nu12; T rho; T sigma_square12; @@ -680,19 +919,13 @@ void LinearAlgebraMethods::ExaGeoStatMLETileMLOEMMOM(Configurations &aConfigu this->ExaGeoStatLap2Desc(truth_alpha, m, CHAM_desc_truth_alpha, EXAGEOSTAT_UPPER_LOWER); this->ExaGeoStatLap2Desc(estimated_alpha, m, CHAM_desc_estimated_alpha, EXAGEOSTAT_UPPER_LOWER); - if (kernel_name == "BivariateMaternParsimonious2" || - kernel_name == "BivariateMaternParsimonious2Profile") { - //// TODO:not implemented in C - throw runtime_error("Selected Kernel Is Not Supported!"); - } - START_TIMING(matrix_gen); VERBOSE("Create K_a and K_t Covariance Matrices (MLOE-MMOM).....") int upper_lower = EXAGEOSTAT_LOWER; - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_desc_K_a, upper_lower, &aObsLocations, + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_K_a, upper_lower, &aObsLocations, &aObsLocations, &median_locations, apEstimatedTheta, 0, &aKernel); this->ExaGeoStatSequenceWait(sequence); - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_desc_K_t, upper_lower, &aObsLocations, + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_K_t, upper_lower, &aObsLocations, &aObsLocations, &median_locations, apTruthTheta, 0, &aKernel); this->ExaGeoStatSequenceWait(sequence); VERBOSE("Done.") @@ -728,9 +961,9 @@ void LinearAlgebraMethods::ExaGeoStatMLETileMLOEMMOM(Configurations &aConfigu } START_TIMING(vecs_gen); upper_lower = EXAGEOSTAT_UPPER_LOWER; - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_desc_k_t, upper_lower, &aObsLocations, lmiss, + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_k_t, upper_lower, &aObsLocations, lmiss, &median_locations, apTruthTheta, 0, &aKernel); - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_desc_k_a, upper_lower, &aObsLocations, lmiss, + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_k_a, upper_lower, &aObsLocations, lmiss, &median_locations, apEstimatedTheta, 0, &aKernel); this->ExaGeoStatSequenceWait(sequence); @@ -787,7 +1020,6 @@ void LinearAlgebraMethods::ExaGeoStatMLETileMLOEMMOM(Configurations &aConfigu } STOP_TIMING(trsm3); - START_TIMING(trsm4); // Triangular Solve (TRSM) k_t = TRSM(L_t^-T, k_t) if (verbose) { @@ -862,13 +1094,13 @@ void LinearAlgebraMethods::ExaGeoStatMLETileMLOEMMOM(Configurations &aConfigu ExaGeoStatGeaddTile(EXAGEOSTAT_NO_TRANS, 1, CHAM_desc_truth_alpha, -1, CHAM_desc_expr3); ExaGeoStatGeaddTile(EXAGEOSTAT_NO_TRANS, 1, CHAM_desc_estimated_alpha, -1, CHAM_desc_expr4); - LOGGER("- Matrix Generation Time: " << matrix_gen << " Vectors Generation Time: " << vecs_gen - << " First Cholesky factorization Time: " << cholesky1 - << " First Cholesky factorization Time: " << cholesky2) - LOGGER("- First Trsm time: " << trsm1 << " Second Trsm time: " << trsm2 << " Third Trsm time: " << trsm3 - << " Fourth Trsm time: " << trsm4) - LOGGER("- First gemm time: " << gevv1 << " Second gemm time: " << gevv2 << " Third gemm time: " << gevv3 - << " Fourth gemm time: " << gevv4 << " Fifth gemm time: " << gevv5) + VERBOSE("- Matrix Generation Time: " << matrix_gen << " Vectors Generation Time: " << vecs_gen + << " First Cholesky factorization Time: " << cholesky1 + << " First Cholesky factorization Time: " << cholesky2) + VERBOSE("- First Trsm time: " << trsm1 << " Second Trsm time: " << trsm2 << " Third Trsm time: " << trsm3 + << " Fourth Trsm time: " << trsm4) + VERBOSE("- First gemm time: " << gevv1 << " Second gemm time: " << gevv2 << " Third gemm time: " << gevv3 + << " Fourth gemm time: " << gevv4 << " Fifth gemm time: " << gevv5) ExaGeoStatMLETileAsyncMLOEMMOM(CHAM_desc_expr2, CHAM_desc_expr3, CHAM_desc_expr4, CHAM_desc_mloe, CHAM_desc_mmom, sequence, request); this->ExaGeoStatSequenceWait(sequence); @@ -902,53 +1134,54 @@ void LinearAlgebraMethods::ExaGeoStatMLETileMLOEMMOM(Configurations &aConfigu template T *LinearAlgebraMethods::ExaGeoStatFisherTile(configurations::Configurations &aConfigurations, - dataunits::ExaGeoStatData &aData, + std::unique_ptr> &aData, const hardware::ExaGeoStatHardware &aHardware, T *apTheta, const kernels::Kernel &aKernel) { this->SetContext(aHardware.GetChameleonContext()); - this->InitiateFisherDescriptors(aConfigurations, *aData.GetDescriptorData()); - - auto *CHAM_desc_A = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_A).chameleon_desc; - auto *CHAM_desc_C = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_C).chameleon_desc; - auto *CHAM_desc_CJ = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_CJ).chameleon_desc; - auto *CHAM_desc_results = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_RESULTS).chameleon_desc; - auto *CHAM_desc_CK = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_CK).chameleon_desc; - auto *CHAM_desc_C_diag = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_C_DIAG).chameleon_desc; - auto *CHAM_desc_C_trace = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_C_TRACE).chameleon_desc; - - auto trace = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_C_trace); + this->InitiateFisherDescriptors(aConfigurations, *aData->GetDescriptorData()); + + auto *CHAM_desc_A = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_A).chameleon_desc; + auto *CHAM_desc_C = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_C).chameleon_desc; + auto *CHAM_desc_CJ = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_CJ).chameleon_desc; + auto *CHAM_desc_results = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_RESULTS).chameleon_desc; + auto *CHAM_desc_CK = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_CK).chameleon_desc; + auto *CHAM_desc_C_diag = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_C_DIAG).chameleon_desc; + auto *CHAM_desc_C_trace = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_C_TRACE).chameleon_desc; + + auto trace = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_C_trace); *trace = 0.0; RUNTIME_request_t request_array[2] = {RUNTIME_REQUEST_INITIALIZER, RUNTIME_REQUEST_INITIALIZER}; RUNTIME_sequence_t *sequence; - if (!aData.GetDescriptorData()->GetSequence()) { + if (!aData->GetDescriptorData()->GetSequence()) { ExaGeoStatCreateSequence(&sequence); - aData.GetDescriptorData()->SetSequence(sequence); - aData.GetDescriptorData()->SetRequest(request_array); + aData->GetDescriptorData()->SetSequence(sequence); + aData->GetDescriptorData()->SetRequest(request_array); } else { - sequence = (RUNTIME_sequence_t *) aData.GetDescriptorData()->GetSequence(); + sequence = (RUNTIME_sequence_t *) aData->GetDescriptorData()->GetSequence(); } - void *request = aData.GetDescriptorData()->GetRequest(); + void *request = aData->GetDescriptorData()->GetRequest(); auto kernel_name = aConfigurations.GetKernelName(); int num_params = aKernel.GetParametersNumbers(); - auto median_locations = Locations(1, aData.GetLocations()->GetDimension()); - aData.CalculateMedianLocations(kernel_name, median_locations); + auto median_locations = Locations(1, aData->GetLocations()->GetDimension()); + aData->CalculateMedianLocations(kernel_name, median_locations); double time = 0.0; START_TIMING(time); VERBOSE("Generate covariance matrix CHAM_desc_C (Fisher Matrix Generation).....") - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_desc_C, EXAGEOSTAT_LOWER, aData.GetLocations(), - aData.GetLocations(), &median_locations, apTheta, aConfigurations.GetDistanceMetric(), + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_C, EXAGEOSTAT_LOWER, aData->GetLocations(), + aData->GetLocations(), &median_locations, apTheta, + aConfigurations.GetDistanceMetric(), &aKernel); ExaGeoStatSequenceWait(sequence); VERBOSE("Done.") @@ -972,11 +1205,12 @@ T *LinearAlgebraMethods::ExaGeoStatFisherTile(configurations::Configurations kernel_name = "UnivariateMaternNuggetsStationary"; } - auto pKernel_cj = plugins::PluginRegistry>::Create(kernel_name); + auto pKernel_cj = plugins::PluginRegistry>::Create(kernel_name, + aConfigurations.GetTimeSlot()); VERBOSE("Generate covariance matrix CHAM_desc_CJ (Fisher Matrix Generation).....") - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_desc_CJ, EXAGEOSTAT_UPPER_LOWER, - aData.GetLocations(), aData.GetLocations(), &median_locations, apTheta, + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_CJ, EXAGEOSTAT_UPPER_LOWER, + aData->GetLocations(), aData->GetLocations(), &median_locations, apTheta, aConfigurations.GetDistanceMetric(), pKernel_cj); ExaGeoStatSequenceWait(sequence); VERBOSE("Done.") @@ -1003,11 +1237,12 @@ T *LinearAlgebraMethods::ExaGeoStatFisherTile(configurations::Configurations kernel_name = "UnivariateMaternNuggetsStationary"; } - auto pKernel_ck = plugins::PluginRegistry>::Create(kernel_name); + auto pKernel_ck = plugins::PluginRegistry>::Create(kernel_name, + aConfigurations.GetTimeSlot()); VERBOSE("Generate covariance matrix CHAM_desc_CK (Fisher Matrix Generation).....") - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_desc_CK, EXAGEOSTAT_UPPER_LOWER, - aData.GetLocations(), aData.GetLocations(), &median_locations, apTheta, + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_CK, EXAGEOSTAT_UPPER_LOWER, + aData->GetLocations(), aData->GetLocations(), &median_locations, apTheta, aConfigurations.GetDistanceMetric(), pKernel_ck); ExaGeoStatSequenceWait(sequence); VERBOSE("Done.") @@ -1072,9 +1307,9 @@ T *LinearAlgebraMethods::ExaGeoStatFisherTile(configurations::Configurations I_matrix[num_params * num_params] = time; results::Results::GetInstance()->SetTotalFisherTime(time); - results::Results::GetInstance()->SetFisher00((double) I_matrix[0]); - results::Results::GetInstance()->SetFisher11((double) I_matrix[4]); - results::Results::GetInstance()->SetFisher22((double) I_matrix[8]); + results::Results::GetInstance()->SetFisher00((T) I_matrix[0]); + results::Results::GetInstance()->SetFisher11((T) I_matrix[4]); + results::Results::GetInstance()->SetFisher22((T) I_matrix[8]); delete[] A; return I_matrix; @@ -1083,11 +1318,11 @@ T *LinearAlgebraMethods::ExaGeoStatFisherTile(configurations::Configurations template void LinearAlgebraMethods::ExaGeoStatGetZObs(Configurations &aConfigurations, T *apZ, const int &aSize, - DescriptorData &aDescData, T *apMeasurementsMatrix) { + DescriptorData &aDescData, T *apMeasurementsMatrix, const int &aP) { auto z_desc = (CHAM_desc_t *) aDescData.GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z_COPY).chameleon_desc; if (!z_desc) { - int n = aConfigurations.GetProblemSize(); + int full_problem_size = aConfigurations.GetProblemSize() * aP; int dts = aConfigurations.GetDenseTileSize(); int p_grid = aConfigurations.GetPGrid(); int q_grid = aConfigurations.GetQGrid(); @@ -1104,7 +1339,7 @@ LinearAlgebraMethods::ExaGeoStatGetZObs(Configurations &aConfigurations, T *a throw runtime_error("Unsupported for now!"); } aDescData.SetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z_COPY, is_OOC, apMeasurementsMatrix, float_point, dts, - dts, dts * dts, n, 1, 0, 0, n, 1, p_grid, q_grid); + dts, dts * dts, full_problem_size, 1, 0, 0, full_problem_size, 1, p_grid, q_grid); z_desc = (CHAM_desc_t *) aDescData.GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z_COPY).chameleon_desc; } this->ExaGeoStatDesc2Lap(apZ, aSize, z_desc, UpperLower::EXAGEOSTAT_UPPER_LOWER); @@ -1365,6 +1600,81 @@ LinearAlgebraMethods::CopyDescriptorZ(DescriptorData &aDescriptorData, voi } +template +int +LinearAlgebraMethods::ExaGeoStatMLEMSPEBivariateTileAsync(void *apDescZPre, void *apDescZMiss, void *apDescsError1, + void *apDescsError2, void *apDescsError, + void *apSequence, void *apRequest) { + // Check for initialize the Chameleon context. + if (!this->mpContext) { + throw std::runtime_error( + "ExaGeoStat hardware is not initialized, please use 'ExaGeoStatHardware(computation, cores_number, gpu_numbers);'."); + } + + RUNTIME_option_t options; + RUNTIME_options_init(&options, (chameleon_context_s *) this->mpContext, + (RUNTIME_sequence_t *) apSequence, + (RUNTIME_request_t *) apRequest); + + int m, m0; + int tempmm; + auto Zpre = (CHAM_desc_t *) apDescZPre; + + struct starpu_codelet *cl = &cl_dmse_bivariate; + + + for (m = 0; m < Zpre->mt; m++) { + tempmm = m == Zpre->mt - 1 ? Zpre->m - m * Zpre->mb : Zpre->mb; + m0 = m * Zpre->mb; + starpu_insert_task(cl, + STARPU_VALUE, &tempmm, sizeof(int), + STARPU_VALUE, &m0, sizeof(int), + STARPU_RW, ExaGeoStatDataGetAddr(apDescsError1, 0, 0), + STARPU_RW, ExaGeoStatDataGetAddr(apDescsError2, 0, 0), + STARPU_RW, ExaGeoStatDataGetAddr(apDescsError, 0, 0), + STARPU_R, ExaGeoStatDataGetAddr(apDescZPre, m, 0), + STARPU_R, ExaGeoStatDataGetAddr(apDescZMiss, m, 0), +#if defined(CHAMELEON_CODELETS_HAVE_NAME) + STARPU_NAME, "dmse_bivariate", +#endif + 0); + } + this->ExaGeoStatOptionsFree(&options); + this->ExaGeoStatOptionsFinalize(&options, (CHAM_context_t *) this->mpContext); + return CHAMELEON_SUCCESS; +} + +#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) { @@ -1375,6 +1685,15 @@ LinearAlgebraMethods::ExaGeoStatDesc2Lap(T *apA, const int &aLDA, void *apDes } +template +void +LinearAlgebraMethods::ExaGeoStatLap2Desc(T *apA, const int &aLDA, void *apDescA, const UpperLower &aUpperLower) { + int status = CHAMELEON_Lap2Desc((cham_uplo_t) aUpperLower, apA, aLDA, (CHAM_desc_t *) apDescA); + if (status != CHAMELEON_SUCCESS) { + throw std::runtime_error("CHAMELEON_Lap2Desc Failed!"); + } +} + template void LinearAlgebraMethods::ExaGeoStatLaSetTile(const common::UpperLower &aUpperLower, T alpha, T beta, void *apDescriptor) { diff --git a/src/linear-algebra-solvers/concrete/CMakeLists.txt b/src/linear-algebra-solvers/concrete/CMakeLists.txt index 0174fa63..d2ef8862 100644 --- a/src/linear-algebra-solvers/concrete/CMakeLists.txt +++ b/src/linear-algebra-solvers/concrete/CMakeLists.txt @@ -4,7 +4,7 @@ # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.0.1 # @brief CMake build script for the linear-algebra-solvers library, which includes the concrete implementations of the # LinearAlgebraMethods class based on the enabled libraries (HiCMA or Chameleon). # @author Mahmoud ElKarargy @@ -13,15 +13,15 @@ # Include the concrete implementations of the LinearAlgebraMethods class based on the enabled libraries (HiCMA or Chameleon) set(SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/chameleon/dense/ChameleonImplementationDense.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/chameleon/diagonal-super-tile/ChameleonImplementationDST.cpp + ${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 (EXAGEOSTAT_USE_HICMA) +if (USE_HICMA) list(APPEND SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/tile-low-rank/HicmaImplementation.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tlr/HicmaImplementation.cpp ) endif () diff --git a/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp b/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp index c2236051..34e7af92 100644 --- a/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp +++ b/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp @@ -59,26 +59,109 @@ int ChameleonImplementation::ExaGeoStatDoubleDotProduct(void *apDescA, void * return CHAMELEON_SUCCESS; } +template +int ChameleonImplementation::ExaGeoStatNonGaussianLogLikeTileAsync(void *apDescZ, void *apDescSum, const T *apTheta, void *apSequence, void *apRequest) { + + // Check for initialize the Chameleon context. + if (!this->mpContext) { + throw std::runtime_error( + "ExaGeoStat hardware is not initialized, please use 'ExaGeoStatHardware(computation, cores_number, gpu_numbers);'."); + } + + RUNTIME_option_t options; + this->ExaGeoStatOptionsInit(&options, this->mpContext, apSequence, apRequest); + + int m, m0; + int temp; + auto Z = (CHAM_desc_t *) apDescZ; + auto A = (CHAM_desc_t *) apDescSum; + struct starpu_codelet *cl = &this->cl_non_gaussian_loglike; + + + for (m = 0; m < Z->mt; m++) { + temp = m == Z->mt - 1 ? Z->m - m * Z->mb : Z->mb; + m0 = m * Z->mb; + + starpu_insert_task(cl, + STARPU_VALUE, &temp, sizeof(int), + STARPU_VALUE, &m0, sizeof(int), + STARPU_R, ExaGeoStatDataGetAddr(Z, m, 0), + STARPU_RW, ExaGeoStatDataGetAddr(A, 0, 0), + STARPU_VALUE, &apTheta[0], sizeof(double), + STARPU_VALUE, &apTheta[1], sizeof(double), + STARPU_VALUE, &apTheta[2], sizeof(double), + STARPU_VALUE, &apTheta[3], sizeof(double), + STARPU_VALUE, &apTheta[4], sizeof(double), + STARPU_VALUE, &apTheta[5], sizeof(double), + 0); + } + + this->ExaGeoStatOptionsFree(&options); + this->ExaGeoStatOptionsFinalize(&options, (CHAM_context_t *) this->mpContext); + return CHAMELEON_SUCCESS; +} + +template +int +ChameleonImplementation::ExaGeoStatNonGaussianTransformTileAsync(void *apDescZ, void *apDescFlag, const T *apTheta, void *apSequence, + void *apRequest) { + // Check for initialize the Chameleon context. + if (!this->mpContext) { + throw std::runtime_error( + "ExaGeoStat hardware is not initialized, please use 'ExaGeoStatHardware(computation, cores_number, gpu_numbers);'."); + } + + RUNTIME_option_t options; + this->ExaGeoStatOptionsInit(&options, this->mpContext, apSequence, apRequest); + + int m, m0; + int tempmm; + auto Z = (CHAM_desc_t *) apDescZ; + struct starpu_codelet *cl = &this->cl_non_gaussian_transform; + + + for (m = 0; m < Z->mt; m++) { + tempmm = m == Z->mt - 1 ? Z->m - m * Z->mb : Z->mb; + m0 = m * Z->mb; + + starpu_insert_task(cl, + STARPU_VALUE, &tempmm, sizeof(int), + STARPU_VALUE, &m0, sizeof(int), + STARPU_RW, ExaGeoStatDataGetAddr(apDescZ, m, 0), + STARPU_W, ExaGeoStatDataGetAddr(apDescFlag, 0, 0), + STARPU_VALUE, &apTheta[0], sizeof(double), + STARPU_VALUE, &apTheta[1], sizeof(double), + STARPU_VALUE, &apTheta[2], sizeof(double), + STARPU_VALUE, &apTheta[3], sizeof(double), + STARPU_VALUE, &apTheta[4], sizeof(double), + STARPU_VALUE, &apTheta[5], sizeof(double), + 0); + } + + this->ExaGeoStatOptionsFree(&options); + this->ExaGeoStatOptionsFinalize(&options, (CHAM_context_t *) this->mpContext); + return CHAMELEON_SUCCESS; +} template -T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardware &aHardware, ExaGeoStatData &aData, +T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardware &aHardware, std::unique_ptr> &aData, Configurations &aConfigurations, const double *theta, T *apMeasurementsMatrix, const kernels::Kernel &aKernel) { this->SetContext(aHardware.GetContext(aConfigurations.GetComputation())); - if (!aData.GetDescriptorData()->GetIsDescriptorInitiated()) { - this->InitiateDescriptors(aConfigurations, *aData.GetDescriptorData(), apMeasurementsMatrix); + if (!aData->GetDescriptorData()->GetIsDescriptorInitiated()) { + this->InitiateDescriptors(aConfigurations, *aData->GetDescriptorData(), aKernel.GetVariablesNumber(), apMeasurementsMatrix); } // Create a Chameleon sequence, if not initialized before through the same descriptors RUNTIME_request_t request_array[2] = {RUNTIME_REQUEST_INITIALIZER, RUNTIME_REQUEST_INITIALIZER}; - if (!aData.GetDescriptorData()->GetSequence()) { + if (!aData->GetDescriptorData()->GetSequence()) { RUNTIME_sequence_t *sequence; this->ExaGeoStatCreateSequence(&sequence); - aData.GetDescriptorData()->SetSequence(sequence); - aData.GetDescriptorData()->SetRequest(request_array); + aData->GetDescriptorData()->SetSequence(sequence); + aData->GetDescriptorData()->SetRequest(request_array); } - auto pSequence = (RUNTIME_sequence_t *) aData.GetDescriptorData()->GetSequence(); + auto pSequence = (RUNTIME_sequence_t *) aData->GetDescriptorData()->GetSequence(); //Initialization T loglik = 0.0, logdet, variance, variance1 = 1, variance2 = 1, variance3, dot_product = 0, dot_product1 = 0, dot_product2 = 0, dot_product3, n, dzcpy_time, time_facto, time_solve, logdet_calculate, matrix_gen_time; double accumulated_executed_time, accumulated_flops; @@ -89,47 +172,54 @@ T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardwa auto kernel_name = aConfigurations.GetKernelName(); int num_params = aKernel.GetParametersNumbers(); - auto median_locations = Locations(1, aData.GetLocations()->GetDimension()); - aData.CalculateMedianLocations(kernel_name, median_locations); + auto median_locations = Locations(1, aData->GetLocations()->GetDimension()); + aData->CalculateMedianLocations(kernel_name, median_locations); - auto *CHAM_desc_C = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + auto *CHAM_desc_C = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, DescriptorName::DESCRIPTOR_C).chameleon_desc; - auto *CHAM_desc_sub_C11 = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + auto *CHAM_desc_sub_C11 = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, DescriptorName::DESCRIPTOR_C11).chameleon_desc; - auto *CHAM_desc_sub_C12 = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + auto *CHAM_desc_sub_C12 = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, DescriptorName::DESCRIPTOR_C12).chameleon_desc; - auto *CHAM_desc_sub_C22 = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + auto *CHAM_desc_sub_C22 = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, DescriptorName::DESCRIPTOR_C22).chameleon_desc; - auto *CHAM_desc_Z = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + auto *CHAM_desc_Z = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, DescriptorName::DESCRIPTOR_Z).chameleon_desc; - auto *CHAM_desc_Z1 = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + auto *CHAM_desc_Z1 = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, DescriptorName::DESCRIPTOR_Z_1).chameleon_desc; - auto *CHAM_desc_Z2 = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + auto *CHAM_desc_Z2 = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, DescriptorName::DESCRIPTOR_Z_2).chameleon_desc; - auto *CHAM_desc_Z3 = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + auto *CHAM_desc_Z3 = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, DescriptorName::DESCRIPTOR_Z_3).chameleon_desc; - auto *CHAM_desc_Zcpy = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + auto *CHAM_desc_Zcpy = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, DescriptorName::DESCRIPTOR_Z_COPY).chameleon_desc; - auto *CHAM_desc_det = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + auto *CHAM_desc_det = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, DescriptorName::DESCRIPTOR_DETERMINANT).chameleon_desc; - auto *CHAM_desc_product = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_PRODUCT).chameleon_desc; - auto *CHAM_desc_product1 = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + auto *CHAM_desc_product = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_PRODUCT).chameleon_desc; + auto *CHAM_desc_sum = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_SUM).chameleon_desc; + auto *CHAM_desc_product1 = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, DescriptorName::DESCRIPTOR_PRODUCT_1).chameleon_desc; - auto *CHAM_desc_product2 = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + auto *CHAM_desc_product2 = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, DescriptorName::DESCRIPTOR_PRODUCT_2).chameleon_desc; - auto *CHAM_desc_product3 = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + auto *CHAM_desc_product3 = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, DescriptorName::DESCRIPTOR_PRODUCT_3).chameleon_desc; - T *determinant = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_det); + T *determinant = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_det); *determinant = 0; - T *product = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_product); + T *product = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_product); *product = 0; + T *sum ; + if(aConfigurations.GetIsNonGaussian()) { + sum = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_sum); + *sum = 0; + } n = CHAM_desc_C->m; nhrs = CHAM_desc_Z->n; string recovery_file = aConfigurations.GetRecoveryFile(); - int iter_count = aData.GetMleIterations(); + int iter_count = aData->GetMleIterations(); if (recovery_file.empty() || !(this->recover((char *) (recovery_file.c_str()), iter_count, (T *) theta, &loglik, num_params))) { @@ -162,8 +252,8 @@ T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardwa int distance_metric = aConfigurations.GetDistanceMetric(); - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_desc_sub_C11, upper_lower, aData.GetLocations(), - aData.GetLocations(), &median_locations, univariate_theta, distance_metric, + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_sub_C11, upper_lower, aData->GetLocations(), + aData->GetLocations(), &median_locations, univariate_theta, distance_metric, &aKernel); nu12 = 0.5 * (theta[3] + theta[4]); @@ -174,8 +264,8 @@ T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardwa univariate2_theta[1] = theta[2]; univariate2_theta[2] = nu12; - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_desc_sub_C12, upper_lower, &median_locations, - aData.GetLocations(), &median_locations, univariate2_theta, 0, &aKernel); + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_sub_C12, upper_lower, &median_locations, + aData->GetLocations(), &median_locations, univariate2_theta, 0, &aKernel); STOP_TIMING(matrix_gen_time); VERBOSE("Done.") @@ -183,12 +273,12 @@ T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardwa univariate3_theta[1] = theta[2]; univariate3_theta[2] = theta[4]; - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_desc_sub_C22, upper_lower, &median_locations, - aData.GetLocations(), &median_locations, univariate2_theta, 0, &aKernel); + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_sub_C22, upper_lower, &median_locations, + aData->GetLocations(), &median_locations, univariate2_theta, 0, &aKernel); } else { int upper_lower = EXAGEOSTAT_LOWER; - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_desc_C, upper_lower, aData.GetLocations(), - aData.GetLocations(), &median_locations, (T *) theta, 0, &aKernel); + this->CovarianceMatrixCodelet(*aData->GetDescriptorData(), CHAM_desc_C, upper_lower, aData->GetLocations(), + aData->GetLocations(), &median_locations, (T *) theta, 0, &aKernel); } this->ExaGeoStatSequenceWait(pSequence); STOP_TIMING(matrix_gen_time); @@ -211,6 +301,20 @@ T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardwa STOP_TIMING(logdet_calculate); VERBOSE("Done.") + if(aConfigurations.GetIsNonGaussian()){ + VERBOSE("Transform Z vector to Gaussian field ...") + this->ExaGeoStatNonGaussianTransformTileAsync(CHAM_desc_Z, CHAM_desc_product, (T *) theta, pSequence, &request_array[0]); + this->ExaGeoStatSequenceWait(pSequence); + VERBOSE(" Done.") + + CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_desc_Z, CHAM_desc_Z, 0, CHAM_desc_product); + + VERBOSE("Calculate non-Gaussian loglik ...") + this->ExaGeoStatNonGaussianLogLikeTileAsync(CHAM_desc_Z, CHAM_desc_sum, (T *) theta, pSequence, &request_array[0]); + this->ExaGeoStatSequenceWait(pSequence); + VERBOSE(" Done.\n") + } + // Solving Linear System (L*X=Z)--->inv(L)*Z VERBOSE("Solving the linear system ...") START_TIMING(time_solve); @@ -224,6 +328,7 @@ T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardwa VERBOSE("Calculating the MLE likelihood function ...") ExaGeoStatDoubleDotProduct(CHAM_desc_Z, CHAM_desc_product, pSequence, request_array); ExaGeoStatSequenceWait(pSequence); + if (kernel_name == "BivariateMaternParsimonious2Profile") { loglik = -(n / 2) + (n / 2) * log(n) - (n / 2) * log(dot_product) - 0.5 * logdet - (T) (n / 2.0) * log(2.0 * PI); @@ -254,7 +359,12 @@ T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardwa variance2 = (1.0 / (n / 3.0)) * dot_product2; } else { dot_product = *product; - loglik = -0.5 * dot_product - 0.5 * logdet - (double) (n / 2.0) * log(2.0 * PI); + loglik = -0.5 * dot_product - 0.5 * logdet; + if(aConfigurations.GetIsNonGaussian()){ + loglik = loglik - *sum - n * log(theta[3]) - (double) (n / 2.0) * log(2.0 * PI); + } else { + loglik = loglik - (double) (n / 2.0) * log(2.0 * PI); + } } VERBOSE("Done.") @@ -301,7 +411,7 @@ T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardwa LOGGER(" ---- Total Time: " << time_facto + logdet_calculate + time_solve) LOGGER(" ---- Gflop/s: " << flops / 1e9 / (time_facto + time_solve)) - aData.SetMleIterations(aData.GetMleIterations() + 1); + aData->SetMleIterations(aData->GetMleIterations() + 1); // for experiments and benchmarking accumulated_executed_time = @@ -316,19 +426,9 @@ T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardwa results::Results::GetInstance()->SetMaximumTheta(vector(theta, theta + num_params)); results::Results::GetInstance()->SetLogLikValue(loglik); - aConfigurations.SetEstimatedTheta(aConfigurations.GetStartingTheta()); return loglik; } -template -void -ChameleonImplementation::ExaGeoStatLap2Desc(T *apA, const int &aLDA, void *apDescA, const UpperLower &aUpperLower) { - int status = CHAMELEON_Lap2Desc((cham_uplo_t) aUpperLower, apA, aLDA, (CHAM_desc_t *) apDescA); - if (status != CHAMELEON_SUCCESS) { - throw std::runtime_error("CHAMELEON_Lap2Desc Failed!"); - } -} - template void ChameleonImplementation::ExaGeoStatLapackCopyTile(const common::UpperLower &aUpperLower, void *apA, void *apB) { int status = CHAMELEON_dlacpy_Tile((cham_uplo_t) aUpperLower, (CHAM_desc_t *) apA, (CHAM_desc_t *) apB); diff --git a/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonImplementationDense.cpp b/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp similarity index 74% rename from src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonImplementationDense.cpp rename to src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp index c81d2d98..17009ca8 100644 --- a/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonImplementationDense.cpp +++ b/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp @@ -6,13 +6,13 @@ /** * @file ChameleonImplementationDense.cpp * @brief Dense Tile implementation of linear algebra methods. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-03-20 **/ -#include +#include using namespace std; @@ -20,8 +20,8 @@ using namespace exageostat::linearAlgebra::dense; template void -ChameleonImplementationDense::ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, - void *apCD, void *apCrk, const int &aMaxRank, const int &aAcc) { +ChameleonDense::ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, + void *apCD, void *apCrk, const int &aMaxRank, const int &aAcc) { int status = CHAMELEON_dpotrf_Tile((cham_uplo_t) aUpperLower, (CHAM_desc_t *) apA); if (status != CHAMELEON_SUCCESS) { throw std::runtime_error("CHAMELEON_dpotrf_Tile Failed, Matrix is not positive definite"); diff --git a/src/linear-algebra-solvers/concrete/chameleon/diagonal-super-tile/ChameleonImplementationDST.cpp b/src/linear-algebra-solvers/concrete/chameleon/dst/ChameleonDST.cpp similarity index 90% rename from src/linear-algebra-solvers/concrete/chameleon/diagonal-super-tile/ChameleonImplementationDST.cpp rename to src/linear-algebra-solvers/concrete/chameleon/dst/ChameleonDST.cpp index 649520e8..b243f58e 100644 --- a/src/linear-algebra-solvers/concrete/chameleon/diagonal-super-tile/ChameleonImplementationDST.cpp +++ b/src/linear-algebra-solvers/concrete/chameleon/dst/ChameleonDST.cpp @@ -6,13 +6,13 @@ /** * @file ChameleonImplementationDST.cpp * @brief Diagonal Super Tile implementation of linear algebra methods. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-03-20 **/ -#include +#include using namespace std; @@ -20,8 +20,8 @@ using namespace exageostat::linearAlgebra::diagonalSuperTile; using namespace exageostat::common; template -void ChameleonImplementationDST::ExaGeoStatPotrfTile(const UpperLower &aUpperLower, void *apA, int aBand, void *apCD, - void *apCrk, const int &aMaxRank, const int &aAcc) { +void ChameleonDST::ExaGeoStatPotrfTile(const UpperLower &aUpperLower, void *apA, int aBand, void *apCD, + void *apCrk, const int &aMaxRank, const int &aAcc) { CHAM_context_t *chameleon_context; RUNTIME_sequence_t *sequence = nullptr; @@ -39,8 +39,8 @@ void ChameleonImplementationDST::ExaGeoStatPotrfTile(const UpperLower &aUpper } template -int ChameleonImplementationDST::ExaGeoStatPotrfDiagonalTileAsync(const common::UpperLower &aUpperLower, void *apA, - int aBand, void *apSequence, void *apRequest) { +int ChameleonDST::ExaGeoStatPotrfDiagonalTileAsync(const common::UpperLower &aUpperLower, void *apA, + int aBand, void *apSequence, void *apRequest) { CHAM_context_t *chameleon_context; chameleon_context = chameleon_context_self(); @@ -87,8 +87,8 @@ int ChameleonImplementationDST::ExaGeoStatPotrfDiagonalTileAsync(const common template -void ChameleonImplementationDST::ExaGeoStatParallelPotrfDiagonal(const common::UpperLower &aUpperLower, void *apA, - int aBand, void *apSequence, void *apRequest) { +void ChameleonDST::ExaGeoStatParallelPotrfDiagonal(const common::UpperLower &aUpperLower, void *apA, + int aBand, void *apSequence, void *apRequest) { CHAM_context_t *chameleon_context; RUNTIME_option_t options; diff --git a/src/linear-algebra-solvers/concrete/tile-low-rank/HicmaImplementation.cpp b/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp similarity index 55% rename from src/linear-algebra-solvers/concrete/tile-low-rank/HicmaImplementation.cpp rename to src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp index c8a2b852..370d4402 100644 --- a/src/linear-algebra-solvers/concrete/tile-low-rank/HicmaImplementation.cpp +++ b/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp @@ -6,13 +6,13 @@ /** * @file HicmaImplementation.cpp * @brief Sets up the HiCMA descriptors needed for the tile low rank computations in ExaGeoStat. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-03-26 **/ -#include +#include using namespace std; @@ -24,15 +24,15 @@ using namespace exageostat::helpers; using namespace exageostat::hardware; using namespace exageostat::configurations; -//// TODO: These variables are required to avoid undefined reference to HiCMA global variables. 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(ExaGeoStatData &aData, Configurations &aConfigurations) { +void HicmaImplementation::SetModelingDescriptors(std::unique_ptr> &aData, + Configurations &aConfigurations, const int &aP) { - int N = aConfigurations.GetProblemSize(); + int full_problem_size = aConfigurations.GetProblemSize() * aP; int lts = aConfigurations.GetLowTileSize(); int p_grid = aConfigurations.GetPGrid(); int q_grid = aConfigurations.GetQGrid(); @@ -51,55 +51,69 @@ void HicmaImplementation::SetModelingDescriptors(ExaGeoStatData &aData, Co int MBD = lts; int NBD = lts; - int MD = N; + int MD = full_problem_size; int ND = MBD; - aData.GetDescriptorData()->SetDescriptor(common::HICMA_DESCRIPTOR, DESCRIPTOR_CD, is_OOC, nullptr, float_point, MBD, - NBD, MBD * NBD, MD, ND, 0, 0, MD, ND, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::HICMA_DESCRIPTOR, DESCRIPTOR_CD, is_OOC, nullptr, float_point, + MBD, + NBD, MBD * NBD, MD, ND, 0, 0, MD, ND, p_grid, q_grid); int MBUV = lts; int NBUV = 2 * max_rank; int MUV; - int N_over_lts_times_lts = N / lts * lts; - if (N_over_lts_times_lts < N) { + int N_over_lts_times_lts = full_problem_size / lts * lts; + if (N_over_lts_times_lts < full_problem_size) { MUV = N_over_lts_times_lts + lts; - } else if (N_over_lts_times_lts == N) { + } else if (N_over_lts_times_lts == full_problem_size) { MUV = N_over_lts_times_lts; } else { throw runtime_error("This case can't happens, N need to be >= lts*lts"); } int expr = MUV / lts; int NUV = 2 * expr * max_rank; - aData.GetDescriptorData()->SetDescriptor(common::HICMA_DESCRIPTOR, DESCRIPTOR_CUV, is_OOC, nullptr, float_point, - MBUV, NBUV, MBUV * NBUV, MUV, NUV, 0, 0, MUV, NUV, p_grid, q_grid); - auto *HICMA_descCUV = aData.GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, - DescriptorName::DESCRIPTOR_CUV).hicma_desc; + aData->GetDescriptorData()->SetDescriptor(common::HICMA_DESCRIPTOR, DESCRIPTOR_CUV, is_OOC, nullptr, float_point, + MBUV, NBUV, MBUV * NBUV, MUV, NUV, 0, 0, MUV, NUV, p_grid, q_grid); + auto *HICMA_descCUV = aData->GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, + DescriptorName::DESCRIPTOR_CUV).hicma_desc; int MBrk = 1; int NBrk = 1; int Mrk = HICMA_descCUV->mt; int Nrk = HICMA_descCUV->mt; - aData.GetDescriptorData()->SetDescriptor(common::HICMA_DESCRIPTOR, DESCRIPTOR_CRK, is_OOC, nullptr, float_point, - MBrk, NBrk, MBrk * NBrk, Mrk, Nrk, 0, 0, Mrk, Nrk, p_grid, q_grid); - aData.GetDescriptorData()->SetDescriptor(common::HICMA_DESCRIPTOR, DESCRIPTOR_Z_COPY, is_OOC, nullptr, float_point, - lts, lts, lts * lts, N, 1, 0, 0, N, 1, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::HICMA_DESCRIPTOR, DESCRIPTOR_CRK, is_OOC, nullptr, float_point, + MBrk, NBrk, MBrk * NBrk, Mrk, Nrk, 0, 0, Mrk, Nrk, p_grid, q_grid); + + aData->GetDescriptorData()->SetDescriptor(common::HICMA_DESCRIPTOR, DESCRIPTOR_Z, is_OOC, nullptr, float_point, + lts, lts, lts * lts, full_problem_size, 1, 0, 0, full_problem_size, 1, p_grid, q_grid); + + aData->GetDescriptorData()->SetDescriptor(common::HICMA_DESCRIPTOR, DESCRIPTOR_Z_COPY, is_OOC, nullptr, float_point, + lts, lts, lts * lts, full_problem_size, 1, 0, 0, full_problem_size, 1, p_grid, q_grid); + if (aConfigurations.GetIsNonGaussian()) { + aData->GetDescriptorData()->SetDescriptor(common::HICMA_DESCRIPTOR, DESCRIPTOR_PRODUCT, is_OOC, nullptr, + float_point, + lts, lts, lts * lts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); + aData->GetDescriptorData()->SetDescriptor(common::HICMA_DESCRIPTOR, DESCRIPTOR_SUM, is_OOC, nullptr, + float_point, + lts, lts, lts * lts, 1, 1, 0, 0, 1, 1, p_grid, q_grid); + } } template -T HicmaImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardware &aHardware, ExaGeoStatData &aData, +T HicmaImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardware &aHardware, + std::unique_ptr> &aData, Configurations &aConfigurations, const double *theta, T *apMeasurementsMatrix, const Kernel &aKernel) { this->SetContext(aHardware.GetContext(aConfigurations.GetComputation())); - if (!aData.GetDescriptorData()->GetIsDescriptorInitiated()) { - this->InitiateDescriptors(aConfigurations, *aData.GetDescriptorData(), apMeasurementsMatrix); + if (!aData->GetDescriptorData()->GetIsDescriptorInitiated()) { + this->InitiateDescriptors(aConfigurations, *aData->GetDescriptorData(),aKernel.GetVariablesNumber(), apMeasurementsMatrix); } // Create a Hicma sequence, if not initialized before through the same descriptors RUNTIME_request_t request_array[2] = {HICMA_REQUEST_INITIALIZER, HICMA_REQUEST_INITIALIZER}; - if (!aData.GetDescriptorData()->GetSequence()) { + if (!aData->GetDescriptorData()->GetSequence()) { HICMA_sequence_t *sequence; this->ExaGeoStatCreateSequence(&sequence); - aData.GetDescriptorData()->SetSequence(sequence); - aData.GetDescriptorData()->SetRequest(request_array); + aData->GetDescriptorData()->SetSequence(sequence); + aData->GetDescriptorData()->SetRequest(request_array); } - auto pSequence = (HICMA_sequence_t *) aData.GetDescriptorData()->GetSequence(); + auto pSequence = (HICMA_sequence_t *) aData->GetDescriptorData()->GetSequence(); //Initialization T loglik, logdet, test_time, variance, variance1 = 1, variance2 = 1, variance3, dot_product, dot_product1, dot_product2, dot_product3, dzcpy_time, time_facto, time_solve, logdet_calculate, matrix_gen_time; @@ -111,52 +125,54 @@ T HicmaImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardware & int N; int lts; int max_rank = aConfigurations.GetMaxRank(); - int iter_count = aData.GetMleIterations(); + int iter_count = aData->GetMleIterations(); auto kernel_name = aConfigurations.GetKernelName(); int num_params = aKernel.GetParametersNumbers(); int acc = aConfigurations.GetAccuracy(); if (iter_count == 0) { - this->SetModelingDescriptors(aData, aConfigurations); + this->SetModelingDescriptors(aData, aConfigurations, aKernel.GetVariablesNumber()); } - auto *HICMA_descCUV = aData.GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, - DescriptorName::DESCRIPTOR_CUV).hicma_desc; - auto *HICMA_descC = aData.GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, - DescriptorName::DESCRIPTOR_C).hicma_desc; - auto *HICMA_descCD = aData.GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, - DescriptorName::DESCRIPTOR_CD).hicma_desc; - auto *HICMA_descCrk = aData.GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, - DescriptorName::DESCRIPTOR_CRK).hicma_desc; - auto *HICMA_descZ = aData.GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, - DescriptorName::DESCRIPTOR_Z).hicma_desc; - auto *CHAM_descZ = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_Z).chameleon_desc; - auto *CHAM_descZcpy = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_Z_COPY).chameleon_desc; - auto *HICMA_descZcpy = aData.GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, - DescriptorName::DESCRIPTOR_Z_COPY).hicma_desc; - auto *HICMA_desc_det = aData.GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, - DescriptorName::DESCRIPTOR_DETERMINANT).hicma_desc; - auto *CHAM_desc_product = aData.GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, - DescriptorName::DESCRIPTOR_PRODUCT).chameleon_desc; - + auto *HICMA_descCUV = aData->GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, + DescriptorName::DESCRIPTOR_CUV).hicma_desc; + auto *HICMA_descC = aData->GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, + DescriptorName::DESCRIPTOR_C).hicma_desc; + auto *HICMA_descCD = aData->GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, + DescriptorName::DESCRIPTOR_CD).hicma_desc; + auto *HICMA_descCrk = aData->GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, + DescriptorName::DESCRIPTOR_CRK).hicma_desc; + auto *HICMA_descZ = aData->GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, + DescriptorName::DESCRIPTOR_Z).hicma_desc; + auto *CHAM_descZ = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_Z).chameleon_desc; + auto *CHAM_descZcpy = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_Z_COPY).chameleon_desc; + auto *HICMA_descZcpy = aData->GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, + DescriptorName::DESCRIPTOR_Z_COPY).hicma_desc; + auto *HICMA_desc_det = aData->GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, + DescriptorName::DESCRIPTOR_DETERMINANT).hicma_desc; + auto *CHAM_desc_product = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_PRODUCT).chameleon_desc; + auto *HICMA_desc_product = aData->GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, + DescriptorName::DESCRIPTOR_PRODUCT).chameleon_desc; + auto *HICMA_desc_sum = aData->GetDescriptorData()->GetDescriptor(DescriptorType::HICMA_DESCRIPTOR, + DescriptorName::DESCRIPTOR_SUM).chameleon_desc; N = HICMA_descCUV->m; NRHS = HICMA_descZ->n; lts = HICMA_descZ->mb; - T *determinant = aData.GetDescriptorData()->GetDescriptorMatrix(HICMA_DESCRIPTOR, HICMA_desc_det); + T *determinant = aData->GetDescriptorData()->GetDescriptorMatrix(HICMA_DESCRIPTOR, HICMA_desc_det); *determinant = 0; - T *product = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_product); + T *product = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_product); *product = 0; + T *sum; string recovery_file = aConfigurations.GetRecoveryFile(); if (recovery_file.empty() || !(this->recover((char *) (recovery_file.c_str()), iter_count, (T *) theta, &loglik, num_params))) { if (iter_count == 0) { - auto *z = new T[N]; - this->ExaGeoStatDesc2Lap(z, N, CHAM_descZ, EXAGEOSTAT_UPPER_LOWER); - this->ExaGeoStatLap2Desc(z, N, HICMA_descZ, EXAGEOSTAT_UPPER_LOWER); - delete[] z; + // Copy dense matrix Z into tile low rank Z. + this->CopyDescriptors(CHAM_descZ, HICMA_descZ, N, CHAMELEON_TO_HICMA); // Save a copy of descZ into descZcpy for restoring each iteration this->ExaGeoStatLapackCopyTile(EXAGEOSTAT_UPPER_LOWER, HICMA_descZ, HICMA_descZcpy); // Save another copy into descZcpy for chameleon, This is in case of other operations after Modeling. ex: Prediction. @@ -175,7 +191,14 @@ T HicmaImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardware & hicma_problem.kernel_type = aConfigurations.GetDistanceMetric() == common::GREAT_CIRCLE_DISTANCE ? STARSH_SPATIAL_MATERN2_GCD : STARSH_SPATIAL_MATERN2_SIMD; - HICMA_zgenerate_problem(HICMA_STARSH_PROB_GEOSTAT, 'S', 0, N, lts, HICMA_descCUV->mt, HICMA_descCUV->nt, + int hicma_data_type; + if (aConfigurations.GetIsNonGaussian()) { + hicma_data_type = HICMA_STARSH_PROB_GEOSTAT_NON_GAUSSIAN; + } else { + hicma_data_type = HICMA_STARSH_PROB_GEOSTAT; + } + + HICMA_zgenerate_problem(hicma_data_type, 'S', 0, N, lts, HICMA_descCUV->mt, HICMA_descCUV->nt, &hicma_problem); int compress_diag = 0; HICMA_zgytlr_Tile(EXAGEOSTAT_LOWER, HICMA_descCUV, HICMA_descCD, HICMA_descCrk, 0, max_rank, pow(10, -1.0 * acc), @@ -194,7 +217,8 @@ T HicmaImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardware & //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, acc); + this->ExaGeoStatPotrfTile(EXAGEOSTAT_LOWER, HICMA_descCUV, 0, HICMA_descCD, HICMA_descCrk, max_rank, + pow(10, -1.0 * acc)); STOP_TIMING(time_facto); flops = flops + flops_dpotrf(N); @@ -210,6 +234,32 @@ T HicmaImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardware & STOP_TIMING(logdet_calculate); VERBOSE("Done.") + if (aConfigurations.GetIsNonGaussian()) { + VERBOSE("Transform Z vector to Gaussian field ...") + this->ExaGeoStatNonGaussianTransformTileAsync(HICMA_descZ, HICMA_desc_product, (T *) theta, pSequence, + &request_array[0]); + ExaGeoStatSequenceWait(pSequence); + + VERBOSE(" Done.") + sum = aData->GetDescriptorData()->GetDescriptorMatrix(HICMA_DESCRIPTOR, HICMA_desc_sum); + *sum = 0; + + VERBOSE("LR:Calculating dot product...") + CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_descZ, CHAM_descZ, 0, CHAM_desc_product); + VERBOSE(" Done.") + + double global_sum; +#if defined(CHAMELEON_USE_MPI) + MPI_Allreduce(&local_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); +#else + global_sum = *product; +#endif + this->ExaGeoStatNonGaussianLogLikeTileAsync(HICMA_descZ, HICMA_desc_sum, (T *) theta, pSequence, + &request_array[0]); + ExaGeoStatSequenceWait(pSequence); + VERBOSE(" Done.") + } + //Solving Linear System (L*X=Z)--->inv(L)*Z VERBOSE("LR:Solving the linear system ...") START_TIMING(time_solve); @@ -220,10 +270,18 @@ T HicmaImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardware & flops = flops + flops_dtrsm(ChamLeft, N, NRHS); VERBOSE("Done.") + VERBOSE("Copy to chameleon") + this->CopyDescriptors(HICMA_descZ, CHAM_descZ, N, HICMA_TO_CHAMELEON); + VERBOSE("LR:Calculating dot product...") CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_descZ, CHAM_descZ, 0, CHAM_desc_product); dot_product = *product; - loglik = -0.5 * dot_product - 0.5 * logdet - (double) (N / 2.0) * log(2.0 * PI); + loglik = -0.5 * dot_product - 0.5 * logdet; + if (aConfigurations.GetIsNonGaussian()) { + loglik = loglik - *sum - N * log(theta[3]) - (double) (N / 2.0) * log(2.0 * PI); + } else { + loglik = loglik - (double) (N / 2.0) * log(2.0 * PI); + } VERBOSE("Done.") LOGGER(iter_count + 1 << " - Model Parameters (", true) @@ -263,7 +321,7 @@ T HicmaImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardware & LOGGER(" ---- Total Time: " << time_facto + logdet_calculate + time_solve) LOGGER(" ---- Gflop/s: " << flops / 1e9 / (time_facto + time_solve)) - aData.SetMleIterations(aData.GetMleIterations() + 1); + aData->SetMleIterations(aData->GetMleIterations() + 1); // for experiments and benchmarking accumulated_executed_time = @@ -379,17 +437,98 @@ int HicmaImplementation::ExaGeoStatMeasureDetTileAsync(void *apDescA, void *a return HICMA_SUCCESS; } +template +void *HicmaImplementation::ExaGeoStatDataGetAddr(void *apA, int aAm, int aAn) { + return HICMA_RUNTIME_data_getaddr((HICMA_desc_t *) apA, aAm, aAn); + +} template -void HicmaImplementation::ExaGeoStatLap2Desc(T *apA, const int &aLDA, void *apDescA, const UpperLower &aUpperLower) { - int status = HICMA_Lapack_to_Tile(apA, aLDA, (HICMA_desc_t *) apDescA); - if (status != HICMA_SUCCESS) { - throw std::runtime_error("HICMA_Lapack_to_Tile Failed!"); +int +HicmaImplementation::ExaGeoStatNonGaussianLogLikeTileAsync(void *apDescZ, void *apDescSum, const T *apTheta, + void *apSequence, + void *apRequest) { + // Check for initialize the Hicma context. + if (!this->mpContext) { + throw std::runtime_error( + "ExaGeoStat hardware is not initialized, please use 'ExaGeoStatHardware(computation, cores_number, gpu_numbers);'."); + } + HICMA_option_t options; + this->ExaGeoStatOptionsInit(&options, this->mpContext, apSequence, apRequest); + + int m, m0; + int tempmm; + auto Z = (HICMA_desc_t *) apDescZ; + + struct starpu_codelet *cl = &this->cl_non_gaussian_loglike_lr; + + + for (m = 0; m < Z->mt; m++) { + tempmm = m == Z->mt - 1 ? Z->m - m * Z->mb : Z->mb; + + m0 = m * Z->mb; + + starpu_insert_task(cl, + STARPU_VALUE, &tempmm, sizeof(int), + STARPU_VALUE, &m0, sizeof(int), + STARPU_R, ExaGeoStatDataGetAddr(apDescZ, m, 0), + STARPU_RW, ExaGeoStatDataGetAddr(apDescSum, 0, 0), + STARPU_VALUE, &apTheta[0], sizeof(double), + STARPU_VALUE, &apTheta[1], sizeof(double), + STARPU_VALUE, &apTheta[2], sizeof(double), + STARPU_VALUE, &apTheta[3], sizeof(double), + STARPU_VALUE, &apTheta[4], sizeof(double), + STARPU_VALUE, &apTheta[5], sizeof(double), +#if defined(CHAMELEON_CODELETS_HAVE_NAME) + STARPU_NAME, "non_gaussian_loglike_lr", +#endif + 0); } + + this->ExaGeoStatOptionsFree(&options); + this->ExaGeoStatOptionsFinalize(&options, (HICMA_context_t *) + this->mpContext); + return HICMA_SUCCESS; } + template -void *HicmaImplementation::ExaGeoStatDataGetAddr(void *apA, int aAm, int aAn) { - return HICMA_RUNTIME_data_getaddr((HICMA_desc_t *) apA, aAm, aAn); +int HicmaImplementation::ExaGeoStatNonGaussianTransformTileAsync(void *apDescZ, void *apDescFlag, const T *apTheta, + void *apSequence, void *apRequest) { + // Check for initialize the Hicma context. + if (!this->mpContext) { + throw std::runtime_error( + "ExaGeoStat hardware is not initialized, please use 'ExaGeoStatHardware(computation, cores_number, gpu_numbers);'."); + } + HICMA_option_t options; + this->ExaGeoStatOptionsInit(&options, this->mpContext, apSequence, apRequest); + + int m, m0; + int tempmm; + auto Z = (HICMA_desc_t *) apDescZ; + struct starpu_codelet *cl = &this->cl_non_gaussian_transform_lr; -} \ No newline at end of file + + for (m = 0; m < Z->mt; m++) { + tempmm = m == Z->mt - 1 ? Z->m - m * Z->mb : Z->mb; + m0 = m * Z->mb; + starpu_insert_task(cl, + STARPU_VALUE, &tempmm, sizeof(int), + STARPU_VALUE, &m0, sizeof(int), + STARPU_RW, ExaGeoStatDataGetAddr(apDescZ, m, 0), + STARPU_VALUE, &apTheta[0], sizeof(double), + STARPU_VALUE, &apTheta[1], sizeof(double), + STARPU_VALUE, &apTheta[2], sizeof(double), + STARPU_VALUE, &apTheta[3], sizeof(double), + STARPU_VALUE, &apTheta[4], sizeof(double), + STARPU_VALUE, &apTheta[5], sizeof(double), +#if defined(CHAMELEON_CODELETS_HAVE_NAME) + STARPU_NAME, "non_gaussian_transform_lr", +#endif + 0); + } + this->ExaGeoStatOptionsFree(&options); + this->ExaGeoStatOptionsFinalize(&options, (HICMA_context_t *) + this->mpContext); + return HICMA_SUCCESS; +} diff --git a/src/prediction/Prediction.cpp b/src/prediction/Prediction.cpp index 1550c5df..08804b55 100644 --- a/src/prediction/Prediction.cpp +++ b/src/prediction/Prediction.cpp @@ -6,7 +6,7 @@ /** * @file Prediction.cpp * @brief Contains the implementation of the Prediction class. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-06-08 @@ -22,7 +22,8 @@ using namespace exageostat::configurations; using namespace exageostat::dataunits; template -void Prediction::PredictMissingData(const hardware::ExaGeoStatHardware &aHardware, ExaGeoStatData &aData, +void Prediction::PredictMissingData(const hardware::ExaGeoStatHardware &aHardware, + std::unique_ptr> &aData, Configurations &aConfigurations, T *apMeasurementsMatrix, const kernels::Kernel &aKernel) { @@ -35,34 +36,42 @@ void Prediction::PredictMissingData(const hardware::ExaGeoStatHardware &aHard break; } } - if (!can_predict && (aConfigurations.GetIsMLOEMMOM() || aConfigurations.GetIsMSPE() || aConfigurations.GetIsFisher())) { + + if (!can_predict && + (aConfigurations.GetIsMLOEMMOM() || aConfigurations.GetIsMSPE() || aConfigurations.GetIsFisher())) { throw std::runtime_error( "Can't predict without an estimated theta, please either pass --etheta or run the modeling module before prediction"); } int number_of_mspe = 3; - int p = aConfigurations.GetP(); + int p = aKernel.GetVariablesNumber(); int z_miss_number = aConfigurations.GetUnknownObservationsNb(); int n_z_obs = aConfigurations.CalculateZObsNumber(); auto linear_algebra_solver = linearAlgebra::LinearAlgebraFactory::CreateLinearAlgebraSolver(common::EXACT_DENSE); - //FISHER Prediction Function Call + // FISHER Prediction Function Call if (aConfigurations.GetIsFisher()) { LOGGER("---- Using Prediction Function Fisher ----") - auto fisher_results = new T[num_params * num_params]; - fisher_results = linear_algebra_solver->ExaGeoStatFisherTile(aConfigurations, aData, aHardware, (T *) aConfigurations.GetEstimatedTheta().data(), aKernel); + T *fisher_results; + fisher_results = linear_algebra_solver->ExaGeoStatFisherTile(aConfigurations, aData, aHardware, + (T *) aConfigurations.GetEstimatedTheta().data(), + aKernel); - LOGGER("- Sd of sigma2, alpha, nu: " << sqrt(fisher_results[0]) << " " << sqrt(fisher_results[4]) << " " << sqrt(fisher_results[8])) - LOGGER("- CI for sigma2: " << aConfigurations.GetEstimatedTheta()[0] - Q_NORM * sqrt(fisher_results[0]) << " " << aConfigurations.GetEstimatedTheta()[0] + Q_NORM * sqrt(fisher_results[0])) + LOGGER("- Sd of sigma2, alpha, nu: " << sqrt(fisher_results[0]) << " " << sqrt(fisher_results[4]) << " " + << sqrt(fisher_results[8])) + LOGGER("- CI for sigma2: " << aConfigurations.GetEstimatedTheta()[0] - Q_NORM * sqrt(fisher_results[0]) << " " + << aConfigurations.GetEstimatedTheta()[0] + Q_NORM * sqrt(fisher_results[0])) - LOGGER("- CI for alpha: " << aConfigurations.GetEstimatedTheta()[1] - Q_NORM * sqrt(fisher_results[4]) << " " << aConfigurations.GetEstimatedTheta()[1] + Q_NORM * sqrt(fisher_results[4])) - LOGGER("- CI for nu: " << aConfigurations.GetEstimatedTheta()[2] - Q_NORM * sqrt(fisher_results[8]) << " " << aConfigurations.GetEstimatedTheta()[2] + Q_NORM * sqrt(fisher_results[8])) + LOGGER("- CI for alpha: " << aConfigurations.GetEstimatedTheta()[1] - Q_NORM * sqrt(fisher_results[4]) << " " + << aConfigurations.GetEstimatedTheta()[1] + Q_NORM * sqrt(fisher_results[4])) + LOGGER("- CI for nu: " << aConfigurations.GetEstimatedTheta()[2] - Q_NORM * sqrt(fisher_results[8]) << " " + << aConfigurations.GetEstimatedTheta()[2] + Q_NORM * sqrt(fisher_results[8])) LOGGER("- Fisher Matrix:") - for (i = 0; i < num_params; i ++){ + for (i = 0; i < num_params; i++) { LOGGER(" ", true) - for (j = 0; j < num_params; j++){ - LOGGER_PRECISION(fisher_results[i * num_params + j] , 18) + for (j = 0; j < num_params; j++) { + LOGGER_PRECISION(fisher_results[i * num_params + j], 18) if (j != num_params - 1) { LOGGER_PRECISION(", ") } @@ -73,22 +82,26 @@ void Prediction::PredictMissingData(const hardware::ExaGeoStatHardware &aHard delete[] fisher_results; } - if (z_miss_number <= 0){ + if (z_miss_number <= 0) { return; } - LOGGER("- Number of Z observations: " << aConfigurations.GetP() * n_z_obs) - results::Results::GetInstance()->SetZMiss(aConfigurations.GetP() * n_z_obs); - T *z_obs = new T[p * n_z_obs]; - T *z_miss = new T[p * z_miss_number]; - T *z_actual = new T[p * z_miss_number]; + LOGGER("- Total number of Z: " << aConfigurations.GetProblemSize()) + LOGGER("- Number of Z Miss: " << z_miss_number) + LOGGER("- Number of Z observations: " << n_z_obs) + + results::Results::GetInstance()->SetZMiss(z_miss_number); + T *z_obs = new T[n_z_obs * p]; + T *z_miss = new T[z_miss_number]; + T *z_actual = new T[z_miss_number * p]; std::vector avg_pred_value(number_of_mspe); - auto miss_locations = new Locations(z_miss_number, aData.GetLocations()->GetDimension()); - auto obs_locations = new Locations(n_z_obs, aData.GetLocations()->GetDimension()); - // We Predict date with only Exact computation. This is a pre-request. + auto miss_locations = new Locations(z_miss_number, aConfigurations.GetDimension()); + // Prediction is only supported with 2D. + auto obs_locations = new Locations(n_z_obs, aConfigurations.GetDimension()); + // We Predict date with only Exact computation. This is a pre-request. InitializePredictionArguments(aConfigurations, aData, linear_algebra_solver, z_obs, z_actual, *miss_locations, - *obs_locations, apMeasurementsMatrix); + *obs_locations, apMeasurementsMatrix, p); // MLOE MMOM Auxiliary Function Call if (aConfigurations.GetIsMLOEMMOM()) { @@ -97,7 +110,6 @@ void Prediction::PredictMissingData(const hardware::ExaGeoStatHardware &aHard (T *) aConfigurations.GetInitialTheta().data(), (T *) aConfigurations.GetEstimatedTheta().data(), *miss_locations, *obs_locations, aKernel); - LOGGER(" ---- mloe_mmom Time(main): %6.2f seconds") } // IDW Auxiliary Function Call @@ -124,15 +136,29 @@ void Prediction::PredictMissingData(const hardware::ExaGeoStatHardware &aHard // MSPE Prediction Function Call if (aConfigurations.GetIsMSPE()) { LOGGER("---- Using MSPE ----") - T *prediction_error_mspe = linear_algebra_solver->ExaGeoStatMLEPredictTile(aData, - (T *) aConfigurations.GetEstimatedTheta().data(), - z_miss_number, n_z_obs, z_obs, - z_actual, z_miss, aHardware, - aConfigurations, *miss_locations, - *obs_locations, aKernel); + T *prediction_error_mspe; + if (aConfigurations.GetIsNonGaussian()) { + prediction_error_mspe = linear_algebra_solver->ExaGeoStatMLENonGaussianPredictTile(aData, + (T *) aConfigurations.GetEstimatedTheta().data(), + z_miss_number, n_z_obs, + z_obs, + z_actual, z_miss, + aHardware, + aConfigurations, + *miss_locations, + *obs_locations, aKernel); + } else { + prediction_error_mspe = linear_algebra_solver->ExaGeoStatMLEPredictTile(aData, + (T *) aConfigurations.GetEstimatedTheta().data(), + z_miss_number, n_z_obs, z_obs, + z_actual, z_miss, aHardware, + aConfigurations, *miss_locations, + *obs_locations, aKernel); + } for (i = 0; i < number_of_mspe; i++) { avg_pred_value[i] += prediction_error_mspe[i]; } + LOGGER("- MSPE: " << avg_pred_value[0]) LOGGER("- Average prediction Error (mspe): ", true) for (i = 0; i < number_of_mspe; i++) { LOGGER_PRECISION(avg_pred_value[i] << "\t", 8) @@ -149,15 +175,18 @@ void Prediction::PredictMissingData(const hardware::ExaGeoStatHardware &aHard } template -void Prediction::InitializePredictionArguments(Configurations &aConfigurations, ExaGeoStatData &aData, +void Prediction::InitializePredictionArguments(Configurations &aConfigurations, + std::unique_ptr> &aData, std::unique_ptr> &aLinearAlgebraSolver, T *apZObs, T *apZActual, Locations &aMissLocation, - Locations &aObsLocation, T *apMeasurementsMatrix) { + Locations &aObsLocation, T *apMeasurementsMatrix, const int &aP) { - int N = aConfigurations.GetProblemSize(); - T *z = new T[N]; + int full_problem_size = aConfigurations.GetProblemSize() * aP; + T *z = new T[full_problem_size]; - aLinearAlgebraSolver->ExaGeoStatGetZObs(aConfigurations, z, N, *aData.GetDescriptorData(), apMeasurementsMatrix); - PredictionHelpers::PickRandomPoints(aConfigurations, aData, apZObs, apZActual, z, aMissLocation, aObsLocation); + aLinearAlgebraSolver->ExaGeoStatGetZObs(aConfigurations, z, full_problem_size, *aData->GetDescriptorData(), + apMeasurementsMatrix, aP); + PredictionHelpers::PickRandomPoints(aConfigurations, aData, apZObs, apZActual, z, aMissLocation, aObsLocation, + aP); delete[] z; } \ No newline at end of file diff --git a/src/prediction/PredictionAuxiliaryFunctions.cpp b/src/prediction/PredictionAuxiliaryFunctions.cpp index fb89d847..1dd7b33b 100644 --- a/src/prediction/PredictionAuxiliaryFunctions.cpp +++ b/src/prediction/PredictionAuxiliaryFunctions.cpp @@ -6,7 +6,7 @@ /** * @file PredictionAuxiliaryFunctions.cpp * @brief Contains the implementation of the PredictionAuxiliaryFunctions class. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-06-08 @@ -57,8 +57,9 @@ void PredictionAuxiliaryFunctions::PredictIDW(T *apZMiss, T *apZActual, T *ap apMSPE[1] = error1 / (aZMissNumber / 2); apMSPE[2] = error2 / (aZMissNumber / 2); - LOGGER("- Z Actual .. Z Miss") - for (int index = 0; index < aZMissNumber; index++) - LOGGER(" (" << apZActual[index] << ", " << apZMiss[index] << ")") + VERBOSE("- Z Actual .. Z Miss") + for (int index = 0; index < aZMissNumber; index++) { + VERBOSE(" (" << apZActual[index] << ", " << apZMiss[index] << ")") + } LOGGER("- Prediction Error (IDW): " << apMSPE[0] << " - " << apMSPE[1] << " - " << apMSPE[2]) } \ No newline at end of file diff --git a/src/prediction/PredictionHelpers.cpp b/src/prediction/PredictionHelpers.cpp index 7acf4c3c..90da508b 100644 --- a/src/prediction/PredictionHelpers.cpp +++ b/src/prediction/PredictionHelpers.cpp @@ -6,7 +6,7 @@ /** * @file PredictionHelpers.cpp * @brief Contains the implementation of the PredictionHelpers class. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-06-08 @@ -21,23 +21,23 @@ using namespace exageostat::configurations; using namespace exageostat::dataunits; template -void PredictionHelpers::PickRandomPoints(Configurations &aConfigurations, ExaGeoStatData &aData, T *apZObs, +void PredictionHelpers::PickRandomPoints(Configurations &aConfigurations, + std::unique_ptr> &aData, T *apZObs, T *apZActual, T *apZ, Locations &aMissLocation, - Locations &aObsLocation) { + Locations &aObsLocation, const int &aP) { int i; int j; - int N = aConfigurations.GetProblemSize(); + int full_problem_size = aConfigurations.GetProblemSize() * aP; int z_miss_number = aConfigurations.GetUnknownObservationsNb(); int z_obs_number = aConfigurations.CalculateZObsNumber(); - auto l = new Locations(N, aData.GetLocations()->GetDimension()); - - int p = aConfigurations.GetP(); bool is_shuffle = true; + int p = aP; + auto l = new Locations(aConfigurations.GetProblemSize(), aData->GetLocations()->GetDimension()); - if (aConfigurations.GetIsMLOEMMOM() && aConfigurations.GetP() == 2) { + if (aConfigurations.GetIsMLOEMMOM() && aP == 2) { p = 1; - N /= 2; + full_problem_size /= 2; is_shuffle = false; } @@ -45,30 +45,35 @@ void PredictionHelpers::PickRandomPoints(Configurations &aConfigurations, Exa T **Z_parts = new T *[p]; // Allocate memory for each row of the 2D array for (i = 0; i < p; i++) { - Z_parts[i] = new T[N / p]; + Z_parts[i] = new T[full_problem_size / p]; } if (p > 1) { // Partition Z into p parts for (i = 0; i < p; i++) { - for (j = 0; j < N; j += p) { - Z_parts[i][j] = apZ[i + j]; + int m = 0; + for (j = 0; j < full_problem_size; j += p) { + Z_parts[i][m] = apZ[i + j]; + m++; } } } - for (i = 0; i < N / p; i++) { - l->GetLocationX()[i] = aData.GetLocations()->GetLocationX()[i]; - l->GetLocationY()[i] = aData.GetLocations()->GetLocationY()[i]; + for (i = 0; i < full_problem_size / p; i++) { + l->GetLocationX()[i] = aData->GetLocations()->GetLocationX()[i]; + l->GetLocationY()[i] = aData->GetLocations()->GetLocationY()[i]; + if (aConfigurations.GetDimension() != common::Dimension2D) { + l->GetLocationZ()[i] = aData->GetLocations()->GetLocationZ()[i]; + } } if (is_shuffle) { if (p == 1) { - Shuffle(apZ, *l, N); + Shuffle(apZ, *l, full_problem_size); } else if (p == 2) { - Shuffle(Z_parts[0], Z_parts[1], *l, N); + Shuffle(Z_parts[0], Z_parts[1], *l, full_problem_size / p); } else if (p == 3) { - Shuffle(Z_parts[0], Z_parts[1], Z_parts[2], *l, N); + Shuffle(Z_parts[0], Z_parts[1], Z_parts[2], *l, full_problem_size / p); } } @@ -107,11 +112,17 @@ void PredictionHelpers::PickRandomPoints(Configurations &aConfigurations, Exa for (i = 0; i < z_miss_number; i++) { aMissLocation.GetLocationX()[i] = l->GetLocationX()[i]; aMissLocation.GetLocationY()[i] = l->GetLocationY()[i]; + if (aConfigurations.GetDimension() != common::Dimension2D) { + aMissLocation.GetLocationZ()[i] = l->GetLocationZ()[i]; + } } for (i = 0; i < z_obs_number; i++) { aObsLocation.GetLocationX()[i] = l->GetLocationX()[z_miss_number + i]; aObsLocation.GetLocationY()[i] = l->GetLocationY()[z_miss_number + i]; + if (aConfigurations.GetDimension() != common::Dimension2D) { + aObsLocation.GetLocationZ()[i] = l->GetLocationZ()[z_miss_number + i]; + } } if (p == 1) { @@ -146,6 +157,12 @@ void PredictionHelpers::Shuffle(T *apArray, Locations &aLocations, int aSi aLocations.GetLocationY()[j] = aLocations.GetLocationY()[i]; aLocations.GetLocationY()[i] = y_temp; + if (aLocations.GetDimension() != common::Dimension2D) { + T z_temp = aLocations.GetLocationZ()[j]; + aLocations.GetLocationZ()[j] = aLocations.GetLocationZ()[i]; + aLocations.GetLocationZ()[i] = z_temp; + } + } } } @@ -174,6 +191,12 @@ void PredictionHelpers::Shuffle(T *apArray1, T *apArray2, Locations &aLoca aLocations.GetLocationY()[j] = aLocations.GetLocationY()[i]; aLocations.GetLocationY()[i] = y_temp; + if (aLocations.GetDimension() != common::Dimension2D) { + T z_temp = aLocations.GetLocationZ()[j]; + aLocations.GetLocationZ()[j] = aLocations.GetLocationZ()[i]; + aLocations.GetLocationZ()[i] = z_temp; + } + } } @@ -207,6 +230,11 @@ void PredictionHelpers::Shuffle(T *apArray1, T *apArray2, T *apArray3, Locati aLocations.GetLocationY()[j] = aLocations.GetLocationY()[i]; aLocations.GetLocationY()[i] = y_temp; + if (aLocations.GetDimension() != common::Dimension2D) { + T z_temp = aLocations.GetLocationZ()[j]; + aLocations.GetLocationZ()[j] = aLocations.GetLocationZ()[i]; + aLocations.GetLocationZ()[i] = z_temp; + } } } diff --git a/src/results/Results.cpp b/src/results/Results.cpp index 3a919d18..63234f6c 100644 --- a/src/results/Results.cpp +++ b/src/results/Results.cpp @@ -6,7 +6,7 @@ /** * @file Results.cpp * @brief Defines the Results class for storing and accessing result data. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-09-14 **/ @@ -48,80 +48,80 @@ void Results::PrintEndSummary() { LOGGER("") LOGGER("********************SUMMARY**********************") - auto locations_number = mGeneratedLocationsNumber; + auto locations_number = this->mGeneratedLocationsNumber; if (locations_number > 0) { LOGGER("---- Data Generation Results ----") - if (mIsSynthetic) { + if (this->mIsSynthetic) { LOGGER(" #Synthetic Dataset") } else { LOGGER(" #Real Dataset") } LOGGER(" #Number of Locations: " << locations_number) - if (mIsLogger && mIsSynthetic) { + if (this->mIsLogger && this->mIsSynthetic) { LOGGER(" #Data is written to file (", true) - if (mLoggerPath.empty()) { - mLoggerPath = LOG_PATH; + if (this->mLoggerPath.empty()) { + this->mLoggerPath = LOG_PATH; } - LOGGER_PRECISION(mLoggerPath << ").") + LOGGER_PRECISION(this->mLoggerPath << ").") LOGGER("") } - LOGGER(" #Total Data Generation Execution Time: " << mExecutionTimeDataGeneration) - LOGGER(" #Total Data Generation Gflop/s: " << mFlopsDataGeneration) + LOGGER(" #Total Data Generation Execution Time: " << this->mExecutionTimeDataGeneration) + LOGGER(" #Total Data Generation Gflop/s: " << this->mFlopsDataGeneration) LOGGER("") } - if (mMLEIterations > 0) { + if (this->mMLEIterations > 0) { LOGGER("---- Data Modeling Results ----") - LOGGER(" #Number of MLE Iterations till reach Maximum: " << mMLEIterations) + LOGGER(" #Number of MLE Iterations till reach Maximum: " << this->mMLEIterations) LOGGER(" #Found Maximum Theta at: ", true) - for (double i: mMaximumTheta) { + for (double i: this->mMaximumTheta) { LOGGER_PRECISION(i << " ", 8) } LOGGER("") - LOGGER(" #Final Log Likelihood value: " << mLogLikValue) + LOGGER(" #Final Log Likelihood value: " << this->mLogLikValue) LOGGER(" #Average Time Modeling per Iteration: " << this->GetAverageModelingExecutionTime()) LOGGER(" #Average Flops per Iteration: " << this->GetAverageModelingFlops()) - LOGGER(" #Total MLE Execution time: " << mTotalModelingExecutionTime) - LOGGER(" #Total MLE Gflop/s: " << mTotalModelingFlops) + LOGGER(" #Total MLE Execution time: " << this->mTotalModelingExecutionTime) + LOGGER(" #Total MLE Gflop/s: " << this->mTotalModelingFlops) LOGGER("") } - if (mZMiss > 0) { + if (this->mZMiss > 0) { LOGGER("---- Data Prediction Results ----") - LOGGER(" #Number of Missing Observations: " << mZMiss) - if (mMSPEError > 0) { + LOGGER(" #Number of Missing Observations: " << this->mZMiss) + if (this->mMSPEError > 0) { LOGGER(" #MSPE") - LOGGER(" #MSPE Prediction Execution Time: " << mExecutionTimeMSPE) - LOGGER(" #MSPE Gflop/s: " << mFlopsMSPE) - LOGGER(" #Mean Square Error MSPE: " << mMSPEError) + LOGGER(" #MSPE Prediction Execution Time: " << this->mExecutionTimeMSPE) + LOGGER(" #MSPE Gflop/s: " << this->mFlopsMSPE) + LOGGER(" #Mean Square Error MSPE: " << this->mMSPEError) } - if (!mIDWError.empty()) { + if (!this->mIDWError.empty()) { LOGGER(" #IDW") LOGGER(" #IDW Error: ( ", true) for (int i = 0; i < 3; i++) { - LOGGER_PRECISION(mIDWError[i] << " ", 8) + LOGGER_PRECISION(this->mIDWError[i] << " ", 8) } LOGGER_PRECISION(").") LOGGER("") } - if (mMLOE > 0 || mMMOM > 0) { + if (this->mMLOE > 0 || this->mMMOM > 0) { LOGGER(" #MLOE MMOM") - LOGGER(" #MLOE: " << mMLOE) - LOGGER(" #MMOM: " << mMMOM) - LOGGER(" #MLOE-MMOM Execution Time: " << mExecutionTimeMLOEMMOM) - LOGGER(" #MLOE-MMOM Matrix Generation Time: " << mGenerationTimeMLOEMMOM) - LOGGER(" #MLOE-MMOM Cholesky Factorization Time: " << mFactoTimeMLOEMMOM) - LOGGER(" #MLOE-MMOM Loop Time: " << mLoopTimeMLOEMMOM) - LOGGER(" #MLOE-MMOM Number of flops: " << mFlopsMLOEMMOM) + LOGGER(" #MLOE: " << this->mMLOE) + LOGGER(" #MMOM: " << this->mMMOM) + LOGGER(" #MLOE-MMOM Execution Time: " << this->mExecutionTimeMLOEMMOM) + LOGGER(" #MLOE-MMOM Matrix Generation Time: " << this->mGenerationTimeMLOEMMOM) + LOGGER(" #MLOE-MMOM Cholesky Factorization Time: " << this->mFactoTimeMLOEMMOM) + LOGGER(" #MLOE-MMOM Loop Time: " << this->mLoopTimeMLOEMMOM) + LOGGER(" #MLOE-MMOM Number of flops: " << this->mFlopsMLOEMMOM) LOGGER("") } } - if(mFisher00 != 0){ + if (this->mFisher00 != 0) { LOGGER(" #Fisher") - LOGGER(" #Sd For Sigma2: " << mFisher00) - LOGGER(" #Sd For Alpha: " << mFisher11) - LOGGER(" #Sd For Nu: " << mFisher22) - LOGGER(" #Fisher Execution Time: " << mTotalFisherTime) + LOGGER(" #Sd For Sigma2: " << this->mFisher00) + LOGGER(" #Sd For Alpha: " << this->mFisher11) + LOGGER(" #Sd For Nu: " << this->mFisher22) + LOGGER(" #Fisher Execution Time: " << this->mTotalFisherTime) LOGGER("") } LOGGER("*************************************************") @@ -242,4 +242,35 @@ void Results::SetFisher11(double aFisher11) { void Results::SetFisher22(double aFisher22) { this->mFisher22 = aFisher22; -} \ No newline at end of file +} + + +double Results::GetMLOE() const { + return this->mMLOE; +} + +double Results::GetMSPEError() const { + return this->mMSPEError; +} + +std::vector Results::GetIDWError() const { + return this->mIDWError; +} + +double Results::GetMMOM() const { + return this->mMMOM; +} + +double Results::GetFisher00() const { + return this->mFisher00; +} + + +double Results::GetFisher11() const { + return this->mFisher11; +} + +double Results::GetFisher22() const { + return this->mFisher22; +} + diff --git a/tests/cpp-tests/CMakeLists.txt b/tests/cpp-tests/CMakeLists.txt index 6d9a940d..e220bf7f 100644 --- a/tests/cpp-tests/CMakeLists.txt +++ b/tests/cpp-tests/CMakeLists.txt @@ -4,16 +4,23 @@ # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy -# @date 2023-01-31 +# @date 2024-01-24 add_subdirectory(api) -add_subdirectory(linear-algebra-solvers) +add_subdirectory(configurations) add_subdirectory(data-generators) -add_subdirectory(configurations/data-generation) -add_subdirectory(kernels) +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 () enable_testing() add_executable(exageostat-tests ${EXAGEOSTAT_TESTFILES}) diff --git a/tests/cpp-tests/api/TestExaGeoStatApi.cpp b/tests/cpp-tests/api/TestExaGeoStatApi.cpp index 1241baa5..4074803f 100644 --- a/tests/cpp-tests/api/TestExaGeoStatApi.cpp +++ b/tests/cpp-tests/api/TestExaGeoStatApi.cpp @@ -6,7 +6,7 @@ /** * @file TestExaGeoStatApi.cpp * @brief Test suite for the ExaGeoStat APIs data generation functionality. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-08-07 @@ -47,7 +47,7 @@ void TEST_GENERATE_DATA() { // initialize ExaGeoStat Hardware. auto hardware = ExaGeoStatHardware(EXACT_DENSE, 4, 0); // Or you could use configurations.GetComputation(). - exageostat::dataunits::ExaGeoStatData data; + std::unique_ptr> data; exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, data); @@ -55,7 +55,7 @@ void TEST_GENERATE_DATA() { double expected_output_data[] = {-1.272336, -2.590700, 0.512143, -0.163880, 0.313504, -1.474411, 0.161705, 0.623389, -1.341858, -1.054282, -1.669383, 0.219171, 0.971214, 0.538973, -0.752828, 0.290822}; - auto *CHAM_descriptorZ = data.GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + auto *CHAM_descriptorZ = data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc; auto *A = (double *) CHAM_descriptorZ->mat; double diff; @@ -108,8 +108,8 @@ void TEST_MODEL_DATA(Computation aComputation) { { // initialize ExaGeoStat Hardware. auto hardware = ExaGeoStatHardware(aComputation, 4, 0); // Or you could use configurations.GetComputation(). - exageostat::dataunits::ExaGeoStatData data(configurations.GetProblemSize(), - configurations.GetDimension()); + std::unique_ptr> data = std::make_unique>(configurations.GetProblemSize(), configurations.GetDimension()); + //initiating the matrix of the CHAMELEON Descriptor Z. auto *z_matrix = new double[N]{-1.272336140360187606, -2.590699695867695773, 0.512142584178685967, @@ -133,8 +133,8 @@ void TEST_MODEL_DATA(Computation aComputation) { 0.573571374074921758, 0.568657969024185528, 0.935835812924391552, 0.942824444953078489}; - data.GetLocations()->SetLocationX(*location_x, N); - data.GetLocations()->SetLocationY(*location_y, N); + data->GetLocations()->SetLocationX(*location_x, N); + data->GetLocations()->SetLocationY(*location_y, N); double log_likelihood = exageostat::api::ExaGeoStat::ExaGeoStatDataModeling(hardware, configurations, data, z_matrix); @@ -147,7 +147,7 @@ void TEST_MODEL_DATA(Computation aComputation) { { // initialize ExaGeoStat Hardware. auto hardware = ExaGeoStatHardware(aComputation, 4, 0); // Or you could use configurations.GetComputation(). - exageostat::dataunits::ExaGeoStatData data; + std::unique_ptr> data; exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, configurations, data); double log_likelihood = exageostat::api::ExaGeoStat::ExaGeoStatDataModeling(hardware, configurations, @@ -181,7 +181,7 @@ void TEST_PREDICTION() { Configurations::SetVerbosity(QUIET_MODE); auto hardware = ExaGeoStatHardware(EXACT_DENSE, configurations.GetCoresNumber(), configurations.GetGPUsNumbers()); - exageostat::dataunits::ExaGeoStatData data(configurations.GetProblemSize(), configurations.GetDimension()); + std::unique_ptr> data = std::make_unique>(configurations.GetProblemSize(), configurations.GetDimension()); auto *z_matrix = new double[N]{-1.272336140360187606, -2.590699695867695773, 0.512142584178685967, -0.163880452049749520, 0.313503633252489700, -1.474410682226017677, @@ -203,8 +203,8 @@ void TEST_PREDICTION() { 0.573571374074921758, 0.568657969024185528, 0.935835812924391552, 0.942824444953078489}; - data.GetLocations()->SetLocationX(*location_x, N); - data.GetLocations()->SetLocationY(*location_y, N); + data->GetLocations()->SetLocationX(*location_x, N); + data->GetLocations()->SetLocationY(*location_y, N); SECTION("Test Prediction - MSPE ONLY") { diff --git a/tests/cpp-tests/configurations/data-generation/CMakeLists.txt b/tests/cpp-tests/configurations/CMakeLists.txt similarity index 79% rename from tests/cpp-tests/configurations/data-generation/CMakeLists.txt rename to tests/cpp-tests/configurations/CMakeLists.txt index bdcadc45..5c54869a 100644 --- a/tests/cpp-tests/configurations/data-generation/CMakeLists.txt +++ b/tests/cpp-tests/configurations/CMakeLists.txt @@ -4,13 +4,13 @@ # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @date 2023-01-31 set(EXAGEOSTAT_TESTFILES - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestSyntheticDataConfigurations.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TestConfigurations.cpp ${EXAGEOSTAT_TESTFILES} PARENT_SCOPE diff --git a/tests/cpp-tests/configurations/data-generation/concrete/TestSyntheticDataConfigurations.cpp b/tests/cpp-tests/configurations/TestConfigurations.cpp similarity index 59% rename from tests/cpp-tests/configurations/data-generation/concrete/TestSyntheticDataConfigurations.cpp rename to tests/cpp-tests/configurations/TestConfigurations.cpp index 0aa00c4e..59da0f29 100644 --- a/tests/cpp-tests/configurations/data-generation/concrete/TestSyntheticDataConfigurations.cpp +++ b/tests/cpp-tests/configurations/TestConfigurations.cpp @@ -4,15 +4,15 @@ // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** -* @file synthetic_data.cpp -* @brief Unit tests for the Configurations class in the ExaGeoStat software package. -* @details This file contains Catch2 unit tests that validate the functionality of the Configurations class -* in the ExaGeoStat software package. The tests cover various setters, getters, and value checks -* for configuration parameters such as dimensions, P-GRID, kernel name, problem size, precision, and more. -* Additionally, the tests include a copy-constructor test for the Configurations class. -* @version 1.0.0 -* @author Mahmoud ElKarargy -* @date 2023-01-31 + * @file synthetic_data.cpp + * @brief Unit tests for the Configurations class in the ExaGeoStat software package. + * @details This file contains Catch2 unit tests that validate the functionality of the Configurations class + * in the ExaGeoStat software package. The tests cover various setters, getters, and value checks + * for configuration parameters such as dimensions, P-GRID, kernel name, problem size, precision, and more. + * Additionally, the tests include a copy-constructor test for the Configurations class. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @date 2023-01-31 **/ #include @@ -25,6 +25,74 @@ using namespace std; using namespace exageostat::common; using namespace exageostat::configurations; +void TEST_ARGUMENT_INITIALIZATION(){ + + const int argc = 17; + char* argv[] = { + const_cast("program_name"), + const_cast("--N=16"), + const_cast("--dts=8"), + const_cast("--kernel=univariate_matern_stationary"), + const_cast("--computation=exact"), + const_cast("--precision=double"), + const_cast("--initial_theta=1:0.1:0.5"), + 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("--ZMiss=6"), + const_cast("--mspe"), + const_cast("--idw"), + const_cast("--mloe-mmom"), + const_cast("--fisher"), + const_cast("--data_path=./dummy-path") + }; + + Configurations configurations; + + // Initialize configuration dictionary with only common arguments + configurations.InitializeArguments(argc, argv); + + REQUIRE(configurations.GetProblemSize() == 16); + REQUIRE(configurations.GetKernelName() == "UnivariateMaternStationary"); + 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()); + REQUIRE_THROWS(configurations.GetTolerance()); + + // 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() == 4); + + // Data prediction arguments initialized + configurations.InitializeDataPredictionArguments(); + + REQUIRE(configurations.GetIsMSPE() == true); + REQUIRE(configurations.GetIsIDW() == true); + REQUIRE(configurations.GetIsFisher() == true); + REQUIRE(configurations.GetIsMLOEMMOM() == true); + REQUIRE(configurations.GetUnknownObservationsNb() == 6); + +} void TEST_SYNTHETIC_CONFIGURATIONS() { Configurations synthetic_data_configurations; @@ -113,7 +181,8 @@ void TEST_COPY_CONSTRUCTOR() { } } -TEST_CASE("Synthetic Data Configurations") { +TEST_CASE("Configurations Tests") { TEST_SYNTHETIC_CONFIGURATIONS(); TEST_COPY_CONSTRUCTOR(); + TEST_ARGUMENT_INITIALIZATION(); } diff --git a/tests/cpp-tests/data-generators/concrete/TestCSVDataGenerator.cpp b/tests/cpp-tests/data-generators/concrete/TestCSVDataGenerator.cpp index a26be8d0..83667823 100644 --- a/tests/cpp-tests/data-generators/concrete/TestCSVDataGenerator.cpp +++ b/tests/cpp-tests/data-generators/concrete/TestCSVDataGenerator.cpp @@ -9,7 +9,7 @@ * @details This file contains Catch2 unit tests that validate the functionality of the CSVDataGenerator class * in the ExaGeoStat software package. The tests cover various aspects of data generation, including spreading * and reversing bits, generating locations for different dimensions, and testing helper functions. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-03-08 **/ @@ -47,7 +47,7 @@ void TEST_CSV_P_1() { vector initial_theta{1, 0.1, 0.5}; configurations.SetInitialTheta(initial_theta); - Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create(configurations.GetKernelName()); + Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create(configurations.GetKernelName(), configurations.GetTimeSlot()); auto hardware = exageostat::hardware::ExaGeoStatHardware(configurations.GetComputation(), configurations.GetCoresNumber(), @@ -88,14 +88,14 @@ void TEST_CSV_P_1() { locations.SetLocationY(*location_y, N); exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N, p, write_path, locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + auto data = csv_reader->CreateData(configurations, hardware, *pKernel); - auto z_desc_mat = data.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, - data.GetDescriptorData()->GetDescriptor( + auto z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, + data->GetDescriptorData()->GetDescriptor( CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc); - auto data_loc_x = data.GetLocations()->GetLocationX(); - auto data_loc_y = data.GetLocations()->GetLocationY(); + auto data_loc_x = data->GetLocations()->GetLocationX(); + auto data_loc_y = data->GetLocations()->GetLocationY(); for (int i = 0; i < N; i++) { REQUIRE(z_desc_mat[i] - measurements_matrix[i] == Catch::Approx(0.0).margin(1e-6)); @@ -121,15 +121,15 @@ void TEST_CSV_P_1() { locations.SetLocationZ(*location_z, N); exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N, p, write_path, locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + auto data = csv_reader->CreateData(configurations, hardware, *pKernel); - auto z_desc_mat = data.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, - data.GetDescriptorData()->GetDescriptor( + auto z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, + data->GetDescriptorData()->GetDescriptor( CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc); - auto data_loc_x = data.GetLocations()->GetLocationX(); - auto data_loc_y = data.GetLocations()->GetLocationY(); - auto data_loc_z = data.GetLocations()->GetLocationZ(); + auto data_loc_x = data->GetLocations()->GetLocationX(); + auto data_loc_y = data->GetLocations()->GetLocationY(); + auto data_loc_z = data->GetLocations()->GetLocationZ(); for (int i = 0; i < N; i++) { REQUIRE(z_desc_mat[i] - measurements_matrix[i] == Catch::Approx(0.0).margin(1e-6)); @@ -137,6 +137,7 @@ void TEST_CSV_P_1() { REQUIRE(data_loc_y[i] - location_y[i] == Catch::Approx(0.0).margin(1e-6)); REQUIRE(data_loc_z[i] - location_z[i] == Catch::Approx(0.0).margin(1e-6)); } + delete[] location_z; } SECTION("Test CSV ST Dimensions locations, p = 1.") { @@ -156,15 +157,15 @@ void TEST_CSV_P_1() { locations.SetLocationZ(*location_time, N); exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N, p, write_path, locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + auto data = csv_reader->CreateData(configurations, hardware, *pKernel); - auto z_desc_mat = data.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, - data.GetDescriptorData()->GetDescriptor( + auto z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, + data->GetDescriptorData()->GetDescriptor( CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc); - auto data_loc_x = data.GetLocations()->GetLocationX(); - auto data_loc_y = data.GetLocations()->GetLocationY(); - auto data_loc_time = data.GetLocations()->GetLocationZ(); + auto data_loc_x = data->GetLocations()->GetLocationX(); + auto data_loc_y = data->GetLocations()->GetLocationY(); + auto data_loc_time = data->GetLocations()->GetLocationZ(); for (int i = 0; i < N; i++) { REQUIRE(z_desc_mat[i] - measurements_matrix[i] == Catch::Approx(0.0).margin(1e-6)); @@ -172,7 +173,7 @@ void TEST_CSV_P_1() { REQUIRE(data_loc_y[i] - location_y[i] == Catch::Approx(0.0).margin(1e-6)); REQUIRE(data_loc_time[i] - location_time[i] == Catch::Approx(0.0).margin(1e-6)); } - + delete[] location_time; } delete[] location_x; @@ -193,13 +194,12 @@ void TEST_CSV_P_2() { configurations.SetIsSynthetic(false); configurations.SetProblemSize(16); configurations.SetDenseTileSize(8); - int p = 2; - configurations.SetP(p); configurations.SetKernelName("BivariateMaternParsimonious"); configurations.SetComputation(exageostat::common::EXACT_DENSE); configurations.SetDataPath(read_path); - Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create(configurations.GetKernelName()); + Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create(configurations.GetKernelName(), configurations.GetTimeSlot()); + int p = pKernel->GetVariablesNumber(); auto hardware = exageostat::hardware::ExaGeoStatHardware(configurations.GetComputation(), configurations.GetCoresNumber(), @@ -252,14 +252,14 @@ void TEST_CSV_P_2() { exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N * p, p, write_path, locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + auto data = csv_reader->CreateData(configurations, hardware, *pKernel); - auto z_desc_mat = data.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, - data.GetDescriptorData()->GetDescriptor( + auto z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, + data->GetDescriptorData()->GetDescriptor( CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc); - auto data_loc_x = data.GetLocations()->GetLocationX(); - auto data_loc_y = data.GetLocations()->GetLocationY(); + auto data_loc_x = data->GetLocations()->GetLocationX(); + auto data_loc_y = data->GetLocations()->GetLocationY(); for (int i = 0; i < N; i++) { REQUIRE(z_desc_mat[i] - measurements_matrix[i] == Catch::Approx(0.0).margin(1e-6)); @@ -289,15 +289,15 @@ void TEST_CSV_P_2() { exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N * p, p, write_path, locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + auto data = csv_reader->CreateData(configurations, hardware, *pKernel); - auto z_desc_mat = data.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, - data.GetDescriptorData()->GetDescriptor( + auto z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, + data->GetDescriptorData()->GetDescriptor( CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc); - auto data_loc_x = data.GetLocations()->GetLocationX(); - auto data_loc_y = data.GetLocations()->GetLocationY(); - auto data_loc_z = data.GetLocations()->GetLocationZ(); + auto data_loc_x = data->GetLocations()->GetLocationX(); + auto data_loc_y = data->GetLocations()->GetLocationY(); + auto data_loc_z = data->GetLocations()->GetLocationZ(); for (int i = 0; i < N; i++) { REQUIRE(z_desc_mat[i] - measurements_matrix[i] == Catch::Approx(0.0).margin(1e-6)); @@ -305,7 +305,7 @@ void TEST_CSV_P_2() { REQUIRE(data_loc_y[i] - location_y[i] == Catch::Approx(0.0).margin(1e-6)); REQUIRE(data_loc_z[i] - location_z[i] == Catch::Approx(0.0).margin(1e-6)); } - + delete[] location_z; } SECTION("Test CSV ST Dimensions locations, p = 2.") { @@ -329,15 +329,15 @@ void TEST_CSV_P_2() { exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N * p, p, write_path, locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + auto data = csv_reader->CreateData(configurations, hardware, *pKernel); - auto z_desc_mat = data.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, - data.GetDescriptorData()->GetDescriptor( + auto z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, + data->GetDescriptorData()->GetDescriptor( CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc); - auto data_loc_x = data.GetLocations()->GetLocationX(); - auto data_loc_y = data.GetLocations()->GetLocationY(); - auto data_loc_time = data.GetLocations()->GetLocationZ(); + auto data_loc_x = data->GetLocations()->GetLocationX(); + auto data_loc_y = data->GetLocations()->GetLocationY(); + auto data_loc_time = data->GetLocations()->GetLocationZ(); for (int i = 0; i < N; i++) { REQUIRE(z_desc_mat[i] - measurements_matrix[i] == Catch::Approx(0.0).margin(1e-6)); @@ -345,7 +345,7 @@ void TEST_CSV_P_2() { REQUIRE(data_loc_y[i] - location_y[i] == Catch::Approx(0.0).margin(1e-6)); REQUIRE(data_loc_time[i] - location_time[i] == Catch::Approx(0.0).margin(1e-6)); } - + delete[] location_time; } delete[] location_x; @@ -366,15 +366,14 @@ void TEST_CSV_P_3() { configurations.SetIsSynthetic(false); configurations.SetProblemSize(16); configurations.SetDenseTileSize(3); - int p = 3; - configurations.SetP(p); configurations.SetKernelName("TrivariateMaternParsimonious"); configurations.SetComputation(exageostat::common::EXACT_DENSE); configurations.SetDataPath(read_path); vector initial_theta{1, 1, 1, 0.1, 0.5, 1, 1.5, 0.1, 0.1, 0}; configurations.SetInitialTheta(initial_theta); - Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create(configurations.GetKernelName()); + Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create(configurations.GetKernelName(), configurations.GetTimeSlot()); + int p = pKernel->GetVariablesNumber(); auto hardware = exageostat::hardware::ExaGeoStatHardware(configurations.GetComputation(), configurations.GetCoresNumber(), @@ -424,14 +423,14 @@ void TEST_CSV_P_3() { exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N * p, p, write_path, locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + auto data = csv_reader->CreateData(configurations, hardware, *pKernel); - auto z_desc_mat = data.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, - data.GetDescriptorData()->GetDescriptor( + auto z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, + data->GetDescriptorData()->GetDescriptor( CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc); - auto data_loc_x = data.GetLocations()->GetLocationX(); - auto data_loc_y = data.GetLocations()->GetLocationY(); + auto data_loc_x = data->GetLocations()->GetLocationX(); + auto data_loc_y = data->GetLocations()->GetLocationY(); for (int i = 0; i < N; i++) { REQUIRE(z_desc_mat[i] - measurements_matrix[i] == Catch::Approx(0.0).margin(1e-6)); @@ -459,15 +458,15 @@ void TEST_CSV_P_3() { exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N * p, p, write_path, locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + auto data = csv_reader->CreateData(configurations, hardware, *pKernel); - auto z_desc_mat = data.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, - data.GetDescriptorData()->GetDescriptor( + auto z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, + data->GetDescriptorData()->GetDescriptor( CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc); - auto data_loc_x = data.GetLocations()->GetLocationX(); - auto data_loc_y = data.GetLocations()->GetLocationY(); - auto data_loc_z = data.GetLocations()->GetLocationZ(); + auto data_loc_x = data->GetLocations()->GetLocationX(); + auto data_loc_y = data->GetLocations()->GetLocationY(); + auto data_loc_z = data->GetLocations()->GetLocationZ(); for (int i = 0; i < N; i++) { REQUIRE(z_desc_mat[i] - measurements_matrix[i] == Catch::Approx(0.0).margin(1e-6)); @@ -476,6 +475,7 @@ void TEST_CSV_P_3() { REQUIRE(data_loc_z[i] - location_z[i] == Catch::Approx(0.0).margin(1e-6)); } + delete[] location_z; } SECTION("Test CSV ST Dimensions locations, p = 3.") { @@ -496,15 +496,15 @@ void TEST_CSV_P_3() { exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N * p, p, write_path, locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + auto data = csv_reader->CreateData(configurations, hardware, *pKernel); - auto z_desc_mat = data.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, - data.GetDescriptorData()->GetDescriptor( + auto z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, + data->GetDescriptorData()->GetDescriptor( CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc); - auto data_loc_x = data.GetLocations()->GetLocationX(); - auto data_loc_y = data.GetLocations()->GetLocationY(); - auto data_loc_time = data.GetLocations()->GetLocationZ(); + auto data_loc_x = data->GetLocations()->GetLocationX(); + auto data_loc_y = data->GetLocations()->GetLocationY(); + auto data_loc_time = data->GetLocations()->GetLocationZ(); for (int i = 0; i < N; i++) { REQUIRE(z_desc_mat[i] - measurements_matrix[i] == Catch::Approx(0.0).margin(1e-6)); @@ -512,7 +512,7 @@ void TEST_CSV_P_3() { REQUIRE(data_loc_y[i] - location_y[i] == Catch::Approx(0.0).margin(1e-6)); REQUIRE(data_loc_time[i] - location_time[i] == Catch::Approx(0.0).margin(1e-6)); } - + delete[] location_time; } delete[] location_x; diff --git a/tests/cpp-tests/data-generators/concrete/TestSyntheticGenerator.cpp b/tests/cpp-tests/data-generators/concrete/TestSyntheticGenerator.cpp index 2c418bc7..a86c4717 100644 --- a/tests/cpp-tests/data-generators/concrete/TestSyntheticGenerator.cpp +++ b/tests/cpp-tests/data-generators/concrete/TestSyntheticGenerator.cpp @@ -9,7 +9,7 @@ * @details This file contains Catch2 unit tests that validate the functionality of the SyntheticGenerator class * in the ExaGeoStat software package. The tests cover various aspects of data generation, including spreading * and reversing bits, generating locations for different dimensions, and testing helper functions. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-03-08 **/ @@ -20,6 +20,8 @@ #include #include #include +#include +#include using namespace std; @@ -29,6 +31,7 @@ using namespace exageostat::dataunits; using namespace exageostat::common; using namespace exageostat::configurations; using namespace exageostat::kernels; +using namespace exageostat::helpers; void TEST_SPREAD_REVERSED_BITS() { @@ -41,7 +44,7 @@ void TEST_SPREAD_REVERSED_BITS() { { uint16_t randomByte = INT16_MAX; REQUIRE(randomByte == 0x7FFF); - uint64_t returnedByte = SyntheticGenerator::SpreadBits(randomByte); + uint64_t returnedByte = SpreadBits(randomByte); // This because 7FFF will first be 16 hex = 64 bits // ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 7FFF // 7FFF to bits is 0111111111111111 @@ -51,7 +54,7 @@ void TEST_SPREAD_REVERSED_BITS() { }SECTION("Reverse Spread Bytes") { uint64_t randomByte = 0x0111111111111111; - uint16_t returnedByte = SyntheticGenerator::ReverseSpreadBits(randomByte); + uint16_t returnedByte = ReverseSpreadBits(randomByte); REQUIRE(returnedByte == 0x7FFF); }SECTION("Spread & reverse 3D") { @@ -61,7 +64,7 @@ void TEST_SPREAD_REVERSED_BITS() { uint16_t z = INT16_MAX; uint64_t vectorZ; - vectorZ = (SyntheticGenerator::SpreadBits(z) << 2); + vectorZ = (SpreadBits(z) << 2); // vector Z will be // ---- ---1 ---1 ---1 ---1 ---1 ---1 ---1 ---1 ---1 ---1 ---1 ---1 ---1 ---1 ---1 // After shifting by 2 @@ -70,7 +73,7 @@ void TEST_SPREAD_REVERSED_BITS() { REQUIRE(vectorZ == 0x0444444444444444); // Do the same for Y - vectorZ += (SyntheticGenerator::SpreadBits(y) << 1); + vectorZ += (SpreadBits(y) << 1); // If vector Z was empty it will be // ---- --1- --1- --1- --1- --1- --1- --1- --1- --1- --1- --1- --1- --1- --1- --1- // But sine vectorZ is already contains Z. then by adding both we get @@ -79,16 +82,16 @@ void TEST_SPREAD_REVERSED_BITS() { REQUIRE(vectorZ == 0x0666666666666666); // Lastly, Adding X - vectorZ += SyntheticGenerator::SpreadBits(x); + vectorZ += SpreadBits(x); // Adding X without shifting will result in // ---- -111 -111 -111 -111 -111 -111 -111 -111 -111 -111 -111 -111 -111 -111 -111 // Since 0111 is equal to 7 in hex then expected to be 0x0777777777777777 REQUIRE(vectorZ == 0x0777777777777777); // Spreading is Done, Now reversing. - uint16_t reversed_x = SyntheticGenerator::ReverseSpreadBits(vectorZ >> 0); - uint16_t reversed_y = SyntheticGenerator::ReverseSpreadBits(vectorZ >> 1); - uint16_t reversed_z = SyntheticGenerator::ReverseSpreadBits(vectorZ >> 2); + uint16_t reversed_x = ReverseSpreadBits(vectorZ >> 0); + uint16_t reversed_y = ReverseSpreadBits(vectorZ >> 1); + uint16_t reversed_z = ReverseSpreadBits(vectorZ >> 2); // What we reversed is what we send. REQUIRE(reversed_x == INT16_MAX); @@ -107,13 +110,13 @@ void TEST_SPREAD_REVERSED_BITS() { uint16_t z_random = 22222; //Spreading - vectorZ = (SyntheticGenerator::SpreadBits(z_random) << 2) + - (SyntheticGenerator::SpreadBits(y_random) << 1) + - SyntheticGenerator::SpreadBits(x_random); + vectorZ = (SpreadBits(z_random) << 2) + + (SpreadBits(y_random) << 1) + + SpreadBits(x_random); // Spreading is Done, Now reversing. - uint16_t reversed_x_random = SyntheticGenerator::ReverseSpreadBits(vectorZ >> 0); - uint16_t reversed_y_random = SyntheticGenerator::ReverseSpreadBits(vectorZ >> 1); - uint16_t reversed_z_random = SyntheticGenerator::ReverseSpreadBits(vectorZ >> 2); + uint16_t reversed_x_random = ReverseSpreadBits(vectorZ >> 0); + uint16_t reversed_y_random = ReverseSpreadBits(vectorZ >> 1); + uint16_t reversed_z_random = ReverseSpreadBits(vectorZ >> 2); REQUIRE(x_random == reversed_x_random); REQUIRE(y_random == reversed_y_random); @@ -128,28 +131,28 @@ void TEST_SPREAD_REVERSED_BITS() { uint16_t z = 0; uint64_t vectorZ; - vectorZ = (SyntheticGenerator::SpreadBits(z) << 2); + vectorZ = (SpreadBits(z) << 2); // vector Z will be zeros REQUIRE(vectorZ == 0x0000000000000000); // Do the same for Y - vectorZ += (SyntheticGenerator::SpreadBits(y) << 1); + vectorZ += (SpreadBits(y) << 1); // vector Z after shift by one will be // ---- --1- --1- --1- --1- --1- --1- --1- --1- --1- --1- --1- --1- --1- --1- --1- // Since 0010 is equal to 2 in hex then expected to be 0x022222222222222 REQUIRE(vectorZ == 0x0222222222222222); // Lastly, Adding X - vectorZ += SyntheticGenerator::SpreadBits(x); + vectorZ += SpreadBits(x); // Adding X without shifting will result in // ---- --11 --11 --11 --11 --11 --11 --11 --11 --11 --11 --11 --11 --11 --11 --11 // Since 0011 is equal to 3 in hex then expected to be 0x0333333333333333 REQUIRE(vectorZ == 0x0333333333333333); // Spreading is Done, Now reversing. - uint16_t reversed_x = SyntheticGenerator::ReverseSpreadBits(vectorZ >> 0); - uint16_t reversed_y = SyntheticGenerator::ReverseSpreadBits(vectorZ >> 1); - uint16_t reversed_z = SyntheticGenerator::ReverseSpreadBits(vectorZ >> 2); + uint16_t reversed_x = ReverseSpreadBits(vectorZ >> 0); + uint16_t reversed_y = ReverseSpreadBits(vectorZ >> 1); + uint16_t reversed_z = ReverseSpreadBits(vectorZ >> 2); // What we reversed is what we send. REQUIRE(reversed_x == INT16_MAX); @@ -168,13 +171,13 @@ void TEST_SPREAD_REVERSED_BITS() { uint16_t z_random = 0; //Spreading - vectorZ = (SyntheticGenerator::SpreadBits(z_random) << 2) + - (SyntheticGenerator::SpreadBits(y_random) << 1) + - SyntheticGenerator::SpreadBits(x_random); + vectorZ = (SpreadBits(z_random) << 2) + + (SpreadBits(y_random) << 1) + + SpreadBits(x_random); // Spreading is Done, Now reversing. - uint16_t reversed_x_random = SyntheticGenerator::ReverseSpreadBits(vectorZ >> 0); - uint16_t reversed_y_random = SyntheticGenerator::ReverseSpreadBits(vectorZ >> 1); - uint16_t reversed_z_random = SyntheticGenerator::ReverseSpreadBits(vectorZ >> 2); + uint16_t reversed_x_random = ReverseSpreadBits(vectorZ >> 0); + uint16_t reversed_y_random = ReverseSpreadBits(vectorZ >> 1); + uint16_t reversed_z_random = ReverseSpreadBits(vectorZ >> 2); REQUIRE(x_random == reversed_x_random); REQUIRE(y_random == reversed_y_random); @@ -191,7 +194,7 @@ void TEST_GENERATE_LOCATIONS() { synthetic_data_configurations.SetComputation(exageostat::common::EXACT_DENSE); vector initial_theta{1, 0.1, 0.5}; synthetic_data_configurations.SetInitialTheta(initial_theta); - Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create(synthetic_data_configurations.GetKernelName()); + Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create(synthetic_data_configurations.GetKernelName(), synthetic_data_configurations.GetTimeSlot()); auto hardware = exageostat::hardware::ExaGeoStatHardware(synthetic_data_configurations.GetComputation(), @@ -203,7 +206,7 @@ void TEST_GENERATE_LOCATIONS() { synthetic_data_configurations); synthetic_data_configurations.SetDimension(Dimension2D); - auto *data = synthetic_generator->CreateData(synthetic_data_configurations, hardware, *pKernel); + auto data = synthetic_generator->CreateData(synthetic_data_configurations, hardware, *pKernel); double *x = data->GetLocations()->GetLocationX(); double *y = data->GetLocations()->GetLocationY(); @@ -213,14 +216,13 @@ void TEST_GENERATE_LOCATIONS() { REQUIRE(x[i] != 0); REQUIRE(y[i] != 0); } - delete data; } SECTION("3D Generation") { synthetic_data_configurations.SetDimension(Dimension3D); unique_ptr> synthetic_generator = DataGenerator::CreateGenerator( synthetic_data_configurations); - auto *data = synthetic_generator->CreateData(synthetic_data_configurations, + auto data = synthetic_generator->CreateData(synthetic_data_configurations, hardware, *pKernel); double *x = data->GetLocations()->GetLocationX(); @@ -232,7 +234,7 @@ void TEST_GENERATE_LOCATIONS() { REQUIRE(y[i] != 0); REQUIRE(z[i] != 0); } - delete data; + } SECTION("ST Generation") { @@ -240,7 +242,7 @@ void TEST_GENERATE_LOCATIONS() { synthetic_data_configurations.SetTimeSlot(2); unique_ptr> synthetic_generator = DataGenerator::CreateGenerator( synthetic_data_configurations); - auto *data = synthetic_generator->CreateData(synthetic_data_configurations, + auto data = synthetic_generator->CreateData(synthetic_data_configurations, hardware, *pKernel); double *x = data->GetLocations()->GetLocationX(); @@ -252,7 +254,7 @@ void TEST_GENERATE_LOCATIONS() { REQUIRE(y[i] != 0.0); REQUIRE(z[i] != 0.0); } - delete data; + } delete pKernel; @@ -269,7 +271,7 @@ void TEST_HELPERS_FUNCTIONS() { { double lowerRange = -0.4; double higherRange = 0.4; - double uniformed_num = SyntheticGenerator::UniformDistribution(lowerRange, higherRange); + double uniformed_num = LocationGenerator::UniformDistribution(lowerRange, higherRange); REQUIRE(uniformed_num > lowerRange); REQUIRE(uniformed_num < 1); } @@ -277,9 +279,9 @@ void TEST_HELPERS_FUNCTIONS() { SECTION("Compare Uint32") { uint32_t num1 = 16; - REQUIRE(SyntheticGenerator::CompareUint64(num1, num1) == false); - REQUIRE(SyntheticGenerator::CompareUint64(num1, num1 + num1) == true); - REQUIRE(SyntheticGenerator::CompareUint64(num1 + num1, num1) == false); + REQUIRE(CompareUint64(num1, num1) == false); + REQUIRE(CompareUint64(num1, num1 + num1) == true); + REQUIRE(CompareUint64(num1 + num1, num1) == false); SyntheticGenerator::ReleaseInstance(); } } @@ -302,14 +304,14 @@ void TEST_GENERATION() { synthetic_data_configurations.GetCoresNumber(), synthetic_data_configurations.GetGPUsNumbers()); - Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create(synthetic_data_configurations.GetKernelName()); + Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create(synthetic_data_configurations.GetKernelName(), synthetic_data_configurations.GetTimeSlot()); unique_ptr> synthetic_generator = DataGenerator::CreateGenerator( synthetic_data_configurations); // Initialize the seed manually with zero, to get the first generated seeded numbers. int seed = 0; srand(seed); - auto *data = synthetic_generator->CreateData(synthetic_data_configurations, hardware, *pKernel); + auto data = synthetic_generator->CreateData(synthetic_data_configurations, hardware, *pKernel); // The expected output of the locations. vector x = {0.257389, 0.456062, 0.797269, 0.242161, 0.440742, 0.276432, 0.493965, 0.953933, 0.86952}; vector y = {0.138506, 0.238193, 0.170245, 0.579583, 0.514397, 0.752682, 0.867704, 0.610986, 0.891279}; @@ -320,7 +322,7 @@ void TEST_GENERATION() { } // Now test re-generating locations again, but without modifying seed manually which will results in completely new locations values - auto *data1 = synthetic_generator->CreateData(synthetic_data_configurations, hardware, *pKernel); + auto data1 = synthetic_generator->CreateData(synthetic_data_configurations, hardware, *pKernel); for (int i = 0; i < N; i++) { REQUIRE((data1->GetLocations()->GetLocationX()[i] - x[i]) != Catch::Approx(0.0).margin(1e-6)); REQUIRE((data1->GetLocations()->GetLocationY()[i] - y[i]) != Catch::Approx(0.0).margin(1e-6)); @@ -329,14 +331,11 @@ void TEST_GENERATION() { // Now if we modified seed again, we will get the first generated locations again. int seed_srand = 0; srand(seed_srand); - auto *data2 = synthetic_generator->CreateData(synthetic_data_configurations, hardware, *pKernel); + auto data2 = synthetic_generator->CreateData(synthetic_data_configurations, hardware, *pKernel); for (int i = 0; i < N; i++) { REQUIRE((data2->GetLocations()->GetLocationX()[i] - x[i]) == Catch::Approx(0.0).margin(1e-6)); REQUIRE((data2->GetLocations()->GetLocationY()[i] - y[i]) == Catch::Approx(0.0).margin(1e-6)); } - delete data; - delete data1; - delete data2; delete pKernel; } } diff --git a/tests/cpp-tests/data-units/CMakeLists.txt b/tests/cpp-tests/data-units/CMakeLists.txt new file mode 100644 index 00000000..2abfab94 --- /dev/null +++ b/tests/cpp-tests/data-units/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (c) 2017-2023 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.0.1 +# @author Mahmoud ElKarargy +# @date 2024-01-24 + +set(EXAGEOSTAT_TESTFILES + ${CMAKE_CURRENT_SOURCE_DIR}/TestDescriptorData.cpp + ${EXAGEOSTAT_TESTFILES} + PARENT_SCOPE + ) diff --git a/tests/cpp-tests/data-units/TestDescriptorData.cpp b/tests/cpp-tests/data-units/TestDescriptorData.cpp new file mode 100644 index 00000000..cdeb6f5f --- /dev/null +++ b/tests/cpp-tests/data-units/TestDescriptorData.cpp @@ -0,0 +1,66 @@ +// Copyright (c) 2017-2023 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 TestDescriptorData.cpp + * @brief Tests for CHAMELEON to HICMA descriptor conversion in ExaGeoStat. + * @details This test case verifies the conversion of matrix descriptors from the CHAMELEON format to the HICMA format. + * It ensures that key properties of the matrix descriptor, such as dimensions, block sizes, and grid distribution parameters, are preserved during the conversion process. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @date 2024-02-04 +**/ + +#include + +#include + +using namespace std; + +using namespace exageostat::linearAlgebra; +using namespace exageostat::common; +using namespace exageostat::configurations; +using namespace exageostat::dataunits; +using namespace exageostat::hardware; + +void TEST_CHAM_TO_HICMA_CONV(){ + + // Initialize Configuration + Configurations synthetic_data_configurations; + synthetic_data_configurations.SetProblemSize(4); + synthetic_data_configurations.SetDenseTileSize(1); + + // Initialize linear algebra solver + int p = 1; + auto hardware = ExaGeoStatHardware(EXACT_DENSE, 1, 0); + auto linearAlgebraSolver = LinearAlgebraFactory::CreateLinearAlgebraSolver(EXACT_DENSE); + linearAlgebraSolver->SetContext(hardware.GetChameleonContext()); + auto *data = new DescriptorData(); + linearAlgebraSolver->InitiateDescriptors(synthetic_data_configurations, *data, p); + + // Create CHAM descriptor and convert it to HICMA descriptor + auto *CHAM_descriptorC = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C).chameleon_desc; + auto *HICMA_descriptor = data->ConvertChameleonToHicma(CHAM_descriptorC); + + // Verify common attributes are of same value + REQUIRE(CHAM_descriptorC->m == HICMA_descriptor->m); + REQUIRE(CHAM_descriptorC->n == HICMA_descriptor->n); + REQUIRE(CHAM_descriptorC->mb == HICMA_descriptor->mb); + REQUIRE(CHAM_descriptorC->nb == HICMA_descriptor->nb); + REQUIRE(CHAM_descriptorC->bsiz == HICMA_descriptor->bsiz); + REQUIRE(CHAM_descriptorC->i == HICMA_descriptor->i); + REQUIRE(CHAM_descriptorC->j == HICMA_descriptor->j); + REQUIRE(CHAM_descriptorC->mt == HICMA_descriptor->mt); + REQUIRE(CHAM_descriptorC->nt == HICMA_descriptor->nt); + REQUIRE(CHAM_descriptorC->lm == HICMA_descriptor->lm); + REQUIRE(CHAM_descriptorC->ln == HICMA_descriptor->ln); + REQUIRE(CHAM_descriptorC->p == HICMA_descriptor->p); + REQUIRE(CHAM_descriptorC->q == HICMA_descriptor->q); + + delete data; +} + +TEST_CASE(" CHAMELEON To HICMA Converter"){ + TEST_CHAM_TO_HICMA_CONV(); +} diff --git a/tests/cpp-tests/hardware/CMakeLists.txt b/tests/cpp-tests/hardware/CMakeLists.txt new file mode 100644 index 00000000..059454b0 --- /dev/null +++ b/tests/cpp-tests/hardware/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (c) 2017-2023 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.0.1 +# @author Mahmoud ElKarargy +# @date 2024-01-24 + +set(EXAGEOSTAT_TESTFILES + ${CMAKE_CURRENT_SOURCE_DIR}/TestExaGeoStatHardware.cpp + ${EXAGEOSTAT_TESTFILES} + PARENT_SCOPE +) diff --git a/tests/cpp-tests/hardware/TestExaGeoStatHardware.cpp b/tests/cpp-tests/hardware/TestExaGeoStatHardware.cpp new file mode 100644 index 00000000..89f1459f --- /dev/null +++ b/tests/cpp-tests/hardware/TestExaGeoStatHardware.cpp @@ -0,0 +1,113 @@ + +// Copyright (c) 2017-2023 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 TestExaGeoStatHardware.cpp + * @brief Unit tests for the ExaGeoStatHardware class in the ExaGeoStat software package. + * @details This file contains Catch2 unit tests that validate the functionality of the ExaGeoStatHardware class + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @date 2024-01-24 +**/ + +#include + +#include + +using namespace exageostat::hardware; +using namespace exageostat::common; +using namespace exageostat::hardware; + +void TEST_HARDWARE_CONSTRUCTION() { + + //Initialize multiple instances of the hardware, and verify chameleon context is not null. + auto hardware_1 = ExaGeoStatHardware(EXACT_DENSE, 4, 0); + REQUIRE(hardware_1.GetChameleonContext() != nullptr); + + auto hardware_2 = ExaGeoStatHardware(DIAGONAL_APPROX, 4, 0); + REQUIRE(hardware_2.GetChameleonContext() != nullptr); + REQUIRE(hardware_1.GetChameleonContext() == hardware_2.GetChameleonContext()); + + //In case of HICMA initialize a TLR hardware and verify non-null context, + // otherwise exception is raised in case of initialization. +#ifdef USE_HICMA + auto hardware_3 = ExaGeoStatHardware(TILE_LOW_RANK, 4, 0); + REQUIRE(hardware_3.GetHicmaContext() != nullptr); + + auto hardware_4 = ExaGeoStatHardware(TILE_LOW_RANK, 4, 0); + REQUIRE(hardware_4.GetHicmaContext() != nullptr); + REQUIRE(hardware_3.GetHicmaContext() == hardware_4.GetHicmaContext()); +#else + REQUIRE_THROWS(ExaGeoStatHardware(TILE_LOW_RANK, 4, 0)); +#endif + +} + +void TEST_STATIC_CONTEXT() { + + //Initialize multiple instances of the hardware: EXACT_DENSE,DIAGONAL_APPROX ,and verify they all have same static Chameleon context. + auto hardware_1 = ExaGeoStatHardware(EXACT_DENSE, 4, 0); + auto context_hardware_1 = ExaGeoStatHardware::GetContext(EXACT_DENSE); + + auto hardware_2 = ExaGeoStatHardware(EXACT_DENSE, 1, 0); + auto context_hardware_2 = ExaGeoStatHardware::GetContext(EXACT_DENSE); + REQUIRE(context_hardware_1 == context_hardware_2); + + auto hardware_3 = ExaGeoStatHardware(DIAGONAL_APPROX, 7, 0); + auto context_hardware_3 = ExaGeoStatHardware::GetContext(DIAGONAL_APPROX); + REQUIRE(context_hardware_2 == context_hardware_3); + + auto hardware_4 = ExaGeoStatHardware(DIAGONAL_APPROX, 3, 0); + auto context_hardware_4 = ExaGeoStatHardware::GetContext(DIAGONAL_APPROX); + REQUIRE(context_hardware_3 == context_hardware_4); + + //In case of HICMA initialize multiple instances of the TLR hardware. +#ifdef USE_HICMA + // Verify they have same static HICMA context + auto hardware_5 = ExaGeoStatHardware(TILE_LOW_RANK, 4, 0); + REQUIRE(hardware_5.GetContext(TILE_LOW_RANK) != nullptr); + + auto hardware_6 = ExaGeoStatHardware(TILE_LOW_RANK, 4, 0); + REQUIRE(hardware_6.GetContext(TILE_LOW_RANK) != nullptr); + REQUIRE(hardware_5.GetContext(TILE_LOW_RANK) == hardware_6.GetContext(TILE_LOW_RANK)); + + // Verify they have same Chameleon context as the EXACT_DENSE and DIAGONAL_APPROX hardware + REQUIRE(hardware_5.GetContext(EXACT_DENSE) == hardware_6.GetContext(EXACT_DENSE)); + REQUIRE(hardware_5.GetContext(EXACT_DENSE) == hardware_1.GetContext(EXACT_DENSE)); +#endif + +} + +void TEST_CONTEXT_GETTER() { + + // Initialize multiple instances of hardware, and verify context getter results. + auto hardware_1 = ExaGeoStatHardware(EXACT_DENSE, 1, 0); + auto hardware_2 = ExaGeoStatHardware(DIAGONAL_APPROX, 1, 0); + + // Chameleon context is always non-null + REQUIRE(hardware_1.GetContext(EXACT_DENSE) != nullptr); + REQUIRE(hardware_2.GetContext(DIAGONAL_APPROX) != nullptr); + + //In case of HICMA, initialize TLR hardware. +#ifdef USE_HICMA + auto hardware_3 = ExaGeoStatHardware(TILE_LOW_RANK, 4, 0); + + // Hicma context and Chameleon context are always non-null + REQUIRE(hardware_3.GetContext(TILE_LOW_RANK) != nullptr); + REQUIRE(hardware_3.GetContext(EXACT_DENSE) != nullptr); + REQUIRE(hardware_3.GetContext(DIAGONAL_APPROX) != nullptr); +#else + // Otherwise an exception is raised + REQUIRE_THROWS(hardware_1.GetContext(TILE_LOW_RANK)); + REQUIRE_THROWS(hardware_2.GetContext(TILE_LOW_RANK)); +#endif +} + +TEST_CASE("ExaGeoStat Hardware Tests") { + TEST_HARDWARE_CONSTRUCTION(); + TEST_CONTEXT_GETTER(); + TEST_STATIC_CONTEXT(); +} + diff --git a/tests/cpp-tests/helpers/CMakeLists.txt b/tests/cpp-tests/helpers/CMakeLists.txt index 4bae3c7a..b2943b6c 100644 --- a/tests/cpp-tests/helpers/CMakeLists.txt +++ b/tests/cpp-tests/helpers/CMakeLists.txt @@ -3,15 +3,15 @@ # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy -# @author Sameh Abdulah -# @date 2023-12-08 +# @date 2024-01-24 set(EXAGEOSTAT_TESTFILES - ${CMAKE_CURRENT_SOURCE_DIR}/TestPredictionHelpers.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TestDiskWriter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TestDistanceCalculationHelpers.cpp ${EXAGEOSTAT_TESTFILES} PARENT_SCOPE - ) +) diff --git a/tests/cpp-tests/helpers/TestDiskWriter.cpp b/tests/cpp-tests/helpers/TestDiskWriter.cpp new file mode 100644 index 00000000..ee3d1450 --- /dev/null +++ b/tests/cpp-tests/helpers/TestDiskWriter.cpp @@ -0,0 +1,80 @@ + +// Copyright (c) 2017-2023 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 TestDiskWriter.cpp + * @brief Unit tests for the DiskWriter in the ExaGeoStat software package. + * @details This file contains Catch2 unit tests that validate the functionality of the class DiskWriter. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @date 2024-01-24 +**/ + +#include +#include + +#include +#include + +using namespace exageostat::dataunits; +using namespace exageostat::common; + +void TEST_3D_VECTORS_WRITING() { + // Initialize data vectors + int N = 8; + auto *location_x = new double[N]{0.193041886015106440, 0.330556191348134576, 0.181612878614480805, + 0.370473792629892440, 0.652140077821011688, 0.806332494087129037, + 0.553322652018005678, 0.800961318379491916}; + + auto *location_y = new double[N]{0.103883421072709245, 0.135790035858701447, 0.434683756771190977, + 0.400778210116731537, 0.168459601739528508, 0.105195696955825133, + 0.396398870832379624, 0.296757457846952011}; + + auto *location_z = new double[N]{1, 1, 1, 1, + 1, 1, 1, 1}; + + auto *measurements_matrix = new double[N]{-1.272336140360187606, -2.590699695867695773, 0.512142584178685967, + -0.163880452049749520, 0.313503633252489700, -1.474410682226017677, + 0.161705025505231914, 0.623389205185149065}; + + // Initialize Locations object, that will be written in file + Locations locations(N, Dimension3D); + locations.SetLocationX(*location_x, N); + locations.SetLocationY(*location_y, N); + locations.SetLocationZ(*location_z, N); + + const int p = 1; + + std::string write_path = PROJECT_SOURCE_DIR; + std::string expectedFilePath = write_path + "/synthetic_ds/SYN_" + std::to_string(N / p) + "_1"; + + // Write the data into file + exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N, p, write_path, locations); + REQUIRE(std::filesystem::exists(expectedFilePath)); + + std::ifstream file(expectedFilePath); + REQUIRE(file.is_open()); + + // Read the contents from the file + std::string line; + for (int i = 0; i < N / p; ++i) { + std::getline(file, line); + + std::ostringstream oss; + oss << std::setprecision(15) << locations.GetLocationX()[i] << ',' + << locations.GetLocationY()[i] << ',' << locations.GetLocationZ()[i] << ","<< std::setprecision(15) << measurements_matrix[i] ; + std::string expectedLine = oss.str(); + + REQUIRE(line == expectedLine); + } + + delete[] location_x; + delete[] location_y; + delete[] location_z; + delete[] measurements_matrix; +} +TEST_CASE("Disk Writer Tests"){ + TEST_3D_VECTORS_WRITING(); +} diff --git a/tests/cpp-tests/helpers/TestDistanceCalculationHelpers.cpp b/tests/cpp-tests/helpers/TestDistanceCalculationHelpers.cpp new file mode 100644 index 00000000..8a7f5e62 --- /dev/null +++ b/tests/cpp-tests/helpers/TestDistanceCalculationHelpers.cpp @@ -0,0 +1,144 @@ + +// Copyright (c) 2017-2023 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 TestDistanceCalculationHelpers.cpp + * @brief Unit tests for the DistanceCalculationHelpers.cpp in the ExaGeoStat software package. + * @details This file contains Catch2 unit tests that validate the functionality of the class DistanceCalculationHelpers. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @date 2024-01-24 +**/ + +#include +#include + +#include +#include + +using namespace exageostat::common; +using namespace exageostat::helpers; +using namespace exageostat::dataunits; + +void TEST_RADIAN_CONVERSION() { + exageostat::helpers::DistanceCalculationHelpers distance_helper; + REQUIRE(distance_helper.DegreeToRadian(0) == Catch::Approx(0.0)); + REQUIRE(distance_helper.DegreeToRadian(90) == Catch::Approx(PI / 2)); + REQUIRE(distance_helper.DegreeToRadian(180) == Catch::Approx(PI)); +} + +void TEST_CALCULATE_DISTANCE() { + + SECTION("2D - Euclidean & Haversine Distance") { + int size = 2; + + // 2D - Locations initializations + auto *location_x = new double[size]{10.0, 4.0}; + auto *location_y = new double[size]{12.0, 4.0}; + + Locations location1(size, Dimension2D); + Locations location2(size, Dimension2D); + + location1.SetLocationX(*location_x, size); + location1.SetLocationY(*location_y, size); + location2.SetLocationX(*location_x, size); + location2.SetLocationY(*location_y, size); + + int idx1 = 0; // index of x-coordinate + int idx2 = 1; // index of y-coordinate + int flagZ = 0; // 2D case + + int distanceMetric = 0; // Default - Use Euclidean distance + REQUIRE(DistanceCalculationHelpers::CalculateDistance(location1, location2, idx1, idx2, distanceMetric, + flagZ) == 10); + + distanceMetric = 1; // Use Haversine distance + auto distance_earth = DistanceCalculationHelpers::DistanceEarth(location_x[idx1], location_y[idx1], + location_x[idx2], location_y[idx2]); + REQUIRE(DistanceCalculationHelpers::CalculateDistance(location1, location2, idx1, idx2, distanceMetric, + flagZ) == distance_earth); + + delete[] location_x; + delete[] location_y; + }SECTION("3D - Euclidean & Haversine Distance") { + int size = 3; + + // 3D - Locations initializations + auto *location_x = new double[size]{10.0, 4.0}; + auto *location_y = new double[size]{12.0, 4.0}; + auto *location_z = new double[size]{1, 2}; + + Locations location1(size, Dimension3D); + Locations location2(size, Dimension3D); + + location1.SetLocationX(*location_x, size); + location1.SetLocationY(*location_y, size); + location1.SetLocationZ(*location_z, size); + + location2.SetLocationX(*location_x, size); + location2.SetLocationY(*location_y, size); + location2.SetLocationZ(*location_z, size); + + int idx1 = 0; // index of x-coordinate + int idx2 = 1; // index of y-coordinate + int flagZ = 1; // 2D case + + int distanceMetric = 0; // Use Euclidean distance + REQUIRE(DistanceCalculationHelpers::CalculateDistance(location1, location2, idx1, idx2, distanceMetric, + flagZ) == Catch::Approx(10.05).epsilon(0.01)); + + distanceMetric = 1; // Use Haversine distance + REQUIRE_THROWS( + DistanceCalculationHelpers::CalculateDistance(location1, location2, idx1, idx2, distanceMetric, + flagZ)); + + delete[] location_x; + delete[] location_y; + delete[] location_z; + } +} + +void TEST_DISTANCE_EARTH() { + SECTION("Distance between two identical points") { + + double lat = 0.1, lon = 0.2; + REQUIRE(DistanceCalculationHelpers::DistanceEarth(lat, lon, lat, lon) == Catch::Approx(0.0)); + + }SECTION("Distance between North Pole and South Pole") { + + double north_pole_Lat = 90.0, pole_Lon = 0.0; + double south_pole_Lat = -90.0; + REQUIRE(DistanceCalculationHelpers::DistanceEarth(north_pole_Lat, pole_Lon, south_pole_Lat, pole_Lon) == + Catch::Approx(EARTH_RADIUS * M_PI)); + + }SECTION("Distance between two points on the equator 90 degrees apart") { + + double equator_Lat = 0.0; + double lon1 = 0.0, lon2 = 90.0; + REQUIRE(DistanceCalculationHelpers::DistanceEarth(equator_Lat, lon1, equator_Lat, lon2) == + Catch::Approx(EARTH_RADIUS * M_PI / 2)); + + }SECTION("Distance between two arbitrary points") { + + // Arbitrary location coordinates + double location1_lat = 40.7128; + double location1_lon = -74.0060; + double location2_lat = 34.0522; + double location2_lon = -118.2437; + + // The expected distance is approximately 3940 kilometers + double expectedDistance = 3940.0; + double calculatedDistance = DistanceCalculationHelpers::DistanceEarth(location1_lat, location1_lon, + location2_lat, location2_lon); + REQUIRE(calculatedDistance == Catch::Approx(expectedDistance).epsilon(0.01)); + + } +} + +TEST_CASE("Degree to Radian Conversion") { + TEST_RADIAN_CONVERSION(); + TEST_CALCULATE_DISTANCE(); + TEST_DISTANCE_EARTH(); +} \ No newline at end of file diff --git a/tests/cpp-tests/kernels/CMakeLists.txt b/tests/cpp-tests/kernels/CMakeLists.txt index cc96f6b4..01d039c3 100644 --- a/tests/cpp-tests/kernels/CMakeLists.txt +++ b/tests/cpp-tests/kernels/CMakeLists.txt @@ -4,14 +4,13 @@ # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @date 2023-04-29 set(EXAGEOSTAT_TESTFILES ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternStationary.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternNonStationary.cpp ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestBivariateMaternFlexible.cpp ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDsigmaSquare.cpp ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestBivariateMaternParsimonious.cpp @@ -29,7 +28,6 @@ set(EXAGEOSTAT_TESTFILES ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternNonGaussian.cpp ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateExpNonGaussian.cpp ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestTrivariateMaternParsimonious.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternNonStat.cpp ${EXAGEOSTAT_TESTFILES} PARENT_SCOPE ) diff --git a/tests/cpp-tests/kernels/concrete/TestBivariateMaternFlexible.cpp b/tests/cpp-tests/kernels/concrete/TestBivariateMaternFlexible.cpp index 9ad99895..48cee8bb 100644 --- a/tests/cpp-tests/kernels/concrete/TestBivariateMaternFlexible.cpp +++ b/tests/cpp-tests/kernels/concrete/TestBivariateMaternFlexible.cpp @@ -7,7 +7,7 @@ * @brief Unit tests for the BivariateMaternFlexible kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the BivariateMaternFlexible kernel * in the ExaGeoStat software package. The tests cover the generation of data using this kernel with various configurations. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-09 @@ -49,10 +49,10 @@ void TEST_KERNEL_GENERATION_BivariateMaternFlexible() { int seed = 0; srand(seed); - exageostat::dataunits::ExaGeoStatData data; + std::unique_ptr> data; exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, data); - auto *CHAM_descriptorZ = data.GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, + auto *CHAM_descriptorZ = data->GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, exageostat::common::DESCRIPTOR_Z).chameleon_desc; auto *A = (double *) CHAM_descriptorZ->mat; // Define the expected output diff --git a/tests/cpp-tests/kernels/concrete/TestBivariateMaternParsimonious.cpp b/tests/cpp-tests/kernels/concrete/TestBivariateMaternParsimonious.cpp index 497a979b..cda682fe 100644 --- a/tests/cpp-tests/kernels/concrete/TestBivariateMaternParsimonious.cpp +++ b/tests/cpp-tests/kernels/concrete/TestBivariateMaternParsimonious.cpp @@ -8,7 +8,7 @@ * @brief Unit tests for the TestBivariateMaternParsimonious kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestBivariateMaternParsimonious kernel * in the ExaGeoStat software package. The tests cover the generation of data using this kernel with various configurations. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -50,10 +50,10 @@ void TEST_KERNEL_GENERATION_BivariateMaternParsimonious() { int seed = 0; srand(seed); - exageostat::dataunits::ExaGeoStatData data; + std::unique_ptr> data; exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, data); - auto *CHAM_descriptorZ = data.GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, + auto *CHAM_descriptorZ = data->GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, exageostat::common::DESCRIPTOR_Z).chameleon_desc; auto *A = (double *) CHAM_descriptorZ->mat; // Define the expected output diff --git a/tests/cpp-tests/kernels/concrete/TestBivariateSpacetimeMaternStationary.cpp b/tests/cpp-tests/kernels/concrete/TestBivariateSpacetimeMaternStationary.cpp index 81fde6bf..6b0d4387 100644 --- a/tests/cpp-tests/kernels/concrete/TestBivariateSpacetimeMaternStationary.cpp +++ b/tests/cpp-tests/kernels/concrete/TestBivariateSpacetimeMaternStationary.cpp @@ -8,7 +8,7 @@ * @brief Unit tests for the TestBivariateSpacetimeMaternStationary kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestBivariateSpacetimeMaternStationary kernel * in the ExaGeoStat software package. The tests cover the generation of data using this kernel with various configurations. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -41,7 +41,7 @@ void TEST_KERNEL_GENERATION_BivariateSpacetimeMaternStationary() { synthetic_data_configurations.SetInitialTheta(initial_theta); synthetic_data_configurations.SetDimension(DimensionST); - synthetic_data_configurations.SetTimeSlot(5); + synthetic_data_configurations.SetTimeSlot(3); int dts = 4; synthetic_data_configurations.SetDenseTileSize(dts); synthetic_data_configurations.SetComputation(EXACT_DENSE); @@ -51,22 +51,19 @@ void TEST_KERNEL_GENERATION_BivariateSpacetimeMaternStationary() { int seed = 0; srand(seed); - exageostat::dataunits::ExaGeoStatData data; + std::unique_ptr> data; exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, data); - auto *CHAM_descriptorZ = data.GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, - exageostat::common::DESCRIPTOR_Z).chameleon_desc; + auto *CHAM_descriptorZ = data->GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, + exageostat::common::DESCRIPTOR_Z).chameleon_desc; auto *A = (double *) CHAM_descriptorZ->mat; // Define the expected output - double expected_output_data[] = { - -1.272336, -2.516013, -1.182511, -2.512958, -1.203093, -2.548053, -1.213645, -2.511269, -1.807922, - -2.992990, -2.072972, -3.001448, -1.525724, -3.004085, -1.997874, -2.993439, -1.256771, -2.832258, - -1.022281, -2.827732, -0.924332, -2.856855, -1.363071, -2.832165, -1.680104, -3.400946, -1.685995, - -3.414854, -1.318928, -3.440336, -1.944915, -3.428945, -1.300296, -3.367150, -1.572847, -3.392844, - -1.126261, -3.392112, -1.682665, -3.394862 - }; - - for (size_t i = 0; i < N; i++) { + double expected_output_data[] = {-1.272336, -2.516013, -1.171584, -2.513616, -1.168821, -2.531118, -1.200293, + -1.960279, -1.919141, -2.005663, -2.279083, -2.006927, -0.807580, -1.719351, + -1.532754, -1.733719, -0.935139, -1.752957, 0.125841, -1.722780, -0.162095, + -1.738346, -0.866950, -1.753649}; + + for (size_t i = 0; i < N * 3 * 2; i++) { double diff = A[i] - expected_output_data[i]; REQUIRE(diff == Catch::Approx(0.0).margin(1e-6)); } diff --git a/tests/cpp-tests/kernels/concrete/TestTrivariateMaternParsimonious.cpp b/tests/cpp-tests/kernels/concrete/TestTrivariateMaternParsimonious.cpp index 5c42c4c2..4859dceb 100644 --- a/tests/cpp-tests/kernels/concrete/TestTrivariateMaternParsimonious.cpp +++ b/tests/cpp-tests/kernels/concrete/TestTrivariateMaternParsimonious.cpp @@ -8,7 +8,7 @@ * @brief Unit tests for the TestTrivariateMaternParsimonious kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestTrivariateMaternParsimonious kernel * in the ExaGeoStat software package. The tests cover the generation of data using this kernel with various configurations. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -48,10 +48,10 @@ void TEST_KERNEL_GENERATION_TrivariateMaternParsimonious() { int seed = 0; srand(seed); - exageostat::dataunits::ExaGeoStatData data; + std::unique_ptr> data; exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, data); - auto *CHAM_descriptorZ = data.GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, + auto *CHAM_descriptorZ = data->GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, exageostat::common::DESCRIPTOR_Z).chameleon_desc; auto *A = (double *) CHAM_descriptorZ->mat; // Define the expected output diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonGaussian.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonGaussian.cpp index daec5161..31fbd107 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonGaussian.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonGaussian.cpp @@ -8,7 +8,7 @@ * @brief Unit tests for the TestUnivariateMaternNonGaussian kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateMaternNonGaussian kernel * in the ExaGeoStat software package. The tests cover the generation of data using this kernel with various configurations. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -36,6 +36,12 @@ void TEST_KERNEL_GENERATION_UnivariateMaternNonGaussian() { synthetic_data_configurations.SetProblemSize(N); synthetic_data_configurations.SetKernelName("UnivariateMaternNonGaussian"); + vector lb{0.01, 0.01, -5, 0.1, -2}; + synthetic_data_configurations.SetLowerBounds(lb); + + vector ub{15, 5, 5, 5, 2, 2}; + synthetic_data_configurations.SetUpperBounds(ub); + vector initial_theta{7.0711, 1, 0, 2, 0, 0}; synthetic_data_configurations.SetInitialTheta(initial_theta); int dts = 3; @@ -46,10 +52,10 @@ void TEST_KERNEL_GENERATION_UnivariateMaternNonGaussian() { int seed = 0; srand(seed); - exageostat::dataunits::ExaGeoStatData data; + std::unique_ptr> data; exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, data); - auto *CHAM_descriptorZ = data.GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, + auto *CHAM_descriptorZ = data->GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, exageostat::common::DESCRIPTOR_Z).chameleon_desc; auto *A = (double *) CHAM_descriptorZ->mat; // Define the expected output @@ -60,7 +66,7 @@ void TEST_KERNEL_GENERATION_UnivariateMaternNonGaussian() { }; for (size_t i = 0; i < N; i++) { - double diff = A[i] - expected_output_data[i]; + double diff = A[i] - expected_output_data[i]/2; REQUIRE(diff == Catch::Approx(0.0).margin(1e-6)); } } diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonStat.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonStat.cpp deleted file mode 100644 index a7382c04..00000000 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonStat.cpp +++ /dev/null @@ -1,75 +0,0 @@ - -// Copyright (c) 2017-2023 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 TestUnivariateMaternNonStat.cpp - * @brief Unit tests for the TestUnivariateMaternNonStat kernel in the ExaGeoStat software package. - * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateMaternNonStat kernel - * in the ExaGeoStat software package. The tests cover the generation of data using this kernel with various configurations. - * @version 1.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @date 2023-05-10 -**/ - -#include -#include -#include - -using namespace std; - -using namespace exageostat::configurations; -using namespace exageostat::api; -using namespace exageostat::common; -using namespace exageostat::hardware; - -void TEST_KERNEL_GENERATION_UnivariateMaternNonStat() { - - SECTION("UnivariateMaternNonStat") - { - - // Create a new synthetic_data_configurations object with the provided command line arguments - Configurations synthetic_data_configurations; - - int N = 16; - synthetic_data_configurations.SetProblemSize(N); - synthetic_data_configurations.SetKernelName("UnivariateMaternNonStat"); - synthetic_data_configurations.SetDimension(Dimension2D); - - vector initial_theta{0.04, 1.57, 0.33, -1, 0.8, 0.1, -0.5, 0.5}; - synthetic_data_configurations.SetInitialTheta(initial_theta); - - int dts = 3; - synthetic_data_configurations.SetDenseTileSize(dts); - synthetic_data_configurations.SetComputation(EXACT_DENSE); - // initialize ExaGeoStat Hardware. - auto hardware = ExaGeoStatHardware(EXACT_DENSE, 3, 0); - - int seed = 0; - srand(seed); - exageostat::dataunits::ExaGeoStatData data; - exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, - data); - auto *CHAM_descriptorZ = data.GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, - exageostat::common::DESCRIPTOR_Z).chameleon_desc; - auto *A = (double *) CHAM_descriptorZ->mat; - // Define the expected output - double expected_output_data[] = { - -1.329875, -2.691617, 0.043584, -0.606902, -0.213657, -1.322967, - -0.281561, 0.084918, -1.152730, -1.209422, -1.776260, -0.410195, - 0.221300, 0.454534, -0.742289, 0.135949 - }; - - for (size_t i = 0; i < N; i++) { - double diff = A[i] - expected_output_data[i]; - REQUIRE(diff == Catch::Approx(0.0).margin(1e-6)); - } - } -} - -TEST_CASE("UnivariateMaternNonStat kernel test") { - TEST_KERNEL_GENERATION_UnivariateMaternNonStat(); - -} \ No newline at end of file diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonStationary.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonStationary.cpp deleted file mode 100644 index 35be6dc5..00000000 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonStationary.cpp +++ /dev/null @@ -1,13 +0,0 @@ - -// Copyright (c) 2017-2023 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 TestUnivariateMaternNonStationary.cpp - * @brief - * @version 1.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @date 2023-05-08 -**/ diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNuggetsStationary.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNuggetsStationary.cpp index da21bc33..1f43a7fd 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNuggetsStationary.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNuggetsStationary.cpp @@ -8,7 +8,7 @@ * @brief Unit tests for the TestUnivariateMaternNuggetsStationary kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateMaternNuggetsStationary kernel * in the ExaGeoStat software package. The tests cover the generation of data using this kernel with various configurations. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -48,10 +48,10 @@ void TEST_KERNEL_GENERATION_UnivariateMaternNuggetsStationary() { int seed = 0; srand(seed); - exageostat::dataunits::ExaGeoStatData data; + std::unique_ptr> data; exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, data); - auto *CHAM_descriptorZ = data.GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, + auto *CHAM_descriptorZ = data->GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, exageostat::common::DESCRIPTOR_Z).chameleon_desc; auto *A = (double *) CHAM_descriptorZ->mat; // Define the expected output diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternStationary.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternStationary.cpp index 461c0a20..a9b4777a 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternStationary.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternStationary.cpp @@ -8,7 +8,7 @@ * @brief Unit tests for the TestUnivariateMaternStationary kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateMaternStationary kernel * in the ExaGeoStat software package. The tests cover the generation of data using this kernel with various configurations. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-29 @@ -49,11 +49,11 @@ void TEST_KERNEL_GENERATION_UnivariateMaternStationary() { int seed = 0; srand(seed); - exageostat::dataunits::ExaGeoStatData data; + std::unique_ptr> data; exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, data); - auto *CHAM_descriptorZ = data.GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, + auto *CHAM_descriptorZ = data->GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, exageostat::common::DESCRIPTOR_Z).chameleon_desc; auto *A = (double *) CHAM_descriptorZ->mat; // Define the expected output diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateSpacetimeMaternStationary.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateSpacetimeMaternStationary.cpp index 365bcf7d..65147642 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateSpacetimeMaternStationary.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateSpacetimeMaternStationary.cpp @@ -8,7 +8,7 @@ * @brief Unit tests for the TestUnivariateSpacetimeMaternStationary kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateSpacetimeMaternStationary kernel * in the ExaGeoStat software package. The tests cover the generation of data using this kernel with various configurations. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -50,22 +50,18 @@ void TEST_KERNEL_GENERATION_UnivariateSpacetimeMaternStationary() { int seed = 0; srand(seed); - exageostat::dataunits::ExaGeoStatData data; + std::unique_ptr> data; exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, data); - auto *CHAM_descriptorZ = data.GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, - exageostat::common::DESCRIPTOR_Z).chameleon_desc; + auto *CHAM_descriptorZ = data->GetDescriptorData()->GetDescriptor(exageostat::common::CHAMELEON_DESCRIPTOR, + exageostat::common::DESCRIPTOR_Z).chameleon_desc; auto *A = (double *) CHAM_descriptorZ->mat; // Define the expected output - double expected_output_data[] = { - -1.272336, -2.499643, 0.241533, -0.680865, - -0.966917, -2.919659, 0.289843, -0.387418, - -1.633527, -2.982286, -0.534392, -0.453970, - -0.907212, -2.455697, -0.617580, -0.289998, - -0.755687, -3.013465, 0.547427, -0.665510 - }; - - for (size_t i = 0; i < N; i++) { + double expected_output_data[] = {-1.272336, -2.600097, -0.482699, -0.533521, 0.008692, -1.750492, -0.453709, + 0.336176, -1.573801, -1.256633, -1.817694, -0.305688, 0.627641, 0.376389, + -0.939680, 0.167822, 0.514814, -1.315864, 1.884674, -0.234791}; + + for (size_t i = 0; i < N * 5; i++) { double diff = A[i] - expected_output_data[i]; REQUIRE(diff == Catch::Approx(0.0).margin(1e-6)); } diff --git a/tests/cpp-tests/linear-algebra-solvers/CMakeLists.txt b/tests/cpp-tests/linear-algebra-solvers/CMakeLists.txt index 555e0cb7..f7afad0d 100644 --- a/tests/cpp-tests/linear-algebra-solvers/CMakeLists.txt +++ b/tests/cpp-tests/linear-algebra-solvers/CMakeLists.txt @@ -4,7 +4,7 @@ # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.0.1 # @author Mahmoud ElKarargy # @date 2023-04-06 @@ -14,7 +14,7 @@ set(EXAGEOSTAT_TESTFILES ${EXAGEOSTAT_TESTFILES} ) -if (EXAGEOSTAT_USE_HICMA) +if (USE_HICMA) list(APPEND EXAGEOSTAT_TESTFILES ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestHiCMAImplementationTLR.cpp ) diff --git a/tests/cpp-tests/linear-algebra-solvers/concrete/TestChameleonImplementationDST.cpp b/tests/cpp-tests/linear-algebra-solvers/concrete/TestChameleonImplementationDST.cpp index 4d889111..8c956b1b 100644 --- a/tests/cpp-tests/linear-algebra-solvers/concrete/TestChameleonImplementationDST.cpp +++ b/tests/cpp-tests/linear-algebra-solvers/concrete/TestChameleonImplementationDST.cpp @@ -6,7 +6,7 @@ /** * @file TestChameleonImplementationDST.cpp * @brief Unit tests for the Diagonal Super Tile computation in the ExaGeoStat software package. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-04-09 **/ @@ -34,7 +34,7 @@ using namespace exageostat::hardware; void TEST_CHAMELEON_DESCRIPTORS_VALUES_DST() { Configurations synthetic_data_configurations; - + int p = 1; SECTION("SINGLE") { // initialize Hardware. @@ -47,7 +47,7 @@ void TEST_CHAMELEON_DESCRIPTORS_VALUES_DST() { synthetic_data_configurations.SetDenseTileSize(16); auto *data = new DescriptorData(); - linearAlgebraSolver->InitiateDescriptors(synthetic_data_configurations, *data, nullptr); + linearAlgebraSolver->InitiateDescriptors(synthetic_data_configurations, *data, p, nullptr); auto *CHAM_descriptorC = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C).chameleon_desc; auto *CHAM_descriptorZ = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc; @@ -55,7 +55,7 @@ void TEST_CHAMELEON_DESCRIPTORS_VALUES_DST() { auto *CHAM_descriptorDeterminant = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_DETERMINANT).chameleon_desc; auto *CHAM_descriptorProduct = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_PRODUCT).chameleon_desc; - int N = synthetic_data_configurations.GetProblemSize() * synthetic_data_configurations.GetP(); + int N = synthetic_data_configurations.GetProblemSize(); int dts = synthetic_data_configurations.GetDenseTileSize(); int pGrid = synthetic_data_configurations.GetPGrid(); int qGrid = synthetic_data_configurations.GetQGrid(); @@ -171,7 +171,7 @@ void TEST_CHAMELEON_DESCRIPTORS_VALUES_DST() { synthetic_data_configurations.SetDenseTileSize(16); auto *data = new DescriptorData(); - linearAlgebraSolver->InitiateDescriptors(synthetic_data_configurations, *data, nullptr); + linearAlgebraSolver->InitiateDescriptors(synthetic_data_configurations, *data, p, nullptr); auto *CHAM_descriptorC = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C).chameleon_desc; auto *CHAM_descriptorZ = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc; @@ -181,7 +181,7 @@ void TEST_CHAMELEON_DESCRIPTORS_VALUES_DST() { auto *CHAM_descriptorProduct = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_PRODUCT).chameleon_desc; auto *CHAM_descriptorProduct_1 = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_PRODUCT_1).chameleon_desc; auto *CHAM_descriptorProduct_2 = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_PRODUCT_2).chameleon_desc; - int N = synthetic_data_configurations.GetProblemSize() * synthetic_data_configurations.GetP(); + int N = synthetic_data_configurations.GetProblemSize(); int dts = synthetic_data_configurations.GetDenseTileSize(); int pGrid = synthetic_data_configurations.GetPGrid(); int qGrid = synthetic_data_configurations.GetQGrid(); diff --git a/tests/cpp-tests/linear-algebra-solvers/concrete/TestChameleonImplementationDense.cpp b/tests/cpp-tests/linear-algebra-solvers/concrete/TestChameleonImplementationDense.cpp index c96b7417..a7d2c204 100644 --- a/tests/cpp-tests/linear-algebra-solvers/concrete/TestChameleonImplementationDense.cpp +++ b/tests/cpp-tests/linear-algebra-solvers/concrete/TestChameleonImplementationDense.cpp @@ -6,7 +6,7 @@ /** * @file TestChameleonImplmentationDense.cpp * @brief Unit tests for the Dense computation in the ExaGeoStat software package. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-04-06 **/ @@ -33,7 +33,7 @@ using namespace exageostat::hardware; void TEST_CHAMELEON_DESCRIPTORS_VALUES() { Configurations synthetic_data_configurations; - + int p = 1; SECTION("SINGLE") { @@ -47,7 +47,7 @@ void TEST_CHAMELEON_DESCRIPTORS_VALUES() { synthetic_data_configurations.SetDenseTileSize(1); auto *data = new DescriptorData(); - linearAlgebraSolver->InitiateDescriptors(synthetic_data_configurations, *data, nullptr); + linearAlgebraSolver->InitiateDescriptors(synthetic_data_configurations, *data, p, nullptr); auto *CHAM_descriptorC = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C).chameleon_desc; auto *CHAM_descriptorZ = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc; @@ -55,7 +55,7 @@ void TEST_CHAMELEON_DESCRIPTORS_VALUES() { auto *CHAM_descriptorDeterminant = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_DETERMINANT).chameleon_desc; auto *CHAM_descriptorProduct = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_PRODUCT).chameleon_desc; - int N = synthetic_data_configurations.GetProblemSize() * synthetic_data_configurations.GetP(); + int N = synthetic_data_configurations.GetProblemSize(); int dts = synthetic_data_configurations.GetDenseTileSize(); int pGrid = synthetic_data_configurations.GetPGrid(); int qGrid = synthetic_data_configurations.GetQGrid(); @@ -171,7 +171,7 @@ void TEST_CHAMELEON_DESCRIPTORS_VALUES() { synthetic_data_configurations.SetDenseTileSize(8); auto *data = new DescriptorData(); - linearAlgebraSolver->InitiateDescriptors(synthetic_data_configurations, *data, nullptr); + linearAlgebraSolver->InitiateDescriptors(synthetic_data_configurations, *data, p, nullptr); auto *CHAM_descriptorC = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C).chameleon_desc; auto *CHAM_descsubC11 = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C11).chameleon_desc; @@ -187,7 +187,7 @@ void TEST_CHAMELEON_DESCRIPTORS_VALUES() { auto *CHAM_descriptorProduct_1 = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_PRODUCT_1).chameleon_desc; auto *CHAM_descriptorProduct_2 = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_PRODUCT_2).chameleon_desc; - int N = synthetic_data_configurations.GetProblemSize() * synthetic_data_configurations.GetP(); + int N = synthetic_data_configurations.GetProblemSize(); int dts = synthetic_data_configurations.GetDenseTileSize(); int pGrid = synthetic_data_configurations.GetPGrid(); int qGrid = synthetic_data_configurations.GetQGrid(); diff --git a/tests/cpp-tests/linear-algebra-solvers/concrete/TestHiCMAImplementationTLR.cpp b/tests/cpp-tests/linear-algebra-solvers/concrete/TestHiCMAImplementationTLR.cpp index 00f1f51d..9d0c7877 100644 --- a/tests/cpp-tests/linear-algebra-solvers/concrete/TestHiCMAImplementationTLR.cpp +++ b/tests/cpp-tests/linear-algebra-solvers/concrete/TestHiCMAImplementationTLR.cpp @@ -6,7 +6,7 @@ /** * @file TestHiCMAImplementationTLR.cpp * @brief Unit tests for the Tile Low Rank computation in the ExaGeoStat software package. - * @version 1.0.0 + * @version 1.0.1 * @author Mahmoud ElKarargy * @date 2023-04-09 **/ @@ -52,14 +52,14 @@ void TEST_HICMA_DESCRIPTORS_VALUES_TLR() { auto hardware = ExaGeoStatHardware(TILE_LOW_RANK, 1, 0); synthetic_data_configurations.SetApproximationMode(1); - exageostat::dataunits::ExaGeoStatData data; + std::unique_ptr> data; exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, data); exageostat::api::ExaGeoStat::ExaGeoStatDataModeling(hardware, synthetic_data_configurations, data); - auto *HICMA_descriptorC = data.GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, DESCRIPTOR_C).hicma_desc; + auto *HICMA_descriptorC = data->GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, DESCRIPTOR_C).hicma_desc; int approximationMode = synthetic_data_configurations.GetApproximationMode(); - int N = synthetic_data_configurations.GetProblemSize() * synthetic_data_configurations.GetP(); + int N = synthetic_data_configurations.GetProblemSize(); int lts = synthetic_data_configurations.GetLowTileSize(); int pGrid = synthetic_data_configurations.GetPGrid(); int qGrid = synthetic_data_configurations.GetQGrid(); @@ -86,12 +86,12 @@ void TEST_HICMA_DESCRIPTORS_VALUES_TLR() { // initialize Hardware. auto hardware = ExaGeoStatHardware(TILE_LOW_RANK, 1, 0); - exageostat::dataunits::ExaGeoStatData data; + std::unique_ptr> data; exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, data); exageostat::api::ExaGeoStat::ExaGeoStatDataModeling(hardware, synthetic_data_configurations, data); - int N = synthetic_data_configurations.GetProblemSize() * synthetic_data_configurations.GetP(); + int N = synthetic_data_configurations.GetProblemSize(); int lts = synthetic_data_configurations.GetLowTileSize(); int pGrid = synthetic_data_configurations.GetPGrid(); int qGrid = synthetic_data_configurations.GetQGrid(); @@ -101,15 +101,15 @@ void TEST_HICMA_DESCRIPTORS_VALUES_TLR() { int maxRank = synthetic_data_configurations.GetMaxRank(); string actualObservationsFilePath = synthetic_data_configurations.GetActualObservationsFilePath(); - auto *HICMA_descriptorZ = data.GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, DESCRIPTOR_Z).hicma_desc; - auto *HICMA_descriptorZcpy = data.GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, + auto *HICMA_descriptorZ = data->GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, DESCRIPTOR_Z).hicma_desc; + auto *HICMA_descriptorZcpy = data->GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, DESCRIPTOR_Z_COPY).hicma_desc; - auto *HICMA_descriptorDeterminant = data.GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, + auto *HICMA_descriptorDeterminant = data->GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, DESCRIPTOR_DETERMINANT).hicma_desc; - auto *HICMA_descriptorCD = data.GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, DESCRIPTOR_CD).hicma_desc; - auto *HICMA_descriptorCUV = data.GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, + auto *HICMA_descriptorCD = data->GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, DESCRIPTOR_CD).hicma_desc; + auto *HICMA_descriptorCUV = data->GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, DESCRIPTOR_CUV).hicma_desc; - auto *HICMA_descriptorCrk = data.GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, + auto *HICMA_descriptorCrk = data->GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, DESCRIPTOR_CRK).hicma_desc; // Descriptor CD. diff --git a/tests/cpp-tests/prediction/CMakeLists.txt b/tests/cpp-tests/prediction/CMakeLists.txt new file mode 100644 index 00000000..00fd6916 --- /dev/null +++ b/tests/cpp-tests/prediction/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright (c) 2017-2023 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.0.1 +# @author Mahmoud ElKarargy +# @date 2024-01-24 + +set(EXAGEOSTAT_TESTFILES + + ${CMAKE_CURRENT_SOURCE_DIR}/TestPrediction.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TestPredictionHelpers.cpp + + ${EXAGEOSTAT_TESTFILES} + PARENT_SCOPE +) + diff --git a/tests/cpp-tests/prediction/TestPrediction.cpp b/tests/cpp-tests/prediction/TestPrediction.cpp new file mode 100644 index 00000000..98455d5a --- /dev/null +++ b/tests/cpp-tests/prediction/TestPrediction.cpp @@ -0,0 +1,198 @@ + +// Copyright (c) 2017-2023 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 TestPrediction.cpp + * @brief Unit tests for the TestPrediction class in the ExaGeoStat software package. + * @details This file contains Catch2 unit tests that validate the functionality of the TestPrediction class + * @version 1.0.0 + * @author Mahmoud ElKarargy + * @date 2024-1-18 +**/ + +#include + +#include + +using namespace std; + +using namespace exageostat::common; +using namespace exageostat::configurations; +using namespace exageostat::hardware; +using namespace exageostat::prediction; + +void TEST_PREDICTION_MISSING_DATA() { + + //Init configuration + Configurations configurations; + configurations.SetUnknownObservationsNb(4); + int N = 16; + configurations.SetProblemSize(N); + configurations.SetKernelName("UnivariateMaternStationary"); + int dts = 8; + + configurations.SetDenseTileSize(dts); + configurations.SetComputation(EXACT_DENSE); + configurations.SetMaxMleIterations(3); + configurations.SetTolerance(pow(10, -4)); + + vector lb{0.1, 0.1, 0.1}; + configurations.SetLowerBounds(lb); + configurations.SetStartingTheta(lb); + vector ub{5, 5, 5}; + configurations.SetUpperBounds(ub); + vector initial_theta{1, 0.1, 0.5}; + configurations.SetInitialTheta(initial_theta); + + + auto hardware = ExaGeoStatHardware(EXACT_DENSE, configurations.GetCoresNumber(), configurations.GetGPUsNumbers()); + std::unique_ptr> data = std::make_unique>( + configurations.GetProblemSize(), configurations.GetDimension()); + + auto *z_matrix = new double[N]{-1.272336140360187606, -2.590699695867695773, 0.512142584178685967, + -0.163880452049749520, 0.313503633252489700, -1.474410682226017677, + 0.161705025505231914, 0.623389205185149065, -1.341858445399783495, + -1.054282062428600009, -1.669383221392507943, 0.219170645803740793, + 0.971213790000161170, 0.538973474182433021, -0.752828466476077041, + 0.290822066007430102}; + //creating locations x and y. + auto *location_x = new double[N]{0.193041886015106440, 0.330556191348134576, 0.181612878614480805, + 0.370473792629892440, 0.652140077821011688, 0.806332494087129037, + 0.553322652018005678, 0.800961318379491916, 0.207324330510414295, + 0.347951476310368490, 0.092042420080872822, 0.465445944914930965, + 0.528267338063630132, 0.974792095826657490, 0.552452887769893985, + 0.877592126344701295}; + auto *location_y = new double[N]{0.103883421072709245, 0.135790035858701447, 0.434683756771190977, + 0.400778210116731537, 0.168459601739528508, 0.105195696955825133, + 0.396398870832379624, 0.296757457846952011, 0.564507515068284116, + 0.627679865720607300, 0.928648813611047563, 0.958236057068741931, + 0.573571374074921758, 0.568657969024185528, 0.935835812924391552, + 0.942824444953078489}; + + data->GetLocations()->SetLocationX(*location_x, N); + data->GetLocations()->SetLocationY(*location_y, N); + + SECTION("Test Prediction - MSPE ") + { + configurations.SetIsIDW(false); + configurations.SetIsMLOEMMOM(false); + configurations.SetIsFisher(false); + configurations.SetIsMSPE(true); + + vector estimated_theta{0.9, 0.09, 0.4}; + configurations.SetEstimatedTheta(estimated_theta); + + Prediction predictor; + + // Register and create a kernel object + exageostat::kernels::Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create( + configurations.GetKernelName(), + configurations.GetTimeSlot()); + + // Add the data prediction arguments. + configurations.InitializeDataPredictionArguments(); + predictor.PredictMissingData(hardware, data, configurations, z_matrix, *pKernel); + + REQUIRE(exageostat::results::Results::GetInstance()->GetMSPEError()== Catch::Approx(0.552448)); + delete pKernel; + } + SECTION("Test Prediction - IDW ") { + configurations.SetIsMLOEMMOM(false); + configurations.SetIsFisher(false); + configurations.SetIsMSPE(false); + configurations.SetIsIDW(true); + + vector estimated_theta{0.9, 0.09, 0.4}; + configurations.SetEstimatedTheta(estimated_theta); + + Prediction predictor; + + std::vector idw_error={ 1.18856255, 1.25725881, 1.11986628 }; + + // Register and create a kernel object + exageostat::kernels::Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create( + configurations.GetKernelName(), + configurations.GetTimeSlot()); + // Add the data prediction arguments. + configurations.InitializeDataPredictionArguments(); + predictor.PredictMissingData(hardware, data, configurations, z_matrix, *pKernel); + for(int i =0;i<3;i++){ + REQUIRE(exageostat::results::Results::GetInstance()->GetIDWError()[i] == Catch::Approx(idw_error[i])); + } + delete pKernel; + } + SECTION("Test Prediction - MLOE_MMOM ") { + configurations.SetIsMSPE(false); + configurations.SetIsIDW(false); + configurations.SetIsMLOEMMOM(true); + configurations.SetIsFisher(false); + + vector estimated_theta{0.9, 0.09, 0.4}; + configurations.SetEstimatedTheta(estimated_theta); + + Prediction predictor; + // Register and create a kernel object + exageostat::kernels::Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create( + configurations.GetKernelName(), + configurations.GetTimeSlot()); + // Add the data prediction arguments. + configurations.InitializeDataPredictionArguments(); + predictor.PredictMissingData(hardware, data, configurations, z_matrix, *pKernel); + REQUIRE(exageostat::results::Results::GetInstance()->GetMLOE() == Catch::Approx(0.004467).margin(0.001)); + REQUIRE(exageostat::results::Results::GetInstance()->GetMMOM() == Catch::Approx(-0.0812376).margin(0.001)); + + + vector new_estimated_theta1{1, 0.1, 0.5}; + configurations.SetEstimatedTheta(new_estimated_theta1); + // Add the data prediction arguments. + configurations.InitializeDataPredictionArguments(); + predictor.PredictMissingData(hardware, data, configurations, z_matrix, *pKernel); + REQUIRE(exageostat::results::Results::GetInstance()->GetMLOE() == Catch::Approx(0).margin(0.001)); + REQUIRE(exageostat::results::Results::GetInstance()->GetMMOM() == Catch::Approx(0).margin(0.001)); + delete pKernel; + } + + SECTION("Test Prediction - FISHER") { + configurations.SetIsMSPE(false); + configurations.SetIsIDW(false); + configurations.SetIsMLOEMMOM(false); + configurations.SetIsFisher(true); + + vector new_estimated_theta{0.9, 0.09, 0.4}; + configurations.SetEstimatedTheta(new_estimated_theta); + Prediction predictor; + // Register and create a kernel object + exageostat::kernels::Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create( + configurations.GetKernelName(), + configurations.GetTimeSlot()); + // Add the data prediction arguments. + configurations.InitializeDataPredictionArguments(); + predictor.PredictMissingData(hardware, data, configurations, z_matrix, *pKernel); + + REQUIRE(exageostat::results::Results::GetInstance()->GetFisher00() == Catch::Approx(0.104589)); + REQUIRE(exageostat::results::Results::GetInstance()->GetFisher11() == Catch::Approx(0.187355)); + REQUIRE(exageostat::results::Results::GetInstance()->GetFisher22() == Catch::Approx(10.556483)); + delete pKernel; + } + SECTION("Test Prediction - Exception"){ + vector new_estimated_theta{-1, -1, -1}; + configurations.SetEstimatedTheta(new_estimated_theta); + Prediction predictor; + // Register and create a kernel object + configurations.SetIsMLOEMMOM(true); + exageostat::kernels::Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create( + configurations.GetKernelName(), + configurations.GetTimeSlot()); + REQUIRE_THROWS(predictor.PredictMissingData(hardware, data, configurations, z_matrix, *pKernel)); + delete pKernel; + } + delete[] location_x; + delete[] location_y; + delete[] z_matrix; +} + +TEST_CASE("Test Predictions") { + TEST_PREDICTION_MISSING_DATA(); +} \ No newline at end of file diff --git a/tests/cpp-tests/helpers/TestPredictionHelpers.cpp b/tests/cpp-tests/prediction/TestPredictionHelpers.cpp similarity index 99% rename from tests/cpp-tests/helpers/TestPredictionHelpers.cpp rename to tests/cpp-tests/prediction/TestPredictionHelpers.cpp index b69b45fe..eca6c9e3 100644 --- a/tests/cpp-tests/helpers/TestPredictionHelpers.cpp +++ b/tests/cpp-tests/prediction/TestPredictionHelpers.cpp @@ -4,7 +4,7 @@ // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** - * @file TestPrediction.cpp + * @file TestPredictionHelpers.cpp * @brief Unit tests for the TestPrediction class in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestPrediction class * @version 1.0.0 diff --git a/tests/cpp-tests/results/CMakeLists.txt b/tests/cpp-tests/results/CMakeLists.txt new file mode 100644 index 00000000..2be16bf6 --- /dev/null +++ b/tests/cpp-tests/results/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (c) 2017-2023 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.0.1 +# @author Mahmoud ElKarargy +# @date 2024-01-24 + +set(EXAGEOSTAT_TESTFILES + ${CMAKE_CURRENT_SOURCE_DIR}/TestResults.cpp + ${EXAGEOSTAT_TESTFILES} + PARENT_SCOPE +) diff --git a/tests/cpp-tests/results/TestResults.cpp b/tests/cpp-tests/results/TestResults.cpp new file mode 100644 index 00000000..72c4da1c --- /dev/null +++ b/tests/cpp-tests/results/TestResults.cpp @@ -0,0 +1,59 @@ +// Copyright (c) 2017-2023 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 TestResults.cpp + * @brief Unit tests for the Results class in the ExaGeoStat software package. + * @details This file contains Catch2 unit tests that validate the functionality of the Results class + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @date 2024-01-24 +**/ + +#include + +#include + +using namespace exageostat::results; + +void TEST_SINGLETON_RESULTS() { + //Test singleton instance of results + auto results1 = Results::GetInstance(); + auto results2 = Results::GetInstance(); + REQUIRE(results1 == results2); +} + +void TEST_SETTERS_AND_GETTERS() { + + auto results_instacne = Results::GetInstance(); + + SECTION("Total Modeling Execution Time Setter/Getter") { + results_instacne->SetTotalModelingExecutionTime(1.0); + REQUIRE(results_instacne->GetTotalModelingExecutionTime() == 1.0); + + }SECTION("Total Modeling Flops Setter/Getter") { + results_instacne->SetTotalModelingFlops(1.0); + REQUIRE(results_instacne->GetTotalModelingFlops() == 1.0); + + }SECTION("Avg Modeling Execution Time Setter/Getter") { + REQUIRE_THROWS(results_instacne->GetAverageModelingExecutionTime()); + + results_instacne->SetMLEIterations(2.0); + results_instacne->SetTotalModelingExecutionTime(4.0); + REQUIRE(results_instacne->GetAverageModelingExecutionTime() == 2.0); + + }SECTION("Avg Modeling Flops Setter/Getter") { + results_instacne->SetMLEIterations(0); + REQUIRE_THROWS(results_instacne->GetAverageModelingFlops()); + + results_instacne->SetMLEIterations(2.0); + results_instacne->SetTotalModelingFlops(4.0); + REQUIRE(results_instacne->GetAverageModelingFlops() == 2.0); + } +} + +TEST_CASE("Test Results") { + TEST_SINGLETON_RESULTS(); + TEST_SETTERS_AND_GETTERS(); +} diff --git a/tests/heavy-tests/CMakeLists.txt b/tests/heavy-tests/CMakeLists.txt new file mode 100644 index 00000000..b3feac02 --- /dev/null +++ b/tests/heavy-tests/CMakeLists.txt @@ -0,0 +1,14 @@ + +# Copyright (c) 2017-2023 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.0.1 +# @author Mahmoud ElKarargy +# @date 2023-12-20 + +enable_testing() +add_executable(exageostat-heavy-tests ${CMAKE_CURRENT_SOURCE_DIR}/HeavyTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ExamplesTests.cpp) +target_link_libraries(exageostat-heavy-tests Catch2::Catch2WithMain ${PROJECT_NAME}_INTERFACE) +catch_discover_tests(exageostat-heavy-tests) \ No newline at end of file diff --git a/tests/heavy-tests/ExamplesTests.cpp b/tests/heavy-tests/ExamplesTests.cpp new file mode 100644 index 00000000..df7133f1 --- /dev/null +++ b/tests/heavy-tests/ExamplesTests.cpp @@ -0,0 +1,97 @@ + +// Copyright (c) 2017-2023 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 TestExaGeoStatApi.cpp + * @brief Test suite for the ExaGeoStat APIs data generation functionality. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @date 2023-12-26 +**/ + +#include +#include + +#include + +using namespace std; +using namespace std::filesystem; + +using namespace exageostat::configurations; +using namespace exageostat::dataunits; +using namespace exageostat::api; + +TEST_CASE("EXAMPLES") { + + // Specify the examples path + path currentPath = current_path().parent_path().parent_path() / "examples"; + + SECTION("Configuration"){ + path configurations_example = currentPath / "configurations/Example_Configurations "; + string arguments_string = "--N=10 --dts=8 --kernel=univariate_matern_stationary"; + cout << "Running Configurations example with arguments: " + arguments_string << endl << flush; + + std::string fullCommand = std::string(configurations_example) + " " + arguments_string; + if (std::system(fullCommand.c_str())) { + throw runtime_error("This test failed " + fullCommand); + } + } + SECTION("Synthetic Data Generation"){ + path synthetic_data_example = currentPath / "data-generators/Example_Synthetic_Data_Generation"; + string arguments_string = "--N=16 --dts=8 --kernel=univariate_matern_stationary --dimension=2d --computation=exact --itheta=1:0.1:0.5 --ub=5:5:5 --lb=0.1:0.1:0.1"; + cout << "Running synthetic locations example with arguments: " + arguments_string << endl << flush; + + std::string fullCommand = std::string(synthetic_data_example) + " " + arguments_string; + if (std::system(fullCommand.c_str())) { + throw runtime_error("This test failed " + fullCommand); + } + } + currentPath = currentPath / "end-to-end"; + SECTION("Data Generation Module"){ + path data_generation_example = currentPath / "Example_Data_Generation"; + string arguments_string = "--N=32 --dts=8 --kernel=univariate_matern_stationary --dimension=3D --computation=diagonal_approx --itheta=1:0.1:0.5 --ub=5:5:5 --lb=0.1:0.1:0.1"; + cout << "Running Data Generation Module example with arguments: " + arguments_string << endl << flush; + + std::string fullCommand = std::string(data_generation_example) + " " + arguments_string; + if (std::system(fullCommand.c_str())) { + throw runtime_error("This test failed " + fullCommand); + } + } + SECTION("Data Modeling Module"){ + path data_modeling_example = currentPath / "Example_Data_Modeling"; +#ifdef USE_HICMA + string arguments_string = "--N=16 --dts=8 --lts=8 --kernel=univariate_matern_stationary --dimension=2D --computation=tlr --itheta=1:0.1:0.5 --ub=5:5:5 --lb=0.1:0.1:0.1 --max_mle_iterations=3 --tolerance=10 --max_rank=500"; +#else + string arguments_string = "--N=16 --dts=8 --kernel=univariate_matern_stationary --computation=exact --itheta=1:0.1:0.5 --ub=5:5:5 --lb=0.1:0.1:0.1 --max_mle_iterations=3 --tolerance=10"; +#endif + cout << "Running Data Modeling example with arguments: " + arguments_string << endl << flush; + std::string fullCommand = std::string(data_modeling_example) + " " + arguments_string; + if (std::system(fullCommand.c_str())) { + throw runtime_error("This test failed " + fullCommand); + } + } + SECTION("Data Prediction Module"){ + path data_prediction_example = currentPath / "Example_Data_Prediction"; + + string arguments_string = "--N=16 --dts=8 --kernel=univariate_matern_stationary --computation=exact --itheta=1:0.1:0.5 --ub=5:5:5 --lb=0.1:0.1:0.1 --Zmiss=10 --mspe --fisher --mloe_mmom --etheta=1.1:0.1:0.5"; + cout << "Running Data Prediction example with arguments: " + arguments_string << endl << flush; + + std::string fullCommand = std::string(data_prediction_example) + " " + arguments_string; + if (std::system(fullCommand.c_str())) { + throw runtime_error("This test failed " + fullCommand); + } + } + SECTION("Data Generation and Modeling"){ + path data_generation_modeling_example = currentPath / "Example_Data_Generation_and_Modeling"; + + string arguments_string = "--N=16 --dts=8 --kernel=univariate_matern_stationary --computation=exact --itheta=1:0.1:0.5 --ub=5:5:5 --lb=0.1:0.1:0.1 --max_mle_iterations=2 --tolerance=4 --etheta=1.1:?:0.5"; + cout << "Running Data data generation and modeling example with arguments: " + arguments_string << endl << flush; + + std::string fullCommand = std::string(data_generation_modeling_example) + " " + arguments_string; + if (std::system(fullCommand.c_str())) { + throw runtime_error("This test failed " + fullCommand); + } + } +} diff --git a/tests/heavy-tests/HeavyTests.cpp b/tests/heavy-tests/HeavyTests.cpp new file mode 100644 index 00000000..bb3f23a3 --- /dev/null +++ b/tests/heavy-tests/HeavyTests.cpp @@ -0,0 +1,253 @@ + +// Copyright (c) 2017-2023 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 TestExaGeoStatApi.cpp + * @brief Test suite for the ExaGeoStat APIs data generation functionality. + * @version 1.0.1 + * @author Mahmoud ElKarargy + * @date 2023-12-20 +**/ + +#include +#include +#include +#ifdef USE_CUDA +#include +#endif + +#include + +#include +#include + +using namespace std; + +using namespace exageostat::configurations; +using namespace exageostat::dataunits; +using namespace exageostat::api; +using namespace exageostat::kernels; + +void GenerateCommandLineArguments(const string &aKernelName, const string &aComputation, vector &aDimensions, + const string &aPrecision, vector &arguments_vector, + const string &aDistanceType) { + + // Search for the substring "TimeSpace" in the kernel name, As ST dimension only works with kernels having Spacetime in their name. + // This is a required convention described in the user manual + size_t found = aKernelName.find("Spacetime"); + // Check if the substring was found + if (found != std::string::npos) { + aDimensions = {"ST"}; + } else { + aDimensions = {"2D", "3D"}; + } + + // Set up a random number generator + random_device rd; + mt19937 gen(rd()); + int LOWER_SIZE = 5; + int MULTIPLICATION = 5; + int lts = INT16_MAX; + uniform_int_distribution problem_size_distribution(LOWER_SIZE, LOWER_SIZE * MULTIPLICATION); + int max_threads_size = static_cast(std::thread::hardware_concurrency()); + uniform_int_distribution cpu_size_distribution(1, max_threads_size - 1); + uniform_int_distribution max_iteration_distribution(1, 4); + uniform_int_distribution band_distribution(1, 6); + uniform_int_distribution tolerance_distribution(1, 5); + uniform_int_distribution max_rank_distribution(200, 600); + uniform_int_distribution seed_distribution(0, 3); + + int N_value = problem_size_distribution(gen); + + if (aComputation == "tlr") { + uniform_int_distribution lts_distribution(LOWER_SIZE, N_value); + lts = lts_distribution(gen); + N_value = lts * lts; + if (aKernelName.find("Bivariate") != string::npos || aKernelName.find("Trivariate") != string::npos) { + lts = 18; + } + arguments_vector.push_back("--lts=" + to_string(lts)); + } + + // tile size need to be smaller than N or lts in case of HiCMA. + uniform_int_distribution dts_distribution(LOWER_SIZE, min(N_value, lts)); + int dts = dts_distribution(gen); + + if (aKernelName.find("Bivariate") != string::npos || aKernelName.find("Trivariate") != string::npos) { + dts = 18; + N_value = 162; + } + if (aKernelName.find("Trivariate") != string::npos) { + N_value = 108; + } + arguments_vector.push_back("--dts=" + to_string(dts)); + arguments_vector.push_back("--N=" + to_string(N_value)); + + uniform_int_distribution zMiss_distribution(2, min(N_value / 2, 100)); + // Create a kernel object to get the number of parameters for each kernel. + Kernel *pKernel = exageostat::plugins::PluginRegistry>::Create(aKernelName, 1); + int param_number = pKernel->GetParametersNumbers(); + delete pKernel; + + string initial_theta_arguments, lb_arguments, ub_arguments; + int zmiss; + zmiss = zMiss_distribution(gen); + if (aKernelName.find("Bivariate") != string::npos) { + do { + zmiss = zMiss_distribution(gen); + } while (zmiss % 2 != 0); + } + + if (aKernelName == "BivariateMaternFlexible") { + initial_theta_arguments = "0.3:0.6:0.01:0.3:0.9:0.9:0.05:0.3:1.5:0.9:0.99"; + lb_arguments = "0.01:0.01:0.01:0.01:0.01:0.01:0.01:0.01:0.01:0.01:0.01"; + ub_arguments = "50:50:50:50:50:50:50:50:50:50:50"; + } else if (aKernelName == "BivariateMaternParsimonious") { + initial_theta_arguments = "1:1:0.1:0.5:0.5:0.1"; + lb_arguments = "0.1:0.1:0.1:0.1:0.1:0.1"; + ub_arguments = "5:5:5:5:5:5"; + } else if (aKernelName == "BivariateSpacetimeMaternStationary" || aKernelName == "TrivariateMaternParsimonious") { + initial_theta_arguments = "1:1:0.1:0.5:0.5:0.1:0:0:0:0"; + lb_arguments = "0.1:0.1:0.1:0.1:0.1:0.1:0.1:0.1:0.1:0.1"; + ub_arguments = "5:5:5:5:5:5:5:5:5:5"; + } else { + uniform_real_distribution initial_theta_distribution(0.01, 2); + // Upper bond need to be larger than the initial theta + uniform_real_distribution ub_distribution(2, 5); + + for (int n = 0; n < param_number; n++) { + double initial_theta_value = initial_theta_distribution(gen); + initial_theta_arguments += to_string(initial_theta_value); + double lb_temp; + do { + lb_temp = initial_theta_distribution(gen); + } while (lb_temp >= initial_theta_value); + lb_arguments += to_string(lb_temp); + ub_arguments += to_string(ub_distribution(gen)); + if (n < param_number - 1) { + initial_theta_arguments += ":"; + ub_arguments += ":"; + lb_arguments += ":"; + } + } + } + + arguments_vector.push_back("--cores=" + to_string(cpu_size_distribution(gen))); +#ifdef USE_CUDA + int nDevices; + cudaGetDeviceCount(&nDevices); + uniform_int_distribution gpu_size_distribution(1, nDevices); + arguments_vector.push_back("--gpus=" + to_string(gpu_size_distribution(gen))); +#endif + + arguments_vector.push_back("--kernel=" + aKernelName); + arguments_vector.push_back("--computation=" + aComputation); + arguments_vector.push_back("--precision=" + aPrecision); + arguments_vector.push_back("--initial_theta=" + initial_theta_arguments); + arguments_vector.push_back("--ub=" + ub_arguments); + arguments_vector.push_back("--lb=" + lb_arguments); + arguments_vector.push_back("--max_mle_iterations=" + to_string(max_iteration_distribution(gen))); + arguments_vector.push_back("--tolerance=" + to_string(tolerance_distribution(gen))); + arguments_vector.push_back("--max_rank=" + to_string(max_rank_distribution(gen))); + arguments_vector.push_back("--band=" + to_string(band_distribution(gen))); + arguments_vector.push_back("--ZMiss=" + to_string(zmiss)); + arguments_vector.push_back("--seed=" + to_string(seed_distribution(gen))); + arguments_vector.emplace_back("--idw"); + arguments_vector.emplace_back("--distance_metric=" + aDistanceType); + if (aKernelName.find("Bivariate") == string::npos && aKernelName.find("Trivariate") == string::npos) { + arguments_vector.emplace_back("--fisher"); + } + if (aKernelName.find("Trivariate") == string::npos) { + arguments_vector.emplace_back("--mspe"); + arguments_vector.emplace_back("--mloe-mmom"); + } +} + +TEST_CASE("END-TO-END") { + + // Add all the possible combination of code. + vector kernels_vector = { + "BivariateMaternFlexible", + "BivariateMaternParsimonious", + "BivariateSpacetimeMaternStationary", + "TrivariateMaternParsimonious", + "UnivariateExpNonGaussian", + "UnivariateMaternNonGaussian", + "UnivariateMaternNuggetsStationary", + "UnivariateMaternStationary", + "UnivariateSpacetimeMaternStationary" + }; + + vector computation_vector = {"exact", "diag_approx"}; +#ifdef USE_HICMA + computation_vector.emplace_back("tlr"); +#endif + vector dimensions_vector; + vector precision_vector = {"single", "double"}; + vector distance_vector = {"eg", "gcd"}; + + size_t combination_number = 1; + size_t number_of_iterations = 1; + for (int i = 0; i < number_of_iterations; i++) { + cout << "**** END-TO_END TESTS -- ITERATION NUMBER (" << i + 1 << ") ****" << endl; + // Generate combinations. + for (const auto ¤t_kernel: kernels_vector) { + for (const auto &computation: computation_vector) { + for (const auto &precision: precision_vector) { + for (const auto &distance_type: distance_vector) { + vector arguments_vector; + // This helper function will fill the arguments vector with the software arguments commands + GenerateCommandLineArguments(current_kernel, computation, dimensions_vector, precision, + arguments_vector, distance_type); + // Generate combination of dimensions. + for (const auto &dimension: dimensions_vector) { + // Add the dimension into the arguments vector + arguments_vector.push_back("--dimension=" + dimension); + + // Great Circle (GC) distance is only valid for 2D! + if (distance_type == "gcd" && (dimension == "3D" || dimension == "ST")) { + continue; + } + if (dimension == "ST" && computation == "tlr") { + continue; + } + if (dimension == "ST") { + random_device rd; + mt19937 gen(rd()); + uniform_int_distribution time_slot_distribution(1, 5); + arguments_vector.push_back("--time_slot=" + to_string(time_slot_distribution(gen))); + } + + string arguments_string; + for (const auto &j: arguments_vector) { + arguments_string += " " + j; + } + + cout << "(" << combination_number + << ") Testing the software with arguments: " + arguments_string << endl << flush; + + // Specify the executable path as the first argument + std::filesystem::path currentPath = + std::filesystem::current_path().parent_path().parent_path() / + "examples/end-to-end/Example_Data_Generation_Modeling_and_Prediction"; + std::string fullCommand = std::string(currentPath) + arguments_string; + if (std::system(fullCommand.c_str())) { + throw runtime_error("This test failed " + fullCommand); + } + + // To remove the previous dimension. + arguments_vector.pop_back(); + if (dimension == "ST") { + // To remove the time slot. + arguments_vector.pop_back(); + } + combination_number += 1; + } + } + } + } + } + } +} diff --git a/tests/heavy-tests/README.md b/tests/heavy-tests/README.md new file mode 100644 index 00000000..fe40887d --- /dev/null +++ b/tests/heavy-tests/README.md @@ -0,0 +1,3 @@ +# Heavy Tests Subdirectory + +This directory encompasses all the comprehensive tests for the project. It executes all project computations utilizing a range of technologies to guarantee the seamless functionality of every aspect. \ No newline at end of file