From d1270be8dbe2663cac9fe071cc4470ceebefc86c Mon Sep 17 00:00:00 2001 From: Mahmoud Elkarargy <113839437+mahmoudElkarargyBS@users.noreply.github.com> Date: Sun, 12 May 2024 11:07:55 +0300 Subject: [PATCH] v1.1.0 (#4) * add the pow_exp kernel and tested * all fixes * resolve threads plus some modifications * Fix cuda * fix for linking cuda * fix: hicma modifactions * try fixing Jenkines * Adding R structure * fix:add doxygen in Jenkines * add test file for pow-exp kernel * test with -fpic * some modifications for HiCMA * updates * try 2 gpu devices * back to starsh * a potential fix to doxygen * roll back * test Rcpp * Fix Jenkines * fix errors * Updated in design * updates * all release issue without src checks * adding MakeFile * Updated MPI * Documentation * fix examples tests * modeling takes pointers * example for read and write data * fix: typpo in Initialize * fix passing numbers of theta * fix: performance of gsl * fix: GPU support * fix:mspe * updated devel * R branch init * tests:add r tests * fix tests * bug: in tlr * fix:tlr * fix Jenkines * fix: Jenkines in Documentation * minior updates * huge refactoring * full R * potential for tlr issue * updates in heavy tests * a fix for gpu in gaussian kernels * smalling tlr size * update sizes of heavy_tests * smalling size for gpu * minior changes * Huge refactoring in docs * resolve threads * fix MPI * resolve thread * updated R documentation * documentation and hardware changes * finalized documentations * minior change in Hardware * Ft test mpi mk (#6) * solve multi thread issue in MPI * Fix MPI tests with chameleon * Fixed HiCMA with MPI * update license * minior cleanings (#7) --------- Co-authored-by: Sameh M. Abdulah Co-authored-by: Mahmoud Karargy --- .gitignore | 688 +++++++++ CHANGELOG.md | 40 + CMakeLists.txt | 191 ++- CONTRIBUTING.md | 5 +- DESCRIPTION | 24 + ExaGeoStatCPPConfig.cmake.in | 142 ++ Jenkinsfile | 17 +- LICENSE | 2 +- NAMESPACE | 3 + R/ExaGeoStatCPP.R | 1 + README.md | 207 ++- USER_MANUAL.md | 360 +++-- clean_build.sh | 29 +- .../FindPkgconfigLibrariesAbsolutePath.cmake | 2 +- cmake/FindR.cmake | 172 +++ cmake/FindTMG.cmake | 308 ++++ cmake/ImportBLAS.cmake | 36 + cmake/ImportBLASPP.cmake | 65 + cmake/ImportBlas.cmake | 41 - cmake/ImportBlasPP.cmake | 54 - cmake/ImportCatch2.cmake | 54 +- cmake/ImportChameleon.cmake | 84 +- cmake/ImportCuSolver.cmake | 20 - cmake/ImportGFortran.cmake | 17 - cmake/ImportGSL.cmake | 68 +- cmake/ImportHCore.cmake | 37 + cmake/ImportHcore.cmake | 50 - cmake/ImportHiCMA.cmake | 82 +- cmake/ImportHwloc.cmake | 72 +- cmake/ImportLapack.cmake | 54 +- cmake/ImportLapackPP.cmake | 60 - cmake/ImportNLOPT.cmake | 72 +- cmake/ImportOpenMP.cmake | 27 - cmake/ImportStarPu.cmake | 108 +- cmake/ImportStarsH.cmake | 103 +- cmake/macros/BuildDependency.cmake | 105 +- cmake/macros/ImportDependency.cmake | 85 ++ cmake/toolchains/CudaToolchain.cmake | 5 +- cmake/toolchains/GccToolchain.cmake | 4 +- config.sh | 133 -- configure | 274 ++++ docs/CMakeLists.txt | 4 +- docs/ExaGeoStat-CPP-Manual.pdf | Bin 0 -> 1078489 bytes docs/ExaGeoStat-R-Interface-Manual.pdf | Bin 0 -> 115185 bytes docs/ExaGeoStatCPP-handout.png | Bin 0 -> 748012 bytes docs/config.in | 21 +- exageostatcppConfig.cmake.in | 67 - examples/CMakeLists.txt | 11 +- examples/configurations/CMakeLists.txt | 14 +- .../RunningWithDifferentConfigurations.cpp | 74 + ...tionModule.cpp => SetupConfigurations.cpp} | 27 +- examples/data-generators/CMakeLists.txt | 4 +- .../SyntheticDataGeneration.cpp | 40 +- .../SyntheticLocationsGeneration.cpp | 80 - examples/data-loader/CMakeLists.txt | 16 + examples/data-loader/CSVLoader.cpp | 79 + examples/descriptors/CMakeLists.txt | 24 + examples/descriptors/ChameleonDescriptor.cpp | 101 ++ .../descriptors/ChameleonToHicmaConverter.cpp | 126 ++ examples/descriptors/HicmaDescriptor.cpp | 108 ++ examples/end-to-end/CMakeLists.txt | 7 +- examples/end-to-end/DataGeneration.cpp | 23 +- .../end-to-end/DataGenerationAndModeling.cpp | 28 +- .../DataGenerationAndPrediction.cpp | 44 + .../DataGenerationModelingAndPrediction.cpp | 35 +- examples/end-to-end/DataModeling.cpp | 32 +- examples/end-to-end/DataPrediction.cpp | 31 +- examples/hardware/CMakeLists.txt | 17 + examples/hardware/ExaGeoStatHardware.cpp | 42 + .../Rcpp-adapters/FunctionsAdapter.hpp | 260 ++++ inst/include/api/ExaGeoStat.hpp | 41 +- inst/include/common/Definitions.hpp | 54 +- inst/include/common/PluginRegistry.hpp | 22 +- inst/include/common/Utils.hpp | 106 -- .../include/configurations/Configurations.hpp | 121 +- .../include/data-generators/DataGenerator.hpp | 24 +- .../data-generators/LocationGenerator.hpp | 74 + .../concrete/CSVDataGenerator.hpp | 98 -- .../concrete/SyntheticGenerator.hpp | 67 +- inst/include/data-loader/DataLoader.hpp | 80 + .../data-loader/concrete/CSVLoader.hpp | 92 ++ inst/include/data-units/DescriptorData.hpp | 48 +- inst/include/data-units/ExaGeoStatData.hpp | 175 ++- inst/include/data-units/Locations.hpp | 9 +- .../data-units/ModelingDataHolders.hpp | 15 +- .../descriptor/ExaGeoStatDescriptor.hpp | 9 +- .../concrete/ChameleonDescriptor.hpp | 8 +- .../descriptor/concrete/HicmaDescriptor.hpp | 8 +- inst/include/hardware/ExaGeoStatHardware.hpp | 183 ++- inst/include/helpers/BasselFunction.hpp | 69 + inst/include/helpers/ByteHandler.hpp | 48 + inst/include/helpers/CommunicatorMPI.hpp | 16 +- inst/include/helpers/DiskWriter.hpp | 55 - .../helpers/DistanceCalculationHelpers.hpp | 16 +- inst/include/kernels/Kernel.hpp | 61 +- .../concrete/BivariateMaternFlexible.hpp | 8 +- .../concrete/BivariateMaternParsimonious.hpp | 8 +- .../BivariateSpacetimeMaternStationary.hpp | 8 +- .../concrete/TrivariateMaternParsimonious.hpp | 8 +- .../concrete/UnivariateExpNonGaussian.hpp | 8 +- .../concrete/UnivariateMaternDbeta.hpp | 8 +- .../concrete/UnivariateMaternDdbetaBeta.hpp | 8 +- .../concrete/UnivariateMaternDdbetaNu.hpp | 8 +- .../concrete/UnivariateMaternDdnuNu.hpp | 8 +- .../UnivariateMaternDdsigmaSquare.hpp | 8 +- .../UnivariateMaternDdsigmaSquareBeta.hpp | 8 +- .../UnivariateMaternDdsigmaSquareNu.hpp | 8 +- .../kernels/concrete/UnivariateMaternDnu.hpp | 8 +- .../concrete/UnivariateMaternDsigmaSquare.hpp | 8 +- .../concrete/UnivariateMaternNonGaussian.hpp | 8 +- .../concrete/UnivariateMaternNonStat.hpp | 141 -- .../UnivariateMaternNonStationary.hpp | 72 - .../UnivariateMaternNuggetsStationary.hpp | 8 +- .../concrete/UnivariateMaternStationary.hpp | 8 +- .../concrete/UnivariatePowExpStationary.hpp | 87 ++ .../UnivariateSpacetimeMaternStationary.hpp | 8 +- .../LinearAlgebraFactory.hpp | 4 +- .../LinearAlgebraMethods.hpp | 631 ++------ .../concrete/ChameleonHeaders.hpp | 2 +- .../concrete/HicmaHeaders.hpp | 4 +- .../chameleon/ChameleonImplementation.hpp | 90 +- ...ementationDense.hpp => ChameleonDense.hpp} | 21 +- .../ChameleonDST.hpp} | 18 +- .../HicmaImplementation.hpp | 47 +- inst/include/prediction/Prediction.hpp | 48 +- .../PredictionAuxiliaryFunctions.hpp | 15 +- inst/include/prediction/PredictionHelpers.hpp | 18 +- inst/include/results/Results.hpp | 108 +- inst/include/runtime/RuntimeFunctions.hpp | 230 +++ .../runtime/starpu/StarPuCodeletsHeaders.hpp | 26 + .../runtime/starpu/concrete/dcmg-codelet.hpp | 87 ++ .../runtime/starpu/concrete/ddotp-codelet.hpp | 80 + .../runtime/starpu/concrete/dmdet-codelet.hpp | 92 ++ .../starpu/concrete/dmloe-mmom-codelet.hpp | 83 ++ .../concrete/dmse-bivariate-codelet.hpp | 83 ++ .../runtime/starpu/concrete/dmse-codelet.hpp | 80 + .../starpu/concrete/dtrace-codelet.hpp | 91 ++ .../runtime/starpu/concrete/dzcpy-codelet.hpp | 82 + .../concrete/gaussian-to-non-codelet.hpp | 92 ++ .../concrete/non-gaussian-loglike-codelet.hpp | 93 ++ .../non-gaussian-transform-codelet.hpp | 132 ++ .../starpu/concrete/stride-vec-codelet.hpp | 81 + .../concrete/tri-stride-vec-codelet.hpp | 82 + .../runtime/starpu/helpers/StarPuHelpers.hpp | 114 ++ .../starpu/helpers/StarPuHelpersFactory.hpp | 42 + .../concrete/ChameleonStarPuHelpers.hpp | 108 ++ .../helpers/concrete/HicmaStarPuHelpers.hpp | 107 ++ inst/include/utilities/EnumStringParser.hpp | 64 + inst/include/utilities/ErrorHandler.hpp | 95 ++ inst/include/utilities/Logger.hpp | 130 ++ man/Data.Rd | 45 + man/Hardware.Rd | 56 + man/fisher.Rd | 83 ++ man/get_Z_measurement_vector.Rd | 51 + man/get_locations.Rd | 49 + man/idw.Rd | 88 ++ man/mloe_mmom.Rd | 89 ++ man/model_data.Rd | 96 ++ man/predict_data.Rd | 84 ++ man/simulate_data.Rd | 83 ++ package.pc.in | 2 +- scripts/Benchmarking.sh | 67 + src/CMakeLists.txt | 48 +- src/Makefile | 14 + src/Rcpp-adapters/CMakeLists.txt | 17 + src/Rcpp-adapters/FunctionsAdapter.cpp | 375 +++++ src/Rcpp-adapters/RcppExports.cpp | 45 + src/Rcpp-adapters/RcppModules.cpp | 73 + src/api/CMakeLists.txt | 4 +- src/api/ExaGeoStat.cpp | 56 +- src/configurations/CMakeLists.txt | 4 +- src/configurations/Configurations.cpp | 198 +-- src/data-generators/CMakeLists.txt | 7 +- src/data-generators/DataGenerator.cpp | 39 +- src/data-generators/LocationGenerator.cpp | 124 ++ src/data-generators/concrete/CMakeLists.txt | 6 +- .../concrete/CSVDataGenerator.cpp | 201 --- .../concrete/SyntheticGenerator.cpp | 207 +-- src/data-loader/CMakeLists.txt | 20 + src/data-loader/DataLoader.cpp | 67 + src/data-loader/concrete/CMakeLists.txt | 17 + src/data-loader/concrete/CSVLoader.cpp | 241 +++ src/data-units/CMakeLists.txt | 4 +- src/data-units/DescriptorData.cpp | 87 +- src/data-units/ExaGeoStatData.cpp | 22 +- src/data-units/Locations.cpp | 7 +- src/data-units/descriptor/CMakeLists.txt | 4 +- .../descriptor/ExaGeoStatDescriptor.cpp | 29 +- .../descriptor/concrete/CMakeLists.txt | 6 +- .../concrete/ChameleonDescriptor.cpp | 8 +- .../descriptor/concrete/HicmaDescriptor.cpp | 9 +- src/hardware/CMakeLists.txt | 4 +- src/hardware/ExaGeoStatHardware.cpp | 164 +- src/helpers/BasselFunction.cpp | 44 + src/helpers/ByteHandler.cpp | 52 + src/helpers/CMakeLists.txt | 7 +- src/helpers/CommunicatorMPI.cpp | 31 +- src/helpers/DiskWriter.cpp | 114 -- src/helpers/DistanceCalculationHelpers.cpp | 10 +- src/kernels/CMakeLists.txt | 30 +- src/kernels/Kernel.cpp | 55 +- .../concrete/BivariateMaternFlexible.cpp | 14 +- .../concrete/BivariateMaternParsimonious.cpp | 14 +- .../BivariateSpacetimeMaternStationary.cpp | 12 +- .../concrete/TrivariateMaternParsimonious.cpp | 14 +- .../concrete/UnivariateExpNonGaussian.cpp | 13 +- .../concrete/UnivariateMaternDbeta.cpp | 16 +- .../concrete/UnivariateMaternDdbetaBeta.cpp | 18 +- .../concrete/UnivariateMaternDdbetaNu.cpp | 19 +- .../concrete/UnivariateMaternDdnuNu.cpp | 45 +- .../UnivariateMaternDdsigmaSquare.cpp | 8 +- .../UnivariateMaternDdsigmaSquareBeta.cpp | 14 +- .../UnivariateMaternDdsigmaSquareNu.cpp | 12 +- src/kernels/concrete/UnivariateMaternDnu.cpp | 17 +- .../concrete/UnivariateMaternDsigmaSquare.cpp | 12 +- .../concrete/UnivariateMaternNonGaussian.cpp | 14 +- .../concrete/UnivariateMaternNonStat.cpp | 145 -- .../UnivariateMaternNonStationary.cpp | 115 -- .../UnivariateMaternNuggetsStationary.cpp | 14 +- .../concrete/UnivariateMaternStationary.cpp | 8 +- .../concrete/UnivariatePowExpStationary.cpp | 67 + .../UnivariateSpacetimeMaternStationary.cpp | 14 +- src/linear-algebra-solvers/CMakeLists.txt | 4 +- .../LinearAlgebraFactory.cpp | 21 +- .../LinearAlgebraMethods.cpp | 1321 +++++++++-------- .../concrete/CMakeLists.txt | 12 +- .../chameleon/ChameleonImplementation.cpp | 412 ++--- ...ementationDense.cpp => ChameleonDense.cpp} | 14 +- .../ChameleonDST.cpp} | 18 +- .../tile-low-rank/HicmaImplementation.cpp | 395 ----- .../concrete/tlr/HicmaImplementation.cpp | 404 +++++ src/prediction/CMakeLists.txt | 4 +- src/prediction/Prediction.cpp | 217 ++- .../PredictionAuxiliaryFunctions.cpp | 15 +- src/prediction/PredictionHelpers.cpp | 66 +- src/results/CMakeLists.txt | 4 +- src/results/Results.cpp | 154 +- src/runtime/CMakeLists.txt | 25 + src/runtime/parsec/CMakeLists.txt | 17 + src/runtime/parsec/ParsecFunctions.cpp | 87 ++ src/runtime/starpu/CMakeLists.txt | 55 + src/runtime/starpu/StarPuFunctions.cpp | 258 ++++ src/runtime/starpu/concrete/dcmg-codelet.cpp | 90 ++ src/runtime/starpu/concrete/ddotp-codelet.cpp | 72 + src/runtime/starpu/concrete/dmdet-codelet.cpp | 80 + .../starpu/concrete/dmloe-mmom-codelet.cpp | 103 ++ .../concrete/dmse-bivariate-codelet.cpp | 87 ++ src/runtime/starpu/concrete/dmse-codelet.cpp | 73 + .../starpu/concrete/dtrace-codelet.cpp | 78 + src/runtime/starpu/concrete/dzcpy-codelet.cpp | 65 + .../concrete/gaussian-to-non-codelet.cpp | 98 ++ .../concrete/non-gaussian-loglike-codelet.cpp | 101 ++ .../non-gaussian-transform-codelet.cpp | 136 ++ .../starpu/concrete/stride-vec-codelet.cpp | 76 + .../concrete/tri-stride-vec-codelet.cpp | 83 ++ src/runtime/starpu/helpers/CMakeLists.txt | 23 + .../starpu/helpers/StarPuHelpersFactory.cpp | 38 + .../concrete/ChameleonStarPuHelpers.cpp | 61 + .../helpers/concrete/HicmaStarPuHelpers.cpp | 58 + tests/R-tests/TestDataGeneration.R | 57 + tests/R-tests/TestDataModeling.R | 76 + tests/R-tests/TestDataPrediction.R | 74 + tests/R-tests/TestExaGeoStatAPI.R | 78 + tests/cpp-tests/CMakeLists.txt | 29 +- tests/cpp-tests/Rcpp-adapters/CMakeLists.txt | 16 + .../Rcpp-adapters/TestAllRFunctions.cpp | 169 +++ tests/cpp-tests/api/CMakeLists.txt | 4 +- tests/cpp-tests/api/TestExaGeoStatApi.cpp | 68 +- .../{data-generation => }/CMakeLists.txt | 6 +- ...figurations.cpp => TestConfigurations.cpp} | 92 +- .../cpp-tests/data-generators/CMakeLists.txt | 4 +- .../concrete/TestCSVDataGenerator.cpp | 195 ++- .../concrete/TestSyntheticGenerator.cpp | 115 +- tests/cpp-tests/data-units/CMakeLists.txt | 14 + .../data-units/TestDescriptorData.cpp | 64 + tests/cpp-tests/hardware/CMakeLists.txt | 14 + .../hardware/TestExaGeoStatHardware.cpp | 111 ++ tests/cpp-tests/helpers/CMakeLists.txt | 10 +- tests/cpp-tests/helpers/TestDiskWriter.cpp | 83 ++ .../TestDistanceCalculationHelpers.cpp | 144 ++ tests/cpp-tests/kernels/CMakeLists.txt | 31 +- .../concrete/TestBivariateMaternFlexible.cpp | 16 +- .../TestBivariateMaternParsimonious.cpp | 16 +- ...TestBivariateSpacetimeMaternStationary.cpp | 33 +- .../TestTrivariateMaternParsimonious.cpp | 16 +- .../concrete/TestUnivariateExpNonGaussian.cpp | 4 +- .../concrete/TestUnivariateMaternDbeta.cpp | 7 +- .../TestUnivariateMaternDdbetaBeta.cpp | 6 +- .../concrete/TestUnivariateMaternDdbetaNu.cpp | 7 +- .../concrete/TestUnivariateMaternDdnuNu.cpp | 6 +- .../TestUnivariateMaternDdsigmaSquare.cpp | 10 +- .../TestUnivariateMaternDdsigmaSquareBeta.cpp | 7 +- .../TestUnivariateMaternDdsigmaSquareNu.cpp | 6 +- .../concrete/TestUnivariateMaternDnu.cpp | 6 +- .../TestUnivariateMaternDsigmaSquare.cpp | 6 +- .../TestUnivariateMaternNonGaussian.cpp | 24 +- .../TestUnivariateMaternNonStationary.cpp | 13 - .../TestUnivariateMaternNuggetsStationary.cpp | 16 +- .../TestUnivariateMaternStationary.cpp | 16 +- ...cpp => TestUnivariatePowExpStationary.cpp} | 52 +- ...estUnivariateSpacetimeMaternStationary.cpp | 30 +- .../linear-algebra-solvers/CMakeLists.txt | 6 +- .../TestChameleonImplementationDST.cpp | 21 +- .../TestChameleonImplementationDense.cpp | 21 +- .../concrete/TestHiCMAImplementationTLR.cpp | 131 +- tests/cpp-tests/main.cpp | 23 + tests/cpp-tests/prediction/CMakeLists.txt | 18 + tests/cpp-tests/prediction/TestPrediction.cpp | 202 +++ .../TestPredictionHelpers.cpp | 8 +- tests/cpp-tests/results/CMakeLists.txt | 14 + tests/cpp-tests/results/TestResults.cpp | 60 + tests/heavy-tests/CMakeLists.txt | 14 + tests/heavy-tests/ExamplesTests.cpp | 138 ++ tests/heavy-tests/HeavyTests.cpp | 254 ++++ tests/heavy-tests/README.md | 3 + 315 files changed, 15049 insertions(+), 6527 deletions(-) create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100755 DESCRIPTION create mode 100644 ExaGeoStatCPPConfig.cmake.in create mode 100644 NAMESPACE create mode 100755 R/ExaGeoStatCPP.R create mode 100644 cmake/FindR.cmake create mode 100644 cmake/FindTMG.cmake create mode 100644 cmake/ImportBLAS.cmake create mode 100644 cmake/ImportBLASPP.cmake delete mode 100644 cmake/ImportBlas.cmake delete mode 100644 cmake/ImportBlasPP.cmake delete mode 100644 cmake/ImportCuSolver.cmake delete mode 100644 cmake/ImportGFortran.cmake create mode 100644 cmake/ImportHCore.cmake delete mode 100644 cmake/ImportHcore.cmake delete mode 100644 cmake/ImportLapackPP.cmake delete mode 100644 cmake/ImportOpenMP.cmake create mode 100644 cmake/macros/ImportDependency.cmake delete mode 100755 config.sh create mode 100755 configure create mode 100644 docs/ExaGeoStat-CPP-Manual.pdf create mode 100644 docs/ExaGeoStat-R-Interface-Manual.pdf create mode 100644 docs/ExaGeoStatCPP-handout.png delete mode 100644 exageostatcppConfig.cmake.in create mode 100644 examples/configurations/RunningWithDifferentConfigurations.cpp rename examples/configurations/{ConfigurationModule.cpp => SetupConfigurations.cpp} (82%) delete mode 100644 examples/data-generators/SyntheticLocationsGeneration.cpp create mode 100644 examples/data-loader/CMakeLists.txt create mode 100644 examples/data-loader/CSVLoader.cpp create mode 100644 examples/descriptors/CMakeLists.txt create mode 100644 examples/descriptors/ChameleonDescriptor.cpp create mode 100644 examples/descriptors/ChameleonToHicmaConverter.cpp create mode 100644 examples/descriptors/HicmaDescriptor.cpp create mode 100644 examples/end-to-end/DataGenerationAndPrediction.cpp create mode 100644 examples/hardware/CMakeLists.txt create mode 100644 examples/hardware/ExaGeoStatHardware.cpp create mode 100644 inst/include/Rcpp-adapters/FunctionsAdapter.hpp delete mode 100644 inst/include/common/Utils.hpp create mode 100644 inst/include/data-generators/LocationGenerator.hpp delete mode 100644 inst/include/data-generators/concrete/CSVDataGenerator.hpp create mode 100644 inst/include/data-loader/DataLoader.hpp create mode 100644 inst/include/data-loader/concrete/CSVLoader.hpp create mode 100644 inst/include/helpers/BasselFunction.hpp create mode 100644 inst/include/helpers/ByteHandler.hpp delete mode 100644 inst/include/helpers/DiskWriter.hpp delete mode 100644 inst/include/kernels/concrete/UnivariateMaternNonStat.hpp delete mode 100644 inst/include/kernels/concrete/UnivariateMaternNonStationary.hpp create mode 100644 inst/include/kernels/concrete/UnivariatePowExpStationary.hpp rename inst/include/linear-algebra-solvers/concrete/chameleon/dense/{ChameleonImplementationDense.hpp => ChameleonDense.hpp} (75%) rename inst/include/linear-algebra-solvers/concrete/chameleon/{diagonal-super-tile/ChameleonImplementationDST.hpp => dst/ChameleonDST.hpp} (86%) rename inst/include/linear-algebra-solvers/concrete/hicma/{tile-low-rank => tlr}/HicmaImplementation.hpp (65%) create mode 100644 inst/include/runtime/RuntimeFunctions.hpp create mode 100644 inst/include/runtime/starpu/StarPuCodeletsHeaders.hpp create mode 100644 inst/include/runtime/starpu/concrete/dcmg-codelet.hpp create mode 100644 inst/include/runtime/starpu/concrete/ddotp-codelet.hpp create mode 100644 inst/include/runtime/starpu/concrete/dmdet-codelet.hpp create mode 100644 inst/include/runtime/starpu/concrete/dmloe-mmom-codelet.hpp create mode 100644 inst/include/runtime/starpu/concrete/dmse-bivariate-codelet.hpp create mode 100644 inst/include/runtime/starpu/concrete/dmse-codelet.hpp create mode 100644 inst/include/runtime/starpu/concrete/dtrace-codelet.hpp create mode 100644 inst/include/runtime/starpu/concrete/dzcpy-codelet.hpp create mode 100644 inst/include/runtime/starpu/concrete/gaussian-to-non-codelet.hpp create mode 100644 inst/include/runtime/starpu/concrete/non-gaussian-loglike-codelet.hpp create mode 100644 inst/include/runtime/starpu/concrete/non-gaussian-transform-codelet.hpp create mode 100644 inst/include/runtime/starpu/concrete/stride-vec-codelet.hpp create mode 100644 inst/include/runtime/starpu/concrete/tri-stride-vec-codelet.hpp create mode 100644 inst/include/runtime/starpu/helpers/StarPuHelpers.hpp create mode 100644 inst/include/runtime/starpu/helpers/StarPuHelpersFactory.hpp create mode 100644 inst/include/runtime/starpu/helpers/concrete/ChameleonStarPuHelpers.hpp create mode 100644 inst/include/runtime/starpu/helpers/concrete/HicmaStarPuHelpers.hpp create mode 100644 inst/include/utilities/EnumStringParser.hpp create mode 100644 inst/include/utilities/ErrorHandler.hpp create mode 100644 inst/include/utilities/Logger.hpp create mode 100644 man/Data.Rd create mode 100644 man/Hardware.Rd create mode 100644 man/fisher.Rd create mode 100644 man/get_Z_measurement_vector.Rd create mode 100644 man/get_locations.Rd create mode 100644 man/idw.Rd create mode 100644 man/mloe_mmom.Rd create mode 100644 man/model_data.Rd create mode 100644 man/predict_data.Rd create mode 100644 man/simulate_data.Rd create mode 100644 scripts/Benchmarking.sh create mode 100644 src/Makefile create mode 100644 src/Rcpp-adapters/CMakeLists.txt create mode 100644 src/Rcpp-adapters/FunctionsAdapter.cpp create mode 100644 src/Rcpp-adapters/RcppExports.cpp create mode 100644 src/Rcpp-adapters/RcppModules.cpp create mode 100644 src/data-generators/LocationGenerator.cpp delete mode 100644 src/data-generators/concrete/CSVDataGenerator.cpp create mode 100644 src/data-loader/CMakeLists.txt create mode 100644 src/data-loader/DataLoader.cpp create mode 100644 src/data-loader/concrete/CMakeLists.txt create mode 100644 src/data-loader/concrete/CSVLoader.cpp create mode 100644 src/helpers/BasselFunction.cpp create mode 100644 src/helpers/ByteHandler.cpp delete mode 100644 src/helpers/DiskWriter.cpp delete mode 100644 src/kernels/concrete/UnivariateMaternNonStat.cpp delete mode 100644 src/kernels/concrete/UnivariateMaternNonStationary.cpp create mode 100644 src/kernels/concrete/UnivariatePowExpStationary.cpp rename src/linear-algebra-solvers/concrete/chameleon/dense/{ChameleonImplementationDense.cpp => ChameleonDense.cpp} (62%) rename src/linear-algebra-solvers/concrete/chameleon/{diagonal-super-tile/ChameleonImplementationDST.cpp => dst/ChameleonDST.cpp} (89%) delete mode 100644 src/linear-algebra-solvers/concrete/tile-low-rank/HicmaImplementation.cpp create mode 100644 src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp create mode 100644 src/runtime/CMakeLists.txt create mode 100644 src/runtime/parsec/CMakeLists.txt create mode 100644 src/runtime/parsec/ParsecFunctions.cpp create mode 100644 src/runtime/starpu/CMakeLists.txt create mode 100644 src/runtime/starpu/StarPuFunctions.cpp create mode 100644 src/runtime/starpu/concrete/dcmg-codelet.cpp create mode 100644 src/runtime/starpu/concrete/ddotp-codelet.cpp create mode 100644 src/runtime/starpu/concrete/dmdet-codelet.cpp create mode 100644 src/runtime/starpu/concrete/dmloe-mmom-codelet.cpp create mode 100644 src/runtime/starpu/concrete/dmse-bivariate-codelet.cpp create mode 100644 src/runtime/starpu/concrete/dmse-codelet.cpp create mode 100644 src/runtime/starpu/concrete/dtrace-codelet.cpp create mode 100644 src/runtime/starpu/concrete/dzcpy-codelet.cpp create mode 100644 src/runtime/starpu/concrete/gaussian-to-non-codelet.cpp create mode 100644 src/runtime/starpu/concrete/non-gaussian-loglike-codelet.cpp create mode 100644 src/runtime/starpu/concrete/non-gaussian-transform-codelet.cpp create mode 100644 src/runtime/starpu/concrete/stride-vec-codelet.cpp create mode 100644 src/runtime/starpu/concrete/tri-stride-vec-codelet.cpp create mode 100644 src/runtime/starpu/helpers/CMakeLists.txt create mode 100644 src/runtime/starpu/helpers/StarPuHelpersFactory.cpp create mode 100644 src/runtime/starpu/helpers/concrete/ChameleonStarPuHelpers.cpp create mode 100644 src/runtime/starpu/helpers/concrete/HicmaStarPuHelpers.cpp create mode 100644 tests/R-tests/TestDataGeneration.R create mode 100644 tests/R-tests/TestDataModeling.R create mode 100644 tests/R-tests/TestDataPrediction.R create mode 100644 tests/R-tests/TestExaGeoStatAPI.R create mode 100644 tests/cpp-tests/Rcpp-adapters/CMakeLists.txt create mode 100644 tests/cpp-tests/Rcpp-adapters/TestAllRFunctions.cpp rename tests/cpp-tests/configurations/{data-generation => }/CMakeLists.txt (65%) rename tests/cpp-tests/configurations/{data-generation/concrete/TestSyntheticDataConfigurations.cpp => TestConfigurations.cpp} (58%) create mode 100644 tests/cpp-tests/data-units/CMakeLists.txt create mode 100644 tests/cpp-tests/data-units/TestDescriptorData.cpp create mode 100644 tests/cpp-tests/hardware/CMakeLists.txt create mode 100644 tests/cpp-tests/hardware/TestExaGeoStatHardware.cpp create mode 100644 tests/cpp-tests/helpers/TestDiskWriter.cpp create mode 100644 tests/cpp-tests/helpers/TestDistanceCalculationHelpers.cpp delete mode 100644 tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonStationary.cpp rename tests/cpp-tests/kernels/concrete/{TestUnivariateMaternNonStat.cpp => TestUnivariatePowExpStationary.cpp} (55%) create mode 100644 tests/cpp-tests/main.cpp create mode 100644 tests/cpp-tests/prediction/CMakeLists.txt create mode 100644 tests/cpp-tests/prediction/TestPrediction.cpp rename tests/cpp-tests/{helpers => prediction}/TestPredictionHelpers.cpp (98%) create mode 100644 tests/cpp-tests/results/CMakeLists.txt create mode 100644 tests/cpp-tests/results/TestResults.cpp create mode 100644 tests/heavy-tests/CMakeLists.txt create mode 100644 tests/heavy-tests/ExamplesTests.cpp create mode 100644 tests/heavy-tests/HeavyTests.cpp create mode 100644 tests/heavy-tests/README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ba44e88c --- /dev/null +++ b/.gitignore @@ -0,0 +1,688 @@ +# 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 +..Rcheck +src/symbols.rds + +# 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..0353252f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,40 @@ +# 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). + +## [1.1.0](https://github.com/ecrc/ExaGeoStatCPP/releases/tag/1.1.0) - 2024-04-25 +### Added +- Implemented a new changelog. +- Introduced a benchmarking script. +- .gitignore file. +- More examples. +- Add tests for all src files. +- Rcpp support. + +### 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 The non-stationary kernel support. +- Removed FindOpenMP.cmake, FindLAPACKPP.cmake, and FindCuSOLVER.cmake. + +## [1.0.0](https://github.com/ecrc/ExaGeoStatCPP/releases/tag/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..18ce5b92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -8,10 +8,10 @@ # 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.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah -# @date 2023-01-30 +# @date 2024-02-04 # Set the minimum CMake version required to 3.20 cmake_minimum_required(VERSION 3.20 FATAL_ERROR) @@ -20,16 +20,26 @@ 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(USE_R "Enable the use of R and Rcpp in the project" OFF) +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}") +if (${BUILD_SHARED_LIBS}) + set(BLA_STATIC OFF) +else () + set(BLA_STATIC ON) +endif () + # 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 +54,19 @@ 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}/") +# Set kernels path. +add_definitions(-DKERNELS_PATH="${PROJECT_SOURCE_DIR}/inst/include/kernels/concrete/") -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 CUDA +# ------------------------------- if (USE_CUDA) message("-- Build CUDA Support") else () @@ -67,73 +75,74 @@ else () unset(BLA_VENDOR) endif () -# EXAGEOSTAT depends on a MPI +# ExaGeoStatCPP depends on 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 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 StarPU runtime # ------------------------------- include(ImportStarPu) -# EXAGEOSTAT depends on a GSL +# ExaGeoStatCPP depends on GSL # ------------------------------- include(ImportGSL) -# EXAGEOSTAT depends on a NLOPT +# ExaGeoStatCPP depends on 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 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,12 +150,25 @@ 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}) add_definitions(-DMY_LOGGER_PATH="${CMAKE_CURRENT_SOURCE_DIR}") +if (USE_R) + message("") + message("---------------------------------------- Rcpp") + # Find R and Rcpp using FindR Module + find_package(R REQUIRED) + if (${R_FOUND}) + message(STATUS "Using R technology") + list(APPEND LIBS R) + add_definitions(-DUSING_R) + endif () +endif () + + # Add src Directory to expose added libraries add_subdirectory(src) @@ -158,14 +180,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 +190,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 +276,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/CONTRIBUTING.md b/CONTRIBUTING.md index c8b28557..f1cacec5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,6 +7,7 @@ Contributing to ExaGeoStatCPP - [Developing new features](#developing-new-features) - [Developing bug fixes](#developing-bug-fixes) - [Creating pull requests](#creating-pull-requests) +- [Adding new Kernel](#adding-new-kernel) - [Tests](#tests) Synopsis @@ -260,10 +261,12 @@ To add a new kernel, you need to follow these steps. 1. Place your kernel header file in the inst/include/kernels/concrete directory. The file name should match the kernel's name. For instance, if your header file is named UnivariateMaternStationary.hpp, it can be invoked using either univariate_matern_stationary or UnivariateMaternStationary. The naming linkage is handled automatically, so there's no additional setup required on your part. -2. Derive from the base class located in kernel.hpp and implement the necessary functions. +2. Derive from the base class located in Kernel.hpp and implement the necessary functions. 3. Ensure your kernel includes all the requisite functions that adhere to the established naming conventions found in other kernels. This will allow for proper support and integration of your new kernel. +4. Test your kernel, create a test file for your kernel in tests/cpp-tests/kernels/concrete The file name should match the kernel's name. Also, The naming linkage is handled automatically, so there's no additional setup required on your part. + After finalizing your feature and confirming that your tests run successfully, you are ready to push your branch to GitHub and submit a pull request. diff --git a/DESCRIPTION b/DESCRIPTION new file mode 100755 index 00000000..47ca856f --- /dev/null +++ b/DESCRIPTION @@ -0,0 +1,24 @@ +Package: ExaGeoStatCPP +Type: Package +Title: R Package demonstrates the R/C++ Interface for Exascale GeoStatistics software (ExaGeoStat) +Version: 1.1.0 +Date: 2024-01-14 +Author: Mahmoud ElKarargy [aut, cph], Sameh Abdulah [cre, cph], KAUST King Abdullah University of Science and Technology [fnd, cph], Brightskies [cph] +Maintainer: Sameh Abdulah +Description: An R-Interface for the ExaGeoStatCPP software: a parallel high performance unified framework for geostatistics on manycore systems. Its abbreviation stands for Exascale Geostatistics. The framework aims at optimizing the likelihood function for a given spatial data to provide an efficient way to predict missing observations. The framework targets many-core systems: clusters of CPUs and GPUs. +License: GPL (>= 3) +Imports: assertthat (>= 0.2.1), MASS, methods, Rcpp (>= 1.0.9) +Depends: R (>= 3.5.0), assertthat (>= 0.2.1) +RoxygenNote: 7.2.3 +SystemRequirements: C++ (>= 11), CMake (>= 3.2), LAPACKE +NeedsCompilation: yes +OS_type: unix +Authors@R: c( + person("Mahmoud", "ElKarargy", role=c("aut", "cph"), email="mahmoud.elkarargy@brightskiesinc.com"), + person("Sameh", "Abdulah", role=c("cre","cph"), email="sameh.abdulah@kaust.edu.sa"), + person("KAUST", "King Abdullah University of Science and Technology", role=c("fnd","cph")), + person("Brightskies", role=c("cph")) + ) +URL: https://github.com/ecrc/ExaGeoStatCPP +BugReports: https://github.com/ecrc/ExaGeoStatCPP/issues +Encoding: UTF-8 \ No newline at end of file diff --git a/ExaGeoStatCPPConfig.cmake.in b/ExaGeoStatCPPConfig.cmake.in new file mode 100644 index 00000000..410e4c61 --- /dev/null +++ b/ExaGeoStatCPPConfig.cmake.in @@ -0,0 +1,142 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file ExaGeoStatCPPConfig.cmake.in +# @version 1.1.0 +# @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..bd84a4de 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -20,14 +20,14 @@ 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 + ./configure -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,14 +62,14 @@ 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 + ./configure -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,14 @@ 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 + #################################################### + + ./configure -e ./clean_build.sh cd bin make docs diff --git a/LICENSE b/LICENSE index 0808c82b..bcfd34e7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2017-2023, King Abdullah University of Science and Technology +Copyright (c) 2017-2024, King Abdullah University of Science and Technology All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/NAMESPACE b/NAMESPACE new file mode 100644 index 00000000..7f899c19 --- /dev/null +++ b/NAMESPACE @@ -0,0 +1,3 @@ +useDynLib(ExaGeoStatCPP, .registration=TRUE) +exportPattern("^[[:alpha:]]+") +import(methods, Rcpp) \ No newline at end of file diff --git a/R/ExaGeoStatCPP.R b/R/ExaGeoStatCPP.R new file mode 100755 index 00000000..c2ac7275 --- /dev/null +++ b/R/ExaGeoStatCPP.R @@ -0,0 +1 @@ +loadModule("ExaGeoStatCPP", TRUE) diff --git a/README.md b/README.md index b66daad7..66a29c8f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -What is ExaGeoStat? -================ +# ExaGeoStat The **Exascale GeoStatistics** project (ExaGeoStat) is a parallel high-performance unified framework for computational geostatistics on many-core systems. The project aims to optimize the likelihood function for a given spatial data to @@ -9,19 +8,19 @@ from commodity x86 to GPU accelerator-based shared and distributed-memory system tackle computationally challenging scientific problems at large-scale while abstracting the hardware complexity through state-of-the-art high-performance linear algebra software libraries. - -What is ExaGeoStatCPP? -==================== +### ExaGeoStatCPP ExaGeoStatCPP is a C++ API for ExaGeoStat that aims to offer a user-friendly and efficient API for C++ developers, essentially maintaining traditional practices and embracing contemporary C++ elements like namespaces, templates, and exceptions to enhance functionality. +### ExaGeoStatR : R Interface of ExaGeoStat +R is a powerful and versatile tool for scientific computing, offering a wide range of statistical and graphical +techniques, strong community support, and the flexibility to integrate with other programming languages. +Its open-source nature and extensive package ecosystem make it an invaluable resource for researchers and data scientists. +Therefore, we decided to create ExaGeoStatR: An interface for functionalities provided by ExaGeoStatCPP to make use of R's various benefits. -Vision of ExaGeoStat/ExaGeoStatCPP -================= - +### Vision of ExaGeoStat/ExaGeoStatCPP The ExaGeoStat/ExaGeoStatCPP project is a collaboration between the KAUST Spatial Statistics group and the Extreme Computing Research -Center (ECRC). Its contribution lies not in a new algorithm nor a new dataset, -but in demonstrating the routine use of the larger datasets becoming available to geospatial +Center (ECRC). Lies not in a new algorithm nor a new dataset, but in demonstrating the routine use of the larger datasets becoming available to geospatial statisticians, thanks to the implementation of state-of-the-art statistical algorithms on High Performance Computing (HPC) hardware. @@ -54,108 +53,93 @@ This low-rank matrix approximation permits the exploitation of the data sparsity numerical accuracy. This further expands practical problem sizes for statisticians with modest computational resources. +## Installation -Current Version of ExaGeoStatCPP: 1.0.0 -====================== -Operations: - -1. (Data Generation): Generating large geospatial synthetic datasets using dense, Diagonal Super-Tile (DST) and Tile Low-Rank (TLR) approximation techniques. -2. (Data Modeling): Modeling large geospatial datasets on dense, Diagonal Super-Tile (DST) and Tile Low-Rank (TLR) approximation techniques through the Maximum likelihood Estimation (MLE) operation. -3. (Data Prediction): Predicting missing measurements on given locations using dense, Diagonal Super-Tile (DST), and Tile Low-Rank (TLR) approximation techniques. -4. (MLOE/MMOM): Computing the Mean Loss of Efficiency (MLOE), Mean Misspecification of the Mean Square Error (MMOM), and Root mean square MOM (RMOM) to describe the prediction performance over the whole observation region. -5. (Fisher Information Matrix (FIM)): Quantifying the information content that a variable x carries about a parameter $\theta$ within a Gaussian distribution. - -Supported Covariance Functions: -====================== - -1. Univariate Matérn (Gaussian/Stationary) -2. Univariate Matérn with Nugget (Gaussian/Stationary) -3. Flexible Bivariate Matérn (Gaussian/Stationary) -4. Parsimonious Bivariate Matérn (Gaussian/Stationary) -5. Parsimonious trivariate Matérn (Gaussian/Stationary) -6. Univariate Space/Time Matérn (Gaussian/Stationary) -7. Bivariate Space/Time Matérn (Gaussian/Stationary) -8. Tukey g-and-h Univariate Matérn (non-Gaussian/Stationary) -9. Tukey g-and-h Univariate Power Exponential (non-Gaussian/Stationary) - -Programming models: - -1. MPI -2. Task-based programming models - -External libraries: - -1. NLOPT [https://nlopt.readthedocs.io/en/latest/](https://nlopt.readthedocs.io/en/latest/) -2. GSL [https://www.gnu.org/software/gsl/](https://www.gnu.org/software/gsl/) -3. HWLOC [https://www.open-mpi.org/projects/hwloc/](https://www.open-mpi.org/projects/hwloc/) -4. StarPU dynamic runtime system [https://starpu.gitlabpages.inria.fr/](https://starpu.gitlabpages.inria.fr/) -5. HCORE [https://github.com/ecrc/hcore](https://github.com/ecrc/hcore) -6. HiCMA [https://github.com/ecrc/hicma](https://github.com/ecrc/hicma) -7. Stars-H [https://github.com/ecrc/stars-h](https://github.com/ecrc/stars-h) -8. Chameleon [https://gitlab.inria.fr/solverstack/chameleon](https://gitlab.inria.fr/solverstack/chameleon) - -Project Hierarchy --------------------- - -* **```cmake```** A directory contains essential CMake modules that facilitate the importation and location of required dependencies. -* **```docs```** A directory contains all the necessary documents. -* **```examples```** A directory contains a comprehensive collection of demo code that illustrates the framework's application and demonstrates its features and capabilities. -* **```inst```** A directory contains all the system's header files, mirroring the structure of the src directory. -* **```prerequisites```** A directory contains all the necessary prerequisites for the project and default scripts for their installation. -* **```src```** A directory contains all the source files. -* **```tests```** A directory contains all the test files and follows the same structure as the src folder. -* **```clean_build.sh```** A script is designed to compile the software tests once all dependencies are installed, and it is set to build everything by default. -* **```CMakeLists.txt```** The top-level CMake file to configure the build system. -* **```config.sh```** A Script used to generate the building system inside a 'bin' directory. - -Installation -============ - -Installation requires at least **CMake of version 3.2**. to build ExaGeoStatCPP, -please follow these instructions: - -1. Get from git repository +> Note: Installation requires at least **CMake of version 3.2**. to build ExaGeoStatCPP. - git clone git@github.com:ecrc/exageostatcpp +### C++ source code installation +To install the `ExaGeoStat` project locally, run the following commands in your terminal: - or +1. Clone the project from the remote gitHub repository into your local machine using the following command + ```bash + git clone https://github.com/ecrc/ExaGeoStatCPP.git + ``` - git clone https://github.com/ecrc/exageostatcpp +2. Change your current directory by getting into the `ExaGeoStatCPP` project directory + ```bash + cd ExaGeoStatCPP + ``` -2. Go into the ExaGeoStatCPP folder +3. Run `configure` script with the flag `-h` for help, to know the supported options and their corresponding flags. + ```bash + ./configure -h + ``` - cd exageostatcpp +4. Run `clean_build.sh` script with the flag `-h` for help, to know the needed arguments to run with your specific options. + ```bash + ./clean_build.sh -h + ``` -3. Run help of config.sh to know the needed arguments to run with your specific options. - - ./config.sh --h - or check user manual. - -4. Run help of clean_build.sh to know the needed arguments to run with your specific options. - - ./clean_build.sh -h - -10. Export the installation paths of the dependencies, e.g., - - export PKG_CONFIG_PATH=$PWD/installdir/_deps/DEPENDENCY_NAME/lib/pkgconfig:$PKG_CONFIG_PATH - - to your .bashrc file. +5. Export the installation paths of the dependencies to your `.bashrc` file, e.g. + ```bash + export PKG_CONFIG_PATH=$PWD/installdir/_deps/DEPENDENCY_NAME/lib/pkgconfig:$PKG_CONFIG_PATH + ``` Now, you can use the pkg-config executable to collect compiler and linker flags for -EXAGEOSTATCPP. - -Using ExaGeoStatCPP -============ -Please refer to **```USER_MANUAL```** for detailed instructions. -Please take a look at the end-to-end examples as a reference for using all the operations. - -Contribute -======= - -[Contribution Guidelines](CONTRIBUTING.md) - -References -========== +ExaGeoStatCPP. + +### R package installation +1. Open the R prompt window by simply running `R` command in the terminal, inside the prompt, we will install needed packages by running the following commands: + ```R + install.packages(Rcpp) + install.packages("assert") + ``` + +2. close the R prompt and return to the terminal. Run the following command, make sure your current path is the ExaGeoStat project directory + + ```commandline + R CMD INSTALL . --configure-args="-r" + ``` + +> For more detailed information on installing ExaGeoStat with different configurations and enabling technologies such as CUDA, MPI, R, etc., please refer to the [User Manual](USER_MANUAL.md) + + +## Usage +#### C++ Example +```C++ +int main(int argc, char **argv) { + + // Create a new configurations object. + Configurations configurations; + // Initialize the arguments with the provided command line arguments + configurations.InitializeArguments(argc, argv); + // Initialize the ExaGeoStat Hardware + auto hardware = ExaGeoStatHardware(configurations.GetComputation(), configurations.GetCoresNumber(), configurations.GetGPUsNumbers()); + // Load data by either read from file or create synthetic data. + std::unique_ptr> data; + ExaGeoStat::ExaGeoStatLoadData(configurations, data); + // Modeling module. + ExaGeoStat::ExaGeoStatDataModeling(configurations, data); + // Prediction module + ExaGeoStat::ExaGeoStatPrediction(configurations, data); + + return 0; +} +``` +### R Example: +```R +hardware <- new(Hardware, computation, ncores, ngpus, p, q) +exageostat_data <- simulate_data(kernel=kernel, initial_theta=initial_theta, problem_size=problem_size, dts=dts, dimension=dimension) +estimated_theta <- model_data(data=exageostat_data, kernel=kernel, dts=dts, dimension=dimension,lb=lower_bound, ub=upper_bound, mle_itr=10) +predict_data(train_data=list(x, y, z_measurement), test_data=list(test_x, test_y), kernel=kernel, dts=dts, estimated_theta=estimated_theta) +``` + +> Please take a look at the end-to-end examples as a reference for using all the operations. + +## Contributing +Find detailed information on how to contribute to ExaGeoStatCPP [here](CONTRIBUTING.md) + +## References 1. Sameh Abdulah, Hatem Ltaief, Ying Sun, Marc G. Genton, and David E. Keyes. "ExaGeoStat: A high performance unified software for geostatistics on manycore systems." IEEE Transactions on Parallel and Distributed Systems 29, no. 12 ( @@ -190,12 +174,17 @@ References geostatistical modeling and prediction for extreme-scale environmental applications." In 2022 SC22: International Conference for High-Performance Computing, Networking, Storage and Analysis (SC), pp. 13-24. IEEE Computer Society, 2022. (ACM GORDON BELL PRIZE Finalist). - + 9. Sagnik Mondal, Sameh Abdulah, Hatem Ltaief, Ying Sun, Marc G. Genton, and David E. Keyes. "Tile low-rank approximations - of non-Gaussian space and space-time Tukey g-and-h random field likelihoods and predictions on large-scale systems." - Journal of Parallel and Distributed Computing 180 (2023): 104715. - + of non-Gaussian space and space-time Tukey g-and-h random field likelihoods and predictions on large-scale systems." + Journal of Parallel and Distributed Computing 180 (2023): 104715. + 10. Qinglei Cao, Sameh Abdulah, Hatem Ltaief, Marc G. Genton, David E. Keyes, and George Bosilca. "Reducing Data Motion and Energy Consumption of Geospatial Modeling Applications Using Automated Precision Conversion." In 2023 IEEE International Conference - on Cluster Computing (CLUSTER), IEEE, 2023. - + on Cluster Computing (CLUSTER), IEEE, 2023. + +## License +[BSD 3-Clause](LICENSE) + +## Handout +![ExaGeoStatCPP-handout.png](docs/ExaGeoStatCPP-handout.png) \ No newline at end of file diff --git a/USER_MANUAL.md b/USER_MANUAL.md index e8a35059..1ebfec7f 100644 --- a/USER_MANUAL.md +++ b/USER_MANUAL.md @@ -1,83 +1,104 @@ -ExaGeoStatCPP User Manual -================ +# ExaGeoStatCPP User Manual + +## Content + +1. [ExaGeoStatCPP v1.1.0](#ExaGeoStatCPP) +2. [Configurations of the software](#configurations) +3. [Building ExaGeoStatCPP](#building) +4. [Arguments](#arguments) +5. [List of Descriptors](#list-of-descriptors) +6. [Supported operations](#supported-operations) +7. [Manuals](#Manuals) +8. [Contributing](#contributing) + +## ExaGeoStatCPP +> Current Version of ExaGeoStatCPP: 1.1.0 +### Supported Operations: +1. (Data Generation): Generating large geospatial synthetic datasets using dense, Diagonal Super-Tile (DST) and Tile Low-Rank (TLR) approximation techniques. +2. (Data Modeling): Modeling large geospatial datasets on dense, DST and TLR approximation techniques through the Maximum likelihood Estimation (MLE) operation. +3. (Data Prediction): Predicting missing measurements on given locations using dense, DST, and TLR approximation techniques. +4. (MLOE/MMOM): Computing the Mean Loss of Efficiency (MLOE), Mean Misspecification of the Mean Square Error (MMOM), and Root mean square MOM (RMOM) to describe the prediction performance over the whole observation region. +5. (Fisher Information Matrix (FIM)): Quantifying the information content that a variable x carries about a parameter $\theta$ within a Gaussian distribution. + +### Supported Covariance Functions: +1. Univariate Matérn (Gaussian/Stationary) +2. Univariate Matérn with Nugget (Gaussian/Stationary) +3. Flexible Bivariate Matérn (Gaussian/Stationary) +4. Parsimonious Bivariate Matérn (Gaussian/Stationary) +5. Parsimonious trivariate Matérn (Gaussian/Stationary) +6. Univariate Space/Time Matérn (Gaussian/Stationary) +7. Bivariate Space/Time Matérn (Gaussian/Stationary) +8. Tukey g-and-h Univariate Matérn (non-Gaussian/Stationary) +9. Tukey g-and-h Univariate Power Exponential (non-Gaussian/Stationary) +> To add your kernel, please refer to [Contribution Guidelines](CONTRIBUTING.md) + +### Programming models: +1. MPI +2. Task-based programming models + +### External libraries: +1. NLOPT [https://nlopt.readthedocs.io/en/latest/](https://nlopt.readthedocs.io/en/latest/) +2. GSL [https://www.gnu.org/software/gsl/](https://www.gnu.org/software/gsl/) +3. HWLOC [https://www.open-mpi.org/projects/hwloc/](https://www.open-mpi.org/projects/hwloc/) +4. StarPU dynamic runtime system [https://starpu.gitlabpages.inria.fr/](https://starpu.gitlabpages.inria.fr/) +5. HCORE [https://github.com/ecrc/hcore](https://github.com/ecrc/hcore) +6. HiCMA [https://github.com/ecrc/hicma](https://github.com/ecrc/hicma) +7. Stars-H [https://github.com/ecrc/stars-h](https://github.com/ecrc/stars-h) +8. Chameleon [https://gitlab.inria.fr/solverstack/chameleon](https://gitlab.inria.fr/solverstack/chameleon) + +### Project Hierarchy + +* **```cmake```** A directory contains essential CMake modules that facilitate the importation and location of required dependencies. +* **```docs```** A directory contains all the necessary documents. +* **```examples```** A directory contains a comprehensive collection of demo code that illustrates the framework's application and demonstrates its features and capabilities. +* **```inst```** A directory contains all the system's header files, mirroring the structure of the src directory. +* **```man```** A directory contains all the R functions documentation. +* **```scripts```** A directory contains benchmarking scripts. +* **```src```** A directory contains all the source files. +* **```tests```** A directory contains all the test files and follows the same structure as the src folder. +* **```clean_build.sh```** A script is designed to compile the software tests once all dependencies are installed, and it is set to build everything by default. +* **```CMakeLists.txt```** The top-level CMake file to configure the build system. +* **```configure```** A Script used to generate the building system inside a 'bin' directory. -# Content - -1. Configurations of the software. -2. Building ExaGeoStatCPP. -3. Supported Covariance kernels. -4. Arguments. -5. List of Descriptors. -6. Supported operations. -7. Contributing ## Configurations -* Run help of config.sh to know the needed arguments to run with 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```** +* Run the help of `configure` to know the needed arguments for your specific options. + ``` bash + ./configure -h + ``` + +* To enable R interface, add `-r` disabled by default. +* 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 ` the default is project_path/installdir/_deps/ on Unix systems. +* To enable packaging system for distribution, add `-p` disabled by default. +* To enable showing code warnings, add `-w` disabled by default. +* To manually set mkl as blas vendor, add `--use-mkl`. MKL is required as blas vendor and it's automatically detected but in some environments it need to be manually set. -* To enable Verbose add **```-v```** - -* To enable debug mode add **```-d```** - -* To change the installation path of the dependencies use **```-i ```** - -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. -```commandline -./clean_build.sh -h -``` -* Run clean_build.sh to clean, Build and Install the project. -```commandline -./clean_build.sh -``` -* To enable verbose printing, Run the following command. -```commandline -./clean_build.sh -v -``` -* To enable building with a specific number of threads, run the following command. -```commandline -./clean_build.sh -j -``` +* Run the help of `clean_build.sh` to know additional argument options. -Supported Covariance Functions/ Kernels: -====================== - -1. univariate_matern_stationary -2. univariate_exp_non_gaussian -3. univariate_matern_dbeta -4. univariate_matern_ddbeta_beta -5. univariate_matern_ddbeta_nu -6. univariate_matern_ddnu_nu -7. univariate_matern_ddsigma_square -8. univariate_matern_ddsigma_square_beta -9. univariate_matern_ddsigma_square_nu -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 + ```bash + ./clean_build.sh -h + ``` +* Run clean_build.sh to build the project. + ```bash + ./clean_build.sh + ``` +* To enable the installation of the project, add `-i` disabled by default. +* To enable verbose printing, add `-v` disabled by default. +* To enable building with a specific number of threads, add `-j ` running with maximum number of threads by default. -## Arguments +## Arguments +These are the arguments that you can specify when running any C++ example. * {Mandatory} To set the problem size (N) --N= @@ -87,18 +108,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 +128,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 +156,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= @@ -194,8 +218,6 @@ Supported Covariance Functions/ Kernels: 8. DESCRIPTOR_C12UV : HiCMA descCUV descriptor 9. DESCRIPTOR_C22UV : HiCMA descCUV descriptor - - ## Supported Operations ### Provide Arguments @@ -218,45 +240,115 @@ for setting your arguments: synthetic_data_configurations.SetKernelName("BivariateSpacetimeMaternStationary"); synthetic_data_configurations.SetPrecision(exageostat::common::double); ``` -### Initialize the Hardware +### Initialize and Finalize the Hardware class To use any operations, you must initialize the hardware by selecting the number of CPUs and/or GPUs. ```c++ +// Initialize an instance of the hardware auto hardware = ExaGeoStatHardware(computation, number of cores, number of gpus); + +// Other code goes here + +// Finalize the hardware instance. +hardware.FinalizeHardware() ``` +The subsequent arguments are as follows: -### Synthetic and Real Data + - `computation`: Specifies the computation mode for the solver. + - `number of cores`: Indicates the number of CPU cores to be used for the solver. + - `number of gpus`: Specifies the number of GPUs to be used for the solver. -ExaGeoStatCPP can be used with different types of data, including: -Synthetic data: Synthetic data is generated by the software according to the user arguments. +##### *ExaGeoStat R Interface* +```R +hardware <- new(Hardware, computation, number of cores, number of gpus, p-grid, q-grid); +hardware$finalize_hardware() +``` +First arguement represents the name of the R class that wrapps its correponding C++ class, the rest of arguments are the same as the C++ version + +### Types of Data + +ExaGeoStatCPP can be used with 2 types of data: -Real data: ExaGeoStatCPP can also be used with real data, such as data from satellite imagery or weather sensors. Real data -can be used to train the software to predict the values of new data better. +- Synthetic data i.e. generated by the software according to the user arguments. +- Real data e.g. data from satellite imagery or weather sensors. Real data can be used to train the software to predict the values of new data better. -##### Synthetic Data Generation +#### Using Synthetic Data -After you provide your arguments with the Configurations module, you must do the following two steps: +Here we generate the data to be used by providing the needed arguments with the Configurations module, and then using the following code: ```c++ // Create a new ExaGeoStat data that holds the locations and descriptors data. -ExaGeoStatData 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); +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(configurations, data); ``` -##### Real Data +#### Using Real Data -- The Data Path must be passed to Configuration. +Here we use existing data by providing the path to it: - --log_path= -- Then do the following two steps. +- The Data Path must be passed to Configuration + ``` + data_path <- + ``` + +And then using the following code: + +```R +exageostat_data <- simulate_data(kernel=kernel, initial_theta=initial_theta, problem_size=problem_size, dts=dts, dimension=dimension, data_path=data_path) +``` + +### Location Getters + +ExaGeoStat support 2D and 3D spatial locations, and therefore we have getters for X, Y and Z coordinates. + +#### X-coordinate Getter ```c++ -// Create a new ExaGeoStat data that holds the locations data and descriptors data. -ExaGeoStatData 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); +double *locations_x = exageostat_data->GetLocations()->GetLocationX(); +``` + +#### Y-coordinate Getter +```c++ +double *locations_y = exageostat_data->GetLocations()->GetLocationY(); +``` + +#### Z-coordinate Getter +```c++ +double *locations_z = exageostat_data->GetLocations()->GetLocationZ(); +``` + +##### *ExaGeoStat R Interface* +```R +locations <- get_locations(data=exageostat_data) ``` +Returns all the locations values. The subsequent arguments are as follows: + +- `exagostat_data`: pointer to ExaGeoStatData object containing the spatial data. + +#### Descriptive Z Values Getter +This function is used to retrieve descriptive Z values from ExaGeoStat data based on type of descriptor. +```c++ +//in this example, we use a chameleon descriptor. Similar code can be used for hicma descriptor. +DescriptorType descriptor_type = CHAMELEON_DESCRIPTOR; +void *descriptor = exageostat_data->GetDescriptorData()->GetDescriptor(descriptor_type, DESCRIPTOR_Z).chameleon_desc; +double *desc_Z_values = exagostat_data->GetDescriptorData()->GetDescriptorMatrix(descriptor_type, descriptor); +``` +The used variables are as follows: + +- `descriptor_type`: enum denoting the descriptor type,e.g. CHAMELEON_DESCRIPTOR,HICMA_DESCRIPTOR. +- `exagostat_data`: pointer to ExaGeoStatData object containing the spatial data. +- `desc_Z_values`: pointer to descriptor matrix. + +##### *ExaGeoStat R Interface* +```R +desc_Z_values <- get_Z_measurement_vector(data=exageostat_data, type="chameleon") +``` +The subsequent arguments are as follows: + +- `exagostat_data`: pointer to ExaGeoStatData object containing the spatial data. +- `type`: string specifying the type of descriptor value to retrieve. ### Data Modeling @@ -266,36 +358,88 @@ To use data modeling, you have to do this operation. ExaGeoStat::ExaGeoStatDataModeling(hardware, configurations, data, z_matrix); ``` + +##### *ExaGeoStat R Interface* +```R +estimated_theta <- model_data(matrix=z_value, x=locations_x, y=locations_y, kernel=kernel, dts=dts, dimension=dimension,lb=lower_bound, ub=upper_bound, mle_itr=10, computation=computation, band=1) +``` +Or +```R +estimated_theta <- model_data(data=exageostat_data, kernel=kernel, dts=dts, dimension=dimension,lb=lower_bound, ub=upper_bound, mle_itr=10) +``` + ### Data Prediction ```c++ //You have to pass your arguments through the configurations, your hardware, and your data. -ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data, z_matrix); +ExaGeoStat::ExaGeoStatPrediction(configurations, data, z_matrix); +``` + + +##### *ExaGeoStat R Interface* +```R +predict_data(train_data=list(locations_x, locations_y, locations_z, z_value), test_data=list(test_x, test_y, test_z), kernel=kernel, dts=dts, estimated_theta=estimated_theta) ``` ### Fisher Function 1. Pass the fisher arguments to the Configurations. +``` +--fisher +``` - --fisher 2. Call the Data Prediction function. ```c++ // you have to pass your arguments through the configurations, your hardware and your data. -ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data, z_matrix); +ExaGeoStat::ExaGeoStatPrediction(configurations, data, z_matrix); ``` + + +##### *ExaGeoStat R Interface* +```R +fisher_matrix <- fisher(train_data=list(locations_x, locations_y, z_value), test_data=list(test_x, test_y), kernel=kernel, dts=dts, estimated_theta=estimated_theta) +``` + ### MLOE-MMOM Function 1. Pass the MLOE-MMOM arguments to the Configurations. - --mloe-mmom +``` +--mloe-mmom +``` + 2. Call the Data Prediction function. ```c++ // you have to pass your arguments through the configurations, your hardware and your data. -ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data, z_matrix); +ExaGeoStat::ExaGeoStatPrediction(configurations, data, z_matrix); ``` + + +##### *ExaGeoStat R Interface* +```R +result_mloe_mmom = mloe_mmom(train_data=list(locations_x, locations_y, z_value), test_data=list(test_x, test_y), kernel=kernel, dts=dts, estimated_theta=estimated_theta, true_theta=true_theta) +``` + ### IDW Function 1. Pass the IDW arguments to the Configurations. - --idw +``` +--idw +``` + 2. Call the Data Prediction function. ```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 +ExaGeoStat::ExaGeoStatPrediction(configurations, data, z_matrix); +``` + + +##### *ExaGeoStat R Interface* +```R +idw_error = idw(train_data=list(locations_x, locations_y, z_value), test_data=list(test_x, test_y), kernel=kernel, dts=dts, estimated_theta=estimated_theta, test_measurements=test_measurements) +``` + +## Manuals +- Find a detailed Manual for R functions in [ExaGeoStatCPP-R-Interface-Manual](docs/ExaGeoStat-R-Interface-Manual.pdf) +- Find a detailed Manual for C++ functions in [ExaGeoStatC-CPP-Manual](docs/ExaGeoStat-CPP-Manual.pdf) +- Doxygen Manual: https://ecrc.github.io/ExaGeoStatCPP + +## Contributing +[Contribution Guidelines](CONTRIBUTING.md) diff --git a/clean_build.sh b/clean_build.sh index 8d56b8a9..3cd86582 100755 --- a/clean_build.sh +++ b/clean_build.sh @@ -1,20 +1,21 @@ -#!/bin/bash -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +#! /bin/sh +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file clean_build.sh # @brief This script cleans and builds a software package called ExaGeoStat. -# @version 1.0.0 +# @version 1.1.0 # @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/FindPkgconfigLibrariesAbsolutePath.cmake b/cmake/FindPkgconfigLibrariesAbsolutePath.cmake index c1c94c1f..5eef4e0b 100644 --- a/cmake/FindPkgconfigLibrariesAbsolutePath.cmake +++ b/cmake/FindPkgconfigLibrariesAbsolutePath.cmake @@ -16,7 +16,7 @@ # Univ. of California Berkeley, # Univ. of Colorado Denver. # -# @version 1.0.0 +# @version 1.1.0 # @author Florent Pruvost # @date 06-04-2018 # diff --git a/cmake/FindR.cmake b/cmake/FindR.cmake new file mode 100644 index 00000000..94806380 --- /dev/null +++ b/cmake/FindR.cmake @@ -0,0 +1,172 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file FindR.cmake +# @brief Find the R and Rcpp library, Set some helpful variables. +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @author David Helmy +# @date 2024-01-14 + + +# Usage: +# find_package(R [REQUIRED] [QUIET] ) +# +# It sets the following variables: +# R _FOUND ... true if R and Rcpp is found on the system +# R_LIBRARIES ... full path to R and Rcpp library +# R_INCLUDE_DIRS ... R and Rcpp include directory +# +# The following variables will be checked by the function +# R_ROOT_PATH ... if set, the R libraries are exclusively searched +# under this path +# R_LIB_PATH ... if set, the Rcpp libraries are exclusively searched +# under this path + +if (DEFINED ENV{R_HOME}) + set(R_ROOT_PATH "$ENV{R_HOME}") + +else () + execute_process(COMMAND R RHOME OUTPUT_VARIABLE R_HOME) + string(REGEX REPLACE "\n" "" R_HOME "${R_HOME}") + set(R_ROOT_PATH "${R_HOME}") + +endif () + +if (NOT R_INCLUDE_PATH) + execute_process(COMMAND ${R_ROOT_PATH}/bin/Rscript -e "cat(Sys.getenv('R_INCLUDE_DIR'))" OUTPUT_VARIABLE R_INCLUDE_DIR) + string(REGEX REPLACE "\n" "" R_INCLUDE_DIR "${R_INCLUDE_DIR}") + set(R_INCLUDE_PATH "${R_INCLUDE_DIR}") + message(STATUS "R Include Path : " ${R_INCLUDE_PATH}) +endif () + + +if (NOT RCPP_LIB_PATH) + execute_process( + COMMAND ${R_ROOT_PATH}/bin/Rscript -e "cat(find.package('Rcpp'))" + OUTPUT_VARIABLE RCPP_LIB_PATH + RESULT_VARIABLE RSCRIPT_RESULT + ) + + # Check if the command was successful + if (RSCRIPT_RESULT EQUAL 0) + # Trim whitespace from both ends of the output + string(STRIP ${RCPP_LIB_PATH} RCPP_LIB_PATH) + message(STATUS "RCPP_LIB_PATH: ${RCPP_LIB_PATH}") + else() + message(FATAL_ERROR "Error running Rscript. Exit code: ${RSCRIPT_RESULT}") + endif() +endif () + +message(STATUS "R Home Path : " ${R_ROOT_PATH}) + +if (R_ROOT_PATH) + + if (APPLE) + find_library( + R_DYN_LIB + NAMES "libR.dylib" + PATHS ${R_ROOT_PATH} + PATH_SUFFIXES "lib" "lib64" "bin" + NO_DEFAULT_PATH + ) + + else () + #find libs + find_library( + R_DYN_LIB + NAMES "libR.so" + PATHS ${R_ROOT_PATH} + PATH_SUFFIXES "lib" "lib64" "bin" + NO_DEFAULT_PATH + ) + + endif () + + if (R_DYN_LIB MATCHES R_DYN_LIB-NOTFOUND) + set(R_DYN_LIB "") + message("R is built with no dynamic library support") + endif () + + set(R_LIB + ${R_DYN_LIB} + ) + +else () + error("R is not installed ") +endif (R_ROOT_PATH) + + +if (R_INCLUDE_PATH) + # find includes + find_path( + R_INCLUDE_DIRS + REQUIRED + NAMES "R.h" + PATHS ${R_INCLUDE_PATH} + PATH_SUFFIXES "include" + NO_DEFAULT_PATH + ) +endif () + +if (RCPP_LIB_PATH) + #find libs + find_library( + RCPP_LIB + REQUIRED + NAMES "Rcpp.so" + PATHS ${RCPP_LIB_PATH} + PATH_SUFFIXES "/libs" "/lib64" "/bin" + NO_DEFAULT_PATH + ) + + # find includes + find_path( + RCPP_INCLUDE_DIRS + REQUIRED + NAMES "Rcpp.h" + PATHS ${RCPP_LIB_PATH} + PATH_SUFFIXES "/include" + NO_DEFAULT_PATH + ) + + +else () + message("Rcpp is not installed ...") +endif (RCPP_LIB_PATH) + +set(R_INCLUDE + ${R_INCLUDE} + ${R_INCLUDE_DIRS} + ${RCPP_INCLUDE_DIRS} + ) + +add_library(R INTERFACE IMPORTED) + +if (R_LIB) + set_target_properties(R + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${R_INCLUDE}" + INTERFACE_LINK_LIBRARIES "${R_LIB}" + IMPORTED_LOCATION ${RCPP_LIB} + ) + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(R DEFAULT_MSG + R_INCLUDE R_LIB) + + include_directories(${R_INCLUDE}) + mark_as_advanced(R_INCLUDE R_INCLUDE_DIRS RCPP_INCLUDE_DIRS R_LIB RCPP_LIB) + +else () + set_target_properties(R + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${R_INCLUDE}" + IMPORTED_LOCATION ${RCPP_LIB} + ) + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(R DEFAULT_MSG + R_INCLUDE) + + include_directories(${R_INCLUDE}) + mark_as_advanced(R_INCLUDE R_INCLUDE_DIRS RCPP_INCLUDE_DIRS RCPP_LIB) +endif () \ No newline at end of file diff --git a/cmake/FindTMG.cmake b/cmake/FindTMG.cmake new file mode 100644 index 00000000..bdf63250 --- /dev/null +++ b/cmake/FindTMG.cmake @@ -0,0 +1,308 @@ +### +# +# @copyright (c) 2009-2014 The University of Tennessee and The University +# of Tennessee Research Foundation. +# All rights reserved. +# @copyright (c) 2012-2016 Inria. All rights reserved. +# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. +# @copyright (c) 2022 King Abdullah University of Science and Technology (KAUST). +# All rights reserved. +# +### +# +# - Find TMG include dirs and libraries +# Use this module by invoking find_package with the form: +# find_package(TMG +# [REQUIRED] # Fail with error if tmg is not found +# ) +# +# This module finds headers and tmg library. +# Results are reported in variables: +# TMG_FOUND - True if headers and requested libraries were found +# TMG_LINKER_FLAGS - list of required linker flags (excluding -l and -L) +# TMG_INCLUDE_DIRS - tmg include directories +# TMG_LIBRARY_DIRS - Link directories for tmg libraries +# TMG_LIBRARIES - tmg component libraries to be linked +# TMG_INCLUDE_DIRS_DEP - tmg + dependencies include directories +# TMG_LIBRARY_DIRS_DEP - tmg + dependencies link directories +# TMG_LIBRARIES_DEP - tmg libraries + dependencies +# +# The user can give specific paths where to find the libraries adding cmake +# options at configure (ex: cmake path/to/project -DTMG=path/to/tmg): +# TMG_DIR - Where to find the base directory of tmg +# TMG_INCDIR - Where to find the header files +# TMG_LIBDIR - Where to find the library files +# The module can also look for the following environment variables if paths +# are not given as cmake variable: TMG_DIR, TMG_INCDIR, TMG_LIBDIR + +#============================================================================= +# Copyright 2012-2013 Inria +# Copyright 2012-2013 Emmanuel Agullo +# Copyright 2012-2013 Mathieu Faverge +# Copyright 2012 Cedric Castagnede +# Copyright 2013-2016 Florent Pruvost +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file ECRC-Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of Ecrc, substitute the full +# License text for the above reference.) + + +if (NOT TMG_FOUND) + set(TMG_DIR "" CACHE PATH "Installation directory of TMG library") + if (NOT TMG_FIND_QUIETLY) + message(STATUS "A cache variable, namely TMG_DIR, has been set to specify the install directory of TMG") + endif() +endif() + + +# used to test a TMG function after +get_property(_LANGUAGES_ GLOBAL PROPERTY ENABLED_LANGUAGES) +if (NOT _LANGUAGES_ MATCHES Fortran) + include(CheckFunctionExists) +else (NOT _LANGUAGES_ MATCHES Fortran) + include(CheckFortranFunctionExists) +endif (NOT _LANGUAGES_ MATCHES Fortran) + +# TMG depends on LAPACK anyway, try to find it +if (NOT LAPACK_FOUND) + if(TMG_FIND_REQUIRED) + find_package(LAPACKEXT REQUIRED) + else() + find_package(LAPACKEXT) + endif() +endif() + +# TMG depends on LAPACK +if (LAPACK_FOUND) + + # check if a tmg function exists in the LAPACK lib + set(CMAKE_REQUIRED_LIBRARIES "${LAPACK_LINKER_FLAGS};${LAPACK_LIBRARIES}") + include(CheckFunctionExists) + include(CheckFortranFunctionExists) + unset(TMG_WORKS CACHE) + if (NOT _LANGUAGES_ MATCHES Fortran) + check_function_exists(dlarnv TMG_WORKS) + else (NOT _LANGUAGES_ MATCHES Fortran) + check_fortran_function_exists(dlarnv TMG_WORKS) + endif (NOT _LANGUAGES_ MATCHES Fortran) + if (TMG_WORKS) + unset(TMG_WORKS CACHE) + if (NOT _LANGUAGES_ MATCHES Fortran) + check_function_exists(dlagsy TMG_WORKS) + else (NOT _LANGUAGES_ MATCHES Fortran) + check_fortran_function_exists(dlagsy TMG_WORKS) + endif (NOT _LANGUAGES_ MATCHES Fortran) + mark_as_advanced(TMG_WORKS) + endif() + set(CMAKE_REQUIRED_LIBRARIES) + + if(TMG_WORKS) + if(NOT TMG_FIND_QUIETLY) + message(STATUS "Looking for tmg: test with lapack succeeds") + endif() + # test succeeds: TMG is in LAPACK + set(TMG_LIBRARIES "${LAPACK_LIBRARIES}") + if (LAPACK_LIBRARY_DIRS) + set(TMG_LIBRARY_DIRS "${LAPACK_LIBRARY_DIRS}") + endif() + if(LAPACK_INCLUDE_DIRS) + set(TMG_INCLUDE_DIRS "${LAPACK_INCLUDE_DIRS}") + endif() + if (LAPACK_LINKER_FLAGS) + set(TMG_LINKER_FLAGS "${LAPACK_LINKER_FLAGS}") + endif() + else() + + if(NOT TMG_FIND_QUIETLY) + message(STATUS "Looking for tmg : test with lapack fails") + message(STATUS "Looking for tmg : try to find it elsewhere") + endif() + # test fails: try to find TMG lib exterior to LAPACK + + # Looking for lib tmg + # ------------------- + + # Add system library paths to search lib + # -------------------------------------- + unset(_lib_env) + set(ENV_TMG_DIR "$ENV{TMG_DIR}") + set(ENV_TMG_LIBDIR "$ENV{TMG_LIBDIR}") + if(ENV_TMG_LIBDIR) + list(APPEND _lib_env "${ENV_TMG_LIBDIR}") + elseif(ENV_TMG_DIR) + list(APPEND _lib_env "${ENV_TMG_DIR}") + list(APPEND _lib_env "${ENV_TMG_DIR}/lib") + else() + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") + else() + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") + else() + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") + endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + endif() + endif() + list(REMOVE_DUPLICATES _lib_env) + + # Try to find the tmg lib in the given paths + # ---------------------------------------------- + + # call cmake macro to find the lib path + if(TMG_LIBDIR) + set(TMG_tmg_LIBRARY "TMG_tmg_LIBRARY-NOTFOUND") + find_library(TMG_tmg_LIBRARY + NAMES tmglib tmg + HINTS ${TMG_LIBDIR} ) + else() + if(TMG_DIR) + set(TMG_tmg_LIBRARY "TMG_tmg_LIBRARY-NOTFOUND") + find_library(TMG_tmg_LIBRARY + NAMES tmglib tmg + HINTS ${TMG_DIR} + PATH_SUFFIXES lib lib32 lib64 ) + else() + set(TMG_tmg_LIBRARY "TMG_tmg_LIBRARY-NOTFOUND") + find_library(TMG_tmg_LIBRARY + NAMES tmglib tmg + HINTS ${_lib_env} ) + endif() + endif() + mark_as_advanced(TMG_tmg_LIBRARY) + + # If found, add path to cmake variable + # ------------------------------------ + if (TMG_tmg_LIBRARY) + get_filename_component(tmg_lib_path ${TMG_tmg_LIBRARY} PATH) + # set cmake variables (respects naming convention) + set(TMG_LIBRARIES "${TMG_tmg_LIBRARY}") + set(TMG_LIBRARY_DIRS "${tmg_lib_path}") + else () + set(TMG_LIBRARIES "TMG_LIBRARIES-NOTFOUND") + set(TMG_LIBRARY_DIRS "TMG_LIBRARY_DIRS-NOTFOUND") + if(NOT TMG_FIND_QUIETLY) + message(STATUS "Looking for tmg -- lib tmg not found") + endif() + endif () + + if (TMG_LIBRARY_DIRS) + list(REMOVE_DUPLICATES TMG_LIBRARY_DIRS) + endif () + + # check a function to validate the find + if(TMG_LIBRARIES) + + set(REQUIRED_LDFLAGS) + set(REQUIRED_INCDIRS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) + + # TMG + if (TMG_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${TMG_INCLUDE_DIRS}") + endif() + if (TMG_LIBRARY_DIRS) + set(REQUIRED_LIBDIRS "${TMG_LIBRARY_DIRS}") + endif() + set(REQUIRED_LIBS "${TMG_LIBRARIES}") + # LAPACK + if (LAPACK_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${LAPACK_INCLUDE_DIRS}") + endif() + if (LAPACK_LIBRARY_DIRS) + list(APPEND REQUIRED_LIBDIRS "${LAPACK_LIBRARY_DIRS}") + endif() + list(APPEND REQUIRED_LIBS "${LAPACK_LIBRARIES}") + if (LAPACK_LINKER_FLAGS) + list(APPEND REQUIRED_LDFLAGS "${LAPACK_LINKER_FLAGS}") + endif() + + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}") + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + + # test link + unset(TMG_WORKS CACHE) + include(CheckFunctionExists) + include(CheckFortranFunctionExists) + if (NOT _LANGUAGES_ MATCHES Fortran) + check_function_exists(dlarnv TMG_WORKS) + else (NOT _LANGUAGES_ MATCHES Fortran) + check_fortran_function_exists(dlarnv TMG_WORKS) + endif (NOT _LANGUAGES_ MATCHES Fortran) + if (TMG_WORKS) + unset(TMG_WORKS CACHE) + if (NOT _LANGUAGES_ MATCHES Fortran) + check_function_exists(dlagsy TMG_WORKS) + else (NOT _LANGUAGES_ MATCHES Fortran) + check_fortran_function_exists(dlagsy TMG_WORKS) + endif (NOT _LANGUAGES_ MATCHES Fortran) + mark_as_advanced(TMG_WORKS) + endif() + + if(TMG_WORKS) + # save link with dependencies + set(TMG_LIBRARIES_DEP "${REQUIRED_LIBS}") + set(TMG_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}") + set(TMG_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}") + set(TMG_LINKER_FLAGS "${REQUIRED_LDFLAGS}") + list(REMOVE_DUPLICATES TMG_LIBRARY_DIRS_DEP) + list(REMOVE_DUPLICATES TMG_INCLUDE_DIRS_DEP) + list(REMOVE_DUPLICATES TMG_LINKER_FLAGS) + else() + if(NOT TMG_FIND_QUIETLY) + message(STATUS "Looking for tmg: test of dlarnv and dlagsy with tmg and lapack libraries fails") + message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") + message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") + message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") + endif() + endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_LIBRARIES) + endif(TMG_LIBRARIES) + + endif() + +else() + + if(NOT TMG_FIND_QUIETLY) + message(STATUS "TMG requires LAPACK but LAPACK has not been found." + "Please look for LAPACK first.") + endif() + +endif() + +if (TMG_LIBRARIES) + list(GET TMG_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + if (${first_lib_path} MATCHES "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)") + string(REGEX REPLACE "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)" "" not_cached_dir "${first_lib_path}") + set(TMG_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of TMG library" FORCE) + else() + set(TMG_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of TMG library" FORCE) + endif() +endif() +mark_as_advanced(TMG_DIR) +mark_as_advanced(TMG_DIR_FOUND) + +# check that TMG has been found +# ------------------------------- +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(TMG DEFAULT_MSG + TMG_LIBRARIES + TMG_WORKS) diff --git a/cmake/ImportBLAS.cmake b/cmake/ImportBLAS.cmake new file mode 100644 index 00000000..8b2bec5d --- /dev/null +++ b/cmake/ImportBLAS.cmake @@ -0,0 +1,36 @@ +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file ImportBLAS.cmake +# @brief This file searches for the BLAS library and includes it if not already included. +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @date 2023-03-12 + +# Set basic configuration variables for the BLAS library. +# 'name' is set to "BLAS", which is the identifier used for the dependency throughout the script. +set(name "BLAS") +# 'tag' specifies the version tag of the BLAS library to fetch, indicating a specific state of the source code in the repository. +set(tag "v0.3.21") +# 'version' specifies the version of the BLAS library. This may be used to ensure compatibility or meet specific requirements. +set(version "0.3.21") +# 'flag' can be used to pass additional flags to the configure/make commands when building the dependency, but it's empty here. +set(flag "") +# 'is_cmake' is a boolean flag indicating whether the BLAS library uses CMake for its build system. It's set to ON, meaning it does. +set(is_cmake ON) +# 'is_git' is a boolean flag indicating whether the BLAS library's source code is hosted in a git repository. It's set to ON. +set(is_git ON) +# 'auto_gen' is a boolean flag indicating whether to use autogen scripts for the configuration process. It's set to OFF here. +set(auto_gen OFF) +# 'url' specifies the location of the BLAS library's source code repository. +set(url "https://github.com/xianyi/OpenBLAS") + +# Include the 'ImportDependency' macro script located in the 'macros' directory. +# This macro is responsible for importing and possibly installing the dependency. +include(macros/ImportDependency) +# Call the 'ImportDependency' macro with the previously set configuration parameters. +# This macro checks if BLAS is already available; if not, it proceeds to fetch, configure, build, and install it. +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) +# Print a message indicating the completion of the BLAS setup process. +message(STATUS "${name} done") diff --git a/cmake/ImportBLASPP.cmake b/cmake/ImportBLASPP.cmake new file mode 100644 index 00000000..480b2e5c --- /dev/null +++ b/cmake/ImportBLASPP.cmake @@ -0,0 +1,65 @@ +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file ImportBLASPP.cmake +# @brief This file searches for the BLAS++ library and includes it if not already included. +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @date 2024-02-04 + +# Include the ImportBLAS script, which presumably sets up basic BLAS dependencies. +include(ImportBLAS) + +# Set up basic configuration variables for locating or installing BLAS++. +# `name` variable set to 'blaspp' to represent the BLAS++ library throughout the script. +set(name blaspp) +# Convert the name to uppercase and store it in `capital_name` for display purposes. +string(TOUPPER ${name} capital_name) +# Set the `tag` variable to specify the version of BLAS++ to be used or installed. +set(tag "v2023.01.00") +# Set the `url` variable to the location of the BLAS++ repository on GitHub. +set(url "https://github.com/icl-utk-edu/blaspp") +# Configure the directory where BLAS++ will be installed or found. +set(${name}_DIR "${CMAKE_INSTALL_PREFIX}/${capital_name}/${name}-build/") + +# Display a header message indicating the start of the BLAS++ setup process. +message("") +message("---------------------------------------- ${capital_name}") +# Output the version of BLAS++ being checked for or installed. +message(STATUS "Checking for ${capital_name} with Version ${version}") + +# Check if the BLAS++ target is already defined in the current CMake environment. +IF (NOT TARGET ${name}) + # Include the FindPkgConfig module to use pkg-config for finding installed libraries. + include(FindPkgConfig) + # Attempt to find the pkg-config utility quietly. + find_package(PkgConfig QUIET) + # Quietly search for the BLAS++ package, without specifying components or version. + find_package(${name} ${version} QUIET COMPONENTS ${components}) + + # If BLAS++ is found, output its location and libraries linked. + if (${name}_FOUND) + message(" Found ${capital_name}; ${${name}_DIR} ${${name}_LIBRARIES}") + else () + # If BLAS++ is not found, indicate it and proceed to install it. + message(" Can't find ${capital_name}, Installing it instead ..") + # Include the FetchContent module to download external projects during the configure stage. + include(FetchContent) + # Set the base directory for downloading and building the external project. + set(FETCHCONTENT_BASE_DIR ${CMAKE_INSTALL_PREFIX}/${capital_name}) + # Declare the external project (BLAS++) with its Git repository and specific tag. + FetchContent_Declare(${name} GIT_REPOSITORY "${url}" GIT_TAG "${tag}") + # Make the declared content available, effectively downloading and setting up BLAS++. + FetchContent_MakeAvailable(${name}) + + endif () +else () + # If the BLAS++ target is already defined, indicate that it's already included. + message(STATUS "${capital_name} already included") +endif () + +# Add BLAS++ to the list of libraries to be linked against by setting `LIBS`. +set(LIBS ${name} ${LIBS}) +# Final status message indicating completion of the BLAS++ setup. +message(STATUS "${name} done") 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..263a54bf 100644 --- a/cmake/ImportCatch2.cmake +++ b/cmake/ImportCatch2.cmake @@ -1,40 +1,34 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file 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.1.0 # @author Mahmoud ElKarargy -# @author Sameh Abdulah # @date 2023-03-13 -message("") -message("---------------------------------------- Catch2") -message(STATUS "Checking for Catch2") -include(macros/BuildDependency) +# Sets the 'name' variable to "Catch2", identifying the dependency being imported. +set(name "Catch2") +# Specifies the 'tag' variable as "v3.3.2", which likely corresponds to a specific release or version of Catch2. +set(tag "v3.3.2") +# Sets the 'version' variable to "3.3.2", defining the expected version of Catch2 to be used in the project. +set(version "3.3.2") +# Initializes the 'flag' variable as an empty string, which could be used for additional configuration options during the build or installation process. +set(flag "") +# Sets the 'is_cmake' flag to ON, indicating that Catch2 uses CMake as its build system. +set(is_cmake ON) +# Sets the 'is_git' flag to ON, suggesting that Catch2's source code is hosted in a git repository. +set(is_git ON) +# Initializes the 'auto_gen' flag to OFF, implying that there's no need for auto-generation scripts (like autogen.sh) in the building process of Catch2. +set(auto_gen OFF) +# Defines the 'url' variable with the GitHub repository URL of Catch2, specifying the source location from which Catch2 will be fetched. +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 () +# Includes the 'ImportDependency' macro script located in the 'macros' directory. This script is responsible for checking the presence of the specified dependency and importing it if necessary. +include(macros/ImportDependency) +# Calls the 'ImportDependency' macro with the previously set variables as arguments. This macro will check for Catch2's presence, and if it's not found, it will attempt to fetch and install it using the provided details. +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) +# Logs a message indicating the completion of the Catch2 import process. +message(STATUS "${name} done") diff --git a/cmake/ImportChameleon.cmake b/cmake/ImportChameleon.cmake index 4d19a5ea..650db197 100644 --- a/cmake/ImportChameleon.cmake +++ b/cmake/ImportChameleon.cmake @@ -1,65 +1,45 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file 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.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-13 -message("") -message("---------------------------------------- Chameleon") -message(STATUS "Checking for Chameleon") -include(macros/BuildDependency) - -if (NOT TARGET CHAMELEON_FOUND) - include(FindPkgConfig) - find_package(PkgConfig QUIET) - find_package(CHAMELEON QUIET) - - # 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}) +# Set basic configuration variables for the Chameleon library. +# 'name' is set to "CHAMELEON", which is the identifier used for the dependency throughout the script. +set(name "CHAMELEON") +# 'tag' specifies the version tag of the Chameleon library to fetch, indicating a specific state of the source code in the repository. +set(tag "v1.1.0") +# 'version' specifies the version of the Chameleon library. This may be used to ensure compatibility or meet specific requirements. +set(version "1.1.0") +# 'flag' can be used to pass additional flags to the configure/make commands when building the dependency. Flags here are for CUDA, BLAS vendor, MPI, StarPU, and disabling testing. +set(flag -DCHAMELEON_USE_CUDA=${USE_CUDA} \-DBLA_VENDOR=${BLA_VENDOR} \-DCHAMELEON_USE_MPI=${USE_MPI} \-DCHAMELEON_SCHED_STARPU=ON \-DCHAMELEON_ENABLE_TESTING=OFF) +# 'is_cmake' is a boolean flag indicating whether the Chameleon library uses CMake for its build system. It's set to ON, meaning it does. +set(is_cmake ON) +# 'is_git' is a boolean flag indicating whether the Chameleon library's source code is hosted in a git repository. It's set to ON. +set(is_git ON) +# 'auto_gen' is a boolean flag indicating whether to use autogen scripts for the configuration process. It's set to OFF here. +set(auto_gen OFF) +# 'url' specifies the location of the Chameleon library's source code repository. +set(url "https://gitlab.inria.fr/solverstack/chameleon.git") + +# Include the 'ImportDependency' macro script located in the 'macros' directory. +# This macro is responsible for importing and possibly installing the dependency. +include(macros/ImportDependency) +# Call the 'ImportDependency' macro with the previously set configuration parameters. +# This macro checks if CHAMELEON is already available; if not, it proceeds to fetch, configure, build, and install it. +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) + +# Additional include directories for Chameleon are specified, ensuring the project can find Chameleon's headers. +# The AFTER keyword specifies that these directories should be searched after the default ones. include_directories(AFTER ${CHAMELEON_DIR_FOUND}/include/coreblas) include_directories(${CHAMELEON_DIR_FOUND}/chameleon-src) +include_directories(${CHAMELEON_DIR_FOUND}) -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") +# Print a status message indicating the completion of Chameleon's inclusion process. +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..9a159744 100644 --- a/cmake/ImportGSL.cmake +++ b/cmake/ImportGSL.cmake @@ -1,51 +1,41 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file 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.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-16 -message("") -message("---------------------------------------- GSL") -message(STATUS "Checking for GSL") - -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 () - -# Add the GSL library to the project's list of libraries. +# Configurations for integrating the GSL (GNU Scientific Library) +# 'name' is assigned "GSL" to identify the GNU Scientific Library within this script. +set(name "GSL") +# 'tag' specifies the version tag "v2.7.1" for the GSL library, indicating the exact version to be used. +set(tag "v2.7.1") +# 'version' sets "2.7.1" as the version of the GSL library, ensuring compatibility with project requirements. +set(version "2.7.1") +# 'flag' is available for additional configuration options during build or installation, but remains empty here. +set(flag "") +# 'is_cmake' indicates whether GSL uses CMake for building. It is set to OFF, implying an alternative build system is used. +set(is_cmake OFF) +# 'is_git' denotes if GSL's source code is hosted in a Git repository. It is set to OFF, suggesting the source is obtained from a different location. +set(is_git OFF) +# 'auto_gen' signifies the need for autogen scripts in the build process. Here, it is set to OFF, indicating they are not needed. +set(auto_gen OFF) +# 'url' provides the download location for the GSL source code, pointing to the GNU archive. +set(url "https://ftp.gnu.org/gnu/gsl/gsl-2.7.1.tar.gz") + +# Include the 'ImportDependency' macro, responsible for managing the GSL library's import and setup process. +include(macros/ImportDependency) +# Execute the 'ImportDependency' macro with the previously established parameters to handle the detection, downloading, and integration of GSL. +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) + +# Add GSL to the project's list of linked libraries, making its functionality accessible within the project. list(APPEND LIBS gsl) -include_directories(${GSL_INCLUDE_DIRS}) -link_directories(${GSL_LIBRARY_DIRS}) -message("${GSL_LIBRARIES}") -message(STATUS "GSL done") +# Output a message signaling the successful integration of the GSL library into the project. +message(STATUS "${name} done") + diff --git a/cmake/ImportHCore.cmake b/cmake/ImportHCore.cmake new file mode 100644 index 00000000..0595ceb1 --- /dev/null +++ b/cmake/ImportHCore.cmake @@ -0,0 +1,37 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file ImportHCore.cmake +# @brief Checks for the Hcore library and includes it in the project if it is not already present. +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @author Sameh Abdulah +# @date 2023-03-15 + +# Configurations for the HCORE library +# 'name' is set to "HCORE", serving as the identifier for the dependency throughout this script. +set(name "HCORE") +# 'tag' defines the version tag of the HCORE library to be fetched, represents a specific snapshot of the source code in the repository. +set(tag "v0.1.3") +# 'version' indicates the version of the HCORE library, used to ensure compatibility or fulfill certain requirements. +set(version "0.1.3") +# 'flag' is intended for passing additional flags to the configure/make commands during the building of the dependency, but is left empty here. +set(flag "") +# 'is_cmake' is a boolean flag that denotes whether the HCORE library utilizes CMake for its build process. Here, it's set to ON. +set(is_cmake ON) +# 'is_git' is a boolean flag that signifies if the source code for HCORE is maintained in a git repository. This is set to ON. +set(is_git ON) +# 'auto_gen' is a boolean flag that indicates whether autogen scripts are required for the configuration process. It is set to OFF in this context. +set(auto_gen OFF) +# 'url' provides the location of the HCORE library's source code repository. +set(url "https://github.com/ecrc/hcore.git") + +# The 'ImportDependency' macro script, located in the 'macros' directory, is included. This macro is crucial for importing and potentially installing the dependency. +include(macros/ImportDependency) +# The 'ImportDependency' macro is invoked with the configuration parameters set above to handle the detection, fetching, and setup of HCORE. +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) +# A message is logged to indicate the successful completion of the HCORE setup process. +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..bb879d66 100644 --- a/cmake/ImportHiCMA.cmake +++ b/cmake/ImportHiCMA.cmake @@ -1,66 +1,42 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file ImportHiCMA.cmake # @brief Find and include HiCMA library as a dependency. -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-13 -message("") -message("---------------------------------------- Hicma") -message(STATUS "Checking for HiCMA") -include(macros/BuildDependency) - -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 HiCMA headers in the project. -include_directories(${HICMA_INCLUDE_DIRS_DEP}) +# Configuration settings for integrating the HICMA library into the project +# 'name' sets the identifier for the HICMA library within this script to "HICMA". +set(name "HICMA") +# 'tag' specifies "v1.0.0" as the version tag of HICMA, denoting a specific release to be fetched. +set(tag "v1.0.0") +# 'version' defines "1.0.0" as the version of the HICMA library, ensuring compatibility with project requirements. +set(version "1.0.0") +# 'flag' is used to pass additional configuration options during the build, specifically for enabling or disabling MPI support based on the project's needs. +set(flag -DHICMA_USE_MPI=${USE_MPI}) +# 'is_cmake' indicates that HICMA uses CMake for its build system, set to ON. +set(is_cmake ON) +# 'is_git' denotes that HICMA's source code is hosted on a Git repository, set to ON. +set(is_git ON) +# 'auto_gen' signals whether autogen scripts are necessary for the build process; it is set to OFF for HICMA. +set(auto_gen OFF) +# 'url' provides the GitHub repository URL for HICMA, specifying where the source code can be cloned from. +set(url "https://github.com/ecrc/hicma.git") + +# The 'ImportDependency' macro, located in the 'macros' directory, is included. This macro handles the import and setup of the HICMA library. +include(macros/ImportDependency) +# The 'ImportDependency' macro is invoked with the previously defined parameters to manage the detection, fetching, and setup of HICMA. +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) + +# Directories containing HiCMA headers are included in the project, ensuring that HiCMA's functions and types are accessible. include_directories(${HICMA_LIBDIR}/../hicma-src/hicma_ext) +include_directories(${HICMA_LIBDIR}/../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 () +# A status message is displayed to indicate the successful inclusion of the HiCMA library into the project. +message(STATUS "HiCMA done") -message(STATUS "HiCMA done") \ No newline at end of file diff --git a/cmake/ImportHwloc.cmake b/cmake/ImportHwloc.cmake index 019f8c82..5f632725 100644 --- a/cmake/ImportHwloc.cmake +++ b/cmake/ImportHwloc.cmake @@ -1,56 +1,38 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file ImportHwloc.cmake # @brief Find and include Hwloc library as a dependency. -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-15 +# Configuration settings for integrating the HWLOC library +# 'name' sets the identifier for the HWLOC library within this script to "HWLOC". +set(name "HWLOC") +# 'tag' specifies "hwloc-2.10.0" as the version tag, identifying a specific release of HWLOC to be used. +set(tag "hwloc-2.10.0") +# 'version' defines "2.10.0" as the version of HWLOC, ensuring it meets project compatibility requirements. +set(version "2.10.0") +# 'flag' is available for additional build configuration options but remains empty for HWLOC. +set(flag "") +# 'is_cmake' indicates whether HWLOC uses CMake for its build system. It's set to OFF, suggesting an alternative build system is used. +set(is_cmake OFF) +# 'is_git' denotes that HWLOC's source code is maintained in a Git repository, set to ON. +set(is_git ON) +# 'auto_gen' signals the need for running autogen scripts as part of the build process for HWLOC, set to ON. +set(auto_gen ON) +# 'url' provides the GitHub repository URL for HWLOC, indicating the source code's location. +set(url "https://github.com/open-mpi/hwloc") + +# Includes the 'ImportDependency' macro script, located in the 'macros' directory, responsible for handling the import and setup of dependencies. +include(macros/ImportDependency) +# The 'ImportDependency' macro is called with the configuration parameters above to manage the detection, fetching, and setup of HWLOC. +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) + +# A message is logged to indicate the successful integration of the HWLOC library into the project. +message(STATUS "${name} done") -message("") -message("---------------------------------------- Hwloc") -message(STATUS "Checking for Hwloc") - -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") diff --git a/cmake/ImportLapack.cmake b/cmake/ImportLapack.cmake index c0e77417..da0ab62b 100644 --- a/cmake/ImportLapack.cmake +++ b/cmake/ImportLapack.cmake @@ -1,42 +1,38 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file ImportLapack.cmake # @brief Find and include LAPACK library as a dependency. -# @version 1.0.0 +# @version 1.1.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") +# Configuration settings for the integration of the LAPACK library +# 'name' is designated as "LAPACK" to identify the LAPACK library within the scope of this script. +set(name "LAPACK") +# 'tag' is set to "v0.3.21", specifying the particular version tag of LAPACK to be utilized. +set(tag "v0.3.21") +# 'version' denotes the LAPACK library version as "0.3.21", aligned with the tag for consistency in versioning. +set(version "0.3.21") +# 'flag' is intended for any additional flags needed for configuration or building, but is left blank in this case. +set(flag "") +# 'is_cmake' is a boolean flag indicating that LAPACK uses CMake for its build process, set to ON. +set(is_cmake ON) +# 'is_git' signifies that the source code for LAPACK is available in a Git repository, set to ON. +set(is_git ON) +# 'auto_gen' indicates whether autogen scripts are necessary for the configuration process; it is set to OFF for LAPACK. +set(auto_gen OFF) +# 'url' provides the repository URL for LAPACK, pointing to the location where the source code can be accessed. +set(url "https://github.com/xianyi/OpenBLAS") -include(macros/BuildDependency) +# The 'ImportDependency' macro script from the 'macros' directory is included, which facilitates the import and setup of dependencies. +include(macros/ImportDependency) +# The 'ImportDependency' macro is executed with the above-defined parameters to manage the detection, retrieval, and configuration of LAPACK. +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) +# A status message is output to indicate the successful completion of the LAPACK setup process. +message(STATUS "${name} done") - 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") 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..b3ce08c6 100644 --- a/cmake/ImportNLOPT.cmake +++ b/cmake/ImportNLOPT.cmake @@ -1,56 +1,38 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file ImportNLOPT.cmake # @brief Find and include NLOPT library as a dependency. -# @version 1.0.0 +# @version 1.1.0 # @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) +# Configuration settings for the integration of the NLOPT library +# 'name' is assigned to "NLOPT", serving as the identifier for this library within the script. +set(name "NLOPT") +# 'tag' defines "v2.7.1" as the version tag of NLOPT, indicating the specific release to be utilized. +set(tag "v2.7.1") +# 'version' specifies "2.7.1" as the version of the NLOPT library, ensuring compatibility with the project's requirements. +set(version "2.7.1") +# 'flag' is intended for additional configuration options during the build process. A space is placed as a placeholder. +set(flag " ") +# 'is_cmake' indicates that NLOPT uses CMake for its build system, which is set to ON. +set(is_cmake ON) +# 'is_git' denotes that the NLOPT source code is hosted in a Git repository, which is set to ON. +set(is_git ON) +# 'auto_gen' signals whether autogen scripts are required for the build process, which is set to OFF for NLOPT. +set(auto_gen OFF) +# 'url' provides the location of the NLOPT source code repository on GitHub. +set(url "https://github.com/stevengj/nlopt") + +# The 'ImportDependency' macro script, located in the 'macros' directory, is included for managing the import and setup of the NLOPT library. +include(macros/ImportDependency) +# The 'ImportDependency' macro is invoked with the above-defined parameters to handle the detection, fetching, and integration of NLOPT into the project. +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) + +# A status message is outputted to indicate the successful integration of the NLOPT library into the project. +message(STATUS "${name} done") - # 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 ..") - - # 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 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..523ebc06 100644 --- a/cmake/ImportStarPu.cmake +++ b/cmake/ImportStarPu.cmake @@ -1,78 +1,52 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file ImportSTARPU.cmake # @brief Find and include STARPU library as a dependency. -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-13 -message("") -message("---------------------------------------- StarPU") -message(STATUS "Checking for StarPU") +# Configuration settings for integrating the STARPU library into the project +# 'name' is set to "STARPU" to identify this specific library within the script. +set(name "STARPU") +# 'tag' specifies "starpu-1.3.10" as the version tag, indicating the exact version of STARPU to be used. +set(tag "starpu-1.3.10") +# 'version' sets "1.3.10" as the version of the STARPU library, ensuring project compatibility. +set(version "1.3.10") + +# Conditional setting of 'flag' based on project configurations for CUDA and MPI. +if (USE_CUDA AND USE_MPI) + # Sets flags for enabling CUDA and MPI, and disables OpenCL, documentation build, and export dynamic when both CUDA and MPI are used. + set(flag \--enable-cuda \--disable-opencl \--enable-shared \--disable-build-doc \--disable-export-dynamic \--enable-mpi) +elseif(USE_CUDA) + # Sets flags for enabling CUDA and shared libraries, and disables OpenCL, documentation build, export dynamic, and MPI when only CUDA is used. + set(flag \--enable-cuda \--disable-opencl \--enable-shared \--disable-build-doc \--disable-export-dynamic \--disable-mpi) +elseif(USE_MPI) + # Sets flags for enabling MPI and shared libraries, and disables CUDA, OpenCL, documentation build, and export dynamic when only MPI is used. + set(flag \--disable-cuda \--disable-opencl \--enable-shared \--disable-build-doc \--disable-export-dynamic \--enable-mpi) +else() + # Sets flags for enabling shared libraries, and disables CUDA, OpenCL, documentation build, export dynamic, and MPI when neither CUDA nor MPI is used. + set(flag \--disable-cuda \--disable-opencl \--enable-shared \--disable-build-doc \--disable-export-dynamic \--disable-mpi) +endif() + +# 'is_cmake' is set to OFF indicating STARPU does not use CMake as its primary build system. +set(is_cmake OFF) +# 'is_git' is set to ON, denoting that STARPU's source code is maintained in a Git repository. +set(is_git ON) +# 'auto_gen' is set to ON, signaling the need for autogen scripts to be run as part of the build process. +set(auto_gen ON) +# 'url' provides the location of the STARPU source code repository. +set(url "https://gitlab.inria.fr/starpu/starpu.git") + +# Include the 'ImportDependency' macro script, responsible for handling the import and setup of dependencies. +include(macros/ImportDependency) +# The 'ImportDependency' macro is invoked with the configuration parameters to manage the detection, fetching, and integration of STARPU. +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "${STARPU_COMPONENT_LIST}" ${is_cmake} ${is_git} ${auto_gen}) + +# A message is logged to indicate the successful integration of the STARPU library into the project. +message(STATUS "${name} done") -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") diff --git a/cmake/ImportStarsH.cmake b/cmake/ImportStarsH.cmake index 585fecbb..0fd9cde5 100644 --- a/cmake/ImportStarsH.cmake +++ b/cmake/ImportStarsH.cmake @@ -1,86 +1,37 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt # @brief Find and include STARSH library as a dependency. -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-13 -message("") -message("---------------------------------------- Stars-H") -message(STATUS "Checking for STARSH") -include(macros/BuildDependency) - -if (NOT TARGET STARSH_FOUND) - # Try to find STARSH. - include(FindPkgConfig) - find_package(PkgConfig QUIET) - find_package(STARSH QUIET) - - # 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 +# Configuration parameters for integrating the STARSH library +# 'name' is set to "STARSH" to identify the STARSH library within this script. +set(name "STARSH") +# 'tag' specifies "v0.3.1" as the version tag for STARSH, denoting the exact release to be used. +set(tag "v0.3.1") +# 'version' sets "0.3.1" as the version of the STARSH library, ensuring it aligns with project requirements. +set(version "0.3.1") +# 'flag' is used for additional build configuration options, specifically disabling StarPU and optionally enabling MPI. +set(flag \-DSTARPU=OFF \-DMPI=${USE_MPI}) +# 'is_cmake' indicates that STARSH uses CMake as its build system, set to ON. +set(is_cmake ON) +# 'is_git' denotes that the source code for STARSH is hosted on a Git repository, set to ON. +set(is_git ON) +# 'auto_gen' signals whether autogen scripts are needed for the build process; it is set to OFF for STARSH. +set(auto_gen OFF) +# 'url' provides the GitHub repository URL for STARSH, specifying the source code's location. +set(url "https://github.com/ecrc/stars-h.git") + +# The 'ImportDependency' macro, located in the 'macros' directory, is included to manage the import and setup of the STARSH library. +include(macros/ImportDependency) +# The 'ImportDependency' macro is called with the configuration parameters set above to manage the detection, fetching, and setup of STARSH. +ImportDependency(${name} ${tag} ${version} ${url} "${flag}" "" ${is_cmake} ${is_git} ${auto_gen}) + +# A message is output to indicate the successful integration of the STARSH library into the project. +message(STATUS "${name} done") diff --git a/cmake/macros/BuildDependency.cmake b/cmake/macros/BuildDependency.cmake index 5edee634..50f5c125 100644 --- a/cmake/macros/BuildDependency.cmake +++ b/cmake/macros/BuildDependency.cmake @@ -1,96 +1,115 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file BuildDependency.cmake # @brief Fetches, builds, and installs a dependency. -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy -# @author Sameh Abdulah -# @date 2023-03-12 +# @author Amr Nasr +# @date 2024-02-04 -# @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. -# 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. +# 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. + +# Define the macro BuildDependency with parameters for handling various aspects of dependency management. +macro(BuildDependency raw_name url tag flags is_using_cmake is_using_git auto_generation) + + # Convert the raw dependency name to lowercase and uppercase for different uses and set them as 'name' and 'capital_name'. string(TOLOWER ${raw_name} name) string(TOUPPER ${raw_name} capital_name) - # Fetch the dependency, depending on whether it's a git repo or not. + # Log the start of the fetch process for the dependency, including its name, tag, and source URL. message(STATUS "Fetching ${name} ${tag} from ${url}") + # Include the CMake module for downloading and updating content during the configure step. include(FetchContent) - set(FETCHCONTENT_BASE_DIR ${EXAGEOSTAT_INSTALL_PREFIX}/${capital_name}/) - if (ISGIT) + # Set the base directory for fetched content to a directory within the install prefix, named after the dependency. + set(FETCHCONTENT_BASE_DIR ${CMAKE_INSTALL_PREFIX}/${capital_name}) + + # Check if the dependency is hosted in a git repository and declare it accordingly with FetchContent, using git-specific options. + if (${is_using_git}) FetchContent_Declare(${name} GIT_REPOSITORY "${url}" GIT_TAG "${tag}" - GIT_SHALLOW TRUE - GIT_PROGRESS TRUE + GIT_SHALLOW TRUE # For a shallow clone, fetching only the history needed for the specified tag + GIT_PROGRESS TRUE # Show progress during the clone ) else () + # If not using git, declare the dependency for FetchContent using a direct URL (e.g., for a tarball). FetchContent_Declare(${name} URL "${url}") endif () + + # Make the content available, effectively downloading it if necessary. FetchContent_Populate(${name}) - # Set up build paths and create directory for build artifacts. - set(${name}_srcpath ${EXAGEOSTAT_INSTALL_PREFIX}/${capital_name}/${name}-src) + # Set variables for the source path, binary (build) path, and installation path of the dependency. + 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}) + # Ensure the binary path directory exists. file(MAKE_DIRECTORY ${${name}_binpath}) - # Configure subproject. - if (ISCMAKE) - execute_process(COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${EXAGEOSTAT_INSTALL_PREFIX}/${capital_name}/ ${FLAGS} + # Configure the project. If using CMake, run cmake command with specified flags and install prefix within the binary path. + if (${is_using_cmake}) + execute_process(COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}/${capital_name} -DCMAKE_C_FLAGS=-fPIC ${flags} ${${name}_srcpath} - WORKING_DIRECTORY - ${${name}_binpath}) + WORKING_DIRECTORY ${${name}_binpath}) else () - if (AUTO_GEN) + # For non-CMake projects, run autogen.sh if auto_generation is true, then configure the project with specified flags. + if (${auto_generation}) execute_process(COMMAND ./autogen.sh WORKING_DIRECTORY ${${name}_srcpath} - COMMAND_ERROR_IS_FATAL ANY) + COMMAND_ERROR_IS_FATAL ANY) # Halt on error 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) + COMMAND_ERROR_IS_FATAL ANY) # Halt on error endif () - # Build and install subproject. + # Include the ProcessorCount module to determine the number of CPUs for parallel build and install commands. include(ProcessorCount) ProcessorCount(N) - if (ISCMAKE) + # Build the project using make, with parallel jobs based on processor count. This applies to both CMake and non-CMake projects. + if (${is_using_cmake}) execute_process(COMMAND make -j ${N} WORKING_DIRECTORY ${${name}_binpath} - COMMAND_ERROR_IS_FATAL ANY) + COMMAND_ERROR_IS_FATAL ANY) # Halt on error + # Install the built project, also with parallel jobs. execute_process(COMMAND make install -j ${N} WORKING_DIRECTORY ${${name}_binpath} - COMMAND_ERROR_IS_FATAL ANY) + COMMAND_ERROR_IS_FATAL ANY) # Halt on error else () execute_process(COMMAND make -j ${N} WORKING_DIRECTORY ${${name}_srcpath} - COMMAND_ERROR_IS_FATAL ANY) + COMMAND_ERROR_IS_FATAL ANY) # Halt on error execute_process(COMMAND make install -j ${N} WORKING_DIRECTORY ${${name}_srcpath} - COMMAND_ERROR_IS_FATAL ANY) + COMMAND_ERROR_IS_FATAL ANY) # Halt on error endif () - # Set environment variables and include/link to the installation directory of the dependency. + # Set environment variables for dynamic and static linking as well as include paths, pointing to the dependency's installation directory. set(ENV{LD_LIBRARY_PATH} "${${name}_installpath}/lib:${${name}_installpath}/lib64:$ENV{LD_LIBRARY_PATH}") 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 +132,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..1e6e71b0 --- /dev/null +++ b/cmake/macros/ImportDependency.cmake @@ -0,0 +1,85 @@ +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file ImportDependency.cmake +# @brief CMake script for importing and building external dependencies. +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @author Amr Nasr +# @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. + +# Define a macro named ImportDependency for handling external dependencies. The macro checks for the dependency's presence and installs it if missing. +macro(ImportDependency name tag version url flag components is_cmake is_git auto_gen) + + # Check if the installation prefix is set to a system path (like /usr/) and warn the user about potential need for administrative privileges. + 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 the dependency name to uppercase for consistent messaging. + string(TOUPPER ${name} capital_name) + # Begin a section in the output to visually separate the handling of this dependency. + message("") + message("---------------------------------------- ${capital_name}") + # Log the attempt to check for the specified version of the dependency. + message(STATUS "Checking for ${capital_name} with Version ${version}") + + # Include the previously defined BuildDependency macro script for potential use. + include(macros/BuildDependency) + + # If the dependency has not already been targeted for building in the current CMake process, proceed to check its presence. + IF (NOT TARGET ${name}) + # Use the FindPkgConfig module to potentially use pkg-config for finding installed libraries. + include(FindPkgConfig) + find_package(PkgConfig QUIET) + # Attempt to find the specified version of the package quietly, without generating much output. + find_package(${name} ${version} QUIET COMPONENTS ${components}) + + # If the package is found, output a message detailing the found configuration. + if (${name}_FOUND) + message(" Found ${capital_name}; ${${name}_DIR} ${${name}_LIBRARIES}") + else () + # If the package is not found, notify and invoke BuildDependency to install it. + message(" Can't find ${capital_name}, Installing it instead ..") + BuildDependency(${name} ${url} ${tag} "${flag}" ${is_cmake} ${is_git} ${auto_gen}) + # After attempting installation, forcibly attempt to find the package again, this time requiring its presence. + find_package(${name} ${version} REQUIRED COMPONENTS ${components}) + endif () + else () + # If the dependency target already exists, log that it's already been included. + message(STATUS "${capital_name} already included") + endif () + + # Setup link and include directories based on the found or installed package configuration. + # Add the dependency's library directories to the link directories for the current CMake target. + link_directories(${${name}_LIBRARY_DIRS_DEP}) + link_directories(${${name}_LIBRARY_DIRS}) + # Add the dependency's include directories to the include path. + include_directories(${${name}_INCLUDE_DIRS}) + include_directories(AFTER ${${name}_INCLUDE_DIRS_DEP}) + + # If the dependency is not GSL, append its libraries to the list of libraries to be linked against. + if(NOT ${name} STREQUAL "GSL") + list(APPEND LIBS ${${name}_LIBRARIES}) + endif() + # Append any additional dependency libraries to the list of libraries. + list(APPEND LIBS ${${name}_LIBRARIES_DEP}) + +endmacro() diff --git a/cmake/toolchains/CudaToolchain.cmake b/cmake/toolchains/CudaToolchain.cmake index f9edaa67..89721ad9 100644 --- a/cmake/toolchains/CudaToolchain.cmake +++ b/cmake/toolchains/CudaToolchain.cmake @@ -1,11 +1,11 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CudaToolchain.cmake # @brief This file is used to set up the CUDA toolchain for compilation. -# @version 1.0.0 +# @version 1.1.0 # @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/cmake/toolchains/GccToolchain.cmake b/cmake/toolchains/GccToolchain.cmake index d02499de..82864184 100644 --- a/cmake/toolchains/GccToolchain.cmake +++ b/cmake/toolchains/GccToolchain.cmake @@ -1,10 +1,10 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file GccToolchain.cmake # @brief This file is used to set up the GCC toolchain for compilation. -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-12 diff --git a/config.sh b/config.sh deleted file mode 100755 index 1f7d390b..00000000 --- a/config.sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/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.0 -# @author Mahmoud ElKarargy -# @date 2023-01-30 - -# Set variables and default values -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -BLUE='\033[0;34m' -NC='\033[0m' - -INSTALL_PREFIX=$PWD/installdir/_deps -PROJECT_SOURCE_DIR=$(dirname "$0") -BUILDING_TESTS="OFF" -BUILDING_EXAMPLES="OFF" -USING_HiCMA="OFF" -VERBOSE=OFF -USE_CUDA="OFF" -USE_MPI="OFF" -BLAS_VENDOR="" - -# Parse command line options -while getopts ":tevhHi:cms" opt; do - case $opt in - i) ##### Define installation path ##### - echo -e "${YELLOW}Installation path set to $OPTARG.${NC}" - INSTALL_PREFIX=$OPTARG - ;; - t) ##### Building tests enabled ##### - echo -e "${GREEN}Building tests enabled.${NC}" - BUILDING_TESTS="ON" - ;; - e) ##### Building examples enabled ##### - echo -e "${GREEN}Building examples enabled.${NC}" - BUILDING_EXAMPLES="ON" - ;; - H) ##### Using HiCMA ##### - echo -e "${GREEN}Using HiCMA.${NC}" - USING_HiCMA="ON" - ;; - c)##### Using cuda enabled ##### - echo -e "${GREEN}Cuda enabled ${NC}" - USE_CUDA=ON - ;; - m)##### Using MPI enabled ##### - echo -e "${GREEN}MPI enabled ${NC}" - USE_MPI=ON - ;; - v) ##### printing full output of make ##### - echo -e "${YELLOW}printing make with details.${NC}" - VERBOSE=ON - ;; - s) ##### Passing Blas vendor with mkl ##### - echo -e "${YELLOW}MKL as a Blas vendor${NC}" - BLAS_VENDOR="Intel10_64lp" - ;; - \?) ##### Error unknown option ##### - echo "Option $OPTARG parameter is unknown, please -h for help" - exit 1 - ;; - :) ##### Error in an option ##### - echo "Option $OPTARG requires parameter(s)" - exit 0 - ;; - h) ##### Prints the help ##### - echo "Usage of $(basename "$0"):" - 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" "-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" "-h :" "Help." - echo "" - exit 1 - ;; - esac -done - -if [ -z "$BUILDING_TESTS" ]; then - BUILDING_TESTS="OFF" - echo -e "${RED}Building tests disabled.${NC}" -fi - -if [ -z "$BUILDING_EXAMPLES" ]; then - BUILDING_EXAMPLES="OFF" - echo -e "${RED}Building examples disabled.${NC}" -fi - -echo -e "${BLUE}Installation path set to $INSTALL_PREFIX.${NC}" - -if [ -z "$USING_HiCMA" ]; then - echo -e "${RED}Using HiCMA is disabled.${NC}" -fi - -if [ -z "$USE_CUDA" ]; then - USE_CUDA="OFF" - echo -e "${RED}Using CUDA disabled${NC}" -fi - -if [ -z "$USE_MPI" ]; then - USE_MPI="OFF" - echo -e "${RED}Using MPI disabled${NC}" -fi - -echo "" -echo -e "${YELLOW}Use -h to print the usages of exageostat-cpp flags.${NC}" -echo "" -rm -rf bin/ -mkdir -p bin/installdir - -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}" \ - -DCMAKE_VERBOSE_MAKEFILE:BOOL=${VERBOSE} \ - -DUSE_CUDA="${USE_CUDA}" \ - -DUSE_MPI="${USE_MPI}" \ - -DBLA_VENDOR="${BLAS_VENDOR}" \ - -H"${PROJECT_SOURCE_DIR}" \ - -B"${PROJECT_SOURCE_DIR}/bin" \ - -G "Unix Makefiles" diff --git a/configure b/configure new file mode 100755 index 00000000..5e6a92f2 --- /dev/null +++ b/configure @@ -0,0 +1,274 @@ +#! /bin/sh +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file configure +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @author David Helmy +# @date 2024-02-04 + +# Set variables and default values +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +INSTALL_PREFIX=$PWD/installdir/_deps + +# Function to install CMake from source +install_cmake() { + echo "CMake not found. Installing CMake from source..." + + # Create a temporary directory for building CMake + temp_dir=$(mktemp -d) + cd "$temp_dir" || exit 1 + + # Download CMake source code + wget https://github.com/Kitware/CMake/releases/download/v3.28.1/cmake-3.28.1.tar.gz + + # Extract the source code + tar -xzvf cmake-3.28.1.tar.gz + + # Enter the extracted directory + cd cmake-3.28.1 || exit 1 + + # Configure, build, and install CMake to the specified location + ./bootstrap --prefix="$INSTALL_PREFIX" --parallel=2 -- -DCMAKE_USE_OPENSSL=OFF + make -j 2 + sudo make install + + # Clean up + cd "$temp_dir" || exit 1 + rm -rf "$temp_dir" +} + +# shellcheck disable=SC2164 +cd "$(dirname "$0")" +# Get the operating system type using uname +OS_TYPE=$(uname) + +if [ "$OS_TYPE" = "darwin"* ]; then + ABSOLUTE_PATH=$([[ $1 == /* ]] && echo "$1" || echo "$PWD/${1#./}") +else + ABSOLUTE_PATH=$(dirname "$(realpath "$0")") +fi + +BUILDING_TESTS="OFF" +BUILDING_HEAVY_TESTS="OFF" +BUILDING_EXAMPLES="OFF" +USING_HiCMA="OFF" +VERBOSE="OFF" +USE_CUDA="OFF" +USE_MPI="OFF" +BLAS_VENDOR="" +PACKAGE="OFF" +RUNTIME_TYPE="starpu" +SHOW_WARNINGS="OFF" +COMPILE_FLAGS="-Wl,--no-as-needed -w -fpic" +DEVELOPER_WARNINGS="-Wno-dev" + +for arg in "$@" +do + case $arg in + --use-mkl) + echo "${GREEN}MKL as a BLA vendor${NC}" + BLAS_VENDOR="Intel10_64lp" + ;; + --use-parsec) + echo "${GREEN}Parsec as a runtime${NC}" + RUNTIME_TYPE="parsec" + ;; + *) + # Collect non-option arguments as a space-delimited string + params="$params $arg" + ;; + esac +done + +# Reset positional parameters to collected non-option arguments +eval set -- $params + +# Parse command line options +while getopts ":tevhHi:cmpTwr" opt; do + case $opt in + i) ##### Define installation path ##### + echo "${YELLOW}Installation path set to $OPTARG.${NC}" + INSTALL_PREFIX=$OPTARG + ;; + t) ##### Building tests enabled ##### + echo "${GREEN}Building tests enabled.${NC}" + BUILDING_TESTS="ON" + ;; + T) ##### Building heavy tests enabled ##### + echo "${GREEN}Building heavy tests enabled.${NC}" + BUILDING_HEAVY_TESTS="ON" + ;; + e) ##### Building examples enabled ##### + echo "${GREEN}Building examples enabled.${NC}" + BUILDING_EXAMPLES="ON" + ;; + H) ##### Using HiCMA ##### + echo "${GREEN}Using HiCMA.${NC}" + USING_HiCMA="ON" + ;; + c) ##### Using cuda enabled ##### + echo "${GREEN}Cuda enabled ${NC}" + USE_CUDA="ON" + ;; + m) ##### Using MPI enabled ##### + echo "${GREEN}MPI enabled ${NC}" + USE_MPI="ON" + ;; + v) ##### printing full output of make ##### + echo "${GREEN}printing make with details.${NC}" + VERBOSE="ON" + ;; + p) ##### Enabling packaging system for distribution ##### + echo "${GREEN}CPACK enabled${NC}" + PACKAGE=ON + ;; + w) ##### Enable showing all the warnings ##### + echo "${GREEN}Showing Warnings is enabled${NC}" + SHOW_WARNINGS="ON" + ;; + r) ##### Enable R and Rcpp support ##### + echo "${GREEN}R is enabled${NC}" + USE_R="ON" + ;; + \?) ##### Error unknown option ##### + echo "Option $OPTARG parameter is unknown, please -h for help" + exit 1 + ;; + :) ##### Error in an option ##### + echo "Option $OPTARG requires parameter(s)" + exit 0 + ;; + h) ##### Prints the help ##### + echo "Usage of $(basename "$0"):" + echo "" + printf "%20s %s\n" "--use-mkl :" "to use MKL as a BLA vendor." + printf "%20s %s\n" "--use-parsec :" "to use parsec runtime." + 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" "-p :" "to enable a packaging system for distribution." + printf "%20s %s\n" "-w :" "to enable showing warnings." + printf "%20s %s\n" "-r :" "to enable R support" + printf "%20s %s\n" "-h :" "Help." + echo "" + exit 1 + ;; + esac +done + +if [ -z "$BUILDING_TESTS" ]; then + BUILDING_TESTS="OFF" + echo "${RED}Building tests disabled.${NC}" +fi + +if [ -z "$BUILDING_EXAMPLES" ]; then + BUILDING_EXAMPLES="OFF" + echo "${RED}Building examples disabled.${NC}" +fi + +if [ -z "$USING_HiCMA" ]; then + echo "${RED}Using HiCMA is disabled.${NC}" +fi + +if [ -z "$USE_CUDA" ]; then + USE_CUDA="OFF" + echo "${RED}Using CUDA disabled${NC}" +fi + +if [ -z "$USE_MPI" ]; then + USE_MPI="OFF" + echo "${RED}Using MPI disabled${NC}" +fi + +if [ "$SHOW_WARNINGS" = "ON" ]; then + COMPILE_FLAGS="$COMPILE_FLAGS -W" + DEVELOPER_WARNINGS="" +elif [ "$SHOW_WARNINGS" = "OFF" ]; then + COMPILE_FLAGS="$COMPILE_FLAGS -w" +fi + +if [ -z "$USE_R" ]; then + USE_R="OFF" + echo "${RED}Using R is disabled${NC}" +fi + +echo "${BLUE}Installation path set to $INSTALL_PREFIX.${NC}" +echo "" +echo "${YELLOW}Use -h to print the usages of exageostat-cpp flags.${NC}" +echo "" + +# cleaning bin +rm -rf bin/ +mkdir bin/ + +# Check if cmake is installed +if command -v cmake /dev/null 2>&1; then + # Save the installation directory to the variable + cmake_install_dir=$(command -v cmake | xargs dirname) + echo "CMake is installed in: $cmake_install_dir" + cmake_command_bin=cmake +elif [ -x "/Applications/CMake.app/Contents/bin/cmake" ]; then + echo "CMake found in /Applications/CMake.app/Contents/bin/cmake." + cmake_install_dir="/Applications/CMake.app/Contents/bin" + cmake_command_bin="${cmake_install_dir}/cmake" +else + echo "Installing CMake from source" + mkdir "${ABSOLUTE_PATH}/inst/_deps/" + install_dir="${ABSOLUTE_PATH}/inst/_deps/" + install_cmake "$install_dir" + cmake_command_bin="${ABSOLUTE_PATH}/inst/_deps/bin/cmake" +fi + +"$cmake_command_bin" "$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}" \ + -DUSE_R="${USE_R}" \ + -DBLA_VENDOR="${BLAS_VENDOR}" \ + -DCREATE_PACKAGE="${PACKAGE}" \ + -DRUNTIME_TYPE="${RUNTIME_TYPE}" \ + -DBUILD_SHARED_LIBS=OFF \ + -H"${ABSOLUTE_PATH}" \ + -B"${ABSOLUTE_PATH}/bin" \ + -G "Unix Makefiles" \ + -DCMAKE_CXX_FLAGS_DEBUG="$COMPILE_FLAGS" \ + -DCMAKE_CXX_FLAGS_RELEASE="$COMPILE_FLAGS" + +if [ "$USE_R" = "ON" ]; then + # Change to the bin directory, or exit if it doesn't exist. + cd bin/ || { + echo "Error: bin directory not found." + exit 1 + } + + # Clean the directory and build the code with the specified options. + "$cmake_command_bin" --build . -j 10 + + if [ "$OS_TYPE" = "darwin"* ]; then + cp "${ABSOLUTE_PATH}/bin/src/libExaGeoStatCPP.dylib" "${ABSOLUTE_PATH}/src/ExaGeoStatCPP.so" || echo "Failed: libExaGeoStatCPP.dylib -> src" + else + cp "${ABSOLUTE_PATH}/bin/src/libExaGeoStatCPP.so" "${ABSOLUTE_PATH}/src/ExaGeoStatCPP.so" || echo "Failed: libExaGeoStatCPP.so -> src" + fi + + rm -rf "${ABSOLUTE_PATH:?}/bin/"* + +fi diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 39b38388..28885b94 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,11 +1,11 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt # @brief Configures and generates documentation using Doxygen. -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-03-12 diff --git a/docs/ExaGeoStat-CPP-Manual.pdf b/docs/ExaGeoStat-CPP-Manual.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bb2a09ab647d91b587d9a7e3f08e94218f287972 GIT binary patch literal 1078489 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

8Z72s=)D#eW3uZxqxDD2e8disx2dfrcp!?F# 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 z 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�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 z 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­H&zCg5Q-x!mg)5>qM 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

Y*rl+gjuj_q=XvEqfvld_B}%*1Idg-7q| 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≺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%0AC7&kTB6bWW?k@W+3J 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∋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 literal 0 HcmV?d00001 diff --git a/docs/ExaGeoStat-R-Interface-Manual.pdf b/docs/ExaGeoStat-R-Interface-Manual.pdf new file mode 100644 index 0000000000000000000000000000000000000000..940ad14d018f6820777f6f675f6fa39b2962f754 GIT binary patch literal 115185 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


jiit$DnT7dT}&eE-UcDGbo5f8F_uEJh* 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

nY1Tl05V!DY9|LFI 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 z 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%0D<3DPOLI`;zw_jB3|-Jlt&8p|WA9 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 literal 0 HcmV?d00001 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/CMakeLists.txt b/examples/CMakeLists.txt index fd6d1ce3..450c6d91 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,15 +1,18 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt # @brief Includes subdirectories for different modules of the ExaGeoStat software package. -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy -# @date 2023-01-31 +# @date 2024-02-24 # Include subdirectories for end-to-end module, configurations module and data-generators module. -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/end-to-end) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/configurations) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/data-generators) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/data-loader) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/descriptors) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/end-to-end) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/hardware) diff --git a/examples/configurations/CMakeLists.txt b/examples/configurations/CMakeLists.txt index 769ba295..e0ea9f99 100644 --- a/examples/configurations/CMakeLists.txt +++ b/examples/configurations/CMakeLists.txt @@ -1,16 +1,18 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @brief Defines an executable and links it with the ExaGeoStat library and other libraries. -# @version 1.0.0 +# @brief Defines an executables and links them with the ExaGeoStat library and other libraries. +# @version 1.1.0 # @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..4ff37b1a --- /dev/null +++ b/examples/configurations/RunningWithDifferentConfigurations.cpp @@ -0,0 +1,74 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file RunningWithDifferentConfigurations.cpp + * @brief Demonstrates running ExaGeoStat with various configurations. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-01-04 +**/ + +#include +#include + +using namespace exageostat::api; +using namespace exageostat::configurations; + +/** + * @brief Main entry point for the Data Generation & Data Modeling program. + * @details Initializes configuration settings, loads data, and performs data modeling with ExaGeoStat. + * The program demonstrates running ExaGeoStat with two different sets of configurations to showcase the software's capability in handling various statistical models and computational settings. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * + */ +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 + ExaGeoStatHardware hardware(configurations.GetComputation(), configurations.GetCoresNumber(),configurations.GetGPUsNumbers()); + // Load data by either read from file or create synthetic data. + std::unique_ptr> data; + ExaGeoStat::ExaGeoStatLoadData(configurations, data); + // Modeling module. + ExaGeoStat::ExaGeoStatDataModeling(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(configurations2, data); + // Modeling module. + ExaGeoStat::ExaGeoStatDataModeling(configurations2, data); + + return 0; +} diff --git a/examples/configurations/ConfigurationModule.cpp b/examples/configurations/SetupConfigurations.cpp similarity index 82% rename from examples/configurations/ConfigurationModule.cpp rename to examples/configurations/SetupConfigurations.cpp index 975b0897..284500d6 100644 --- a/examples/configurations/ConfigurationModule.cpp +++ b/examples/configurations/SetupConfigurations.cpp @@ -1,22 +1,20 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** -* @file 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. -* @version 1.0.0 +* to obtain user-defined configurations. +* @version 1.1.0 * @author Mahmoud ElKarargy -* @date 2023-01-31 +* @date 2024-02-04 * **/ -#include - -#include +#include #include using namespace std; @@ -26,22 +24,20 @@ 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. - * + * @details This example 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. - * @return The status code of the program. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * */ 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 +97,6 @@ int main(int argc, char **argv) { } VERBOSE("VERBOSE ACTIVATED") + return 0; } \ No newline at end of file diff --git a/examples/data-generators/CMakeLists.txt b/examples/data-generators/CMakeLists.txt index d90f9abe..99324d4d 100644 --- a/examples/data-generators/CMakeLists.txt +++ b/examples/data-generators/CMakeLists.txt @@ -1,11 +1,11 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt # @brief CMake file for building the Example_Synthetic_Data_Generation executable. -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @date 2023-03-04 diff --git a/examples/data-generators/SyntheticDataGeneration.cpp b/examples/data-generators/SyntheticDataGeneration.cpp index 1c4323df..e4df4645 100644 --- a/examples/data-generators/SyntheticDataGeneration.cpp +++ b/examples/data-generators/SyntheticDataGeneration.cpp @@ -1,34 +1,30 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file SyntheticLocationsGeneration.cpp * @brief This file contains the main function for generating synthetic Locations for ExaGeoStat - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy - * @date 2023-03-04 + * @date 2024-02-04 **/ -#include - #include -using namespace std; - -using namespace exageostat::configurations; using namespace exageostat::generators; using namespace exageostat::common; -using namespace exageostat::hardware; using namespace exageostat::kernels; +using namespace exageostat::configurations; /** * @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. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * */ int main(int argc, char **argv) { @@ -39,18 +35,19 @@ int main(int argc, char **argv) { synthetic_data_configurations.InitializeDataGenerationArguments(); // initialize ExaGeoStat Hardware. - auto hardware = ExaGeoStatHardware(synthetic_data_configurations.GetComputation(), - synthetic_data_configurations.GetCoresNumber(), - synthetic_data_configurations.GetGPUsNumbers()); + ExaGeoStatHardware hardware(synthetic_data_configurations.GetComputation(), + 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( + std::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, *pKernel); // Define a struct to hold pointers to the x, y, and z coordinates of the generated data struct DataPointers { double *x; @@ -59,9 +56,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,10 +73,11 @@ 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; - return 0; } \ No newline at end of file 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/data-loader/CMakeLists.txt b/examples/data-loader/CMakeLists.txt new file mode 100644 index 00000000..4e1c4ae5 --- /dev/null +++ b/examples/data-loader/CMakeLists.txt @@ -0,0 +1,16 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @brief Defines an executables and link it with the ExaGeoStat library and other libraries. +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @date 2024-02-14 + +# Define the target executable +add_executable(Example_CSV_Loader ${CMAKE_CURRENT_SOURCE_DIR}/CSVLoader.cpp) + +# Link the target executable with the project and any additional libraries +target_link_libraries(Example_CSV_Loader PRIVATE ${PROJECT_NAME}_INTERFACE) diff --git a/examples/data-loader/CSVLoader.cpp b/examples/data-loader/CSVLoader.cpp new file mode 100644 index 00000000..701f3b10 --- /dev/null +++ b/examples/data-loader/CSVLoader.cpp @@ -0,0 +1,79 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file CSVLoader.cpp + * @brief Example of the CSVLoader class + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-18 +**/ + +#include + +using namespace std; + +using namespace exageostat::kernels; +using namespace exageostat::generators; +using namespace exageostat::dataLoader::csv; +using namespace exageostat::configurations; + +/** + * @brief Main entry point demonstrating the usage of CSVLoader in ExaGeoStat. + * @details The program demonstrates initializing configuration settings, creating synthetic data, setting up ExaGeoStat hardware, initializing kernels, and then using the + * CSVLoader to read spatial and measurement data from a CSV file. The spatial dimensions can be 2D or 3D, and the data read includes locations (X, Y, [Z]) and measurements. + * @param argc The number of command-line arguments. + * @param argv The array of command-line arguments. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * + */ + +int main(int argc, char **argv) { + + LOGGER("** Example of CSV Loader **") + + // Create and Initialize a new configurations object. + Configurations configurations; + configurations.InitializeArguments(argc, argv); + + // Generate Data and Log it into file + configurations.SetLogger(true); + configurations.InitializeDataGenerationArguments(); + + // Initialize ExaGeoStat Hardware and Kernel. + auto hardware = ExaGeoStatHardware(configurations.GetComputation(), configurations.GetCoresNumber(), + configurations.GetGPUsNumbers()); + + Kernel *kernel = exageostat::plugins::PluginRegistry>::Create( + configurations.GetKernelName(), configurations.GetTimeSlot()); + int kernel_variables = kernel->GetVariablesNumber(); + + // Create a unique pointer to a DataGenerator object and generate data + configurations.SetIsSynthetic(true); + unique_ptr> synthetic_generator = DataGenerator::CreateGenerator(configurations); + auto data = synthetic_generator->CreateData(configurations, *kernel); + + // Read csv file using data loader + vector measurements_vector; + vector x_locations; + vector y_locations; + vector z_locations; + + auto loader = CSVLoader::GetInstance(); + loader->ReadData(configurations, measurements_vector, x_locations, y_locations, z_locations, kernel_variables); + + // Print loaded data + LOGGER("Data Loaded:") + for (int i = 0; i < x_locations.size(); i++) { + LOGGER_PRECISION("X: " << x_locations[i] << " Y: " << y_locations[i], 18) + if (configurations.GetDimension() != exageostat::common::Dimension2D) { + LOGGER_PRECISION(" Z: " << z_locations[i], 18) + } + LOGGER_PRECISION(" z: " << measurements_vector[i] << "\n", 18) + } + + delete kernel; + return 0; +} diff --git a/examples/descriptors/CMakeLists.txt b/examples/descriptors/CMakeLists.txt new file mode 100644 index 00000000..eb3cf6c2 --- /dev/null +++ b/examples/descriptors/CMakeLists.txt @@ -0,0 +1,24 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @brief Defines an executables and links them with the ExaGeoStat library and other libraries. +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @date 2024-02-14 + +# Define the target executable +add_executable(Example_Chameleon_Descriptor ChameleonDescriptor.cpp) + +if (USE_HICMA) + add_executable(Example_Hicma_Descriptor HicmaDescriptor.cpp) + add_executable(Example_Chameleon_Hicma_Converter ChameleonToHicmaConverter.cpp) + + target_link_libraries(Example_Hicma_Descriptor PRIVATE ${PROJECT_NAME}_INTERFACE) + target_link_libraries(Example_Chameleon_Hicma_Converter PRIVATE ${PROJECT_NAME}_INTERFACE) +endif () + +# Link the target executable with the project and any additional libraries +target_link_libraries(Example_Chameleon_Descriptor PRIVATE ${PROJECT_NAME}_INTERFACE) \ No newline at end of file diff --git a/examples/descriptors/ChameleonDescriptor.cpp b/examples/descriptors/ChameleonDescriptor.cpp new file mode 100644 index 00000000..929403c5 --- /dev/null +++ b/examples/descriptors/ChameleonDescriptor.cpp @@ -0,0 +1,101 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ChameleonDescriptor.cpp + * @brief Example file for the Chameleon descriptor. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-14 +**/ + +#include +#include +#include + +using namespace std; + +using namespace exageostat::common; +using namespace exageostat::kernels; +using namespace exageostat::dataunits; +using namespace exageostat::configurations; + +/** + * @brief Main entry point for demonstrating the use of Chameleon Descriptor in ExaGeoStat. + * @details Initializes configurations, hardware, data, and kernels. Demonstrates the setup and usage of a Chameleon descriptor for handling matrices, including setting up matrix + * dimensions, tile sizes, distribution grids, and memory management. The example showcases how to interact with the descriptor to access and manage data efficiently for computational purposes. + * @param argc Number of command-line arguments. + * @param argv Array of command-line argument strings. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * + */ +int main(int argc, char **argv) { + + LOGGER("** Example of Chameleon Descriptor **") + + // Initialize Configuration + Configurations configuration; + configuration.InitializeArguments(argc, argv); + + // Initialize Hardware and Data + auto hardware = ExaGeoStatHardware(configuration.GetComputation(), configuration.GetCoresNumber(), + configuration.GetGPUsNumbers()); + unique_ptr> data = make_unique>(); + Kernel *kernel = exageostat::plugins::PluginRegistry>::Create( + configuration.GetKernelName(), configuration.GetTimeSlot()); + + // Get arguments for Descriptors Initialization + int kernel_variables_number = kernel->GetVariablesNumber(); + int config_problem_size = configuration.GetProblemSize(); + int config_full_problem_size = config_problem_size * kernel_variables_number; + int config_dts = configuration.GetDenseTileSize(); + int config_p_grid = configuration.GetPGrid(); + int config_q_grid = configuration.GetQGrid(); + bool config_is_OOC = configuration.GetIsOOC(); + + // Randomly Initialized Matrix of Data + std::vector matrix(config_problem_size * config_problem_size); + for (int i = 0; i < config_problem_size; ++i) { + matrix[i] = i; + } + + // Set Data Descriptor + data->SetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C, config_is_OOC, matrix.data(), EXAGEOSTAT_REAL_DOUBLE, + config_dts, + config_dts, + config_dts * config_dts, config_full_problem_size, config_full_problem_size, 0, 0, + config_full_problem_size, + config_full_problem_size, config_p_grid, config_q_grid); + + auto *CHAM_descriptorC = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C).chameleon_desc; + + //Print Descriptor Parameters + LOGGER("** Descriptor Parameters:") + LOGGER(" Problem Size: " << CHAM_descriptorC->m) + LOGGER(" Dense Tile Size: " << CHAM_descriptorC->mb) + + LOGGER(" Entire Number of Rows :" << CHAM_descriptorC->lm) + LOGGER(" Entire Number of Columns :" << CHAM_descriptorC->ln) + + LOGGER(" Number of Sub-matrix Tile Rows: " << CHAM_descriptorC->mt) + LOGGER(" Number of Sub-matrix Tile Columns: " << CHAM_descriptorC->nt) + + LOGGER(" Number of Rows of 2D distribution grid: " << CHAM_descriptorC->p) + LOGGER(" Number of Rows of 2D distribution grid: " << CHAM_descriptorC->q) + + LOGGER(" Is Matrix Not Fit in Memory: " << CHAM_descriptorC->ooc) + LOGGER(" Size including Padding: " << CHAM_descriptorC->bsiz) + + // Print Data Matrix of Descriptor + LOGGER("** Data in Matrix:") + LOGGER_2("", 0) + auto *data_mat = (double *) CHAM_descriptorC->mat; + for (int i = 0; i < config_problem_size; ++i) { + LOGGER_PRECISION_1(" " << data_mat[i], 0) + } + + delete kernel; + return 0; +} diff --git a/examples/descriptors/ChameleonToHicmaConverter.cpp b/examples/descriptors/ChameleonToHicmaConverter.cpp new file mode 100644 index 00000000..2806ae75 --- /dev/null +++ b/examples/descriptors/ChameleonToHicmaConverter.cpp @@ -0,0 +1,126 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ChameleonDescriptor.cpp + * @brief Example file for the Chameleon to Hicma Converter. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-14 +**/ + +#include +#include +#include + +using namespace std; + +using namespace exageostat::common; +using namespace exageostat::kernels; +using namespace exageostat::dataunits; +using namespace exageostat::configurations; + +/** + * @brief Main entry point for the Chameleon to Hicma descriptor conversion example. + * @details Demonstrates the process of initializing ExaGeoStat configurations, setting up hardware, creating and initializing a kernel, and then generating and setting up a + * Chameleon descriptor. The example then showcases the conversion of the Chameleon descriptor to a Hicma descriptor, detailing the changes and continuity in descriptor + * attributes and matrix data through the conversion process. + * @param argc Number of command-line arguments. + * @param argv Array of command-line argument strings. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * + */ + +int main(int argc, char **argv) { + + LOGGER("** Example of Chameleon To Hicma Converter **") + + // Initialize Configuration + Configurations configuration; + configuration.InitializeArguments(argc, argv); + + // Initialize Hardware and Data + auto hardware = ExaGeoStatHardware(configuration.GetComputation(), configuration.GetCoresNumber(), + configuration.GetGPUsNumbers()); + unique_ptr> data = make_unique>(); + Kernel *kernel = exageostat::plugins::PluginRegistry>::Create( + configuration.GetKernelName(), configuration.GetTimeSlot()); + + // Get arguments for Descriptors Initialization + int kernel_variables_number = kernel->GetVariablesNumber(); + int config_problem_size = configuration.GetProblemSize(); + int config_full_problem_size = config_problem_size * kernel_variables_number; + int config_dts = configuration.GetDenseTileSize(); + int config_p_grid = configuration.GetPGrid(); + int config_q_grid = configuration.GetQGrid(); + bool config_is_OOC = configuration.GetIsOOC(); + + // Randomly Initialized Matrix of Data + std::vector matrix(config_problem_size); + for (int i = 0; i < config_problem_size; ++i) { + matrix[i] = i; + } + + // Set Data Descriptor + data->SetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C, config_is_OOC, matrix.data(), EXAGEOSTAT_REAL_DOUBLE, + config_dts, config_dts, config_dts * config_dts, config_full_problem_size, + config_full_problem_size, 0, 0, config_full_problem_size, config_full_problem_size, + config_p_grid, config_q_grid); + auto *CHAM_descriptorC = data->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_C).chameleon_desc; + + //Print Descriptor Attributes Before and After conversion + LOGGER("** Chameleon Descriptor, Before Conversion:") + LOGGER(" Problem Size: " << CHAM_descriptorC->m) + LOGGER(" Dense Tile Size: " << CHAM_descriptorC->mb) + + LOGGER(" Entire Number of Rows :" << CHAM_descriptorC->lm) + LOGGER(" Entire Number of Columns :" << CHAM_descriptorC->ln) + + LOGGER(" Number of Sub-matrix Tile Rows: " << CHAM_descriptorC->mt) + LOGGER(" Number of Sub-matrix Tile Columns: " << CHAM_descriptorC->nt) + + LOGGER(" Number of Rows of 2D distribution grid: " << CHAM_descriptorC->p) + LOGGER(" Number of Rows of 2D distribution grid: " << CHAM_descriptorC->q) + + LOGGER(" Is Matrix Not Fit in Memory: " << CHAM_descriptorC->ooc) + LOGGER(" Size including Padding: " << CHAM_descriptorC->bsiz) + + // Print Data Matrix of Descriptor + LOGGER("** Data in Matrix of Chameleon descriptor:") + LOGGER_2("", 0) + auto *cham_mat = (double *) CHAM_descriptorC->mat; + for (int i = 0; i < config_problem_size; ++i) { + LOGGER_PRECISION_1(" " << cham_mat[i], 0) + } + + auto *HICMA_descriptorC = data->ConvertChameleonToHicma(CHAM_descriptorC, DESCRIPTOR_C); + + //Print Descriptor Attributes + LOGGER(" Problem Size: " << HICMA_descriptorC->m) + LOGGER(" Dense Tile Size: " << HICMA_descriptorC->mb) + + LOGGER(" Entire Number of Rows :" << HICMA_descriptorC->lm) + LOGGER(" Entire Number of Columns :" << HICMA_descriptorC->ln) + + LOGGER(" Number of Sub-matrix Tile Rows: " << HICMA_descriptorC->mt) + LOGGER(" Number of Sub-matrix Tile Columns: " << HICMA_descriptorC->nt) + + LOGGER(" Number of Rows of 2D distribution grid: " << HICMA_descriptorC->p) + LOGGER(" Number of Rows of 2D distribution grid: " << HICMA_descriptorC->q) + + LOGGER(" Is Matrix Not Fit in Memory: " << HICMA_descriptorC->ooc) + LOGGER(" Size including Padding: " << HICMA_descriptorC->bsiz) + + // Print Data Matrix of Descriptor + LOGGER("** Data in Matrix:") + LOGGER_2("", 0) + auto *data_mat = (double *) HICMA_descriptorC->mat; + for (int i = 0; i < config_problem_size; ++i) { + LOGGER_PRECISION_1(" " << data_mat[i], 0) + } + + delete kernel; + return 0; +} diff --git a/examples/descriptors/HicmaDescriptor.cpp b/examples/descriptors/HicmaDescriptor.cpp new file mode 100644 index 00000000..5c81ae16 --- /dev/null +++ b/examples/descriptors/HicmaDescriptor.cpp @@ -0,0 +1,108 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file HicmaDescriptor.cpp + * @brief Example file for the Hicma descriptor. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-14 +**/ + +#include +#include +#include + +using namespace std; + +using namespace exageostat::common; +using namespace exageostat::kernels; +using namespace exageostat::dataunits; +using namespace exageostat::configurations; + +/** + * @brief Main entry point for the Hicma descriptor example in ExaGeoStat. + * @details Initializes configurations tailored for Hicma usage, sets up hardware, creates a kernel, and demonstrates the creation and initialization of a Hicma descriptor. + * The process includes checking for TILE_LOW_RANK computation mode, generating a data matrix, and setting up the Hicma descriptor with this matrix, showcasing how ExaGeoStat + * handles hierarchical matrix representations for efficient large-scale computations. + * @param argc Number of command-line arguments. + * @param argv Array of command-line argument strings. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * + */ + +int main(int argc, char **argv) { + + LOGGER("** Example of Hicma Descriptor **") + + // Initialize Synthetic Configuration + Configurations configuration; + configuration.InitializeArguments(argc, argv); + + //Check for TLR computation specific for HICMA descriptor + if (configuration.GetComputation() != TILE_LOW_RANK) { + LOGGER("You must provide TILE_LOW_RANK computation to initialize HICMA descriptor.") + LOGGER("Consider adding \"--computation=tlr\" to the arguments") + return 0; + } + // Initialize Hardware and Data + auto hardware = ExaGeoStatHardware(configuration.GetComputation(), configuration.GetCoresNumber(), + configuration.GetGPUsNumbers()); + unique_ptr> data = make_unique>(); + Kernel *kernel = exageostat::plugins::PluginRegistry>::Create( + configuration.GetKernelName(), configuration.GetTimeSlot()); + + // Get arguments for Descriptors Initialization + int kernel_variables_number = kernel->GetVariablesNumber(); + int config_problem_size = configuration.GetProblemSize(); + int config_full_problem_size = config_problem_size * kernel_variables_number; + int config_dts = configuration.GetDenseTileSize(); + int config_p_grid = configuration.GetPGrid(); + int config_q_grid = configuration.GetQGrid(); + bool config_is_OOC = configuration.GetIsOOC(); + + // Randomly Initialized Matrix of Data + std::vector matrix(config_problem_size * config_problem_size); + for (int i = 0; i < config_problem_size; ++i) { + matrix[i] = i; + } + + // Set Data Descriptor + data->SetDescriptor(HICMA_DESCRIPTOR, DESCRIPTOR_C, config_is_OOC, matrix.data(), EXAGEOSTAT_REAL_DOUBLE, + config_dts, + config_dts, + config_dts * config_dts, config_full_problem_size, config_full_problem_size, 0, 0, + config_full_problem_size, + config_full_problem_size, config_p_grid, config_q_grid); + + auto *HICMA_descriptorC = data->GetDescriptor(HICMA_DESCRIPTOR, DESCRIPTOR_C).hicma_desc; + + //Print Descriptor Attributes + LOGGER(" Problem Size: " << HICMA_descriptorC->m) + LOGGER(" Dense Tile Size: " << HICMA_descriptorC->mb) + + LOGGER(" Entire Number of Rows :" << HICMA_descriptorC->lm) + LOGGER(" Entire Number of Columns :" << HICMA_descriptorC->ln) + + LOGGER(" Number of Sub-matrix Tile Rows: " << HICMA_descriptorC->mt) + LOGGER(" Number of Sub-matrix Tile Columns: " << HICMA_descriptorC->nt) + + LOGGER(" Number of Rows of 2D distribution grid: " << HICMA_descriptorC->p) + LOGGER(" Number of Rows of 2D distribution grid: " << HICMA_descriptorC->q) + + LOGGER(" Is Matrix Not Fit in Memory: " << HICMA_descriptorC->ooc) + LOGGER(" Size including Padding: " << HICMA_descriptorC->bsiz) + + // Print Data Matrix of Descriptor + LOGGER("** Data in Matrix:") + LOGGER_2("", 0) + auto *data_mat = (double *) HICMA_descriptorC->mat; + for (int i = 0; i < config_problem_size; ++i) { + LOGGER_PRECISION_1(" " << data_mat[i], 0) + } + + delete kernel; + return 0; +} diff --git a/examples/end-to-end/CMakeLists.txt b/examples/end-to-end/CMakeLists.txt index bfce4c30..4131b826 100644 --- a/examples/end-to-end/CMakeLists.txt +++ b/examples/end-to-end/CMakeLists.txt @@ -1,10 +1,11 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @brief Defines an executables and links them with the ExaGeoStat library and other libraries. +# @version 1.1.0 # @author Mahmoud ElKarargy # @date 2023-01-31 @@ -14,6 +15,7 @@ add_executable(Example_Data_Modeling ${CMAKE_CURRENT_SOURCE_DIR}/DataModeling.cp add_executable(Example_Data_Generation_and_Modeling ${CMAKE_CURRENT_SOURCE_DIR}/DataGenerationAndModeling.cpp) add_executable(Example_Data_Generation_Modeling_and_Prediction ${CMAKE_CURRENT_SOURCE_DIR}/DataGenerationModelingAndPrediction.cpp) add_executable(Example_Data_Prediction ${CMAKE_CURRENT_SOURCE_DIR}/DataPrediction.cpp) +add_executable(Example_Data_Generation_and_Prediction ${CMAKE_CURRENT_SOURCE_DIR}/DataGenerationAndPrediction.cpp) # Link the target executable with the project and any additional libraries target_link_libraries(Example_Data_Generation PUBLIC ${PROJECT_NAME}_INTERFACE) @@ -21,3 +23,4 @@ target_link_libraries(Example_Data_Modeling PUBLIC ${PROJECT_NAME}_INTERFACE) target_link_libraries(Example_Data_Generation_and_Modeling PUBLIC ${PROJECT_NAME}_INTERFACE) target_link_libraries(Example_Data_Generation_Modeling_and_Prediction PUBLIC ${PROJECT_NAME}_INTERFACE) target_link_libraries(Example_Data_Prediction PUBLIC ${PROJECT_NAME}_INTERFACE) +target_link_libraries(Example_Data_Generation_and_Prediction PUBLIC ${PROJECT_NAME}_INTERFACE) diff --git a/examples/end-to-end/DataGeneration.cpp b/examples/end-to-end/DataGeneration.cpp index 5d3ad6b0..fde12d35 100644 --- a/examples/end-to-end/DataGeneration.cpp +++ b/examples/end-to-end/DataGeneration.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -7,25 +7,22 @@ * @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.1.0 * @author Mahmoud ElKarargy - * @date 2023-05-30 + * @date 2024-02-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 DataGeneration program. * @details This function either generates synthetic data using the ExaGeoStat library, or reads an CSV file containing real data. * @param[in] argc The number of command line arguments. * @param[in] argv An array of command line argument strings. - * @return An integer indicating the success or failure of the program. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * */ int main(int argc, char **argv) { @@ -33,14 +30,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 ** ") - ExaGeoStat::ExaGeoStatLoadData(hardware, configurations, data); - LOGGER("** All example stages have been completed successfully ** ") + // Load data by either read from file or create synthetic data. + std::unique_ptr> data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(configurations, data); 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..30fdf5d8 100644 --- a/examples/end-to-end/DataGenerationAndModeling.cpp +++ b/examples/end-to-end/DataGenerationAndModeling.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -7,25 +7,23 @@ * @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.1.0 * @author Mahmoud ElKarargy - * @date 2023-06-21 + * @date 2024-02-04 **/ -#include #include -using namespace exageostat::configurations; using namespace exageostat::api; -using namespace exageostat::hardware; -using namespace exageostat::dataunits; +using namespace exageostat::configurations; /** * @brief Main entry point for the Data Generation & Data Modeling program. * @details This function either generates synthetic data using the ExaGeoStat library, or reads an CSV file, then models the loaded data. * @param[in] argc The number of command line arguments. * @param[in] argv An array of command line argument strings. - * @return An integer indicating the success or failure of the program. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * */ int main(int argc, char **argv) { @@ -33,16 +31,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 ** ") - ExaGeoStat::ExaGeoStatLoadData(hardware, configurations, data); - LOGGER("** ExaGeoStat data Modeling ** ") - ExaGeoStat::ExaGeoStatDataModeling(hardware, configurations, data); - LOGGER("** All example stages have been completed successfully ** ") + // Load data by either read from file or create synthetic data. + std::unique_ptr> data; + ExaGeoStat::ExaGeoStatLoadData(configurations, data); + // Modeling module. + ExaGeoStat::ExaGeoStatDataModeling(configurations, data); return 0; } diff --git a/examples/end-to-end/DataGenerationAndPrediction.cpp b/examples/end-to-end/DataGenerationAndPrediction.cpp new file mode 100644 index 00000000..7150c78e --- /dev/null +++ b/examples/end-to-end/DataGenerationAndPrediction.cpp @@ -0,0 +1,44 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file DataGenerationAndPrediction.cpp + * @brief This program This program either generates synthetic data using the ExaGeoStat library, or reads an CSV file containing real data, then predicts missing measurements using the ExaGeoStat library. + * @details The program takes command line arguments to configure the data generation. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-03-03 +**/ + +#include + +using namespace exageostat::api; +using namespace exageostat::configurations; + +/** + * @brief Main entry point for the Data Generation & Data Modeling program. + * @details This function either generates synthetic data using the ExaGeoStat library, or reads an CSV file containing real data, models it, and predicts missing values. + * @param[in] argc The number of command line arguments. + * @param[in] argv An array of command line argument strings. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * + */ +int main(int argc, char **argv) { + + // Create a new configurations object. + Configurations configurations; + // Initialize the arguments with the provided command line arguments + configurations.InitializeArguments(argc, argv); + // Initialize the ExaGeoStat Hardware + auto hardware = ExaGeoStatHardware(configurations.GetComputation(), configurations.GetCoresNumber(), + configurations.GetGPUsNumbers()); + // Load data by either read from file or create synthetic data. + std::unique_ptr> data; + ExaGeoStat::ExaGeoStatLoadData(configurations, data); + // Prediction module + ExaGeoStat::ExaGeoStatPrediction(configurations, data); + + return 0; +} diff --git a/examples/end-to-end/DataGenerationModelingAndPrediction.cpp b/examples/end-to-end/DataGenerationModelingAndPrediction.cpp index a1ec90ea..746efdd8 100644 --- a/examples/end-to-end/DataGenerationModelingAndPrediction.cpp +++ b/examples/end-to-end/DataGenerationModelingAndPrediction.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -7,43 +7,40 @@ * @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.1.0 * @author Mahmoud ElKarargy - * @date 2023-06-21 + * @date 2024-02-04 **/ -#include #include -using namespace exageostat::configurations; using namespace exageostat::api; -using namespace exageostat::hardware; -using namespace exageostat::dataunits; +using namespace exageostat::configurations; /** * @brief Main entry point for the Data Generation & Data Modeling program. * @details This function either generates synthetic data using the ExaGeoStat library, or reads an CSV file containing real data, models it, and predicts missing values. * @param[in] argc The number of command line arguments. * @param[in] argv An array of command line argument strings. - * @return An integer indicating the success or failure of the program. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * */ 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 **") - ExaGeoStat::ExaGeoStatLoadData(hardware, configurations, data); - LOGGER("** ExaGeoStat data Modeling **") - ExaGeoStat::ExaGeoStatDataModeling(hardware, configurations, data); - LOGGER("** ExaGeoStat data Prediction **") - ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data); - LOGGER("** All example stages have been completed successfully ** ") + // Load data by either read from file or create synthetic data. + std::unique_ptr> data; + ExaGeoStat::ExaGeoStatLoadData(configurations, data); + // Modeling module. + ExaGeoStat::ExaGeoStatDataModeling(configurations, data); + // Prediction module + ExaGeoStat::ExaGeoStatPrediction(configurations, data); + return 0; } diff --git a/examples/end-to-end/DataModeling.cpp b/examples/end-to-end/DataModeling.cpp index 76706ea8..3ce1070f 100644 --- a/examples/end-to-end/DataModeling.cpp +++ b/examples/end-to-end/DataModeling.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -7,20 +7,15 @@ * @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.1.0 * @author Mahmoud ElKarargy - * @date 2023-06-21 + * @date 2024-02-04 **/ -#include - -#include #include using namespace exageostat::api; -using namespace exageostat::dataunits; using namespace exageostat::configurations; -using namespace exageostat::hardware; /** * @brief Main entry point for the Data Modeling program. @@ -30,14 +25,15 @@ using namespace exageostat::hardware; * the library's efficiency in handling large spatial datasets while efficiently utilizing hardware resources.. * @param[in] argc The number of command line arguments. * @param[in] argv An array of command line argument strings. - * @return An integer indicating the success or failure of the program. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * */ int main(int argc, char **argv) { // Create a new data_modeling_configurations object with the provided command line arguments and example variables Configurations configurations; configurations.InitializeArguments(argc, argv); /** - * Since this example is currently relying on user inputs instead of reading files, The following points are important to know: + * Since this example is relying on user inputs, The following points are important to know: * The N and dts have to match with the Location X, Y and Z_values you're going to provide. * You have to provide Locations and Z values in order to use Modeling without generation. */ @@ -47,13 +43,12 @@ 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 +72,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); + + // Modeling module. + ExaGeoStat::ExaGeoStatDataModeling(configurations, data, z_matrix); - LOGGER("** ExaGeoStat Data Modeling ** ") - 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..dbe1a1f8 100644 --- a/examples/end-to-end/DataPrediction.cpp +++ b/examples/end-to-end/DataPrediction.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -7,25 +7,23 @@ * @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.1.0 * @author Mahmoud ElKarargy - * @date 2023-09-11 + * @date 2024-02-04 **/ -#include #include -using namespace exageostat::configurations; using namespace exageostat::api; -using namespace exageostat::hardware; -using namespace exageostat::dataunits; +using namespace exageostat::configurations; /** * @brief Main entry point for the Data Prediction program. * @details This function predicts missing values. * @param[in] argc The number of command line arguments. * @param[in] argv An array of command line argument strings. - * @return An integer indicating the success or failure of the program. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * */ int main(int argc, char **argv) { @@ -34,7 +32,7 @@ int main(int argc, char **argv) { // Initialize the arguments with the provided command line arguments configurations.InitializeArguments(argc, argv); /** - * Since this example is currently relying on user inputs instead of reading files, The following points are important to know: + * Since this example is currently relying on user inputs, The following points are important to know: * The N and dts have to match with the Location X, Y and Z_values you're going to provide. * You have to provide Locations and Z values in order to use Modeling without generation. */ @@ -44,13 +42,12 @@ 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 +72,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 **") - ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data, z_matrix); - LOGGER("** All example stages have been completed successfully **") + // Prediction module + ExaGeoStat::ExaGeoStatPrediction(configurations, data, z_matrix); delete[] location_x; delete[] location_y; delete[] z_matrix; + return 0; } \ No newline at end of file diff --git a/examples/hardware/CMakeLists.txt b/examples/hardware/CMakeLists.txt new file mode 100644 index 00000000..82d5e8f9 --- /dev/null +++ b/examples/hardware/CMakeLists.txt @@ -0,0 +1,17 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @brief Defines an executable and links it with the ExaGeoStat library and other libraries. +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @date 2024-02-14 + +# Define the target executable +add_executable(Example_Hardware ${CMAKE_CURRENT_SOURCE_DIR}/ExaGeoStatHardware.cpp) + +# Link the target executable with the project and any additional libraries +target_link_libraries(Example_Hardware PRIVATE ${PROJECT_NAME}_INTERFACE) + diff --git a/examples/hardware/ExaGeoStatHardware.cpp b/examples/hardware/ExaGeoStatHardware.cpp new file mode 100644 index 00000000..0710943f --- /dev/null +++ b/examples/hardware/ExaGeoStatHardware.cpp @@ -0,0 +1,42 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file TestExaGeoStatHardware.cpp + * @briefExample for the ExaGeoStatHardware class in the ExaGeoStat software package. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-14 +**/ + +#include +#include + +using namespace exageostat::configurations; + +/** + * @brief Main entry point for demonstrating the ExaGeoStatHardware class usage. + * @details This program demonstrates how to initialize the ExaGeoStatHardware class using configuration settings derived from command-line arguments. + * It showcases the initialization process for hardware configurations, including the computation mode, number of cores, and number of GPUs, + * highlighting the simplicity and effectiveness of managing hardware resources in ExaGeoStat. + * @param argc Number of command-line arguments. + * @param argv Array of command-line argument strings. + * @return An integer indicating the success or failure of the program. A return value of 0 indicates success, while any non-zero value indicates failure. + * + */ +int main(int argc, char **argv) { + + LOGGER("** Example of Hardware **") + + // Initialize Configuration + Configurations configuration; + configuration.InitializeArguments(argc, argv); + + // Initialize Hardware + auto hardware = ExaGeoStatHardware(configuration.GetComputation(), configuration.GetCoresNumber(), + configuration.GetGPUsNumbers()); + + return 0; +} \ No newline at end of file diff --git a/inst/include/Rcpp-adapters/FunctionsAdapter.hpp b/inst/include/Rcpp-adapters/FunctionsAdapter.hpp new file mode 100644 index 00000000..17cb7dc3 --- /dev/null +++ b/inst/include/Rcpp-adapters/FunctionsAdapter.hpp @@ -0,0 +1,260 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file FunctionAdapter.hpp + * @brief Header file for function adapters in the ExaGeoStat software. + * @details It provides declarations for functions that adapt and initialize statistical models or algorithms based on user-defined configurations. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-01-29 +**/ + +#ifndef EXAGEOSTATCPP_FUNCTIONSADAPTER_HPP +#define EXAGEOSTATCPP_FUNCTIONSADAPTER_HPP + +#include + +#include +#include + +namespace exageostat::adapters { + + /** + * @brief Retrieves locations from ExaGeoStat data. + * @details Extracts and returns the locations stored in an ExaGeoStatData object, + * @param[in] apData Pointer to ExaGeoStatData object containing the spatial data. + * @return vector of locations coordinates. + * + */ + std::vector> R_GetLocations(ExaGeoStatData *apData); + + /** + * @brief Retrieves descriptive Z values from ExaGeoStat data based on type. + * @details Extracts and returns Z values from an ExaGeoStatData object, aiding in targeted spatial data analysis and visualization within ExaGeoStat. + * @param[in] apData Pointer to ExaGeoStatData object containing the spatial data. + * @param[in] aType String specifying the type of descriptor value to retrieve (e.g., "Chameleon", "HiCMA"). + * @return Numeric vector of descriptive Z values. + * + */ + Rcpp::NumericVector R_GetDescZValues(ExaGeoStatData *apData, const std::string &aType); + + /** + * @brief Function to load ExaGeoStat data. + * @details This function loads data into an ExaGeoStatData object using the provided configuration and computational settings. + * It is designed to initialize the data structure necessary for subsequent statistical model operations within the ExaGeoStat framework. + * @param[in] aKernelName Name of the computational kernel to be utilized. + * @param[in] aInitialTheta Initial parameter values for the statistical model. + * @param[in] aDistanceMatrix Type of distance matrix to be used ("euclidean", "manhattan", etc.). + * @param[in] aProblemSize Size of the problem or dataset. + * @param[in] aSeed Seed for random number generation, ensuring reproducibility. + * @param[in] aDenseTileSize Size of the tile for dense computations. + * @param[in] aLowTileSize Size of the tile for low-rank computations. + * @param[in] aDimension Dimensionality of the problem ("2D" for two dimensions, "3D" for three dimensions). + * @param[in] aLogPath Path to the log file where execution details will be stored. + * @param[in] aDataPath Path to the data file containing spatial observations. + * @param[in] aRecoveryFilePath Path for saving intermediate computation states, aiding in recovery from interruptions. + * @param[in] aObservationsFilePath Path to the file containing observation data. + * @return A pointer to an ExaGeoStatData object containing the loaded data. + * + */ + ExaGeoStatData * + R_ExaGeoStatLoadData(const std::string &aKernelName, const std::vector &aInitialTheta, + const std::string &aDistanceMatrix, const int &aProblemSize, const int &aSeed, + const int &aDenseTileSize, const int &aLowTileSize, const std::string &aDimension, + const std::string &aLogPath, const std::string &aDataPath, + const std::string &aRecoveryFilePath, const std::string &aObservationsFilePath); + + /** + * @brief Models ExaGeoStat data using specified arguments. + * @details Applies statistical modeling to ExaGeoStatData based on the provided configurations. + * This function is essential for preparing the data for in-depth statistical analysis and predictions, + * optimizing internal representations and parameters for the modeling process. + * @param[in] aComputation Computational method to be used. + * @param[in] aKernelName Name of the kernel for computations. + * @param[in] aDistanceMatrix Type of distance matrix ("euclidean", "manhattan", etc.). + * @param[in] aLowerBound Lower bound for optimization parameters. + * @param[in] aUpperBound Upper bound for optimization parameters. + * @param[in] aTolerance Tolerance level for the optimization algorithm. + * @param[in] aMleIterations Maximum number of iterations for the Maximum Likelihood Estimation (MLE) algorithm. + * @param[in] aDenseTileSize Tile size for dense matrix computations. + * @param[in] aLowTileSize Tile size for low-rank approximations. + * @param[in] aDimension Dimensionality of the problem ("2D" or "3D"). + * @param[in] aBand Bandwidth for band matrices, applicable in certain computational kernels. + * @param[in] aMaxRank Maximum rank for low-rank approximations. + * @param[in] apData Pointer to ExaGeoStatData object to be modeled. + * @param[in] aMeasurementsVector Optional vector of measurements to enhance modeling, can be nullable. + * @param[in] aLocationsX Optional vector of X coordinates for locations, can be nullable. + * @param[in] aLocationsY Optional vector of Y coordinates for locations, can be nullable. + * @param[in] aLocationsZ Optional vector of Z coordinates for locations, can be nullable. + * @return Vector of doubles represents the modeled theta. + * + */ + std::vector R_ExaGeoStatModelData(const std::string &aComputation, const std::string &aKernelName, + const std::string &aDistanceMatrix, + const std::vector &aLowerBound, + const std::vector &aUpperBound, const int &aTolerance, + const int &aMleIterations, const int &aDenseTileSize, + const int &aLowTileSize, const std::string &aDimension, const int &aBand, + const int &aMaxRank, SEXP apData, + Rcpp::Nullable aMeasurementsVector = R_NilValue, + Rcpp::Nullable aLocationsX = R_NilValue, + Rcpp::Nullable aLocationsY = R_NilValue, + Rcpp::Nullable aLocationsZ = R_NilValue); + + /** + * @brief Predicts outcomes using ExaGeoStat data and configurations. + * @details Utilizes a modeled ExaGeoStatData object to perform predictions, leveraging specified computational settings and statistical models. + * This function is integral for generating spatial predictions based on the data and models within the ExaGeoStat framework. + * @param[in] aKernelName Name of the kernel used for prediction computations. + * @param[in] aDistanceMatrix Type of distance matrix used ("euclidean", "manhattan", etc.). + * @param[in] aEstimatedTheta Vector of estimated parameters from the model. + * @param[in] aDenseTileSize Tile size for dense matrix operations. + * @param[in] aLowTileSize Tile size for low-rank matrix operations. + * @param[in] aDimension Dimensionality of the spatial data ("2D" or "3D"). + * @param[in] aTrainData Training data set used for predictions. + * @param[in] aTestData Test data set for which predictions are made. + * @return Vector of predicted values based on the test data. + * + */ + std::vector R_ExaGeoStatPredictData(const std::string &aKernelName, const std::string &aDistanceMatrix, + const std::vector &aEstimatedTheta, const int &aDenseTileSize, + const int &aLowTileSize, const std::string &aDimension, + std::vector> &aTrainData, + std::vector> &aTestData); + + /** + * @brief Calculates the Mean Logarithmic Error (MLOE) and the Mean Measure of Model Output (MMOM) for ExaGeoStat predictions. + * @details Assesses the accuracy of spatial predictions made by the ExaGeoStat framework by computing the MLOE and MMOM, + * which provide insights into the predictive performance and uncertainty of the models. + * @param[in] aKernelName Kernel used for the prediction computations. + * @param[in] aDistanceMatrix Type of distance matrix ("euclidean", "manhattan", etc.). + * @param[in] aEstimatedTheta Vector of estimated parameters from the model. + * @param[in] aTrueTheta Vector of true parameter values for validation. + * @param[in] aDenseTileSize Tile size for dense matrix operations. + * @param[in] aLowTileSize Tile size for low-rank matrix operations. + * @param[in] aDimension Dimensionality of the spatial data ("2D" or "3D"). + * @param[in] aTrainData Training data set used in the model. + * @param[in] aTestData Test data set used for validation. + * @return Vector containing the calculated MLOE and MMOM values. + * + */ + std::vector R_ExaGeoStatMLOE_MMOM(const std::string &aKernelName, const std::string &aDistanceMatrix, + const std::vector &aEstimatedTheta, + const std::vector &aTrueTheta, const int &aDenseTileSize, + const int &aLowTileSize, const std::string &aDimension, + std::vector> &aTrainData, + std::vector> &aTestData); + + /** + * @brief Computes the Fisher information matrix for ExaGeoStat models. + * @details Utilizes the estimated parameters and the Fisher information matrix to evaluate the information content and + * parameter uncertainties within the ExaGeoStat framework, contributing to the understanding of model reliability and sensitivity. + * @param[in] aKernelName Kernel used for computations. + * @param[in] aDistanceMatrix Type of distance matrix ("euclidean", "manhattan", etc.). + * @param[in] aEstimatedTheta Vector of estimated parameters from the model. + * @param[in] aDenseTileSize Tile size for dense matrix operations. + * @param[in] aLowTileSize Tile size for low-rank matrix operations. + * @param[in] aDimension Dimensionality of the spatial data ("2D" or "3D"). + * @param[in] aTrainData Training data set used in the model. + * @param[in] aTestData Test data set used for validation. + * @return Vector represents the Fisher information matrix. + * + */ + std::vector R_ExaGeoStatFisher(const std::string &aKernelName, const std::string &aDistanceMatrix, + const std::vector &aEstimatedTheta, const int &aDenseTileSize, + const int &aLowTileSize, const std::string &aDimension, + std::vector> &aTrainData, + std::vector> &aTestData); + + /** + * @brief Applies Inverse Distance Weighting (IDW) for spatial interpolation using ExaGeoStat data. + * @details Implements the IDW interpolation method to estimate spatial variables at unsampled locations based on the distances + * and values of nearby sampled points within the ExaGeoStat framework, enhancing spatial prediction capabilities. + * @param[in] aKernelName Kernel used for IDW computations. + * @param[in] aDistanceMatrix Type of distance matrix ("euclidean", "manhattan", etc.). + * @param[in] aEstimatedTheta Vector of parameters, typically used for weighting in IDW. + * @param[in] aDenseTileSize Tile size for dense matrix operations. + * @param[in] aLowTileSize Tile size for low-rank matrix operations. + * @param[in] aDimension Dimensionality of the spatial data ("2D" or "3D"). + * @param[in] aTrainData Training data set providing sampled locations and values. + * @param[in] aTestData Test data set providing unsampled locations for which values are interpolated. + * @param[in] aTestMeasurementsValues Vector of measured values at the test locations, used as reference in some IDW implementations. + * @return Vector of interpolated values at the test locations. + * + */ + std::vector R_ExaGeoStatIDW(const std::string &aKernelName, const std::string &aDistanceMatrix, + const std::vector &aEstimatedTheta, const int &aDenseTileSize, + const int &aLowTileSize, const std::string &aDimension, + std::vector> &aTrainData, + std::vector> &aTestData, + std::vector &aTestMeasurementsValues); + + /** + * @brief Extracts and prepares data from given arguments for ExaGeoStat operations. + * @details This function is designed to parse and prepare spatial and measurement data from provided arguments, + * making it suitable for processing within the ExaGeoStat framework. It handles optional data vectors for measurements + * and locations (X, Y, Z coordinates), and configures an ExaGeoStatData object based on these inputs along with other + * computational and configuration parameters. + * @param[in] aMeasurementsVector vector of measurements to enhance modeling, can be nullable. + * @param[in] aLocationsX vector of X coordinates for locations, can be nullable. + * @param[in] aLocationsY vector of Y coordinates for locations, can be nullable. + * @param[in] aLocationsZ vector of Z coordinates for locations, can be nullable. + * @param[in] aData Pointer to ExaGeoStatData object to be modeled. + * @param[in] aConfigurations Configuration settings specifying computational details such as the kernel type, matrix storage format, etc. + * @param[in] aKernelName Name of the kernel for computations. + * @param[in] aDistanceMatrix Type of distance matrix ("euclidean", "manhattan", etc.). + * @param[in] aDenseTileSize Tile size for dense matrix computations. + * @param[in] aLowTileSize Tile size for low-rank approximations. + * @param[in] aDimension Dimensionality of the problem ("2D" or "3D"). + * @param[in] aComputation Computational method to be used. + * @return Pointer to a double array containing the prepared data, ready for use in ExaGeoStat operations. + * + */ + double *GetDataFromArguments(Rcpp::Nullable aMeasurementsVector, + Rcpp::Nullable aLocationsX, + Rcpp::Nullable aLocationsY, + Rcpp::Nullable aLocationsZ, + std::unique_ptr> &aData, + configurations::Configurations &aConfigurations, const std::string &aKernelName, + const std::string &aDistanceMatrix, const int &aDenseTileSize, const int &aLowTileSize, + const std::string &aDimension, const common::Computation &aComputation); + + /** + * @brief Validates the dimensions of input data. + * @details This function checks the dimensions of the provided data vectors to ensure they meet the expected format and size requirements for a given data type. + * It's used to verify that the data structures passed into algorithms or processes are correctly formatted, preventing errors or inconsistencies in data processing. + * @param aData A constant reference to a vector of vectors containing the data to be validated. + * @param aDataType A string describing the type of data being validated, which influences the expected dimensions and format of the data. + * @return void + * + */ + void ValidateDataDimensions(const std::vector> &aData, const std::string &aDataType); + + /** + * @brief Sets up the prediction environment. + * @details This function prepares the necessary configurations and data structures for making predictions. It involves setting up various parameters, including kernel names, distance matrices, tile sizes, dimensions, and training/test data. The function is crucial for initializing the prediction process with the appropriate settings and data. + * @param aConfigurations Reference to a Configurations object containing various prediction and algorithm configurations. + * @param aKernelName Name of the kernel to be used in predictions. + * @param aDistanceMatrix String representation of the distance matrix to be used. + * @param aDenseTileSize Size of the dense tiles in the matrix. + * @param aLowTileSize Size of the low-resolution tiles in the matrix. + * @param aDimension String representation of the dimensionality of the data. + * @param aTrainData Reference to a vector of vectors containing the training data. + * @param aTestData Reference to a vector of vectors containing the test data. + * @param aEstimatedTheta Vector containing estimated theta values for the model. + * @param aTestMeasurementsValues Vector containing the test measurement values. + * @return Pointer to a double array containing the prepared data, ready for use in ExaGeoStat operations. + * + */ + void PredictionSetupHelper(configurations::Configurations &aConfigurations, const std::string &aKernelName, + const std::string &aDistanceMatrix, const int &aDenseTileSize, const int &aLowTileSize, + const std::string &aDimension, std::vector> &aTrainData, + std::vector> &aTestData, + const std::vector &aEstimatedTheta, + const std::vector &aTestMeasurementsValues); + +} +#endif //EXAGEOSTATCPP_FUNCTIONSADAPTER_HPP diff --git a/inst/include/api/ExaGeoStat.hpp b/inst/include/api/ExaGeoStat.hpp index 7de91beb..54c61c16 100644 --- a/inst/include/api/ExaGeoStat.hpp +++ b/inst/include/api/ExaGeoStat.hpp @@ -1,14 +1,14 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file ExaGeoStat.hpp * @brief High-Level Wrapper class containing the static API for ExaGeoStat operations. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy - * @date 2023-05-30 + * @date 2024-02-04 **/ #ifndef EXAGEOSTATCPP_EXAGEOSTAT_HPP @@ -16,10 +16,8 @@ #include -#include #include #include -#include namespace exageostat::api { /** @@ -33,28 +31,24 @@ namespace exageostat::api { /** * @brief Generates Data whether it's synthetic data or real. - * @param[in] aHardware Reference to Hardware configuration for the ExaGeoStat solver. * @param[in] aConfigurations Reference to Configurations object containing user input data. * @param[out] aData Reference to an ExaGeoStatData object where generated data will be stored. * @return void * */ - static void ExaGeoStatLoadData(const hardware::ExaGeoStatHardware &aHardware, - configurations::Configurations &aConfigurations, - dataunits::ExaGeoStatData &aData); + static void ExaGeoStatLoadData(configurations::Configurations &aConfigurations, + std::unique_ptr> &aData); /** * @brief Models Data whether it's synthetic data or real. - * @param[in] aHardware Reference to Hardware configuration for the ExaGeoStat solver. * @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, + static T ExaGeoStatDataModeling(configurations::Configurations &aConfigurations, + std::unique_ptr> &aData, T *apMeasurementsMatrix = nullptr); @@ -64,28 +58,25 @@ namespace exageostat::api { * @param[in] aGrad An array of length n where you can optionally return the gradient of the objective function. * @param[in] apInfo pointer containing needed configurations and data. * @return double MLE results. + * */ static double ExaGeoStatMLETileAPI(const std::vector &aTheta, std::vector &aGrad, void *apInfo); /** * @brief Predict missing measurements values. - * @param[in] aHardware Reference to Hardware configuration for the ExaGeoStat solver. * @param[in] aConfigurations Reference to Configurations object containing user input data. * @param[in, out] aData Reference to an ExaGeoStatData object containing needed descriptors, and locations. * @param[in] apMeasurementsMatrix Pointer to the user input measurements matrix. + * @param[in] apTrainLocations (Optional) Pointer to Locations represents training locations. these are used in training phase. + * @param[in] apTestLocations (Optional) Pointer to Locations represents test locations. These are used in prediction phase. * @return void + * */ - static void ExaGeoStatPrediction(const hardware::ExaGeoStatHardware &aHardware, - configurations::Configurations &aConfigurations, - exageostat::dataunits::ExaGeoStatData &aData, - T *apMeasurementsMatrix = nullptr); + static void + ExaGeoStatPrediction(configurations::Configurations &aConfigurations, std::unique_ptr> &aData, + T *apMeasurementsMatrix = nullptr, dataunits::Locations *apTrainLocations = nullptr, + dataunits::Locations *apTestLocations = nullptr); - private: - /** - * @brief - * Prevent Class Instantiation for API Wrapper Class. - */ - ExaGeoStat() = default; }; /** diff --git a/inst/include/common/Definitions.hpp b/inst/include/common/Definitions.hpp index 406e44c4..400e26df 100644 --- a/inst/include/common/Definitions.hpp +++ b/inst/include/common/Definitions.hpp @@ -1,11 +1,11 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file Definitions.hpp - * @version 1.0.0 + * @version 1.1.0 * @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. @@ -14,27 +14,24 @@ * @date 2023-03-21 **/ - #ifndef EXAGEOSTATCPP_DEFINITIONS_HPP #define EXAGEOSTATCPP_DEFINITIONS_HPP -//// TODO: This is a hot fix to avoid the problem in HiCMA which set the min definition with a conflict implementation of chrono library. +// This is a fix to avoid the problem in HiCMA which set the min definition with a conflict implementation of chrono library. +#ifdef USE_HICMA #ifdef min #undef min #endif +#endif -#include -#include -#include #include #include -#include /** * @def EXAGEOSTAT_INSTANTIATE_CLASS * @brief Macro definition to instantiate the EXAGEOSTAT template classes with supported types. + * **/ - #define EXAGEOSTAT_INSTANTIATE_CLASS(TEMPLATE_CLASS) template class TEMPLATE_CLASS; \ template class TEMPLATE_CLASS; @@ -57,6 +54,11 @@ */ #define Q_NORM 1.959964 +/** + * Logging Path Definition + */ +#define LOG_PATH PROJECT_SOURCE_DIR "/synthetic_ds/" + namespace exageostat::common { /** @@ -84,6 +86,7 @@ namespace exageostat::common { /** * @enum Side * @brief Enum denoting the side on which the matrix appears in an equation. + * */ enum Side { EXAGEOSTAT_LEFT = 141, @@ -93,6 +96,7 @@ namespace exageostat::common { /** * @enum Trans * @brief Enum denoting whether or not to transpose a matrix. + * */ enum Trans { EXAGEOSTAT_NO_TRANS = 111, @@ -103,6 +107,7 @@ namespace exageostat::common { /** * @enum Diag * @brief Enum denoting whether the diagonal is unitary. + * */ enum Diag { EXAGEOSTAT_NON_UNIT = 131, @@ -112,6 +117,7 @@ namespace exageostat::common { /** * @enum Distance metric * @brief Enum denoting distance metric type. + * */ enum DistanceMetric { EUCLIDEAN_DISTANCE = 0, @@ -121,15 +127,27 @@ namespace exageostat::common { /** * @enum Descriptor Type * @brief Enum denoting the Descriptor Type. + * */ enum DescriptorType { CHAMELEON_DESCRIPTOR = 0, 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. + * */ enum DescriptorName : int { DESCRIPTOR_C = 0, @@ -184,10 +202,15 @@ namespace exageostat::common { DESCRIPTOR_C_DIAG = 49, DESCRIPTOR_A = 50, DESCRIPTOR_RESULTS = 51, + DESCRIPTOR_SUM = 52, + DESCRIPTOR_R = 53, + DESCRIPTOR_R_COPY = 54, }; /** + * @enum Tile Storage * @brief Matrix tile storage + * */ typedef enum TileStorage { EXAGOSTAT_CM = 101, @@ -246,6 +269,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. @@ -253,14 +286,13 @@ namespace exageostat::common { * The set is initialized with a lambda function that iterates through a directory * and extracts the kernel names from the filenames. It also adds lowercase versions * of the kernel names with underscores before each capital letter. + * @return set of all available kernels names * */ const static std::set availableKernels = []() { // This set stores the kernel names. std::set kernelNames; // This string stores the directory path where the kernel files are located. - // The path is obtained by using the __FILE__ macro to get the full path of the current source file, - // and then navigating two levels up to reach the directory that contains the kernel files. const std::string directoryPath = KERNELS_PATH; // This loop iterates through all the files in the directory and extracts the kernel names. for (const auto &entry: std::filesystem::directory_iterator(directoryPath)) { diff --git a/inst/include/common/PluginRegistry.hpp b/inst/include/common/PluginRegistry.hpp index b0ba4f6e..b59a9d7f 100644 --- a/inst/include/common/PluginRegistry.hpp +++ b/inst/include/common/PluginRegistry.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file PluginRegistry.hpp * @brief Defines a template class for registering and creating plugins. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @date 2023-04-30 **/ @@ -14,17 +14,17 @@ #ifndef EXAGEOSTATCPP_PLUGINREGISTRY_HPP #define EXAGEOSTATCPP_PLUGINREGISTRY_HPP -//// TODO: This is a hot fix to avoid the problem in HiCMA which set the min definition with a conflict implementation of chrono library. +// This is a fix to avoid the problem in HiCMA which set the min definition with a conflict implementation of chrono library. +#ifdef USE_HICMA #ifdef min #undef min #endif +#endif -#include -#include -#include -#include #include +#include + namespace exageostat::plugins { /** * @brief Template class for registering and creating plugins. @@ -68,13 +68,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/common/Utils.hpp b/inst/include/common/Utils.hpp deleted file mode 100644 index f0428098..00000000 --- a/inst/include/common/Utils.hpp +++ /dev/null @@ -1,106 +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 Utils.hpp - * @brief This file contains common functions used in ExaGeoStat software package. - * @details These functions include so far the VERBOSE macro that prints a message - * to the console if the verbosity setting is set to "verbose mode. - * @version 1.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @date 2023-03-21 -**/ - -#ifndef EXAGEOSTATCPP_UTILS_HPP -#define EXAGEOSTATCPP_UTILS_HPP - -#include -#include -#include - -#include -#include -#include - -/** - * DEFAULT_PRECISION the value of the default C++ std::cout number of precision. - */ -#define DEFAULT_PRECISION 6 - -/** -* Verbose macro for logging and debugging mode -*/ -#define VERBOSE(msg) \ - if(exageostat::configurations::Configurations::GetVerbosity() == exageostat::common::Verbose::DETAILED_MODE && exageostat::helpers::CommunicatorMPI::GetInstance()->GetRank()) \ - std::cout << "\t\t\t " << msg << std::endl; - -/** - * LOGGER_1 macro for logging outputs with double taps and new line at the end. - */ - -#define LOGGER_1(msg) \ - if(!(exageostat::configurations::Configurations::GetVerbosity() == exageostat::common::Verbose::QUIET_MODE) && exageostat::helpers::CommunicatorMPI::GetInstance()->GetRank()) \ - std::cout << "\t\t " << std::fixed << std::setprecision(DEFAULT_PRECISION) << msg << std::endl; - -/** - * LOGGER_2 macro for logging outputs with double taps and without new line at the end. - */ -#define LOGGER_2(msg, A) \ - if(!(exageostat::configurations::Configurations::GetVerbosity() == exageostat::common::Verbose::QUIET_MODE) && exageostat::helpers::CommunicatorMPI::GetInstance()->GetRank()) \ - std::cout << "\t\t " << std::fixed << std::setprecision(DEFAULT_PRECISION) << msg; - -/** - * LOGGER_CONTROL is The internal macro that simply strips the excess and ends up with the required macro - */ -#define LOGGER_CONTROL(x, A, B, FUNC, ...) FUNC - -/** - * LOGGER macro that's called, Used to logging outputs - */ -#define LOGGER(...) LOGGER_CONTROL(,##__VA_ARGS__, \ - LOGGER_2(__VA_ARGS__), \ - LOGGER_1(__VA_ARGS__), \ - ) - -/** -* LOGGER_PRECISION_1 macro for logging outputs without any taps, without new line at the end and with customized precision. -*/ -#define LOGGER_PRECISION_1(msg, precision) \ - if(!(exageostat::configurations::Configurations::GetVerbosity() == exageostat::common::Verbose::QUIET_MODE) && exageostat::helpers::CommunicatorMPI::GetInstance()->GetRank()) \ - std::cout << std::fixed << std::setprecision(precision) << msg; - -/** -* LOGGER_PRECISION macro for logging outputs without any taps, without new line at the end and with default C++ precision. -*/ -#define LOGGER_PRECISION_2(msg) \ - if(!(exageostat::configurations::Configurations::GetVerbosity() == exageostat::common::Verbose::QUIET_MODE) && exageostat::helpers::CommunicatorMPI::GetInstance()->GetRank()) \ - std::cout << std::fixed << std::setprecision(DEFAULT_PRECISION) << msg; - -/** - * LOGGER_CONTROL is The internal macro that simply strips the excess and ends up with the required macro - */ -#define LOGGER_PRECISION_CONTROL(x, A, B, FUNC, ...) FUNC - -/** - * LOGGER macro that's called, Used to logging outputs - */ -#define LOGGER_PRECISION(...) LOGGER_PRECISION_CONTROL(,##__VA_ARGS__, \ - LOGGER_PRECISION_1(__VA_ARGS__), \ - LOGGER_PRECISION_2(__VA_ARGS__), \ - ) - -/** - * Timing macro to start timing. - */ -#define START_TIMING(t) auto t##_start = std::chrono::high_resolution_clock::now() - -/** - * Timing macro to stop timing. - */ -#define STOP_TIMING(t) auto t##_end = std::chrono::high_resolution_clock::now(); \ - t = std::chrono::duration_cast>(t##_end - t##_start).count() - -#endif //EXAGEOSTATCPP_UTILS_HPP diff --git a/inst/include/configurations/Configurations.hpp b/inst/include/configurations/Configurations.hpp index 4c69a9b1..5e523cc8 100644 --- a/inst/include/configurations/Configurations.hpp +++ b/inst/include/configurations/Configurations.hpp @@ -1,15 +1,15 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file Configurations.hpp -* @version 1.0.0 +* @version 1.1.0 * @brief Contains the declaration of the Configurations class and its member functions. -* @author Sameh Abdulah * @author Mahmoud ElKarargy -* @date 2023-01-31 +* @author Sameh Abdulah +* @date 2024-02-04 **/ #ifndef EXAGEOSTAT_CPP_CONFIGURATIONS_HPP @@ -27,7 +27,6 @@ * the specified type and sets the member variable with the specified name * to the value of the argument. The name of the member variable is used as * the key to set the corresponding value in the specified dictionary. - * * @param[in] name The name of the member variable to be set. * @param[in] type The data type of the member variable. * @param[in] argument_name The name of the argument to the generated function. @@ -44,7 +43,6 @@ void Set##name(type argument_name) \ * @brief Macro that generates a getter function for a member variable. * @details This macro generates a function named Get##name that returns the value of * the member variable with the specified name from the specified dictionary. - * * @param[in] name The name of the member variable to be retrieved. * @param[in] type The data type of the member variable. * @param[in] dictionary_name The name of the dictionary to retrieve the value from. @@ -75,23 +73,26 @@ 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(); /** * @brief Initialize the module arguments. * @param[in] aArgC The number of arguments being passed into the program from the command line. * @param[in] apArgV The array of arguments. + * @param[in] aEnableR check if R is enabled * @details This method initializes the command line arguments and set default values for unused args. + * @return void * */ - void InitializeArguments(const int &aArgC, char **apArgV); + void InitializeArguments(const int &aArgC, char **apArgV, const bool &aEnableR = false); /** * @brief Initialize the all theta arguments. * @return void + * */ void InitializeAllTheta(); @@ -190,7 +191,7 @@ namespace exageostat::configurations { CREATE_GETTER_FUNCTION(LoggerPath, std::string, "LoggerPath") - CREATE_SETTER_FUNCTION(InitialTheta, std::vector &, apTheta, "InitialTheta") + CREATE_SETTER_FUNCTION(InitialTheta, const std::vector &, apTheta, "InitialTheta") CREATE_GETTER_FUNCTION(InitialTheta, std::vector &, "InitialTheta") @@ -206,30 +207,26 @@ 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") - - CREATE_SETTER_FUNCTION(LowerBounds, std::vector &, apTheta, "LowerBounds") + CREATE_SETTER_FUNCTION(LowerBounds, const std::vector &, apTheta, "LowerBounds") CREATE_GETTER_FUNCTION(LowerBounds, std::vector &, "LowerBounds") - CREATE_SETTER_FUNCTION(UpperBounds, std::vector &, apTheta, "UpperBounds") + CREATE_SETTER_FUNCTION(UpperBounds, const std::vector &, apTheta, "UpperBounds") CREATE_GETTER_FUNCTION(UpperBounds, std::vector &, "UpperBounds") - CREATE_SETTER_FUNCTION(EstimatedTheta, std::vector &, apTheta, "EstimatedTheta") + CREATE_SETTER_FUNCTION(EstimatedTheta, const std::vector &, apTheta, "EstimatedTheta") CREATE_GETTER_FUNCTION(EstimatedTheta, std::vector &, "EstimatedTheta") - CREATE_SETTER_FUNCTION(StartingTheta, std::vector &, apTheta, "StartingTheta") + CREATE_SETTER_FUNCTION(StartingTheta, const std::vector &, apTheta, "StartingTheta") CREATE_GETTER_FUNCTION(StartingTheta, std::vector &, "StartingTheta") + CREATE_SETTER_FUNCTION(IsNonGaussian, bool, aIsNonGaussian, "IsNonGaussian") + + CREATE_GETTER_FUNCTION(IsNonGaussian, bool, "IsNonGaussian") + /** * @brief Getter for the verbosity. * @return The verbosity mode. @@ -250,10 +247,6 @@ namespace exageostat::configurations { CREATE_GETTER_FUNCTION(IsSynthetic, bool, "IsSynthetic") - CREATE_SETTER_FUNCTION(IsCSV, bool, aIsCSV, "IsCSV") - - CREATE_GETTER_FUNCTION(IsCSV, bool, "IsCSV") - CREATE_SETTER_FUNCTION(DataPath, const std::string&, aDataPath, "DataPath") CREATE_GETTER_FUNCTION(DataPath, std::string, "DataPath") @@ -271,16 +264,6 @@ namespace exageostat::configurations { CREATE_SETTER_FUNCTION(FileLogName, const std::string&, aFileLogName, "FileLogName") - CREATE_GETTER_FUNCTION(FileLogName, std::string, "FileLogName") - - CREATE_SETTER_FUNCTION(AvgExecutedTimePerIteration, double, aAvgExecTimePerIter, "AvgExecuted") - - CREATE_GETTER_FUNCTION(AvgExecutedTimePerIteration, double, "AvgExecuted") - - CREATE_SETTER_FUNCTION(AvgFlopsPerIteration, double, aAvgFlopsPerIter, "AvgFlops") - - CREATE_GETTER_FUNCTION(AvgFlopsPerIteration, double, "AvgFlops") - CREATE_SETTER_FUNCTION(DistanceMetric, common::DistanceMetric, aDistanceMetric, "DistanceMetric") CREATE_GETTER_FUNCTION(DistanceMetric, common::DistanceMetric, "DistanceMetric") @@ -293,7 +276,7 @@ namespace exageostat::configurations { CREATE_GETTER_FUNCTION(Accuracy, int, "Accuracy") - CREATE_SETTER_FUNCTION(Tolerance, double, aTolerance, "Tolerance") + void SetTolerance(double aTolerance); CREATE_GETTER_FUNCTION(Tolerance, double, "Tolerance") @@ -320,6 +303,10 @@ namespace exageostat::configurations { CREATE_GETTER_FUNCTION(IsFisher, bool, "IsFisher") + CREATE_SETTER_FUNCTION(ObservationNumber, int, aObservationsNumber, "ObservationNumber") + + CREATE_GETTER_FUNCTION(ObservationNumber, int, "ObservationNumber") + /** END OF THE DATA PREDICTION MODULES. **/ /** @@ -332,7 +319,7 @@ namespace exageostat::configurations { /** * @brief Checks the value of the dimension parameter. - * @param[in] aDimension A string representing the dimension. + * @param[in] aDimension A string represents the dimension. * @return The corresponding dimension value. * */ @@ -364,8 +351,9 @@ namespace exageostat::configurations { /** * @brief Checks the value of the unknown observations parameter. - * @param[in] aValue A string representing the number of unknown observations. + * @param[in] aValue A string represents the number of unknown observations. * @return The corresponding integer value. + * */ int CheckUnknownObservationsValue(const std::string &aValue); @@ -381,37 +369,16 @@ namespace exageostat::configurations { /** * @brief print the summary of MLE inputs. * @return void + * */ - inline void PrintSummary(); + void PrintSummary(); /** * @brief Calculates the number of observed measurements. * @return number of observed measurements. - */ - int CalculateZObsNumber(); - - - 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"). - * @throws std::range_error if the input string is not "verbose" or "standard". - * @return void - * - */ - static void ParseVerbose(const std::string &aVerbosity); - - /** - * @brief Checks if a given string is in camel case format. - * @param[in] aString The string to check. - * @return true if the string is in camel case format, false otherwise. * */ - static bool IsCamelCase(const std::string &aString); + int CalculateZObsNumber(); /** * @brief Parses a string of theta values and returns an array of doubles. @@ -421,21 +388,33 @@ namespace exageostat::configurations { */ static std::vector ParseTheta(const std::string &aInputValues); + /** * @brief parse user's input to distance metric. * @param[in] aDistanceMetric string specifying the used distance metric. * @return void + * */ void ParseDistanceMetric(const std::string &aDistanceMetric); + private: + /** - * @brief Initializes the log file. - * @details This function attempts to open a log file with the name returned by GetFileLogName(), - * and sets the file log path accordingly. If an exception occurs during the file opening, - * a default log file named "log_file" is created. + * @brief Checks the run mode and sets the verbosity level. + * @param[in] aVerbosity A string represents the desired run mode ("verbose" or "standard"). + * @throws std::range_error if the input string is not "verbose" or "standard". * @return void + * */ - void InitLog(); + static void ParseVerbose(const std::string &aVerbosity); + + /** + * @brief Checks if a given string is in camel case format. + * @param[in] aString The string to check. + * @return true if the string is in camel case format, false otherwise. + * + */ + static bool IsCamelCase(const std::string &aString); /// Used Dictionary std::unordered_map mDictionary; @@ -447,9 +426,11 @@ namespace exageostat::configurations { static exageostat::common::Verbose mVerbosity; //// Used bool for init theta static bool mIsThetaInit; - + //// Used bool for R allocated memory on heap + static bool mHeapAllocated; + //// Used bool for indicating the first init of configurations for printing summary + static bool mFirstInit; }; }//namespace exageostat #endif //EXAGEOSTAT_CPP_CONFIGURATIONS_HPP - diff --git a/inst/include/data-generators/DataGenerator.hpp b/inst/include/data-generators/DataGenerator.hpp index e0c167cb..2e5d4344 100644 --- a/inst/include/data-generators/DataGenerator.hpp +++ b/inst/include/data-generators/DataGenerator.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file DataGenerator.hpp * @brief Contains definition for abstract Data Generator Class. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @date 2023-02-14 **/ @@ -14,8 +14,6 @@ #ifndef EXAGEOSTAT_CPP_DATAGENERATOR_HPP #define EXAGEOSTAT_CPP_DATAGENERATOR_HPP -#include - #include #include @@ -36,13 +34,12 @@ namespace exageostat::generators { * @brief Either generates synthetic data or reads data files. * @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 * - CreateData(exageostat::configurations::Configurations &aConfigurations, - const exageostat::hardware::ExaGeoStatHardware &aHardware, + virtual std::unique_ptr> + CreateData(configurations::Configurations &aConfigurations, exageostat::kernels::Kernel &aKernel) = 0; /** @@ -53,7 +50,7 @@ namespace exageostat::generators { * */ static std::unique_ptr - CreateGenerator(exageostat::configurations::Configurations &aConfigurations); + CreateGenerator(configurations::Configurations &aConfigurations); /** * @brief Destructor for the data generator object. @@ -63,10 +60,9 @@ 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..798d2271 --- /dev/null +++ b/inst/include/data-generators/LocationGenerator.hpp @@ -0,0 +1,74 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file LocationGenerator.hpp + * @brief Generates and manages spatial locations for ExaGeoStat. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-04 +**/ + +#ifndef EXAGEOSTATCPP_LOCATIONGENERATOR_HPP +#define EXAGEOSTATCPP_LOCATIONGENERATOR_HPP + +#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..d159f161 100644 --- a/inst/include/data-generators/concrete/SyntheticGenerator.hpp +++ b/inst/include/data-generators/concrete/SyntheticGenerator.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file SyntheticGenerator.hpp * @brief A class for generating synthetic data. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-02-14 @@ -38,74 +38,15 @@ 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 * - CreateData(exageostat::configurations::Configurations &aConfigurations, - const exageostat::hardware::ExaGeoStatHardware &aHardware, + std::unique_ptr> + CreateData(configurations::Configurations &aConfigurations, 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..5f530bd6 --- /dev/null +++ b/inst/include/data-loader/DataLoader.hpp @@ -0,0 +1,80 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file DataLoader.hpp + * @brief Manages data loading operations for ExaGeoStat. + * @version 1.1.0 + * @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(configurations::Configurations &aConfigurations, 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. + * @return void + * + */ + virtual void + ReadData(configurations::Configurations &aConfigurations, std::vector &aMeasurementsMatrix, + std::vector &aXLocations, + std::vector &aYLocations, std::vector &aZLocations, const int &aP) = 0; + + /** + * @brief Writes a matrix of vectors to disk. + * @param[in] aMatrixPointer A Reference to the matrix data. + * @param[in] aProblemSize The size of the problem. + * @param[in] aP The number of processes. + * @param[in] aLoggerPath The path to the logger file. + * @param[in] aLocations A Reference to the Locations object. + * @return void + * + */ + virtual void + WriteData(const T &aMatrixPointer, const int &aProblemSize, const int &aP, std::string &aLoggerPath, + exageostat::dataunits::Locations &aLocations) = 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..52b185bd --- /dev/null +++ b/inst/include/data-loader/concrete/CSVLoader.hpp @@ -0,0 +1,92 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file CSVLoader.hpp + * @brief A class for generating synthetic data. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-04 +**/ + +#ifndef EXAGEOSTAT_CPP_CSVDATALOADER_HPP +#define EXAGEOSTAT_CPP_CSVDATALOADER_HPP + +#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(configurations::Configurations &aConfigurations, std::vector &aMeasurementsMatrix, + std::vector &aXLocations, std::vector &aYLocations, std::vector &aZLocations, + const int &aP) override; + + /** + * @brief Writes a matrix of vectors to disk. + * @copydoc DataLoader::WriteData() + * + */ + void + WriteData(const T &aMatrixPointer, const int &aProblemSize, const int &aP, std::string &aLoggerPath, + exageostat::dataunits::Locations &aLocations) override; + + /** + * @brief 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..4c2b1d89 100644 --- a/inst/include/data-units/DescriptorData.hpp +++ b/inst/include/data-units/DescriptorData.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file DescriptorData.hpp * @brief Contains the definition of the DescriptorData class. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-07-18 @@ -15,18 +15,21 @@ #ifndef EXAGEOSTATCPP_DESCRIPTORDATA_HPP #define EXAGEOSTATCPP_DESCRIPTORDATA_HPP +#include + #include #include namespace exageostat::dataunits { /** - * @brief Union representing the base descriptor. + * @brief Union represents the base descriptor. * @details This union is used to store different types of descriptors based on the configuration. + * */ union BaseDescriptor { CHAM_desc_t *chameleon_desc; -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA HICMA_desc_t *hicma_desc; #endif }; @@ -35,6 +38,7 @@ namespace exageostat::dataunits { * @Class DescriptorData * @brief Manages geo-statistical descriptor data with functions for retrieving and manipulating descriptors * @tparam T Data Type: float or double + * */ template class DescriptorData { @@ -42,21 +46,24 @@ namespace exageostat::dataunits { public: /** * @brief Default Constructor for DescriptorData. + * */ explicit DescriptorData() = default; /** * @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); @@ -71,7 +78,7 @@ namespace exageostat::dataunits { /** * @brief Set the sequence. * @param[in] apSequence Pointer to the sequence. - * + * @return void */ void SetSequence(void *apSequence); @@ -85,18 +92,22 @@ namespace exageostat::dataunits { /** * @brief Set the request. * @param[in] apRequest Pointer to the request. + * @return void * */ void SetRequest(void *apRequest); -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA /** * @brief Converts a CHAMELEON descriptor to a HICMA descriptor. * @param[in] apChameleonDesc Pointer to the CHAMELEON descriptor to be converted. + * @param[in] aDescriptorName The name of the descriptor. * @return Pointer to the converted HICMA descriptor. + * */ - HICMA_desc_t *ConvertChameleonToHicma(CHAM_desc_t *apChameleonDesc); + HICMA_desc_t * + ConvertChameleonToHicma(CHAM_desc_t *apChameleonDesc, const common::DescriptorName &aDescriptorName); #endif @@ -118,32 +129,40 @@ 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 + * @param[in] aConverted Boolean indicates whether it's a converted descriptor from chameleon to hicma or not, default is false * @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, const bool &aConverted = false); /** * @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. + * @param[in] aDescriptorName The name of 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); + T *GetDescriptorMatrix(const common::DescriptorType &aDescriptorType, + const common::DescriptorName &aDescriptorName); /** * @brief Getter for the mIsDescriptorInitiated field. * @return mIsDescriptorInitiated + * */ bool GetIsDescriptorInitiated(); /** * @brief Setter for mIsDescriptorInitiated field. * @param aIsInitiated Boolean for setting the mIsDescriptorInitiated field. + * */ void SetIsDescriptorInitiated(bool aIsInitiated); @@ -153,6 +172,7 @@ namespace exageostat::dataunits { * @param[in] aDescriptorName The descriptor name. * @return The descriptor name as a string. * @throws std::invalid_argument if the provided descriptor name is not available. + * */ std::string GetDescriptorName(const common::DescriptorName &aDescriptorName); diff --git a/inst/include/data-units/ExaGeoStatData.hpp b/inst/include/data-units/ExaGeoStatData.hpp index c35f1ac8..bc9017bf 100644 --- a/inst/include/data-units/ExaGeoStatData.hpp +++ b/inst/include/data-units/ExaGeoStatData.hpp @@ -1,15 +1,15 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file ExaGeoStatData.hpp * @brief Contains the definition of the ExaGeoStatData class. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-07-19 + * @date 2024-02-04 **/ #ifndef EXAGEOSTATCPP_EXAGEOSTATDATA_HPP @@ -17,90 +17,103 @@ #include #include -#include -#include -namespace exageostat::dataunits { +/** + * @Class ExaGeoStatData + * @brief Manages geo-statistical data with functions for location and descriptor manipulation + * @tparam T Data Type: float or double + */ +template +class ExaGeoStatData { + +public: + /** + * @brief Constructor for ExaGeoStatData. + * @param[in] aSize The size of the data. + * @param[in] aDimension The dimension of the data. + * + */ + ExaGeoStatData(const int &aSize, const exageostat::common::Dimension &aDimension); + + /** + * @brief Constructor for ExaGeoStatData. + * @param[in] aSize The size of the data. + * @param[in] aDimension The dimension of the data. + * + */ + ExaGeoStatData(const int &aSize, const std::string &aDimension); + + /** + * @brief Default constructor for ExaGeoStatData. + * + */ + ExaGeoStatData() = default; /** - * @Class ExaGeoStatData - * @brief Manages geo-statistical data with functions for location and descriptor manipulation - * @tparam T Data Type: float or double + * @brief Destructor for ExaGeoStatData. + * */ - template - class ExaGeoStatData { - - public: - /** - * @brief Constructor for ExaGeoStatData. - * @param[in] aSize The size of the data. - * @param[in] aDimension The dimension of the data. - */ - ExaGeoStatData(const int &aSize, const exageostat::common::Dimension &aDimension); - - /** - * @brief Default constructor for ExaGeoStatData. - */ - ExaGeoStatData() = default; - - /** - * @brief Destructor for ExaGeoStatData. - */ - ~ExaGeoStatData(); - - /** - * @brief Get the locations. - * @return Pointer to the Locations object. - */ - Locations *GetLocations(); - - /** - * @brief Set the locations. - * @param[in] aLocation Pointer to the Locations object. - */ - void SetLocations(Locations &aLocation); - - /** - * @brief Get the descriptor data. - * @return Pointer to the DescriptorData object. - */ - DescriptorData *GetDescriptorData(); - - /** - * @brief Setter for the number of performed MLE iterations. - * @param[in] aMleIterations number of performed MLE iterations. - * @return void - */ - void SetMleIterations(const int &aMleIterations); - - /** - * @brief Get the number of performed MLE iterations. - * @return Pointer to the DescriptorData object. - */ - int GetMleIterations(); - - /** - * @brief Calculates Median Locations. - * @param[in] aKernelName Name of the Kernel used. - * @param[out] aLocations Location object to save medianLocations in. - * @return void - */ - void CalculateMedianLocations(const std::string &aKernelName, dataunits::Locations &aLocations); - - private: - //// Used descriptor data. - DescriptorData *mpDescriptorData = nullptr; - //// Used locations data. - Locations *mpLocations = nullptr; - //// Current number of performed MLE iterations. - int mMleIterations = 0; - }; + ~ExaGeoStatData(); /** - * @brief Instantiates the ExaGeoStatData class for float and double types. - * @tparam T Data Type: float or double + * @brief Get the locations. + * @return Pointer to the Locations object. + * */ - EXAGEOSTAT_INSTANTIATE_CLASS(ExaGeoStatData) -} // namespace exageostat + exageostat::dataunits::Locations *GetLocations(); + + /** + * @brief Set the locations. + * @param[in] aLocation Pointer to the Locations object. + * @return void + * + */ + void SetLocations(exageostat::dataunits::Locations &aLocation); + + /** + * @brief Get the descriptor data. + * @return Pointer to the DescriptorData object. + * + */ + exageostat::dataunits::DescriptorData *GetDescriptorData(); + + /** + * @brief Setter for the number of performed MLE iterations. + * @param[in] aMleIterations number of performed MLE iterations. + * @return void + * + */ + void SetMleIterations(const int &aMleIterations); + + /** + * @brief Get the number of performed MLE iterations. + * @return Pointer to the DescriptorData object. + * + */ + int GetMleIterations(); + + /** + * @brief Calculates Median Locations. + * @param[in] aKernelName Name of the Kernel used. + * @param[out] aLocations Location object to save medianLocations in. + * @return void + * + */ + void CalculateMedianLocations(const std::string &aKernelName, exageostat::dataunits::Locations &aLocations); + +private: + //// Used descriptor data. + exageostat::dataunits::DescriptorData *mpDescriptorData = nullptr; + //// Used locations data. + exageostat::dataunits::Locations *mpLocations = nullptr; + //// Current number of performed MLE iterations. + int mMleIterations = 0; +}; + +/** + * @brief Instantiates the ExaGeoStatData class for float and double types. + * @tparam T Data Type: float or double + */ +EXAGEOSTAT_INSTANTIATE_CLASS(ExaGeoStatData) #endif //EXAGEOSTATCPP_EXAGEOSTATDATA_HPP \ No newline at end of file diff --git a/inst/include/data-units/Locations.hpp b/inst/include/data-units/Locations.hpp index 032be1f9..72115ddd 100644 --- a/inst/include/data-units/Locations.hpp +++ b/inst/include/data-units/Locations.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file Locations.hpp * @brief Header file for the Locations class, which contains methods to set and get location data. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-02-27 @@ -39,14 +39,15 @@ namespace exageostat::dataunits { /** * @brief Default copy constructor. * @param[in] aLocations Locations to be copied. + * */ 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..bc9b8f15 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.1.0 * @author Mahmoud ElKarargy * @date 2023-08-24 **/ @@ -18,11 +18,9 @@ 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. - const hardware::ExaGeoStatHardware *mpHardware; /// Used Kernel for ExaGeoStat Modeling Data. const kernels::Kernel *mpKernel; @@ -33,13 +31,12 @@ namespace exageostat::dataunits { * @brief Constructor. * @param aData The ExaGeoStatData object. * @param aConfiguration The Configurations object. - * @param aHardware The hardware configuration object. * @param aKernel The Kernel object. */ - mModelingData(dataunits::ExaGeoStatData &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) {} + mModelingData(std::unique_ptr> &aData, configurations::Configurations &aConfiguration, + T &aMatrix, const kernels::Kernel &aKernel) : + mpData(std::move(&aData)), mpConfiguration(&aConfiguration), mpMeasurementsMatrix(&aMatrix), + mpKernel(&aKernel) {} }; }//namespace exageostat diff --git a/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp b/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp index ab82aeb5..fbf1eb3d 100644 --- a/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp +++ b/inst/include/data-units/descriptor/ExaGeoStatDescriptor.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file ExaGeoStatDescriptor.hpp * @brief Class for creating matrix descriptors used in CHAMELEON and HiCMA libraries. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-07-16 @@ -15,8 +15,6 @@ #ifndef EXAGEOSTATCPP_EXAGEOSTATDESCRIPTOR_HPP #define EXAGEOSTATCPP_EXAGEOSTATDESCRIPTOR_HPP -#include - #include #include #include @@ -69,13 +67,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..cabe7557 100644 --- a/inst/include/data-units/descriptor/concrete/ChameleonDescriptor.hpp +++ b/inst/include/data-units/descriptor/concrete/ChameleonDescriptor.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file ChameleonDescriptor.hpp * @brief Defines the ChameleonDescriptor class for creating matrix descriptors using the CHAMELEON library. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-08-15 @@ -16,7 +16,6 @@ #define EXAGEOSTATCPP_CHAMELEONDESCRIPTOR_HPP #include - #include namespace exageostat::dataunits::descriptor { @@ -47,6 +46,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 +54,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..0ffb27fe 100644 --- a/inst/include/data-units/descriptor/concrete/HicmaDescriptor.hpp +++ b/inst/include/data-units/descriptor/concrete/HicmaDescriptor.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file HicmaDescriptor.hpp * @brief Defines the Hicma Descriptor class for creating matrix descriptors using the HICMA library. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-08-15 @@ -16,7 +16,6 @@ #define EXAGEOSTATCPP_HICMADESCRIPTOR_HPP #include - #include namespace exageostat::dataunits::descriptor { @@ -47,6 +46,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 +54,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..6e872091 100644 --- a/inst/include/hardware/ExaGeoStatHardware.hpp +++ b/inst/include/hardware/ExaGeoStatHardware.hpp @@ -1,15 +1,15 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file ExaGeoStatHardware.hpp * @brief Contains the definition of the ExaGeoStatHardware class. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-08-07 + * @date 2024-01-24 **/ #ifndef EXAGEOSTATCPP_EXAGEOSTATHARDWARE_HPP @@ -17,64 +17,131 @@ #include -namespace exageostat::hardware { +/** + * @brief Class represents the hardware configuration for the ExaGeoStat solver. + * + */ +class ExaGeoStatHardware { +public: /** - * @brief Class representing the hardware configuration for the ExaGeoStat solver. + * @brief Constructor for ExaGeoStatHardware. + * @param[in] aComputation The computation mode for the solver. + * @param[in] aCoreNumber The number of CPU cores to use for the solver. + * @param[in] aGpuNumber The number of GPUs to use for the solver. + * @param[in] aP The P grid dimension setting, default is 1. + * @param[in] aQ The Q grid dimension setting, default is 1. + * */ - class ExaGeoStatHardware { - - public: - /** - * @brief Constructor for ExaGeoStatHardware. - * @param[in] aComputation The computation mode for the solver. - * @param[in] aCoreNumber The number of CPU cores to use for the solver. - * @param[in] aGpuNumber The number of GPUs to use for the solver. - * - */ - ExaGeoStatHardware(const common::Computation &aComputation, const int &aCoreNumber, const int &aGpuNumber); - - /** - * @brief Destructor for ExaGeoStatHardware. - */ - virtual ~ExaGeoStatHardware(); - - /** - * @brief Get the Chameleon hardware context. - * @return Pointer to the hardware context. - * - */ - [[nodiscard]] void *GetChameleonContext() const; - -#ifdef EXAGEOSTAT_USE_HICMA + explicit ExaGeoStatHardware(const exageostat::common::Computation &aComputation, const int &aCoreNumber, + const int &aGpuNumber, const int &aP = 1, const int &aQ = 1); -/** - * @brief Get the Hicma hardware context. - * @return Pointer to the hardware context. - * - */ - [[nodiscard]] void *GetHicmaContext() const; - -#endif - - /** - * @brief Get the hardware context. - * @param[in] aComputation Used computation to decide whether to use Hicma or Chameleon context. - * @return Pointer to the hardware context. - * - */ - [[nodiscard]] void *GetContext(common::Computation aComputation) const; - - private: - //// Used Pointer to the Chameleon hardware context. - void *mpChameleonContext = nullptr; -#ifdef EXAGEOSTAT_USE_HICMA - //// Used Pointer to the Hicma hardware context. - void *mpHicmaContext = nullptr; -#endif - //// Used Computation mode for the solver. - common::Computation mComputation; - }; -} // namespace exageostat + /** + * @brief Constructor for ExaGeoStatHardware. + * @param[in] aComputation The computation mode for the solver as a string. + * @param[in] aCoreNumber The number of CPU cores to use for the solver. + * @param[in] aGpuNumber The number of GPUs to use for the solver. + * @param[in] aP The P grid dimension setting. + * @param[in] aQ The Q grid dimension setting. + * + */ + explicit ExaGeoStatHardware(const std::string &aComputation, const int &aCoreNumber, const int &aGpuNumber, + const int &aP = 1, const int &aQ = 1); + + /** + * @brief A Finalize caller for Hardware. + * @return void. + * + */ + void FinalizeHardware(); + + /** + * @brief Destructor for ExaGeoStatHardware. + * + */ + ~ExaGeoStatHardware(); + + /** + * @brief Initializes hardware configuration. + * @param[in] aComputation The computation mode for the solver. + * @param[in] aCoreNumber The number of CPU cores to use for the solver. + * @param[in] aGpuNumber The number of GPUs to use for the solver. + * @param[in] aP The P grid dimension setting. + * @param[in] aQ The Q grid dimension setting. + * @return void + * + */ + static void + InitHardware(const exageostat::common::Computation &aComputation, const int &aCoreNumber, const int &aGpuNumber, + const int &aP, const int &aQ); + + /** + * @brief Get the Chameleon hardware context. + * @return Pointer to the hardware context. + * + */ + [[nodiscard]] static void *GetChameleonContext(); + + /** + * @brief Get the HiCMA hardware context. + * @return Pointer to the hardware context. + * + */ + [[nodiscard]] static void *GetHicmaContext(); + + /** + * @brief Get the hardware context. + * @param[in] aComputation Used computation to decide whether to use Hicma or Chameleon context. + * @return Pointer to the hardware context. + * + */ + [[nodiscard]] static void *GetContext(exageostat::common::Computation aComputation); + + /** + * @brief Retrieves the P dimension of the grid. + * @details This function returns the current setting of the P dimension of the grid, which is part of the grid configuration used in various computational processes. + * @return The current P dimension setting. + * + **/ + static int GetPGrid(); + + /** + * @brief Retrieves the Q dimension of the grid. + * @details This function returns the current setting of the Q dimension of the grid, which is part of the grid configuration used in various computational processes. + * @return int The current Q dimension setting. + * + **/ + static int GetQGrid(); + + /** + * @brief Sets the P dimension of the grid. + * @details This function updates the P dimension setting of the grid. This dimension is critical in configuring the grid's layout for simulations or calculations. + * @param[in] aP The new value for the P dimension. + * @return void + * + **/ + static void SetPGrid(int aP); + + /** + * @brief Sets the Q dimension of the grid. + * @details This function updates the Q dimension setting of the grid. This dimension is crucial in configuring the grid's layout for simulations or calculations. + * @param[in] aQ The new value for the Q dimension. + * @return void + * + **/ + static void SetQGrid(int aQ); + +private: + //// Used Pointer to the Chameleon hardware context. + static void *mpChameleonContext; + //// Used Pointer to the Hicma hardware context. + static void *mpHicmaContext; + //// Used P-Grid + static int mPGrid; + //// Used Q-Grid + static int mQGrid; + //// Used boolean to avoid re-init mpi + static bool mIsMPIInit; +}; #endif // EXAGEOSTATCPP_EXAGEOSTATHARDWARE_HPP \ No newline at end of file diff --git a/inst/include/helpers/BasselFunction.hpp b/inst/include/helpers/BasselFunction.hpp new file mode 100644 index 00000000..2ce49385 --- /dev/null +++ b/inst/include/helpers/BasselFunction.hpp @@ -0,0 +1,69 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file 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.1.0 + * @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..2a7f41d1 --- /dev/null +++ b/inst/include/helpers/ByteHandler.hpp @@ -0,0 +1,48 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ByteHandler.hpp + * @brief Implementation of byte manipulation functions for ExaGeoStat. + * @version 1.1.0 + * @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/CommunicatorMPI.hpp b/inst/include/helpers/CommunicatorMPI.hpp index d9051cbb..1b1f1bb9 100644 --- a/inst/include/helpers/CommunicatorMPI.hpp +++ b/inst/include/helpers/CommunicatorMPI.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file CommunicatorMPI.hpp * @brief Defines the CommunicatorMPI class for MPI rank communication. - * @version 1.0.0 + * @version 1.1.0 * @author Sameh Abdulah * @date 2023-11-10 **/ @@ -27,6 +27,7 @@ namespace exageostat::helpers { /** * @brief Get a pointer to the singleton instance of the CommunicatorMPI class. * @return A pointer to the instance of the CommunicatorMPI class. + * */ static CommunicatorMPI *GetInstance(); @@ -35,7 +36,7 @@ namespace exageostat::helpers { * @return The rank of the MPI process. * */ - [[nodiscard]] bool GetRank() const; + [[nodiscard]] int GetRank() const; /** * @brief Set the hardware initialization flag. @@ -55,14 +56,19 @@ namespace exageostat::helpers { private: + /** + * @brief Prevent Class Instantiation for Communicator MPI Class. + * + */ + CommunicatorMPI() = default; + /** * @brief Pointer to the singleton instance of the CommunicatorMPI class. * */ static CommunicatorMPI *mpInstance; - /// Used boolean to check if hardware is initialized. - bool mIsHardwareInitialized = false; + bool mIsHardwareInitialized; }; } #endif //EXAGEOSTATCPP_COMMUNICATORMPI_HPP diff --git a/inst/include/helpers/DiskWriter.hpp b/inst/include/helpers/DiskWriter.hpp deleted file mode 100644 index 822e86a4..00000000 --- a/inst/include/helpers/DiskWriter.hpp +++ /dev/null @@ -1,55 +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 DiskWriter.hpp - * @brief Contains the definition of the DiskWriter class for writing data to disk. - * @version 1.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @date 2023-06-08 -**/ - -#ifndef EXAGEOSTATCPP_DISKWRITER_HPP -#define EXAGEOSTATCPP_DISKWRITER_HPP - -#include -#include - -namespace exageostat::helpers { - - /** - * @class DiskWriter - * @brief A class for writing data to disk. - * @tparam T Data Type: float or double - * - */ - template - class DiskWriter { - public: - - /** - * @brief Writes a matrix of vectors to disk. - * @param[in] aMatrixPointer A Reference to the matrix data. - * @param[in] aProblemSize The size of the problem. - * @param[in] aP The number of processes. - * @param[in] aLoggerPath The path to the logger file. - * @param[in] aLocations A Reference to the Locations object. - * @return void - * - */ - void static - WriteVectorsToDisk(const T &aMatrixPointer, const int &aProblemSize, const int &aP, std::string &aLoggerPath, - exageostat::dataunits::Locations &aLocations); - }; - - /** - * @brief Instantiates the DiskWriter class for float and double types. - * @tparam T Data Type: float or double - * - */ - EXAGEOSTAT_INSTANTIATE_CLASS(DiskWriter) -} -#endif //EXAGEOSTATCPP_DISKWRITER_HPP diff --git a/inst/include/helpers/DistanceCalculationHelpers.hpp b/inst/include/helpers/DistanceCalculationHelpers.hpp index c8c5e44f..bf74c31a 100644 --- a/inst/include/helpers/DistanceCalculationHelpers.hpp +++ b/inst/include/helpers/DistanceCalculationHelpers.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file DistanceCalculationHelpers.hpp * @brief Contains the definition of the DistanceCalculationHelpers class. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-06-08 @@ -23,6 +23,7 @@ namespace exageostat::helpers { * @Class DistanceCalculationHelpers * @brief Class to calculate the distance between two points. * @tparam T Data Type: float or double. + * */ template @@ -37,6 +38,7 @@ namespace exageostat::helpers { * @param[in] aDistanceMetric Flag indicating the distance metric to use (1 for Manhattan distance, 2 for Euclidean distance). * @param[in] aFlagZ Flag indicating whether the points are in 2D or 3D space (0 for 2D, 1 for 3D). * @return The Euclidean distance between the two points. + * */ static T CalculateDistance(exageostat::dataunits::Locations &aLocations1, exageostat::dataunits::Locations &aLocations2, const int &aIdxLocation1, @@ -49,9 +51,19 @@ namespace exageostat::helpers { * @param[in] aLatitude2 Latitude of the second point in degrees. * @param[in] aLongitude2 Longitude of the second point in degrees. * @return The distance between the two points in kilometers. + * */ 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..3d018d5c 100644 --- a/inst/include/kernels/Kernel.hpp +++ b/inst/include/kernels/Kernel.hpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -30,6 +30,7 @@ extern "C" { #include #include #include +#include /** * @def EARTH_RADIUS @@ -39,15 +40,6 @@ extern "C" { */ #define EARTH_RADIUS 6371.0 -/** - * @def POW_e - * @brief The value of e to the power of 1. - * @details This macro defines the value of e to the power of 1, which is used in some kernel functions. - * - */ -#define POW_e (2.71828182845904) - - namespace exageostat::kernels { struct KernelsConfigurations { @@ -77,6 +69,7 @@ namespace exageostat::kernels { /** * Default virtual destructor to be overridden by the the suitable concrete kernel destructor. + * */ virtual ~Kernel() = default; @@ -93,6 +86,7 @@ namespace exageostat::kernels { * @param[in] aLocalTheta An array of kernel parameters. * @param [in] aDistanceMetric Distance metric to be used (1 = Euclidean, 2 = Manhattan, 3 = Minkowski). * @return void + * */ virtual void GenerateCovarianceMatrix(T *apMatrixA, const int &aRowsNumber, const int &aColumnsNumber, const int &aRowOffset, @@ -100,55 +94,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 +119,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/BivariateMaternFlexible.hpp b/inst/include/kernels/concrete/BivariateMaternFlexible.hpp index c8286aea..73caa332 100644 --- a/inst/include/kernels/concrete/BivariateMaternFlexible.hpp +++ b/inst/include/kernels/concrete/BivariateMaternFlexible.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file BivariateMaternFlexible.hpp * @brief Defines the BivariateMaternFlexible class, a Bivariate Matern Flexible kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class BivariateMaternFlexible - * @brief A class representing a Bivariate Matern Flexible kernel. + * @brief A class represents a Bivariate Matern Flexible kernel. * @details This class represents a Bivariate Matern Flexible, 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new BivariateMaternFlexible object. * @details Initializes a new BivariateMaternFlexible object with default values. + * */ BivariateMaternFlexible(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/BivariateMaternParsimonious.hpp b/inst/include/kernels/concrete/BivariateMaternParsimonious.hpp index ae702c31..f98b2d32 100644 --- a/inst/include/kernels/concrete/BivariateMaternParsimonious.hpp +++ b/inst/include/kernels/concrete/BivariateMaternParsimonious.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file BivariateMaternParsimonious.hpp * @brief Defines the BivariateMaternParsimonious class, a Bivariate Matern Parsimonious kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class BivariateMaternParsimonious - * @brief A class representing a Bivariate Matern Parsimonious kernel. + * @brief A class represents a Bivariate Matern Parsimonious kernel. * @details This class represents a Bivariate Matern Parsimonious, 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new BivariateMaternParsimonious object. * @details Initializes a new BivariateMaternParsimonious object with default values. + * */ BivariateMaternParsimonious(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/BivariateSpacetimeMaternStationary.hpp b/inst/include/kernels/concrete/BivariateSpacetimeMaternStationary.hpp index a6b0416a..89236fae 100644 --- a/inst/include/kernels/concrete/BivariateSpacetimeMaternStationary.hpp +++ b/inst/include/kernels/concrete/BivariateSpacetimeMaternStationary.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file BivariateSpacetimeMaternStationary.hpp * @brief Defines the BivariateSpacetimeMaternStationary class, a Bivariate Spacetime Matern Stationary kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class BivariateSpacetimeMaternStationary - * @brief A class representing a Bivariate Spacetime Matern Stationary kernel. + * @brief A class represents a Bivariate Spacetime Matern Stationary kernel. * @details This class represents a Bivariate Spacetime Matern 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new BivariateSpacetimeMaternStationary object. * @details Initializes a new BivariateSpacetimeMaternStationary object with default values. + * */ BivariateSpacetimeMaternStationary(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/TrivariateMaternParsimonious.hpp b/inst/include/kernels/concrete/TrivariateMaternParsimonious.hpp index c81bd704..b3024753 100644 --- a/inst/include/kernels/concrete/TrivariateMaternParsimonious.hpp +++ b/inst/include/kernels/concrete/TrivariateMaternParsimonious.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file TrivariateMaternParsimonious.hpp * @brief Defines the TrivariateMaternParsimonious class, a Trivariate Matern Parsimonious kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class TrivariateMaternParsimonious - * @brief A class representing a Trivariate Matern Parsimonious kernel. + * @brief A class represents a Trivariate Matern Parsimonious kernel. * @details This class represents a Trivariate Matern Parsimonious, 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new TrivariateMaternParsimonious object. * @details Initializes a new TrivariateMaternParsimonious object with default values. + * */ TrivariateMaternParsimonious(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/UnivariateExpNonGaussian.hpp b/inst/include/kernels/concrete/UnivariateExpNonGaussian.hpp index 3248cfed..7a51d0db 100644 --- a/inst/include/kernels/concrete/UnivariateExpNonGaussian.hpp +++ b/inst/include/kernels/concrete/UnivariateExpNonGaussian.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateExpNonGaussian.hpp * @brief Defines the UnivariateExpNonGaussian class, a Univariate Exp Non Gaussian kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class UnivariateExpNonGaussian - * @brief A class representing a Univariate Exp Non Gaussian kernel. + * @brief A class represents a Univariate Exp Non Gaussian kernel. * @details This class represents a Univariate Exp Non Gaussian, 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateExpNonGaussian object. * @details Initializes a new UnivariateExpNonGaussian object with default values. + * */ UnivariateExpNonGaussian(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/UnivariateMaternDbeta.hpp b/inst/include/kernels/concrete/UnivariateMaternDbeta.hpp index b1a6a95f..7f51a7eb 100644 --- a/inst/include/kernels/concrete/UnivariateMaternDbeta.hpp +++ b/inst/include/kernels/concrete/UnivariateMaternDbeta.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDbeta.hpp * @brief Defines the UnivariateMaternDbeta class, a Univariate Matern Dbeta kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class UnivariateMaternDbeta - * @brief A class representing a Univariate Matern Dbeta kernel. + * @brief A class represents a Univariate Matern Dbeta kernel. * @details This class represents a Univariate Matern Dbeta, 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateMaternDbeta object. * @details Initializes a new UnivariateMaternDbeta object with default values. + * */ UnivariateMaternDbeta(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/UnivariateMaternDdbetaBeta.hpp b/inst/include/kernels/concrete/UnivariateMaternDdbetaBeta.hpp index a012eb87..33cc1dc6 100644 --- a/inst/include/kernels/concrete/UnivariateMaternDdbetaBeta.hpp +++ b/inst/include/kernels/concrete/UnivariateMaternDdbetaBeta.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDdbetaBeta.hpp * @brief Defines the UnivariateMaternDdbetaBeta class, a Univariate Matern Ddbeta Beta kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class UnivariateMaternDdbetaBeta - * @brief A class representing a Univariate Matern Ddbeta Beta kernel. + * @brief A class represents a Univariate Matern Ddbeta Beta kernel. * @details This class represents a Univariate Matern Ddbeta Beta, 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateMaternDdbetaBeta object. * @details Initializes a new UnivariateMaternDdbetaBeta object with default values. + * */ UnivariateMaternDdbetaBeta(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/UnivariateMaternDdbetaNu.hpp b/inst/include/kernels/concrete/UnivariateMaternDdbetaNu.hpp index 689e37ee..06fa2bc0 100644 --- a/inst/include/kernels/concrete/UnivariateMaternDdbetaNu.hpp +++ b/inst/include/kernels/concrete/UnivariateMaternDdbetaNu.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDdbetaNu.hpp * @brief Defines the UnivariateMaternDdbetaNu class, a Univariate Matern Ddbeta Nu kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class UnivariateMaternDdbetaNu - * @brief A class representing a Univariate Matern Ddbeta Nu kernel. + * @brief A class represents a Univariate Matern Ddbeta Nu kernel. * @details This class represents a Univariate Matern Ddbeta Nu, 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateMaternDdbetaNu object. * @details Initializes a new UnivariateMaternDdbetaNu object with default values. + * */ UnivariateMaternDdbetaNu(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/UnivariateMaternDdnuNu.hpp b/inst/include/kernels/concrete/UnivariateMaternDdnuNu.hpp index 5623debd..6d2376a3 100644 --- a/inst/include/kernels/concrete/UnivariateMaternDdnuNu.hpp +++ b/inst/include/kernels/concrete/UnivariateMaternDdnuNu.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDdnuNu.hpp * @brief Defines the UnivariateMaternDdnuNu class, a Univariate Matern Ddnu Nu kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class UnivariateMaternDdnuNu - * @brief A class representing a Univariate Matern Ddnu Nu kernel. + * @brief A class represents a Univariate Matern Ddnu Nu kernel. * @details This class represents a Univariate Matern Ddnu Nu , 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateMaternDdnuNu object. * @details Initializes a new UnivariateMaternDdnuNu object with default values. + * */ UnivariateMaternDdnuNu(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/UnivariateMaternDdsigmaSquare.hpp b/inst/include/kernels/concrete/UnivariateMaternDdsigmaSquare.hpp index 162bee37..9b596972 100644 --- a/inst/include/kernels/concrete/UnivariateMaternDdsigmaSquare.hpp +++ b/inst/include/kernels/concrete/UnivariateMaternDdsigmaSquare.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDdsigmaSquare.hpp * @brief Defines the UnivariateMaternDdsigmaSquare class, a univariate stationary Matern kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -28,7 +28,7 @@ namespace exageostat::kernels { /** * @class UnivariateMaternDdsigmaSquare - * @brief A class representing a Univariate Matern Ddsigma Square kernel. + * @brief A class represents a Univariate Matern Ddsigma Square kernel. * @details This class represents a Univariate Matern Ddsigma Square, 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. * @@ -41,6 +41,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateMaternDdsigmaSquare object. * @details Initializes a new UnivariateMaternDdsigmaSquare object with default values. + * */ UnivariateMaternDdsigmaSquare(); @@ -53,6 +54,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/UnivariateMaternDdsigmaSquareBeta.hpp b/inst/include/kernels/concrete/UnivariateMaternDdsigmaSquareBeta.hpp index 57f622fc..46c71588 100644 --- a/inst/include/kernels/concrete/UnivariateMaternDdsigmaSquareBeta.hpp +++ b/inst/include/kernels/concrete/UnivariateMaternDdsigmaSquareBeta.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDdsigmaSquareBeta.hpp * @brief Defines the UnivariateMaternDdsigmaSquareBeta class, a Univariate Matern Ddsigma Square Beta kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class UnivariateMaternDdsigmaSquareBeta - * @brief A class representing a Univariate Matern Ddsigma Square Beta kernel. + * @brief A class represents a Univariate Matern Ddsigma Square Beta kernel. * @details This class represents a Univariate Matern Ddsigma Square Beta, 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateMaternDdsigmaSquareBeta object. * @details Initializes a new UnivariateMaternDdsigmaSquareBeta object with default values. + * */ UnivariateMaternDdsigmaSquareBeta(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/UnivariateMaternDdsigmaSquareNu.hpp b/inst/include/kernels/concrete/UnivariateMaternDdsigmaSquareNu.hpp index ae33506a..5092e4ae 100644 --- a/inst/include/kernels/concrete/UnivariateMaternDdsigmaSquareNu.hpp +++ b/inst/include/kernels/concrete/UnivariateMaternDdsigmaSquareNu.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDdsigmaSquareNu.hpp * @brief Defines the UnivariateMaternDdsigmaSquareNu class, a Univariate Matern Ddsigma Square Nu kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class UnivariateMaternDdsigmaSquareNu - * @brief A class representing a Univariate Matern Ddsigma Square Nu kernel. + * @brief A class represents a Univariate Matern Ddsigma Square Nu kernel. * @details This class represents a Univariate Matern Ddsigma Square Nu, 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateMaternDdsigmaSquareNu object. * @details Initializes a new UnivariateMaternDdsigmaSquareNu object with default values. + * */ UnivariateMaternDdsigmaSquareNu(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/UnivariateMaternDnu.hpp b/inst/include/kernels/concrete/UnivariateMaternDnu.hpp index f9eefb5a..6c830bc7 100644 --- a/inst/include/kernels/concrete/UnivariateMaternDnu.hpp +++ b/inst/include/kernels/concrete/UnivariateMaternDnu.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDnu.hpp * @brief Defines the UnivariateMaternDnu class, a Univariate Matern Dnu kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class UnivariateMaternDnu - * @brief A class representing a Univariate Matern Dnu kernel. + * @brief A class represents a Univariate Matern Dnu kernel. * @details This class represents a Univariate Matern Dnu, 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateMaternDnu object. * @details Initializes a new UnivariateMaternDnu object with default values. + * */ UnivariateMaternDnu(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/UnivariateMaternDsigmaSquare.hpp b/inst/include/kernels/concrete/UnivariateMaternDsigmaSquare.hpp index 1da69311..d1a3350b 100644 --- a/inst/include/kernels/concrete/UnivariateMaternDsigmaSquare.hpp +++ b/inst/include/kernels/concrete/UnivariateMaternDsigmaSquare.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDsigmaSquare.hpp * @brief Defines the UnivariateMaternDsigmaSquare class, a Univariate Matern Dsigma Square kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class UnivariateMaternDsigmaSquare - * @brief A class representing a Univariate Matern Dsigma Square kernel. + * @brief A class represents a Univariate Matern Dsigma Square kernel. * @details This class represents a Univariate Matern Dsigma Square, 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateMaternDsigmaSquare object. * @details Initializes a new UnivariateMaternDsigmaSquare object with default values. + * */ UnivariateMaternDsigmaSquare(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/UnivariateMaternNonGaussian.hpp b/inst/include/kernels/concrete/UnivariateMaternNonGaussian.hpp index 1ee3a74e..203c4c6e 100644 --- a/inst/include/kernels/concrete/UnivariateMaternNonGaussian.hpp +++ b/inst/include/kernels/concrete/UnivariateMaternNonGaussian.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternNonGaussian.hpp * @brief Defines the UnivariateMaternNonGaussian class, a Univariate Matern Non Gaussian kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class UnivariateMaternNonGaussian - * @brief A class representing a Univariate Matern Non Gaussian kernel. + * @brief A class represents a Univariate Matern Non Gaussian kernel. * @details This class represents a Univariate Matern Non Gaussian, 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateMaternNonGaussian object. * @details Initializes a new UnivariateMaternNonGaussian object with default values. + * */ UnivariateMaternNonGaussian(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, 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/kernels/concrete/UnivariateMaternNuggetsStationary.hpp b/inst/include/kernels/concrete/UnivariateMaternNuggetsStationary.hpp index 86e6cae9..3503ac44 100644 --- a/inst/include/kernels/concrete/UnivariateMaternNuggetsStationary.hpp +++ b/inst/include/kernels/concrete/UnivariateMaternNuggetsStationary.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternNuggetsStationary.hpp * @brief Defines the UnivariateMaternNuggetsStationary class, a Univariate Matern Nuggets Stationary kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class UnivariateMaternNuggetsStationary - * @brief A class representing a Univariate Matern Nuggets Stationary kernel. + * @brief A class represents a Univariate Matern Nuggets Stationary kernel. * @details This class represents a Univariate Matern Nuggets 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateMaternNuggetsStationary object. * @details Initializes a new UnivariateMaternNuggetsStationary object with default values. + * */ UnivariateMaternNuggetsStationary(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/UnivariateMaternStationary.hpp b/inst/include/kernels/concrete/UnivariateMaternStationary.hpp index ceb8cc7c..25db2fee 100644 --- a/inst/include/kernels/concrete/UnivariateMaternStationary.hpp +++ b/inst/include/kernels/concrete/UnivariateMaternStationary.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternStationary.hpp * @brief Defines the UnivariateMaternStationary class, a univariate stationary Matern kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -28,7 +28,7 @@ namespace exageostat::kernels { /** * @class UnivariateMaternStationary - * @brief A class representing a Univariate Matern Stationary kernel. + * @brief A class represents a Univariate Matern Stationary kernel. * @details This class represents a Univariate Matern 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. * @@ -41,6 +41,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateMaternStationary object. * @details Initializes a new UnivariateMaternStationary object with default values. + * */ UnivariateMaternStationary(); @@ -53,6 +54,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/kernels/concrete/UnivariatePowExpStationary.hpp b/inst/include/kernels/concrete/UnivariatePowExpStationary.hpp new file mode 100644 index 00000000..e4a76c4b --- /dev/null +++ b/inst/include/kernels/concrete/UnivariatePowExpStationary.hpp @@ -0,0 +1,87 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file UnivariatePowExpStationary.hpp + * @brief Defines the UnivariatePowExpStationary class, a univariate stationary PowExp kernel. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @author Suhas Shankar + * @author Mary Lai Salvana + * @date 2024-11-22 + * + * This file provides the declaration of the UnivariatePowExpStationary class, which is a subclass of the Kernel class + * and represents a univariate stationary PowExp kernel. It provides a method for generating a covariance matrix + * using a set of input locations and kernel parameters. + * +**/ + +#ifndef EXAGEOSTATCPP_UNIVARIATEMATERNSTATIONARY_HPP +#define EXAGEOSTATCPP_UNIVARIATEMATERNSTATIONARY_HPP + +#include + +namespace exageostat::kernels { + + /** + * @class UnivariatePowExpStationary + * @brief A class represents a Univariate PowExp Stationary kernel. + * @details This class represents a Univariate PowExp 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 UnivariatePowExpStationary : public Kernel { + + public: + + /** + * @brief Constructs a new UnivariatePowExpStationary object. + * @details Initializes a new UnivariatePowExpStationary object with default values. + * + */ + UnivariatePowExpStationary(); + + /** + * @brief Virtual destructor to allow calls to the correct concrete destructor. + * + */ + ~UnivariatePowExpStationary() 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 UnivariatePowExpStationary object. + * @details This method creates a new UnivariatePowExpStationary object and returns a pointer to it. + * @return A pointer to the new UnivariatePowExpStationary object. + * + */ + static Kernel *Create(); + + 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(UnivariatePowExpStationary) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_UNIVARIATEMATERNSTATIONARY_HPP diff --git a/inst/include/kernels/concrete/UnivariateSpacetimeMaternStationary.hpp b/inst/include/kernels/concrete/UnivariateSpacetimeMaternStationary.hpp index 35b52842..25ef5393 100644 --- a/inst/include/kernels/concrete/UnivariateSpacetimeMaternStationary.hpp +++ b/inst/include/kernels/concrete/UnivariateSpacetimeMaternStationary.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateSpacetimeMaternStationary.hpp * @brief Defines the UnivariateSpacetimeMaternStationary class, a Univariate Spacetime Matern Stationary kernel. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @author Suhas Shankar @@ -23,7 +23,7 @@ namespace exageostat::kernels { /** * @class UnivariateSpacetimeMaternStationary - * @brief A class representing a Univariate Spacetime Matern Stationary kernel. + * @brief A class represents a Univariate Spacetime Matern Stationary kernel. * @details This class represents a Univariate Spacetime Matern 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. * @@ -36,6 +36,7 @@ namespace exageostat::kernels { /** * @brief Constructs a new UnivariateSpacetimeMaternStationary object. * @details Initializes a new UnivariateSpacetimeMaternStationary object with default values. + * */ UnivariateSpacetimeMaternStationary(); @@ -48,6 +49,7 @@ namespace exageostat::kernels { /** * @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, diff --git a/inst/include/linear-algebra-solvers/LinearAlgebraFactory.hpp b/inst/include/linear-algebra-solvers/LinearAlgebraFactory.hpp index 68bf6729..fc789af8 100644 --- a/inst/include/linear-algebra-solvers/LinearAlgebraFactory.hpp +++ b/inst/include/linear-algebra-solvers/LinearAlgebraFactory.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file LinearAlgebraFactory.hpp * @brief Header file for the LinearAlgebraFactory class, which creates linear algebra solvers based on the input computation type. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @date 2023-03-20 **/ diff --git a/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp b/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp index 9790b352..251d6319 100644 --- a/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp +++ b/inst/include/linear-algebra-solvers/LinearAlgebraMethods.hpp @@ -1,15 +1,15 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file LinearAlgebraMethods.hpp * @brief Header file for the LinearAlgebraMethods class, which defines the interface for linear algebra solvers. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-03-20 + * @date 2024-02-25 * @details This header file defines the abstract class LinearAlgebraMethods, which provides an interface for linear algebra solvers. * The purpose of this interface is to allow different concrete linear algebra solvers to be interchangeable, * so that they can be used interchangeably by other parts of the software system that rely on linear algebra. @@ -25,10 +25,10 @@ extern "C" { #include } -#include -#include -#include +#include +#include #include +#include #include namespace exageostat::linearAlgebra { @@ -54,22 +54,26 @@ 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. * @param[in] aConfigurations Configurations object containing relevant settings. * @param[in,out] aDescriptorData Descriptor Data object to be populated with descriptors and data. + * @return void + * */ 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. @@ -78,62 +82,32 @@ namespace exageostat::linearAlgebra { * */ void InitiatePredictionDescriptors(configurations::Configurations &aConfigurations, - dataunits::ExaGeoStatData &aData); + std::unique_ptr> &aData); /** * @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. * @param[in] aConfigurations The configurations object containing relevant settings. - * @param[in] aHardware ExaGeoStatHardware object representing the hardware. * @param[in,out] aData ExaGeoStatData object to be populated with synthetic data. * @param[in] aKernel Reference to the kernel object to use. - * @return None. + * @return void. * */ void GenerateSyntheticData(configurations::Configurations &aConfigurations, - const hardware::ExaGeoStatHardware &aHardware, dataunits::ExaGeoStatData &aData, + std::unique_ptr> &aData, const kernels::Kernel &aKernel); - /** - * @brief Computes the covariance matrix. - * @param[in] aDescriptorData pointer to the DescriptorData object holding descriptors and data. - * @param[out] apDescriptor Pointer to the descriptor for the covariance matrix. - * @param[in] aTriangularPart Specifies whether the upper or lower triangular part of the covariance matrix is stored. - * @param[in] apLocation1 Pointer to the first set of locations. - * @param[in] apLocation2 Pointer to the second set of locations. - * @param[in] apLocation3 Pointer to the third set of locations. - * @param[in] apLocalTheta Pointer to the local theta values. - * @param[in] aDistanceMetric Specifies the distance metric to use. - * @param[in] apKernel Pointer to the kernel object to use. - * @return void - * - */ - void CovarianceMatrixCodelet(dataunits::DescriptorData &aDescriptorData, void *apDescriptor, - const int &aTriangularPart, dataunits::Locations *apLocation1, - dataunits::Locations *apLocation2, dataunits::Locations *apLocation3, - T *apLocalTheta, const int &aDistanceMetric, const kernels::Kernel *apKernel); - - /** - * @brief Copies the descriptor data to a double vector. - * @param[in] aDescriptorData pointer to the DescriptorData object holding descriptors and data. - * @param[in] apDescriptor Pointer to the descriptor data. - * @param[in,out] apDoubleVector Pointer to the double vector to copy the descriptor data to. - * @return void - * - */ - void - CopyDescriptorZ(dataunits::DescriptorData &aDescriptorData, void *apDescriptor, T *apDoubleVector); - /** * @brief Generates the observations vector. * @param[in] aConfigurations Configurations object containing relevant settings. @@ -147,14 +121,14 @@ 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); /** * @brief Calculates the log likelihood value of a given value theta. - * @param[in] aHardware ExaGeoStatHardware object representing the hardware. * @param[in,out] aData DescriptorData object to be populated with descriptors and data. * @param[in] aConfigurations Configurations object containing relevant settings. * @param[in] apTheta Optimization parameter used by NLOPT. @@ -163,18 +137,10 @@ namespace exageostat::linearAlgebra { * @return log likelihood value * */ - virtual T ExaGeoStatMLETile(const hardware::ExaGeoStatHardware &aHardware, dataunits::ExaGeoStatData &aData, + virtual T ExaGeoStatMLETile(std::unique_ptr> &aData, configurations::Configurations &aConfigurations, const double *apTheta, T *apMeasurementsMatrix, const kernels::Kernel &aKernel) = 0; - /** - * @brief Converts a Gaussian descriptor to a non-tiled descriptor. - * @param[in] aDescriptorData DescriptorData struct with the Gaussian descriptor. - * @param[in] apDesc Pointer to the non-tiled descriptor. - * @param[in] apTheta Theta vector. - * @return void - */ - void ExaGeoStatGaussianToNonTileAsync(dataunits::DescriptorData &aDescriptorData, void *apDesc, T *apTheta); /** * @brief Copies a matrix in the tile layout from source to destination @@ -186,33 +152,6 @@ namespace exageostat::linearAlgebra { */ virtual void ExaGeoStatLapackCopyTile(const common::UpperLower &aUpperLower, void *apA, void *apB) = 0; - /** - * @brief Initialize the runtime option structure for either HiCMA or CHAMELEON. - * @param[in, out] apOptions The options structure that needs to be initialized. - * @param[in] apContext The runtime context in which to initialize the runtime support. - * @param[in] apSequence The sequence structure to associate in the options. - * @param[in] apRequest The request structure to associate in the options. - * @return void - */ - virtual void - ExaGeoStatOptionsInit(void *apOptions, void *apContext, void *apSequence, void *apRequest) = 0; - - /** - * @brief Submit the release of the workspaces associated to the options structure. - * @param[in,out] apOptions The options structure for which to workspaces will be released - * @return void - */ - virtual void ExaGeoStatOptionsFree(void *apOptions) = 0; - - /** - * @brief Finalize the runtime option structure for either HiCMA or CHAMELEON. - * @param[in,out] apOptions The options structure that needs to be finalized. - * @param[in] apContext The runtime context in which to finalize the runtime support. - * @return void - * - */ - virtual void ExaGeoStatOptionsFinalize(void *apOptions, void *apContext) = 0; - /** * @brief Wait for the completion of a sequence. * @param[in] apSequence apSequence A pointer to either CHAMELEON or HiCMA sequence. @@ -240,6 +179,7 @@ namespace exageostat::linearAlgebra { * @param[in] aMaxRank Maximum rank parameter. * @param[in] aAcc Accuracy parameter. * @return void + * */ virtual void ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, void *apCD, void *apCrk, @@ -258,35 +198,12 @@ namespace exageostat::linearAlgebra { * @param[in, out] apZ The matrix B of dimension, on exit is overwritten by the solution matrix X. * @param[in] aMaxRank Maximum rank parameter. * @return void + * */ virtual void ExaGeoStatTrsmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) = 0; - /** - * @brief Calculate determinant for triangular matrix. - * @param[in] apDescA Pointer to the descriptor of the matrix 'descA'. - * @param[in] apSequence Pointer to a sequence structure for managing asynchronous execution. - * @param[in] apRequest Pointer to a request structure for tracking the operation's status. - * @param[out] apDescNum Pointer to the descriptor of the matrix to store the sum of elements. - * @param[out] apDescTrace Pointer to the descriptor of the matrix to store the trace. - * @return void - */ - void - 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. - * @param[in] apRequest Identifies this function call (for exception handling purposes). - * @param[in] apDescDet determinant value - * @return Returns 0 for success, error code otherwise. - * - */ - virtual int - ExaGeoStatMeasureDetTileAsync(void *apDescA, void *apSequence, void *apRequest, void *apDescDet) = 0; /** * @brief Solve a positive definite linear system of equations AX = B using tiled algorithms. @@ -294,23 +211,36 @@ namespace exageostat::linearAlgebra { * @param [in] apA coefficient matrix of the system of linear equations. This matrix is expected to be positive definite. * @param [in] apB Pointer to coefficient matrix of the system of linear equations. This matrix is expected to be positive definite. * @return void + * */ void ExaGeoStatPosvTile(const common::UpperLower &aUpperLower, void *apA, void *apB); /** - * @brief Calculate mean square prediction error (MSPE) scalar value of the prediction. - * @param[in] apDescZPredict Observed measurements. - * @param[in] apDescZMiss Missing measurements. - * @param[out] apDescError Mean Square Prediction Error (MSPE). - * @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. + * @brief Predict missing values base on a set of given values and 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] 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). + * */ - int ExaGeoStatMLEMSPETileAsync(void *apDescZPredict, void *apDescZMiss, void *apDescError, void *apSequence, - void *apRequest); + T *ExaGeoStatMLEPredictTile(std::unique_ptr> &aData, T *apTheta, + const int &aZMissNumber, + const int &aZObsNumber, T *apZObs, T *apZActual, T *apZMiss, + 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 covariance matrix/ + * @brief 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). @@ -318,19 +248,20 @@ namespace exageostat::linearAlgebra { * @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 * 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 *ExaGeoStatMLENonGaussianPredictTile(std::unique_ptr> &aData, T *apTheta, + const int &aZMissNumber, + const int &aZObsNumber, T *apZObs, T *apZActual, T *apZMiss, + configurations::Configurations &aConfiguration, + exageostat::dataunits::Locations &aMissLocations, + exageostat::dataunits::Locations &aObsLocations, + const kernels::Kernel &aKernel); /** * @brief Copy Lapack matrix to Descriptor Matrix. @@ -339,9 +270,9 @@ namespace exageostat::linearAlgebra { * @param[out] apDescA Matrix Descriptor. * @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. @@ -350,9 +281,26 @@ namespace exageostat::linearAlgebra { * @param[in] apDescA Matrix Descriptor * @param[in] aUpperLower Specifies whether the upper or lower triangular part of the covariance matrix is stored. * @return void + * */ 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. @@ -360,6 +308,7 @@ namespace exageostat::linearAlgebra { * @param[in] aBeta All the diagonal array elements are set to aBeta. * @param[out] apDescriptor Pointer to matrix descriptor to be set with aAlpha and aBeta. * @return void + * */ void ExaGeoStatLaSetTile(const common::UpperLower &aUpperLower, T aAlpha, T aBeta, void *apDescriptor); @@ -368,9 +317,13 @@ 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. + * @return void + * */ - void ExaGeoStatGetZObs(exageostat::configurations::Configurations &aConfigurations, T *apZ, const int &aSize, - exageostat::dataunits::DescriptorData &aDescData, T *apMeasurementsMatrix); + void ExaGeoStatGetZObs(configurations::Configurations &aConfigurations, T *apZ, const int &aSize, + exageostat::dataunits::DescriptorData &aDescData, T *apMeasurementsMatrix, + const int &aP); /** * @brief Predict missing values based on a set of given values and covariance matrix. @@ -378,50 +331,32 @@ namespace exageostat::linearAlgebra { * maximum likelihood on the empirical orthogonal functions (MLOE), and method of moments (MMOM). * @param[in] aConfigurations Configurations for the prediction. * @param[in, out] aData Data for prediction (input and output). - * @param[in] aHardware Hardware specifications for the prediction. * @param[in] apTruthTheta Pointer to the true theta values. * @param[in] apEstimatedTheta Pointer to the estimated theta values. * @param[in] aMissLocations Locations of missing values. * @param[in] aObsLocations Locations of observed values. * @param[in] aKernel Reference to the kernel object to use. * @return void + * */ - void ExaGeoStatMLETileMLOEMMOM(exageostat::configurations::Configurations &aConfigurations, - exageostat::dataunits::ExaGeoStatData &aData, - const exageostat::hardware::ExaGeoStatHardware &aHardware, T *apTruthTheta, - T *apEstimatedTheta, dataunits::Locations &aMissLocations, + void ExaGeoStatMLETileMLOEMMOM(configurations::Configurations &aConfigurations, + std::unique_ptr> &aData, + T *apTruthTheta, T *apEstimatedTheta, dataunits::Locations &aMissLocations, dataunits::Locations &aObsLocations, const kernels::Kernel &aKernel); /** * @brief Maximum Likelihood Evaluation (MLE) Fisher method. * @param[in] aConfigurations Configurations object containing relevant settings. * @param[in,out] aData Descriptor Data object to be populated with descriptors and data. - * @param[in] aHardware ExaGeoStatHardware object representing the hardware. * @param[in] apTheta Pointer containing three parameter (Variance, Range, Smoothness) that is used to to generate the Covariance Matrix. * @param[in] aKernel Reference to the kernel object to use. * @return Fisher Matrix + * */ T * - ExaGeoStatFisherTile(configurations::Configurations &aConfigurations, dataunits::ExaGeoStatData &aData, - const hardware::ExaGeoStatHardware &aHardware, T *apTheta, - const kernels::Kernel &aKernel); - - /** - * @brief Perform an asynchronous computation of MLE, MLOE, and MMOM for a tile. - * @details his function performs the computation of Maximum Likelihood Estimation (MLE), - * Maximum Likelihood on the Empirical Orthogonal Functions (MLOE), and - * Method of Moments (MMOM) for a tile asynchronously. - * @param[in] apDescExpr2 Descriptor for expression 2. - * @param[in] apDescExpr3 Descriptor for expression 3. - * @param[in] apDescExpr4 Descriptor for expression 4. - * @param[in] apDescMLOE Descriptor for MLOE. - * @param[in] apDescMMOM Descriptor for MMOM. - * @param[in] apSequence Sequence for the computation. - * @param[in] apRequest Request for the computation. - * @return Result of the asynchronous operation. - */ - int ExaGeoStatMLETileAsyncMLOEMMOM(void *apDescExpr2, void *apDescExpr3, void *apDescExpr4, void *apDescMLOE, - void *apDescMMOM, void *apSequence, void *apRequest); + ExaGeoStatFisherTile(configurations::Configurations &aConfigurations, + std::unique_ptr> &aData, + T *apTheta, const kernels::Kernel &aKernel); /** * @brief Perform a matrix addition with scaling. @@ -432,6 +367,7 @@ namespace exageostat::linearAlgebra { * @param[in] aBeta Scaling factor for matrix B. * @param[in] apDescB Descriptor for matrix B. * @return void + * */ void ExaGeoStatGeaddTile(const common::Trans &aTrans, const T &aAlpha, void *apDescA, const T &aBeta, void *apDescB); @@ -446,396 +382,23 @@ namespace exageostat::linearAlgebra { * @param[in] alpha Scaling factor for the multiplication. * @param[in] apDescA Descriptor for matrix A. * @param[in] apDescB Descriptor for matrix B. + * */ void ExaGeoStatTrmmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, const common::Trans &aTrans, const common::Diag &aDiag, const T &alpha, void *apDescA, void *apDescB); /** - * @brief Get the pointer to the data or the runtime handler associated to the piece of data (m, n) in desc. - * @param[in] apA The descriptor to which belongs the piece of data - * @param[in] aAm The row coordinate of the piece of data in the matrix - * @param[in] aAn he column coordinate of the piece of data in the matrix - * @return The runtime handler address of the piece of data. - */ - virtual void *ExaGeoStatDataGetAddr(void *apA, int aAm, int aAn) = 0; - - /** - * @brief Sets the context. - * @param[in] apContext The context. + * @brief Recovers theta and log-likelihood from a file. + * @param[in] apPath A pointer to the path of the file from which to recover the data. + * @param[in] aIterationCount The iteration count to look for in the file. + * @param[in,out] apTheta A pointer to the array where the theta values will be stored. + * @param[in,out] apLogLik A pointer to the variable where the log-likelihood value will be stored. + * @param[in] aNumParams The number of parameters (elements) in the theta array. + * @return bool `true` if the specified iteration count is found and successfully parsed, `false` otherwise. * */ - void SetContext(void *apContext) { - this->mpContext = apContext; - } - - //// TODO: Create a Factory for Runtime system. This is a solution fix for now - struct starpu_codelet cl_gaussian_to_non = - { - .where = STARPU_CPU, - .cpu_funcs = {CORE_gaussian_to_non_starpu}, - .nbuffers = 1, - .modes = {STARPU_RW}, - .name = "gaussian_to_non" - }; - - struct starpu_codelet cl_dzcpy = - { - .where = STARPU_CPU, - .cpu_funcs = {CORE_dzcpy_Starpu}, - .nbuffers = 1, - .modes = {STARPU_W}, - .name = "dzcpy" - }; - - struct starpu_codelet cl_dmdet = - { - .where = STARPU_CPU, - .cpu_funcs = {CORE_dmdet_starpu}, - .nbuffers = 2, - .modes = {STARPU_R, STARPU_RW}, - .name = "dmdet" - }; - - struct starpu_codelet cl_stride_vec = - { - .where = STARPU_CPU, - .cpu_funcs = {CORE_stride_vector_starpu}, - .nbuffers = 3, - .modes = {STARPU_R, STARPU_W, STARPU_W}, - .name = "stride_vec" - }; - - struct starpu_codelet cl_tri_stride_vec = - { - .where = STARPU_CPU, - .cpu_funcs = {CORE_tri_stride_vector_starpu}, - .nbuffers = 4, - .modes = {STARPU_R, STARPU_W, STARPU_W, STARPU_W}, - .name = "tri_stride_vec" - }; - - struct starpu_codelet cl_dmse = - { - .where = STARPU_CPU, - .cpu_funcs = {CORE_dmse_starpu}, - .nbuffers = 3, - .modes = {STARPU_RW, STARPU_R, STARPU_R}, - .name = "dmse" - }; - - struct starpu_codelet cl_dmloe_mmom = - { - .where = STARPU_CPU, - .cpu_funcs = {CORE_dmloe_mmom_starpu}, - .nbuffers = 5, - .modes = {STARPU_R, STARPU_R, STARPU_R, STARPU_RW, STARPU_RW}, - .name = "dmloe_mmom" - }; - - struct starpu_codelet cl_dcmg = - { - .where = STARPU_CPU, - .cpu_funcs = {CORE_dcmg_starpu}, - .nbuffers = 1, - .modes = {STARPU_W}, - .name = "dcmg" - }; - - struct starpu_codelet cl_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" - }; - - - - 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; - int distance_metric; - kernels::Kernel *kernel; - - 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); - } - - 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]); - - starpu_codelet_unpack_args(apCodeletArguments, &m, &m0, &theta[0], &theta[1], &theta[2], &theta[3], - &theta[4], &theta[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; - } - } - - static void CORE_dzcpy_Starpu(void *apBuffers[], void *apCodeletArguments) { - int m; - T *A; - int m0; - T *r; - - A = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); - starpu_codelet_unpack_args(apCodeletArguments, &m, &m0, &r); - memcpy(A, &r[m0], m * sizeof(T)); - } - - static void CORE_dmdet_starpu(void *apBuffers[], void *apCodeletArguments) { - int m; - int n; - T *A; - int m0; - int n0; - T det = 0; - T *determinant = &det; - - *determinant = 0; - A = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); - determinant = (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; - } - - static void CORE_stride_vector_starpu(void *apBuffers[], void *apCodeletArguments) { - int m; - int temp; - T *A; - T *B; - T *C; - 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]); - 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]; - j++; - } - } - - static void CORE_tri_stride_vector_starpu(void *apBuffers[], void *apCodeletArguments) { - int m; - int temp; - double *A; - double *B; - double *C; - double *D; - 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]); - - 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]; - 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; - - pError = (double *) STARPU_MATRIX_GET_PTR(apBuffers[0]); - pZPredict = (double *) STARPU_MATRIX_GET_PTR(apBuffers[1]); - pZMiss = (double *) STARPU_MATRIX_GET_PTR(apBuffers[2]); - - starpu_codelet_unpack_args(apCodeletArguments, &m, &m0); - for (i = 0; i < m; i++) { - local_error += pow((pZPredict[i] - pZMiss[i]), 2); - } - *pError += local_error; - } - - static void CORE_dmloe_mmom_starpu(void *apBuffers[], void *apCodeletArguments) { - int m; - int n; - int i; - double *expr2; - double *expr3; - double *expr4; - double *mloe; - double *mmom; - 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]); - starpu_codelet_unpack_args(apCodeletArguments, &m, &n, &m0, &n0); - double expr2_ = 0, expr3_ = 0, expr4_ = 0; - for (i = 0; i < m * n; i += 2) { - expr2_ += expr2[i]; - expr3_ += expr3[i]; - expr4_ += expr4[i]; - } - - if (expr3_ == 0.0) { - *mloe -= 1.0; - } else { - *mloe += (expr2_ / expr3_) - 1.0; - } - - if (expr2_ == 0.0) { - *mmom -= 1.0; - } else { - *mmom += (expr4_ / expr2_) - 1.0; - } - } - - static void CORE_dtrace_starpu(void *buffers[], void *cl_arg) { - 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; - } - - static double core_dtrace (double *A, int m, double* trace) { - int i; - double res = 0.0; - for (i = 0; i < m; i++) - { - res += A[i + i * m]; - trace[i] = A[i + i * m]; - } - 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; - } - - bool recover(char *apPath, int aIterationCount, T *apTheta, T *apLogLik, int aNumParams) { - - FILE *fp; - char *line = nullptr; - size_t len = 0; - int count; - int i; - char *pch; - fp = fopen(apPath, "r"); - if (fp == nullptr) { - LOGGER("cannot open observations file\n") - exit(EXIT_FAILURE); - } - while (getline(&line, &len, fp) != -1) { - pch = strtok(line, " "); - count = (int) strtol(pch, nullptr, 10); - if (count == aIterationCount) { - pch = strtok(nullptr, " "); - for (i = 0; i < aNumParams; i++) { - apTheta[i] = strtol(pch, nullptr, 10); - pch = strtok(nullptr, " "); - } - *apLogLik = strtol(pch, nullptr, 10); - fclose(fp); - free(line); - return true; - } - } - - fclose(fp); - free(line); - return false; - } - - protected: - /// Used Context. - void *mpContext = nullptr; + bool Recover(char *apPath, const int &aIterationCount, T *apTheta, T *apLogLik, const int &aNumParams); }; /** diff --git a/inst/include/linear-algebra-solvers/concrete/ChameleonHeaders.hpp b/inst/include/linear-algebra-solvers/concrete/ChameleonHeaders.hpp index d851e510..ece6a56a 100644 --- a/inst/include/linear-algebra-solvers/concrete/ChameleonHeaders.hpp +++ b/inst/include/linear-algebra-solvers/concrete/ChameleonHeaders.hpp @@ -1,7 +1,7 @@ /** * @file ChameleonHeaders.hpp * @brief This file contains the necessary includes for using the Chameleon library. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @date 2023-08-24 **/ diff --git a/inst/include/linear-algebra-solvers/concrete/HicmaHeaders.hpp b/inst/include/linear-algebra-solvers/concrete/HicmaHeaders.hpp index 159c9c87..2093821b 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.1.0 * @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..8653bfc5 100644 --- a/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp +++ b/inst/include/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.hpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -7,7 +7,7 @@ * @file ChameleonImplementation.hpp * @brief This file contains the declaration of ChameleonImplementation class. * @details ChameleonImplementation is a concrete implementation of the LinearAlgebraMethods class for the common functionality implementation shared between dense and diagonal-super tile matrices. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-03-20 @@ -32,47 +32,32 @@ 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(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() + * */ void ExaGeoStatLapackCopyTile(const common::UpperLower &aUpperLower, void *apA, void *apB) 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 Solves one of the matrix equations op( A )*X = alpha*B, or X*op( A ) = alpha*B. * @copydoc LinearAlgebraMethods::ExaGeoStatTrsmTile() + * */ void ExaGeoStatTrsmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) override; - /** - * @brief Calculate determinant for triangular matrix. - * @copydoc LinearAlgebraMethods::ExaGeoStatMeasureDetTileAsync() - */ - int - ExaGeoStatMeasureDetTileAsync(void *apDescA, void *apSequence, void *apRequest, void *apDescDet) override; - /** * @brief Wait for the completion of a sequence. * @copydoc LinearAlgebraMethods::ExaGeoStatSequenceWait() + * */ void ExaGeoStatSequenceWait(void *apSequence) override; @@ -80,69 +65,10 @@ namespace exageostat::linearAlgebra { /** * @brief Create CHAMELEON Sequence. * @copydoc LinearAlgebraMethods::ExaGeoStatCreateSequence() + * */ void ExaGeoStatCreateSequence(void *apSequence) override; - - /** - * @brief Initialize the runtime option structure for CHAMELEON - * @copydoc LinearAlgebraMethods::ExaGeoStatOptionsInit() - */ - void - ExaGeoStatOptionsInit(void *apOptions, void *apContext, void *apSequence, void *apRequest) override; - - /** - * @brief Submit the release of the workspaces associated to the options structure. - * @copydoc LinearAlgebraMethods::ExaGeoStatOptionsFree() - */ - void - ExaGeoStatOptionsFree(void *apOptions) override; - - /** - * @brief Finalize the runtime option structure for CHAMELEON. - * @copydoc LinearAlgebraMethods::ExaGeoStatOptionsFinalize() - */ - void - ExaGeoStatOptionsFinalize(void *apOptions, void *apContext) override; - - /** - * @brief copy Chameleon descriptor to vector float*. - * @param[in] apDescA Exageostat descriptor A. - * @param[in] apDescB Exageostat descriptor B. - * @param[in] apDescC Exageostat descriptor C. - * @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. - * - */ - int - ExaGeoStaStrideVectorTileAsync(void *apDescA, void *apDescB, void *apDescC, void *apSequence, void *apRequest); - - /** - * @brief Copy Chameleon descriptor to vector float*. - * @param[in] apDescA Exageostat descriptor A. - * @param[in] apDescB Exageostat descriptor B. - * @param[in] apDescC Exageostat descriptor C. - * @param[in] apDescD Exageostat descriptor D. - * @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. - */ - int - ExaGeoStaStrideVectorTileAsync(void *apDescA, void *apDescB, void *apDescC, void *apDescD, void *apSequence, - void *apRequest); - - /** - * @brief Computes dot product of A.A. - * @param[in] apDescA A Descriptor - * @param[out] apDescProduct Stores the result of A.A. - * @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. - */ - int - ExaGeoStatDoubleDotProduct(void *apDescA, void *apDescProduct, void *apSequence, void *apRequest); - }; 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 75% 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..81a3c05e 100644 --- a/inst/include/linear-algebra-solvers/concrete/chameleon/dense/ChameleonImplementationDense.hpp +++ b/inst/include/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.hpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @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,22 +26,25 @@ 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. * @copydoc LinearAlgebraMethods::ExaGeoStatPotrfTile() + * */ void ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, void *apCD, void *apCrk, @@ -54,8 +57,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 86% 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..f8e96954 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 @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @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 65% 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..4c488a3d 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 @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-03-26 @@ -43,15 +43,16 @@ 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(std::unique_ptr> &aData, configurations::Configurations &aConfigurations, const double *theta, T *apMeasurementsMatrix, const kernels::Kernel &aKernel) override; @@ -61,25 +62,6 @@ namespace exageostat::linearAlgebra::tileLowRank { */ void ExaGeoStatLapackCopyTile(const common::UpperLower &aUpperLower, void *apA, void *apB) override; - /** - * @brief Initialize the runtime option structure for HiCMA - * @copydoc LinearAlgebraMethods::ExaGeoStatOptionsInit() - */ - void - ExaGeoStatOptionsInit(void *apOptions, void *apContext, void *apSequence, void *apRequest) override; - - /** - * @brief Submit the release of the workspaces associated to the options structure. - * @copydoc LinearAlgebraMethods::ExaGeoStatOptionsFree() - */ - void ExaGeoStatOptionsFree(void *apOptions) override; - - /** - * @brief Finalize the runtime option structure for HiCMA. - * @copydoc LinearAlgebraMethods::ExaGeoStatOptionsFinalize() - */ - void ExaGeoStatOptionsFinalize(void *apOptions, void *apContext) override; - /** * @brief Wait for the completion of a sequence. * @copydoc LinearAlgebraMethods::ExaGeoStatSequenceWait() @@ -109,23 +91,6 @@ namespace exageostat::linearAlgebra::tileLowRank { const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) override; - /** - * @brief Calculate determinant for triangular matrix. - * @copydoc LinearAlgebraMethods::ExaGeoStatMeasureDetTileAsync() - */ - 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; }; /** diff --git a/inst/include/prediction/Prediction.hpp b/inst/include/prediction/Prediction.hpp index 87b33f16..280a2396 100644 --- a/inst/include/prediction/Prediction.hpp +++ b/inst/include/prediction/Prediction.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file Prediction.hpp * @brief Contains the definition of the Prediction class. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-06-08 @@ -23,35 +23,28 @@ namespace exageostat::prediction { * @Class Prediction * @brief Class to handle different Prediction Module calls. * @tparam T Data Type: float or double. + * */ - template 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. * @param[in, out] aData Reference to an ExaGeoStatData object containing needed descriptors, and locations. * @param[in] aConfigurations Reference to Configurations object containing user input data. * @param[in] apMeasurementsMatrix Pointer to the user input measurements matrix. * @param[in] aKernel Reference to the kernel object to use. - * @return + * @param[in] apTrainLocations (Optional) Pointer to Locations represents training locations. these are used in training phase. + * @param[in] apTestLocations (Optional) Pointer to Locations represents test locations. These are used in prediction phase. + * @return void + * */ - void PredictMissingData(const exageostat::hardware::ExaGeoStatHardware &aHardware, - exageostat::dataunits::ExaGeoStatData &aData, - exageostat::configurations::Configurations &aConfigurations, T *apMeasurementsMatrix, - const kernels::Kernel &aKernel); + static void + PredictMissingData(std::unique_ptr> &aData, configurations::Configurations &aConfigurations, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel, + dataunits::Locations *apTrainLocations = nullptr, + dataunits::Locations *apTestLocations = nullptr); /** * @brief Initializes needed pointers for prediction. @@ -63,13 +56,20 @@ 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. + * @param[in] apTrainLocations (Optional) Pointer to Locations represents training locations. these are used in training phase. + * @param[in] apTestLocations (Optional) Pointer to Locations represents test locations. These are used in prediction phase. * @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(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, dataunits::Locations *apTrainLocations, + dataunits::Locations *apTestLocations); }; diff --git a/inst/include/prediction/PredictionAuxiliaryFunctions.hpp b/inst/include/prediction/PredictionAuxiliaryFunctions.hpp index ad07828f..c8dc3b70 100644 --- a/inst/include/prediction/PredictionAuxiliaryFunctions.hpp +++ b/inst/include/prediction/PredictionAuxiliaryFunctions.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file PredictionAuxiliaryFunctions.hpp * @brief Contains the definition of the PredictionAuxiliaryFunctions.hpp class. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-06-08 @@ -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. @@ -50,6 +40,7 @@ namespace exageostat::prediction { * @param[in] aObsLocation Reference to the observed locations. * @param[out] apMSPE Pointer to be filled with MSPE value. * @return T Array provides insight into the accuracy of the IDW-interpolated predictions for missing values + * */ static void PredictIDW(T *apZMiss, T *apZActual, T *apZObs, const int &aZMissNumber, const int &aZObsNumber, exageostat::dataunits::Locations &aMissLocation, diff --git a/inst/include/prediction/PredictionHelpers.hpp b/inst/include/prediction/PredictionHelpers.hpp index 7955357e..b4be1875 100644 --- a/inst/include/prediction/PredictionHelpers.hpp +++ b/inst/include/prediction/PredictionHelpers.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file PredictionHelpers.hpp * @brief Contains the definition of the PredictionHelpers.hpp class. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-06-08 @@ -29,6 +29,7 @@ namespace exageostat::prediction { template class PredictionHelpers { public: + /** * @brief Pick random Z points for prediction depending on p. * @param[in] aConfigurations Configurations object containing relevant settings. @@ -38,12 +39,14 @@ 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, + static void PickRandomPoints(configurations::Configurations &aConfigurations, + 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. @@ -51,6 +54,7 @@ namespace exageostat::prediction { * @param[in, out] aLocations Locations to be shuffled. * @param[out] aSize Size of data. * @return void + * */ static void Shuffle(T *apArray, exageostat::dataunits::Locations &aLocations, int aSize); @@ -61,6 +65,7 @@ namespace exageostat::prediction { * @param[in, out] aLocations Locations to be shuffled. * @param[out] aSize Size of data. * @return void + * */ static void Shuffle(T *apArray1, T *apArray2, exageostat::dataunits::Locations &aLocations, int aSize); @@ -72,6 +77,7 @@ namespace exageostat::prediction { * @param[in, out] aLocations Locations to be shuffled. * @param[out] aSize Size of data. * @return void + * */ static void Shuffle(T *apArray1, T *apArray2, T *apArray3, exageostat::dataunits::Locations &aLocations, int aSize); @@ -82,6 +88,7 @@ namespace exageostat::prediction { * @param aCount[in] Number of elements in the input array. * @param aDimension[in] Dimension of the input data. * @return void + * */ static void SortArray(uint32_t *aData, int aCount); @@ -92,6 +99,7 @@ namespace exageostat::prediction { * @param[in,out] aLocations Reference to the Locations object containing X and Y coordinates (input/output). * @param[in,out] apZ Pointer to the array containing observation values (input/output). * @return 0 if the sorting is successful. + * */ static int SortInplace(int aN, exageostat::dataunits::Locations &aLocations, T *apZ); diff --git a/inst/include/results/Results.hpp b/inst/include/results/Results.hpp index b112284c..1f21c6b9 100644 --- a/inst/include/results/Results.hpp +++ b/inst/include/results/Results.hpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file Results.hpp * @brief Defines the Results class for storing and accessing result data. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @date 2023-09-14 **/ @@ -26,197 +26,265 @@ namespace exageostat::results { /** * @brief Get a pointer to the singleton instance of the Results class. * @return A pointer to the instance of the Results class. + * */ static Results *GetInstance(); /** * @brief Set the flag indicating whether the results are synthetic or not. * @param[in] aIsSynthetic True if the results are synthetic, false otherwise. + * */ void SetIsSynthetic(bool aIsSynthetic); /** * @brief Set the number of generated locations. * @param[in] aNumLocations The number of generated locations. + * */ void SetGeneratedLocationsNumber(int aNumLocations); /** * @brief Set the flag indicating whether the logger is active or not. * @param[in] aIsLogger True if the logger is active, false otherwise. + * */ void SetIsLogger(bool aIsLogger); /** * @brief Set the path for the logger. * @param[in] aLoggerPath The path for the logger. + * */ void SetLoggerPath(const std::string &aLoggerPath); /** * @brief Set the Total Data Generation execution time. * @param[in] aTime The execution time. + * */ void SetTotalDataGenerationExecutionTime(double aTime); /** * @brief Set the Data Generation floating-point operations (FLOPs). * @param[in] aFlops The number of FLOPs. + * */ void SetTotalDataGenerationFlops(double aFlops); /** * @brief Set the log-likelihood value. * @param[in] aLogLikValue The log-likelihood value. + * */ void SetLogLikValue(double aLogLikValue); /** * @brief Set the number of maximum likelihood estimation (MLE) iterations. * @param[in] aIterationsNumber The number of MLE iterations. + * */ void SetMLEIterations(int aIterationsNumber); /** * @brief Set the vector of maximum theta values. * @param[in] aMaximumTheta The vector of maximum theta values. + * */ void SetMaximumTheta(const std::vector &aMaximumTheta); /** * @brief Set the total modeling execution time. * @param[in] aTime The total execution time for data modeling. + * */ void SetTotalModelingExecutionTime(double aTime); /** * @brief Get the total modeling execution time. * @return The total execution time for data modeling. + * */ [[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 elements. + * @return the Fisher matrix. + * + */ + [[nodiscard]] std::vector GetFisherMatrix() const; + + /** + * @brief Get the Predicted Missed Z matrix elements. + * @return the Z Predicted matrix. + * + */ + [[nodiscard]] std::vector GetPredictedMissedValues() const; + /** * @brief Set the total modeling FLOPs. * @param[in] aTime The total number of FLOPs for data modeling. + * */ void SetTotalModelingFlops(double aTime); /** * @brief Get the total modeling FLOPs. * @return The total number of FLOPs for data modeling. + * */ [[nodiscard]] double GetTotalModelingFlops() const; /** * @brief Get the average modeling execution time. * @return The average execution time for data modeling. + * */ [[nodiscard]] double GetAverageModelingExecutionTime() const; /** * @brief Get the average modeling FLOPs. * @return The average number of FLOPs for data modeling. + * */ [[nodiscard]] double GetAverageModelingFlops() const; /** * @brief Set the value of ZMiss. * @param[in] aZMiss The value of ZMiss. + * */ void SetZMiss(int aZMiss); /** * @brief Set the value of MSPEError. * @param[in] aMSPEError The value of MSPEError. + * */ void SetMSPEError(double aMSPEError); /** * @brief Set the MSPE execution time. * @param[in] aTime The execution time. + * */ void SetMSPEExecutionTime(double aTime); /** * @brief Set the MSPE number of floating-point operations (FLOPs). * @param[in] aFlops The number of FLOPs. + * */ void SetMSPEFlops(double aFlops); /** * @brief Set the vector of IDW errors. * @param[in] aIDWError The vector of IDW errors. + * */ void SetIDWError(const std::vector &aIDWError); /** * @brief Set the value of MLOE. * @param[in] aMLOE The value of MLOE. + * */ void SetMLOE(double aMLOE); /** * @brief Set the value of MMOM. * @param[in] aMMOM The value of MMOM. + * */ void SetMMOM(double aMMOM); /** * @brief Set the MLOE-MMOM execution time. * @param[in] aTime The execution time. + * */ void SetExecutionTimeMLOEMMOM(double aTime); /** * @brief Set the MLOE-MMOM matrix generation time. * @param[in] aTime The execution time. + * */ void SetMatrixGenerationTimeMLOEMMOM(double aTime); /** * @brief Set the MLOE-MMOM cholesky factorization time. * @param[in] aTime The execution time. + * */ void SetFactoTimeMLOEMMOM(double aTime); /** * @brief Set the MLOE-MMOM loop time. * @param[in] aTime The execution time. + * */ void SetLoopTimeMLOEMMOM(double aTime); /** * @brief Set the MLOE-MMOM number of floating-point operations (FLOPs). * @param[in] aFlops The number of FLOPs. + * */ void SetFlopsMLOEMMOM(double aFlops); /** * @brief Set The total execution time of the fisher tile computation. * @param[in] aTime The total execution time for fisher tile computation. + * */ - void SetTotalFisherTime (double aTime); - - /** - * @brief Set the element 00 of the fisher matrix. - * @param aFisher00 Element 00 of the fisher matrix. - */ - void SetFisher00(double aFisher00); + void SetTotalFisherTime(double aTime); /** - * @brief Set the element 11 of the fisher matrix. - * @param aFisher11 element 11 of the fisher matrix. + * @brief Set the elements of the fisher matrix. + * @param aFisherMatrix Elements of the fisher matrix. + * */ - void SetFisher11(double aFisher11); + void SetFisherMatrix(std::vector aFisherMatrix); /** - * @brief Set the element 22 of the fisher matrix. - * @param aFisher22 element 22 of the fisher matrix. + * @brief Set the elements of the Z missed matrix. + * @param aPredictedValues Elements of the Predicted Z missed matrix. + * */ - void SetFisher22(double aFisher22); + void SetPredictedMissedValues(std::vector aPredictedValues); /** * @brief Print the end summary of the results. + * */ void PrintEndSummary(); @@ -273,12 +341,10 @@ namespace exageostat::results { double mTotalModelingFlops = 0; /// Used Total Fisher Time. double mTotalFisherTime = 0; - /// Fisher matrix element 00. - double mFisher00 = 0; - /// Fisher matrix element 11. - double mFisher11 = 0; - /// Fisher matrix element 22. - double mFisher22 = 0; + /// Fisher matrix + std::vector mFisherMatrix; + /// Z miss values + std::vector mPredictedMissedValues; }; }//namespace exageostat diff --git a/inst/include/runtime/RuntimeFunctions.hpp b/inst/include/runtime/RuntimeFunctions.hpp new file mode 100644 index 00000000..83cbdbe8 --- /dev/null +++ b/inst/include/runtime/RuntimeFunctions.hpp @@ -0,0 +1,230 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file RuntimeFunctions.hpp + * @brief A class for runtime static functions. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-03-10 +**/ + +#ifndef EXAGEOSTATCPP_RUNTIMEFUNCTIONS_HPP +#define EXAGEOSTATCPP_RUNTIMEFUNCTIONS_HPP + +#include +#include + +namespace exageostat::runtime { + + /** + * @class RuntimeFunctions + * @brief A class that defines runtime static functions. + * @tparam T Data Type: float or double. + * + */ + template + class RuntimeFunctions { + + public: + + /** + * @brief Computes the covariance matrix. + * @param[in] aDescriptorData pointer to the DescriptorData object holding descriptors and data. + * @param[out] apDescriptor Pointer to the descriptor for the covariance matrix. + * @param[in] aTriangularPart Specifies whether the upper or lower triangular part of the covariance matrix is stored. + * @param[in] apLocation1 Pointer to the first set of locations. + * @param[in] apLocation2 Pointer to the second set of locations. + * @param[in] apLocation3 Pointer to the third set of locations. + * @param[in] apLocalTheta Pointer to the local theta values. + * @param[in] aDistanceMetric Specifies the distance metric to use. + * @param[in] apKernel Pointer to the kernel object to use. + * @return void + * + */ + static void + CovarianceMatrix(dataunits::DescriptorData &aDescriptorData, void *apDescriptor, const int &aTriangularPart, + dataunits::Locations *apLocation1, dataunits::Locations *apLocation2, + dataunits::Locations *apLocation3, T *apLocalTheta, const int &aDistanceMetric, + const kernels::Kernel *apKernel); + + /** + * @brief Perform an asynchronous computation of MLE, MLOE, and MMOM for a tile. + * @details his function performs the computation of Maximum Likelihood Estimation (MLE), + * Maximum Likelihood on the Empirical Orthogonal Functions (MLOE), and + * Method of Moments (MMOM) for a tile asynchronously. + * @param[in] apDescExpr2 Descriptor for expression 2. + * @param[in] apDescExpr3 Descriptor for expression 3. + * @param[in] apDescExpr4 Descriptor for expression 4. + * @param[in] apDescMLOE Descriptor for MLOE. + * @param[in] apDescMMOM Descriptor for MMOM. + * @param[in] apSequence Sequence for the computation. + * @param[in] apRequest Request for the computation. + * @return void + * + */ + static void + ExaGeoStatMLETileAsyncMLOEMMOM(void *apDescExpr2, void *apDescExpr3, void *apDescExpr4, void *apDescMLOE, + void *apDescMMOM, void *apSequence, void *apRequest); + + /** + * @brief Calculate mean square prediction error (MSPE) scalar value of the prediction. + * @param[in] apDescZPredict Observed measurements. + * @param[in] apDescZMiss Missing measurements. + * @param[out] apDescError Mean Square Prediction Error (MSPE). + * @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 void + * + */ + static void + ExaGeoStatMLEMSPETileAsync(void *apDescZPredict, void *apDescZMiss, void *apDescError, void *apSequence, + void *apRequest); + + /** + * @brief Copies the descriptor data to a double vector. + * @param[in] aComputation computation used in configuration. + * @param[in] aDescriptorData pointer to the DescriptorData object holding descriptors and data. + * @param[in] apDescriptor Pointer to the descriptor data. + * @param[in,out] apDoubleVector Pointer to the double vector to copy the descriptor data to. + * @return void + * + */ + static void + CopyDescriptorZ(dataunits::DescriptorData &aDescriptorData, void *apDescriptor, T *apDoubleVector); + + /** + * @brief Converts a Gaussian descriptor to a non-tiled descriptor. + * @param[in] aDescriptorData DescriptorData struct with the Gaussian descriptor. + * @param[in] apDesc Pointer to the non-tiled descriptor. + * @param[in] apTheta Theta vector. + * @return void + * + */ + static void + ExaGeoStatGaussianToNonTileAsync(dataunits::DescriptorData &aDescriptorData, void *apDesc, T *apTheta); + + /** + * @brief copy Chameleon descriptor to vector float*. + * @param[in] apDescA Exageostat descriptor A. + * @param[in] apDescB Exageostat descriptor B. + * @param[in] apDescC Exageostat descriptor C. + * @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 void + * + */ + static void + ExaGeoStaStrideVectorTileAsync(void *apDescA, void *apDescB, void *apDescC, void *apSequence, void *apRequest); + + /** + * @brief Copy Chameleon descriptor to vector float*. + * @param[in] apDescA Exageostat descriptor A. + * @param[in] apDescB Exageostat descriptor B. + * @param[in] apDescC Exageostat descriptor C. + * @param[in] apDescD Exageostat descriptor D. + * @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 void + * + */ + static void + ExaGeoStaStrideVectorTileAsync(void *apDescA, void *apDescB, void *apDescC, void *apDescD, void *apSequence, + void *apRequest); + + /** + * @brief Calculate determinant for triangular matrix. + * @param[in] aComputation computation used in configuration. + * @param[in] apDescA Exageostat descriptor. + * @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). + * @param[in] apDescDet determinant value + * @return void + * + */ + static void + ExaGeoStatMeasureDetTileAsync(const common::Computation &aComputation, void *apDescA, void *apSequence, + void *apRequest, void *apDescDet); + + /** + * @brief Calculate determinant for triangular matrix. + * @param[in] apDescA Pointer to the descriptor of the matrix 'descA'. + * @param[in] apSequence Pointer to a sequence structure for managing asynchronous execution. + * @param[in] apRequest Pointer to a request structure for tracking the operation's status. + * @param[out] apDescNum Pointer to the descriptor of the matrix to store the sum of elements. + * @param[out] apDescTrace Pointer to the descriptor of the matrix to store the trace. + * @return void + * + */ + static void ExaGeoStatMLETraceTileAsync(void *apDescA, void *apSequence, void *apRequest, void *apDescNum, + void *apDescTrace); + + /** + * @brief Computes dot product of A.A. + * @param[in] apDescA A Descriptor + * @param[out] apDescProduct Stores the result of A.A. + * @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 void + * + */ + static void ExaGeoStatDoubleDotProduct(void *apDescA, void *apDescProduct, void *apSequence, void *apRequest); + + /** + * @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] apDescError1 Mean Square Error (MSE) 1. + * @param[out] apDescError2 Mean Square Error (MSE) 2. + * @param[out] apDescError Mean Square Error (MSE). + * @param[in] apSequence Sequence for the computation. + * @param[in] apRequest Request for the computation. + * @return void + * + */ + static void + ExaGeoStatMLEMSPEBivariateTileAsync(void *apDescZPre, void *apDescZMiss, void *apDescError1, void *apDescError2, + void *apDescError, void *apSequence, void *apRequest); + + /** + * @brief Calculate the log likelihood of non-Gaussian MLE. + * @param[in] aComputation computation used in configuration. + * @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 void + * + */ + static void + ExaGeoStatNonGaussianLogLikeTileAsync(const common::Computation &aComputation, void *apDescZ, void *apDescSum, + const T *apTheta, void *apSequence, void *apRequest); + + /** + * @brief Transform the measurements vector inside the non-Gaussian MLE function. + * @param[in] aComputation computation used in configuration. + * @param[in] apDescZ pointer to the Observed Measurements 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 void + * + */ + static void + ExaGeoStatNonGaussianTransformTileAsync(const common::Computation &aComputation, void *apDescZ, + const T *apTheta, void *apSequence, void *apRequest); + }; + + /** + * @brief Instantiates the Runtime Functions class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(RuntimeFunctions) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_RUNTIMEFUNCTIONS_HPP diff --git a/inst/include/runtime/starpu/StarPuCodeletsHeaders.hpp b/inst/include/runtime/starpu/StarPuCodeletsHeaders.hpp new file mode 100644 index 00000000..caacc019 --- /dev/null +++ b/inst/include/runtime/starpu/StarPuCodeletsHeaders.hpp @@ -0,0 +1,26 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file StarPuCodelets.hpp + * @brief Header file to include all codelet classes. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-25 +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/inst/include/runtime/starpu/concrete/dcmg-codelet.hpp b/inst/include/runtime/starpu/concrete/dcmg-codelet.hpp new file mode 100644 index 00000000..6c45b139 --- /dev/null +++ b/inst/include/runtime/starpu/concrete/dcmg-codelet.hpp @@ -0,0 +1,87 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dcmg-codelet.hpp + * @brief A class for starpu codelet dcmg. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-19 +**/ + +#ifndef EXAGEOSTATCPP_DCMG_CODELET_HPP +#define EXAGEOSTATCPP_DCMG_CODELET_HPP + +#include + +namespace exageostat::runtime { + + /** + * @class DCMG Codelet + * @brief A class for starpu codelet dcmg. + * @tparam T Data Type: float or double + * @details This class encapsulates the struct cl_dcmg and its CPU functions. + * + */ + template + class DCMGCodelet { + + public: + + /** + * @brief Default constructor + * + */ + DCMGCodelet() = default; + + /** + * @brief Default destructor + * + */ + ~DCMGCodelet() = default; + + /** + * @brief Inserts a task for DCMG codelet processing. + * @param[in,out] apDescriptor A pointer to the descriptor containing task information. + * @param[in] aTriangularPart An integer specifying the triangular part of the matrix (upper or lower). + * @param[in] apLocation1 A pointer to the first location object for the matrix elements. + * @param[in] apLocation2 A pointer to the second location object for the matrix elements. + * @param[in] apLocation3 A pointer to the third location object for the matrix elements. + * @param[in] apLocalTheta A pointer to the local theta value. + * @param[in] aDistanceMetric An integer specifying the distance metric to be used. + * @param[in] apKernel A pointer to the kernel function to be applied during the task execution. + * @return void + * + */ + void InsertTask(void *apDescriptor, const int &aTriangularPart, dataunits::Locations *apLocation1, + dataunits::Locations *apLocation2, dataunits::Locations *apLocation3, T *apLocalTheta, + const int &aDistanceMetric, const kernels::Kernel *apKernel); + + private: + + /** + * @brief CPU Function used by starpu_codelet struct + * @param[in] apBuffers An array of pointers to the buffers containing the matrix data. + * @param[in] apCodeletArguments A pointer to the codelet arguments structure + * @return void + * + */ + static void cl_dcmg_function(void **apBuffers, void *apCodeletArguments); + + /// starpu_codelet struct + static struct starpu_codelet cl_dcmg; + }; + + /** + * @brief Instantiates the dcmg codelet class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(DCMGCodelet) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_DCMG_CODELET_HPP \ No newline at end of file diff --git a/inst/include/runtime/starpu/concrete/ddotp-codelet.hpp b/inst/include/runtime/starpu/concrete/ddotp-codelet.hpp new file mode 100644 index 00000000..45061fd8 --- /dev/null +++ b/inst/include/runtime/starpu/concrete/ddotp-codelet.hpp @@ -0,0 +1,80 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ddotp-codelet.hpp + * @brief A class for starpu codelet ddotp. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#ifndef EXAGEOSTATCPP_DDOTP_CODELET_HPP +#define EXAGEOSTATCPP_DDOTP_CODELET_HPP + +#include + +namespace exageostat::runtime { + + /** + * @class DDOTP Codelet + * @brief A class for starpu codelet ddotp. + * @tparam T Data Type: float or double + * @details This class encapsulates the struct cl_ddotp and its CPU functions. + * + */ + template + class DDOTPCodelet { + + public: + + /** + * @brief Default constructor + * + */ + DDOTPCodelet() = default; + + /** + * @brief Default destructor + * + */ + ~DDOTPCodelet() = default; + + /** + * @brief Inserts a task for DDOTP codelet processing. + * @param[in] apDescA A pointer to the descriptor for the vector. + * @param[in,out] apDescProduct A pointer to the descriptor for the dot product. + * @return void + * + */ + void InsertTask(void *apDescA, void *apDescProduct); + + private: + + /** + * @brief Executes the DDOTP codelet function for dot product calculation. + * @param[in] apBuffers An array of pointers to the buffers. + * @param[in] apCodeletArguments A pointer to the codelet arguments structure, which includes the vector size (m) and the offset (m0). + * @return void + * + */ + static void cl_ddotp_function(void **apBuffers, void *apCodeletArguments); + + /// starpu_codelet struct + static struct starpu_codelet cl_ddotp; + + }; + + /** + * @brief Instantiates the ddotp codelet class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(DDOTPCodelet) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_DDOTP_CODELET_HPP diff --git a/inst/include/runtime/starpu/concrete/dmdet-codelet.hpp b/inst/include/runtime/starpu/concrete/dmdet-codelet.hpp new file mode 100644 index 00000000..8fa47e0d --- /dev/null +++ b/inst/include/runtime/starpu/concrete/dmdet-codelet.hpp @@ -0,0 +1,92 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dmdet-codelet.hpp + * @brief A class for starpu codelet dmdet. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-21 +**/ + +#ifndef EXAGEOSTATCPP_DMDET_CODELET_HPP +#define EXAGEOSTATCPP_DMDET_CODELET_HPP + +#include + +namespace exageostat::runtime { + + /** + * @class DMDET Codelet + * @brief A class for starpu codelet dmdet. + * @tparam T Data Type: float or double + * @details This class encapsulates the struct cl_dmdet and its CPU functions. + * + */ + template + class DMDETCodelet { + + public: + + /** + * @brief Default constructor + * + */ + DMDETCodelet() = default; + + /** + * @brief Default destructor + * + */ + ~DMDETCodelet() = default; + + /** + * @brief Inserts a task for DMDET codelet processing. + * @param[in] aComputation The type of computation to be performed, such as diagonal approximation or exact dense computation. + * @param[in] apDescA A pointer to the descriptor for matrix A. + * @param[in,out] apDescDet A pointer to the descriptor for the determinant. + * @param[in] aStarPuHelpers A reference to a unique pointer of StarPuHelpers, used for accessing and managing data. + * @return void + * + */ + void InsertTask(const common::Computation &aComputation, void *apDescA, void *apDescDet, + std::unique_ptr &aStarPuHelpers); + + private: + + /** + * @brief Executes the DMDET codelet function for matrix determinant calculation. + * @param[in] apBuffers An array of pointers to the buffers containing the matrix data and the determinant. + * @param[in] apCodeletArguments A pointer to the codelet arguments structure, which includes the matrix size. + * @return void + * + */ + static void cl_dmdet_function(void **apBuffers, void *apCodeletArguments); + + /** + * @brief Calculates the determinant of a matrix. + * @param[in] apDescriptor A pointer to the matrix data. + * @param[in] aSize The size of the matrix (assumed to be square). + * @return T The calculated determinant of the matrix. + * + */ + static T core_dmdet(const T *apDescriptor, const int &aSize); + + /// starpu_codelet struct + static struct starpu_codelet cl_dmdet; + + }; + + /** + * @brief Instantiates the dmdet codelet class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(DMDETCodelet) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_DMDET_CODELET_HPP diff --git a/inst/include/runtime/starpu/concrete/dmloe-mmom-codelet.hpp b/inst/include/runtime/starpu/concrete/dmloe-mmom-codelet.hpp new file mode 100644 index 00000000..b995843c --- /dev/null +++ b/inst/include/runtime/starpu/concrete/dmloe-mmom-codelet.hpp @@ -0,0 +1,83 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dmloe-mmom-codelet.hpp + * @brief A class for starpu codelet dmloe-mmom. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-19 +**/ + +#ifndef EXAGEOSTATCPP_DMLOE_MMOM_HPP +#define EXAGEOSTATCPP_DMLOE_MMOM_HPP + +#include + +namespace exageostat::runtime { + + /** + * @class Dmloe-Mmom Codelet + * @brief A class for starpu codelet dmloe-mmom. + * @tparam T Data Type: float or double + * @details This class encapsulates the struct cl_dmloe_mmom and its CPU functions. + * + */ + template + class DmloeMmomCodelet { + + public: + + /** + * @brief Default constructor + * + */ + DmloeMmomCodelet() = default; + + /** + * @brief Default destructor + * + */ + ~DmloeMmomCodelet() = default; + + /** + * @brief Inserts a task for DmloeMmom codelet processing. + * @param[in] apDescExpr1 A pointer to the descriptor for the first expression. + * @param[in] apDescExpr2 A pointer to the descriptor for the second expression. + * @param[in] apDescExpr3 A pointer to the descriptor for the third expression. + * @param[in,out] apDescMLOE A pointer to the descriptor for the MLOE result. + * @param[in,out] apDescMMOM A pointer to the descriptor for the MMOM result. + * @return void + * + */ + void InsertTask(void *apDescExpr1, void *apDescExpr2, void *apDescExpr3, void *apDescMLOE, + void *apDescMMOM); + + private: + + /** + * @brief Executes the DmloeMmom codelet function for MLOE and MMOM calculations. + * @param[in] apBuffers An array of pointers to the buffers. + * @param[in] apCodeletArguments A pointer to the codelet arguments structure, which includes the matrix dimensions and offsets. + * @return void + * + */ + static void cl_dmloe_mmom_function(void **apBuffers, void *apCodeletArguments); + + /// starpu_codelet struct + static struct starpu_codelet cl_dmloe_mmom; + }; + + /** + * @brief Instantiates the dmloe-mmom codelet class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(DmloeMmomCodelet) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_DMLOE_MMOM_HPP diff --git a/inst/include/runtime/starpu/concrete/dmse-bivariate-codelet.hpp b/inst/include/runtime/starpu/concrete/dmse-bivariate-codelet.hpp new file mode 100644 index 00000000..8a0043eb --- /dev/null +++ b/inst/include/runtime/starpu/concrete/dmse-bivariate-codelet.hpp @@ -0,0 +1,83 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dmse-bivariate-codelet.hpp + * @brief A class for starpu codelet dmse-bivariate. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#ifndef EXAGEOSTATCPP_DMSE_BIVARIATE_CODELET_HPP +#define EXAGEOSTATCPP_DMSE_BIVARIATE_CODELET_HPP + +#include + +namespace exageostat::runtime { + + /** + * @class DMSE Bivariate Codelet + * @brief A class for starpu codelet dmse-bivariate. + * @tparam T Data Type: float or double + * @details This class encapsulates the struct cl_dmse_bivariate and its CPU functions. + * + */ + template + class DMSEBivariateCodelet { + + public: + + /** + * @brief Default constructor + * + */ + DMSEBivariateCodelet() = default; + + /** + * @brief Default destructor + * + */ + ~DMSEBivariateCodelet() = default; + + /** + * @brief Inserts a task for DMSEBivariate codelet processing. + * @param[in] apDescZMiss A pointer to the descriptor for the observed values. + * @param[in] apDescZPre A pointer to the descriptor for the predicted values. + * @param[in,out] apDescsError A pointer to the descriptor for the total error sum. + * @param[in,out] apDescsError1 A pointer to the descriptor for the error sum for the first variable. + * @param[in,out] apDescsError2 A pointer to the descriptor for the error sum for the second variable. + * @return void + * + */ + void + InsertTask(void *apDescZMiss, void *apDescZPre, void *apDescsError, void *apDescsError1, void *apDescsError2); + + private: + + /** + * @brief Executes the DMSEBivariate codelet function for bivariate error calculation. + * @param[in] apBuffers An array of pointers to the buffers. + * @param[in] apCodeletArguments A pointer to the codelet arguments structure, which includes the vector size and offset. + * @return void + * + */ + static void cl_dmse_bivariate_function(void **apBuffers, void *apCodeletArguments); + + /// starpu_codelet struct + static struct starpu_codelet cl_dmse_bivariate; + }; + + /** + * @brief Instantiates the dmse-bivariate codelet class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(DMSEBivariateCodelet) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_DMSE_BIVARIATE_CODELET_HPP diff --git a/inst/include/runtime/starpu/concrete/dmse-codelet.hpp b/inst/include/runtime/starpu/concrete/dmse-codelet.hpp new file mode 100644 index 00000000..4e30408c --- /dev/null +++ b/inst/include/runtime/starpu/concrete/dmse-codelet.hpp @@ -0,0 +1,80 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dmse-codelet.hpp + * @brief A class for starpu codelet dmse. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-21 +**/ + +#ifndef EXAGEOSTATCPP_DMSE_CODELET_HPP +#define EXAGEOSTATCPP_DMSE_CODELET_HPP + +#include + +namespace exageostat::runtime { + + /** + * @class DMSE Codelet + * @brief A class for starpu codelet dmse. + * @tparam T Data Type: float or double + * @details This class encapsulates the struct cl_dmse and its CPU functions. + * + */ + template + class DMSECodelet { + + public: + + /** + * @brief Constructor for DMSE codelet + * + */ + DMSECodelet() = default; + + /** + * @brief Default destructor + * + */ + ~DMSECodelet() = default; + + /** + * @brief Inserts a task for DMSE codelet processing. + * @param[in,out] apDescError A pointer to the descriptor for the error sum. + * @param[in] apDescZPredict A pointer to the descriptor for the predicted values. + * @param[in] apDescZMiss A pointer to the descriptor for the observed values. + * @return void + * + */ + void InsertTask(void *apDescError, void *apDescZPredict, void *apDescZMiss); + + private: + + /** + * @brief Executes the DMSE codelet function for error calculation. + * @param[in] apBuffers An array of pointers to the buffers. + * @param[in] apCodeletArguments A pointer to the codelet arguments structure, which includes the vector size and offset. + * @retur void + * + */ + static void cl_dmse_function(void **apBuffers, void *apCodeletArguments); + + /// starpu_codelet struct + static struct starpu_codelet cl_dmse; + }; + + /** + * @brief Instantiates the dmse codelet class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(DMSECodelet) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_DMSE_CODELET_HPP diff --git a/inst/include/runtime/starpu/concrete/dtrace-codelet.hpp b/inst/include/runtime/starpu/concrete/dtrace-codelet.hpp new file mode 100644 index 00000000..d10ce526 --- /dev/null +++ b/inst/include/runtime/starpu/concrete/dtrace-codelet.hpp @@ -0,0 +1,91 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dtrace-codelet.hpp + * @brief A class for starpu codelet dtrace. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#ifndef EXAGEOSTATCPP_DTRACE_CODELET_HPP +#define EXAGEOSTATCPP_DTRACE_CODELET_HPP + +#include + +namespace exageostat::runtime { + + /** + * @class DTRACE Codelet + * @brief A class for starpu codelet dtrace. + * @tparam T Data Type: float or double + * @details This class encapsulates the struct cl_dtrace and its CPU functions. + * + */ + template + class DTRACECodelet { + + public: + + /** + * @brief Default constructor + * + */ + DTRACECodelet() = default; + + /** + * @brief Default destructor + * + */ + ~DTRACECodelet() = default; + + /** + * @brief Inserts a task for DTRACE codelet processing. + * @param[in] apDescA A pointer to the descriptor for the matrix. + * @param[in,out] apDescNum A pointer to the descriptor for the sum. + * @param[in,out] apDescTrace A pointer to the descriptor for the trace. + * @return void + * + */ + void InsertTask(void *apDescA, void *apDescNum, void *apDescTrace); + + private: + + /** + * @brief Executes the DTRACE codelet function for matrix trace calculation. + * @param[in] apBuffers An array of pointers to the buffers. + * @param[in] apCodeletArguments A pointer to the codelet arguments structure, which includes the matrix size. + * @return void + * + */ + static void cl_dtrace_function(void **apBuffers, void *apCodeletArguments); + + /** + * @brief Calculates the trace of a matrix. + * @param[in] pDescriptor A pointer to the matrix data. + * @param[in] aSize The size of the matrix (assumed to be square). + * @param[in,out] pTrace A pointer to the buffer where the trace value will be stored. + * @return The calculated trace of the matrix. + * + */ + static double core_dtrace(const T *pDescriptor, const int &aSize, T *pTrace); + + /// starpu_codelet struct + static struct starpu_codelet cl_dtrace; + + }; + + /** + * @brief Instantiates the dtrace codelet class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(DTRACECodelet) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_DTRACE_CODELET_HPP diff --git a/inst/include/runtime/starpu/concrete/dzcpy-codelet.hpp b/inst/include/runtime/starpu/concrete/dzcpy-codelet.hpp new file mode 100644 index 00000000..c8980eee --- /dev/null +++ b/inst/include/runtime/starpu/concrete/dzcpy-codelet.hpp @@ -0,0 +1,82 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dzcpy-codelet.hpp + * @brief A class for starpu codelet dzcpy. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#ifndef EXAGEOSTATCPP_DZCPY_CODELET_HPP +#define EXAGEOSTATCPP_DZCPY_CODELET_HPP + +#include + +namespace exageostat::runtime { + + /** + * @class DZCPY Codelet + * @brief A class for starpu codelet dzcpy. + * @tparam T Data Type: float or double + * @details This class encapsulates the struct cl_dzcpy and its CPU functions. + * + */ + template + class DZCPYCodelet { + + public: + + /** + * @brief Default constructor + * + */ + DZCPYCodelet() = default; + + /** + * @brief Default destructor + * + */ + ~DZCPYCodelet() = default; + + /** + * @brief Inserts a task for DZCPY codelet processing. + * @param[in,out] apDescriptor A pointer to the descriptor for the vector. + * @param[in] apDoubleVector A pointer to the double vector to be copied. + * @return void + * + */ + void InsertTask(void *apDescriptor, void *apDoubleVector); + + private: + + /** + * @brief Executes the DZCPY codelet function for copying a double vector. + * @param[in] apBuffers An array of pointers to the buffers. + * @param[in] apCodeletArguments A pointer to the codelet arguments structure, which includes the vector size, + * offset, and the pointer to the destination vector. + * @return void + * + */ + static void cl_dzcpy_function(void **apBuffers, void *apCodeletArguments); + + /// starpu_codelet struct + static struct starpu_codelet cl_dzcpy; + }; + + /** + * @brief Instantiates the dzcpy codelet class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(DZCPYCodelet) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_DZCPY_CODELET_HPP + + diff --git a/inst/include/runtime/starpu/concrete/gaussian-to-non-codelet.hpp b/inst/include/runtime/starpu/concrete/gaussian-to-non-codelet.hpp new file mode 100644 index 00000000..932e1dd2 --- /dev/null +++ b/inst/include/runtime/starpu/concrete/gaussian-to-non-codelet.hpp @@ -0,0 +1,92 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file gaussian-to-non-codelet.hpp + * @brief A class for starpu codelet gaussian-to-non. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#ifndef EXAGEOSTATCPP_GAUSSIAN_TO_NON_CODELET_H +#define EXAGEOSTATCPP_GAUSSIAN_TO_NON_CODELET_H + +#include + +namespace exageostat::runtime { + + /** + * @class Gaussian-To-Non Codelet + * @brief A class for starpu codelet gaussian-to-non. + * @tparam T Data Type: float or double + * @details This class encapsulates the struct cl_gaussian_to_non and its CPU functions. + * + */ + template + class GaussianCodelet { + + public: + + /** + * @brief Default constructor + * + */ + GaussianCodelet() = default; + + /** + * @brief Default destructor + * + */ + ~GaussianCodelet() = default; + + /** + * @brief Inserts a task for Gaussian to non-Gaussian conversion codelet processing. + * @param[in,out] apDesc A pointer to the descriptor for the matrix tile. + * @param[in] apTheta A pointer to the transformation parameters. + * @return void + * + */ + void InsertTask(void *apDesc, T *apTheta); + + private: + + /** + * @brief Executes the Gaussian to non-Gaussian conversion codelet function. + * @param[in] apBuffers An array of pointers to the buffers. + * @param[in] apCodeletArguments A pointer to the codelet arguments structure, which includes the matrix size, + * offset, and the transformation parameters. + * @return void + * + */ + static void cl_gaussian_to_non_function(void **apBuffers, void *apCodeletArguments); + + /** + * @brief Transforms data from a Gaussian distribution to a non-Gaussian distribution. + * @param[in,out] apDescriptorZ A pointer to the array of data to be transformed. This array is modified in place. + * @param[in] apLocalTheta A pointer to the array of transformation parameters. The first element is the mean (`xi`), + * the second element is the scale (`omega`), the third element is the skewness (`g`), and the fourth element is the kurtosis (`h`). + * @param[in] aSize The size of the data array (`pZ`) and the transformation parameters array (`apLocalTheta`). + * @throws std::runtime_error If the kurtosis parameter (`h`) is negative, indicating an invalid transformation parameter. + * @return void + * + */ + static void core_gaussian_to_non(T *apDescriptorZ, const T *apLocalTheta, const int &aSize); + + /// starpu_codelet struct + static struct starpu_codelet cl_gaussian_to_non; + }; + + /** + * @brief Instantiates the gaussian-to-non codelet class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(GaussianCodelet) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_GAUSSIAN_TO_NON_CODELET_H diff --git a/inst/include/runtime/starpu/concrete/non-gaussian-loglike-codelet.hpp b/inst/include/runtime/starpu/concrete/non-gaussian-loglike-codelet.hpp new file mode 100644 index 00000000..cc103f24 --- /dev/null +++ b/inst/include/runtime/starpu/concrete/non-gaussian-loglike-codelet.hpp @@ -0,0 +1,93 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file non-gaussian-loglike-codelet.hpp + * @brief A class for starpu codelet non-gaussian-loglike. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-26 +**/ + +#ifndef EXAGEOSTATCPP_NON_GAUSSIAN_LOGLIKE_CODELET_HPP +#define EXAGEOSTATCPP_NON_GAUSSIAN_LOGLIKE_CODELET_HPP + +#include + +namespace exageostat::runtime { + + /** + * @class NonGaussianLoglike + * @brief A class for starpu codelet non gaussian loglike. + * @tparam T Data Type: float or double + * @details This class encapsulates the struct cl_non_gaussian_loglike and its CPU functions. + * + */ + template + class NonGaussianLoglike { + + public: + + /** + * @brief Constructor for NonGaussianLoglike + * + */ + NonGaussianLoglike() = default; + + /** + * @brief Default destructor + * + */ + ~NonGaussianLoglike() = default; + + /** + * @brief Inserts a task for Non-Gaussian log-likelihood codelet processing. + * @param[in] apDescZ A pointer to the descriptor for the dataset. + * @param[in,out] apDescSum A pointer to the descriptor for the sum. + * @param[in] apTheta A pointer to the transformation parameters. + * @param[in] aStarPuHelpers A reference to a unique pointer of StarPuHelpers, used for accessing and managing data. + * @return void + * + */ + void + InsertTask(void *apDescZ, void *apDescSum, const T *apTheta, std::unique_ptr &aStarPuHelper); + + private: + + /** + * @brief Executes the Non-Gaussian log-likelihood codelet function. + * @param[in] apBuffers An array of pointers to the buffers. + * @param[in] apCodeletArguments A pointer to the codelet arguments structure, which includes the dataset size, + * offset, and the transformation parameters. + * @return void + * + */ + static void cl_non_gaussian_loglike_function(void **apBuffers, void *apCodeletArguments); + + /** + * @brief Helper function for calculating the log-likelihood under a non-Gaussian distribution. + * @param[in] apDescriptorZ A pointer to the dataset. + * @param[in] apLocalTheta A pointer to the transformation parameters. + * @param[in] aSize The size of the dataset. + * @return T The calculated log-likelihood of the dataset under a non-Gaussian distribution. + * + */ + static double core_non_gaussian_loglike_helper(const T *apDescriptorZ, const T *apLocalTheta, const int &aSize); + + /// starpu_codelet struct + static struct starpu_codelet cl_non_gaussian_loglike; + }; + + /** + * @brief Instantiates the non-gaussian-loglike class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(NonGaussianLoglike) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_NON_GAUSSIAN_LOGLIKE_CODELET_HPP diff --git a/inst/include/runtime/starpu/concrete/non-gaussian-transform-codelet.hpp b/inst/include/runtime/starpu/concrete/non-gaussian-transform-codelet.hpp new file mode 100644 index 00000000..c79fd79a --- /dev/null +++ b/inst/include/runtime/starpu/concrete/non-gaussian-transform-codelet.hpp @@ -0,0 +1,132 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file non-gaussian-transform-codelet.hpp + * @brief A class for starpu codelet non-gaussian-transform. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-26 +**/ + +#ifndef EXAGEOSTATCPP_NON_GAUSSIAN_TRANSFORM_CODELET_HPP +#define EXAGEOSTATCPP_NON_GAUSSIAN_TRANSFORM_CODELET_HPP + +#include + +namespace exageostat::runtime { + + /** + * @class NonGaussianTransform Codelet + * @brief A class for starpu codelet non gaussian transform. + * @tparam T Data Type: float or double + * @details This class encapsulates the struct cl_non_gaussian_transform and its CPU functions. + * + */ + template + class NonGaussianTransform { + + public: + + /** + * @brief Default constructor + * + */ + NonGaussianTransform() = default; + + /** + * @brief Default destructor + * + */ + ~NonGaussianTransform() = default; + + /** + * @brief Inserts a task for Non-Gaussian transformation codelet processing. + * @param[in,out] apDescZ A pointer to the descriptor for the dataset. + * @param[in] apTheta A pointer to the transformation parameters. + * @param[in] apStarPuHelpers A reference to a unique pointer of StarPuHelpers, used for accessing and managing data. + * @return void + * + */ + void InsertTask(void *apDescZ, const T *apTheta, std::unique_ptr &apStarPuHelpers); + + private: + + /** + * @brief Executes the Non-Gaussian transformation codelet function. + * @param[in] apBuffers An array of pointers to the buffers. + * @param[in] apCodeletArguments A pointer to the codelet arguments structure, which includes the dataset size, + * offset, and the transformation parameters. + * @return void + * + */ + static void cl_non_gaussian_transform_function(void **apBuffers, void *apCodeletArguments); + + /** + * @brief Helper function for transforming a dataset to a non-Gaussian representation. It applies + * the Non-Gaussian transformation to each element of a dataset using the + * Newton-Raphson method for finding the root of a function. + * @param[in,out] apDescripZ A pointer to the dataset to be transformed. + * @param[in] apLocalTheta A pointer to the transformation parameters. + * @param[in] aSize The size of the dataset. + * @return void + * + */ + static void core_non_gaussian_transform_helper(T *apDescripZ, const T *apLocalTheta, const int &aSize); + + /** + * @brief Implements the Newton-Raphson method for finding the root of a function. + * @param[in] apDescriptorZ The initial guess for the root. + * @param[in] aTransLocation The location parameter of the transformation. + * @param[in] aTransScale The scale parameter of the transformation. + * @param[in] aTransShape The shape parameter of the transformation. + * @param[in] aTransKurtosis The kurtosis parameter of the transformation. + * @param[in] aEpsilon The error threshold for the root-finding process. + * @return T The calculated root of the function. + * + */ + static double + newton_raphson(T apDescriptorZ, T aTransLocation, T aTransScale, T aTransShape, T aTransKurtosis, T aEpsilon); + + /** + * @brief Calculates the Non-Gaussian transformation of a value. + * @param[in] aOriginalValue The original value to be transformed. + * @param[in] aCurrentValue The current value of the transformation variable. + * @param[in] aTransLocation The location parameter of the transformation. + * @param[in] aTransScale The scale parameter of the transformation. + * @param[in] aTransShape The shape parameter of the transformation. + * @param[in] aTransKurtosis The kurtosis parameter of the transformation. + * @return T The transformed value. + * + */ + static double tukeyGHTransfor(T aOriginalValue, T aCurrentValue, T aTransLocation, T aTransScale, T aTransShape, + T aTransKurtosis); + + /** + * @brief Calculates the derivative of the Non-Gaussian transformation. + * @param[in] aCurrentValue The current value of the transformation variable. + * @param[in] aTransScale The scale parameter of the transformation. + * @param[in] aTransShape The shape parameter of the transformation. + * @param[in] aTransKurtosis The kurtosis parameter of the transformation. + * @return T The derivative of the transformation at the given value. + * + */ + static double tukeyGHDiferencial(T aCurrentValue, T aTransScale, T aTransShape, T aTransKurtosis); + + /// starpu_codelet struct + static struct starpu_codelet cl_non_gaussian_transform; + }; + + /** + * @brief Instantiates the non-gaussian-transform codelet class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(NonGaussianTransform) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_NON_GAUSSIAN_TRANSFORM_CODELET_HPP diff --git a/inst/include/runtime/starpu/concrete/stride-vec-codelet.hpp b/inst/include/runtime/starpu/concrete/stride-vec-codelet.hpp new file mode 100644 index 00000000..687c4a17 --- /dev/null +++ b/inst/include/runtime/starpu/concrete/stride-vec-codelet.hpp @@ -0,0 +1,81 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file stride-vec-codelet.hpp + * @brief A class for starpu codelet stride-vec. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#ifndef EXAGEOSTATCPP_STRIDE_VEC_CODELET_HPP +#define EXAGEOSTATCPP_STRIDE_VEC_CODELET_HPP + +#include + +namespace exageostat::runtime { + + /** + * @class stride-vec Codelet + * @brief A class for starpu codelet stride-vec. + * @tparam T Data Type: float or double + * @details This class encapsulates the struct cl_stride_vec and its CPU functions. + * + */ + template + class STRIDEVECCodelet { + + public: + + /** + * @brief Default constructor + * + */ + STRIDEVECCodelet() = default; + + /** + * @brief Default destructor + * + */ + ~STRIDEVECCodelet() = default; + + /** + * @brief Inserts a task for STRIDE vector operation codelet processing. + * @param[in] apDescA A pointer to the descriptor for the source vector. + * @param[in,out] apDescB A pointer to the descriptor for the first destination vector. + * @param[in,out] apDescC A pointer to the descriptor for the second destination vector. + * @return void + * + */ + void InsertTask(const void *apDescA, void *apDescB, void *apDescC); + + private: + + /** + * @brief Executes the STRIDE vector operation codelet function. + * @param[in] apBuffers An array of pointers to the buffers. + * @param[in] apCodeletArguments A pointer to the codelet arguments structure, which includes the vector size, + * offset, and the stride factor. + * @return void + * + */ + static void cl_stride_vec_function(void **apBuffers, void *apCodeletArguments); + + /// starpu_codelet struct + static struct starpu_codelet cl_stride_vec; + }; + + /** + * @brief Instantiates the stride-vec codelet class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(STRIDEVECCodelet) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_STRIDE_VEC_CODELET_HPP diff --git a/inst/include/runtime/starpu/concrete/tri-stride-vec-codelet.hpp b/inst/include/runtime/starpu/concrete/tri-stride-vec-codelet.hpp new file mode 100644 index 00000000..ae26f348 --- /dev/null +++ b/inst/include/runtime/starpu/concrete/tri-stride-vec-codelet.hpp @@ -0,0 +1,82 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file tri-stride-vec-codelet.hpp + * @brief A class for starpu codelet tri-stride-vec. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#ifndef EXAGEOSTATCPP_TRI_STRIDE_VEC_CODELET_HPP +#define EXAGEOSTATCPP_TRI_STRIDE_VEC_CODELET_HPP + +#include + +namespace exageostat::runtime { + + /** + * @class TriStrideVecCodelet Codelet + * @brief A class for starpu codelet tri_stride_vec. + * @tparam T Data Type: float or double + * @details This class encapsulates the struct cl_tri_stride_vec and its CPU functions. + * + */ + template + class TriStrideVecCodelet { + + public: + + /** + * @brief Default constructor + * + */ + TriStrideVecCodelet() = default; + + /** + * @brief Default destructor + * + */ + ~TriStrideVecCodelet() = default; + + /** + * @brief Inserts a task for TriStride vector operation codelet processing. + * @param[in] apDescA A pointer to the descriptor for the source vector. + * @param[in,out] apDescB A pointer to the descriptor for the first destination vector. + * @param[in,out] apDescC A pointer to the descriptor for the second destination vector. + * @param[in,out] apDescD A pointer to the descriptor for the third destination vector. + * @return void + * + */ + void InsertTask(const void *apDescA, void *apDescB, void *apDescC, void *apDescD); + + private: + + /** + * @brief Executes the TriStride vector operation codelet function. + * @param[in] apBuffers An array of pointers to the buffers. + * @param[in] apCodeletArguments A pointer to the codelet arguments structure, which includes the vector size, + * offset, and the stride factor. + * @return void + * + */ + static void cl_tri_stride_vec_function(void **apBuffers, void *apCodeletArguments); + + /// starpu_codelet struct + static struct starpu_codelet cl_tri_stride_vec; + }; + + /** + * @brief Instantiates the tri-stride-vec codelet class for float and double types. + * @tparam T Data Type: float or double + * + */ + EXAGEOSTAT_INSTANTIATE_CLASS(TriStrideVecCodelet) + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_TRI_STRIDE_VEC_CODELET_HPP diff --git a/inst/include/runtime/starpu/helpers/StarPuHelpers.hpp b/inst/include/runtime/starpu/helpers/StarPuHelpers.hpp new file mode 100644 index 00000000..cfaa98f5 --- /dev/null +++ b/inst/include/runtime/starpu/helpers/StarPuHelpers.hpp @@ -0,0 +1,114 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file StarPuHelpers.hpp + * @brief An interface for StarPu helpers. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-25 +**/ + +#ifndef EXAGEOSTATCPP_STARPUHELPERS_HPP +#define EXAGEOSTATCPP_STARPUHELPERS_HPP + +#include + +#include +#include + +namespace exageostat::runtime { + + /** + * @class StarPuHelpers + * @brief A class that defines the interface for StarPu helpers. + * @tparam T Data Type: float or double. + * + */ + class StarPuHelpers { + public: + + /** + * @brief Initialize the runtime option structure for either HiCMA or CHAMELEON. + * @param[in, out] apOptions The options structure that needs to be initialized. + * @param[in] apSequence The sequence structure to associate in the options. + * @param[in] apRequest The request structure to associate in the options. + * @return void + * + */ + virtual void + ExaGeoStatOptionsInit(void *apOptions, void *apSequence, void *apRequest) = 0; + + /** + * @brief Submit the release of the workspaces associated to the options structure. + * @param[in,out] apOptions The options structure for which to workspaces will be released + * @return void + * + */ + virtual void ExaGeoStatOptionsFree(void *apOptions) = 0; + + /** + * @brief Finalize the runtime option structure for either HiCMA or CHAMELEON. + * @param[in,out] apOptions The options structure that needs to be finalized. + * @return void + * + */ + virtual void ExaGeoStatOptionsFinalize(void *apOptions) = 0; + + /** + * @brief Get the pointer to the data or the runtime handler associated to the piece of data (m, n) in desc. + * @param[in] apDescriptor The descriptor to which belongs the piece of data + * @param[in] aDescRow The row coordinate of the piece of data in the matrix + * @param[in] aDescCol The column coordinate of the piece of data in the matrix + * @return void + * + */ + virtual void *ExaGeoStatDataGetAddr(void *apDescriptor, const int &aDescRow, const int &aDescCol) = 0; + + /** + * @brief Get the number of tile rows of the sub-matrix + * @param[in] apDescriptor + * @return int + * + */ + virtual int GetMT(void *apDescriptor) = 0; + + /** + * @brief Get the descriptor number of rows + * @param[in] apDescriptor + * @return int + * + */ + virtual int GetM(void *apDescriptor) = 0; + + /** + * @brief Get the descriptor number of rows in a tile + * @param[in] apDescriptor + * @return int + * + */ + virtual int GetMB(void *apDescriptor) = 0; + + /** + * @brief Get the descriptor options + * @return void pointer to descriptor_option + * @return void + * + */ + virtual void *GetOptions() = 0; + + /** + * @brief Delete the options object + * @param apOptions + * @return void + * + */ + virtual void DeleteOptions(void *apOptions) = 0; + + }; + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_STARPUHELPERS_HPP diff --git a/inst/include/runtime/starpu/helpers/StarPuHelpersFactory.hpp b/inst/include/runtime/starpu/helpers/StarPuHelpersFactory.hpp new file mode 100644 index 00000000..e8d9656c --- /dev/null +++ b/inst/include/runtime/starpu/helpers/StarPuHelpersFactory.hpp @@ -0,0 +1,42 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file StarPuHelpersFactory.hpp + * @brief Factory for StarPu helpers. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-25 +**/ + +#ifndef EXAGEOSTATCPP_STARPUHELPERSFACTORY_HPP +#define EXAGEOSTATCPP_STARPUHELPERSFACTORY_HPP + +#include + +namespace exageostat::runtime { + + /** + * @class StarPuHelpersFactory + * @brief A class that creates StarPu helpers based on the input computation type. + * + */ + class StarPuHelpersFactory { + + public: + + /** + * @brief Creates a StarPu helper. + * @param[in] aComputation The computation type to create the solver for. + * @return Unique pointer to the created StarPu helper. + * + */ + static std::unique_ptr CreateStarPuHelper(const common::Computation &aComputation); + + }; + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_STARPUHELPERSFACTORY_HPP diff --git a/inst/include/runtime/starpu/helpers/concrete/ChameleonStarPuHelpers.hpp b/inst/include/runtime/starpu/helpers/concrete/ChameleonStarPuHelpers.hpp new file mode 100644 index 00000000..ee597973 --- /dev/null +++ b/inst/include/runtime/starpu/helpers/concrete/ChameleonStarPuHelpers.hpp @@ -0,0 +1,108 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ChameleonStarPuHelpers.hpp + * @brief A class for Chameleon implementation of StarPu helpers interface StarPuHelpers.hpp. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-25 +**/ + +#ifndef EXAGEOSTATCPP_CHAMELEONSTARPUHELPERS_HPP +#define EXAGEOSTATCPP_CHAMELEONSTARPUHELPERS_HPP + +#include + +namespace exageostat::runtime { + + /** + * @brief ChameleonStarPuHelpers is a concrete implementation of StarPuHelpers interface for Chameleon library. + * + */ + class ChameleonStarPuHelpers : public StarPuHelpers { + public: + + /** + * @brief Default constructor. + */ + ChameleonStarPuHelpers() = default; + + /** + * @brief Default destructor. + */ + ~ChameleonStarPuHelpers() = default; + + /** + * @brief Initialize the runtime option structure for CHAMELEON + * @copydoc StarPuHelpers::ExaGeoStatOptionsInit() + * + */ + void + ExaGeoStatOptionsInit(void *apOptions, void *apSequence, void *apRequest) override; + + /** + * @brief Submit the release of the workspaces associated to the options structure. + * @copydoc StarPuHelpers::ExaGeoStatOptionsFree() + * + */ + void + ExaGeoStatOptionsFree(void *apOptions) override; + + /** + * @brief Finalize the runtime option structure for CHAMELEON. + * @copydoc StarPuHelpers::ExaGeoStatOptionsFinalize() + * + */ + void + ExaGeoStatOptionsFinalize(void *apOptions) override; + + /** + * @brief Get the pointer to the data or the runtime handler associated to the piece of data (m, n) in desc. + * @copydoc StarPuHelpers::ExaGeoStatDataGetAddr() + * + */ + void *ExaGeoStatDataGetAddr(void *apDescriptor, const int &aDescRow, const int &aDescCol) override; + + /** + * @brief Get the number of tile rows of the sub-matrix + * @copydoc StarPuHelpers::GetMT() + * + */ + int GetMT(void *apDescriptor) override; + + /** + * @brief Get the descriptor number of rows + * @copydoc StarPuHelpers::GetM() + * + */ + int GetM(void *apDescriptor) override; + + /** + * @brief Get the descriptor number of rows in a tile + * @copydoc StarPuHelpers::GetMB() + * + */ + int GetMB(void *apDescriptor) override; + + /** + * @brief Get the descriptor options + * @copydoc StarPuHelpers::GetOptions() + * + */ + void *GetOptions() override; + + /** + * @brief Delete the options object + * @copydoc StarPuHelpers::DeleteOptions() + * + */ + void DeleteOptions(void *apOptions) override; + + }; + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_CHAMELEONSTARPUHELPERS_HPP diff --git a/inst/include/runtime/starpu/helpers/concrete/HicmaStarPuHelpers.hpp b/inst/include/runtime/starpu/helpers/concrete/HicmaStarPuHelpers.hpp new file mode 100644 index 00000000..c59d2ff3 --- /dev/null +++ b/inst/include/runtime/starpu/helpers/concrete/HicmaStarPuHelpers.hpp @@ -0,0 +1,107 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file HicmaStarPuHelpers.hpp + * @brief A class for Hicma implementation of StarPu helpers interface StarPuHelpers.hpp. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-25 +**/ + +#ifndef EXAGEOSTATCPP_HICMASTARPUHELPERS_HPP +#define EXAGEOSTATCPP_HICMASTARPUHELPERS_HPP + +#include + +namespace exageostat::runtime { + + /** + * @brief HicmaStarPuHelpers is a concrete implementation of StarPuHelpers interface for Hicma library. + * + */ + class HicmaStarPuHelpers : public StarPuHelpers { + public: + + /** + * @brief Default constructor. + * + */ + HicmaStarPuHelpers() = default; + + /** + * @brief Default destructor. + * + */ + ~HicmaStarPuHelpers() = default; + + /** + * @brief Initialize the runtime option structure for HiCMA + * @copydoc StarPuHelpers::ExaGeoStatOptionsInit() + * + */ + void ExaGeoStatOptionsInit(void *apOptions, void *apSequence, void *apRequest) override; + + /** + * @brief Submit the release of the workspaces associated to the options structure. + * @copydoc StarPuHelpers::ExaGeoStatOptionsFree() + * + */ + void ExaGeoStatOptionsFree(void *apOptions) override; + + /** + * @brief Finalize the runtime option structure for HiCMA. + * @copydoc StarPuHelpers::ExaGeoStatOptionsFinalize() + * + */ + void ExaGeoStatOptionsFinalize(void *apOptions) override; + + /** + * @brief Get the pointer to the data or the runtime handler associated to the piece of data (m, n) in desc. + * @copydoc StarPuHelpers::ExaGeoStatDataGetAddr() + * + */ + void *ExaGeoStatDataGetAddr(void *apDescriptor, const int &aDescRow, const int &aDescCol) override; + + /** + * @brief Get the number of tile rows of the sub-matrix + * @copydoc StarPuHelpers::GetMT() + * + **/ + int GetMT(void *apDescriptor) override; + + /** + * @brief Get the descriptor number of rows + * @copydoc StarPuHelpers::GetM() + * + */ + int GetM(void *apDescriptor) override; + + /** + * @brief Get the descriptor number of rows in a tile + * @copydoc StarPuHelpers::GetMB() + * + */ + int GetMB(void *apDescriptor) override; + + /** + * @brief Get the descriptor options + * @copydoc StarPuHelpers::GetOptions) + * + */ + void *GetOptions() override; + + /** + * @brief Delete the options object + * @copydoc StarPuHelpers::DeleteOptions() + * + */ + void DeleteOptions(void *apOptions) override; + + }; + +}//namespace exageostat + +#endif //EXAGEOSTATCPP_HICMASTARPUHELPERS_HPP diff --git a/inst/include/utilities/EnumStringParser.hpp b/inst/include/utilities/EnumStringParser.hpp new file mode 100644 index 00000000..ee7201bb --- /dev/null +++ b/inst/include/utilities/EnumStringParser.hpp @@ -0,0 +1,64 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file EnumStringParser.hpp + * @brief Provides utility functions for parsing enumeration values from strings. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-01-20 +**/ + +#ifndef EXAGEOSTATCPP_ENUMSTRINGPARSER_HPP +#define EXAGEOSTATCPP_ENUMSTRINGPARSER_HPP + +#include + +#include +#include + +/** + * @brief Convert a string representation of computation mode to its corresponding enum value. + * @param[in] aComputation String representation of computation mode. + * @return Computation enum value. + */ +inline exageostat::common::Computation GetInputComputation(std::string aComputation) { + std::transform(aComputation.begin(), aComputation.end(), + aComputation.begin(), ::tolower); + + if (aComputation == "exact" || aComputation == "dense") { + return exageostat::common::EXACT_DENSE; + } else if (aComputation == "dst" || aComputation == "diag_approx") { + return exageostat::common::DIAGONAL_APPROX; + } else if (aComputation == "tlr" || aComputation == "tile_low_rank") { + return exageostat::common::TILE_LOW_RANK; + } else { + const std::string msg = "Error in Initialization : Unknown computation Value" + std::string(aComputation); + throw API_EXCEPTION(msg, INVALID_ARGUMENT_ERROR); + } +} + +/** + * @brief Converts string to dimension enum. + * @param[in] aDimension Dimension as a string. + * @return Dimension as an enum. + */ +inline exageostat::common::Dimension GetInputDimension(std::string aDimension) { + std::transform(aDimension.begin(), aDimension.end(), + aDimension.begin(), ::tolower); + + if (aDimension == "2d") { + return exageostat::common::Dimension2D; + } else if (aDimension == "3d") { + return exageostat::common::Dimension3D; + } else if (aDimension == "st") { + return exageostat::common::DimensionST; + } else { + const std::string msg = "Error in Initialization : Unknown computation Value" + std::string(aDimension); + throw API_EXCEPTION(msg, INVALID_ARGUMENT_ERROR); + } +} + +#endif //EXAGEOSTATCPP_ENUMSTRINGPARSER_HPP diff --git a/inst/include/utilities/ErrorHandler.hpp b/inst/include/utilities/ErrorHandler.hpp new file mode 100644 index 00000000..41b24628 --- /dev/null +++ b/inst/include/utilities/ErrorHandler.hpp @@ -0,0 +1,95 @@ +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ErrorHandler.hpp + * @version 1.1.0 + * @brief Provides error handling functionalities. + * @details Defines macros and functions for handling errors and warnings. + * @author Mahmoud ElKarargy + * @author David Helmy + * @date 2024-01-20 +**/ + +#ifndef EXAGEOSTATCPP_ERRORHANDLER_HPP +#define EXAGEOSTATCPP_ERRORHANDLER_HPP + +#ifdef USE_CUDA +#include +#endif + +/** + * @brief EXAGEOSTAT API Exceptions Macro to use for Errors and Warnings. + */ +#define API_EXCEPTION(MESSAGE, ERROR_TYPE) \ + APIException(MESSAGE, ERROR_TYPE) + +#ifdef USE_CUDA +/** + * @brief Useful macro wrapper for all cuda API calls to ensure correct returns, + * and error throwing on failures. + */ +#define GPU_ERROR_CHECK(ans) { APIException::AssertGPU((ans), __FILE__, __LINE__); } +#endif + +/** + * @brief Enumeration for error types. + */ +enum ErrorType : int { + RUNTIME_ERROR = 0, + RANGE_ERROR = 1, + INVALID_ARGUMENT_ERROR = 2, + WARNING = 3, +}; + +/** + * @class APIException + * @brief Custom exception class for handling API errors and warnings. + */ +class APIException : public std::exception { + +public: + + /** + * @brief Constructor for APIException. + * @param[in] aMessage The error or warning message. + * @param[in] aErrorCode The error type. + */ + APIException(const std::string &aMessage, const ErrorType &aErrorCode) { + + if (aErrorCode == RUNTIME_ERROR) { + throw std::runtime_error(aMessage); + } else if (aErrorCode == INVALID_ARGUMENT_ERROR) { + throw std::invalid_argument(aMessage); + } else if (aErrorCode == RANGE_ERROR) { + throw std::range_error(aMessage); + } + } + + /** + * @brief Destructor for APIException. + */ + ~APIException() override = default; + +#ifdef USE_CUDA + /** + * @brief Function to assert the return code of a CUDA API call and ensure it completed successfully. + * @param[in] aCode The code returned from the CUDA API call. + * @param[in] aFile The name of the file that the assertion was called from. + * @param[in] aLine The line number in the file that the assertion was called from. + */ + inline static void AssertGPU(cudaError_t aCode, const char *aFile, int aLine) + { + if (aCode != cudaSuccess) + { + char s[200]; + sprintf((char*)s,"GPU Assert: %s %s %d\n", cudaGetErrorString(aCode), aFile, aLine); + throw std::invalid_argument(s); + } + } +#endif + +}; + +#endif //EXAGEOSTATCPP_ERRORHANDLER_HPP \ No newline at end of file diff --git a/inst/include/utilities/Logger.hpp b/inst/include/utilities/Logger.hpp new file mode 100644 index 00000000..04fbb1c6 --- /dev/null +++ b/inst/include/utilities/Logger.hpp @@ -0,0 +1,130 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file Logger.hpp + * @brief Provides logging and timing macros for debugging and profiling. + * @details Defines macros for verbose logging, various levels of logging, and timing. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-04 +**/ + +#ifndef EXAGEOSTATCPP_LOGGER_HPP +#define EXAGEOSTATCPP_LOGGER_HPP + +#include +#include +#include + +#include +#include +#include + +/** + * @def DEFAULT_PRECISION + * @brief The value of the default C++ std::std::cout number of precision. + */ +#define DEFAULT_PRECISION 6 + +/** + * @def VERBOSE(msg) + * @brief Verbose macro for logging and debugging mode. + */ +#define VERBOSE(msg) \ + if(exageostat::configurations::Configurations::GetVerbosity() == exageostat::common::Verbose::DETAILED_MODE && \ + !exageostat::helpers::CommunicatorMPI::GetInstance()->GetRank()) { \ + std::ostringstream oss; \ + oss << "\t\t\t " << msg << std::endl; \ + std::cout << oss.str(); \ + } + +/** + * @def LOGGER_1(msg) + * @brief LOGGER_1 macro for logging outputs with double taps and new line at the end. + */ +#define LOGGER_1(msg) \ + if(!(exageostat::configurations::Configurations::GetVerbosity() == exageostat::common::Verbose::QUIET_MODE) && !exageostat::helpers::CommunicatorMPI::GetInstance()->GetRank()){ \ + std::ostringstream oss; \ + oss << "\t\t " << std::fixed << std::setprecision(DEFAULT_PRECISION) << msg << std::endl; \ + std::cout << oss.str(); \ + } + +/** + * @def LOGGER_2(msg, A) + * @brief LOGGER_2 macro for logging outputs with double taps and without new line at the end. + */ +#define LOGGER_2(msg, A) \ + if(!(exageostat::configurations::Configurations::GetVerbosity() == exageostat::common::Verbose::QUIET_MODE) && !exageostat::helpers::CommunicatorMPI::GetInstance()->GetRank()){ \ + std::ostringstream oss; \ + oss << "\t\t " << std::fixed << std::setprecision(DEFAULT_PRECISION) << msg; \ + std::cout << oss.str(); \ +} +/** + * @def LOGGER_CONTROL(x, A, B, FUNC, ...) + * @brief LOGGER_CONTROL is The internal macro that simply strips the excess and ends up with the required macro + */ +#define LOGGER_CONTROL(x, A, B, FUNC, ...) FUNC + +/** + * @def LOGGER(...) + * @brief LOGGER macro that's called, Used to logging outputs. + */ +#define LOGGER(...) LOGGER_CONTROL(,##__VA_ARGS__, \ + LOGGER_2(__VA_ARGS__), \ + LOGGER_1(__VA_ARGS__), \ + ) + +/** + * @def LOGGER_PRECISION_1(msg, precision) + * @brief LOGGER_PRECISION_1 macro for logging outputs without any taps, without new line at the end, and with customized precision. + */ +#define LOGGER_PRECISION_1(msg, precision) \ + if(!(exageostat::configurations::Configurations::GetVerbosity() == exageostat::common::Verbose::QUIET_MODE) && !exageostat::helpers::CommunicatorMPI::GetInstance()->GetRank()){ \ + std::ostringstream oss; \ + oss << std::fixed << std::setprecision(precision) << msg; \ + std::cout << oss.str(); \ + } + +/** + * @def LOGGER_PRECISION_2(msg) + * @brief LOGGER_PRECISION_2 macro for logging outputs without any taps, without new line at the end, and with default C++ precision. + */ +#define LOGGER_PRECISION_2(msg) \ + if(!(exageostat::configurations::Configurations::GetVerbosity() == exageostat::common::Verbose::QUIET_MODE) && !exageostat::helpers::CommunicatorMPI::GetInstance()->GetRank()) {\ + std::ostringstream oss; \ + oss << std::fixed << std::setprecision(DEFAULT_PRECISION) << msg; \ + std::cout << oss.str(); \ + } +/** + * @def LOGGER_PRECISION_CONTROL + * @brief is The internal macro that simply strips the excess and ends up with the required macro + */ +#define LOGGER_PRECISION_CONTROL(x, A, B, FUNC, ...) FUNC + +/** + * @def LOGGER_PRECISION(...) + * @brief LOGGER_PRECISION macro that's called, Used for logging outputs with precision. + */ +#define LOGGER_PRECISION(...) LOGGER_PRECISION_CONTROL(,##__VA_ARGS__, \ + LOGGER_PRECISION_1(__VA_ARGS__), \ + LOGGER_PRECISION_2(__VA_ARGS__), \ + ) + +/** + * @def START_TIMING(t) + * @brief Timing macro to start timing. + */ +#define START_TIMING(t) auto t##_start = std::chrono::high_resolution_clock::now() + +/** + * @def STOP_TIMING(t) + * @brief Timing macro to stop timing. + */ +#define STOP_TIMING(t) auto t##_end = std::chrono::high_resolution_clock::now(); \ + t = std::chrono::duration_cast>(t##_end - t##_start).count() + +#endif //EXAGEOSTATCPP_LOGGER_HPP diff --git a/man/Data.Rd b/man/Data.Rd new file mode 100644 index 00000000..7a42007f --- /dev/null +++ b/man/Data.Rd @@ -0,0 +1,45 @@ + +% Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +% All rights reserved. +% ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +% @file Data.Rd +% @brief roxygen2 documentation for the R Interface of ExaGeoStatData class +% @version 1.1.0 +% @author Mahmoud ElKarargy +% @date 2024-03-17 + +\name{ExaGeoStatData} +\alias{ExaGeoStatData} +\title{ExaGeoStatData Class} + +\description{ +The \code{ExaGeoStatData} class is designed to facilitate the handling and manipulation of geospatial statistics data within the ExaGeoStat framework. +It provides a structured way to store and manage data points based on their dimensions. +Instances of this class can hold a specified number of location points, and support different data dimensions including two-dimensional (2D), three-dimensional (3D), and spatiotemporal (ST) configurations. +} + +\section{Constructor}{ + \code{\link{ExaGeoStatData}} Creates a new instance of the + \code{ExaGeoStatData} class by calling: + \preformatted{ + new(ExaGeoStatData, problem_size, dimension) + } + \describe{ + \item{\code{size}}{An integer represents the size of the locations data.} + \item{\code{dimension}}{A string represents the dimensions of the data. + Available dimensions are "2D", "3D", and "ST".} + } +} + +\value{ +An object of class \code{ExaGeoStatData} represents a data component with the specified size and dimension. +} + +\examples{ +problem_size <- 4 +dimension = "3D" +empty_data <- new(Data, problem_size, dimension) +} + +\keyword{S4 class} diff --git a/man/Hardware.Rd b/man/Hardware.Rd new file mode 100644 index 00000000..4b85582f --- /dev/null +++ b/man/Hardware.Rd @@ -0,0 +1,56 @@ + +% Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +% All rights reserved. +% ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +% @file Hardware.Rd +% @brief roxygen2 documentation for the R Interface of ExaGeoStatHardware class. +% @version 1.1.0 +% @author Mahmoud ElKarargy +% @date 2024-03-17 + +\name{ExaGeoStatHardware} +\alias{ExaGeoStatHardware} +\title{ExaGeoStatHardware Class} + +\description{ +The ExaGeoStatHardware class represents a hardware component in the ExaGeoStat system. +It is initialized with computation mode, and two integers represents number of CPU cores and number of GPU cores. +} + +\section{Constructor}{ + \code{\link{ExaGeoStatHardware}} Creates a new instance of the + \code{ExaGeoStatHardware} class by calling: + \preformatted{ + new(Hardware, computation, ncores, ngpus, p, q) + } + \describe{ + \item{\code{computation}}{A string specifies the computation method, either "exact" or "dst" or "tlr".} + \item{\code{ncores}}{An integer represents number of CPU cores.} + \item{\code{ngpus}}{An integer represents number of GPU cores.} + \item{\code{p}}{An integer represents P grid dimension.} + \item{\code{q}}{An integer represents Q grid dimension.} +} +} + +\section{Methods}{ +\subsection{finalize_hardware}{ +\code{finalize_hardware()} manually finalizes the hardware by resetting the context. +} +} + +\value{ +An object of class \code{ExaGeoStatHardware} represents a hardware component with the specified component and number of CPU cores and GPU cores. +} + +\examples{ +ncores <- 2 +ngpus <- 0 +p <- 2 +q <- 2 +computation <- "exact" +hardware <- new(Hardware, computation, ncores, ngpus, p, q) +hardware$finalize_hardware() +} + +\keyword{S4 class} diff --git a/man/fisher.Rd b/man/fisher.Rd new file mode 100644 index 00000000..a0fc0b7a --- /dev/null +++ b/man/fisher.Rd @@ -0,0 +1,83 @@ + +% Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +% All rights reserved. +% ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +% @file fisher.Rd +% @brief roxygen2 documentation for the R Interface of R_ExaGeoStatFisher function. +% @version 1.1.0 +% @author Mahmoud ElKarargy +% @date 2024-03-17 + +\name{fisher} +\alias{fisher } +\title{Fisher function} + +\usage{ +fisher(kernel, distance_matrix = "euclidean", estimated_theta, dts, +lts = 0, dimension = "2D", train_data, test_data) +} + +\arguments{ +\item{kernel}{A string specifies the kernel to use. Available kernels include: + \itemize{ + \item "BivariateMaternFlexible" + \item "BivariateMaternParsimonious" + \item "BivariateSpacetimeMaternStationary" + \item "TrivariateMaternParsimonious" + \item "UnivariateExpNonGaussian" + \item "UnivariateMaternDbeta" + \item "UnivariateMaternDdbetaBeta" + \item "UnivariateMaternDdbetaNu" + \item "UnivariateMaternDdnuNu" + \item "UnivariateMaternDdsigmaSquare" + \item "UnivariateMaternDdsigmaSquareBeta" + \item "UnivariateMaternDdsigmaSquareNu" + \item "UnivariateMaternDnu" + \item "UnivariateMaternDsigmaSquare" + \item "UnivariateMaternNonGaussian" + \item "UnivariateMaternNuggetsStationary" + \item "UnivariateMaternStationary" + \item "UnivariatePowExpStationary" + \item "UnivariateSpacetimeMaternStationary" + } + } +\item{distance_matrix}{ A string specifies the distance metric, either "euclidean" or "great_circle". Default is "euclidean".} +\item{estimated_theta}{A list of estimated theta parameters.} +\item{dts}{A numeric value represents the time step size.} +\item{lts}{A numeric value represents the length step size. Default is 0.} +\item{dimension}{A string specifies the data dimension, either "2D" or "3D". Default is "2D".} +\item{train_data}{ A numeric vector contains the locations and z measurements for training.} +\item{test_data}{ A numeric vector contains the locations for testing.} +} + +\value{A vector contains the Fisher information matrix elements.} + +\description{This function computes the Fisher information matrix for a given dataset and theta vector, +using a specified kernel and distance metric. It also allows for the inclusion of missing values and the specification of data dimensions.} + +\examples{ +dimension = "2D" +ncores <- 1 +ngpus <- 0 +dts <- 2 +kernel <- "univariate_matern_stationary" +estimated_theta <- c(1,0.1,0.5) +computation <- "exact" +p <- 1 +q <- 1 +hardware <- new(Hardware, computation, ncores, ngpus, p, q) + +z_value <- c(-1.272336140360187606, -2.590699695867695773, + 0.512142584178685967, -0.163880452049749520) +locations_x <- c(0.092042420080872822, 0.193041886015106440, + 0.330556191348134576, 0.181612878614480805) +locations_y <- c(0.928648813611047563, 0.103883421072709245, + 0.135790035858701447, 0.434683756771190977) + +test_x <- c(0.347951, 0.62768) +test_y <- c(0.806332, 0.105196) + +fisher_matrix <- fisher(train_data=list(locations_x, locations_y, z_value), +test_data=list(test_x, test_y), kernel=kernel, dts=dts, estimated_theta=estimated_theta) +} diff --git a/man/get_Z_measurement_vector.Rd b/man/get_Z_measurement_vector.Rd new file mode 100644 index 00000000..5dc60933 --- /dev/null +++ b/man/get_Z_measurement_vector.Rd @@ -0,0 +1,51 @@ +// TODO: dots +% Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +% All rights reserved. +% ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +% @file get_Z_measurement_vector.Rd +% @brief roxygen2 documentation for the R Interface of get_Z_measurment_vector function. +% @version 1.1.0 +% @author Mahmoud ElKarargy +% @date 2024-03-17 + +\name{get_Z_measurement_vector} +\alias{get_Z_measurement_vector} +\title{Get descriptive Z values function} + +\description{ +Retrieves descriptive Z values from ExaGeoStat data based on type. +} + +\usage{ +get_Z_measurement_vector(data,type) +} + +\arguments{ +\item{data}{A list of ExaGeoStatData that contains the locations.} +\item{type}{A string specifies the type of descriptor value to retrieve (e.g., "Chameleon", "HiCMA").} +} + +\value{ +A numeric vector of descriptive Z values. +} + +\examples{ +ncores <- 2 +ngpus <- 0 +computation <- "exact" +p <- 1 +q <- 1 +hardware <- new(Hardware, computation, ncores, ngpus, p, q) + +dimension = "3D" +problem_size <- 4 +empty_data <- new(Data, problem_size, dimension) + +dts <- 2 +kernel <- "univariate_matern_stationary" +initial_theta <- c(1,0.1,0.5) +exageostat_data <- simulate_data(kernel=kernel, initial_theta=initial_theta, +problem_size=problem_size, dts=dts, dimension=dimension) +Z <- get_Z_measurement_vector(data=exageostat_data, type="chameleon") +} diff --git a/man/get_locations.Rd b/man/get_locations.Rd new file mode 100644 index 00000000..42eb4153 --- /dev/null +++ b/man/get_locations.Rd @@ -0,0 +1,49 @@ +% Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +% All rights reserved. +% ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +% @file get_locations.Rd +% @brief roxygen2 documentation for the R Interface of get_locations function for all coordinates. +% @version 1.1.0 +% @author Mahmoud ElKarargy +% @date 2024-03-17 + +\name{get_locations} +\alias{get_locations} +\title{Get Locations function} + +\description{ +Retrieves all the coordinates of locations from ExaGeoStatData object. +} + +\usage{ +get_locations(data) +} + +\arguments{ +\item{data}{A list of ExaGeoStatData that contains the locations.} +} + +\value{ +A numeric vector of locations. +} + +\examples{ +ncores <- 1 +ngpus <- 0 +computation <- "exact" +p <- 1 +q <- 1 +hardware <- new(Hardware, computation, ncores, ngpus, p, q) + +dimension = "2D" +problem_size <- 4 +empty_data <- new(Data, problem_size, dimension) + +dts <- 2 +kernel <- "univariate_matern_stationary" +initial_theta <- c(1,0.1,0.5) +exageostat_data <- simulate_data(kernel=kernel, initial_theta=initial_theta, +problem_size=problem_size, dts=dts, dimension=dimension) +locs <- get_locations(data=exageostat_data) +} diff --git a/man/idw.Rd b/man/idw.Rd new file mode 100644 index 00000000..a102bab0 --- /dev/null +++ b/man/idw.Rd @@ -0,0 +1,88 @@ + +% Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +% All rights reserved. +% ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +% @file idw.Rd +% @brief roxygen2 documentation for the R Interface of R_ExaGeoStatIDW function. +% @version 1.1.0 +% @author Mahmoud ElKarargy +% @date 2024-03-17 + +\name{idw} +\alias{idw} +\title{IDW function} + +\usage{ +idw(kernel, distance_matrix = "euclidean", estimated_theta, dts, lts = 0, +dimension = "2D", train_data, test_data, test_measurements) +} + +\arguments{ +\item{kernel}{A string specifies the kernel to use. Available kernels include: + \itemize{ + \item "BivariateMaternFlexible" + \item "BivariateMaternParsimonious" + \item "BivariateSpacetimeMaternStationary" + \item "TrivariateMaternParsimonious" + \item "UnivariateExpNonGaussian" + \item "UnivariateMaternDbeta" + \item "UnivariateMaternDdbetaBeta" + \item "UnivariateMaternDdbetaNu" + \item "UnivariateMaternDdnuNu" + \item "UnivariateMaternDdsigmaSquare" + \item "UnivariateMaternDdsigmaSquareBeta" + \item "UnivariateMaternDdsigmaSquareNu" + \item "UnivariateMaternDnu" + \item "UnivariateMaternDsigmaSquare" + \item "UnivariateMaternNonGaussian" + \item "UnivariateMaternNuggetsStationary" + \item "UnivariateMaternStationary" + \item "UnivariatePowExpStationary" + \item "UnivariateSpacetimeMaternStationary" + } + } + \item{distance_matrix}{ A string specifies the distance metric, either "euclidean" or "great_circle". Default is "euclidean".} + \item{estimated_theta}{A list of estimated theta parameters.} + \item{dts}{A numeric value represents the time step size.} + \item{lts}{A numeric value represents the length step size. Default is 0.} + \item{dimension}{A string specifies the data dimension, either "2D" or "3D". Default is "2D".} + \item{train_data}{ A numeric vector contains the locations and z measurements for training.} + \item{test_data}{ A numeric vector contains the locations for testing.} + \item{test_measurements}{ A numeric vector contains the z measurements for testing.} +} + +\value{ + A vector contains the IDW error. +} + +\description{ +This function performs Inverse Distance Weighting (IDW) interpolation for a given dataset and theta vector. +} + +\examples{ +ncores <- 2 +ngpus <- 0 +computation <- "exact" +hardware <- new(Hardware, computation, ncores, ngpus, 1, 1) + +problem_size <- 4 +dimension = "2D" +dts <- 2 +kernel <- "univariate_matern_stationary" +estimated_theta <- c(1,0.1,0.5) + +z_value <- c( -1.272336140360187606, -2.590699695867695773, 0.512142584178685967, + -0.163880452049749520) +locations_x <- c(0.193041886015106440, 0.330556191348134576, 0.181612878614480805, + 0.370473792629892440) +locations_y <- c(0.103883421072709245, 0.135790035858701447, 0.434683756771190977, + 0.400778210116731537) +test_x <- c(0.347951, 0.62768) +test_y <- c(0.806332, 0.105196) +test_measurements = c(-1.05428, -1.47441) + +idw_error = idw(kernel=kernel, estimated_theta=estimated_theta, dts=dts, +train_data=list(locations_x, locations_y, z_value), +test_data=list(test_x, test_y), test_measurements=test_measurements) +} diff --git a/man/mloe_mmom.Rd b/man/mloe_mmom.Rd new file mode 100644 index 00000000..eed7afcb --- /dev/null +++ b/man/mloe_mmom.Rd @@ -0,0 +1,89 @@ + +% Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +% All rights reserved. +% ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +% @file mloe_mmom.Rd +% @brief roxygen2 documentation for the R Interface of R_ExaGeoStatMLOE_MMOM function +% @version 1.1.0 +% @author Mahmoud ElKarargy +% @date 2024-03-17 + +\name{mloe_mmom} +\alias{mloe_mmom} +\title{MLOE MMOM function} + +\usage{ +mloe_mmom(kernel, distance_matrix="euclidean", estimated_theta, true_theta, +dts, lts=0, dimension="2D", train_data, test_data) +} + +\arguments{ + \item{kernel}{A string specifies the kernel to use. Available kernels include: + \itemize{ + \item "BivariateMaternFlexible" + \item "BivariateMaternParsimonious" + \item "BivariateSpacetimeMaternStationary" + \item "TrivariateMaternParsimonious" + \item "UnivariateExpNonGaussian" + \item "UnivariateMaternDbeta" + \item "UnivariateMaternDdbetaBeta" + \item "UnivariateMaternDdbetaNu" + \item "UnivariateMaternDdnuNu" + \item "UnivariateMaternDdsigmaSquare" + \item "UnivariateMaternDdsigmaSquareBeta" + \item "UnivariateMaternDdsigmaSquareNu" + \item "UnivariateMaternDnu" + \item "UnivariateMaternDsigmaSquare" + \item "UnivariateMaternNonGaussian" + \item "UnivariateMaternNuggetsStationary" + \item "UnivariateMaternStationary" + \item "UnivariatePowExpStationary" + \item "UnivariateSpacetimeMaternStationary" + } + } +\item{distance_matrix}{ A string specifies the distance metric, either "euclidean" or "great_circle". Default is "euclidean".} +\item{estimated_theta}{A list of estimated theta parameters.} +\item{true_theta}{A list of truth theta parameters.} +\item{dts}{A numeric value represents the time step size.} +\item{lts}{A numeric value represents the length step size. Default is 0.} +\item{dimension}{A string specifies the data dimension, either "2D" or "3D". Default is "2D".} +\item{train_data}{ A numeric vector contains the locations and z measurements for training.} +\item{test_data}{ A numeric vector contains the locations for testing.} +} + +\value{ +A vector of MLOE/MMOM values +} + +\description{ +This function calculates Mean Misspecification of the Mean Square Error (MMOM) and Mean Loss of Efficiency (MLOE). +} + +\examples{ +ncores <- 2 +ngpus <- 0 +computation <- "exact" +hardware <- new(Hardware, computation, ncores, ngpus, 1, 1) + +problem_size <- 4 +dimension = "2D" +dts <- 2 +kernel <- "univariate_matern_stationary" +estimated_theta <- c(1,0.1,0.5) +true_theta <- c(1.1,0.2,0.5) + +z_value <- c(-1.272336140360187606, -2.590699695867695773, 0.512142584178685967, + -0.163880452049749520) +locations_x <- c(0.092042420080872822, 0.193041886015106440, 0.330556191348134576, + 0.181612878614480805) +locations_y <- c(0.928648813611047563, 0.103883421072709245, 0.135790035858701447, + 0.434683756771190977) + +test_x <- c(0.347951, 0.62768) +test_y <- c(0.806332, 0.105196) + +result_mloe_mmom = mloe_mmom(train_data=list(locations_x, locations_y, z_value), +test_data=list(test_x, test_y), kernel=kernel, dts=dts, +estimated_theta=estimated_theta, true_theta=true_theta) +} diff --git a/man/model_data.Rd b/man/model_data.Rd new file mode 100644 index 00000000..b49a3665 --- /dev/null +++ b/man/model_data.Rd @@ -0,0 +1,96 @@ + +% Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +% All rights reserved. +% ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +% @file model_data.Rd +% @brief roxygen2 documentation for the R Interface of R_ExaGeoStatModelData function. +% @version 1.1.0 +% @author Mahmoud ElKarargy +% @date 2024-03-17 + +\name{model_data} +\alias{model_data} +\title{Model Data function} + +\usage{ +model_data(computation = "exact", kernel, distance_matrix = "euclidean", lb, +ub, tol = 4, mle_itr, dts, lts = 0, dimension = "2D", band = 0, max_rank = 500, +data = NULL, matrix = NULL, x = NULL, y = NULL, z = NULL) +} + +\arguments{ +\item{computation}{A string specifies the computation method, either "exact" or "dst" or "tlr". Default is "exact".} + \item{kernel}{A string specifies the kernel to use. Available kernels include: + \itemize{ + \item "BivariateMaternFlexible" + \item "BivariateMaternParsimonious" + \item "BivariateSpacetimeMaternStationary" + \item "TrivariateMaternParsimonious" + \item "UnivariateExpNonGaussian" + \item "UnivariateMaternDbeta" + \item "UnivariateMaternDdbetaBeta" + \item "UnivariateMaternDdbetaNu" + \item "UnivariateMaternDdnuNu" + \item "UnivariateMaternDdsigmaSquare" + \item "UnivariateMaternDdsigmaSquareBeta" + \item "UnivariateMaternDdsigmaSquareNu" + \item "UnivariateMaternDnu" + \item "UnivariateMaternDsigmaSquare" + \item "UnivariateMaternNonGaussian" + \item "UnivariateMaternNuggetsStationary" + \item "UnivariateMaternStationary" + \item "UnivariatePowExpStationary" + \item "UnivariateSpacetimeMaternStationary" + } + } +\item{distance_matrix}{A string specifies the distance metric, either "euclidean" or "great_circle". Default is "euclidean".} +\item{lb}{A numeric value represents the lower bound for the computation.} +\item{ub}{A numeric value represents the upper bound for the computation.} +\item{tol}{A numeric value specifies the tolerance for the computation. Default is 4.} +\item{mle_itr}{A numeric value specifies the maximum number of iterations for the computation.} +\item{dts}{A numeric value represents the time step size.} +\item{lts}{A numeric value represents the length step size. Default is 0.} +\item{dimension}{A string specifies the data dimension, either "2D" or "3D". Default is "2D".} +\item{band}{A numeric value Bandwidth for band matrices, applicable in certain computational kernels, Default is 0.} +\item{max_rank}{A numeric value specifies the Maximum rank for low-rank approximations, Default is 500.} +\item{data}{A list of data vectors. Default is `R_NilValue`.} +\item{matrix}{A matrix object. Default is `R_NilValue`.} +\item{x}{A numeric vector. Default is `R_NilValue`.} +\item{y}{A numeric vector. Default is `R_NilValue`.} +\item{z}{A numeric vector. Default is `R_NilValue`.} +} + +\value{ +A vector contains the starting theta. +} + +\description{ +This function models data based on the provided computation method, kernel, distance matrix, and other parameters. +} + +\examples{ +ncores <- 2 +ngpus <- 0 +computation <- "exact" +hardware <- new(Hardware, computation, ncores, ngpus, 1, 1) + +dimension = "2D" +problem_size <- 4 +empty_data <- new(Data, problem_size, dimension) + +dts <- 2 +kernel <- "univariate_matern_stationary" +lower_bound <- c(0.1,0.1,0.1) +upper_bound <- c(5,5,5) + +z_value <- c( -1.272336140360187606, -2.590699695867695773, 0.512142584178685967, + -0.163880452049749520) +locations_x <- c(0.193041886015106440, 0.330556191348134576, 0.181612878614480805, + 0.370473792629892440) +locations_y <- c(0.103883421072709245, 0.135790035858701447, 0.434683756771190977, + 0.400778210116731537) + +theta <- model_data(kernel=kernel, lb=lower_bound, ub=upper_bound, +mle_itr=10, dts=dts, matrix=z_value, x=locations_x, y=locations_y) +} diff --git a/man/predict_data.Rd b/man/predict_data.Rd new file mode 100644 index 00000000..217bf2f2 --- /dev/null +++ b/man/predict_data.Rd @@ -0,0 +1,84 @@ + +% Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +% All rights reserved. +% ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +% @file predict_data.Rd +% @brief roxygen2 documentation for the R Interface of R_ExaGeoStatPredictData function. +% @version 1.1.0 +% @author Mahmoud ElKarargy +% @date 2024-03-17 + +\name{predict_data} +\alias{predict_data} +\title{Predict Data function} + +\usage{ +predict_data(kernel, distance_matrix = "euclidean", estimated_theta, +dts, lts = 0, dimension = "2D", train_data, test_data) +} + +\arguments{ + \item{kernel}{A string specifies the kernel to use. Available kernels include: + \itemize{ + \item "BivariateMaternFlexible" + \item "BivariateMaternParsimonious" + \item "BivariateSpacetimeMaternStationary" + \item "TrivariateMaternParsimonious" + \item "UnivariateExpNonGaussian" + \item "UnivariateMaternDbeta" + \item "UnivariateMaternDdbetaBeta" + \item "UnivariateMaternDdbetaNu" + \item "UnivariateMaternDdnuNu" + \item "UnivariateMaternDdsigmaSquare" + \item "UnivariateMaternDdsigmaSquareBeta" + \item "UnivariateMaternDdsigmaSquareNu" + \item "UnivariateMaternDnu" + \item "UnivariateMaternDsigmaSquare" + \item "UnivariateMaternNonGaussian" + \item "UnivariateMaternNuggetsStationary" + \item "UnivariateMaternStationary" + \item "UnivariatePowExpStationary" + \item "UnivariateSpacetimeMaternStationary" + } + } + \item{distance_matrix}{ A string specifies the distance metric, either "euclidean" or "great_circle". Default is "euclidean".} + \item{estimated_theta}{A list of estimated theta parameters.} + \item{dts}{A numeric value represents the time step size.} + \item{lts}{A numeric value represents the length step size. Default is 0.} + \item{dimension}{A string specifies the data dimension, either "2D" or "3D". Default is "2D".} + \item{train_data}{ A numeric vector contains the locations and z measurements for training.} + \item{test_data}{ A numeric vector contains the locations for testing.} +} + +\value{ + A vector of predicted z values +} + +\description{ +This function predicts data based on the provided kernel, distance matrix, estimated theta, and other parameters. +} + +\examples{ +ncores <- 2 +ngpus <- 0 +problem_size <- 4 +dts <- 2 +computation <- "exact" +hardware <- new(Hardware, computation, ncores, ngpus, 1, 1) +kernel <- "univariate_matern_stationary" +estimated_theta <- c(1,0.1,0.5) + +z_value <- c( -1.272336140360187606, -2.590699695867695773, 0.512142584178685967, + -0.163880452049749520) +locations_x <- c(0.193041886015106440, 0.330556191348134576, 0.181612878614480805, + 0.370473792629892440) +locations_y <- c(0.103883421072709245, 0.135790035858701447, 0.434683756771190977, + 0.400778210116731537) +test_x <- c(0.347951, 0.62768) +test_y <- c(0.806332, 0.105196) + +predict_data(train_data=list(locations_x, locations_y, z_value), +test_data=list(test_x, test_y), kernel=kernel, dts=dts, +estimated_theta=estimated_theta) +} diff --git a/man/simulate_data.Rd b/man/simulate_data.Rd new file mode 100644 index 00000000..c9f40a2f --- /dev/null +++ b/man/simulate_data.Rd @@ -0,0 +1,83 @@ + +% Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +% All rights reserved. +% ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +% @file simulate_data.Rd +% @brief roxygen2 documentation for the R Interface of R_ExaGeoStatLoadData function +% @version 1.1.0 +% @author Mahmoud ElKarargy +% @date 2024-03-17 + +\name{simulate_data} +\alias{simulate_data} +\title{Simulate Data function} + +\usage{ +simulate_data(kernel, initial_theta, distance_matrix = "euclidean", problem_size, +seed = 0, dts, lts = 0, dimension = "2D", log_path = "", data_path = "", +observations_file = "", recovery_file = "") +} + +\arguments{ + \item{kernel}{A string specifies the kernel to use. Available kernels include: + \itemize{ + \item "BivariateMaternFlexible" + \item "BivariateMaternParsimonious" + \item "BivariateSpacetimeMaternStationary" + \item "TrivariateMaternParsimonious" + \item "UnivariateExpNonGaussian" + \item "UnivariateMaternDbeta" + \item "UnivariateMaternDdbetaBeta" + \item "UnivariateMaternDdbetaNu" + \item "UnivariateMaternDdnuNu" + \item "UnivariateMaternDdsigmaSquare" + \item "UnivariateMaternDdsigmaSquareBeta" + \item "UnivariateMaternDdsigmaSquareNu" + \item "UnivariateMaternDnu" + \item "UnivariateMaternDsigmaSquare" + \item "UnivariateMaternNonGaussian" + \item "UnivariateMaternNuggetsStationary" + \item "UnivariateMaternStationary" + \item "UnivariatePowExpStationary" + \item "UnivariateSpacetimeMaternStationary" + } + } +\item{initial_theta}{A list of initial theta parameters.} +\item{distance_matrix}{A string specifies the distance metric, either "euclidean" or "great_circle". Default is "euclidean".} +\item{problem_size}{A numeric value represents the size of the problem to simulate.} +\item{seed}{ A numeric value specifies the seed for random number generation. Default is 0.} +\item{dts}{ A numeric value represents the time step size.} +\item{lts}{ A numeric value represents the length step size. Default is 0.} +\item{dimension}{A string specifies the data dimension, either "2D" or "3D". Default is "2D".} +\item{log_path}{A string specifies the path for logging.} +\item{data_path}{A string specifies the path for data storage.} +\item{observations_file}{A string specifies the file name for observations.} +\item{recovery_file}{A string specifies the file name for recovery.} +} + +\value{ +A pointer to ExaGeoStatData object that contains the loaded data. +} + +\description{ +This function loads data into an ExaGeoStatData object using the provided configuration and computational settings. +} + +\examples{ +ncores <- 2 +ngpus <- 0 +computation <- "exact" +hardware <- new(Hardware, computation, ncores, ngpus, 1, 1) + +dimension = "2D" +problem_size <- 4 +empty_data <- new(Data, problem_size, dimension) + +dts <- 2 +kernel <- "univariate_matern_stationary" +initial_theta <- c(1,0.1,0.5) + +exageostat_data <- simulate_data(kernel=kernel, initial_theta=initial_theta, +problem_size=problem_size, dts=dts, dimension=dimension) +} 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..ac72b5f6 --- /dev/null +++ b/scripts/Benchmarking.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file Benchmarking.sh +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @date 2023-10-10 + +# Set the output file name +output_file="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..beb9378f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,37 +1,40 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt # @brief This file contains the CMake configuration for the ExaGeoStat library. -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah -# @date 2023-01-30 +# @date 2024-02-04 # Add subdirectories for configurations, data-generators, data-units, and linear-algebra-solvers. -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/configurations) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/data-generators) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/data-units) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/linear-algebra-solvers) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/kernels) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/api) -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(api) +add_subdirectory(configurations) +add_subdirectory(data-generators) +add_subdirectory(data-loader) +add_subdirectory(data-units) +add_subdirectory(hardware) +add_subdirectory(helpers) +add_subdirectory(kernels) +add_subdirectory(linear-algebra-solvers) +add_subdirectory(prediction) +add_subdirectory(results) +add_subdirectory(runtime) + +if (USE_R) + add_subdirectory(Rcpp-adapters) +endif () # Set the name of the library to be created. set(LIB_NAME ${PROJECT_NAME}) - # Create the library with the specified source files and linking libraries. -add_library(${LIB_NAME} - STATIC - ${SOURCES} - ) +add_library(${LIB_NAME} SHARED ${SOURCES}) + target_compile_definitions(${LIB_NAME} PUBLIC ${COMPILE_DEFINITIONS}) -target_link_libraries(${LIB_NAME} PUBLIC ${LIBS}) +target_link_libraries(${LIB_NAME} ${LIBS}) # Set the version of the library. set_target_properties(${LIB_NAME} @@ -46,7 +49,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/Makefile b/src/Makefile new file mode 100644 index 00000000..af240108 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,14 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file Makefile +# @brief Makefile for custom building ExaGeoStat +# @version 1.1.0 +# @author David Helmy +# @date 2024-01-30 + +# this file is added to let R CMD build with Custom build configuration instead of using its +# main build system +all : diff --git a/src/Rcpp-adapters/CMakeLists.txt b/src/Rcpp-adapters/CMakeLists.txt new file mode 100644 index 00000000..d161a223 --- /dev/null +++ b/src/Rcpp-adapters/CMakeLists.txt @@ -0,0 +1,17 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @date 2024-01-29 + +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/FunctionsAdapter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/RcppExports.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/RcppModules.cpp + ${SOURCES} + PARENT_SCOPE + ) \ No newline at end of file diff --git a/src/Rcpp-adapters/FunctionsAdapter.cpp b/src/Rcpp-adapters/FunctionsAdapter.cpp new file mode 100644 index 00000000..4d5407ae --- /dev/null +++ b/src/Rcpp-adapters/FunctionsAdapter.cpp @@ -0,0 +1,375 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file FunctionsAdapter.cpp + * @brief Header file for function adapters in the ExaGeoStat software. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-01-29 +**/ + +#include +#include +#include + +using namespace std; +using namespace Rcpp; + +using namespace exageostat::api; +using namespace exageostat::common; +using namespace exageostat::results; +using namespace exageostat::configurations; + +namespace exageostat::adapters { + + vector> R_GetLocations(ExaGeoStatData *apData) { + + // Number of points per each dimension + int length = apData->GetLocations()->GetSize(); + bool is3D = apData->GetLocations()->GetDimension() == Dimension3D; + + double *locationXArray = apData->GetLocations()->GetLocationX(); + double *locationYArray = apData->GetLocations()->GetLocationY(); + double *locationZArray = nullptr; + if (is3D) { + locationZArray = apData->GetLocations()->GetLocationZ(); + } + + vector> locations_matrix; + for (int i = 0; i < length; ++i) { + vector point; + point.push_back(locationXArray[i]); + point.push_back(locationYArray[i]); + if (is3D) { + point.push_back(locationZArray[i]); + } + locations_matrix.push_back(point); + } + return locations_matrix; + } + + NumericVector R_GetDescZValues(ExaGeoStatData *apData, const string &aType) { + + DescriptorType descriptorType; + void *pDescriptor; + + if (aType == "chameleon" || aType == "Chameleon") { + descriptorType = CHAMELEON_DESCRIPTOR; + } else if (aType == "hicma" || aType == "Hicma" || aType == "HICMA") { +#ifdef USE_HICMA + descriptorType = HICMA_DESCRIPTOR; +#else + throw runtime_error("Please enable HiCMA to use HiCMA descriptors."); +#endif + } else { + throw domain_error("Invalid type of descriptor, please use chameleon or hicma."); + } + + // Obtain the pointer to the array of doubles + double *data = apData->GetDescriptorData()->GetDescriptorMatrix(descriptorType, DESCRIPTOR_Z); + int length = apData->GetLocations()->GetSize(); + // Create an empty NumericVector of the appropriate length + NumericVector vec(length); + // Copy data from the double array to the NumericVector + copy(data, data + length, vec.begin()); + return vec; + } + + ExaGeoStatData * + R_ExaGeoStatLoadData(const string &aKernelName, const vector &aInitialTheta, const string &aDistanceMatrix, + const int &aProblemSize, const int &aSeed, const int &aDenseTileSize, const int &aLowTileSize, + const string &aDimension, const string &aLogPath, const string &aDataPath, + const string &aRecoveryFilePath, const string &aObservationsFilePath) { + + // manually set the configurations values with the user input from R. + Configurations configurations; + configurations.SetProblemSize(aProblemSize); + configurations.CheckKernelValue(aKernelName); + configurations.ParseDistanceMetric(aDistanceMatrix); + configurations.SetSeed(aSeed); + configurations.SetDenseTileSize(aDenseTileSize); + configurations.SetLowTileSize(aLowTileSize); + configurations.SetComputation(EXACT_DENSE); + configurations.SetInitialTheta(aInitialTheta); + configurations.SetDimension(Configurations::CheckDimensionValue(aDimension)); + + if (!aLogPath.empty()) { + configurations.SetLogger(true); + configurations.SetLoggerPath(aLogPath); + } + if (!aDataPath.empty()) { + configurations.SetDataPath(aDataPath); + configurations.SetIsSynthetic(false); + } + configurations.SetRecoveryFile(aRecoveryFilePath); + configurations.SetActualObservationsFilePath(aObservationsFilePath); + + unique_ptr> data; + ExaGeoStat::ExaGeoStatLoadData(configurations, data); + + // We can safely return the raw pointer, but we need to release it from data to avoid deletion. + return data.release(); + } + + vector + R_ExaGeoStatModelData(const string &aComputation, const string &aKernelName, const string &aDistanceMatrix, + const vector &aLowerBound, const vector &aUpperBound, const int &aTolerance, + const int &aMleIterations, const int &aDenseTileSize, const int &aLowTileSize, + const string &aDimension, const int &aBand, const int &aMaxRank, SEXP apData, + Nullable aMeasurementsVector, Nullable aLocationsX, + Nullable aLocationsY, Nullable aLocationsZ) { + + Configurations configurations; + bool is_initialized = ((SEXP) apData == R_NilValue); + unique_ptr> data; + if (!is_initialized) { + auto temp_data = (ExaGeoStatData *) Rcpp::internal::as_module_object_internal(apData); + // Set the unique_ptr to manage the ExaGeoStatData pointer + data.reset(temp_data); + } else { + NumericVector z_values(aMeasurementsVector.get()); + + // Create a new ExaGeoStatData object with configurations and manage it with unique_ptr + data = make_unique>(z_values.size(), configurations.GetDimension()); + } + double *pMeasurementsVectorPtr = GetDataFromArguments(aMeasurementsVector, aLocationsX, aLocationsY, + aLocationsZ, data, configurations, aKernelName, + aDistanceMatrix, aDenseTileSize, aLowTileSize, aDimension, + Configurations::CheckComputationValue(aComputation)); + + configurations.SetLowerBounds(aLowerBound); + configurations.SetUpperBounds(aUpperBound); + configurations.SetMaxMleIterations(aMleIterations); + configurations.SetTolerance(aTolerance); + configurations.SetBand(aBand); + configurations.SetMaxRank(aMaxRank); + + ExaGeoStat::ExaGeoStatDataModeling(configurations, data, pMeasurementsVectorPtr); + // Take back ownership, to avoid deleting apData when the unique_ptr goes out of scope. + apData = (SEXP) data.release(); + return configurations.GetStartingTheta(); + } + + vector R_ExaGeoStatPredictData(const string &aKernelName, const string &aDistanceMatrix, + const vector &aEstimatedTheta, const int &aDenseTileSize, + const int &aLowTileSize, const string &aDimension, + vector > &aTrainData, vector > &aTestData) { + + Configurations configurations; + configurations.SetIsMSPE(TRUE); + configurations.SetEstimatedTheta(aEstimatedTheta); + vector empty_vector; + PredictionSetupHelper(configurations, aKernelName, aDistanceMatrix, aDenseTileSize, aLowTileSize, aDimension, + aTrainData, aTestData, aEstimatedTheta, empty_vector); + return Results::GetInstance()->GetPredictedMissedValues(); + } + + vector R_ExaGeoStatMLOE_MMOM(const string &aKernelName, const string &aDistanceMatrix, + const vector &aEstimatedTheta, const vector &aTrueTheta, + const int &aDenseTileSize, const int &aLowTileSize, const string &aDimension, + vector > &aTrainData, vector > &aTestData) { + + Configurations configurations; + configurations.SetEstimatedTheta(aEstimatedTheta); + configurations.SetInitialTheta(aTrueTheta); + configurations.SetIsMLOEMMOM(TRUE); + + vector empty_vector; + PredictionSetupHelper(configurations, aKernelName, aDistanceMatrix, aDenseTileSize, aLowTileSize, aDimension, + aTrainData, aTestData, aEstimatedTheta, empty_vector); + + vector mloe_mmom_values; + mloe_mmom_values.push_back(Results::GetInstance()->GetMLOE()); + mloe_mmom_values.push_back(Results::GetInstance()->GetMMOM()); + return mloe_mmom_values; + } + + vector + R_ExaGeoStatFisher(const string &aKernelName, const string &aDistanceMatrix, const vector &aEstimatedTheta, + const int &aDenseTileSize, const int &aLowTileSize, const string &aDimension, + vector > &aTrainData, vector > &aTestData) { + + Configurations configurations; + configurations.SetIsFisher(TRUE); + + vector empty_vector; + PredictionSetupHelper(configurations, aKernelName, aDistanceMatrix, aDenseTileSize, aLowTileSize, aDimension, + aTrainData, aTestData, aEstimatedTheta, empty_vector); + + return Results::GetInstance()->GetFisherMatrix(); + } + + vector + R_ExaGeoStatIDW(const string &aKernelName, const string &aDistanceMatrix, const vector &aEstimatedTheta, + const int &aDenseTileSize, const int &aLowTileSize, const string &aDimension, + vector > &aTrainData, vector > &aTestData, + vector &aTestMeasurementsValues) { + + Configurations configurations; + configurations.SetIsIDW(TRUE); + + PredictionSetupHelper(configurations, aKernelName, aDistanceMatrix, aDenseTileSize, aLowTileSize, aDimension, + aTrainData, aTestData, aEstimatedTheta, aTestMeasurementsValues); + + return Results::GetInstance()->GetIDWError(); + } + + double *GetDataFromArguments(Nullable aMeasurementsVector, Nullable aLocationsX, + Nullable aLocationsY, Nullable aLocationsZ, + unique_ptr > &aData, Configurations &aConfigurations, + const string &aKernelName, const string &aDistanceMatrix, const int &aDenseTileSize, + const int &aLowTileSize, const string &aDimension, const Computation &aComputation) { + + double *pMeasurementsVectorPtr = nullptr; + if (aMeasurementsVector == nullptr || aMeasurementsVector.isNull()) { + // This was the only way to pass C++ tests, if we checked for aMeasurementsVector != nullptr a seg fault occurs + } else { + NumericVector mat(aMeasurementsVector.get()); + pMeasurementsVectorPtr = &mat[0]; // Get the raw pointer to the matrix data + + if (!aLocationsX.isNull()) { + double *pLocationsXPtr; + NumericVector mat_location(aLocationsX.get()); + pLocationsXPtr = &mat_location[0]; // Get the raw pointer to the matrix data + // Check for overflow + if (mat_location.size() > numeric_limits::max()) { + // Handle the overflow by logging an error + throw runtime_error("Warning: Size exceeds the limit of int type for Locations X."); + } else { + // Safe to convert + int size = static_cast(mat_location.size()); + aData->GetLocations()->SetLocationX(*pLocationsXPtr, size); + } + } + + if (aLocationsY.isNotNull()) { + double *pLocationsYPtr; + NumericVector mat_location(aLocationsY.get()); + pLocationsYPtr = &mat_location[0]; // Get the raw pointer to the matrix data + // Check for overflow + if (mat_location.size() > numeric_limits::max()) { + // Handle the overflow by logging an error + throw runtime_error("Warning: Size exceeds the limit of int type for Locations Y."); + } else { + // Safe to convert + int size = static_cast(mat_location.size()); + aData->GetLocations()->SetLocationY(*pLocationsYPtr, size); + } + } + + if (aLocationsZ.isNotNull()) { + double *pLocationsZPtr; + NumericVector mat_location(aLocationsZ.get()); + pLocationsZPtr = &mat_location[0]; // Get the raw pointer to the matrix data + // Check for overflow + if (mat_location.size() > numeric_limits::max()) { + // Handle the overflow by logging an error + throw runtime_error("Warning: Size exceeds the limit of int type for Locations Z."); + } else { + // Safe to convert + int size = static_cast(mat_location.size()); + aData->GetLocations()->SetLocationZ(*pLocationsZPtr, size); + } + } + } + // Set common configurations. + aConfigurations.SetComputation(aComputation); + aConfigurations.CheckKernelValue(aKernelName); + aConfigurations.ParseDistanceMetric(aDistanceMatrix); + aConfigurations.SetDenseTileSize(aDenseTileSize); + aConfigurations.SetLowTileSize(aLowTileSize); + aConfigurations.SetDimension(Configurations::CheckDimensionValue(aDimension)); + aConfigurations.SetProblemSize(aData->GetLocations()->GetSize()); + return pMeasurementsVectorPtr; + } + + void ValidateDataDimensions(const vector > &aData, const string &aDataType) { + if (aData.empty() || aData.front().empty()) { + throw runtime_error("No " + aDataType + " data provided."); + } + + size_t expectedSize = aData.front().size(); + for (const auto &vec: aData) { + if (vec.size() != expectedSize) { + throw runtime_error("Inconsistent dimensions in " + aDataType + " data."); + } + } + } + + void + PredictionSetupHelper(Configurations &aConfigurations, const string &aKernelName, const string &aDistanceMatrix, + const int &aDenseTileSize, const int &aLowTileSize, const string &aDimension, + vector > &aTrainData, vector > &aTestData, + const vector &aEstimatedTheta, const vector &aTestMeasurementsValues) { + + aConfigurations.SetComputation(EXACT_DENSE); + + ValidateDataDimensions(aTrainData, "train"); + ValidateDataDimensions(aTestData, "test"); + + size_t potential_train_data_size = aTrainData[0].size(); + if (potential_train_data_size > static_cast(numeric_limits::max())) { + throw runtime_error("Train data size exceeds the maximum size for int type."); + } + int train_data_size = static_cast(potential_train_data_size); + + size_t potential_test_data_size = aTestData[0].size(); + if (potential_test_data_size > static_cast(numeric_limits::max())) { + throw runtime_error("Test data size exceeds the maximum size for int type."); + } + int test_data_size = static_cast(potential_test_data_size); + + auto data = make_unique>(train_data_size, aConfigurations.GetDimension()); + dataunits::Locations train_locations(train_data_size, aConfigurations.GetDimension()); + dataunits::Locations test_locations(test_data_size, aConfigurations.GetDimension()); + + // Allocate memory for z_values to hold elements from both sources + auto *z_values = new double[aTrainData.back().size() + aTestMeasurementsValues.size()]; + + for (int i = 0; i < train_data_size; i++) { + train_locations.SetLocationX(*aTrainData[0].data(), train_data_size); + train_locations.SetLocationY(*aTrainData[1].data(), train_data_size); + data->GetLocations()->SetLocationX(*aTrainData[0].data(), train_data_size); + data->GetLocations()->SetLocationY(*aTrainData[1].data(), train_data_size); + if (aTrainData.size() > 3) { + train_locations.SetLocationZ(*aTrainData[2].data(), train_data_size); + data->GetLocations()->SetLocationZ(*aTrainData[2].data(), train_data_size); + } + } + memcpy(z_values, aTrainData.back().data(), aTrainData.back().size() * sizeof(double)); + // Calculate the starting position for the next part of the data in z_values + auto *destination = z_values + aTrainData.back().size(); + // Copy data from aTestMeasurementsValues to the next part of z_values, after the previously copied data + memcpy(destination, aTestMeasurementsValues.data(), aTestMeasurementsValues.size() * sizeof(double)); + + for (int i = 0; i < test_data_size; i++) { + test_locations.SetLocationX(*aTestData[0].data(), test_data_size); + test_locations.SetLocationY(*aTestData[1].data(), test_data_size); + if (aTestData.size() > 2) { + test_locations.SetLocationZ(*aTestData[2].data(), test_data_size); + } + } + + // Set common configurations. + aConfigurations.CheckKernelValue(aKernelName); + aConfigurations.ParseDistanceMetric(aDistanceMatrix); + aConfigurations.SetDenseTileSize(aDenseTileSize); + aConfigurations.SetLowTileSize(aLowTileSize); + aConfigurations.SetDimension(Configurations::CheckDimensionValue(aDimension)); + aConfigurations.SetProblemSize(data->GetLocations()->GetSize()); + aConfigurations.SetEstimatedTheta(aEstimatedTheta); + + // Temporarily release ownership to pass to the function. + ExaGeoStatData *tempData = data.release(); + ExaGeoStat::ExaGeoStatPrediction(aConfigurations, + reinterpret_cast> &>(tempData), + z_values, &train_locations, &test_locations); + // Take back ownership + data.reset(tempData); + + delete[] z_values; + } +} \ No newline at end of file diff --git a/src/Rcpp-adapters/RcppExports.cpp b/src/Rcpp-adapters/RcppExports.cpp new file mode 100644 index 00000000..2b1fbbab --- /dev/null +++ b/src/Rcpp-adapters/RcppExports.cpp @@ -0,0 +1,45 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file RcppExports.cpp + * @brief Rcpp export definitions for ExaGeoStatCPP module. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author David Helmy + * @date 2023-01-20 +**/ + +#include + +using namespace Rcpp; + +#ifdef RCPP_USE_GLOBAL_ROSTREAM +Rcpp::Rostream& Rcpp::Rcout = Rcpp::Rcpp_cout_get(); +Rcpp::Rostream& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get(); +#endif + +/** + * @brief Rcpp module boot function for ExaGeoStatCPP. + * @return A SEXP represents the Rcpp module. + */ +RcppExport SEXP _rcpp_module_boot_ExaGeoStatCPP(); + +/** + * @brief Array of R function call entries. + */ +static const R_CallMethodDef CallEntries[] = { + {"_rcpp_module_boot_ExaGeoStatCPP", (DL_FUNC) &_rcpp_module_boot_ExaGeoStatCPP, 0}, + {nullptr, nullptr, 0} +}; + +/** + * @brief R initialization function for ExaGeoStatCPP module. + * @param dll The DllInfo structure. + */ +RcppExport void R_init_ExaGeoStatCPP(DllInfo *dll) { + R_registerRoutines(dll, nullptr, CallEntries, nullptr, nullptr); + R_useDynamicSymbols(dll, FALSE); +} diff --git a/src/Rcpp-adapters/RcppModules.cpp b/src/Rcpp-adapters/RcppModules.cpp new file mode 100644 index 00000000..b56b3154 --- /dev/null +++ b/src/Rcpp-adapters/RcppModules.cpp @@ -0,0 +1,73 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file RcppModules.cpp + * @brief Rcpp module definitions for ExaGeoStatCPP. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author David Helmy + * @date 2023-01-20 +**/ + +#include + +#include +#include +#include + +/** Expose C++ class to R to be able to use Wrap and As + * Allows C++ to Send and Receive Class object from R + **/ +RCPP_EXPOSED_CLASS(ExaGeoStatHardware) +RCPP_EXPOSED_CLASS_NODECL(ExaGeoStatData) + +/** Expose C++ Object With the Given functions **/ +RCPP_MODULE(ExaGeoStatCPP) { + + /** ExaGeoStatCPP Class **/ + using namespace Rcpp; + + /** Hardware Class **/ + class_("Hardware") + .constructor() + .method("finalize_hardware", &ExaGeoStatHardware::FinalizeHardware, "Manually finalize the hardware"); + + /** Data Class **/ + class_>("Data") + .constructor(); + + function("simulate_data", &exageostat::adapters::R_ExaGeoStatLoadData, + List::create(_["kernel"], _["initial_theta"], _["distance_matrix"] = "euclidean", _["problem_size"], + _["seed"] = 0, _["dts"], _["lts"] = 0, _["dimension"] = "2D", _["log_path"] = "", + _["data_path"] = "", _["observations_file"] = "", _["recovery_file"] = "")); + + function("model_data", &exageostat::adapters::R_ExaGeoStatModelData, + List::create(_["computation"] = "exact", _["kernel"], _["distance_matrix"] = "euclidean", _["lb"], _["ub"], + _["tol"] = 4, _["mle_itr"], _["dts"], _["lts"] = 0, _["dimension"] = "2D", _["band"] = 0, + _["max_rank"] = 500, _["data"] = R_NilValue, _["matrix"] = R_NilValue, _["x"] = R_NilValue, + _["y"] = R_NilValue, _["z"] = R_NilValue)); + + function("predict_data", &exageostat::adapters::R_ExaGeoStatPredictData, + List::create(_["kernel"], _["distance_matrix"] = "euclidean", _["estimated_theta"], _["dts"], _["lts"] = 0, + _["dimension"] = "2D", _["train_data"], _["test_data"])); + + function("mloe_mmom", &exageostat::adapters::R_ExaGeoStatMLOE_MMOM, + List::create(_["kernel"], _["distance_matrix"] = "euclidean", _["estimated_theta"], _["true_theta"], + _["dts"], _["lts"] = 0, _["dimension"] = "2D", _["train_data"], _["test_data"])); + + function("fisher", &exageostat::adapters::R_ExaGeoStatFisher, + List::create(_["kernel"], _["distance_matrix"] = "euclidean", _["estimated_theta"], _["dts"], _["lts"] = 0, + _["dimension"] = "2D", _["train_data"], _["test_data"])); + + function("idw", &exageostat::adapters::R_ExaGeoStatIDW, + List::create(_["kernel"], _["distance_matrix"] = "euclidean", _["estimated_theta"], _["dts"], _["lts"] = 0, + _["dimension"] = "2D", _["train_data"], _["test_data"], _["test_measurements"])); + + function("get_locations", &exageostat::adapters::R_GetLocations, List::create(_["data"])); + + function("get_Z_measurement_vector", &exageostat::adapters::R_GetDescZValues, List::create(_["data"], _["type"])); + +} diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt index 9a434188..223513e0 100644 --- a/src/api/CMakeLists.txt +++ b/src/api/CMakeLists.txt @@ -1,10 +1,10 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @brief CMake build script for the operators library, which includes the OperatorMethods base class and the OperatorFactory class for creating operators of different types. # @author Mahmoud ElKarargy # @date 2023-05-30 diff --git a/src/api/ExaGeoStat.cpp b/src/api/ExaGeoStat.cpp index 11cc407e..830aa481 100644 --- a/src/api/ExaGeoStat.cpp +++ b/src/api/ExaGeoStat.cpp @@ -1,14 +1,14 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file ExaGeoStat.cpp * @brief High-Level Wrapper class containing the static API for ExaGeoStat operations. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy - * @date 2023-05-30 + * @date 2024-02-04 **/ #include @@ -20,52 +20,56 @@ using namespace std; using namespace nlopt; using namespace exageostat::api; -using namespace exageostat::configurations; using namespace exageostat::generators; using namespace exageostat::dataunits; -using namespace exageostat::hardware; -using namespace exageostat::prediction; +using namespace exageostat::configurations; template -void ExaGeoStat::ExaGeoStatLoadData(const ExaGeoStatHardware &aHardware, - configurations::Configurations &aConfigurations, - dataunits::ExaGeoStatData &aData) { +void ExaGeoStat::ExaGeoStatLoadData(Configurations &aConfigurations, std::unique_ptr> &aData) { + + aConfigurations.PrintSummary(); + LOGGER("** ExaGeoStat data generation/loading **") // 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, *pKernel); delete pKernel; + LOGGER("\t*Data generation/loading finished*") } template -T ExaGeoStat::ExaGeoStatDataModeling(const ExaGeoStatHardware &aHardware, Configurations &aConfigurations, - ExaGeoStatData &aData, T *apMeasurementsMatrix) { +T ExaGeoStat::ExaGeoStatDataModeling(Configurations &aConfigurations, std::unique_ptr> &aData, + T *apMeasurementsMatrix) { + aConfigurations.PrintSummary(); + 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(); int parameters_number = pKernel->GetParametersNumbers(); int max_number_of_iterations = aConfigurations.GetMaxMleIterations(); // Setting struct of data to pass to the modeling. - auto modeling_data = new mModelingData(aData, aConfigurations, aHardware, *apMeasurementsMatrix, *pKernel); + auto modeling_data = new mModelingData(aData, aConfigurations, *apMeasurementsMatrix, *pKernel); // Create nlopt double opt_f; opt optimizing_function(nlopt::LN_BOBYQA, parameters_number); // Initialize problem's bound. optimizing_function.set_lower_bounds(aConfigurations.GetLowerBounds()); optimizing_function.set_upper_bounds(aConfigurations.GetUpperBounds()); - optimizing_function.set_ftol_abs(pow(10, -1 * aConfigurations.GetTolerance())); + optimizing_function.set_ftol_abs(aConfigurations.GetTolerance()); // Set max iterations value. optimizing_function.set_maxeval(max_number_of_iterations); optimizing_function.set_max_objective(ExaGeoStatMLETileAPI, (void *) modeling_data); // Optimize mle using nlopt. optimizing_function.optimize(aConfigurations.GetStartingTheta(), opt_f); + aConfigurations.SetEstimatedTheta(aConfigurations.GetStartingTheta()); delete pKernel; delete modeling_data; @@ -75,28 +79,32 @@ T ExaGeoStat::ExaGeoStatDataModeling(const ExaGeoStatHardware &aHardware, Con template double ExaGeoStat::ExaGeoStatMLETileAPI(const std::vector &aTheta, std::vector &aGrad, void *apInfo) { + auto config = ((mModelingData *) apInfo)->mpConfiguration; auto data = ((mModelingData *) apInfo)->mpData; - auto hardware = ((mModelingData *) apInfo)->mpHardware; auto measurements = ((mModelingData *) apInfo)->mpMeasurementsMatrix; auto kernel = ((mModelingData *) apInfo)->mpKernel; // We do Date Modeling with any computation. auto linear_algebra_solver = linearAlgebra::LinearAlgebraFactory::CreateLinearAlgebraSolver( config->GetComputation()); - return linear_algebra_solver->ExaGeoStatMLETile(*hardware, *data, *config, aTheta.data(), measurements, *kernel); + return linear_algebra_solver->ExaGeoStatMLETile(*data, *config, aTheta.data(), measurements, *kernel); } template -void ExaGeoStat::ExaGeoStatPrediction(const ExaGeoStatHardware &aHardware, Configurations &aConfigurations, - ExaGeoStatData &aData, T *apMeasurementsMatrix) { +void ExaGeoStat::ExaGeoStatPrediction(Configurations &aConfigurations, std::unique_ptr> &aData, + T *apMeasurementsMatrix, Locations *apTrainLocations, + Locations *apTestLocations) { - Prediction predictor; + aConfigurations.PrintSummary(); + 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::Prediction::PredictMissingData(aData, aConfigurations, apMeasurementsMatrix, *pKernel, + apTrainLocations, apTestLocations); delete pKernel; } \ No newline at end of file diff --git a/src/configurations/CMakeLists.txt b/src/configurations/CMakeLists.txt index d0bee479..3575e1a3 100644 --- a/src/configurations/CMakeLists.txt +++ b/src/configurations/CMakeLists.txt @@ -1,11 +1,11 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt # @brief This file contains the CMake configuration for the data-units directory. -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-01-31 diff --git a/src/configurations/Configurations.cpp b/src/configurations/Configurations.cpp index f7a0ada3..884f44f2 100644 --- a/src/configurations/Configurations.cpp +++ b/src/configurations/Configurations.cpp @@ -1,20 +1,20 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file Configurations.cpp * @brief This file defines the Configurations class which stores the configuration parameters for ExaGeoStat. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-01-31 + * @date 2024-02-04 **/ #include #include -#include +#include using namespace std; @@ -23,11 +23,13 @@ using namespace exageostat::common; Verbose Configurations::mVerbosity = Verbose::STANDARD_MODE; bool Configurations::mIsThetaInit = false; +bool Configurations::mHeapAllocated = false; +bool Configurations::mFirstInit = false; Configurations::Configurations() { // Set default values for arguments! - SetComputation(common::EXACT_DENSE); + SetComputation(EXACT_DENSE); SetCoresNumber(1); SetGPUsNumbers(0); SetPGrid(1); @@ -35,50 +37,49 @@ Configurations::Configurations() { SetMaxRank(1); SetIsOOC(false); SetKernelName(""); - SetDimension(common::Dimension2D); + SetDimension(Dimension2D); SetTimeSlot(1); SetProblemSize(0); SetDenseTileSize(0); -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA SetLowTileSize(0); #endif SetBand(0); SetLoggerPath(""); SetIsSynthetic(true); - SetIsCSV(false); vector theta; SetInitialTheta(theta); SetLowerBounds(theta); SetUpperBounds(theta); SetEstimatedTheta(theta); - SetP(1); SetSeed(0); SetLogger(false); SetUnknownObservationsNb(0); - SetMeanSquareError(0.0); SetApproximationMode(1); SetActualObservationsFilePath(""); SetRecoveryFile(""); - SetPrecision(common::DOUBLE); + SetPrecision(DOUBLE); SetIsMSPE(false); SetIsFisher(false); SetIsIDW(false); SetIsMLOEMMOM(false); SetDataPath(""); - SetDistanceMetric(common::EUCLIDEAN_DISTANCE); + SetDistanceMetric(EUCLIDEAN_DISTANCE); SetAccuracy(0); + SetIsNonGaussian(false); + mIsThetaInit = false; } - -void Configurations::InitializeArguments(const int &aArgC, char **apArgV) { +void Configurations::InitializeArguments(const int &aArgC, char **apArgV, const bool &aEnableR) { this->mArgC = aArgC; this->mpArgV = apArgV; + mHeapAllocated = aEnableR; + // Get the example name string example_name = apArgV[0]; // Remove the './' example_name.erase(0, 2); - LOGGER("Running " + example_name) string argument; string argument_name; string argument_value; @@ -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,27 @@ void Configurations::InitializeArguments(const int &aArgC, char **apArgV) { throw domain_error("You need to set the Kernel, before starting"); } - if (GetLogger()) { - //initlog - InitLog(); + size_t found = GetKernelName().find("NonGaussian"); + // Check if the substring was found + if (found != std::string::npos) { + SetIsNonGaussian(true); } - 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,19 +265,15 @@ 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); } } } 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 +300,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 +324,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 +360,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 +398,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 +498,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) { @@ -589,25 +596,15 @@ int Configurations::CheckUnknownObservationsValue(const string &aValue) { } void Configurations::ParseDistanceMetric(const std::string &aDistanceMetric) { - if (aDistanceMetric == "eg" || aDistanceMetric == "EG") { + if (aDistanceMetric == "eg" || aDistanceMetric == "EG" || aDistanceMetric == "euclidean") { SetDistanceMetric(EUCLIDEAN_DISTANCE); - } else if (aDistanceMetric == "gcd" || aDistanceMetric == "GCD") { + } else if (aDistanceMetric == "gcd" || aDistanceMetric == "GCD" || aDistanceMetric == "great_circle") { SetDistanceMetric(GREAT_CIRCLE_DISTANCE); } else { throw range_error("Invalid value. Please use eg or gcd values only."); } } -void Configurations::InitLog() { - try { - SetFileLogPath(fopen(GetFileLogName().c_str(), "w+")); - } - catch (std::exception &e) { - SetFileLogPath(fopen("log_file", "w+")); - } - fprintf(GetFileLogPath(), "\t\tlog file is generated by ExaGeoStat application\n"); - fprintf(GetFileLogPath(), "\t\t============================================\n"); -} void Configurations::InitTheta(vector &aTheta, const int &size) { @@ -628,13 +625,14 @@ void Configurations::PrintSummary() { Verbose temp = this->GetVerbosity(); mVerbosity = STANDARD_MODE; - if (!mIsPrinted) { + + if (!mFirstInit) { LOGGER("********************SUMMARY**********************") if (this->GetIsSynthetic()) { - LOGGER("#Synthetic Dataset") + LOGGER("#Synthetic Data generation") } else { - LOGGER("#Real Dataset") + LOGGER("#Real Data loader") } LOGGER("#Number of Locations: " << this->GetProblemSize()) LOGGER("#Threads per node: " << this->GetCoresNumber()) @@ -647,7 +645,7 @@ void Configurations::PrintSummary() { LOGGER("#Precision: Single/Double") } LOGGER("#Dense Tile Size: " << this->GetDenseTileSize()) -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA LOGGER("#Low Tile Size: " << this->GetLowTileSize()) #endif if (this->GetComputation() == TILE_LOW_RANK) { @@ -657,16 +655,46 @@ void Configurations::PrintSummary() { } 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("*************************************************") - mIsPrinted = true; + mVerbosity = temp; + mFirstInit = true; } - mVerbosity = temp; } -bool Configurations::mIsPrinted = false; - int Configurations::CalculateZObsNumber() { - return this->GetProblemSize() - GetUnknownObservationsNb(); -} \ No newline at end of file + return (this->GetProblemSize()) - this->GetUnknownObservationsNb(); +} + +Configurations::~Configurations() { + + if (mHeapAllocated) { + for (size_t i = 0; i < this->mArgC; ++i) { + delete[] this->mpArgV[i]; // Delete each string + } + delete[] this->mpArgV; // Delete the array of pointers + } + this->mpArgV = nullptr; + mFirstInit = false; +} + +void Configurations::SetTolerance(double aTolerance) { + mDictionary["Tolerance"] = pow(10, -1 * aTolerance); +} diff --git a/src/data-generators/CMakeLists.txt b/src/data-generators/CMakeLists.txt index 67966b9e..e5e32bdb 100644 --- a/src/data-generators/CMakeLists.txt +++ b/src/data-generators/CMakeLists.txt @@ -1,14 +1,14 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt # @brief CMake configuration file for Data Generators module -# @version 1.0.0 +# @version 1.1.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..dd4bec8b 100644 --- a/src/data-generators/DataGenerator.cpp +++ b/src/data-generators/DataGenerator.cpp @@ -1,40 +1,40 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file DataGenerator.cpp * @brief Implementation of DataGenerator class - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy - * @date 2023-02-14 + * @date 2024-02-04 **/ #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; +using namespace exageostat::results; template -std::unique_ptr> DataGenerator::CreateGenerator(Configurations &apConfigurations) { +std::unique_ptr> DataGenerator::CreateGenerator(configurations::Configurations &apConfigurations) { + //// TODO: In case of other file support, Then we can create another layer for the factory creation depending on the file size. // Check the used Data generation method, whether it's synthetic or real. - mIsSynthetic = apConfigurations.GetIsSynthetic(); - mIsCSV = apConfigurations.GetIsCSV(); - results::Results::GetInstance()->SetIsSynthetic(mIsSynthetic); + aDataSourceType = apConfigurations.GetIsSynthetic() ? SYNTHETIC : CSV_FILE; // Return DataGenerator unique pointer of Synthetic type - if (mIsSynthetic) { + if (aDataSourceType == SYNTHETIC) { + Results::GetInstance()->SetIsSynthetic(true); return std::unique_ptr>(SyntheticGenerator::GetInstance()); - } else if (mIsCSV) { - return std::unique_ptr>(CSVDataGenerator::GetInstance()); + } else if (aDataSourceType == CSV_FILE) { + Results::GetInstance()->SetIsSynthetic(false); + return std::unique_ptr>(CSVLoader::GetInstance()); } else { throw std::runtime_error("Data Loading for this file type is unsupported for now"); } @@ -43,15 +43,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 = SYNTHETIC; diff --git a/src/data-generators/LocationGenerator.cpp b/src/data-generators/LocationGenerator.cpp new file mode 100644 index 00000000..5703e04b --- /dev/null +++ b/src/data-generators/LocationGenerator.cpp @@ -0,0 +1,124 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file LocationGenerator.cpp + * @brief Generates and manages spatial locations for ExaGeoStat. + * @version 1.1.0 + * @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..bca0dfdb 100644 --- a/src/data-generators/concrete/CMakeLists.txt +++ b/src/data-generators/concrete/CMakeLists.txt @@ -1,11 +1,11 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt # @brief CMake configuration file for the Synthetic Generator module -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-02-14 @@ -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/CSVDataGenerator.cpp b/src/data-generators/concrete/CSVDataGenerator.cpp deleted file mode 100644 index 820a9fab..00000000 --- a/src/data-generators/concrete/CSVDataGenerator.cpp +++ /dev/null @@ -1,201 +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.cpp - * @brief Implementation of the CSVDataGenerator class - * @version 1.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @date 2023-02-14 -**/ - -#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; - -template -CSVDataGenerator *CSVDataGenerator::GetInstance() { - - if (mpInstance == nullptr) { - mpInstance = new CSVDataGenerator(); - } - 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) { - - //Check if the user entered a valid path for the CSV file. - if (aConfigurations.GetDataPath().empty()) { - throw runtime_error("Please enter the path to data file."); - } - - string data_path = aConfigurations.GetDataPath(); - Dimension dimension = aConfigurations.GetDimension(); - int p = aConfigurations.GetP(); - ifstream file; - - file.open(data_path, ios::in); - - //Throw error if unable to open file. - if (!file.is_open()) { - throw runtime_error("Cannot read locations file: " + data_path); - } - - //Keep track of number of lines. - int index = 0; - string line; - //Loop through the lines - while (getline(file, line)) { - istringstream iss(line); - string token; - - // Split each line into tokens using ',' as the delimiter - if (getline(iss, token, ',')) { - aXLocations.push_back(stod(token)); - } - if (getline(iss, token, ',')) { - 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 (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 (getline(iss, token, ',')) { - aMeasurementsMatrix.push_back(stod(token)); - } else { - throw runtime_error( - "The data P in the provided file isn't consistent with the Kernel's P."); - } - } - if (p == 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)); - } - if (getline(iss, token, ',')) { - aMeasurementsMatrix.push_back(stod(token)); - } else { - throw runtime_error( - "The data P in the provided file isn't consistent with the Kernel's P."); - } - } - } else { - aZLocations.push_back(stod(token)); - } - } - - if (getline(iss, token, ',')) { - 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 (getline(iss, token, ',')) { - aMeasurementsMatrix.push_back(stod(token)); - } else { - throw runtime_error( - "The data P in the provided file isn't consistent with the Kernel's P."); - } - } - if (p == 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)); - } - if (getline(iss, token, ',')) { - aMeasurementsMatrix.push_back(stod(token)); - } else { - throw runtime_error( - "The data P in the provided file isn't consistent with the Kernel's P."); - } - } - } else { - throw runtime_error( - "The data dimensions in the provided file isn't consistent with the dimensions input."); - } - } else if (dimension != Dimension2D) { - throw runtime_error("The data dimensions in the provided file isn't consistent with the dimensions input."); - } - index++; - } - - //problem size is equal to the number of the CSV lines * P / aConfigurations.GetTimeSlot(). - aConfigurations.SetProblemSize(index * p / aConfigurations.GetTimeSlot()); - - file.close(); -} - -template -void CSVDataGenerator::ReleaseInstance() { - if (mpInstance != nullptr) { - mpInstance = nullptr; - } -} - -template CSVDataGenerator *CSVDataGenerator::mpInstance = nullptr; diff --git a/src/data-generators/concrete/SyntheticGenerator.cpp b/src/data-generators/concrete/SyntheticGenerator.cpp index 2f21aa6a..85cfa7ec 100644 --- a/src/data-generators/concrete/SyntheticGenerator.cpp +++ b/src/data-generators/concrete/SyntheticGenerator.cpp @@ -1,27 +1,25 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file SyntheticGenerator.cpp * @brief Implementation of the SyntheticGenerator class - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-02-14 + * @date 2024-02-04 **/ #include +#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; +using namespace exageostat::results; template SyntheticGenerator *SyntheticGenerator::GetInstance() { @@ -33,204 +31,63 @@ SyntheticGenerator *SyntheticGenerator::GetInstance() { } template -ExaGeoStatData *SyntheticGenerator::CreateData(exageostat::configurations::Configurations &aConfigurations, - const exageostat::hardware::ExaGeoStatHardware &aHardware, - exageostat::kernels::Kernel &aKernel) { +std::unique_ptr> +SyntheticGenerator::CreateData(Configurations &aConfigurations, + exageostat::kernels::Kernel &aKernel) { - auto *data = new ExaGeoStatData(aConfigurations.GetProblemSize(), aConfigurations.GetDimension()); + 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()); - - aConfigurations.SetP(aKernel.GetPValue()); + auto *locations = new dataunits::Locations(n, aConfigurations.GetDimension()); 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, data, aKernel); if (aConfigurations.GetLogger()) { VERBOSE("Writing generated data to the disk (Synthetic Dataset Generation Phase) .....") -#ifdef CHAMELEON_USE_MPI +#ifdef USE_MPI auto pMatrix = new T[aConfigurations.GetProblemSize()]; std::string path = aConfigurations.GetLoggerPath(); 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, - DESCRIPTOR_Z).chameleon_desc->mat), - aConfigurations.GetProblemSize(), aConfigurations.GetP(), path, - *data->GetLocations()); + DESCRIPTOR_Z).chameleon_desc, + pMatrix, aConfigurations.GetProblemSize()); + if (helpers::CommunicatorMPI::GetInstance()->GetRank() == 0) { + dataLoader::csv::CSVLoader::GetInstance()->WriteData( + *((T *) data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_Z).chameleon_desc->mat), + aConfigurations.GetProblemSize(), parameters_number, path, + *data->GetLocations()); } delete[] pMatrix; #else std::string path = aConfigurations.GetLoggerPath(); - DiskWriter::WriteVectorsToDisk(*((T *) data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + dataLoader::csv::CSVLoader::GetInstance()->WriteData(*((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()->SetIsLogger(aConfigurations.GetLogger()); - results::Results::GetInstance()->SetLoggerPath(aConfigurations.GetLoggerPath()); + Results::GetInstance()->SetGeneratedLocationsNumber(n); + Results::GetInstance()->SetIsLogger(aConfigurations.GetLogger()); + 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..03a54e86 --- /dev/null +++ b/src/data-loader/CMakeLists.txt @@ -0,0 +1,20 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @brief CMake configuration file for Data loader module +# @version 1.1.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..fb7ca2fd --- /dev/null +++ b/src/data-loader/DataLoader.cpp @@ -0,0 +1,67 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file SyntheticGenerator.cpp + * @brief Implementation of the SyntheticGenerator class + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2023-02-14 +**/ + +#include + +using namespace std; + +using namespace exageostat::dataLoader; +using namespace exageostat::common; +using namespace exageostat::results; + +template +std::unique_ptr> +DataLoader::CreateData(configurations::Configurations &aConfigurations, exageostat::kernels::Kernel &aKernel) { + + // create vectors that will be populated with read data. + vector measurements_vector; + vector x_locations; + vector y_locations; + vector z_locations; + + aKernel.SetPValue(aConfigurations.GetTimeSlot()); + int p = aKernel.GetVariablesNumber(); + + //Read the data out of the CSV file. + this->ReadData(aConfigurations, measurements_vector, x_locations, y_locations, z_locations, p); + + //create data object + auto data = std::make_unique>(aConfigurations.GetProblemSize() / p, + aConfigurations.GetDimension()); + + //Initialize the descriptors. + auto linear_algebra_solver = linearAlgebra::LinearAlgebraFactory::CreateLinearAlgebraSolver(EXACT_DENSE); + linear_algebra_solver->InitiateDescriptors(aConfigurations, *data->GetDescriptorData(), p); + linear_algebra_solver->ExaGeoStatLaSetTile(EXAGEOSTAT_UPPER_LOWER, 0, 0, + data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_C).chameleon_desc); + //populate data object with read data + for (int i = 0; i < aConfigurations.GetProblemSize() / p; i++) { + data->GetLocations()->GetLocationX()[i] = x_locations[i]; + data->GetLocations()->GetLocationY()[i] = y_locations[i]; + if (aConfigurations.GetDimension() != Dimension2D) { + data->GetLocations()->GetLocationZ()[i] = z_locations[i]; + } + } + for (int i = 0; i < aConfigurations.GetProblemSize(); i++) { + ((T *) data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_Z).chameleon_desc->mat)[i] = measurements_vector[i]; + } + + Results::GetInstance()->SetGeneratedLocationsNumber(aConfigurations.GetProblemSize() / p); + Results::GetInstance()->SetIsLogger(aConfigurations.GetLogger()); + Results::GetInstance()->SetLoggerPath(aConfigurations.GetLoggerPath()); + + return data; +} diff --git a/src/data-loader/concrete/CMakeLists.txt b/src/data-loader/concrete/CMakeLists.txt new file mode 100644 index 00000000..88180c80 --- /dev/null +++ b/src/data-loader/concrete/CMakeLists.txt @@ -0,0 +1,17 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @brief CMake configuration file for the data loader module +# @version 1.1.0 +# @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-loader/concrete/CSVLoader.cpp b/src/data-loader/concrete/CSVLoader.cpp new file mode 100644 index 00000000..bfd153cd --- /dev/null +++ b/src/data-loader/concrete/CSVLoader.cpp @@ -0,0 +1,241 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file CSVDataGenerator.cpp + * @brief Implementation of the CSVDataGenerator class + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2023-02-14 +**/ + +#include + +#include + +using namespace std; + +using namespace exageostat::configurations; +using namespace exageostat::common; +using namespace exageostat::dataLoader::csv; + +template +CSVLoader *CSVLoader::GetInstance() { + + if (mpInstance == nullptr) { + mpInstance = new CSVLoader(); + } + return mpInstance; +} + +template +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()) { + throw runtime_error("Please enter the path to data file."); + } + + string data_path = aConfigurations.GetDataPath(); + Dimension dimension = aConfigurations.GetDimension(); + ifstream file; + + file.open(data_path, ios::in); + + //Throw error if unable to open file. + if (!file.is_open()) { + throw runtime_error("Cannot read locations file: " + data_path); + } + + //Keep track of number of lines. + int index = 0; + string line; + //Loop through the lines + while (getline(file, line)) { + istringstream iss(line); + string token; + + // Split each line into tokens using ',' as the delimiter + if (getline(iss, token, ',')) { + aXLocations.push_back(stod(token)); + } + if (getline(iss, token, ',')) { + aYLocations.push_back(stod(token)); + } + if (getline(iss, token, ',')) { + //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 (aP == 2) { + if (getline(iss, token, ',')) { + aMeasurementsMatrix.push_back(stod(token)); + } else { + throw runtime_error( + "The data P in the provided file isn't consistent with the Kernel's P."); + } + } + 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)); + } + if (getline(iss, token, ',')) { + aMeasurementsMatrix.push_back(stod(token)); + } else { + throw runtime_error( + "The data P in the provided file isn't consistent with the Kernel's P."); + } + } + } else { + aZLocations.push_back(stod(token)); + } + } + + if (getline(iss, token, ',')) { + 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 (aP == 2) { + if (getline(iss, token, ',')) { + aMeasurementsMatrix.push_back(stod(token)); + } else { + throw runtime_error( + "The data P in the provided file isn't consistent with the Kernel's P."); + } + } + 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)); + } + if (getline(iss, token, ',')) { + aMeasurementsMatrix.push_back(stod(token)); + } else { + throw runtime_error( + "The data P in the provided file isn't consistent with the Kernel's P."); + } + } + } else { + throw runtime_error( + "The data dimensions in the provided file isn't consistent with the dimensions input."); + } + } else if (dimension != Dimension2D) { + throw runtime_error("The data dimensions in the provided file isn't consistent with the dimensions input."); + } + index++; + } + + //problem size is equal to the number of the CSV lines * P / aConfigurations.GetTimeSlot(). + aConfigurations.SetProblemSize(index * aP / aConfigurations.GetTimeSlot()); + + file.close(); + LOGGER("\tData is read from " << data_path << " successfully.") +} + +template +void CSVLoader::WriteData(const T &aMatrixPointer, const int &aProblemSize, const int &aP, std::string &aLoggerPath, + dataunits::Locations &aLocations) { + // Determine the path for storing the output files + if (aLoggerPath.empty()) { + aLoggerPath = LOG_PATH; + } else { + if (aLoggerPath.back() == '/') { + aLoggerPath += "synthetic_ds"; + } else { + aLoggerPath += "/synthetic_ds"; + } + } + // Create a new directory if it does not already exist + bool created; + if (!filesystem::exists(aLoggerPath)) { + try { + created = filesystem::create_directories(aLoggerPath); + } catch (const filesystem::filesystem_error &e) { + throw runtime_error("Error creating directory: " + aLoggerPath); + } + } else { + created = true; + } + + // Check if the directory was created successfully + if (!created) { + throw runtime_error("Error creating directory: " + aLoggerPath); + } + + // Determine the names of the output files + size_t i = 1, j; + std::ofstream p_file_synthetic, p_file_log; + std::string n_file_synthetic = aLoggerPath + "/SYN_" + std::to_string(aProblemSize / aP) + "_"; + std::string n_file_log = aLoggerPath + "/log_" + std::to_string(aProblemSize / aP) + "_"; + std::string temp = n_file_log + std::to_string(i); + + // Check if log file exists + while (std::filesystem::exists(temp)) { + i++; + temp = n_file_log + std::to_string(i); + } + + n_file_synthetic += std::to_string(i); + p_file_synthetic.open(n_file_synthetic); + + for (j = 0, i = 0; i < aProblemSize / aP; i++) { + if (aLocations.GetLocationZ() == nullptr) { + //2 Dimensions + if (aP == 1) { + p_file_synthetic << std::setprecision(15) << aLocations.GetLocationX()[i] << ',' + << aLocations.GetLocationY()[i] << "," << std::setprecision(15) << (&aMatrixPointer)[i] + << '\n'; + } else if (aP == 2) { + p_file_synthetic << std::setprecision(15) << aLocations.GetLocationX()[i] << ',' + << aLocations.GetLocationY()[i] << "," << std::setprecision(15) << (&aMatrixPointer)[j] + << "," + << std::setprecision(15) << (&aMatrixPointer)[j + 1] << '\n'; + j += 2; + } else if (aP == 3) { + p_file_synthetic << std::setprecision(15) << aLocations.GetLocationX()[i] << ',' + << aLocations.GetLocationY()[i] << "," << std::setprecision(15) << (&aMatrixPointer)[j] + << "," + << std::setprecision(15) << (&aMatrixPointer)[j + 1] << "," << std::setprecision(15) + << (&aMatrixPointer)[j + 2] << '\n'; + j += 3; + } + } else { + //3 Dimensions + if (aP == 1) { + p_file_synthetic << std::setprecision(15) << aLocations.GetLocationX()[i] << ',' + << aLocations.GetLocationY()[i] << ',' << aLocations.GetLocationZ()[i] << "," + << std::setprecision(15) << (&aMatrixPointer)[i] << '\n'; + } else if (aP == 2) { + p_file_synthetic << std::setprecision(15) << aLocations.GetLocationX()[i] << ',' + << aLocations.GetLocationY()[i] << ',' << aLocations.GetLocationZ()[i] << "," + << std::setprecision(15) << (&aMatrixPointer)[j] << std::setprecision(15) << "," + << (&aMatrixPointer)[j + 1] << '\n'; + j += 2; + } else if (aP == 3) { + p_file_synthetic << std::setprecision(15) << aLocations.GetLocationX()[i] << ',' + << aLocations.GetLocationY()[i] << ',' << aLocations.GetLocationZ()[i] << "," + << std::setprecision(15) << (&aMatrixPointer)[j] << "," << std::setprecision(15) + << (&aMatrixPointer)[j + 1] << "," << std::setprecision(15) << (&aMatrixPointer)[j + 2] + << '\n'; + j += 3; + } + } + } + p_file_synthetic.close(); +} + +template +void CSVLoader::ReleaseInstance() { + if (mpInstance != nullptr) { + mpInstance = nullptr; + } +} + +template CSVLoader *CSVLoader::mpInstance = nullptr; diff --git a/src/data-units/CMakeLists.txt b/src/data-units/CMakeLists.txt index d05e9096..85e48392 100644 --- a/src/data-units/CMakeLists.txt +++ b/src/data-units/CMakeLists.txt @@ -1,10 +1,10 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-02-27 diff --git a/src/data-units/DescriptorData.cpp b/src/data-units/DescriptorData.cpp index b64f9d03..eff728d3 100644 --- a/src/data-units/DescriptorData.cpp +++ b/src/data-units/DescriptorData.cpp @@ -1,18 +1,17 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file DescriptorData.cpp * @brief Contains the definition of the DescriptorData class. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-07-18 **/ -#include #include using namespace exageostat::dataunits; @@ -28,8 +27,8 @@ DescriptorData::~DescriptorData() { for (const auto &pair: this->mDictionary) { 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 + exaGeoStatDescriptor.DestroyDescriptor(CHAMELEON_DESCRIPTOR, pair.second); +#ifdef USE_HICMA // Since there are converted descriptors from Chameleon to Hicma, which have the same memory address. // So, by deleting the owner which is Chameleon, no need to delete hicma. Therefore, we remove the row of that descriptor. std::string converted_chameleon = key.substr(0, key.length() - chameleon.length()); @@ -41,7 +40,7 @@ DescriptorData::~DescriptorData() { } #endif } else if (key.find("HICMA") != std::string::npos && pair.second != nullptr) { - exaGeoStatDescriptor.DestroyDescriptor(common::HICMA_DESCRIPTOR, pair.second); + exaGeoStatDescriptor.DestroyDescriptor(HICMA_DESCRIPTOR, pair.second); } } this->mDictionary.clear(); @@ -70,35 +69,19 @@ void *DescriptorData::GetRequest() { return this->mpRequest; } -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA template -HICMA_desc_t *DescriptorData::ConvertChameleonToHicma(CHAM_desc_t *apChameleonDesc) { +HICMA_desc_t * +DescriptorData::ConvertChameleonToHicma(CHAM_desc_t *apChameleonDesc, const DescriptorName &aDescriptorName) { - // Create a new HICMA descriptor - auto *hicma_desc = new HICMA_desc_t; + this->SetDescriptor(HICMA_DESCRIPTOR, aDescriptorName, apChameleonDesc->ooc, apChameleonDesc->mat, + (FloatPoint) (apChameleonDesc->dtyp), apChameleonDesc->mb, apChameleonDesc->nb, + apChameleonDesc->bsiz, apChameleonDesc->lm, apChameleonDesc->ln, apChameleonDesc->i, + apChameleonDesc->j, apChameleonDesc->m, apChameleonDesc->n, apChameleonDesc->p, + apChameleonDesc->q, apChameleonDesc->ooc, true); - // Set function pointers in HICMA descriptor - hicma_desc->get_blkaddr = hicma_getaddr_ccrb; - hicma_desc->get_blkldd = hicma_getblkldd_ccrb; - hicma_desc->get_rankof = hicma_getrankof_2d; - - // Set sizes and offsets for memory copy - size_t hicma_desc_total_size = 184; - size_t chameleon_desc_total_size = 200; - // Size of the common members between Hicma_desc and Chameleon_desc - size_t common_total_size = 3 * sizeof(size_t) + 30 * sizeof(int); - // Skip the size of function pointers. - size_t hicma_offset = hicma_desc_total_size - (common_total_size + sizeof(void *)); - size_t chameleon_offset = chameleon_desc_total_size - (common_total_size + sizeof(void *)); - - // Copy common data from CHAMELEON descriptor to HICMA descriptor - memcpy(((char *) hicma_desc) + hicma_offset, ((char *) apChameleonDesc) + chameleon_offset, common_total_size); - // Set additional data in HICMA descriptor - hicma_desc->mat = apChameleonDesc->mat; - hicma_desc->schedopt = apChameleonDesc->schedopt; - - return hicma_desc; + return this->GetDescriptor(HICMA_DESCRIPTOR, aDescriptorName).hicma_desc; } #endif @@ -115,7 +98,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"]; @@ -126,13 +109,14 @@ DescriptorData::GetDescriptor(const DescriptorType &aDescriptorType, const De } else if (this->mDictionary.find(GetDescriptorName(aDescriptorName) + "_CHAMELEON") != this->mDictionary.end()) { descriptor.hicma_desc = this->ConvertChameleonToHicma( - (CHAM_desc_t *) this->mDictionary[GetDescriptorName(aDescriptorName) + "_CHAMELEON"]); + (CHAM_desc_t *) this->mDictionary[GetDescriptorName(aDescriptorName) + "_CHAMELEON"], + aDescriptorName); this->mDictionary[GetDescriptorName(aDescriptorName) + "_CHAM_HIC"] = descriptor.hicma_desc; } else { 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; @@ -140,10 +124,10 @@ DescriptorData::GetDescriptor(const DescriptorType &aDescriptorType, const De template void DescriptorData::SetDescriptor(const DescriptorType &aDescriptorType, const DescriptorName &aDescriptorName, - const bool &aIsOOC, void *apMatrix, const common::FloatPoint &aFloatPoint, + const bool &aIsOOC, void *apMatrix, const FloatPoint &aFloatPoint, const int &aMB, const int &aNB, const int &aSize, const int &aLM, const int &aLN, const int &aI, const int &aJ, const int &aM, const int &aN, const int &aP, - const int &aQ) { + const int &aQ, const bool &aValidOOC, const bool &aConverted) { void *descriptor; std::string type; @@ -151,32 +135,37 @@ 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 } + if (aConverted) { + type = "_CHAM_HIC"; + } this->mDictionary[GetDescriptorName(aDescriptorName) + type] = descriptor; + } template -T *DescriptorData::GetDescriptorMatrix(const common::DescriptorType &aDescriptorType, void *apDesc) { - if (aDescriptorType == common::CHAMELEON_DESCRIPTOR) { - return (T *) ((CHAM_desc_t *) apDesc)->mat; +T * +DescriptorData::GetDescriptorMatrix(const DescriptorType &aDescriptorType, const DescriptorName &aDescriptorName) { + if (aDescriptorType == CHAMELEON_DESCRIPTOR) { + return (T *) (this->GetDescriptor(CHAMELEON_DESCRIPTOR, aDescriptorName).chameleon_desc)->mat; } else { -#ifdef EXAGEOSTAT_USE_HICMA - return (T *) ((HICMA_desc_t *) apDesc)->mat; +#ifdef USE_HICMA + return (T *) (this->GetDescriptor(HICMA_DESCRIPTOR, aDescriptorName).hicma_desc)->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 +278,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/ExaGeoStatData.cpp b/src/data-units/ExaGeoStatData.cpp index f64078e0..a1c912a5 100644 --- a/src/data-units/ExaGeoStatData.cpp +++ b/src/data-units/ExaGeoStatData.cpp @@ -1,18 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file ExaGeoStatData.cpp * @brief Contains the implementation of the ExaGeoStatData class. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-07-21 + * @date 2024-02-04 **/ #include +#include using namespace exageostat::dataunits; using namespace exageostat::common; @@ -23,6 +24,13 @@ ExaGeoStatData::ExaGeoStatData(const int &aSize, const Dimension &aDimension) this->mpDescriptorData = new DescriptorData(); } +template +ExaGeoStatData::ExaGeoStatData(const int &aSize, const std::string &aDimension) { + + this->mpLocations = new Locations(aSize, GetInputDimension(aDimension)); + this->mpDescriptorData = new DescriptorData(); +} + template ExaGeoStatData::~ExaGeoStatData() { delete this->mpLocations; @@ -70,7 +78,7 @@ void ExaGeoStatData::CalculateMedianLocations(const std::string &aKernelName, T x_min = this->mpLocations->GetLocationX()[0], x_max = this->mpLocations->GetLocationX()[0], y_min = this->mpLocations->GetLocationY()[0], y_max = this->mpLocations->GetLocationY()[0], z_min, z_max; - if (this->mpLocations->GetDimension() != common::Dimension2D) { + if (this->mpLocations->GetDimension() != Dimension2D) { z_min = this->mpLocations->GetLocationZ()[0]; z_max = this->mpLocations->GetLocationZ()[0]; } @@ -84,7 +92,7 @@ void ExaGeoStatData::CalculateMedianLocations(const std::string &aKernelName, y_min = (y < y_min) ? y : y_min; y_max = (y > y_max) ? y : y_max; - if (this->mpLocations->GetDimension() != common::Dimension2D) { + if (this->mpLocations->GetDimension() != Dimension2D) { T z = this->mpLocations->GetLocationX()[i]; z_min = (z < z_min) ? z : z_min; z_max = (z > z_max) ? z : z_max; @@ -93,13 +101,13 @@ void ExaGeoStatData::CalculateMedianLocations(const std::string &aKernelName, aLocations.GetLocationX()[0] = x_min + (x_max - x_min) / 2; aLocations.GetLocationY()[0] = y_min + (y_max - y_min) / 2; - if (this->mpLocations->GetDimension() != common::Dimension2D) { + if (this->mpLocations->GetDimension() != Dimension2D) { aLocations.GetLocationZ()[0] = z_min + (z_max - z_min) / 2; } } else { aLocations.GetLocationX()[0] = 0.5; aLocations.GetLocationY()[0] = 0.5; - if (this->mpLocations->GetDimension() != common::Dimension2D) { + if (this->mpLocations->GetDimension() != Dimension2D) { aLocations.GetLocationY()[0] = 0.5; } } diff --git a/src/data-units/Locations.cpp b/src/data-units/Locations.cpp index a2605ee3..abe0572c 100644 --- a/src/data-units/Locations.cpp +++ b/src/data-units/Locations.cpp @@ -1,24 +1,21 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file Locations.cpp * @brief Implementation of the Locations class - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-02-27 **/ -#include #include #include -using namespace std; - using namespace exageostat::dataunits; using namespace exageostat::common; diff --git a/src/data-units/descriptor/CMakeLists.txt b/src/data-units/descriptor/CMakeLists.txt index fd3cff70..352aec33 100644 --- a/src/data-units/descriptor/CMakeLists.txt +++ b/src/data-units/descriptor/CMakeLists.txt @@ -1,10 +1,10 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-08-15 diff --git a/src/data-units/descriptor/ExaGeoStatDescriptor.cpp b/src/data-units/descriptor/ExaGeoStatDescriptor.cpp index 38e104d9..5d6cd730 100644 --- a/src/data-units/descriptor/ExaGeoStatDescriptor.cpp +++ b/src/data-units/descriptor/ExaGeoStatDescriptor.cpp @@ -1,45 +1,46 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file ExaGeoStatDescriptor.cpp * @brief Implementation of creating matrix descriptors used in CHAMELEON and HiCMA libraries. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-07-17 **/ +#include + +#include #include -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA #include #endif -#include - using namespace exageostat::common; 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 +52,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..6bb197d4 100644 --- a/src/data-units/descriptor/concrete/CMakeLists.txt +++ b/src/data-units/descriptor/concrete/CMakeLists.txt @@ -1,10 +1,10 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @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..964215ec 100644 --- a/src/data-units/descriptor/concrete/ChameleonDescriptor.cpp +++ b/src/data-units/descriptor/concrete/ChameleonDescriptor.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file ChameleonDescriptor.cpp * @brief Defines the ChameleonDescriptor class for creating matrix descriptors using the CHAMELEON library. - * @version 1.0.0 + * @version 1.1.0 * @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..9a4e6724 100644 --- a/src/data-units/descriptor/concrete/HicmaDescriptor.cpp +++ b/src/data-units/descriptor/concrete/HicmaDescriptor.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file HicmaDescriptor.cpp * @brief Defines the Hicma Descriptor class for creating matrix descriptors using the HICMA library. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-08-15 @@ -20,9 +20,10 @@ 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/CMakeLists.txt b/src/hardware/CMakeLists.txt index 4d5f98f4..98fc7760 100644 --- a/src/hardware/CMakeLists.txt +++ b/src/hardware/CMakeLists.txt @@ -1,11 +1,11 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt # @brief This file contains the CMake configuration for the configurations directory. -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-08-08 diff --git a/src/hardware/ExaGeoStatHardware.cpp b/src/hardware/ExaGeoStatHardware.cpp index 7419c4dc..3e9f3c18 100644 --- a/src/hardware/ExaGeoStatHardware.cpp +++ b/src/hardware/ExaGeoStatHardware.cpp @@ -1,104 +1,160 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file ExaGeoStatHardware.cpp * @brief Contains the implementation of the ExaGeoStatHardware class. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-08-07 + * @date 2024-02-04 **/ +#ifdef USE_MPI +#include +#endif + #include #include #include #include #include +#include +#include + +using namespace exageostat::common; +using namespace exageostat::results; + +ExaGeoStatHardware::ExaGeoStatHardware(const Computation &aComputation, const int &aCoreNumber, const int &aGpuNumber, + const int &aP, const int &aQ) { + InitHardware(aComputation, aCoreNumber, aGpuNumber, aP, aQ); +} -using namespace exageostat::hardware; +// Constructor for R +ExaGeoStatHardware::ExaGeoStatHardware(const std::string &aComputation, const int &aCoreNumber, const int &aGpuNumber, + const int &aP, const int &aQ) { + InitHardware(GetInputComputation(aComputation), aCoreNumber, aGpuNumber, aP, aQ); +} + +void ExaGeoStatHardware::InitHardware(const Computation &aComputation, const int &aCoreNumber, const int &aGpuNumber, + const int &aP, const int &aQ) { -ExaGeoStatHardware::ExaGeoStatHardware(const common::Computation &aComputation, const int &aCoreNumber, - const int &aGpuNumber) { + SetPGrid(aP); + SetQGrid(aQ); + int tag_width = 31, tag_sep = 40; - this->mComputation = aComputation; - int tag_width = 31, tag_sep = 26; // Init hardware using Chameleon - if (!this->mpChameleonContext) { + if (!mpChameleonContext) { +#ifdef USE_MPI + // Due to a bug in Chameleon if CHAMELEON_user_tag_size is called twice with MPI an error happens due to a static variable in chameleon that doesn't change. + if(!mIsMPIInit){ + CHAMELEON_user_tag_size(tag_width, tag_sep); + mIsMPIInit = true; + } +#else CHAMELEON_user_tag_size(tag_width, tag_sep); +#endif 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) { + // Init hardware using HiCMA + if (aComputation == TILE_LOW_RANK) { +#ifdef USE_HICMA + if (!mpHicmaContext) { +#ifdef USE_MPI + // Due to a bug in HiCMA if HICMA_user_tag_size is called twice with MPI an error happens due to a static variable in HiCMA that doesn't change. + if(!mIsMPIInit){ + HICMA_user_tag_size(tag_width, tag_sep); + mIsMPIInit = true; + } +#else HICMA_user_tag_size(tag_width, tag_sep); +#endif 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(); + exageostat::helpers::CommunicatorMPI::GetInstance()->SetHardwareInitialization(); + LOGGER("** Initialize ExaGeoStat hardware **") } -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 { - CHAMELEON_Finalize() - this->mpChameleonContext = nullptr; +void ExaGeoStatHardware::FinalizeHardware() { + + // finalize hardware using HiCMA +#ifdef USE_HICMA + if (mpHicmaContext) { + HICMA_Finalize(); + mpHicmaContext = nullptr; } - 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 { - HICMA_Finalize(); - this->mpHicmaContext = nullptr; - } #endif + + // finalize hardware using Chameleon + if (mpChameleonContext) { +#if defined(USE_MPI) && defined(USE_HICMA) + // Since already HiCMA do so, then no need to remove empty cache. + starpu_mpi_cache_set(0); +#endif + CHAMELEON_Finalize() + mpChameleonContext = nullptr; } - helpers::CommunicatorMPI::GetInstance()->RemoveHardwareInitialization(); - results::Results::GetInstance()->PrintEndSummary(); + + exageostat::helpers::CommunicatorMPI::GetInstance()->RemoveHardwareInitialization(); } -#ifdef EXAGEOSTAT_USE_HICMA +ExaGeoStatHardware::~ExaGeoStatHardware() { -void *ExaGeoStatHardware::GetHicmaContext() const { - if (!this->mpHicmaContext) { - throw std::runtime_error("Hardware is not initialized!"); - } - return this->mpHicmaContext; + Results::GetInstance()->PrintEndSummary(); + FinalizeHardware(); } -#endif +void *ExaGeoStatHardware::GetHicmaContext() { + if (!mpHicmaContext) { + throw std::runtime_error("HiCMA Hardware is not initialized!"); + } + return mpHicmaContext; +} -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 { - if (aComputation == common::EXACT_DENSE || aComputation == common::DIAGONAL_APPROX) { +void *ExaGeoStatHardware::GetContext(Computation aComputation) { + if (aComputation == EXACT_DENSE || aComputation == DIAGONAL_APPROX) { return GetChameleonContext(); } - if (aComputation == common::TILE_LOW_RANK) { -#ifdef EXAGEOSTAT_USE_HICMA + if (aComputation == TILE_LOW_RANK) { return GetHicmaContext(); -#endif } return nullptr; } + +int ExaGeoStatHardware::GetPGrid() { + return mPGrid; +} + +int ExaGeoStatHardware::GetQGrid() { + return mQGrid; +} + +void ExaGeoStatHardware::SetPGrid(int aP) { + mPGrid = aP; +} + +void ExaGeoStatHardware::SetQGrid(int aQ) { + mQGrid = aQ; +} + +void *ExaGeoStatHardware::mpChameleonContext = nullptr; +void *ExaGeoStatHardware::mpHicmaContext = nullptr; +int ExaGeoStatHardware::mPGrid = 1; +int ExaGeoStatHardware::mQGrid = 1; +bool ExaGeoStatHardware::mIsMPIInit = false; diff --git a/src/helpers/BasselFunction.cpp b/src/helpers/BasselFunction.cpp new file mode 100644 index 00000000..b0b58689 --- /dev/null +++ b/src/helpers/BasselFunction.cpp @@ -0,0 +1,44 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file 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.1.0 + * @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..252858b0 --- /dev/null +++ b/src/helpers/ByteHandler.cpp @@ -0,0 +1,52 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ByteHandler.hpp + * @brief Implementation of byte manipulation functions for ExaGeoStat. + * @version 1.1.0 + * @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..f2f6ef82 100644 --- a/src/helpers/CMakeLists.txt +++ b/src/helpers/CMakeLists.txt @@ -1,18 +1,19 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-06-08 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..0abc6d1c 100644 --- a/src/helpers/CommunicatorMPI.cpp +++ b/src/helpers/CommunicatorMPI.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file CommunicatorMPI.cpp * @brief Defines the CommunicatorMPI class for MPI rank communication. - * @version 1.0.0 + * @version 1.1.0 * @author Sameh Abdulah * @date 2023-11-10 **/ @@ -23,25 +23,24 @@ CommunicatorMPI *CommunicatorMPI::GetInstance() { return mpInstance; } -bool CommunicatorMPI::GetRank() const { - - if(!this->mIsHardwareInitialized){ - return false; - } - else{ - if(CHAMELEON_Comm_rank() == 0){ - return true; - } - return false; +int CommunicatorMPI::GetRank() const { +#ifdef USE_MPI + if (!mIsHardwareInitialized) { + return 0; + } else { + return CHAMELEON_Comm_rank(); } +#else + return 0; +#endif } void CommunicatorMPI::SetHardwareInitialization() { - this->mIsHardwareInitialized = true; + mIsHardwareInitialized = true; } -CommunicatorMPI *CommunicatorMPI::mpInstance = nullptr; - void CommunicatorMPI::RemoveHardwareInitialization() { - this->mIsHardwareInitialized = false; + mIsHardwareInitialized = false; } + +CommunicatorMPI *CommunicatorMPI::mpInstance = nullptr; diff --git a/src/helpers/DiskWriter.cpp b/src/helpers/DiskWriter.cpp deleted file mode 100644 index b168c634..00000000 --- a/src/helpers/DiskWriter.cpp +++ /dev/null @@ -1,114 +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 DiskWriter.cpp - * @brief Contains the implementation of the DiskWriter class for writing data to disk. - * @version 1.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @date 2023-06-08 -**/ - -#include -#include -#include - -#include -using namespace std; - -using namespace exageostat::helpers; -using namespace exageostat::dataunits; - -template -void DiskWriter::WriteVectorsToDisk(const T &aMatrixPointer, const int &aProblemSize, const int &aP, - std::string &aLoggerPath, Locations &aLocations) { - - // Determine the path for storing the output files - if (aLoggerPath.empty()) { - aLoggerPath = LOG_PATH; - } else { - if (aLoggerPath.back() == '/') { - aLoggerPath += "synthetic_ds"; - } else { - aLoggerPath += "/synthetic_ds"; - } - } - // Create a new directory if it does not already exist - bool created; - if (!filesystem::exists(aLoggerPath)) { - try { - created = filesystem::create_directories(aLoggerPath); - } catch (const filesystem::filesystem_error &e) { - throw runtime_error("Error creating directory: " + aLoggerPath); - } - } else { - created = true; - } - - // Check if the directory was created successfully - if (!created) { - throw runtime_error("Error creating directory: " + aLoggerPath); - } - - // Determine the names of the output files - size_t i = 1, j; - std::ofstream p_file_synthetic, p_file_log; - std::string n_file_synthetic = aLoggerPath + "/SYN_" + std::to_string(aProblemSize / aP) + "_"; - std::string n_file_log = aLoggerPath + "/log_" + std::to_string(aProblemSize / aP) + "_"; - std::string temp = n_file_log + std::to_string(i); - - // Check if log file exists - while (std::filesystem::exists(temp)) { - i++; - temp = n_file_log + std::to_string(i); - } - - n_file_synthetic += std::to_string(i); - p_file_synthetic.open(n_file_synthetic); - - for (j = 0, i = 0; i < aProblemSize / aP; i++) { - if (aLocations.GetLocationZ() == nullptr) { - //2 Dimensions - if (aP == 1) { - p_file_synthetic << std::setprecision(15) << aLocations.GetLocationX()[i] << ',' - << aLocations.GetLocationY()[i] << "," << std::setprecision(15) << (&aMatrixPointer)[i] - << '\n'; - } else if (aP == 2) { - p_file_synthetic << std::setprecision(15) << aLocations.GetLocationX()[i] << ',' - << aLocations.GetLocationY()[i] << "," << std::setprecision(15) << (&aMatrixPointer)[j] << "," - << std::setprecision(15) << (&aMatrixPointer)[j + 1] << '\n'; - j += 2; - } else if (aP == 3) { - p_file_synthetic << std::setprecision(15) << aLocations.GetLocationX()[i] << ',' - << aLocations.GetLocationY()[i] << "," << std::setprecision(15) << (&aMatrixPointer)[j] << "," - << std::setprecision(15) << (&aMatrixPointer)[j + 1] << "," << std::setprecision(15) - << (&aMatrixPointer)[j + 2] << '\n'; - j += 3; - } - } else { - //3 Dimensions - if (aP == 1) { - p_file_synthetic << std::setprecision(15) << aLocations.GetLocationX()[i] << ',' - << aLocations.GetLocationY()[i] << ',' << aLocations.GetLocationZ()[i] << "," - << std::setprecision(15) << (&aMatrixPointer)[i] << '\n'; - } else if (aP == 2) { - p_file_synthetic << std::setprecision(15) << aLocations.GetLocationX()[i] << ',' - << aLocations.GetLocationY()[i] << ',' << aLocations.GetLocationZ()[i] << "," - << std::setprecision(15) << (&aMatrixPointer)[j] << std::setprecision(15) << "," - << (&aMatrixPointer)[j + 1] << '\n'; - j += 2; - } else if (aP == 3) { - p_file_synthetic << std::setprecision(15) << aLocations.GetLocationX()[i] << ',' - << aLocations.GetLocationY()[i] << ',' << aLocations.GetLocationZ()[i] << "," - << std::setprecision(15) << (&aMatrixPointer)[j] << "," << std::setprecision(15) - << (&aMatrixPointer)[j + 1] << "," << std::setprecision(15) << (&aMatrixPointer)[j + 2] - << '\n'; - j += 3; - } - } - } - p_file_synthetic.close(); -} diff --git a/src/helpers/DistanceCalculationHelpers.cpp b/src/helpers/DistanceCalculationHelpers.cpp index 9ca5d61c..65487536 100644 --- a/src/helpers/DistanceCalculationHelpers.cpp +++ b/src/helpers/DistanceCalculationHelpers.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file DistanceCalculationHelpers.cpp * @brief Contains the implementation of the DistanceCalculationHelpers class. - * @version 1.0.0 + * @version 1.1.0 * @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..1c6b67cd 100644 --- a/src/kernels/CMakeLists.txt +++ b/src/kernels/CMakeLists.txt @@ -1,38 +1,22 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt # @brief This file contains the CMake configuration for the kernels directory. -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-04-11 -# Add the Configurations.cpp file to the list of source files. +# Automatically add all kernels in the concrete directory. +file(GLOB ALL_KERNELS ${CMAKE_CURRENT_SOURCE_DIR}/concrete/*.cpp) + +# Add the kernel.cpp file to the list with other kernels. 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..931a9d97 100644 --- a/src/kernels/Kernel.cpp +++ b/src/kernels/Kernel.cpp @@ -1,74 +1,35 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file Kernel.cpp * @brief implementation file for the Kernels class, which contains the main kernel functions. - * @version 1.0.0 + * @version 1.1.0 * @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..1ae4e414 100644 --- a/src/kernels/concrete/BivariateMaternFlexible.cpp +++ b/src/kernels/concrete/BivariateMaternFlexible.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file BivariateMaternFlexible.cpp * @brief Implementation of the BivariateMaternFlexible kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..1a200997 100644 --- a/src/kernels/concrete/BivariateMaternParsimonious.cpp +++ b/src/kernels/concrete/BivariateMaternParsimonious.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file BivariateMaternParsimonious.cpp * @brief Implementation of the BivariateMaternParsimonious kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..06693b34 100644 --- a/src/kernels/concrete/BivariateSpacetimeMaternStationary.cpp +++ b/src/kernels/concrete/BivariateSpacetimeMaternStationary.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file BivariateSpacetimeMaternStationary.cpp * @brief Implementation of the BivariateSpacetimeMaternStationary kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..628a7b6f 100644 --- a/src/kernels/concrete/TrivariateMaternParsimonious.cpp +++ b/src/kernels/concrete/TrivariateMaternParsimonious.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file TrivariateMaternParsimonious.cpp * @brief Implementation of the BivariateMaternParsimonious kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..1507d6ca 100644 --- a/src/kernels/concrete/UnivariateExpNonGaussian.cpp +++ b/src/kernels/concrete/UnivariateExpNonGaussian.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateExpNonGaussian.cpp * @brief Implementation of the UnivariateExpNonGaussian kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..6ebaf025 100644 --- a/src/kernels/concrete/UnivariateMaternDbeta.cpp +++ b/src/kernels/concrete/UnivariateMaternDbeta.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDbeta.cpp * @brief Implementation of the UnivariateMaternDbeta kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..36ae025b 100644 --- a/src/kernels/concrete/UnivariateMaternDdbetaBeta.cpp +++ b/src/kernels/concrete/UnivariateMaternDdbetaBeta.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDdbetaBeta.cpp * @brief Implementation of the UnivariateMaternDdbetaBeta kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..955ae083 100644 --- a/src/kernels/concrete/UnivariateMaternDdbetaNu.cpp +++ b/src/kernels/concrete/UnivariateMaternDdbetaNu.cpp @@ -1,19 +1,18 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDdbetaNu.cpp * @brief Implementation of the UnivariateMaternDdbetaNu kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..2869e0fb 100644 --- a/src/kernels/concrete/UnivariateMaternDdnuNu.cpp +++ b/src/kernels/concrete/UnivariateMaternDdnuNu.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDdnuNu.cpp * @brief Implementation of the UnivariateMaternDdnuNu kernel. - * @version 1.0.0 + * @version 1.1.0 * @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,23 @@ 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], - expr))); + 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]) * - (pow(expr, aLocalTheta[2]) * - log(expr) * - this->CalculateDerivativeBesselNu( - aLocalTheta[2], - expr) + - pow(expr, aLocalTheta[2]) * - this->CalculateSecondDerivativeBesselNu( - aLocalTheta[2], - expr))); + BasselFunction::CalculateDerivativeBesselNu(aLocalTheta[2], expr) + + 1 / tgamma(aLocalTheta[2]) * + (pow(expr, aLocalTheta[2]) * + log(expr) * + BasselFunction::CalculateDerivativeBesselNu( + aLocalTheta[2], + expr) + + pow(expr, aLocalTheta[2]) * + 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..600c8c5f 100644 --- a/src/kernels/concrete/UnivariateMaternDdsigmaSquare.cpp +++ b/src/kernels/concrete/UnivariateMaternDdsigmaSquare.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDdsigmaSquare.cpp * @brief Implementation of the UnivariateMaternDdsigmaSquare kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..2111d1d0 100644 --- a/src/kernels/concrete/UnivariateMaternDdsigmaSquareBeta.cpp +++ b/src/kernels/concrete/UnivariateMaternDdsigmaSquareBeta.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDdsigmaSquareBeta.cpp * @brief Implementation of the UnivariateMaternDdsigmaSquareBeta kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..20f2e7de 100644 --- a/src/kernels/concrete/UnivariateMaternDdsigmaSquareNu.cpp +++ b/src/kernels/concrete/UnivariateMaternDdsigmaSquareNu.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDdsigmaSquareNu.cpp * @brief Implementation of the UnivariateMaternDdsigmaSquareNu kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..9fe8dd67 100644 --- a/src/kernels/concrete/UnivariateMaternDnu.cpp +++ b/src/kernels/concrete/UnivariateMaternDnu.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDnu.cpp * @brief Implementation of the UnivariateMaternDnu kernel. - * @version 1.0.0 + * @version 1.1.0 * @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,8 @@ 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..d4e7ec77 100644 --- a/src/kernels/concrete/UnivariateMaternDsigmaSquare.cpp +++ b/src/kernels/concrete/UnivariateMaternDsigmaSquare.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternDsigmaSquare.cpp * @brief Implementation of the UnivariateMaternDsigmaSquare kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..070a1e70 100644 --- a/src/kernels/concrete/UnivariateMaternNonGaussian.cpp +++ b/src/kernels/concrete/UnivariateMaternNonGaussian.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternNonGaussian.cpp * @brief Implementation of the UnivariateMaternNonGaussian kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..ab960043 100644 --- a/src/kernels/concrete/UnivariateMaternNuggetsStationary.cpp +++ b/src/kernels/concrete/UnivariateMaternNuggetsStationary.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternNuggetsStationary.cpp * @brief Implementation of the UnivariateMaternNuggetsStationary kernel. - * @version 1.0.0 + * @version 1.1.0 * @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..790d9888 100644 --- a/src/kernels/concrete/UnivariateMaternStationary.cpp +++ b/src/kernels/concrete/UnivariateMaternStationary.cpp @@ -1,19 +1,19 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateMaternStationary.cpp * @brief Implementation of the UnivariateMaternStationary kernel. - * @version 1.0.0 + * @version 1.1.0 * @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/UnivariatePowExpStationary.cpp b/src/kernels/concrete/UnivariatePowExpStationary.cpp new file mode 100644 index 00000000..e4fa247f --- /dev/null +++ b/src/kernels/concrete/UnivariatePowExpStationary.cpp @@ -0,0 +1,67 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file UnivariatePowExpStationary.cpp + * @brief Implementation of the UnivariatePowExpStationary kernel. + * @version 1.1.0 + * @author Sameh Abdulah + * @author Mahmoud ElKarargy + * @date 2023-04-14 +**/ + +#include +#include + +using namespace exageostat::kernels; +using namespace exageostat::dataunits; +using namespace exageostat::helpers; + +template +UnivariatePowExpStationary::UnivariatePowExpStationary() { + this->mP = 1; + this->mParametersNumber = 3; +} + +template +Kernel *UnivariatePowExpStationary::Create() { + KernelsConfigurations::GetParametersNumberKernelMap()["UnivariatePowExpStationary"] = 3; + return new UnivariatePowExpStationary(); +} + +namespace exageostat::kernels { + template bool UnivariatePowExpStationary::plugin_name = plugins::PluginRegistry>::Add( + "UnivariatePowExpStationary", UnivariatePowExpStationary::Create); +} + +template +void +UnivariatePowExpStationary::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) { + + const T sigma_square = aLocalTheta[0]; + const T nu = aLocalTheta[2]; + int i0 = aRowOffset; + int flag = 0; + int j0; + int i, j; + T dist; + + for (i = 0; i < aRowsNumber; i++) { + j0 = aColumnOffset; + for (j = 0; j < aColumnsNumber; j++) { + dist = DistanceCalculationHelpers::CalculateDistance(aLocation1, aLocation2, i0, j0, aDistanceMetric, + flag); + dist = pow(dist, nu); + *(apMatrixA + i + j * aRowsNumber) = (dist == 0.0) ? sigma_square : sigma_square * + exp(-(dist / aLocalTheta[1])); + j0++; + } + i0++; + } +} diff --git a/src/kernels/concrete/UnivariateSpacetimeMaternStationary.cpp b/src/kernels/concrete/UnivariateSpacetimeMaternStationary.cpp index 1eb5d63f..38ab7a9e 100644 --- a/src/kernels/concrete/UnivariateSpacetimeMaternStationary.cpp +++ b/src/kernels/concrete/UnivariateSpacetimeMaternStationary.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file UnivariateSpacetimeMaternStationary.cpp * @brief Implementation of the UnivariateSpacetimeMaternStationary kernel. - * @version 1.0.0 + * @version 1.1.0 * @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/CMakeLists.txt b/src/linear-algebra-solvers/CMakeLists.txt index d3aea1ca..8a9eba80 100644 --- a/src/linear-algebra-solvers/CMakeLists.txt +++ b/src/linear-algebra-solvers/CMakeLists.txt @@ -1,10 +1,10 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @brief CMake build script for the linear-algebra-solvers library, which includes the LinearAlgebraMethods base class and the LinearAlgebraFactory class for creating linear algebra solvers for different computations using HiCMA or Chameleon libraries. # @author Mahmoud ElKarargy # @author Sameh Abdulah diff --git a/src/linear-algebra-solvers/LinearAlgebraFactory.cpp b/src/linear-algebra-solvers/LinearAlgebraFactory.cpp index ec759d52..0d72dbad 100644 --- a/src/linear-algebra-solvers/LinearAlgebraFactory.cpp +++ b/src/linear-algebra-solvers/LinearAlgebraFactory.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @author Mahmoud ElKarargy * @date 2023-03-20 **/ @@ -16,18 +16,17 @@ #include -#include -#include +#include +#include -#ifdef EXAGEOSTAT_USE_HICMA +#ifdef USE_HICMA -#include +#include #endif using namespace exageostat::linearAlgebra; using namespace exageostat::common; -using namespace exageostat::configurations; template std::unique_ptr> LinearAlgebraFactory::CreateLinearAlgebraSolver(Computation aComputation) { @@ -35,19 +34,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..f2d98acb 100644 --- a/src/linear-algebra-solvers/LinearAlgebraMethods.cpp +++ b/src/linear-algebra-solvers/LinearAlgebraMethods.cpp @@ -1,23 +1,27 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file LinearAlgebraMethods.cpp * @brief Implementation of linear algebra methods. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-03-20 + * @date 2024-02-04 **/ #ifdef USE_MPI + #include + #endif + #include #include +#include using namespace std; @@ -25,24 +29,25 @@ using namespace exageostat::linearAlgebra; using namespace exageostat::common; using namespace exageostat::dataunits; using namespace exageostat::configurations; -using namespace exageostat::hardware; +using namespace exageostat::runtime; +using namespace exageostat::results; // 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) { + if (!ExaGeoStatHardware::GetChameleonContext()) { throw std::runtime_error( "ExaGeoStat hardware is not initialized, please use 'ExaGeoStatHardware(computation, cores_number, gpu_numbers);'."); } // 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(); + int p_grid = ExaGeoStatHardware::GetPGrid(); + int q_grid = ExaGeoStatHardware::GetQGrid(); bool is_OOC = aConfigurations.GetIsOOC(); // Create a Chameleon sequence, if not initialized before through the same descriptors @@ -65,57 +70,69 @@ 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); } template -void LinearAlgebraMethods::InitiateFisherDescriptors(configurations::Configurations &aConfigurations, +void LinearAlgebraMethods::InitiateFisherDescriptors(Configurations &aConfigurations, dataunits::DescriptorData &aDescriptorData) { // Check for initialize the Chameleon context. - if (!this->mpContext) { + if (!ExaGeoStatHardware::GetChameleonContext()) { throw std::runtime_error( "ExaGeoStat hardware is not initialized, please use 'ExaGeoStatHardware(computation, cores_number, gpu_numbers);'."); } // 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(); - int q_grid = aConfigurations.GetQGrid(); + int p_grid = ExaGeoStatHardware::GetPGrid(); + int q_grid = ExaGeoStatHardware::GetQGrid(); bool is_OOC = aConfigurations.GetIsOOC(); // Create a Chameleon sequence, if not initialized before through the same descriptors @@ -139,41 +156,46 @@ 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) { +void LinearAlgebraMethods::InitiatePredictionDescriptors(Configurations &aConfigurations, + std::unique_ptr> &aData) { - if (!this->mpContext) { + if (!ExaGeoStatHardware::GetChameleonContext()) { throw std::runtime_error( "ExaGeoStat hardware is not initialized, please use 'ExaGeoStatHardware(computation, cores_number, gpu_numbers);'."); } // Get the problem size and other configuration parameters int dts = aConfigurations.GetDenseTileSize(); - int p_grid = aConfigurations.GetPGrid(); - int q_grid = aConfigurations.GetQGrid(); + int p_grid = ExaGeoStatHardware::GetPGrid(); + int q_grid = ExaGeoStatHardware::GetQGrid(); bool is_OOC = aConfigurations.GetIsOOC(); int z_miss_number = aConfigurations.GetUnknownObservationsNb(); int n_z_obs = aConfigurations.CalculateZObsNumber(); @@ -186,56 +208,68 @@ 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_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_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) { + if (!ExaGeoStatHardware::GetChameleonContext()) { throw std::runtime_error( "ExaGeoStat hardware is not initialized, please use 'ExaGeoStatHardware(computation, cores_number, gpu_numbers);'."); } - int n_z_obs = aConfigurations.CalculateZObsNumber(); + int n_z_obs = aConfigurations.GetObservationNumber(); int dts = aConfigurations.GetDenseTileSize(); - int p_grid = aConfigurations.GetPGrid(); - int q_grid = aConfigurations.GetQGrid(); + int p_grid = ExaGeoStatHardware::GetPGrid(); + int q_grid = ExaGeoStatHardware::GetQGrid(); bool is_OOC = aConfigurations.GetIsOOC(); - int P = aConfigurations.GetP(); FloatPoint float_point; if (sizeof(T) == SIZE_OF_FLOAT) { @@ -245,69 +279,71 @@ 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(); } template -void LinearAlgebraMethods::GenerateSyntheticData(configurations::Configurations &aConfigurations, - const hardware::ExaGeoStatHardware &aHardware, - dataunits::ExaGeoStatData &aData, +void LinearAlgebraMethods::GenerateSyntheticData(Configurations &aConfigurations, + 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) { // Check for initialize the Chameleon context. - if (!this->mpContext) { + if (!ExaGeoStatHardware::GetChameleonContext()) { 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 +351,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()]; @@ -333,154 +369,152 @@ void LinearAlgebraMethods::GenerateObservationsVector(Configurations &aConfig theta[i] = aConfigurations.GetInitialTheta()[i]; } - VERBOSE("Initializing Covariance Matrix (Synthetic Dataset Generation Phase).....") + VERBOSE("\tInitializing Covariance Matrix (Synthetic Dataset Generation Phase).....") int upper_lower = EXAGEOSTAT_LOWER; START_TIMING(matrix_gen_time); - this->CovarianceMatrixCodelet(*aData.GetDescriptorData(), CHAM_descC, upper_lower, apLocation1, apLocation2, - apLocation3, theta, aDistanceMetric, &aKernel); + RuntimeFunctions::CovarianceMatrix(*aData->GetDescriptorData(), CHAM_descC, upper_lower, apLocation1, + apLocation2, + apLocation3, theta, aDistanceMetric, &aKernel); ExaGeoStatSequenceWait(sequence); STOP_TIMING(matrix_gen_time); - VERBOSE("Done.") + VERBOSE("\tDone.") //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); + VERBOSE("\tGenerate Normal Random Distribution Vector Z (Synthetic Dataset Generation Phase) .....") + auto *CHAM_descZ = aData->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc; + RuntimeFunctions::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) .....") + VERBOSE("\tCholesky 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); - VERBOSE("Done.") + flops = flops + flops_dpotrf(full_problem_size); + VERBOSE("\tDone.") //Triangular matrix-matrix multiplication - VERBOSE("Triangular matrix-matrix multiplication Z=L.e (Synthetic Dataset Generation Phase) .....") + VERBOSE("\tTriangular matrix-matrix multiplication Z=L.e (Synthetic Dataset Generation Phase) .....") START_TIMING(time_trmm); 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); - VERBOSE("Done.") + flops = flops + flops_dtrmm(ChamLeft, full_problem_size, CHAM_descZ->n); + VERBOSE("\tDone.") - 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); + RuntimeFunctions::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) .....") -#ifdef CHAMELEON_USE_MPI - pMatrix = new T[n]; +#ifdef USE_MPI + pMatrix = new T[full_problem_size]; string path = aConfigurations.GetLoggerPath(); - ExaGeoStatDesc2Lap(pMatrix, n, CHAM_descZ, EXAGEOSTAT_UPPER_LOWER); - if ( CHAMELEON_Comm_rank() == 0 ){ - helpers::DiskWriter::WriteVectorsToDisk(*pMatrix, n, P, path, *apLocation1); + ExaGeoStatDesc2Lap(pMatrix, full_problem_size, CHAM_descZ, EXAGEOSTAT_UPPER_LOWER); + if (CHAMELEON_Comm_rank() == 0) { + dataLoader::csv::CSVLoader::GetInstance()->WriteData(*pMatrix, full_problem_size, P, path, *apLocation1); } delete[] pMatrix; #else pMatrix = (T *) CHAM_descZ->mat; string path = aConfigurations.GetLoggerPath(); - helpers::DiskWriter::WriteVectorsToDisk(*pMatrix, n, P, path, *apLocation1); + dataLoader::csv::CSVLoader::GetInstance()->WriteData(*pMatrix, full_problem_size, P, path, *apLocation1); #endif - VERBOSE("Done.") + VERBOSE("\tDone.") } ExaGeoStatLaSetTile(EXAGEOSTAT_UPPER_LOWER, 0, 0, CHAM_descC); delete[] randomN; - VERBOSE("Done Z Vector Generation Phase. (Chameleon Synchronous)") + VERBOSE("\tDone Z Vector Generation Phase. (Chameleon Synchronous)") int total_flops = flops / 1e9 / (time_facto + time_trmm); - LOGGER(" ---- Facto Time: " << time_facto) - LOGGER(" ---- dtrmm Time: " << time_trmm) - LOGGER(" ---- Matrix Generation Time: " << matrix_gen_time) - LOGGER(" ---- Total Time: " << time_facto + time_trmm) - LOGGER(" ---- Gflop/s: " << total_flops) - - 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()->SetIsLogger(aConfigurations.GetLogger()); - results::Results::GetInstance()->SetLoggerPath(aConfigurations.GetLoggerPath()); + VERBOSE("\t---- Facto Time: " << time_facto) + VERBOSE("\t---- dtrmm Time: " << time_trmm) + VERBOSE("\t---- Matrix Generation Time: " << matrix_gen_time) + VERBOSE("\t---- Total Time: " << time_facto + time_trmm) + VERBOSE("\t---- Gflop/s: " << total_flops) + + Results::GetInstance()->SetTotalDataGenerationExecutionTime(time_facto + time_trmm); + Results::GetInstance()->SetTotalDataGenerationFlops(total_flops); + Results::GetInstance()->SetGeneratedLocationsNumber(full_problem_size / aConfigurations.GetTimeSlot()); + Results::GetInstance()->SetIsLogger(aConfigurations.GetLogger()); + 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, - Configurations &aConfiguration, Locations &aMissLocations, - Locations &aObsLocations, const kernels::Kernel &aKernel) { +T *LinearAlgebraMethods::ExaGeoStatMLEPredictTile(std::unique_ptr> &aData, T *apTheta, + const int &aZMissNumber, const int &aZObsNumber, T *apZObs, + T *apZActual, T *apZMiss, Configurations &aConfiguration, + Locations &aMissLocations, Locations &aObsLocations, + const kernels::Kernel &aKernel) { int i; - this->SetContext(aHardware.GetChameleonContext()); this->InitiatePredictionDescriptors(aConfiguration, aData); 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, DESCRIPTOR_MSPE); *mspe = 0; - T *mspe_1 = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mspe1); + T *mspe_1 = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_MSPE_1); *mspe_1 = 0; - T *mspe_2 = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mspe2); + T *mspe_2 = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_MSPE_2); *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...") + VERBOSE("\tCopy measurements vector to descZobs descriptor...") ExaGeoStatLap2Desc(apZObs, aZObsNumber, CHAM_desc_Zobs, UpperLower::EXAGEOSTAT_UPPER_LOWER); - VERBOSE("Done.") + VERBOSE("\tDone.") if (apZActual) { //Copy data to vectors - VERBOSE("Copy actual measurements vector to descZactual descriptor...") + VERBOSE("\tCopy actual measurements vector to descZactual descriptor...") ExaGeoStatLap2Desc(apZActual, aZMissNumber, CHAM_desc_Zactual, UpperLower::EXAGEOSTAT_UPPER_LOWER); - VERBOSE("Done.") + VERBOSE("\tDone.") } - LOGGER("- Estimated Parameters (", true) + LOGGER("\t\t- Estimated Theta (", true) for (i = 0; i < num_params; i++) { LOGGER_PRECISION(apTheta[i]) if (i != num_params - 1) { @@ -491,47 +525,51 @@ T *LinearAlgebraMethods::ExaGeoStatMLEPredictTile(ExaGeoStatData &aData, T LOGGER("") START_TIMING(mat_gen_time); - VERBOSE("Generate C22 Covariance Matrix... (Prediction Stage)") + VERBOSE("\tGenerate C22 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); + RuntimeFunctions::CovarianceMatrix(*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, - &aObsLocations, &median_locations, apTheta, 0, &aKernel); + RuntimeFunctions::CovarianceMatrix(*aData->GetDescriptorData(), CHAM_desc_C12, upper_lower, &aMissLocations, + &aObsLocations, &median_locations, apTheta, 0, &aKernel); ExaGeoStatSequenceWait(sequence); - VERBOSE("Done.") + VERBOSE("\tDone.") STOP_TIMING(mat_gen_time); START_TIMING(time_solve); //Start prediction - VERBOSE("Calculate dposv C22 Covariance Matrix... (Prediction Stage)") + VERBOSE("\tCalculate dposv C22 Covariance Matrix... (Prediction Stage)") ExaGeoStatPosvTile(EXAGEOSTAT_LOWER, CHAM_desc_C22, CHAM_desc_Zobs); flops = flops + flops_dpotrf(aZObsNumber); flops = flops + flops_dtrsm(ChamLeft, aZObsNumber, aZObsNumber); - VERBOSE("Done.") + VERBOSE("\tDone.") STOP_TIMING(time_solve); START_TIMING(time_gemm); - VERBOSE("Calculate dgemm Zmiss= C12 * Zobs Covariance Matrix... (Prediction Stage)") + VERBOSE("\tCalculate dgemm Zmiss= C12 * Zobs Covariance Matrix... (Prediction Stage)") CHAMELEON_dgemm_Tile(ChamNoTrans, ChamNoTrans, 1, CHAM_desc_C12, CHAM_desc_Zobs, 0, CHAM_desc_Zmiss); flops = flops + flops_dgemm(aZMissNumber, aZObsNumber, aZObsNumber); - VERBOSE("Done.") + VERBOSE("\tDone.") STOP_TIMING(time_gemm); ExaGeoStatDesc2Lap(apZMiss, aZMissNumber, CHAM_desc_Zmiss, EXAGEOSTAT_UPPER_LOWER); 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."); + VERBOSE("\tCalculate Mean Square Prediction Error (MSPE) ... (Prediction Stage)") + if (kernel_name == "BivariateMaternParsimonious") { + RuntimeFunctions::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); + RuntimeFunctions::ExaGeoStatMLEMSPETileAsync(CHAM_desc_Zactual, CHAM_desc_Zmiss, CHAM_desc_mspe, + sequence, + request); } ExaGeoStatSequenceWait(sequence); - VERBOSE("Done.") + VERBOSE("\tDone.") STOP_TIMING(time_mspe); *mspe /= aZMissNumber; @@ -547,44 +585,240 @@ 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") + if (apZActual) { + VERBOSE("\t- Z Actual .. Z Miss") + for (i = 0; i < aZMissNumber; i++) { + VERBOSE("\t (" << apZActual[i] << ", " << apZMiss[i] << ")") + } + } + + Results::GetInstance()->SetMSPEExecutionTime(time_solve + time_gemm); + Results::GetInstance()->SetMSPEFlops((flops / 1e9 / (time_solve + time_gemm))); + Results::GetInstance()->SetMSPEError(*mspe); + + T *all_mspe = new T[3]; + all_mspe[0] = *mspe; + all_mspe[1] = *mspe_1; + all_mspe[2] = *mspe_2; + + return all_mspe; +} + +template +T *LinearAlgebraMethods::ExaGeoStatMLENonGaussianPredictTile(std::unique_ptr> &aData, + T *apTheta, const int &aZMissNumber, + const int &aZObsNumber, T *apZObs, T *apZActual, + T *apZMiss, + Configurations &aConfiguration, + dataunits::Locations &aMissLocations, + dataunits::Locations &aObsLocations, + const kernels::Kernel &aKernel) { + + int i; + this->InitiatePredictionDescriptors(aConfiguration, aData); + + double time_solve, mat_gen_time, mat_gen_time_2, 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; + + T *mspe = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_MSPE); + *mspe = 0; + T *mspe_1 = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_MSPE_1); + *mspe_1 = 0; + T *mspe_2 = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_MSPE_2); + *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("\tCopy measurements vector to descZobs descriptor...") + ExaGeoStatLap2Desc(apZObs, aZObsNumber, CHAM_desc_Zobs, UpperLower::EXAGEOSTAT_UPPER_LOWER); + VERBOSE("\tDone.") + + if (apZActual) { + //Copy data to vectors + VERBOSE("\tCopy actual measurements vector to descZactual descriptor...") + ExaGeoStatLap2Desc(apZActual, aZMissNumber, CHAM_desc_Zactual, UpperLower::EXAGEOSTAT_UPPER_LOWER); + VERBOSE("\tDone.") + } + + 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 + RuntimeFunctions::ExaGeoStatNonGaussianTransformTileAsync(aConfiguration.GetComputation(), CHAM_desc_Zobs, + apTheta, sequence, &request_array[0]); + + START_TIMING(mat_gen_time); + VERBOSE("\tGenerate R_theta Covariance Matrix... (Prediction Stage)") + int upper_lower = EXAGEOSTAT_LOWER; + RuntimeFunctions::CovarianceMatrix(*aData->GetDescriptorData(), CHAM_desc_C22, upper_lower, &aObsLocations, + &aObsLocations, &median_locations, apTheta, 0, &aKernel); + ExaGeoStatSequenceWait(sequence); + VERBOSE("\tDone.") + 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("\tDone.") + STOP_TIMING(time_solve); + + START_TIMING(mat_gen_time_2); + VERBOSE("Generate R_theta Covariance Matrix... (Prediction Stage)") + RuntimeFunctions::CovarianceMatrix(*aData->GetDescriptorData(), CHAM_desc_R, upper_lower, &aObsLocations, + &aMissLocations, &median_locations, apTheta, 0, &aKernel); + ExaGeoStatSequenceWait(sequence); + VERBOSE("\tDone.") + 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("\tDone.") + 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, DESCRIPTOR_C12); + auto Zmiss2 = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z_MISS); + + 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++) { - LOGGER(" (" << apZActual[i] << ", " << apZMiss[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("\t 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") + RuntimeFunctions::ExaGeoStatMLEMSPETileAsync(CHAM_desc_Zactual, CHAM_desc_Zmiss, CHAM_desc_mspe, sequence, + request); + ExaGeoStatSequenceWait(sequence); + VERBOSE("\t Done.") + STOP_TIMING(time_mspe); + *mspe /= aZMissNumber; + } else { + *mspe = -1; } - results::Results::GetInstance()->SetMSPEExecutionTime(time_solve + time_gemm); - results::Results::GetInstance()->SetMSPEFlops((flops / 1e9 / (time_solve + time_gemm))); - results::Results::GetInstance()->SetMSPEError(*mspe); + if (helpers::CommunicatorMPI::GetInstance()->GetRank() == 0) { + 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("\t- Z Actual .. Z Miss") + for (i = 0; i < aZMissNumber; i++) { + VERBOSE("\t (" << apZActual[i] << ", " << apZMiss[i] << ")") + } + + Results::GetInstance()->SetMSPEExecutionTime(time_solve + time_gemm + time_trsm); + Results::GetInstance()->SetMSPEFlops((flops / 1e9 / (time_solve + time_gemm))); + Results::GetInstance()->SetMSPEError(*mspe); + } 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, ExaGeoStatData &aData, - const ExaGeoStatHardware &aHardware, T *apTruthTheta, - T *apEstimatedTheta, Locations &aMissLocations, - Locations &aObsLocations, +void LinearAlgebraMethods::ExaGeoStatMLETileMLOEMMOM(Configurations &aConfigurations, + std::unique_ptr> &aData, + 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(); - LOGGER("- Truth Theta: ", true) + LOGGER("\t\t- Truth Theta: ", true) for (int num = 0; num < num_par; num++) { LOGGER_PRECISION(apTruthTheta[num] << " ") } LOGGER("") - LOGGER("- Estimated Theta: ", true) + LOGGER("\t\t- Estimated Theta: ", true) for (int num = 0; num < num_par; num++) { LOGGER_PRECISION(apEstimatedTheta[num] << " ") } @@ -595,49 +829,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, DESCRIPTOR_MLOE); *mloe = 0; - T *mmom = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_mmom); + T *mmom = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_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,83 +918,77 @@ 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).....") + VERBOSE("\tCreate 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, - &aObsLocations, &median_locations, apEstimatedTheta, 0, &aKernel); + RuntimeFunctions::CovarianceMatrix(*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, - &aObsLocations, &median_locations, apTruthTheta, 0, &aKernel); + RuntimeFunctions::CovarianceMatrix(*aData->GetDescriptorData(), CHAM_desc_K_t, upper_lower, &aObsLocations, + &aObsLocations, &median_locations, apTruthTheta, 0, &aKernel); this->ExaGeoStatSequenceWait(sequence); - VERBOSE("Done.") + VERBOSE("\tDone.") STOP_TIMING(matrix_gen); //Cholesky factorization for the Co-variance matrix CHAM_desc_K_a START_TIMING(cholesky1); - VERBOSE("Cholesky factorization of CHAM_desc_K_a (MLOE-MMOM) .....") + VERBOSE("\tCholesky factorization of CHAM_desc_K_a (MLOE-MMOM) .....") ExaGeoStatPotrfTile(EXAGEOSTAT_LOWER, CHAM_desc_K_a, aConfigurations.GetBand(), nullptr, nullptr, 0, 0); - VERBOSE("Done.") + VERBOSE("\tDone.") STOP_TIMING(cholesky1); flops = flops + flops_dpotrf(CHAM_desc_K_a->m); START_TIMING(cholesky2); //Cholesky factorization for the Co-variance matrix CHAM_desc_K_t - VERBOSE("Cholesky factorization of CHAM_desc_K_t (MLOE-MMOM) .....") + VERBOSE("\tCholesky factorization of CHAM_desc_K_t (MLOE-MMOM) .....") ExaGeoStatPotrfTile(EXAGEOSTAT_LOWER, CHAM_desc_K_t, aConfigurations.GetBand(), nullptr, nullptr, 0, 0); - VERBOSE("Done.") + VERBOSE("\tDone.") STOP_TIMING(cholesky2); flops = flops + flops_dpotrf(CHAM_desc_K_t->m); T total_loop_time = 0.0; T loop_time; bool verbose; - VERBOSE("* Verbose messages are printed every 10 iteration *") + VERBOSE("\t* Verbose messages are printed every 10 iteration *") for (p = 0; p < n_z_miss; p++) { verbose = p % 10 == 0; lmiss->GetLocationX()[0] = aMissLocations.GetLocationX()[p]; lmiss->GetLocationY()[0] = aMissLocations.GetLocationY()[p]; if (verbose) { - VERBOSE("Generate two vectors k_a and k_t (MLOE-MMOM).....") + VERBOSE("\tGenerate two vectors k_a and k_t (MLOE-MMOM).....") } START_TIMING(vecs_gen); upper_lower = EXAGEOSTAT_UPPER_LOWER; - 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, - &median_locations, apEstimatedTheta, 0, &aKernel); + RuntimeFunctions::CovarianceMatrix(*aData->GetDescriptorData(), CHAM_desc_k_t, upper_lower, &aObsLocations, + lmiss, &median_locations, apTruthTheta, 0, &aKernel); + RuntimeFunctions::CovarianceMatrix(*aData->GetDescriptorData(), CHAM_desc_k_a, upper_lower, &aObsLocations, + lmiss, &median_locations, apEstimatedTheta, 0, &aKernel); this->ExaGeoStatSequenceWait(sequence); STOP_TIMING(vecs_gen); //Copy CHAM_desc_k_a to CHAM_descK_atmp (MLOE-MMOM) if (verbose) { - VERBOSE("Copy CHAM_desc_k_a to CHAM_descK_atmp (MLOE-MMOM).....") + VERBOSE("\tCopy CHAM_desc_k_a to CHAM_descK_atmp (MLOE-MMOM).....") } START_TIMING(copy_vecs); ExaGeoStatLapackCopyTile(EXAGEOSTAT_UPPER_LOWER, CHAM_desc_k_t, CHAM_desc_k_t_tmp); ExaGeoStatLapackCopyTile(EXAGEOSTAT_UPPER_LOWER, CHAM_desc_k_a, CHAM_desc_k_a_tmp); STOP_TIMING(copy_vecs); if (verbose) { - VERBOSE("Done.") + VERBOSE("\tDone.") } START_TIMING(loop_time); START_TIMING(trsm1); // Triangular Solve (TRSM) k_a = TRSM(L_a^-1, k_a) if (verbose) { - VERBOSE("Solving the linear system k_a = TRSM(l_a^-1, k_a) ...(MLOE-MMOM)") + VERBOSE("\tSolving the linear system k_a = TRSM(l_a^-1, k_a) ...(MLOE-MMOM)") } ExaGeoStatTrsmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_NO_TRANS, EXAGEOSTAT_NON_UNIT, 1, CHAM_desc_K_a, nullptr, nullptr, CHAM_desc_k_a, 0); if (verbose) { - VERBOSE("Done.") + VERBOSE("\tDone.") } flops = flops + flops_dtrsm(ChamLeft, CHAM_desc_K_a->m, CHAM_desc_k_a->n); STOP_TIMING(trsm1); @@ -764,75 +996,74 @@ void LinearAlgebraMethods::ExaGeoStatMLETileMLOEMMOM(Configurations &aConfigu START_TIMING(trsm2); // Triangular Solve (TRSM) k_t = TRSM(L_t^-1, k_t) if (verbose) { - VERBOSE("Solving the linear system k_t = TRSM(L_t^-1, k_t) ...(MLOE-MMOM)") + VERBOSE("\tSolving the linear system k_t = TRSM(L_t^-1, k_t) ...(MLOE-MMOM)") } ExaGeoStatTrsmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_NO_TRANS, EXAGEOSTAT_NON_UNIT, 1, CHAM_desc_K_t, nullptr, nullptr, CHAM_desc_k_t, 0); flops = flops + flops_dtrsm(ChamLeft, CHAM_desc_K_t->m, CHAM_desc_k_t->n); if (verbose) { - VERBOSE("Done.") + VERBOSE("\tDone.") } STOP_TIMING(trsm2); START_TIMING(trsm3); // Triangular Solve (TRSM) k_a = TRSM(L_a^-T, k_a) if (verbose) { - VERBOSE("Solving the linear system k_a = TRSM(L_a^-T, k_a) ...(MLOE-MMOM)") + VERBOSE("\tSolving the linear system k_a = TRSM(L_a^-T, k_a) ...(MLOE-MMOM)") } ExaGeoStatTrsmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_TRANS, EXAGEOSTAT_NON_UNIT, 1, CHAM_desc_K_a, nullptr, nullptr, CHAM_desc_k_a, 0); flops = flops + flops_dtrsm(ChamLeft, CHAM_desc_K_a->m, CHAM_desc_k_a->n); if (verbose) { - VERBOSE("Done.") + VERBOSE("\tDone.") } STOP_TIMING(trsm3); - START_TIMING(trsm4); // Triangular Solve (TRSM) k_t = TRSM(L_t^-T, k_t) if (verbose) { - VERBOSE("Solving the linear system k_t = TRSM(L_a^-T, k_t) ...(MLOE-MMOM)") + VERBOSE("\tSolving the linear system k_t = TRSM(L_a^-T, k_t) ...(MLOE-MMOM)") } ExaGeoStatTrsmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_TRANS, EXAGEOSTAT_NON_UNIT, 1, CHAM_desc_K_t, nullptr, nullptr, CHAM_desc_k_t, 0); flops = flops + flops_dtrsm(ChamLeft, CHAM_desc_K_t->m, CHAM_desc_k_t->n); if (verbose) { - VERBOSE("Done.") + VERBOSE("\tDone.") } STOP_TIMING(trsm4); START_TIMING(gevv2); // Calculate dgemm value= CHAM_desc_k_t^T * CHAM_desc_k_a if (verbose) { - VERBOSE("Calculate dgemm CHAM_desc_expr1 = CHAM_desc_k_t^T * CHAM_desc_k_a... (MLOE-MMOM)") + VERBOSE("\tCalculate dgemm CHAM_desc_expr1 = CHAM_desc_k_t^T * CHAM_desc_k_a... (MLOE-MMOM)") } CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_desc_k_t_tmp, CHAM_desc_k_a, 0, CHAM_desc_expr1); flops = flops + flops_dgemm(CHAM_desc_k_t_tmp->m, CHAM_desc_k_a->n, CHAM_desc_expr1->n); if (verbose) { - VERBOSE("Done.") + VERBOSE("\tDone.") } STOP_TIMING(gevv2); START_TIMING(gevv3); // Calculate dgemm value= CHAM_desc_k_a^T * CHAM_desc_k_a_tmp if (verbose) { - VERBOSE("Calculate dgemm CHAM_desc_expr1 = CHAM_desc_k_a^T * CHAM_desc_k_a... (MLOE-MMOM)") + VERBOSE("\tCalculate dgemm CHAM_desc_expr1 = CHAM_desc_k_a^T * CHAM_desc_k_a... (MLOE-MMOM)") } CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_desc_k_a_tmp, CHAM_desc_k_a, 0, CHAM_desc_expr4); flops = flops + flops_dgemm(CHAM_desc_k_a_tmp->m, CHAM_desc_k_a->n, CHAM_desc_expr4->n); if (verbose) { - VERBOSE("Done.") + VERBOSE("\tDone.") } STOP_TIMING(gevv3); START_TIMING(gevv1); // Calculate dgemm value= CHAM_desc_k_a^T * CHAM_desc_k_t if (verbose) { - VERBOSE("Calculate dgemm CHAM_desc_expr4 = CHAM_desc_k_a^T * CHAM_desc_k_t... (Prediction Stage)") + VERBOSE("\tCalculate dgemm CHAM_desc_expr4 = CHAM_desc_k_a^T * CHAM_desc_k_t... (Prediction Stage)") } CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_desc_k_t_tmp, CHAM_desc_k_t, 0, CHAM_desc_expr3); flops = flops + flops_dgemm(CHAM_desc_k_t_tmp->m, CHAM_desc_k_t->n, CHAM_desc_expr3->n); if (verbose) { - VERBOSE("Done.") + VERBOSE("\tDone.") } STOP_TIMING(gevv1); @@ -844,12 +1075,12 @@ void LinearAlgebraMethods::ExaGeoStatMLETileMLOEMMOM(Configurations &aConfigu // Calculate dgemm value= CHAM_desc_k_a^T * CHAM_desc_k_t if (verbose) { - VERBOSE("Calculate dgemm CHAM_desc_expr1 = CHAM_desc_k_a^T * CHAM_desc_k_a... (Prediction Stage)") + VERBOSE("\tCalculate dgemm CHAM_desc_expr1 = CHAM_desc_k_a^T * CHAM_desc_k_a... (Prediction Stage)") } CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_desc_k_a, CHAM_desc_k_a, 0, CHAM_desc_expr2); flops = flops + flops_dgemm(CHAM_desc_k_a_tmp->m, CHAM_desc_k_t->n, CHAM_desc_expr2->n); if (verbose) { - VERBOSE("Done.") + VERBOSE("\tDone.") } START_TIMING(gevv5); STOP_TIMING(gevv5); @@ -862,33 +1093,32 @@ 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) - ExaGeoStatMLETileAsyncMLOEMMOM(CHAM_desc_expr2, CHAM_desc_expr3, CHAM_desc_expr4, CHAM_desc_mloe, - CHAM_desc_mmom, sequence, request); + VERBOSE("\t- Matrix Generation Time: " << matrix_gen << " Vectors Generation Time: " << vecs_gen + << " First Cholesky factorization Time: " << cholesky1 + << " First Cholesky factorization Time: " << cholesky2) + VERBOSE("\t- First Trsm time: " << trsm1 << " Second Trsm time: " << trsm2 << " Third Trsm time: " << trsm3 + << " Fourth Trsm time: " << trsm4) + VERBOSE("\t- First gemm time: " << gevv1 << " Second gemm time: " << gevv2 << " Third gemm time: " << gevv3 + << " Fourth gemm time: " << gevv4 << " Fifth gemm time: " << gevv5) + RuntimeFunctions::ExaGeoStatMLETileAsyncMLOEMMOM(CHAM_desc_expr2, CHAM_desc_expr3, CHAM_desc_expr4, + CHAM_desc_mloe, CHAM_desc_mmom, sequence, request); this->ExaGeoStatSequenceWait(sequence); } - LOGGER(" ---- MLOE-MMOM Gflop/s: " << flops / 1e9 / (total_loop_time + cholesky1 + cholesky2)) + VERBOSE("\t---- MLOE-MMOM Gflop/s: " << flops / 1e9 / (total_loop_time + cholesky1 + cholesky2)) *mloe /= n_z_miss; *mmom /= n_z_miss; STOP_TIMING(all_time); - LOGGER(" ---- MLOE = " << *mloe) - LOGGER(" ---- MMOM = " << *mmom) - LOGGER(" ---- MLOE MMOM Time: " << all_time << " seconds.") - - results::Results::GetInstance()->SetMLOE(*mloe); - results::Results::GetInstance()->SetMMOM(*mmom); - results::Results::GetInstance()->SetExecutionTimeMLOEMMOM(all_time); - results::Results::GetInstance()->SetMatrixGenerationTimeMLOEMMOM(matrix_gen); - results::Results::GetInstance()->SetFactoTimeMLOEMMOM(cholesky1 + cholesky2); - results::Results::GetInstance()->SetLoopTimeMLOEMMOM(total_loop_time); - results::Results::GetInstance()->SetFlopsMLOEMMOM((flops / 1e9 / (total_loop_time + cholesky1 + cholesky2))); + LOGGER("\t\t- MLOE = " << *mloe << "\t\t- MMOM = " << *mmom) + VERBOSE("\t---- MLOE MMOM Time: " << all_time << " seconds.") + + Results::GetInstance()->SetMLOE(*mloe); + Results::GetInstance()->SetMMOM(*mmom); + Results::GetInstance()->SetExecutionTimeMLOEMMOM(all_time); + Results::GetInstance()->SetMatrixGenerationTimeMLOEMMOM(matrix_gen); + Results::GetInstance()->SetFactoTimeMLOEMMOM(cholesky1 + cholesky2); + Results::GetInstance()->SetLoopTimeMLOEMMOM(total_loop_time); + Results::GetInstance()->SetFlopsMLOEMMOM((flops / 1e9 / (total_loop_time + cholesky1 + cholesky2))); delete[] loe; delete[] mom; @@ -901,61 +1131,57 @@ void LinearAlgebraMethods::ExaGeoStatMLETileMLOEMMOM(Configurations &aConfigu } template -T *LinearAlgebraMethods::ExaGeoStatFisherTile(configurations::Configurations &aConfigurations, - dataunits::ExaGeoStatData &aData, - const hardware::ExaGeoStatHardware &aHardware, T *apTheta, +T *LinearAlgebraMethods::ExaGeoStatFisherTile(Configurations &aConfigurations, + std::unique_ptr> &aData, 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, DESCRIPTOR_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(); - auto kernel_name = aConfigurations.GetKernelName(); int num_params = aKernel.GetParametersNumbers(); - auto median_locations = Locations(1, aData.GetLocations()->GetDimension()); - aData.CalculateMedianLocations(kernel_name, median_locations); - double time = 0.0; + auto median_locations = Locations(1, aData->GetLocations()->GetDimension()); + aData->CalculateMedianLocations(kernel_name, median_locations); + double time; 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(), - &aKernel); + RuntimeFunctions::CovarianceMatrix(*aData->GetDescriptorData(), CHAM_desc_C, EXAGEOSTAT_LOWER, + aData->GetLocations(), aData->GetLocations(), &median_locations, apTheta, + aConfigurations.GetDistanceMetric(), &aKernel); ExaGeoStatSequenceWait(sequence); - VERBOSE("Done.") + VERBOSE("\tDone.") - VERBOSE("Calculate Cholesky decomposition (Fisher Matrix Generation).....") + VERBOSE("\tCalculate Cholesky decomposition (Fisher Matrix Generation).....") ExaGeoStatPotrfTile(EXAGEOSTAT_LOWER, CHAM_desc_C, 0, nullptr, nullptr, 0, 0); - VERBOSE("Done.") + VERBOSE("\tDone.") //Allocate memory for A, and initialize it with 0s. auto A = new T[num_params * num_params](); @@ -972,23 +1198,24 @@ 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, - aConfigurations.GetDistanceMetric(), pKernel_cj); + RuntimeFunctions::CovarianceMatrix(*aData->GetDescriptorData(), CHAM_desc_CJ, EXAGEOSTAT_UPPER_LOWER, + aData->GetLocations(), aData->GetLocations(), &median_locations, apTheta, + aConfigurations.GetDistanceMetric(), pKernel_cj); ExaGeoStatSequenceWait(sequence); - VERBOSE("Done.") + VERBOSE("\tDone.") - VERBOSE("Compute triangular solve CHAM_desc_CJ (Fisher Matrix Generation).....") + VERBOSE("\tCompute triangular solve CHAM_desc_CJ (Fisher Matrix Generation).....") ExaGeoStatTrsmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_NO_TRANS, EXAGEOSTAT_NON_UNIT, 1, CHAM_desc_C, nullptr, nullptr, CHAM_desc_CJ, 0); ExaGeoStatTrsmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_TRANS, EXAGEOSTAT_NON_UNIT, 1, CHAM_desc_C, nullptr, nullptr, CHAM_desc_CJ, 0); - VERBOSE("Done.") + VERBOSE("\tDone.") delete pKernel_cj; for (int k = j; k < num_params; k++) { @@ -1003,33 +1230,35 @@ 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, - aConfigurations.GetDistanceMetric(), pKernel_ck); + RuntimeFunctions::CovarianceMatrix(*aData->GetDescriptorData(), CHAM_desc_CK, EXAGEOSTAT_UPPER_LOWER, + aData->GetLocations(), aData->GetLocations(), &median_locations, + apTheta, aConfigurations.GetDistanceMetric(), pKernel_ck); ExaGeoStatSequenceWait(sequence); - VERBOSE("Done.") + VERBOSE("\tDone.") - VERBOSE("Compute tringular solve CHAM_desc_CK (Fisher Matrix Generation).....") + VERBOSE("\tCompute tringular solve CHAM_desc_CK (Fisher Matrix Generation).....") ExaGeoStatTrsmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_NO_TRANS, EXAGEOSTAT_NON_UNIT, 1, CHAM_desc_C, nullptr, nullptr, CHAM_desc_CK, 0); ExaGeoStatTrsmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_TRANS, EXAGEOSTAT_NON_UNIT, 1, CHAM_desc_C, nullptr, nullptr, CHAM_desc_CK, 0); - VERBOSE("Done.") + VERBOSE("\tDone.") - VERBOSE("Compute matrix-matrix multiplication CHAM_desc_CK (Fisher Matrix Generation).....") + VERBOSE("\tCompute matrix-matrix multiplication CHAM_desc_CK (Fisher Matrix Generation).....") CHAMELEON_dgemm_Tile(ChamNoTrans, ChamNoTrans, 1, CHAM_desc_CJ, CHAM_desc_CK, 0, CHAM_desc_results); - VERBOSE("Done.") + VERBOSE("\tDone.") VERBOSE("Compute the trace/diagonal of CHAM_desc_CK (Fisher Matrix Generation).....") - ExaGeoStatMLETraceTileAsync(CHAM_desc_results, sequence, &request_array[0], CHAM_desc_C_trace, - CHAM_desc_C_diag); + RuntimeFunctions::ExaGeoStatMLETraceTileAsync(CHAM_desc_results, sequence, &request_array[0], + CHAM_desc_C_trace, + CHAM_desc_C_diag); ExaGeoStatSequenceWait(sequence); - VERBOSE("Done.") + VERBOSE("\tDone.") A[k + num_params * j] = 0.5 * *trace; *trace = 0; @@ -1039,19 +1268,19 @@ T *LinearAlgebraMethods::ExaGeoStatFisherTile(configurations::Configurations STOP_TIMING(time); - VERBOSE("Copy A array to descriptor CHAM_desc_A (Fisher Matrix Generation).....") + VERBOSE("\tCopy A array to descriptor CHAM_desc_A (Fisher Matrix Generation).....") ExaGeoStatLap2Desc(A, num_params, CHAM_desc_A, EXAGEOSTAT_UPPER_LOWER); - VERBOSE("Done.") + VERBOSE("\tDone.") - VERBOSE("Calculate Cholesky decomposition (Fisher Matrix Generation).....") + VERBOSE("\tCalculate Cholesky decomposition (Fisher Matrix Generation).....") LAPACKE_dpotrf(LAPACK_COL_MAJOR, 'L', num_params, (double *) A, num_params); - VERBOSE("Done.") - VERBOSE("Generate Identity Matrix (I) (Fisher Matrix Generation).....") + VERBOSE("\tDone.") + VERBOSE("\tGenerate Identity Matrix (I) (Fisher Matrix Generation).....") //Allocate memory for A, and initialize it with 0s. auto I_matrix = new T[num_params * num_params + 1](); LAPACKE_dlaset(LAPACK_COL_MAJOR, 'L', num_params, num_params, 0, 1, (double *) I_matrix, num_params); - VERBOSE("Done.") + VERBOSE("\tDone.") cblas_dtrsm( CblasColMajor, @@ -1071,11 +1300,7 @@ 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::GetInstance()->SetTotalFisherTime(time); delete[] A; return I_matrix; } @@ -1083,14 +1308,14 @@ 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(); + int p_grid = ExaGeoStatHardware::GetPGrid(); + int q_grid = ExaGeoStatHardware::GetQGrid(); bool is_OOC = aConfigurations.GetIsOOC(); @@ -1104,266 +1329,46 @@ 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; } + double epsilon = 1e-8; + if (abs(((T *) z_desc->mat)[0]) < epsilon) { + z_desc = (CHAM_desc_t *) aDescData.GetDescriptor(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z).chameleon_desc; + } this->ExaGeoStatDesc2Lap(apZ, aSize, z_desc, UpperLower::EXAGEOSTAT_UPPER_LOWER); } -template -void LinearAlgebraMethods::CovarianceMatrixCodelet(DescriptorData &aDescriptorData, void *apDescriptor, - const int &aTriangularPart, Locations *apLocation1, - Locations *apLocation2, Locations *apLocation3, - T *apLocalTheta, const int &aDistanceMetric, - const kernels::Kernel *apKernel) { +#ifdef USE_HICMA - // 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((RUNTIME_option_t *) &options, (CHAM_context_t *) this->mpContext, - (RUNTIME_sequence_t *) aDescriptorData.GetSequence(), - (RUNTIME_request_t *) aDescriptorData.GetRequest()); - - int temp, tempnn; - auto *CHAM_apDescriptor = (CHAM_desc_t *) apDescriptor; - struct starpu_codelet *cl = &this->cl_dcmg; - int m, n, m0 = 0, n0 = 0; - - for (n = 0; n < CHAM_apDescriptor->nt; n++) { - tempnn = n == CHAM_apDescriptor->nt - 1 ? CHAM_apDescriptor->n - n * CHAM_apDescriptor->nb - : CHAM_apDescriptor->nb; - if (aTriangularPart == ChamUpperLower) { - m = 0; - } else { - m = CHAM_apDescriptor->m == CHAM_apDescriptor->n ? n : 0; +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!"); } - for (; m < CHAM_apDescriptor->mt; m++) { - temp = m == CHAM_apDescriptor->mt - 1 ? CHAM_apDescriptor->m - m * CHAM_apDescriptor->mb - : CHAM_apDescriptor->mb; - m0 = m * CHAM_apDescriptor->mb; - n0 = n * CHAM_apDescriptor->nb; - // Register the data with StarPU - starpu_insert_task(cl, - STARPU_VALUE, &temp, sizeof(int), - STARPU_VALUE, &tempnn, sizeof(int), - STARPU_VALUE, &m0, sizeof(int), - STARPU_VALUE, &n0, sizeof(int), - STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr(CHAM_apDescriptor, m, n), - STARPU_VALUE, &apLocation1, sizeof(Locations *), - STARPU_VALUE, &apLocation2, sizeof(Locations *), - STARPU_VALUE, &apLocation3, sizeof(Locations *), - STARPU_VALUE, &apLocalTheta, sizeof(double *), - STARPU_VALUE, &aDistanceMetric, sizeof(int), - STARPU_VALUE, &apKernel, sizeof(kernels::Kernel *), - 0); + status = HICMA_Lapack_to_Tile(z, aSize, (HICMA_desc_t *) apDestinationDesc); + if (status != HICMA_SUCCESS) { + throw std::runtime_error("HICMA_Lapack_to_Tile Failed!"); } - } - - RUNTIME_options_ws_free(&options); - RUNTIME_options_finalize(&options, (CHAM_context_t *) this->mpContext); -} - -template -void -LinearAlgebraMethods::ExaGeoStatMLETraceTileAsync(void *apDescA, void *apSequence, void *apRequest, void *apDescNum, - void *apDescTrace) { - // 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, n0; - int tempmm; - auto A = *((CHAM_desc_t *) apDescA); - struct starpu_codelet *cl = &this->cl_dtrace; - - for (m = 0; m < A.mt; m++) { - tempmm = m == A.mt - 1 ? A.m - m * A.mb : A.mb; - starpu_insert_task(cl, - STARPU_VALUE, &tempmm, sizeof(int), - STARPU_R, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescA, m, m), - STARPU_RW, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescNum, 0, 0), - STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescTrace, m, 0), - 0); - } - - this->ExaGeoStatOptionsFree(&options); - this->ExaGeoStatOptionsFinalize(&options, this->mpContext); -} - -template -void -LinearAlgebraMethods::ExaGeoStatGaussianToNonTileAsync(DescriptorData &aDescriptorData, void *apDesc, - T *apTheta) { - - // 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, aDescriptorData.GetSequence(), aDescriptorData.GetRequest()); - - int m, m0; - int temp; - auto desc_z = (CHAM_desc_t *) apDesc; - struct starpu_codelet *cl = &this->cl_gaussian_to_non; - - - for (m = 0; m < desc_z->mt; m++) { - temp = m == desc_z->mt - 1 ? desc_z->m - m * desc_z->mb : desc_z->mb; - m0 = m * desc_z->mb; - - starpu_insert_task(cl, - STARPU_VALUE, &temp, sizeof(int), - STARPU_VALUE, &m0, sizeof(int), - STARPU_RW, (starpu_data_handle_t) RUNTIME_data_getaddr(desc_z, m, 0), - STARPU_VALUE, &apTheta[0], sizeof(T), - STARPU_VALUE, &apTheta[1], sizeof(T), - STARPU_VALUE, &apTheta[2], sizeof(T), - STARPU_VALUE, &apTheta[3], sizeof(T), - STARPU_VALUE, &apTheta[4], sizeof(T), - STARPU_VALUE, &apTheta[5], sizeof(T), -#if defined(CHAMELEON_CODELETS_HAVE_NAME) - STARPU_NAME, "gaussian_to_non", -#endif - 0); - } - - this->ExaGeoStatOptionsFree(&options); - this->ExaGeoStatOptionsFinalize(&options, this->mpContext); -} - -template -int LinearAlgebraMethods::ExaGeoStatMLEMSPETileAsync(void *apDescZPredict, void *apDescZMiss, - void *apDescError, void *apSequence, - void *apRequest) { - // Check for Initialise 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; - ExaGeoStatOptionsInit(&options, this->mpContext, apSequence, apRequest); - - int m, m0; - int temp; - auto Zpre = (CHAM_desc_t *) apDescZPredict; - struct starpu_codelet *cl = &this->cl_dmse; - - for (m = 0; m < Zpre->mt; m++) { - temp = m == Zpre->mt - 1 ? Zpre->m - m * Zpre->mb : Zpre->mb; - - m0 = m * Zpre->mb; - starpu_insert_task(cl, - STARPU_VALUE, &temp, sizeof(int), - STARPU_VALUE, &m0, sizeof(int), - STARPU_RW, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescError, 0, 0), - STARPU_R, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescZPredict, m, 0), - STARPU_R, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescZMiss, m, 0), -#if defined(CHAMELEON_CODELETS_HAVE_NAME) - STARPU_NAME, "dmse", -#endif - 0); - } - ExaGeoStatOptionsFree(&options); - ExaGeoStatOptionsFinalize(&options, (CHAM_context_t *) this->mpContext); - return CHAMELEON_SUCCESS; -} - -template -int LinearAlgebraMethods::ExaGeoStatMLETileAsyncMLOEMMOM(void *apDescExpr2, void *apDescExpr3, void *apDescExpr4, - void *apDescMLOE, void *apDescMMOM, void *apSequence, - void *apRequest) { - - // Check for Initialise 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, n, m0, n0; - struct starpu_codelet *cl = &this->cl_dmloe_mmom; - int temp, temp2; - - for (n = 0; n < ((CHAM_desc_t *) apDescExpr2)->nt; n++) { - temp2 = n == ((CHAM_desc_t *) apDescExpr2)->nt - 1 ? ((CHAM_desc_t *) apDescExpr2)->n - - n * ((CHAM_desc_t *) apDescExpr2)->nb - : ((CHAM_desc_t *) apDescExpr2)->nb; - for (m = 0; m < ((CHAM_desc_t *) apDescExpr2)->mt; m++) { - - temp = m == ((CHAM_desc_t *) apDescExpr2)->mt - 1 ? ((CHAM_desc_t *) apDescExpr2)->m - - m * ((CHAM_desc_t *) apDescExpr2)->mb - : ((CHAM_desc_t *) apDescExpr2)->mb; - m0 = m * ((CHAM_desc_t *) apDescExpr2)->mb; - n0 = n * ((CHAM_desc_t *) apDescExpr2)->nb; - starpu_insert_task(cl, - STARPU_VALUE, &temp, sizeof(int), - STARPU_VALUE, &temp2, sizeof(int), - STARPU_VALUE, &m0, sizeof(int), - STARPU_VALUE, &n0, sizeof(int), - STARPU_R, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescExpr2, m, n), - STARPU_R, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescExpr3, m, n), - STARPU_R, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescExpr4, m, n), - STARPU_RW, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescMLOE, m, n), - STARPU_RW, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescMMOM, m, n), - 0); + } 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!"); } } - this->ExaGeoStatOptionsFree(&options); - this->ExaGeoStatOptionsFinalize(&options, this->mpContext); - return CHAMELEON_SUCCESS; + delete[] z; } -template -void -LinearAlgebraMethods::CopyDescriptorZ(DescriptorData &aDescriptorData, void *apDescriptor, T *apDoubleVector) { - - // 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 *) aDescriptorData.GetSequence(), - (RUNTIME_request_t *) aDescriptorData.GetRequest()); - - int m, m0; - int temp; - auto A = (CHAM_desc_t *) apDescriptor; - struct starpu_codelet *cl = &this->cl_dzcpy; - - for (m = 0; m < A->mt; m++) { - temp = m == A->mt - 1 ? A->m - m * A->mb : A->mb; - m0 = m * A->mb; - - starpu_insert_task(cl, - STARPU_VALUE, &temp, sizeof(int), - STARPU_VALUE, &m0, sizeof(int), - STARPU_VALUE, &apDoubleVector, sizeof(double), - STARPU_W, RUNTIME_data_getaddr(A, m, 0), -#if defined(CHAMELEON_CODELETS_HAVE_NAME) - STARPU_NAME, "dzcpy", #endif - 0); - } - RUNTIME_options_ws_free(&options); - -} template void @@ -1375,6 +1380,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) { @@ -1411,4 +1425,39 @@ void LinearAlgebraMethods::ExaGeoStatPosvTile(const common::UpperLower &aUppe if (status != CHAMELEON_SUCCESS) { throw std::runtime_error("CHAMELEON_dposv_Tile Failed!"); } -} \ No newline at end of file +} + +template +bool LinearAlgebraMethods::Recover(char *apPath, const int &aIterationCount, T *apTheta, T *apLogLik, + const int &aNumParams) { + + char *pLine = nullptr, *pTokens; + size_t length = 0; + int count, i; + + FILE *pFile_handler; + pFile_handler = fopen(apPath, "r"); + + if (pFile_handler == nullptr) { + throw std::runtime_error("Cannot open observations file"); + } + while (getline(&pLine, &length, pFile_handler) != -1) { + pTokens = strtok(pLine, " "); + count = (int) strtol(pTokens, nullptr, 10); + if (count == aIterationCount) { + pTokens = strtok(nullptr, " "); + for (i = 0; i < aNumParams; i++) { + apTheta[i] = strtol(pTokens, nullptr, 10); + pTokens = strtok(nullptr, " "); + } + *apLogLik = strtol(pTokens, nullptr, 10); + fclose(pFile_handler); + free(pLine); + return true; + } + } + + fclose(pFile_handler); + free(pLine); + return false; +} diff --git a/src/linear-algebra-solvers/concrete/CMakeLists.txt b/src/linear-algebra-solvers/concrete/CMakeLists.txt index 0174fa63..74df59f8 100644 --- a/src/linear-algebra-solvers/concrete/CMakeLists.txt +++ b/src/linear-algebra-solvers/concrete/CMakeLists.txt @@ -1,10 +1,10 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @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..8ec6abe8 100644 --- a/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp +++ b/src/linear-algebra-solvers/concrete/chameleon/ChameleonImplementation.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -7,14 +7,16 @@ * @file ChameleonImplementation.cpp * @brief This file contains the declaration of ChameleonImplementation class. * @details ChameleonImplementation is a concrete implementation of LinearAlgebraMethods class for dense or diagonal-super tile matrices.. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-03-20 + * @date 2024-02-04 **/ #ifdef USE_MPI + #include + #endif #include @@ -25,60 +27,30 @@ using namespace std; using namespace exageostat::common; using namespace exageostat::dataunits; +using namespace exageostat::runtime; +using namespace exageostat::results; using namespace exageostat::configurations; using namespace exageostat::linearAlgebra; template -int ChameleonImplementation::ExaGeoStatDoubleDotProduct(void *apDescA, void *apDescProduct, void *apSequence, - void *apRequest) { - RUNTIME_option_t options; - this->ExaGeoStatOptionsInit(&options, this->mpContext, apSequence, apRequest); - - - int m, m0; - int tempmm; - auto A = (CHAM_desc_t *) apDescA; - - struct starpu_codelet *cl=&this->cl_ddotp; - - for (m = 0; m < A->mt; m++) { - tempmm = m == A->mt-1 ? A->m - m * A->mb : A->mb; - - m0 = m * A->mb; - - - starpu_insert_task(cl, - STARPU_VALUE, &tempmm, sizeof(int), - STARPU_VALUE, &m0, sizeof(int), - STARPU_RW, ExaGeoStatDataGetAddr(apDescProduct, 0, 0), - STARPU_R, RUNTIME_data_getaddr(A, m, 0), - 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, - Configurations &aConfigurations, const double *theta, +T ChameleonImplementation::ExaGeoStatMLETile(std::unique_ptr> &aData, + configurations::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,64 +61,71 @@ 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 *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, - DescriptorName::DESCRIPTOR_C11).chameleon_desc; - 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, - DescriptorName::DESCRIPTOR_C22).chameleon_desc; - 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, - DescriptorName::DESCRIPTOR_Z_1).chameleon_desc; - 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, - DescriptorName::DESCRIPTOR_Z_3).chameleon_desc; - 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, - 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, - DescriptorName::DESCRIPTOR_PRODUCT_1).chameleon_desc; - 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, - DescriptorName::DESCRIPTOR_PRODUCT_3).chameleon_desc; - - T *determinant = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_det); + auto median_locations = Locations(1, aData->GetLocations()->GetDimension()); + aData->CalculateMedianLocations(kernel_name, median_locations); + + 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, + DescriptorName::DESCRIPTOR_C11).chameleon_desc; + 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, + DescriptorName::DESCRIPTOR_C22).chameleon_desc; + 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, + DescriptorName::DESCRIPTOR_Z_1).chameleon_desc; + 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, + DescriptorName::DESCRIPTOR_Z_3).chameleon_desc; + 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, + DescriptorName::DESCRIPTOR_DETERMINANT).chameleon_desc; + 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, + DescriptorName::DESCRIPTOR_PRODUCT_2).chameleon_desc; + auto *CHAM_desc_product3 = aData->GetDescriptorData()->GetDescriptor(DescriptorType::CHAMELEON_DESCRIPTOR, + DescriptorName::DESCRIPTOR_PRODUCT_3).chameleon_desc; + + T *determinant = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_DETERMINANT); *determinant = 0; - T *product = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_product); + T *product = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_PRODUCT); *product = 0; + T *sum; + if (aConfigurations.GetIsNonGaussian()) { + sum = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_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))) { + !(this->Recover((char *) (recovery_file.c_str()), iter_count, (T *) theta, &loglik, num_params))) { START_TIMING(dzcpy_time); if (iter_count == 0) { // Save a copy of descZ into descZcpy for restoring each iteration (Only for the first iteration) this->ExaGeoStatLapackCopyTile(EXAGEOSTAT_UPPER_LOWER, CHAM_desc_Z, CHAM_desc_Zcpy); } else { - VERBOSE("Re-store the original Z vector...") + VERBOSE("\tRe-store the original Z vector...") this->ExaGeoStatLapackCopyTile(EXAGEOSTAT_UPPER_LOWER, CHAM_desc_Zcpy, CHAM_desc_Z); - VERBOSE("Done.") + VERBOSE("\tDone.") } STOP_TIMING(dzcpy_time); } //Generate new co-variance matrix C based on new theta - VERBOSE("Generate New Covariance Matrix...") + VERBOSE("\tGenerate New Covariance Matrix...") START_TIMING(matrix_gen_time); if (kernel_name == "bivariate_matern_parsimonious2" || @@ -162,9 +141,9 @@ 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, - &aKernel); + RuntimeFunctions::CovarianceMatrix(*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]); rho = theta[5] * sqrt((tgamma(theta[3] + 1) * tgamma(theta[4] + 1)) / (tgamma(theta[3]) * tgamma(theta[4]))) * @@ -174,56 +153,78 @@ 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); + RuntimeFunctions::CovarianceMatrix(*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.") univariate3_theta[0] = theta[1]; 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); + RuntimeFunctions::CovarianceMatrix(*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); + RuntimeFunctions::CovarianceMatrix(*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); - VERBOSE("Done.") + VERBOSE("\tDone.") - VERBOSE("Cholesky factorization of Sigma...") + VERBOSE("\tCholesky factorization of Sigma...") START_TIMING(time_facto); this->ExaGeoStatPotrfTile(EXAGEOSTAT_LOWER, CHAM_desc_C, aConfigurations.GetBand(), nullptr, nullptr, 0, 0); STOP_TIMING(time_facto); flops += flops_dpotrf(n); - VERBOSE("Done.") + VERBOSE("\tDone.") //Calculate log(|C|) --> log(square(|L|)) - VERBOSE("Calculating the log determinant ...") + VERBOSE("\tCalculating the log determinant ...") START_TIMING(logdet_calculate); - this->ExaGeoStatMeasureDetTileAsync(CHAM_desc_C, pSequence, &request_array, CHAM_desc_det); + RuntimeFunctions::ExaGeoStatMeasureDetTileAsync(aConfigurations.GetComputation(), CHAM_desc_C, pSequence, + &request_array, CHAM_desc_det); this->ExaGeoStatSequenceWait(pSequence); logdet = 2 * (*determinant); STOP_TIMING(logdet_calculate); - VERBOSE("Done.") + VERBOSE("\tDone.") + + if (aConfigurations.GetIsNonGaussian()) { + VERBOSE("Transform Z vector to Gaussian field ...") + RuntimeFunctions::ExaGeoStatNonGaussianTransformTileAsync(aConfigurations.GetComputation(), CHAM_desc_Z, + (T *) theta, pSequence, &request_array[0]); + this->ExaGeoStatSequenceWait(pSequence); + VERBOSE("\tDone.") + + CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_desc_Z, CHAM_desc_Z, 0, CHAM_desc_product); + + VERBOSE("Calculate non-Gaussian loglik ...") + RuntimeFunctions::ExaGeoStatNonGaussianLogLikeTileAsync(aConfigurations.GetComputation(), CHAM_desc_Z, + CHAM_desc_sum, (T *) theta, pSequence, + &request_array[0]); + this->ExaGeoStatSequenceWait(pSequence); + VERBOSE("\tDone.") + } // Solving Linear System (L*X=Z)--->inv(L)*Z - VERBOSE("Solving the linear system ...") + VERBOSE("\tSolving the linear system ...") START_TIMING(time_solve); this->ExaGeoStatTrsmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_NO_TRANS, EXAGEOSTAT_NON_UNIT, 1, CHAM_desc_C, nullptr, nullptr, CHAM_desc_Z, 0); STOP_TIMING(time_solve); flops += flops_dtrsm(ChamLeft, n, nhrs); - VERBOSE("Done.") + VERBOSE("\tDone.") //Calculate MLE likelihood VERBOSE("Calculating the MLE likelihood function ...") - ExaGeoStatDoubleDotProduct(CHAM_desc_Z, CHAM_desc_product, pSequence, request_array); + RuntimeFunctions::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); @@ -235,7 +236,8 @@ T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardwa } else if (kernel_name == "BivariateMaternParsimoniousProfile") { loglik = -(n / 2) + (n / 2) * log(n) - (n / 2) * log(dot_product) - 0.5 * logdet - (double) (n / 2.0) * log(2.0 * PI); - this->ExaGeoStaStrideVectorTileAsync(CHAM_desc_Z, CHAM_desc_Z1, CHAM_desc_Z2, pSequence, &request_array[0]); + RuntimeFunctions::ExaGeoStaStrideVectorTileAsync(CHAM_desc_Z, CHAM_desc_Z1, CHAM_desc_Z2, pSequence, + &request_array[0]); CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_desc_Z1, CHAM_desc_Z1, 0, CHAM_desc_product1); CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_desc_Z2, CHAM_desc_Z2, 0, CHAM_desc_product2); variance1 = (1.0 / (n / 2)) * dot_product1; @@ -245,8 +247,8 @@ T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardwa loglik = -(n / 3.0) + (n / 3.0) * log(n / 3.0) - (n / 3.0) * log(dot_product) - 0.5 * logdet - (double) (n / 3.0) * log(2.0 * PI); //to be optimized - this->ExaGeoStaStrideVectorTileAsync(CHAM_desc_Z, CHAM_desc_Z1, CHAM_desc_Z2, CHAM_desc_Z3, pSequence, - &request_array[0]); + RuntimeFunctions::ExaGeoStaStrideVectorTileAsync(CHAM_desc_Z, CHAM_desc_Z1, CHAM_desc_Z2, CHAM_desc_Z3, + pSequence, &request_array[0]); CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_desc_Z1, CHAM_desc_Z1, 0, CHAM_desc_product1); CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_desc_Z2, CHAM_desc_Z2, 0, CHAM_desc_product2); CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_desc_Z3, CHAM_desc_Z3, 0, CHAM_desc_product3); @@ -254,19 +256,24 @@ 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.") + VERBOSE("\tDone.") //Distribute the values in the case of MPI -#if defined(CHAMELEON_USE_MPI) - MPI_Bcast(&loglik, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD ); +#ifdef USE_MPI + MPI_Bcast(&loglik, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); #endif - LOGGER(iter_count + 1 << " - Model Parameters (", true) + LOGGER("\t" << iter_count + 1 << " - Model Parameters (", true) if (aConfigurations.GetLogger()) { - fprintf(aConfigurations.GetFileLogPath(), " %3d- Model Parameters (", iter_count + 1); + fprintf(aConfigurations.GetFileLogPath(), "\t %d- Model Parameters (", iter_count + 1); } if ((aConfigurations.GetKernelName() == "BivariateMaternParsimoniousProfile") || @@ -294,43 +301,33 @@ T ChameleonImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardwa if (aConfigurations.GetLogger()) { fprintf(aConfigurations.GetFileLogPath(), ")----> LogLi: %.18f\n", loglik); } - LOGGER(" ---- Facto Time: " << time_facto) - LOGGER(" ---- Log Determent Time: " << logdet_calculate) - LOGGER(" ---- dtrsm Time: " << time_solve) - LOGGER(" ---- Matrix Generation Time: " << matrix_gen_time) - LOGGER(" ---- Total Time: " << time_facto + logdet_calculate + time_solve) - LOGGER(" ---- Gflop/s: " << flops / 1e9 / (time_facto + time_solve)) + VERBOSE("---- Facto Time: " << time_facto) + VERBOSE("---- Log Determent Time: " << logdet_calculate) + VERBOSE("---- dtrsm Time: " << time_solve) + VERBOSE("---- Matrix Generation Time: " << matrix_gen_time) + VERBOSE("---- Total Time: " << time_facto + logdet_calculate + time_solve) + VERBOSE("---- 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 = - results::Results::GetInstance()->GetTotalModelingExecutionTime() + time_facto + logdet_calculate + + Results::GetInstance()->GetTotalModelingExecutionTime() + time_facto + logdet_calculate + time_solve; - results::Results::GetInstance()->SetTotalModelingExecutionTime(accumulated_executed_time); + Results::GetInstance()->SetTotalModelingExecutionTime(accumulated_executed_time); accumulated_flops = - results::Results::GetInstance()->GetTotalModelingFlops() + (flops / 1e9 / (time_facto + time_solve)); - results::Results::GetInstance()->SetTotalModelingFlops(accumulated_flops); + Results::GetInstance()->GetTotalModelingFlops() + (flops / 1e9 / (time_facto + time_solve)); + Results::GetInstance()->SetTotalModelingFlops(accumulated_flops); - results::Results::GetInstance()->SetMLEIterations(iter_count + 1); - results::Results::GetInstance()->SetMaximumTheta(vector(theta, theta + num_params)); - results::Results::GetInstance()->SetLogLikValue(loglik); + Results::GetInstance()->SetMLEIterations(iter_count + 1); + Results::GetInstance()->SetMaximumTheta(vector(theta, theta + num_params)); + 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) { +void ChameleonImplementation::ExaGeoStatLapackCopyTile(const UpperLower &aUpperLower, void *apA, void *apB) { int status = CHAMELEON_dlacpy_Tile((cham_uplo_t) aUpperLower, (CHAM_desc_t *) apA, (CHAM_desc_t *) apB); if (status != CHAMELEON_SUCCESS) { throw std::runtime_error("CHAMELEON_dlacpy_Tile Failed!"); @@ -338,13 +335,8 @@ void ChameleonImplementation::ExaGeoStatLapackCopyTile(const common::UpperLow } template -void *ChameleonImplementation::ExaGeoStatDataGetAddr(void *apA, int aAm, int aAn) { - return RUNTIME_data_getaddr((CHAM_desc_t *) apA, aAm, aAn); -} - -template -void ChameleonImplementation::ExaGeoStatTrsmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, - const common::Trans &aTrans, const common::Diag &aDiag, +void ChameleonImplementation::ExaGeoStatTrsmTile(const Side &aSide, const UpperLower &aUpperLower, + const Trans &aTrans, const Diag &aDiag, const T &aAlpha, void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) { int status = CHAMELEON_dtrsm_Tile((cham_side_t) aSide, (cham_uplo_t) aUpperLower, (cham_trans_t) aTrans, @@ -369,137 +361,3 @@ void ChameleonImplementation::ExaGeoStatCreateSequence(void *apSequence) { throw std::runtime_error("CHAMELEON_Sequence_Create Failed!"); } } - -template -void -ChameleonImplementation::ExaGeoStatOptionsInit(void *apOptions, void *apContext, void *apSequence, void *apRequest) { - RUNTIME_options_init((RUNTIME_option_t *) apOptions, (CHAM_context_t *) apContext, - (RUNTIME_sequence_t *) apSequence, (RUNTIME_request_t *) apRequest); -} - -template -void ChameleonImplementation::ExaGeoStatOptionsFree(void *apOptions) { - RUNTIME_options_ws_free((RUNTIME_option_t *) apOptions); -} - -template -void ChameleonImplementation::ExaGeoStatOptionsFinalize(void *apOptions, void *apContext) { - RUNTIME_options_finalize((RUNTIME_option_t *) apOptions, (CHAM_context_t *) apContext); -} - -template -int ChameleonImplementation::ExaGeoStatMeasureDetTileAsync(void *apDescA, void *apSequence, void *apRequest, - void *apDescDet) { - - // 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; - int temp; - auto Z = (CHAM_desc_t *) apDescA; - auto det = (CHAM_desc_t *) apDescDet; - struct starpu_codelet *cl = &this->cl_dmdet; - - for (m = 0; m < Z->mt; m++) { - temp = m == Z->mt - 1 ? Z->m - m * Z->mb : Z->mb; - starpu_insert_task(cl, - STARPU_VALUE, &temp, sizeof(int), - STARPU_R, ExaGeoStatDataGetAddr(Z, m, m), - STARPU_RW, ExaGeoStatDataGetAddr(det, 0, 0), - 0); - } - this->ExaGeoStatOptionsFree(&options); - this->ExaGeoStatOptionsFinalize(&options, (CHAM_context_t *) this->mpContext); - return CHAMELEON_SUCCESS; -} - -template -int ChameleonImplementation::ExaGeoStaStrideVectorTileAsync(void *apDescA, void *apDescB, void *apDescC, - 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 A = (CHAM_desc_t *) apDescA; - auto B = (CHAM_desc_t *) apDescB; - auto C = (CHAM_desc_t *) apDescC; - struct starpu_codelet *cl = &this->cl_stride_vec; - - for (m = 0; m < A->mt; m++) { - temp = m == A->mt - 1 ? A->m - m * A->mb : A->mb; - m0 = m * A->mb; - starpu_insert_task(cl, - STARPU_VALUE, &temp, sizeof(int), - STARPU_VALUE, &m0, sizeof(int), - STARPU_VALUE, &m, sizeof(int), - STARPU_R, ExaGeoStatDataGetAddr(A, m, 0), - STARPU_W, ExaGeoStatDataGetAddr(B, (int) floor(m / 2.0), 0), - STARPU_W, ExaGeoStatDataGetAddr(C, (int) floor(m / 2.0), 0), -#if defined(CHAMELEON_CODELETS_HAVE_NAME) - STARPU_NAME, "stride_vec", -#endif - 0); - - } - this->ExaGeoStatOptionsFree(&options); - this->ExaGeoStatOptionsFinalize(&options, (CHAM_context_t *) this->mpContext); - return CHAMELEON_SUCCESS; -} - -template -int -ChameleonImplementation::ExaGeoStaStrideVectorTileAsync(void *apDescA, void *apDescB, void *apDescC, void *apDescD, - 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, (CHAM_context_t *) this->mpContext, (RUNTIME_sequence_t *) apSequence, - (RUNTIME_request_t *) apRequest); - - int m, m0; - int temp; - auto A = (CHAM_desc_t *) apDescA; - auto B = (CHAM_desc_t *) apDescB; - auto C = (CHAM_desc_t *) apDescC; - auto D = (CHAM_desc_t *) apDescD; - struct starpu_codelet *cl = &this->cl_tri_stride_vec; - - for (m = 0; m < A->mt; m++) { - temp = m == A->mt - 1 ? A->m - m * A->mb : A->mb; - m0 = m * A->mb; - starpu_insert_task(cl, - STARPU_VALUE, &temp, sizeof(int), - STARPU_VALUE, &m0, sizeof(int), - STARPU_VALUE, &m, sizeof(int), - STARPU_R, ExaGeoStatDataGetAddr(A, m, 0), - STARPU_W, ExaGeoStatDataGetAddr(B, (int) floor(m / 3.0), 0), - STARPU_W, ExaGeoStatDataGetAddr(C, (int) floor(m / 3.0), 0), - STARPU_W, ExaGeoStatDataGetAddr(D, (int) floor(m / 3.0), 0), -#if defined(CHAMELEON_CODELETS_HAVE_NAME) - STARPU_NAME, "tristride_vec", -#endif - 0); - - } - this->ExaGeoStatOptionsFree(&options); - this->ExaGeoStatOptionsFinalize(&options, (CHAM_context_t *) this->mpContext); - return CHAMELEON_SUCCESS; -} \ No newline at end of file diff --git a/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonImplementationDense.cpp b/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp similarity index 62% rename from src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonImplementationDense.cpp rename to src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp index c81d2d98..f08c8c3b 100644 --- a/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonImplementationDense.cpp +++ b/src/linear-algebra-solvers/concrete/chameleon/dense/ChameleonDense.cpp @@ -1,18 +1,20 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file ChameleonImplementationDense.cpp * @brief Dense Tile implementation of linear algebra methods. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-03-20 **/ -#include +#include + +#include using namespace std; @@ -20,10 +22,12 @@ 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"); } + // Due to a leak in dense mode in Chameleon, We had to free the buffer manually. + mkl_free_buffers(); } \ No newline at end of file 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 89% 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..cc58316b 100644 --- a/src/linear-algebra-solvers/concrete/chameleon/diagonal-super-tile/ChameleonImplementationDST.cpp +++ b/src/linear-algebra-solvers/concrete/chameleon/dst/ChameleonDST.cpp @@ -1,18 +1,18 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file ChameleonImplementationDST.cpp * @brief Diagonal Super Tile implementation of linear algebra methods. - * @version 1.0.0 + * @version 1.1.0 * @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/tile-low-rank/HicmaImplementation.cpp deleted file mode 100644 index c8a2b852..00000000 --- a/src/linear-algebra-solvers/concrete/tile-low-rank/HicmaImplementation.cpp +++ /dev/null @@ -1,395 +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 HicmaImplementation.cpp - * @brief Sets up the HiCMA descriptors needed for the tile low rank computations in ExaGeoStat. - * @version 1.0.0 - * @author Mahmoud ElKarargy - * @author Sameh Abdulah - * @date 2023-03-26 -**/ - -#include - -using namespace std; - -using namespace exageostat::linearAlgebra::tileLowRank; -using namespace exageostat::common; -using namespace exageostat::dataunits; -using namespace exageostat::kernels; -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) { - - int N = aConfigurations.GetProblemSize(); - int lts = aConfigurations.GetLowTileSize(); - int p_grid = aConfigurations.GetPGrid(); - int q_grid = aConfigurations.GetQGrid(); - bool is_OOC = aConfigurations.GetIsOOC(); - int max_rank = aConfigurations.GetMaxRank(); - - // Set the floating point precision based on the template type - FloatPoint float_point; - if (sizeof(T) == SIZE_OF_FLOAT) { - float_point = EXAGEOSTAT_REAL_FLOAT; - } else if (sizeof(T) == SIZE_OF_DOUBLE) { - float_point = EXAGEOSTAT_REAL_DOUBLE; - } else { - throw runtime_error("Unsupported for now!"); - } - - int MBD = lts; - int NBD = lts; - int MD = N; - 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); - 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) { - MUV = N_over_lts_times_lts + lts; - } else if (N_over_lts_times_lts == N) { - 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; - 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); -} - -template -T HicmaImplementation::ExaGeoStatMLETile(const hardware::ExaGeoStatHardware &aHardware, ExaGeoStatData &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); - } - // 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()) { - HICMA_sequence_t *sequence; - this->ExaGeoStatCreateSequence(&sequence); - aData.GetDescriptorData()->SetSequence(sequence); - aData.GetDescriptorData()->SetRequest(request_array); - } - 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; - double accumulated_executed_time, accumulated_flops; - - int NRHS, i; - T flops = 0.0; - - int N; - int lts; - int max_rank = aConfigurations.GetMaxRank(); - 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); - } - 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; - - N = HICMA_descCUV->m; - NRHS = HICMA_descZ->n; - lts = HICMA_descZ->mb; - - T *determinant = aData.GetDescriptorData()->GetDescriptorMatrix(HICMA_DESCRIPTOR, HICMA_desc_det); - *determinant = 0; - T *product = aData.GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, CHAM_desc_product); - *product = 0; - - 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; - // 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. - CHAMELEON_dlacpy_Tile(ChamUpperLower, CHAM_descZ, CHAM_descZcpy); - } - } - //Matrix generation part. - VERBOSE("LR:Generate New Covariance Matrix...") - START_TIMING(matrix_gen_time); - - HICMA_problem_t hicma_problem; - hicma_problem.theta = (double *) theta; - hicma_problem.noise = 1e-4; - hicma_problem.ndim = 2; - - 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, - &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), - compress_diag, HICMA_descC); - - STOP_TIMING(matrix_gen_time); - VERBOSE("Done.") - //****************************** - VERBOSE("LR: re-Copy z...") - START_TIMING(test_time); - //re-store old Z - this->ExaGeoStatLapackCopyTile(EXAGEOSTAT_UPPER_LOWER, HICMA_descZcpy, HICMA_descZ); - STOP_TIMING(test_time); - VERBOSE("Done.") - - //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); - - STOP_TIMING(time_facto); - flops = flops + flops_dpotrf(N); - VERBOSE("Done.") - - //Calculate log(|C|) --> log(square(|L|)) - VERBOSE("LR:Calculating the log determinant ...") - START_TIMING(logdet_calculate); - ExaGeoStatMeasureDetTileAsync(HICMA_descCD, pSequence, &request_array[0], HICMA_desc_det); - ExaGeoStatSequenceWait(pSequence); - - logdet = 2 * (*determinant); - STOP_TIMING(logdet_calculate); - VERBOSE("Done.") - - //Solving Linear System (L*X=Z)--->inv(L)*Z - VERBOSE("LR:Solving the linear system ...") - START_TIMING(time_solve); - //Compute triangular solve LC*X = Z - this->ExaGeoStatTrsmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_NO_TRANS, EXAGEOSTAT_NON_UNIT, 1, - HICMA_descCUV, HICMA_descCD, HICMA_descCrk, HICMA_descZ, max_rank); - STOP_TIMING(time_solve); - flops = flops + flops_dtrsm(ChamLeft, N, NRHS); - VERBOSE("Done.") - - 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); - VERBOSE("Done.") - - LOGGER(iter_count + 1 << " - Model Parameters (", true) - if (aConfigurations.GetLogger()) { - fprintf(aConfigurations.GetFileLogPath(), " %3d- Model Parameters (", iter_count + 1); - } - if ((aConfigurations.GetKernelName() == "bivariate_matern_parsimonious_profile") || - (aConfigurations.GetKernelName() == "bivariate_matern_parsimonious2_profile")) { - LOGGER(setprecision(8) << variance1 << setprecision(8) << variance2) - if (aConfigurations.GetLogger()) { - fprintf(aConfigurations.GetFileLogPath(), "%.8f, %.8f,", variance1, variance2); - } - i = 2; - } else { - i = 0; - } - - for (; i < num_params; i++) { - LOGGER_PRECISION(theta[i]) - if (i < num_params - 1) { - LOGGER_PRECISION(", ") - } - if (aConfigurations.GetLogger()) { - fprintf(aConfigurations.GetFileLogPath(), "%.8f, ", theta[i]); - } - } - LOGGER_PRECISION(")----> LogLi: " << loglik << "\n", 18) - - if (aConfigurations.GetLogger()) { - fprintf(aConfigurations.GetFileLogPath(), ")----> LogLi: %.18f\n", loglik); - } - - LOGGER(" ---- Facto Time: " << time_facto) - LOGGER(" ---- Log Determent Time: " << logdet_calculate) - LOGGER(" ---- dtrsm Time: " << time_solve) - LOGGER(" ---- Matrix Generation Time: " << matrix_gen_time) - LOGGER(" ---- Total Time: " << time_facto + logdet_calculate + time_solve) - LOGGER(" ---- Gflop/s: " << flops / 1e9 / (time_facto + time_solve)) - - aData.SetMleIterations(aData.GetMleIterations() + 1); - - // for experiments and benchmarking - accumulated_executed_time = - results::Results::GetInstance()->GetTotalModelingExecutionTime() + time_facto + logdet_calculate + - time_solve; - results::Results::GetInstance()->SetTotalModelingExecutionTime(accumulated_executed_time); - accumulated_flops = - results::Results::GetInstance()->GetTotalModelingFlops() + (flops / 1e9 / (time_facto + time_solve)); - results::Results::GetInstance()->SetTotalModelingFlops(accumulated_flops); - - results::Results::GetInstance()->SetMLEIterations(iter_count + 1); - results::Results::GetInstance()->SetMaximumTheta(vector(theta, theta + num_params)); - results::Results::GetInstance()->SetLogLikValue(loglik); - - aConfigurations.SetEstimatedTheta(aConfigurations.GetStartingTheta()); - return loglik; -} - - -template -void HicmaImplementation::ExaGeoStatLapackCopyTile(const UpperLower &aUpperLower, void *apA, void *apB) { - int status = HICMA_dlacpy_Tile(aUpperLower, (HICMA_desc_t *) apA, (HICMA_desc_t *) apB); - if (status != HICMA_SUCCESS) { - throw std::runtime_error("CHAMELEON_dlacpy_Tile Failed!"); - } -} - -template -void -HicmaImplementation::ExaGeoStatOptionsInit(void *apOptions, void *apContext, void *apSequence, void *apRequest) { - HICMA_RUNTIME_options_init((HICMA_option_t *) apOptions, (HICMA_context_t *) apContext, - (HICMA_sequence_t *) apSequence, (HICMA_request_t *) apRequest); -} - -template -void HicmaImplementation::ExaGeoStatOptionsFree(void *apOptions) { - HICMA_RUNTIME_options_ws_free((HICMA_option_t *) apOptions); - -} - -template -void HicmaImplementation::ExaGeoStatSequenceWait(void *apSequence) { - HICMA_Sequence_Wait((HICMA_sequence_t *) apSequence); -} - -template -void HicmaImplementation::ExaGeoStatCreateSequence(void *apSequence) { - int status = HICMA_Sequence_Create((HICMA_sequence_t **) apSequence); - if (status != HICMA_SUCCESS) { - throw std::runtime_error("HICMA_Sequence_Create Failed!"); - } -} - -template -void HicmaImplementation::ExaGeoStatOptionsFinalize(void *apOptions, void *apContext) { - RUNTIME_options_finalize((RUNTIME_option_t *) apOptions, (CHAM_context_t *) apContext); - -} - -template -void HicmaImplementation::ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, - void *apCD, void *apCrk, const int &aMaxRank, const int &aAcc) { - int status = HICMA_dpotrf_Tile(EXAGEOSTAT_LOWER, (HICMA_desc_t *) apA, (HICMA_desc_t *) apCD, - (HICMA_desc_t *) apCrk, aBand, aMaxRank, pow(10, -1.0 * aAcc)); - if (status != HICMA_SUCCESS) { - throw std::runtime_error("HICMA_dpotrf_Tile Failed, Matrix is not positive definite"); - } - -} - -template -void HicmaImplementation::ExaGeoStatTrsmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, - const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, - void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) { - - int status = HICMA_dtrsmd_Tile(aSide, aUpperLower, aTrans, aDiag, aAlpha, (HICMA_desc_t *) apA, - (HICMA_desc_t *) apCD, (HICMA_desc_t *) apCrk, (HICMA_desc_t *) apZ, aMaxRank); - if (status != HICMA_SUCCESS) { - throw std::runtime_error("HICMA_dtrsmd_Tile Failed!"); - } -} - -template -int HicmaImplementation::ExaGeoStatMeasureDetTileAsync(void *apDescA, void *apSequence, void *apRequest, - void *apDescDet) { - - // 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; - int temp; - auto Z = (HICMA_desc_t *) apDescA; - auto det = (HICMA_desc_t *) apDescDet; - struct starpu_codelet *cl = &this->cl_dmdet; - - for (m = 0; m < Z->mt; m++) { - temp = m == Z->mt - 1 ? Z->m - m * Z->mb : Z->mb; - starpu_insert_task(cl, - STARPU_VALUE, &temp, sizeof(int), - STARPU_VALUE, &temp, sizeof(int), - STARPU_R, ExaGeoStatDataGetAddr(Z, m, 0), - STARPU_RW, ExaGeoStatDataGetAddr(det, 0, 0), - 0); - } - this->ExaGeoStatOptionsFree(&options); - this->ExaGeoStatOptionsFinalize(&options, (HICMA_context_t *) - this->mpContext); - return HICMA_SUCCESS; -} - - -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!"); - } -} - -template -void *HicmaImplementation::ExaGeoStatDataGetAddr(void *apA, int aAm, int aAn) { - return HICMA_RUNTIME_data_getaddr((HICMA_desc_t *) apA, aAm, aAn); - -} \ No newline at end of file diff --git a/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp b/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp new file mode 100644 index 00000000..c297bb01 --- /dev/null +++ b/src/linear-algebra-solvers/concrete/tlr/HicmaImplementation.cpp @@ -0,0 +1,404 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file HicmaImplementation.cpp + * @brief Sets up the HiCMA descriptors needed for the tile low rank computations in ExaGeoStat. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-04 +**/ + +#include + +#ifdef USE_MPI + +#include + +#endif + +#include + +using namespace std; + +using namespace exageostat::linearAlgebra::tileLowRank; +using namespace exageostat::common; +using namespace exageostat::runtime; +using namespace exageostat::dataunits; +using namespace exageostat::kernels; +using namespace exageostat::helpers; +using namespace exageostat::results; + +int store_only_diagonal_tiles = 1; +int use_scratch = 1; +int global_check = 0; //used to create dense matrix for accuracy check + +template +void HicmaImplementation::SetModelingDescriptors(std::unique_ptr> &aData, + configurations::Configurations &aConfigurations, const int &aP) { + + int full_problem_size = aConfigurations.GetProblemSize() * aP; + int lts = aConfigurations.GetLowTileSize(); + int p_grid = ExaGeoStatHardware::GetPGrid(); + int q_grid = ExaGeoStatHardware::GetQGrid(); + bool is_OOC = aConfigurations.GetIsOOC(); + int max_rank = aConfigurations.GetMaxRank(); + + // Set the floating point precision based on the template type + FloatPoint float_point; + if (sizeof(T) == SIZE_OF_FLOAT) { + float_point = EXAGEOSTAT_REAL_FLOAT; + } else if (sizeof(T) == SIZE_OF_DOUBLE) { + float_point = EXAGEOSTAT_REAL_DOUBLE; + } else { + throw runtime_error("Unsupported for now!"); + } + + int MBD = lts; + int NBD = lts; + int MD = full_problem_size; + int ND = MBD; +#ifdef USE_MPI + // Due to a bug in HiCMA with MPI, the first created descriptor is not seen. + aData->GetDescriptorData()->SetDescriptor(common::HICMA_DESCRIPTOR, DESCRIPTOR_CD, is_OOC, nullptr, float_point, + lts, lts, lts * lts, full_problem_size, 1, 0, 0, full_problem_size, 1, + p_grid, q_grid); +#endif + 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 = 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 == 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; + 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, 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); + aData->GetDescriptorData()->SetDescriptor(common::HICMA_DESCRIPTOR, DESCRIPTOR_DETERMINANT, is_OOC, nullptr, + float_point, lts, lts, lts * lts, 1, 1, 0, 0, 1, 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(std::unique_ptr> &aData, + configurations::Configurations &aConfigurations, const double *theta, + T *apMeasurementsMatrix, const Kernel &aKernel) { + + if (!aData->GetDescriptorData()->GetIsDescriptorInitiated()) { + this->InitiateDescriptors(aConfigurations, *aData->GetDescriptorData(), aKernel.GetVariablesNumber(), + 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()) { + HICMA_sequence_t *sequence; + this->ExaGeoStatCreateSequence(&sequence); + aData->GetDescriptorData()->SetSequence(sequence); + aData->GetDescriptorData()->SetRequest(request_array); + } + 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; + double accumulated_executed_time, accumulated_flops; + + int NRHS, i; + T flops = 0.0; + + int N; + int lts; + int max_rank = aConfigurations.GetMaxRank(); + 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, 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_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, DESCRIPTOR_DETERMINANT); + *determinant = 0; + T *product = aData->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_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) { + // 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. + CHAMELEON_dlacpy_Tile(ChamUpperLower, CHAM_descZ, CHAM_descZcpy); + } + } + //Matrix generation part. + VERBOSE("LR:Generate New Covariance Matrix...") + START_TIMING(matrix_gen_time); + + HICMA_problem_t hicma_problem; + hicma_problem.theta = (double *) theta; + hicma_problem.noise = 1e-4; + hicma_problem.ndim = 2; + + hicma_problem.kernel_type = + aConfigurations.GetDistanceMetric() == common::GREAT_CIRCLE_DISTANCE ? STARSH_SPATIAL_MATERN2_GCD + : STARSH_SPATIAL_MATERN2_SIMD; + 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), + compress_diag, HICMA_descC); + + STOP_TIMING(matrix_gen_time); + VERBOSE("Done.") + //****************************** + VERBOSE("LR: re-Copy z...") + START_TIMING(test_time); + //re-store old Z + this->ExaGeoStatLapackCopyTile(EXAGEOSTAT_UPPER_LOWER, HICMA_descZcpy, HICMA_descZ); + STOP_TIMING(test_time); + VERBOSE("Done.") + + //Calculate Cholesky Factorization (C=LL-1) + VERBOSE("LR: Cholesky factorization of Sigma...") + START_TIMING(time_facto); + this->ExaGeoStatPotrfTile(EXAGEOSTAT_LOWER, HICMA_descCUV, 0, HICMA_descCD, HICMA_descCrk, max_rank, + pow(10, -1.0 * acc)); + + STOP_TIMING(time_facto); + flops = flops + flops_dpotrf(N); + VERBOSE("Done.") + + //Calculate log(|C|) --> log(square(|L|)) + VERBOSE("LR:Calculating the log determinant ...") + START_TIMING(logdet_calculate); + RuntimeFunctions::ExaGeoStatMeasureDetTileAsync(aConfigurations.GetComputation(), HICMA_descCD, pSequence, + &request_array[0], HICMA_desc_det); + ExaGeoStatSequenceWait(pSequence); + logdet = 2 * (*determinant); + STOP_TIMING(logdet_calculate); + VERBOSE("Done.") + + if (aConfigurations.GetIsNonGaussian()) { + VERBOSE("Transform Z vector to Gaussian field ...") + RuntimeFunctions::ExaGeoStatNonGaussianTransformTileAsync(aConfigurations.GetComputation(), HICMA_descZ, + (T *) theta, pSequence, &request_array[0]); + ExaGeoStatSequenceWait(pSequence); + + VERBOSE(" Done.") + sum = aData->GetDescriptorData()->GetDescriptorMatrix(HICMA_DESCRIPTOR, DESCRIPTOR_SUM); + *sum = 0; + + VERBOSE("LR:Calculating dot product...") + CHAMELEON_dgemm_Tile(ChamTrans, ChamNoTrans, 1, CHAM_descZ, CHAM_descZ, 0, CHAM_desc_product); + VERBOSE(" Done.") + +#ifdef USE_MPI + double global_sum; + double local_sum = *product; + MPI_Allreduce(&local_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); +#endif + RuntimeFunctions::ExaGeoStatNonGaussianLogLikeTileAsync(aConfigurations.GetComputation(), 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); + //Compute triangular solve LC*X = Z + this->ExaGeoStatTrsmTile(EXAGEOSTAT_LEFT, EXAGEOSTAT_LOWER, EXAGEOSTAT_NO_TRANS, EXAGEOSTAT_NON_UNIT, 1, + HICMA_descCUV, HICMA_descCD, HICMA_descCrk, HICMA_descZ, max_rank); + STOP_TIMING(time_solve); + 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; + 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("\t" << iter_count + 1 << " - Model Parameters (", true) + if (aConfigurations.GetLogger()) { + fprintf(aConfigurations.GetFileLogPath(), "\t %d- Model Parameters (", iter_count + 1); + } + if ((aConfigurations.GetKernelName() == "bivariate_matern_parsimonious_profile") || + (aConfigurations.GetKernelName() == "bivariate_matern_parsimonious2_profile")) { + LOGGER(setprecision(8) << variance1 << setprecision(8) << variance2) + if (aConfigurations.GetLogger()) { + fprintf(aConfigurations.GetFileLogPath(), "%.8f, %.8f,", variance1, variance2); + } + i = 2; + } else { + i = 0; + } + + for (; i < num_params; i++) { + LOGGER_PRECISION(theta[i]) + if (i < num_params - 1) { + LOGGER_PRECISION(", ") + } + if (aConfigurations.GetLogger()) { + fprintf(aConfigurations.GetFileLogPath(), "%.8f, ", theta[i]); + } + } + LOGGER_PRECISION(")----> LogLi: " << loglik << "\n", 18) + + if (aConfigurations.GetLogger()) { + fprintf(aConfigurations.GetFileLogPath(), ")----> LogLi: %.18f\n", loglik); + } + + VERBOSE(" ---- Facto Time: " << time_facto) + VERBOSE(" ---- Log Determent Time: " << logdet_calculate) + VERBOSE(" ---- dtrsm Time: " << time_solve) + VERBOSE(" ---- Matrix Generation Time: " << matrix_gen_time) + VERBOSE(" ---- Total Time: " << time_facto + logdet_calculate + time_solve) + VERBOSE(" ---- Gflop/s: " << flops / 1e9 / (time_facto + time_solve)) + + aData->SetMleIterations(aData->GetMleIterations() + 1); + + // for experiments and benchmarking + accumulated_executed_time = + Results::GetInstance()->GetTotalModelingExecutionTime() + time_facto + logdet_calculate + + time_solve; + Results::GetInstance()->SetTotalModelingExecutionTime(accumulated_executed_time); + accumulated_flops = + Results::GetInstance()->GetTotalModelingFlops() + (flops / 1e9 / (time_facto + time_solve)); + Results::GetInstance()->SetTotalModelingFlops(accumulated_flops); + + Results::GetInstance()->SetMLEIterations(iter_count + 1); + Results::GetInstance()->SetMaximumTheta(vector(theta, theta + num_params)); + Results::GetInstance()->SetLogLikValue(loglik); + + aConfigurations.SetEstimatedTheta(aConfigurations.GetStartingTheta()); + // Due to a leak in HiCMA in ZGEMM, We had to free the buffer manually. + mkl_free_buffers(); + + return loglik; +} + + +template +void HicmaImplementation::ExaGeoStatLapackCopyTile(const UpperLower &aUpperLower, void *apA, void *apB) { + int status = HICMA_dlacpy_Tile(aUpperLower, (HICMA_desc_t *) apA, (HICMA_desc_t *) apB); + if (status != HICMA_SUCCESS) { + throw std::runtime_error("CHAMELEON_dlacpy_Tile Failed!"); + } +} + +template +void HicmaImplementation::ExaGeoStatSequenceWait(void *apSequence) { + HICMA_Sequence_Wait((HICMA_sequence_t *) apSequence); +} + +template +void HicmaImplementation::ExaGeoStatCreateSequence(void *apSequence) { + int status = HICMA_Sequence_Create((HICMA_sequence_t **) apSequence); + if (status != HICMA_SUCCESS) { + throw std::runtime_error("HICMA_Sequence_Create Failed!"); + } +} + +template +void HicmaImplementation::ExaGeoStatPotrfTile(const common::UpperLower &aUpperLower, void *apA, int aBand, + void *apCD, void *apCrk, const int &aMaxRank, const int &aAcc) { + int status = HICMA_dpotrf_Tile(EXAGEOSTAT_LOWER, (HICMA_desc_t *) apA, (HICMA_desc_t *) apCD, + (HICMA_desc_t *) apCrk, aBand, aMaxRank, pow(10, -1.0 * aAcc)); + if (status != HICMA_SUCCESS) { + throw std::runtime_error("HICMA_dpotrf_Tile Failed, Matrix is not positive definite"); + } + +} + +template +void HicmaImplementation::ExaGeoStatTrsmTile(const common::Side &aSide, const common::UpperLower &aUpperLower, + const common::Trans &aTrans, const common::Diag &aDiag, const T &aAlpha, + void *apA, void *apCD, void *apCrk, void *apZ, const int &aMaxRank) { + + int status = HICMA_dtrsmd_Tile(aSide, aUpperLower, aTrans, aDiag, aAlpha, (HICMA_desc_t *) apA, + (HICMA_desc_t *) apCD, (HICMA_desc_t *) apCrk, (HICMA_desc_t *) apZ, aMaxRank); + if (status != HICMA_SUCCESS) { + throw std::runtime_error("HICMA_dtrsmd_Tile Failed!"); + } +} diff --git a/src/prediction/CMakeLists.txt b/src/prediction/CMakeLists.txt index 63a1f946..1de78426 100644 --- a/src/prediction/CMakeLists.txt +++ b/src/prediction/CMakeLists.txt @@ -1,10 +1,10 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-06-08 diff --git a/src/prediction/Prediction.cpp b/src/prediction/Prediction.cpp index 1550c5df..2cf565c2 100644 --- a/src/prediction/Prediction.cpp +++ b/src/prediction/Prediction.cpp @@ -1,30 +1,36 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file Prediction.cpp * @brief Contains the implementation of the Prediction class. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-06-08 + * @date 2024-02-04 **/ +#include +#include + #include #include #include #include +using namespace std; + using namespace exageostat::prediction; -using namespace exageostat::configurations; using namespace exageostat::dataunits; +using namespace exageostat::results; +using namespace exageostat::configurations; template -void Prediction::PredictMissingData(const hardware::ExaGeoStatHardware &aHardware, ExaGeoStatData &aData, - Configurations &aConfigurations, T *apMeasurementsMatrix, - const kernels::Kernel &aKernel) { +void Prediction::PredictMissingData(unique_ptr> &aData, Configurations &aConfigurations, + T *apMeasurementsMatrix, const kernels::Kernel &aKernel, + Locations *apTrainLocations, Locations *apTestLocations) { int i, j; bool can_predict = true; @@ -35,112 +41,161 @@ void Prediction::PredictMissingData(const hardware::ExaGeoStatHardware &aHard break; } } - if (!can_predict && (aConfigurations.GetIsMLOEMMOM() || aConfigurations.GetIsMSPE() || aConfigurations.GetIsFisher())) { - throw std::runtime_error( + + if (!can_predict && + (aConfigurations.GetIsMLOEMMOM() || aConfigurations.GetIsMSPE() || aConfigurations.GetIsFisher())) { + throw 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 z_miss_number = aConfigurations.GetUnknownObservationsNb(); - int n_z_obs = aConfigurations.CalculateZObsNumber(); + int p = aKernel.GetVariablesNumber(); + int z_miss_number, n_z_obs; + T *z_actual; + if (!apTrainLocations && !apTestLocations) { + z_miss_number = aConfigurations.GetUnknownObservationsNb(); + n_z_obs = aConfigurations.CalculateZObsNumber(); + z_actual = new T[z_miss_number * p]; + } else { + z_miss_number = apTestLocations->GetSize(); + n_z_obs = apTrainLocations->GetSize(); + z_actual = nullptr; + } + aConfigurations.SetObservationNumber(n_z_obs); auto linear_algebra_solver = linearAlgebra::LinearAlgebraFactory::CreateLinearAlgebraSolver(common::EXACT_DENSE); - //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); - - 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])) + VERBOSE("\t- Total number of Z: " << aConfigurations.GetProblemSize()) + LOGGER("\t- Number of Z Miss: " << z_miss_number) + LOGGER("\t- Number of Z observations: " << n_z_obs) - 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 ++){ - LOGGER(" ", true) - for (j = 0; j < num_params; j++){ - LOGGER_PRECISION(fisher_results[i * num_params + j] , 18) + // FISHER Prediction Function Call + if (aConfigurations.GetIsFisher()) { + LOGGER("\t---- Using Prediction Function Fisher ----") + T *fisher_results; + fisher_results = linear_algebra_solver->ExaGeoStatFisherTile(aConfigurations, aData, + (T *) aConfigurations.GetEstimatedTheta().data(), + aKernel); + vector fisher_vector; + fisher_vector.reserve(num_params * num_params); // Reserve memory in advance for efficiency + for (size_t idx = 0; idx < num_params * num_params; ++idx) { + fisher_vector.push_back(fisher_results[idx]); + } + Results::GetInstance()->SetFisherMatrix(fisher_vector); + VERBOSE("\t\t- Sd of sigma2, alpha, nu: " << sqrt(fisher_results[0]) << " " << sqrt(fisher_results[4]) << " " + << sqrt(fisher_results[8])) + VERBOSE("\t\t- CI for sigma2: " << aConfigurations.GetEstimatedTheta()[0] - Q_NORM * sqrt(fisher_results[0]) + << " " + << aConfigurations.GetEstimatedTheta()[0] + Q_NORM * sqrt(fisher_results[0])) + + VERBOSE("\t\t- CI for alpha: " << aConfigurations.GetEstimatedTheta()[1] - Q_NORM * sqrt(fisher_results[4]) + << " " + << aConfigurations.GetEstimatedTheta()[1] + Q_NORM * sqrt(fisher_results[4])) + VERBOSE("\t\t- CI for nu: " << aConfigurations.GetEstimatedTheta()[2] - Q_NORM * sqrt(fisher_results[8]) << " " + << aConfigurations.GetEstimatedTheta()[2] + Q_NORM * sqrt(fisher_results[8])) + + LOGGER("\t\t- Fisher Matrix:") + for (i = 0; i < num_params; i++) { + LOGGER("\t\t ", true) + for (j = 0; j < num_params; j++) { + LOGGER_PRECISION(fisher_results[i * num_params + j], 18) if (j != num_params - 1) { LOGGER_PRECISION(", ") } } LOGGER("") } - LOGGER("") 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]; - 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. + Results::GetInstance()->SetZMiss(z_miss_number); + aConfigurations.SetUnknownObservationsNb(z_miss_number); + T *z_obs = new T[n_z_obs * p]; + T *z_miss = new T[z_miss_number]; + vector avg_pred_value(number_of_mspe); + 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, apTrainLocations, apTestLocations); // MLOE MMOM Auxiliary Function Call if (aConfigurations.GetIsMLOEMMOM()) { LOGGER("---- Using Auxiliary Function MLOE MMOM ----") - linear_algebra_solver->ExaGeoStatMLETileMLOEMMOM(aConfigurations, aData, aHardware, + linear_algebra_solver->ExaGeoStatMLETileMLOEMMOM(aConfigurations, aData, (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 if (aConfigurations.GetIsIDW()) { - LOGGER("---- Using Auxiliary Function IDW ----") + LOGGER("\t---- Using Auxiliary Function IDW ----") T *mspe = new T[number_of_mspe]; + + if (!z_actual) { + z_actual = new T[z_miss_number * p]; + memcpy(z_actual, apMeasurementsMatrix + n_z_obs, z_miss_number * sizeof(T)); + } + PredictionAuxiliaryFunctions::PredictIDW(z_miss, z_actual, z_obs, z_miss_number, n_z_obs, *miss_locations, *obs_locations, mspe); - LOGGER("- Average prediction Error (IDW): ", true) - for (i = 0; i < number_of_mspe; i++) { - avg_pred_value[i] += mspe[i]; - LOGGER_PRECISION(avg_pred_value[i], 9) - if (i != number_of_mspe - 1) { - LOGGER_PRECISION(", ") - } + vector idw_error; + idw_error.reserve(number_of_mspe); // Reserve memory in advance for efficiency + for (size_t idx = 0; idx < number_of_mspe; ++idx) { + idw_error.push_back(mspe[idx]); } - results::Results::GetInstance()->SetIDWError( - std::vector(avg_pred_value.data(), avg_pred_value.data() + number_of_mspe)); - LOGGER("") + + Results::GetInstance()->SetIDWError(idw_error); delete[] mspe; } // 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); + LOGGER("\t---- Using MSPE ----") + 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, + 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, aConfigurations, + *miss_locations, *obs_locations, + aKernel); + } for (i = 0; i < number_of_mspe; i++) { avg_pred_value[i] += prediction_error_mspe[i]; } - LOGGER("- Average prediction Error (mspe): ", true) - for (i = 0; i < number_of_mspe; i++) { - LOGGER_PRECISION(avg_pred_value[i] << "\t", 8) + vector z_miss_vector; + z_miss_vector.reserve(z_miss_number); // Reserve memory in advance for efficiency + for (size_t idx = 0; idx < z_miss_number; ++idx) { + z_miss_vector.push_back(z_miss[idx]); + } + Results::GetInstance()->SetPredictedMissedValues(z_miss_vector); + if (z_actual) { + LOGGER("\t\t- MSPE: " << avg_pred_value[0]) } - LOGGER("") delete[] prediction_error_mspe; } + + // Due to a leak in Chameleon, exactly trsm We had to free the buffer manually. + mkl_free_buffers(); + delete[] z_obs; delete[] z_miss; delete[] z_actual; @@ -149,15 +204,31 @@ void Prediction::PredictMissingData(const hardware::ExaGeoStatHardware &aHard } template -void Prediction::InitializePredictionArguments(Configurations &aConfigurations, ExaGeoStatData &aData, - std::unique_ptr> &aLinearAlgebraSolver, +void Prediction::InitializePredictionArguments(Configurations &aConfigurations, unique_ptr> &aData, + unique_ptr> &aLinearAlgebraSolver, T *apZObs, T *apZActual, Locations &aMissLocation, - Locations &aObsLocation, T *apMeasurementsMatrix) { - - int N = aConfigurations.GetProblemSize(); - T *z = new T[N]; - - aLinearAlgebraSolver->ExaGeoStatGetZObs(aConfigurations, z, N, *aData.GetDescriptorData(), apMeasurementsMatrix); - PredictionHelpers::PickRandomPoints(aConfigurations, aData, apZObs, apZActual, z, aMissLocation, aObsLocation); + Locations &aObsLocation, T *apMeasurementsMatrix, const int &aP, + Locations *apTrainLocations, Locations *apTestLocations) { + + int full_problem_size = aConfigurations.GetProblemSize() * aP; + T *z = new T[full_problem_size]; + + aLinearAlgebraSolver->ExaGeoStatGetZObs(aConfigurations, z, full_problem_size, *aData->GetDescriptorData(), + apMeasurementsMatrix, aP); + + if (!apTrainLocations && !apTestLocations) { + PredictionHelpers::PickRandomPoints(aConfigurations, aData, apZObs, apZActual, z, aMissLocation, + aObsLocation, aP); + } else { + for (int i = 0; i < apTrainLocations->GetSize(); ++i) { + aObsLocation.GetLocationX()[i] = apTrainLocations->GetLocationX()[i]; + aObsLocation.GetLocationY()[i] = apTrainLocations->GetLocationY()[i]; + } + for (int i = 0; i < apTestLocations->GetSize(); ++i) { + aMissLocation.GetLocationX()[i] = apTestLocations->GetLocationX()[i]; + aMissLocation.GetLocationY()[i] = apTestLocations->GetLocationY()[i]; + } + memcpy(apZObs, apMeasurementsMatrix, aObsLocation.GetSize() * sizeof(T)); + } delete[] z; } \ No newline at end of file diff --git a/src/prediction/PredictionAuxiliaryFunctions.cpp b/src/prediction/PredictionAuxiliaryFunctions.cpp index fb89d847..1dc84d28 100644 --- a/src/prediction/PredictionAuxiliaryFunctions.cpp +++ b/src/prediction/PredictionAuxiliaryFunctions.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file PredictionAuxiliaryFunctions.cpp * @brief Contains the implementation of the PredictionAuxiliaryFunctions class. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-06-08 @@ -16,7 +16,7 @@ #include #include -#include +#include using namespace exageostat::prediction; using namespace exageostat::dataunits; @@ -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] << ")") - LOGGER("- Prediction Error (IDW): " << apMSPE[0] << " - " << apMSPE[1] << " - " << apMSPE[2]) + VERBOSE("- Z Actual .. Z Miss") + for (int index = 0; index < aZMissNumber; index++) { + VERBOSE(" (" << apZActual[index] << ", " << apZMiss[index] << ")") + } + LOGGER("\t\t- 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..e4d1b8e9 100644 --- a/src/prediction/PredictionHelpers.cpp +++ b/src/prediction/PredictionHelpers.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file PredictionHelpers.cpp * @brief Contains the implementation of the PredictionHelpers class. - * @version 1.0.0 + * @version 1.1.0 * @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/CMakeLists.txt b/src/results/CMakeLists.txt index 8b7adbbc..e77a4d86 100644 --- a/src/results/CMakeLists.txt +++ b/src/results/CMakeLists.txt @@ -1,10 +1,10 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-09-14 diff --git a/src/results/Results.cpp b/src/results/Results.cpp index 3a919d18..3637fe66 100644 --- a/src/results/Results.cpp +++ b/src/results/Results.cpp @@ -1,21 +1,25 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file Results.cpp * @brief Defines the Results class for storing and accessing result data. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy - * @date 2023-09-14 + * @date 2024-02-04 **/ #include -#include +#include +#include using namespace exageostat::results; using namespace exageostat::common; +using namespace exageostat::configurations; + +using namespace std; Results *Results::GetInstance() { @@ -37,102 +41,84 @@ void Results::SetIsLogger(bool aIsLogger) { this->mIsLogger = aIsLogger; } -void Results::SetLoggerPath(const std::string &aLoggerPath) { +void Results::SetLoggerPath(const string &aLoggerPath) { this->mLoggerPath = aLoggerPath; } void Results::PrintEndSummary() { - Verbose temp = exageostat::configurations::Configurations::GetVerbosity(); - exageostat::configurations::Configurations::SetVerbosity(STANDARD_MODE); - LOGGER("") + Verbose temp = Configurations::GetVerbosity(); + Configurations::SetVerbosity(STANDARD_MODE); LOGGER("********************SUMMARY**********************") - auto locations_number = mGeneratedLocationsNumber; + auto locations_number = this->mGeneratedLocationsNumber; if (locations_number > 0) { - LOGGER("---- Data Generation Results ----") - if (mIsSynthetic) { - LOGGER(" #Synthetic Dataset") - } else { - LOGGER(" #Real Dataset") - } - LOGGER(" #Number of Locations: " << locations_number) - if (mIsLogger && mIsSynthetic) { + LOGGER("#Number of Locations: " << locations_number) + 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("") + VERBOSE("#Total Data Generation Execution Time: " << this->mExecutionTimeDataGeneration) + VERBOSE("#Total Data Generation Gflop/s: " << this->mFlopsDataGeneration) } - if (mMLEIterations > 0) { - LOGGER("---- Data Modeling Results ----") - LOGGER(" #Number of MLE Iterations till reach Maximum: " << mMLEIterations) - LOGGER(" #Found Maximum Theta at: ", true) - for (double i: mMaximumTheta) { + if (this->mMLEIterations > 0) { + LOGGER("#Number of MLE Iterations: " << this->mMLEIterations) + LOGGER("#Found Maximum Theta at: ", true) + for (double i: this->mMaximumTheta) { LOGGER_PRECISION(i << " ", 8) } LOGGER("") - LOGGER(" #Final Log Likelihood value: " << 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("") + LOGGER("#Final Log Likelihood value: " << this->mLogLikValue) + VERBOSE("#Average Time Modeling per Iteration: " << this->GetAverageModelingExecutionTime()) + VERBOSE("#Average Flops per Iteration: " << this->GetAverageModelingFlops()) + VERBOSE("#Total MLE Execution time: " << this->mTotalModelingExecutionTime) + VERBOSE("#Total MLE GFlop/s: " << this->mTotalModelingFlops) } - if (mZMiss > 0) { - LOGGER("---- Data Prediction Results ----") - LOGGER(" #Number of Missing Observations: " << mZMiss) - if (mMSPEError > 0) { - LOGGER(" #MSPE") - LOGGER(" #MSPE Prediction Execution Time: " << mExecutionTimeMSPE) - LOGGER(" #MSPE Gflop/s: " << mFlopsMSPE) - LOGGER(" #Mean Square Error MSPE: " << mMSPEError) + if (this->mZMiss > 0) { + LOGGER("#Number of Missing Observations: " << this->mZMiss) + if (this->mMSPEError > 0) { + VERBOSE("#MSPE Prediction Execution Time: " << this->mExecutionTimeMSPE) + VERBOSE("#MSPE Gflop/s: " << this->mFlopsMSPE) + LOGGER("#Mean Square Error MSPE: " << this->mMSPEError) } - if (!mIDWError.empty()) { - LOGGER(" #IDW") - LOGGER(" #IDW Error: ( ", true) + if (!this->mIDWError.empty()) { + 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) { - 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("") + if (this->mMLOE > 0 || this->mMMOM > 0) { + LOGGER("#MLOE: " << this->mMLOE << "\t\t#MMOM: " << this->mMMOM) + VERBOSE("#MLOE-MMOM Execution Time: " << this->mExecutionTimeMLOEMMOM) + VERBOSE("#MLOE-MMOM Matrix Generation Time: " << this->mGenerationTimeMLOEMMOM) + VERBOSE("#MLOE-MMOM Cholesky Factorization Time: " << this->mFactoTimeMLOEMMOM) + VERBOSE("#MLOE-MMOM Loop Time: " << this->mLoopTimeMLOEMMOM) + VERBOSE("#MLOE-MMOM Number of flops: " << this->mFlopsMLOEMMOM) } } - if(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("") + if (!this->mFisherMatrix.empty()) { + LOGGER("#Sd For Sigma2: " << this->mFisherMatrix[0]) + LOGGER("#Sd For Alpha: " << this->mFisherMatrix[1]) + LOGGER("#Sd For Nu: " << this->mFisherMatrix[2]) + VERBOSE("#Fisher Execution Time: " << this->mTotalFisherTime) } LOGGER("*************************************************") - exageostat::configurations::Configurations::SetVerbosity(temp); + Configurations::SetVerbosity(temp); } void Results::SetMLEIterations(int aIterationsNumber) { this->mMLEIterations = aIterationsNumber; } -void Results::SetMaximumTheta(const std::vector &aMaximumTheta) { +void Results::SetMaximumTheta(const vector &aMaximumTheta) { this->mMaximumTheta = aMaximumTheta; } @@ -148,7 +134,7 @@ void Results::SetMSPEError(double aMSPEError) { this->mMSPEError = aMSPEError; } -void Results::SetIDWError(const std::vector &aIDWError) { +void Results::SetIDWError(const vector &aIDWError) { this->mIDWError = aIDWError; } @@ -180,14 +166,14 @@ double Results::GetAverageModelingExecutionTime() const { if (this->mMLEIterations) { return this->mTotalModelingExecutionTime / this->mMLEIterations; } - throw std::runtime_error("Number of MLE Iterations is not set!"); + throw runtime_error("Number of MLE Iterations is not set!"); } double Results::GetAverageModelingFlops() const { if (this->mMLEIterations) { return this->mTotalModelingFlops / this->mMLEIterations; } - throw std::runtime_error("Number of MLE Iterations is not set!"); + throw runtime_error("Number of MLE Iterations is not set!"); } void Results::SetTotalModelingFlops(double aTime) { @@ -232,14 +218,34 @@ void Results::SetTotalFisherTime(double aTime) { this->mTotalFisherTime = aTime; } -void Results::SetFisher00(double aFisher00) { - this->mFisher00 = aFisher00; +void Results::SetFisherMatrix(vector aFisherMatrix) { + this->mFisherMatrix = std::move(aFisherMatrix); +} + +void Results::SetPredictedMissedValues(vector aPredictedValues) { + this->mPredictedMissedValues = std::move(aPredictedValues); +} + +double Results::GetMLOE() const { + return this->mMLOE; +} + +double Results::GetMSPEError() const { + return this->mMSPEError; +} + +vector Results::GetIDWError() const { + return this->mIDWError; +} + +double Results::GetMMOM() const { + return this->mMMOM; } -void Results::SetFisher11(double aFisher11) { - this->mFisher11 = aFisher11; +std::vector Results::GetFisherMatrix() const { + return this->mFisherMatrix; } -void Results::SetFisher22(double aFisher22) { - this->mFisher22 = aFisher22; +std::vector Results::GetPredictedMissedValues() const { + return this->mPredictedMissedValues; } \ No newline at end of file diff --git a/src/runtime/CMakeLists.txt b/src/runtime/CMakeLists.txt new file mode 100644 index 00000000..74d34df3 --- /dev/null +++ b/src/runtime/CMakeLists.txt @@ -0,0 +1,25 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 1.1.0 +# @brief CMake build script for StarPu functions +# @author Mahmoud ElKarargy +# @date 2024-03-10 + +# Include runtime directory,based on runtime flag. +if ("${RUNTIME_TYPE}" STREQUAL "parsec") + add_subdirectory(parsec) +else () + #by default use StarPu runtime. + add_subdirectory(starpu) +endif () + +# Define the sources for the library +set(SOURCES + ${SOURCES} + PARENT_SCOPE + ) + diff --git a/src/runtime/parsec/CMakeLists.txt b/src/runtime/parsec/CMakeLists.txt new file mode 100644 index 00000000..f1b427db --- /dev/null +++ b/src/runtime/parsec/CMakeLists.txt @@ -0,0 +1,17 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 1.1.0 +# @brief CMake build script for Parsec runtime +# @author Mahmoud ElKarargy +# @date 2024-03-10 + +# Define the sources for the library +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/ParsecFunctions.cpp + ${SOURCES} + PARENT_SCOPE + ) \ No newline at end of file diff --git a/src/runtime/parsec/ParsecFunctions.cpp b/src/runtime/parsec/ParsecFunctions.cpp new file mode 100644 index 00000000..65b0073d --- /dev/null +++ b/src/runtime/parsec/ParsecFunctions.cpp @@ -0,0 +1,87 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ParsecFunctions.cpp + * @brief A class for static functions used in Parsec runtime + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-03-10 +**/ + +#include + +using namespace std; +using namespace exageostat::common; +using namespace exageostat::runtime; +using namespace exageostat::dataunits; + +//TODO: implement parsec functions +template +void RuntimeFunctions::CovarianceMatrix(DescriptorData &aDescriptorData, void *apDescriptor, + const int &aTriangularPart, Locations *apLocation1, + Locations *apLocation2, Locations *apLocation3, + T *apLocalTheta, const int &aDistanceMetric, + const kernels::Kernel *apKernel, void *apContext) {} + +template +void RuntimeFunctions::ExaGeoStatMLETileAsyncMLOEMMOM(void *apDescExpr1, void *apDescExpr2, void *apDescExpr3, + void *apDescMLOE, void *apDescMMOM, void *apSequence, + void *apRequest, void *apContext) {} + +template +void RuntimeFunctions::ExaGeoStatMLEMSPETileAsync(void *apDescZPredict, void *apDescZMiss, void *apDescError, + void *apSequence, void *apRequest, void *apContext) {} + +template +void RuntimeFunctions::CopyDescriptorZ(DescriptorData &aDescriptorData, void *apDescriptor, T *apDoubleVector, + void *apContext) {} + +template +void +RuntimeFunctions::ExaGeoStatGaussianToNonTileAsync(DescriptorData &aDescriptorData, void *apDesc, T *apTheta, + void *apContext) {} + +template +void +RuntimeFunctions::ExaGeoStatMeasureDetTileAsync(const Computation &aComputation, void *apDescA, void *apSequence, + void *apRequest, void *apDescDet, void *apContext) {} + +template +void RuntimeFunctions::ExaGeoStaStrideVectorTileAsync(void *apDescA, void *apDescB, + void *apDescC, void *apSequence, void *apRequest, + void *apContext) {} + +template +void RuntimeFunctions::ExaGeoStaStrideVectorTileAsync(void *apDescA, void *apDescB, void *apDescC, void *apDescD, + void *apSequence, void *apRequest, void *apContext) {} + +template +void +RuntimeFunctions::ExaGeoStatMLETraceTileAsync(void *apDescA, void *apSequence, void *apRequest, void *apDescNum, + void *apDescTrace, void *apContext) {} + +template +void +RuntimeFunctions::ExaGeoStatDoubleDotProduct(void *apDescA, void *apDescProduct, void *apSequence, + void *apRequest, + void *apContext) {} + +template +void +RuntimeFunctions::ExaGeoStatMLEMSPEBivariateTileAsync(void *apDescZPre, void *apDescZMiss, void *apDescsError1, + void *apDescsError2, void *apDescsError, void *apSequence, + void *apRequest, void *apContext) {} + +template +void RuntimeFunctions::ExaGeoStatNonGaussianLogLikeTileAsync(const Computation &aComputation, void *apDescZ, + void *apDescSum, const T *apTheta, void *apSequence, + void *apRequest, void *apContext) {} + +template +void +RuntimeFunctions::ExaGeoStatNonGaussianTransformTileAsync(const Computation &aComputation, void *apDescZ, + const T *apTheta, + void *apSequence, void *apRequest, void *apContext) {} diff --git a/src/runtime/starpu/CMakeLists.txt b/src/runtime/starpu/CMakeLists.txt new file mode 100644 index 00000000..1fce6410 --- /dev/null +++ b/src/runtime/starpu/CMakeLists.txt @@ -0,0 +1,55 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 1.1.0 +# @brief CMake build script for StarPu runtime +# @author Mahmoud ElKarargy +# @date 2024-02-19 + +# Include the concrete implementations of the StarPu codelets classes +file(GLOB ALL_CODELETS ${CMAKE_CURRENT_SOURCE_DIR}/concrete/*.cpp) + +# Include StarPu helpers. +add_subdirectory(helpers) + +# Define the sources for the library +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/StarPuFunctions.cpp + ${ALL_CODELETS} + ${SOURCES} + PARENT_SCOPE + ) + +# Automatically add new codelets header files to StarPuCodeletsHeaders.hpp + +# File documentation +set(DOCUMENTATION_STRING " +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file StarPuCodelets.hpp + * @brief Header file to include all codelet classes. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-25 +**/ + +") + +set(PATH_TO_CODELETS_HEADERS "${PROJECT_SOURCE_DIR}/inst/include/runtime/starpu") +set(GENERATED_INCLUDES "${PATH_TO_CODELETS_HEADERS}/StarPuCodeletsHeaders.hpp") + +file(GLOB_RECURSE HEADER_FILES "${PATH_TO_CODELETS_HEADERS}/concrete/*.hpp") +file(WRITE ${GENERATED_INCLUDES} ${DOCUMENTATION_STRING}) + +foreach (HEADER_FILE ${HEADER_FILES}) + # Construct the include directive by stripping the known base directory part from the full path + string(REPLACE "${PATH_TO_CODELETS_HEADERS}" "" HEADER_RELATIVE_PATH ${HEADER_FILE}) + # Use angle brackets and the desired base path for the include directive + file(APPEND ${GENERATED_INCLUDES} "#include \n") +endforeach () diff --git a/src/runtime/starpu/StarPuFunctions.cpp b/src/runtime/starpu/StarPuFunctions.cpp new file mode 100644 index 00000000..315c1df6 --- /dev/null +++ b/src/runtime/starpu/StarPuFunctions.cpp @@ -0,0 +1,258 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file StarPuFunctions.cpp + * @brief A class for static functions that make use of starpu_codelets. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-28 +**/ + +#include +#include +#include +#include + +using namespace exageostat::common; +using namespace exageostat::runtime; +using namespace exageostat::dataunits; + +template +void RuntimeFunctions::CovarianceMatrix(dataunits::DescriptorData &aDescriptorData, void *apDescriptor, + const int &aTriangularPart, + dataunits::Locations *apLocation1, dataunits::Locations *apLocation2, + dataunits::Locations *apLocation3, T *apLocalTheta, + const int &aDistanceMetric, + const kernels::Kernel *apKernel) { + + auto starpu_helper = StarPuHelpersFactory::CreateStarPuHelper(EXACT_DENSE); + auto *pOptions = starpu_helper->GetOptions(); + starpu_helper->ExaGeoStatOptionsInit(pOptions, aDescriptorData.GetSequence(), + aDescriptorData.GetRequest()); + + DCMGCodelet cl; + cl.InsertTask(apDescriptor, aTriangularPart, apLocation1, apLocation2, apLocation3, apLocalTheta, aDistanceMetric, + apKernel); + + starpu_helper->ExaGeoStatOptionsFree(pOptions); + starpu_helper->ExaGeoStatOptionsFinalize(pOptions); + starpu_helper->DeleteOptions(pOptions); + +} + +template +void RuntimeFunctions::ExaGeoStatMLETileAsyncMLOEMMOM(void *apDescExpr1, void *apDescExpr2, void *apDescExpr3, + void *apDescMLOE, + void *apDescMMOM, void *apSequence, void *apRequest) { + + auto starpu_helper = StarPuHelpersFactory::CreateStarPuHelper(EXACT_DENSE); + auto *pOptions = starpu_helper->GetOptions(); + starpu_helper->ExaGeoStatOptionsInit(pOptions, apSequence, apRequest); + + DmloeMmomCodelet cl; + cl.InsertTask(apDescExpr1, apDescExpr2, apDescExpr3, apDescMLOE, apDescMMOM); + + starpu_helper->ExaGeoStatOptionsFree(pOptions); + starpu_helper->ExaGeoStatOptionsFinalize(pOptions); + starpu_helper->DeleteOptions(pOptions); + +} + +template +void RuntimeFunctions::ExaGeoStatMLEMSPETileAsync(void *apDescZPredict, void *apDescZMiss, void *apDescError, + void *apSequence, + void *apRequest) { + + auto starpu_helper = StarPuHelpersFactory::CreateStarPuHelper(EXACT_DENSE); + auto *pOptions = starpu_helper->GetOptions(); + starpu_helper->ExaGeoStatOptionsInit(pOptions, apSequence, apRequest); + + DMSECodelet cl; + cl.InsertTask(apDescError, apDescZPredict, apDescZMiss); + + starpu_helper->ExaGeoStatOptionsFree(pOptions); + starpu_helper->ExaGeoStatOptionsFinalize(pOptions); + starpu_helper->DeleteOptions(pOptions); + +} + +template +void RuntimeFunctions::CopyDescriptorZ(dataunits::DescriptorData &aDescriptorData, void *apDescriptor, + T *apDoubleVector) { + + auto starpu_helper = StarPuHelpersFactory::CreateStarPuHelper(EXACT_DENSE); + auto *pOptions = starpu_helper->GetOptions(); + starpu_helper->ExaGeoStatOptionsInit(pOptions, aDescriptorData.GetSequence(), + aDescriptorData.GetRequest()); + + DZCPYCodelet cl; + cl.InsertTask(apDescriptor, apDoubleVector); + + starpu_helper->ExaGeoStatOptionsFree(pOptions); + starpu_helper->ExaGeoStatOptionsFinalize(pOptions); + starpu_helper->DeleteOptions(pOptions); + +} + +template +void RuntimeFunctions::ExaGeoStatGaussianToNonTileAsync(dataunits::DescriptorData &aDescriptorData, void *apDesc, + T *apTheta) { + + auto starpu_helper = StarPuHelpersFactory::CreateStarPuHelper(EXACT_DENSE); + auto *pOptions = starpu_helper->GetOptions(); + starpu_helper->ExaGeoStatOptionsInit(pOptions, aDescriptorData.GetSequence(), + aDescriptorData.GetRequest()); + + GaussianCodelet cl; + cl.InsertTask(apDesc, apTheta); + + starpu_helper->ExaGeoStatOptionsFree(pOptions); + starpu_helper->ExaGeoStatOptionsFinalize(pOptions); + starpu_helper->DeleteOptions(pOptions); + +} + +template +void +RuntimeFunctions::ExaGeoStatMeasureDetTileAsync(const common::Computation &aComputation, void *apDescA, + void *apSequence, void *apRequest, + void *apDescDet) { + auto starpu_helper = StarPuHelpersFactory::CreateStarPuHelper(aComputation); + auto *pOptions = starpu_helper->GetOptions(); + starpu_helper->ExaGeoStatOptionsInit(pOptions, apSequence, apRequest); + + DMDETCodelet cl; + cl.InsertTask(aComputation, apDescA, apDescDet, starpu_helper); + + starpu_helper->ExaGeoStatOptionsFree(pOptions); + starpu_helper->ExaGeoStatOptionsFinalize(pOptions); + starpu_helper->DeleteOptions(pOptions); + +} + +template +void RuntimeFunctions::ExaGeoStaStrideVectorTileAsync(void *apDescA, void *apDescB, void *apDescC, void *apSequence, + void *apRequest) { + + auto starpu_helper = StarPuHelpersFactory::CreateStarPuHelper(EXACT_DENSE); + auto *pOptions = starpu_helper->GetOptions(); + starpu_helper->ExaGeoStatOptionsInit(pOptions, apSequence, apRequest); + + STRIDEVECCodelet cl; + cl.InsertTask(apDescA, apDescB, apDescC); + + starpu_helper->ExaGeoStatOptionsFree(pOptions); + starpu_helper->ExaGeoStatOptionsFinalize(pOptions); + starpu_helper->DeleteOptions(pOptions); + +} + +template +void RuntimeFunctions::ExaGeoStaStrideVectorTileAsync(void *apDescA, void *apDescB, void *apDescC, void *apDescD, + void *apSequence, + void *apRequest) { + + auto starpu_helper = StarPuHelpersFactory::CreateStarPuHelper(EXACT_DENSE); + auto *pOptions = starpu_helper->GetOptions(); + starpu_helper->ExaGeoStatOptionsInit(pOptions, apSequence, apRequest); + + TriStrideVecCodelet cl; + cl.InsertTask(apDescA, apDescB, apDescC, apDescD); + + starpu_helper->ExaGeoStatOptionsFree(pOptions); + starpu_helper->ExaGeoStatOptionsFinalize(pOptions); + starpu_helper->DeleteOptions(pOptions); + +} + +template +void RuntimeFunctions::ExaGeoStatMLETraceTileAsync(void *apDescA, void *apSequence, void *apRequest, void *apDescNum, + void *apDescTrace) { + + auto starpu_helper = StarPuHelpersFactory::CreateStarPuHelper(EXACT_DENSE); + auto *pOptions = starpu_helper->GetOptions(); + starpu_helper->ExaGeoStatOptionsInit(pOptions, apSequence, apRequest); + + DTRACECodelet cl; + cl.InsertTask(apDescA, apDescNum, apDescTrace); + + starpu_helper->ExaGeoStatOptionsFree(pOptions); + starpu_helper->ExaGeoStatOptionsFinalize(pOptions); + starpu_helper->DeleteOptions(pOptions); + +} + +template +void +RuntimeFunctions::ExaGeoStatDoubleDotProduct(void *apDescA, void *apDescProduct, void *apSequence, void *apRequest) { + + auto starpu_helper = StarPuHelpersFactory::CreateStarPuHelper(EXACT_DENSE); + auto *pOptions = starpu_helper->GetOptions(); + starpu_helper->ExaGeoStatOptionsInit(pOptions, apSequence, apRequest); + + DDOTPCodelet cl; + cl.InsertTask(apDescA, apDescProduct); + + starpu_helper->ExaGeoStatOptionsFree(pOptions); + starpu_helper->ExaGeoStatOptionsFinalize(pOptions); + starpu_helper->DeleteOptions(pOptions); + +} + +template +void RuntimeFunctions::ExaGeoStatMLEMSPEBivariateTileAsync(void *apDescZPre, void *apDescZMiss, void *apDescError1, + void *apDescError2, + void *apDescError, void *apSequence, void *apRequest) { + auto starpu_helper = StarPuHelpersFactory::CreateStarPuHelper(EXACT_DENSE); + auto *pOptions = starpu_helper->GetOptions(); + starpu_helper->ExaGeoStatOptionsInit(pOptions, apSequence, apRequest); + + DMSEBivariateCodelet cl; + cl.InsertTask(apDescZPre, apDescError, apDescError1, apDescError2, apDescZMiss); + + starpu_helper->ExaGeoStatOptionsFree(pOptions); + starpu_helper->ExaGeoStatOptionsFinalize(pOptions); + starpu_helper->DeleteOptions(pOptions); + +} + +template +void RuntimeFunctions::ExaGeoStatNonGaussianLogLikeTileAsync(const common::Computation &aComputation, void *apDescZ, + void *apDescSum, + const T *apTheta, void *apSequence, void *apRequest) { + + auto starpu_helper = StarPuHelpersFactory::CreateStarPuHelper(aComputation); + void *pOptions = starpu_helper->GetOptions(); + starpu_helper->ExaGeoStatOptionsInit(pOptions, apSequence, apRequest); + + NonGaussianLoglike cl; + cl.InsertTask(apDescZ, apDescSum, apTheta, starpu_helper); + + starpu_helper->ExaGeoStatOptionsFree(pOptions); + starpu_helper->ExaGeoStatOptionsFinalize(pOptions); + starpu_helper->DeleteOptions(pOptions); + +} + +template +void +RuntimeFunctions::ExaGeoStatNonGaussianTransformTileAsync(const common::Computation &aComputation, void *apDescZ, + const T *apTheta, + void *apSequence, void *apRequest) { + + auto starpu_helper = StarPuHelpersFactory::CreateStarPuHelper(aComputation); + void *pOptions = starpu_helper->GetOptions(); + starpu_helper->ExaGeoStatOptionsInit(pOptions, apSequence, apRequest); + + NonGaussianTransform cl; + cl.InsertTask(apDescZ, apTheta, starpu_helper); + + starpu_helper->ExaGeoStatOptionsFree(pOptions); + starpu_helper->ExaGeoStatOptionsFinalize(pOptions); + starpu_helper->DeleteOptions(pOptions); + +} diff --git a/src/runtime/starpu/concrete/dcmg-codelet.cpp b/src/runtime/starpu/concrete/dcmg-codelet.cpp new file mode 100644 index 00000000..71827f84 --- /dev/null +++ b/src/runtime/starpu/concrete/dcmg-codelet.cpp @@ -0,0 +1,90 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dcmg-codelet.cpp + * @brief A class for starpu codelet dcmg. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-19 +**/ + +#include +#include + +using namespace exageostat::runtime; +using namespace exageostat::dataunits; +using namespace exageostat::kernels; + +template +struct starpu_codelet DCMGCodelet::cl_dcmg = { +#ifdef USE_CUDA + .where= STARPU_CPU | STARPU_CUDA, + .cpu_funcs={cl_dcmg_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#else + .where=STARPU_CPU, + .cpu_funcs={cl_dcmg_function}, + .cuda_funcs={}, + .cuda_flags={(0)}, +#endif + .nbuffers = 1, + .modes = {STARPU_W}, + .name = "dcmg" +}; + +template +void DCMGCodelet::InsertTask(void *apDescriptor, const int &aTriangularPart, Locations *apLocation1, + Locations *apLocation2, Locations *apLocation3, T *apLocalTheta, + const int &aDistanceMetric, const Kernel *apKernel) { + int rows_num, cols_num, row, col, tile_row = 0, tile_col = 0; + auto *CHAM_apDescriptor = (CHAM_desc_t *) apDescriptor; + + for (col = 0; col < CHAM_apDescriptor->nt; col++) { + cols_num = col == CHAM_apDescriptor->nt - 1 ? CHAM_apDescriptor->n - col * CHAM_apDescriptor->nb + : CHAM_apDescriptor->nb; + if (aTriangularPart == ChamUpperLower) { + row = 0; + } else { + row = CHAM_apDescriptor->m == CHAM_apDescriptor->n ? col : 0; + } + for (; row < CHAM_apDescriptor->mt; row++) { + rows_num = row == CHAM_apDescriptor->mt - 1 ? CHAM_apDescriptor->m - row * CHAM_apDescriptor->mb + : CHAM_apDescriptor->mb; + tile_row = row * CHAM_apDescriptor->mb; + tile_col = col * CHAM_apDescriptor->nb; + starpu_insert_task(&this->cl_dcmg, + STARPU_VALUE, &rows_num, sizeof(int), + STARPU_VALUE, &cols_num, sizeof(int), + STARPU_VALUE, &tile_row, sizeof(int), + STARPU_VALUE, &tile_col, sizeof(int), + STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr(CHAM_apDescriptor, row, col), + STARPU_VALUE, &apLocation1, sizeof(Locations *), + STARPU_VALUE, &apLocation2, sizeof(Locations *), + STARPU_VALUE, &apLocation3, sizeof(Locations *), + STARPU_VALUE, &apLocalTheta, sizeof(double *), + STARPU_VALUE, &aDistanceMetric, sizeof(int), + STARPU_VALUE, &apKernel, sizeof(kernels::Kernel *), + 0); + } + } +} + +template +void DCMGCodelet::cl_dcmg_function(void *apBuffers[], void *apCodeletArguments) { + int rows_num, cols_num, tile_row, tile_col, distance_metric; + Locations *pLocation1, *pLocation2, *pLocation3; + T *pLocal_theta, *pDescriptor_A; + Kernel *pKernel; + + pDescriptor_A = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + starpu_codelet_unpack_args(apCodeletArguments, &rows_num, &cols_num, &tile_row, &tile_col, &pLocation1, &pLocation2, + &pLocation3, &pLocal_theta, + &distance_metric, &pKernel); + pKernel->GenerateCovarianceMatrix(pDescriptor_A, rows_num, cols_num, tile_row, tile_col, *pLocation1, *pLocation2, + *pLocation3, pLocal_theta, distance_metric); +} diff --git a/src/runtime/starpu/concrete/ddotp-codelet.cpp b/src/runtime/starpu/concrete/ddotp-codelet.cpp new file mode 100644 index 00000000..1057e8a3 --- /dev/null +++ b/src/runtime/starpu/concrete/ddotp-codelet.cpp @@ -0,0 +1,72 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ddotp-codelet.cpp + * @brief A class for starpu codelet ddotp. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#include + +#include +#include + +using namespace exageostat::runtime; + +template +struct starpu_codelet DDOTPCodelet::cl_ddotp = { +#ifdef USE_CUDA + .where= STARPU_CPU | STARPU_CUDA, + .cpu_funcs={cl_ddotp_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#else + .where=STARPU_CPU, + .cpu_funcs={cl_ddotp_function}, + .cuda_funcs={}, + .cuda_flags={(0)}, +#endif + .nbuffers = 2, + .modes = {STARPU_W, STARPU_W}, + .name = "ddotp" +}; + +template +void DDOTPCodelet::InsertTask(void *apDescA, void *apDescProduct) { + + int row, rows_num; + auto pDesc_A = (CHAM_desc_t *) apDescA; + auto pDesc_product = (CHAM_desc_t *) apDescProduct; + + auto desc_mt = pDesc_A->mt; + auto desc_m = pDesc_A->m; + auto desc_mb = pDesc_A->mb; + + for (row = 0; row < desc_mt; row++) { + rows_num = row == desc_mt - 1 ? desc_m - row * desc_mb : desc_mb; + + starpu_insert_task(&this->cl_ddotp, + STARPU_VALUE, &rows_num, sizeof(int), + STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr(pDesc_product, 0, 0), + STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr(pDesc_A, row, 0), + 0); + } +} + +template +void DDOTPCodelet::cl_ddotp_function(void *apBuffers[], void *apCodeletArguments) { + int rows_num; + T *pDescriptor_A, *pDot_product; + + pDot_product = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pDescriptor_A = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + starpu_codelet_unpack_args(apCodeletArguments, &rows_num); + T local_dot = cblas_ddot(rows_num, (double *) pDescriptor_A, 1, (double *) pDescriptor_A, 1); + *pDot_product += local_dot; +} diff --git a/src/runtime/starpu/concrete/dmdet-codelet.cpp b/src/runtime/starpu/concrete/dmdet-codelet.cpp new file mode 100644 index 00000000..b89fc204 --- /dev/null +++ b/src/runtime/starpu/concrete/dmdet-codelet.cpp @@ -0,0 +1,80 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dmdet-codelet.cpp + * @brief A class for starpu codelet dmdet. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-21 +**/ + +#include + +#include + +using namespace exageostat::runtime; +using namespace exageostat::common; + +template +struct starpu_codelet DMDETCodelet::cl_dmdet{ +#ifdef USE_CUDA + .where= STARPU_CPU | STARPU_CUDA, + .cpu_funcs={cl_dmdet_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#else + .where=STARPU_CPU, + .cpu_funcs={cl_dmdet_function}, + .cuda_funcs={}, + .cuda_flags={(0)}, +#endif + .nbuffers = 2, + .modes = {STARPU_W, STARPU_W}, + .name = "dmdet" +}; + +template +void DMDETCodelet::InsertTask(const Computation &aComputation, void *apDescA, void *apDescDet, + std::unique_ptr &aStarPuHelpers) { + int row, rows_num; + auto desc_mt = aStarPuHelpers->GetMT(apDescA); + auto desc_m = aStarPuHelpers->GetM(apDescA); + auto desc_mb = aStarPuHelpers->GetMB(apDescA); + + for (row = 0; row < desc_mt; row++) { + rows_num = row == desc_mt - 1 ? desc_m - row * desc_mb : desc_mb; + starpu_insert_task(&this->cl_dmdet, + STARPU_VALUE, &rows_num, sizeof(int), + STARPU_W, + aStarPuHelpers->ExaGeoStatDataGetAddr(apDescA, row, aComputation != TILE_LOW_RANK ? row : 0), + STARPU_W, aStarPuHelpers->ExaGeoStatDataGetAddr(apDescDet, 0, 0), + 0); + } +} + +template +void DMDETCodelet::cl_dmdet_function(void *apBuffers[], void *apCodeletArguments) { + int rows_num; + T *pDescriptor_A, *pDeterminant; + + pDescriptor_A = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pDeterminant = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + + starpu_codelet_unpack_args(apCodeletArguments, &rows_num); + T local_det = core_dmdet(pDescriptor_A, rows_num); + *pDeterminant += local_det; +} + +template +T DMDETCodelet::core_dmdet(const T *apDescriptor, const int &aSize) { + T result = 0.0; + for (int i = 0; i < aSize; i++) { + if (apDescriptor[i + i * aSize] > 0) + result += log(apDescriptor[i + i * aSize]); + } + return result; +} diff --git a/src/runtime/starpu/concrete/dmloe-mmom-codelet.cpp b/src/runtime/starpu/concrete/dmloe-mmom-codelet.cpp new file mode 100644 index 00000000..e7986d6c --- /dev/null +++ b/src/runtime/starpu/concrete/dmloe-mmom-codelet.cpp @@ -0,0 +1,103 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dmloe-mmom-codelet.cpp + * @brief A class for starpu codelet dmloe-mmom. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#include + +#include +#include + +using namespace exageostat::runtime; + +template +struct starpu_codelet DmloeMmomCodelet::cl_dmloe_mmom = { +#ifdef USE_CUDA + .where= STARPU_CPU | STARPU_CUDA, + .cpu_funcs={cl_dmloe_mmom_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#else + .where=STARPU_CPU, + .cpu_funcs={cl_dmloe_mmom_function}, + .cuda_funcs={}, + .cuda_flags={(0)}, +#endif + .nbuffers = 5, + .modes = {STARPU_W, STARPU_W, STARPU_W, STARPU_W, STARPU_W}, + .name = "dmloe_mmom" +}; + +template +void DmloeMmomCodelet::InsertTask(void *apDescExpr1, void *apDescExpr2, void *apDescExpr3, void *apDescMLOE, + void *apDescMMOM) { + int row, col, rows_num, cols_num; + + for (col = 0; col < ((CHAM_desc_t *) apDescExpr1)->nt; col++) { + cols_num = col == ((CHAM_desc_t *) apDescExpr1)->nt - 1 ? ((CHAM_desc_t *) apDescExpr1)->n - + col * ((CHAM_desc_t *) apDescExpr1)->nb + : ((CHAM_desc_t *) apDescExpr1)->nb; + for (row = 0; row < ((CHAM_desc_t *) apDescExpr1)->mt; row++) { + + rows_num = row == ((CHAM_desc_t *) apDescExpr1)->mt - 1 ? ((CHAM_desc_t *) apDescExpr1)->m - + row * ((CHAM_desc_t *) apDescExpr1)->mb + : ((CHAM_desc_t *) apDescExpr1)->mb; + starpu_insert_task(&this->cl_dmloe_mmom, + STARPU_VALUE, &rows_num, sizeof(int), + STARPU_VALUE, &cols_num, sizeof(int), + STARPU_W, + (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescExpr1, row, col), + STARPU_W, + (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescExpr2, row, col), + STARPU_W, + (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescExpr3, row, col), + STARPU_W, + (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescMLOE, row, col), + STARPU_W, + (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescMMOM, row, col), + 0); + } + } +} + +template +void DmloeMmomCodelet::cl_dmloe_mmom_function(void **apBuffers, void *apCodeletArguments) { + int rows_num, cols_num; + T *pExpr1, *pExpr2, *pExpr3, *pMloe, *pMmom; + + pExpr1 = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pExpr2 = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + pExpr3 = (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, &rows_num, &cols_num); + T expr1_ = 0, expr2_ = 0, expr3_ = 0; + + for (int i = 0; i < rows_num * cols_num; i += 2) { + expr1_ += pExpr1[i]; + expr2_ += pExpr2[i]; + expr3_ += pExpr3[i]; + } + + if (expr2_ == 0.0) { + *pMloe -= 1.0; + } else { + *pMloe += (expr1_ / expr2_) - 1.0; + } + + if (expr2_ == 0.0) { + *pMmom -= 1.0; + } else { + *pMmom += (expr3_ / expr1_) - 1.0; + } +} diff --git a/src/runtime/starpu/concrete/dmse-bivariate-codelet.cpp b/src/runtime/starpu/concrete/dmse-bivariate-codelet.cpp new file mode 100644 index 00000000..badbfa71 --- /dev/null +++ b/src/runtime/starpu/concrete/dmse-bivariate-codelet.cpp @@ -0,0 +1,87 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dmse-bivariate-codelet.cpp + * @brief A class for starpu codelet dmse-bivariate. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#include + +#include +#include + +using namespace exageostat::runtime; + +template +struct starpu_codelet DMSEBivariateCodelet::cl_dmse_bivariate = { +#ifdef USE_CUDA + .where= STARPU_CPU | STARPU_CUDA, + .cpu_funcs={cl_dmse_bivariate_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#else + .where=STARPU_CPU, + .cpu_funcs={cl_dmse_bivariate_function}, + .cuda_funcs={}, + .cuda_flags={(0)}, +#endif + .nbuffers = 5, + .modes = {STARPU_RW, STARPU_RW, STARPU_RW, STARPU_R, STARPU_R}, + .name = "dmse-bivariate" +}; + +template +void DMSEBivariateCodelet::InsertTask(void *apDescZMiss, void *apDescZPre, void *apDescsError, void *apDescsError1, + void *apDescsError2) { + int row, rows_num; + + auto pDesc_ZPre = (CHAM_desc_t *) apDescZPre; + auto desc_mt = pDesc_ZPre->mt; + auto desc_m = pDesc_ZPre->m; + auto desc_mb = pDesc_ZPre->mb; + + for (row = 0; row < desc_mt; row++) { + rows_num = row == desc_mt - 1 ? desc_m - row * desc_mb : desc_mb; + starpu_insert_task(&this->cl_dmse_bivariate, + STARPU_VALUE, &rows_num, sizeof(int), + STARPU_RW, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescsError1, 0, 0), + STARPU_RW, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescsError2, 0, 0), + STARPU_RW, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescsError, 0, 0), + STARPU_R, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescZPre, row, 0), + STARPU_R, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescZMiss, row, 0), + 0); + } +} + +template +void DMSEBivariateCodelet::cl_dmse_bivariate_function(void **apBuffers, void *apCodeletArguments) { + int rows_num; + T *pZpre, *pZmiss, *pSerror1, *pSerror2, *pSerror; + T local_serror1 = 0.0, local_serror2 = 0.0, 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, &rows_num); + + for (int i = 0; i < rows_num; 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; +} diff --git a/src/runtime/starpu/concrete/dmse-codelet.cpp b/src/runtime/starpu/concrete/dmse-codelet.cpp new file mode 100644 index 00000000..79941c50 --- /dev/null +++ b/src/runtime/starpu/concrete/dmse-codelet.cpp @@ -0,0 +1,73 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dmse-codelet.cpp + * @brief A class for starpu codelet dmse. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-21 +**/ + +#include + +#include +#include + +using namespace exageostat::runtime; + +template +struct starpu_codelet DMSECodelet::cl_dmse = { +#ifdef USE_CUDA + .where= STARPU_CPU | STARPU_CUDA, + .cpu_funcs={cl_dmse_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#else + .where=STARPU_CPU, + .cpu_funcs={cl_dmse_function}, + .cuda_funcs={}, + .cuda_flags={(0)}, +#endif + .nbuffers = 3, + .modes = {STARPU_W, STARPU_W, STARPU_W}, + .name = "dmse" +}; + +template +void DMSECodelet::InsertTask(void *apDescError, void *apDescZPredict, void *apDescZMiss) { + int row, rows_num; + auto pDesc_Z_predict = (CHAM_desc_t *) apDescZPredict; + + for (row = 0; row < pDesc_Z_predict->mt; row++) { + rows_num = + row == pDesc_Z_predict->mt - 1 ? pDesc_Z_predict->m - row * pDesc_Z_predict->mb : pDesc_Z_predict->mb; + starpu_insert_task(&this->cl_dmse, + STARPU_VALUE, &rows_num, sizeof(int), + STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescError, 0, 0), + STARPU_W, + (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescZPredict, row, 0), + STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescZMiss, row, 0), + 0); + } +} + +template +void DMSECodelet::cl_dmse_function(void **apBuffers, void *apCodeletArguments) { + int rows_num; + T *pZPredict, *pZMiss, *pError; + T local_error = 0.0; + + 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, &rows_num); + for (int i = 0; i < rows_num; i++) { + local_error += pow((pZPredict[i] - pZMiss[i]), 2); + } + *pError += local_error; +} diff --git a/src/runtime/starpu/concrete/dtrace-codelet.cpp b/src/runtime/starpu/concrete/dtrace-codelet.cpp new file mode 100644 index 00000000..0d840302 --- /dev/null +++ b/src/runtime/starpu/concrete/dtrace-codelet.cpp @@ -0,0 +1,78 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dtrace-codelet.cpp + * @brief A class for starpu codelet dtrace. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#include + +#include +#include + +using namespace exageostat::runtime; + +template +struct starpu_codelet DTRACECodelet::cl_dtrace = { +#ifdef USE_CUDA + .where= STARPU_CPU | STARPU_CUDA, + .cpu_funcs={cl_dtrace_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#else + .where=STARPU_CPU, + .cpu_funcs={cl_dtrace_function}, + .cuda_funcs={}, + .cuda_flags={(0)}, +#endif + .nbuffers = 3, + .modes = {STARPU_W, STARPU_W, STARPU_W}, + .name = "dtrace" +}; + +template +void DTRACECodelet::InsertTask(void *apDescA, void *apDescNum, void *apDescTrace) { + int row, rows_num; + auto pDescriptor_A = (CHAM_desc_t *) apDescA; + + for (row = 0; row < pDescriptor_A->mt; row++) { + rows_num = row == pDescriptor_A->mt - 1 ? pDescriptor_A->m - row * pDescriptor_A->mb : pDescriptor_A->mb; + starpu_insert_task(&this->cl_dtrace, + STARPU_VALUE, &rows_num, sizeof(int), + STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescA, row, row), + STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescNum, 0, 0), + STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr((CHAM_desc_t *) apDescTrace, row, 0), + 0); + } +} + +template +void DTRACECodelet::cl_dtrace_function(void *apBuffers[], void *apCodeletArguments) { + int rows_num; + T *pDescriptor_A, *pSum, *pTrace; + + pDescriptor_A = (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, &rows_num); + T local_sum = core_dtrace(pDescriptor_A, rows_num, pTrace); + *pSum += local_sum; +} + +template +double DTRACECodelet::core_dtrace(const T *pDescriptor, const int &aSize, T *pTrace) { + T result = 0.0; + for (int i = 0; i < aSize; i++) { + result += pDescriptor[i + i * aSize]; + pTrace[i] = pDescriptor[i + i * aSize]; + } + return result; +} diff --git a/src/runtime/starpu/concrete/dzcpy-codelet.cpp b/src/runtime/starpu/concrete/dzcpy-codelet.cpp new file mode 100644 index 00000000..6c213f2e --- /dev/null +++ b/src/runtime/starpu/concrete/dzcpy-codelet.cpp @@ -0,0 +1,65 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file dzcpy-codelet.cpp + * @brief A class for starpu codelet dzcpy. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#include + +#include +#include + +using namespace exageostat::runtime; + +template +struct starpu_codelet DZCPYCodelet::cl_dzcpy = { +#ifdef USE_CUDA + .where= STARPU_CPU | STARPU_CUDA, + .cpu_funcs={cl_dzcpy_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#else + .where=STARPU_CPU, + .cpu_funcs={cl_dzcpy_function}, + .cuda_funcs={}, + .cuda_flags={(0)}, +#endif + .nbuffers = 1, + .modes = {STARPU_W}, + .name = "dzcpy" +}; + +template +void DZCPYCodelet::InsertTask(void *apDescriptor, void *apDoubleVector) { + int row, tile_row, rows_num; + auto pDescriptor_A = (CHAM_desc_t *) apDescriptor; + + for (row = 0; row < pDescriptor_A->mt; row++) { + rows_num = row == pDescriptor_A->mt - 1 ? pDescriptor_A->m - row * pDescriptor_A->mb : pDescriptor_A->mb; + tile_row = row * pDescriptor_A->mb; + starpu_insert_task(&this->cl_dzcpy, + STARPU_VALUE, &rows_num, sizeof(int), + STARPU_VALUE, &tile_row, sizeof(int), + STARPU_VALUE, &apDoubleVector, sizeof(double), + STARPU_W, RUNTIME_data_getaddr(pDescriptor_A, row, 0), + 0); + } +} + +template +void DZCPYCodelet::cl_dzcpy_function(void **apBuffers, void *apCodeletArguments) { + int rows_num, tile_row; + T *pDescriptor_A, *pR; + + pDescriptor_A = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + starpu_codelet_unpack_args(apCodeletArguments, &rows_num, &tile_row, &pR); + memcpy(pDescriptor_A, &pR[tile_row], rows_num * sizeof(T)); +} diff --git a/src/runtime/starpu/concrete/gaussian-to-non-codelet.cpp b/src/runtime/starpu/concrete/gaussian-to-non-codelet.cpp new file mode 100644 index 00000000..81db6fd3 --- /dev/null +++ b/src/runtime/starpu/concrete/gaussian-to-non-codelet.cpp @@ -0,0 +1,98 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file gaussian-to-non-codelet.cpp + * @brief A class for starpu codelet gaussian-to-non. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#include + +#include +#include + +using namespace exageostat::runtime; + +template +struct starpu_codelet GaussianCodelet::cl_gaussian_to_non = { +#ifdef USE_CUDA + .where= STARPU_CPU | STARPU_CUDA, + .cpu_funcs={cl_gaussian_to_non_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#else + .where = STARPU_CPU, + .cpu_funcs = {cl_gaussian_to_non_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#endif + .nbuffers = 1, + .modes = {STARPU_RW}, + .name = "gaussian_to_non" +}; + +template +void GaussianCodelet::InsertTask(void *apDesc, T *apTheta) { + int row, rows_num; + auto pDescriptor_Z = (CHAM_desc_t *) apDesc; + + for (row = 0; row < pDescriptor_Z->mt; row++) { + rows_num = row == pDescriptor_Z->mt - 1 ? pDescriptor_Z->m - row * pDescriptor_Z->mb : pDescriptor_Z->mb; + starpu_insert_task(&this->cl_gaussian_to_non, + STARPU_VALUE, &rows_num, sizeof(int), + STARPU_RW, (starpu_data_handle_t) RUNTIME_data_getaddr(pDescriptor_Z, row, 0), + STARPU_VALUE, &apTheta[0], sizeof(T), + STARPU_VALUE, &apTheta[1], sizeof(T), + STARPU_VALUE, &apTheta[2], sizeof(T), + STARPU_VALUE, &apTheta[3], sizeof(T), + STARPU_VALUE, &apTheta[4], sizeof(T), + STARPU_VALUE, &apTheta[5], sizeof(T), + 0); + } +} + +template +void GaussianCodelet::cl_gaussian_to_non_function(void **apBuffers, void *apCodeletArguments) { + int rows_num; + T *pDescriptorZ, *pTheta; + + pTheta = new T[6]; + pDescriptorZ = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + + starpu_codelet_unpack_args(apCodeletArguments, &rows_num, &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(pDescriptorZ, pTheta, rows_num); + delete[] pTheta; +} + +template +void GaussianCodelet::core_gaussian_to_non(T *apDescriptorZ, const T *apLocalTheta, const int &aSize) { + + T xi = apLocalTheta[2]; + T omega = apLocalTheta[3]; + T g = apLocalTheta[4]; + T h = apLocalTheta[5]; + + int i; + if (h < 0) { + throw std::runtime_error("The kurtosis parameter cannot be negative"); + } + if (g == 0) { + for (i = 0; i < aSize; i++) + apDescriptorZ[i] = xi + omega * apDescriptorZ[i] * (exp(0.5 * h * pow(apDescriptorZ[i], 2))); + } else { + for (i = 0; i < aSize; i++) + apDescriptorZ[i] = + xi + omega * (exp(g * apDescriptorZ[i]) - 1) * (exp(0.5 * h * pow(apDescriptorZ[i], 2))) / g; + } +} + + diff --git a/src/runtime/starpu/concrete/non-gaussian-loglike-codelet.cpp b/src/runtime/starpu/concrete/non-gaussian-loglike-codelet.cpp new file mode 100644 index 00000000..d425ca7e --- /dev/null +++ b/src/runtime/starpu/concrete/non-gaussian-loglike-codelet.cpp @@ -0,0 +1,101 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file non-gaussian-codelet-loglike-codelet.cpp + * @brief A class for starpu codelet non-gaussian-loglike. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-26 +**/ + +#include + +#include + +using namespace exageostat::runtime; + +template +struct starpu_codelet NonGaussianLoglike::cl_non_gaussian_loglike = { +#ifdef USE_CUDA + .where= STARPU_CPU | STARPU_CUDA, + .cpu_funcs={cl_non_gaussian_loglike_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#else + .where=STARPU_CPU, + .cpu_funcs={cl_non_gaussian_loglike_function}, + .cuda_funcs={}, + .cuda_flags={(0)}, +#endif + .nbuffers = 2, + .modes = {STARPU_R, STARPU_RW}, + .name = "non_gaussian_loglike" +}; + +template +void NonGaussianLoglike::InsertTask(void *apDescZ, void *apDescSum, const T *apTheta, + std::unique_ptr &aStarPuHelpers) { + auto desc_mt = aStarPuHelpers->GetMT(apDescZ); + auto desc_m = aStarPuHelpers->GetM(apDescZ); + auto desc_mb = aStarPuHelpers->GetMB(apDescZ); + + int row, rows_num; + for (row = 0; row < desc_mt; row++) { + rows_num = row == desc_mt - 1 ? desc_m - row * desc_mb : desc_mb; + starpu_insert_task(&this->cl_non_gaussian_loglike, + STARPU_VALUE, &rows_num, sizeof(int), + STARPU_R, aStarPuHelpers->ExaGeoStatDataGetAddr(apDescZ, row, 0), + STARPU_RW, aStarPuHelpers->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), + 0); + } +} + +template +void NonGaussianLoglike::cl_non_gaussian_loglike_function(void **apBuffers, void *apCodeletArguments) { + int rows_num; + T *pDescriptor_Z, *pDescriptor_sum; + + auto *pTheta = new T[6]; + pDescriptor_Z = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pDescriptor_sum = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + + starpu_codelet_unpack_args(apCodeletArguments, &rows_num, &pTheta[0], &pTheta[1], &pTheta[2], &pTheta[3], + &pTheta[4], + &pTheta[5]); + T local_sum = core_non_gaussian_loglike_helper(pDescriptor_Z, pTheta, rows_num); + *pDescriptor_sum += local_sum; + delete[] pTheta; +} + +template +double NonGaussianLoglike::core_non_gaussian_loglike_helper(const T *apDescriptorZ, const T *apLocalTheta, + const int &aSize) { + 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 < aSize; i++) { + if (g == 0) + sum += log(1 + h * pow(apDescriptorZ[i], 2)) + 0.5 * h * pow(apDescriptorZ[i], 2); + else { + sum += log(exp(g * apDescriptorZ[i]) + (exp(g * apDescriptorZ[i]) - 1) * h * apDescriptorZ[i] / g) + + 0.5 * h * pow(apDescriptorZ[i], 2); + } + } + return sum; +} diff --git a/src/runtime/starpu/concrete/non-gaussian-transform-codelet.cpp b/src/runtime/starpu/concrete/non-gaussian-transform-codelet.cpp new file mode 100644 index 00000000..0cce4daf --- /dev/null +++ b/src/runtime/starpu/concrete/non-gaussian-transform-codelet.cpp @@ -0,0 +1,136 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file non-gaussian-codelet-transform-codelet.cpp + * @brief A class for starpu codelet non-gaussian-transform. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-26 +**/ + +#include +#include + +#include + +using namespace exageostat::runtime; + +template +struct starpu_codelet NonGaussianTransform::cl_non_gaussian_transform = { +#ifdef USE_CUDA + .where= STARPU_CPU | STARPU_CUDA, + .cpu_funcs={cl_non_gaussian_transform_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#else + .where=STARPU_CPU, + .cpu_funcs={cl_non_gaussian_transform_function}, + .cuda_funcs={}, + .cuda_flags={(0)}, +#endif + .nbuffers = 1, + .modes = {STARPU_RW}, + .name = "non_gaussian_transform" +}; + +template +void +NonGaussianTransform::InsertTask(void *apDescZ, const T *apTheta, std::unique_ptr &apStarPuHelpers) { + int row, rows_num; + + auto desc_mt = apStarPuHelpers->GetMT(apDescZ); + auto desc_m = apStarPuHelpers->GetM(apDescZ); + auto desc_mb = apStarPuHelpers->GetMB(apDescZ); + + for (row = 0; row < desc_mt; row++) { + rows_num = row == desc_mt - 1 ? desc_m - row * desc_mb : desc_mb; + starpu_insert_task(&this->cl_non_gaussian_transform, + STARPU_VALUE, &rows_num, sizeof(int), + STARPU_RW, apStarPuHelpers->ExaGeoStatDataGetAddr(apDescZ, row, 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); + } +} + +template +void NonGaussianTransform::cl_non_gaussian_transform_function(void **apBuffers, void *apCodeletArguments) { + int rows_num; + T *pDescriptorZ, *pTheta; + + pTheta = new T[6]; + pDescriptorZ = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + + starpu_codelet_unpack_args(apCodeletArguments, &rows_num, &pTheta[0], &pTheta[1], &pTheta[2], &pTheta[3], + &pTheta[4], + &pTheta[5]); + core_non_gaussian_transform_helper(pDescriptorZ, pTheta, rows_num); + delete[] pTheta; +} + +template +void +NonGaussianTransform::core_non_gaussian_transform_helper(T *apDescripZ, const T *apLocalTheta, const int &aSize) { + + 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 < aSize; i++) + apDescripZ[i] = newton_raphson(apDescripZ[i], xi, omega, g, h, eps); +} + +template +double +NonGaussianTransform::newton_raphson(const T apDescriptorZ, const T aTransLocation, const T aTransScale, + const T aTransShape, const T aTransKurtosis, const T aEpsilon) { + int itr, max_itr; + T x0 = 0, x1, all_err, diff; + all_err = aEpsilon; + max_itr = 1000; + for (itr = 1; itr <= max_itr; itr++) { + diff = tukeyGHTransfor(apDescriptorZ, x0, aTransLocation, aTransScale, aTransShape, aTransKurtosis) / + tukeyGHDiferencial(x0, aTransScale, aTransShape, aTransKurtosis); + x1 = x0 - diff; + if (fabs(diff) < all_err) + return x1; + x0 = x1; + } + return x1; +} + +template +double NonGaussianTransform::tukeyGHTransfor(const T aOriginalValue, const T aCurrentValue, const T aTransLocation, + const T aTransScale, const T aTransShape, const T aTransKurtosis) { + if (aTransShape == 0) + return aOriginalValue - aTransLocation - + aTransScale * aCurrentValue * exp(0.5 * aTransKurtosis * aCurrentValue * aCurrentValue); + else + return aOriginalValue - aTransLocation - (aTransScale * (exp(aTransShape * aCurrentValue) - 1) * + (exp(0.5 * aTransKurtosis * aCurrentValue * aCurrentValue)) / + aTransShape); +} + +template +double NonGaussianTransform::tukeyGHDiferencial(const T aCurrentValue, const T aTransScale, const T aTransShape, + const T aTransKurtosis) { + if (aTransShape == 0) + return -aTransScale * exp((aTransKurtosis * aCurrentValue * aCurrentValue) / 2.0) - + aTransScale * aTransKurtosis * aCurrentValue * aCurrentValue * + exp((aTransKurtosis * aCurrentValue * aCurrentValue) / 2.0); + else + return -aTransScale * exp(aTransShape * aCurrentValue) * + exp((aTransKurtosis * aCurrentValue * aCurrentValue) / 2.0) - + (aTransKurtosis * aCurrentValue * exp((aTransKurtosis * aCurrentValue * aCurrentValue) / 2.0) * + (aTransScale * exp(aTransShape * aCurrentValue) - aTransScale)) / aTransShape; +} diff --git a/src/runtime/starpu/concrete/stride-vec-codelet.cpp b/src/runtime/starpu/concrete/stride-vec-codelet.cpp new file mode 100644 index 00000000..5c8774e9 --- /dev/null +++ b/src/runtime/starpu/concrete/stride-vec-codelet.cpp @@ -0,0 +1,76 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file stride-vec-codelet.cpp + * @brief A class for starpu codelet stride-vec. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#include + +#include +#include + +using namespace exageostat::runtime; + +template +struct starpu_codelet STRIDEVECCodelet::cl_stride_vec = { +#ifdef USE_CUDA + .where= STARPU_CPU | STARPU_CUDA, + .cpu_funcs={cl_stride_vec_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#else + .where=STARPU_CPU, + .cpu_funcs={cl_stride_vec_function}, + .cuda_funcs={}, + .cuda_flags={(0)}, +#endif + .nbuffers = 3, + .modes = {STARPU_R, STARPU_W, STARPU_W}, + .name = "stride_vec" +}; + +template +void STRIDEVECCodelet::InsertTask(const void *apDescA, void *apDescB, void *apDescC) { + int row, rows_num; + const auto desc_A = (CHAM_desc_t *) apDescA; + auto desc_B = (CHAM_desc_t *) apDescB; + auto desc_C = (CHAM_desc_t *) apDescC; + + auto desc_mt = desc_A->mt; + auto desc_m = desc_A->m; + auto desc_mb = desc_A->mb; + + for (row = 0; row < desc_mt; row++) { + rows_num = row == desc_mt - 1 ? desc_m - row * desc_mb : desc_mb; + starpu_insert_task(&this->cl_stride_vec, + STARPU_VALUE, &rows_num, sizeof(int), + STARPU_R, (starpu_data_handle_t) RUNTIME_data_getaddr(desc_A, row, 0), + STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr(desc_B, (int) floor(row / 2.0), 0), + STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr(desc_C, (int) floor(row / 2.0), 0), + 0); + } +} + +template +void STRIDEVECCodelet::cl_stride_vec_function(void **apBuffers, void *apCodeletArguments) { + int rows_num; + T *pDescriptor_A, *pDescriptor_B, *pDescriptor_C; + + pDescriptor_A = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pDescriptor_B = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + pDescriptor_C = (T *) STARPU_MATRIX_GET_PTR(apBuffers[2]); + starpu_codelet_unpack_args(apCodeletArguments, &rows_num); + + for (int i = 0, j = 0; i < rows_num - 1; i += 2, j++) { + pDescriptor_B[j] = pDescriptor_A[i]; + pDescriptor_C[j] = pDescriptor_A[i + 1]; + } +} diff --git a/src/runtime/starpu/concrete/tri-stride-vec-codelet.cpp b/src/runtime/starpu/concrete/tri-stride-vec-codelet.cpp new file mode 100644 index 00000000..44dc080d --- /dev/null +++ b/src/runtime/starpu/concrete/tri-stride-vec-codelet.cpp @@ -0,0 +1,83 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file tri-stride-vec-codelet.cpp + * @brief A class for starpu codelet tri-stride-vec. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @author Sameh Abdulah + * @date 2024-02-25 +**/ + +#include + +#include +#include + +using namespace exageostat::runtime; + +template +struct starpu_codelet TriStrideVecCodelet::cl_tri_stride_vec = { +#ifdef USE_CUDA + .where= STARPU_CPU | STARPU_CUDA, + .cpu_funcs={cl_tri_stride_vec_function}, + .cuda_funcs={}, + .cuda_flags={0}, +#else + .where=STARPU_CPU, + .cpu_funcs={cl_tri_stride_vec_function}, + .cuda_funcs={}, + .cuda_flags={(0)}, +#endif + .nbuffers = 4, + .modes = {STARPU_R, STARPU_W, STARPU_W, STARPU_W}, + .name = "tri_stride_vec" +}; + +template +void TriStrideVecCodelet::InsertTask(const void *apDescA, void *apDescB, void *apDescC, void *apDescD) { + int row, rows_num; + const auto desc_A = (CHAM_desc_t *) apDescA; + auto desc_B = (CHAM_desc_t *) apDescB; + auto desc_C = (CHAM_desc_t *) apDescC; + auto desc_D = (CHAM_desc_t *) apDescD; + + auto desc_mt = desc_A->mt; + auto desc_m = desc_A->m; + auto desc_mb = desc_A->mb; + + for (row = 0; row < desc_mt; row++) { + rows_num = row == desc_mt - 1 ? desc_m - row * desc_mb : desc_mb; + starpu_insert_task(&this->cl_tri_stride_vec, + STARPU_VALUE, &rows_num, sizeof(int), + STARPU_R, (starpu_data_handle_t) RUNTIME_data_getaddr(desc_A, row, 0), + STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr(desc_B, (int) floor(row / 3.0), 0), + STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr(desc_C, (int) floor(row / 3.0), 0), + STARPU_W, (starpu_data_handle_t) RUNTIME_data_getaddr(desc_D, (int) floor(row / 3.0), 0), + 0); + } +} + +template +void TriStrideVecCodelet::cl_tri_stride_vec_function(void *apBuffers[], void *apCodeletArguments) { + + int rows_num; + T *pDescriptor_A, *pDescriptor_B, *pDescriptor_C, *pDescriptor_D; + + pDescriptor_A = (T *) STARPU_MATRIX_GET_PTR(apBuffers[0]); + pDescriptor_B = (T *) STARPU_MATRIX_GET_PTR(apBuffers[1]); + pDescriptor_C = (T *) STARPU_MATRIX_GET_PTR(apBuffers[2]); + pDescriptor_D = (T *) STARPU_MATRIX_GET_PTR(apBuffers[3]); + + starpu_codelet_unpack_args(apCodeletArguments, &rows_num); + + //accept only temp divided by three (should be optimized) + for (int j = 0, i = 0; i < rows_num - 1; i += 3, j++) { + pDescriptor_B[j] = pDescriptor_A[i]; + pDescriptor_C[j] = pDescriptor_A[i + 1]; + pDescriptor_D[j] = pDescriptor_A[i + 2]; + } +} diff --git a/src/runtime/starpu/helpers/CMakeLists.txt b/src/runtime/starpu/helpers/CMakeLists.txt new file mode 100644 index 00000000..295fba30 --- /dev/null +++ b/src/runtime/starpu/helpers/CMakeLists.txt @@ -0,0 +1,23 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 1.1.0 +# @brief CMake build script for StarPu functions +# @author Mahmoud ElKarargy +# @date 2024-02-19 + +# Include the concrete implementations of the StarPu helpers classes and StarPu Helpes Factory +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/StarPuHelpersFactory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/concrete/ChameleonStarPuHelpers.cpp + ${SOURCES} + ) + +if (USE_HICMA) + list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/concrete/HicmaStarPuHelpers.cpp) +endif () + +set(SOURCES ${SOURCES} PARENT_SCOPE) diff --git a/src/runtime/starpu/helpers/StarPuHelpersFactory.cpp b/src/runtime/starpu/helpers/StarPuHelpersFactory.cpp new file mode 100644 index 00000000..fdb866fa --- /dev/null +++ b/src/runtime/starpu/helpers/StarPuHelpersFactory.cpp @@ -0,0 +1,38 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file StarPuHelpersFactory.cpp + * @brief Factory for StarPu helpers. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-25 +**/ + +#include +#include + +#ifdef USE_HICMA + +#include + +#endif + +using namespace std; +using namespace exageostat::common; +using namespace exageostat::runtime; + +unique_ptr StarPuHelpersFactory::CreateStarPuHelper(const Computation &aComputation) { + if (aComputation == EXACT_DENSE || aComputation == DIAGONAL_APPROX) { + return make_unique(); + } else if (aComputation == TILE_LOW_RANK) { +#ifdef USE_HICMA + return make_unique(); +#else + throw runtime_error("Tile low rank generation isn't supported without enabling HiCMA. Use -DUSE_HICMA=ON"); +#endif + } + throw runtime_error("You need to enable whether HiCMA or Chameleon"); +} diff --git a/src/runtime/starpu/helpers/concrete/ChameleonStarPuHelpers.cpp b/src/runtime/starpu/helpers/concrete/ChameleonStarPuHelpers.cpp new file mode 100644 index 00000000..7d122d8c --- /dev/null +++ b/src/runtime/starpu/helpers/concrete/ChameleonStarPuHelpers.cpp @@ -0,0 +1,61 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file ChameleonStarPuHelpers.cpp + * @brief A class for Chameleon implementation of StarPu helpers. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-25 +**/ + +#include +#include + +using namespace exageostat::runtime; + +void +ChameleonStarPuHelpers::ExaGeoStatOptionsInit(void *apOptions, void *apSequence, void *apRequest) { + + RUNTIME_options_init((RUNTIME_option_t *) apOptions, (CHAM_context_t *) ExaGeoStatHardware::GetChameleonContext(), + (RUNTIME_sequence_t *) apSequence, (RUNTIME_request_t *) apRequest); +} + +void ChameleonStarPuHelpers::ExaGeoStatOptionsFree(void *apOptions) { + RUNTIME_options_ws_free((RUNTIME_option_t *) apOptions); +} + + +void ChameleonStarPuHelpers::ExaGeoStatOptionsFinalize(void *apOptions) { + auto *options = (RUNTIME_option_t *) apOptions; + RUNTIME_options_finalize(options, (CHAM_context_t *) ExaGeoStatHardware::GetChameleonContext()); +} + +void *ChameleonStarPuHelpers::ExaGeoStatDataGetAddr(void *apDescriptor, const int &aDescRow, const int &aDescCol) { + return RUNTIME_data_getaddr((CHAM_desc_t *) apDescriptor, aDescRow, aDescCol); +} + +int ChameleonStarPuHelpers::GetMT(void *apDescriptor) { + auto descriptor = (CHAM_desc_t *) apDescriptor; + return descriptor->mt; +} + +int ChameleonStarPuHelpers::GetM(void *apDescriptor) { + auto descriptor = (CHAM_desc_t *) apDescriptor; + return descriptor->m; +} + +int ChameleonStarPuHelpers::GetMB(void *apDescriptor) { + auto descriptor = (CHAM_desc_t *) apDescriptor; + return descriptor->mb; +} + +void *ChameleonStarPuHelpers::GetOptions() { + return new RUNTIME_option_t; +} + +void ChameleonStarPuHelpers::DeleteOptions(void *apOptions) { + delete (RUNTIME_option_t *) apOptions; +} diff --git a/src/runtime/starpu/helpers/concrete/HicmaStarPuHelpers.cpp b/src/runtime/starpu/helpers/concrete/HicmaStarPuHelpers.cpp new file mode 100644 index 00000000..5b82c4fb --- /dev/null +++ b/src/runtime/starpu/helpers/concrete/HicmaStarPuHelpers.cpp @@ -0,0 +1,58 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file HicmaStarPuHelpers.cpp + * @brief A class for Hicma implementation of StarPu helpers. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-25 +**/ + +#include +#include + +using namespace exageostat::runtime; + +void HicmaStarPuHelpers::ExaGeoStatOptionsInit(void *apOptions, void *apSequence, void *apRequest) { + HICMA_RUNTIME_options_init((HICMA_option_t *) apOptions, (HICMA_context_t *) ExaGeoStatHardware::GetHicmaContext(), + (HICMA_sequence_t *) apSequence, (HICMA_request_t *) apRequest); +} + +void HicmaStarPuHelpers::ExaGeoStatOptionsFree(void *apOptions) { + HICMA_RUNTIME_options_ws_free((HICMA_option_t *) apOptions); +} + +void HicmaStarPuHelpers::ExaGeoStatOptionsFinalize(void *apOptions) { + auto *options = (HICMA_option_t *) apOptions; + HICMA_RUNTIME_options_finalize(options, (HICMA_context_t *) ExaGeoStatHardware::GetHicmaContext()); +} + +void *HicmaStarPuHelpers::ExaGeoStatDataGetAddr(void *apDescriptor, const int &aDescRow, const int &aDescCol) { + return HICMA_RUNTIME_data_getaddr((HICMA_desc_t *) apDescriptor, aDescRow, aDescCol); +} + +int HicmaStarPuHelpers::GetMT(void *apDescriptor) { + auto descriptor = (HICMA_desc_t *) apDescriptor; + return descriptor->mt; +} + +int HicmaStarPuHelpers::GetM(void *apDescriptor) { + auto descriptor = (HICMA_desc_t *) apDescriptor; + return descriptor->m; +} + +int HicmaStarPuHelpers::GetMB(void *apDescriptor) { + auto descriptor = (HICMA_desc_t *) apDescriptor; + return descriptor->mb; +} + +void *HicmaStarPuHelpers::GetOptions() { + return new HICMA_option_t; +} + +void HicmaStarPuHelpers::DeleteOptions(void *apOptions) { + delete (HICMA_option_t *) apOptions; +} diff --git a/tests/R-tests/TestDataGeneration.R b/tests/R-tests/TestDataGeneration.R new file mode 100644 index 00000000..50955842 --- /dev/null +++ b/tests/R-tests/TestDataGeneration.R @@ -0,0 +1,57 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST)# + +# @file TestDataGeneration.R +# @brief +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @date 2024-02-09 + +library("ExaGeoStatCPP") + +paste("---------------------------------------------------------------------------------------------") +paste("ExaGeoStat with Data Generation only - saving data with default path") + +# Variables +dimension = "3D" +ncores <- 4 +ngpus <- 0 +problem_size <- 16 +dts <- 8 +lts <- 0 +computation <- "exact" +kernel <- "univariate_matern_stationary" +initial_theta <- c(1,0.1,0.5) + +# You need to provide a log_path to save the data. +log_path <- getwd() +# data path is where to read data from +data_path <- "" +# observations file path is where to read observation file +observations_file <- "" +# recovery file path is where to read recovery file +recovery_file <- "" +p <- 1 +q <- 1 + +hardware <- new(Hardware, computation, ncores, ngpus, p, q) +exageostat_data <- simulate_data(kernel=kernel, initial_theta=initial_theta, problem_size=problem_size, dts=dts, dimension=dimension, log_path=log_path) + +# Print the data.. +paste("** Locations X - Y - Z") +locations <- get_locations(data=exageostat_data) +paste(locations) + +paste("---------------------------------------------------------------------------------------------") +paste("ExaGeoStat with Data Generation - Reading Data") + +# data path is where to read data from +data_path <- "./synthetic_ds/SYN_16_1" + +exageostat_data <- simulate_data(kernel=kernel, initial_theta=initial_theta, problem_size=problem_size, dts=dts, dimension=dimension, data_path=data_path) + +paste("** Locations X - Y - Z - after reading") +locations <- get_locations(data=exageostat_data) +paste(locations) \ No newline at end of file diff --git a/tests/R-tests/TestDataModeling.R b/tests/R-tests/TestDataModeling.R new file mode 100644 index 00000000..f0b1567d --- /dev/null +++ b/tests/R-tests/TestDataModeling.R @@ -0,0 +1,76 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST)# + +# @file TestDataGeneration.R +# @brief +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @date 2024-02-09 + +library("ExaGeoStatCPP") + +paste("---------------------------------------------------------------------------------------------") +paste("ExaGeoStat with data Modeling only - dst") + +dimension = "2D" +ncores <- 2 +ngpus <- 0 +problem_size <- 16 +dts <- 8 +lts <- 0 +computation <- "diag_approx" +kernel <- "univariate_matern_stationary" +initial_theta <- c(1,0.1,0.5) +lower_bound <- c(0.1,0.1,0.1) +upper_bound <- c(5,5,5) +p <- 1 +q <- 1 + +hardware <- new(Hardware, computation, ncores, ngpus, p, q) + +z_value <- c( -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) + +locations_x <- c(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) + +locations_y <- c(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) + +theta <- model_data(matrix=z_value, x=locations_x, y=locations_y, kernel=kernel, dts=dts, dimension=dimension,lb=lower_bound, ub=upper_bound, mle_itr=10, computation=computation, band=1) +hardware$finalize_hardware() + +paste("---------------------------------------------------------------------------------------------") +paste("ExaGeoStat with data Modeling only - tlr") + +lts <- 8 +computation <- "tlr" + +hardware <- new(Hardware, computation, ncores, ngpus, 1, 1) +empty_data <- new(Data, problem_size, dimension) +theta <- model_data(matrix=z_value, x=locations_x, y=locations_y, kernel=kernel, dts=dts, lts=lts, dimension=dimension,lb=lower_bound, ub=upper_bound, mle_itr=10, computation=computation) +hardware$finalize_hardware() + +paste("---------------------------------------------------------------------------------------------") +paste("ExaGeoStat with data Modeling only - exact") + +lts <- 0 +computation <- "exact" + +empty_data <- new(Data, problem_size, dimension) +hardware <- new(Hardware, computation, ncores, ngpus, 1, 1) +theta <- model_data(matrix=z_value, x=locations_x, y=locations_y, kernel=kernel, dts=dts, dimension=dimension,lb=lower_bound, ub=upper_bound, mle_itr=10, computation=computation) diff --git a/tests/R-tests/TestDataPrediction.R b/tests/R-tests/TestDataPrediction.R new file mode 100644 index 00000000..2afeb679 --- /dev/null +++ b/tests/R-tests/TestDataPrediction.R @@ -0,0 +1,74 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST)# + +# @file TestDataPrediction.R +# @brief +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @date 2024-02-09 + +library("ExaGeoStatCPP") + +paste("---------------------------------------------------------------") +paste("ExaGeoStat with data Prediction only - mspe") + +dimension = "2D" +ncores <- 2 +ngpus <- 0 +problem_size <- 16 +dts <- 8 +lts <- 0 +computation <- "exact" +kernel <- "univariate_matern_stationary" +estimated_theta <- c(1,0.1,0.5) +p <- 1 +q <- 1 + +hardware <- new(Hardware, computation, ncores, ngpus, p, q) + +z_value <- c(-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) + +locations_x <- c(0.092042420080872822, 0.193041886015106440, 0.330556191348134576, + 0.181612878614480805, 0.370473792629892440, 0.652140077821011688, + 0.553322652018005678, 0.800961318379491916, 0.207324330510414295, + 0.465445944914930965, 0.528267338063630132, 0.974792095826657490, + 0.552452887769893985, 0.877592126344701295) + +locations_y <- c(0.928648813611047563, 0.103883421072709245, 0.135790035858701447, 0.434683756771190977, + 0.400778210116731537, 0.168459601739528508, 0.105195696955825133, + 0.396398870832379624, 0.296757457846952011, 0.564507515068284116, + 0.627679865720607300, 0.958236057068741931, + 0.573571374074921758, 0.568657969024185528) + +test_x <- c(0.347951, 0.62768) +test_y <- c(0.806332, 0.105196) +predict_data(train_data=list(locations_x, locations_y, z_value), test_data=list(test_x, test_y), kernel=kernel, dts=dts, estimated_theta=estimated_theta) + +paste("---------------------------------------------------------------") +paste("ExaGeoStat with data Prediction only - idw") + +test_measurements = c(-1.05428, -1.47441) +idw_error = idw(train_data=list(locations_x, locations_y, z_value), test_data=list(test_x, test_y), kernel=kernel, dts=dts, estimated_theta=estimated_theta, test_measurements=test_measurements) +paste("idw error values:") +paste(idw_error) + +paste("---------------------------------------------------------------") +paste("ExaGeoStat with data Prediction only - fisher") + +fisher_matrix <- fisher(train_data=list(locations_x, locations_y, z_value), test_data=list(test_x, test_y), kernel=kernel, dts=dts, estimated_theta=estimated_theta) +paste("fisher matrix values:") +paste(fisher_matrix) + +paste("---------------------------------------------------------------") +paste("ExaGeoStat with data Prediction only - MLOE-MMOM") +true_theta <- c(1.1,0.2,0.5) + +result_mloe_mmom = mloe_mmom(train_data=list(locations_x, locations_y, z_value), test_data=list(test_x, test_y), kernel=kernel, dts=dts, estimated_theta=estimated_theta, true_theta=true_theta) +cat(sprintf("MLOE = %.6f", result_mloe_mmom[1]), "\n") +cat(sprintf("MMOM = %.6f", result_mloe_mmom[2]), "\n") diff --git a/tests/R-tests/TestExaGeoStatAPI.R b/tests/R-tests/TestExaGeoStatAPI.R new file mode 100644 index 00000000..618c2c2c --- /dev/null +++ b/tests/R-tests/TestExaGeoStatAPI.R @@ -0,0 +1,78 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST)# + +# @file TestExaGeoStatAPI.R +# @brief +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @date 2024-02-09 + +library("ExaGeoStatCPP") + +paste("---------------------------------------------------------------") +paste("ExaGeoStat with all Modules - Dense") + +ncores <- 1 +ngpus <- 0 +problem_size <- 16 +dts <- 8 +lts <- 0 +computation <- "exact" +dimension = "2D" +kernel <- "univariate_matern_stationary" +initial_theta <- c(1,0.1,0.5) +lower_bound <- c(0.1,0.1,0.1) +upper_bound <- c(5,5,5) +p <- 1 +q <- 1 + +hardware <- new(Hardware, computation, ncores, ngpus, p, q) + +exageostat_data <- simulate_data(kernel=kernel, initial_theta=initial_theta, problem_size=problem_size, dts=dts, dimension=dimension) +estimated_theta <- model_data(data=exageostat_data, kernel=kernel, dts=dts, dimension=dimension,lb=lower_bound, ub=upper_bound, mle_itr=10) + +test_x <- c(0.2, 0.330) +test_y <- c(0.104, 0.14) +locations = get_locations(data=exageostat_data) +predict_data(train_data=list(sapply(locations, function(v) v[1]), sapply(locations, function(v) v[2]), get_Z_measurement_vector(data=exageostat_data, type="chameleon")), test_data=list(test_x, test_y), kernel=kernel, dts=dts, estimated_theta=estimated_theta) + +paste("---------------------------------------------------------------------------------------------") +paste("ExaGeoStat with Data Generation only") +new_exageostat_data <- simulate_data(kernel=kernel, initial_theta=initial_theta, problem_size=problem_size, dts=dts, dimension=dimension) + +paste("---------------------------------------------------------------------------------------------") +paste("ExaGeoStat with data Modeling only") + +z_value <- c( -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) + +locations_x <- c(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) + +locations_y <- c(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) + +empty_data <- new(Data, problem_size, "2D") +estimated_theta <- model_data(data=empty_data, matrix=z_value, x=locations_x, y=locations_y, kernel=kernel, dts=dts, dimension=dimension,lb=lower_bound, ub=upper_bound, mle_itr=10) + +paste("---------------------------------------------------------------------------------------------") +paste("ExaGeoStat with data Prediction only") + +test_x <- c(0.2, 0.330) +test_y <- c(0.104, 0.14) + +predict_data(train_data=list(locations_x, locations_y, z_value), test_data=list(test_x, test_y), kernel=kernel, dts=dts, estimated_theta=estimated_theta) diff --git a/tests/cpp-tests/CMakeLists.txt b/tests/cpp-tests/CMakeLists.txt index 6d9a940d..75c33860 100644 --- a/tests/cpp-tests/CMakeLists.txt +++ b/tests/cpp-tests/CMakeLists.txt @@ -1,21 +1,32 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @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 () + +if (USE_R) + add_subdirectory(Rcpp-adapters) +endif () enable_testing() -add_executable(exageostat-tests ${EXAGEOSTAT_TESTFILES}) -target_link_libraries(exageostat-tests Catch2::Catch2WithMain ${PROJECT_NAME}_INTERFACE) -catch_discover_tests(exageostat-tests) \ No newline at end of file +add_executable(exageostat-tests main.cpp ${EXAGEOSTAT_TESTFILES}) +target_link_libraries(exageostat-tests Catch2::Catch2 ${PROJECT_NAME}_INTERFACE) +catch_discover_tests(exageostat-tests) diff --git a/tests/cpp-tests/Rcpp-adapters/CMakeLists.txt b/tests/cpp-tests/Rcpp-adapters/CMakeLists.txt new file mode 100644 index 00000000..9a4a59a5 --- /dev/null +++ b/tests/cpp-tests/Rcpp-adapters/CMakeLists.txt @@ -0,0 +1,16 @@ +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 1.1.0 +# @author Mahmoud ElKarargy +# @date 2024-02-09 + +set(EXAGEOSTAT_TESTFILES + + ${CMAKE_CURRENT_SOURCE_DIR}/TestAllRFunctions.cpp + ${EXAGEOSTAT_TESTFILES} + PARENT_SCOPE + ) + diff --git a/tests/cpp-tests/Rcpp-adapters/TestAllRFunctions.cpp b/tests/cpp-tests/Rcpp-adapters/TestAllRFunctions.cpp new file mode 100644 index 00000000..38f193e3 --- /dev/null +++ b/tests/cpp-tests/Rcpp-adapters/TestAllRFunctions.cpp @@ -0,0 +1,169 @@ +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file TestAllRFunctions.cpp + * @brief Test suite for R/Rcpp adapters in C++. + * @details This file contains tests for R methods adapted for use in C++ within the ExaGeoStat software package. + * It includes tests for initializing arguments, loading data, modeling data, and predicting data using Rcpp adapters. + * The test suite specifically verifies the integration and functionality of R methods through the Rcpp interface + * within a C++ environment, ensuring that statistical models and algorithms are correctly initialized, + * data is accurately loaded and processed, and predictions are properly executed. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-09 +**/ + +#include + +#include + +using namespace std; + +using namespace exageostat::adapters; +using namespace exageostat::common; + +void TEST_DATA_GENERATION() { + + const string computation = "exact"; + const string dimension = "2D"; + const string kernel = "univariate_matern_stationary"; + const string distance_matrix = "eg"; + const int cores_number = 1; + const int gpus_number = 0; + const int problem_size = 9; + const int dts = 3; + const int lts = 0; + const vector initial_theta = {1, 0.1, 0.5}; + const vector lower_bound = {0.1, 0.1, 0.1}; + const vector upper_bound = {5, 5, 5}; + const vector estimated_theta = {0.9, 0.2, 0.5}; + srand(0); + + auto hardware = ExaGeoStatHardware(computation, cores_number, gpus_number); + auto exageostat_data = R_ExaGeoStatLoadData(kernel, initial_theta, distance_matrix, problem_size, 0, dts, lts, + dimension, "", "", "", ""); + + 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}; + vector z = {-1.27234, -2.47547, 0.54585, -0.120985, 0.242569, -1.54421, 0.0986468, 0.779835, -1.48139}; + + for (int i = 0; i < problem_size; i++) { + REQUIRE((exageostat_data->GetLocations()->GetLocationX()[i] - x[i]) == Catch::Approx(0.0).margin(1e-6)); + REQUIRE((exageostat_data->GetLocations()->GetLocationY()[i] - y[i]) == Catch::Approx(0.0).margin(1e-6)); + REQUIRE((exageostat_data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z)[i] - + z[i]) == Catch::Approx(0.0).margin(1e-5)); + } + delete exageostat_data; +} + +void TEST_ALL_R_METHODS() { + + const string computation = "exact"; + const int cores_number = 1; + const int gpus_number = 0; + const string dimension = "2D"; + const string kernel = "univariate_matern_stationary"; + const string distance_matrix = "eg"; + const int dts = 8; + const int lts = 0; + + const vector initial_theta = {1, 0.1, 0.5}; + const vector estimated_theta = {0.9, 0.2, 0.5}; + const vector lower_bound = {0.1, 0.1, 0.1}; + const vector upper_bound = {5, 5, 5}; + + vector> train_data = { + {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}, + {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}, + {-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} + }; + vector> test_data = { + {0.193041886015106440, 0.330556191348134576}, + {0.103883421072709245, 0.135790035858701447} + }; + + auto hardware = ExaGeoStatHardware(computation, cores_number, gpus_number); + + SECTION("Prediction Method") { + + // Since we're testing with the same x and y that we sent to the train data, then we expect the same output. + auto result = R_ExaGeoStatPredictData(kernel, distance_matrix, estimated_theta, dts, lts, dimension, train_data, + test_data); + for (int i = 0; i < result.size(); i++) { + REQUIRE((result[i] - train_data[2][i]) == Catch::Approx(0.0).margin(1e-6)); + } + + // Now let's test with new values + test_data = { + {0.2, 0.3}, + {0.2, 0.2} + }; + result = R_ExaGeoStatPredictData(kernel, distance_matrix, estimated_theta, dts, lts, dimension, train_data, + test_data); + vector expected_output = {-1.04437, -1.63133}; + for (int i = 0; i < result.size(); i++) { + REQUIRE((result[i] - expected_output[i]) == Catch::Approx(0.0).margin(1e-5)); + } + + }SECTION("PREDICTION - Fisher") { + + auto result = R_ExaGeoStatFisher(kernel, distance_matrix, estimated_theta, dts, lts, dimension, train_data, + test_data); + + vector expected_output = {0.143552740378975224, 0.022642203822768981, 0.013749788660229965, + 0.022642203822769023, 0.143052423579629107, -0.371722296732991009, + 0.013749788660229986, -0.371722296732990953, 1.101996735797240667}; + + for (int i = 0; i < result.size(); i++) { + REQUIRE((result[i] - expected_output[i]) == Catch::Approx(0.0).margin(1e-6)); + } + } + + SECTION("PREDICTION - MLOE-MMOM") { + test_data = { + {0.347951, 0.62768}, + {0.806332, 0.105196}, + }; + auto result = R_ExaGeoStatMLOE_MMOM(kernel, distance_matrix, estimated_theta, initial_theta, dts, lts, + dimension, train_data, test_data); + vector expected_output = {0.0529825, -0.408526}; + for (int i = 0; i < result.size(); i++) { + REQUIRE((result[i] - expected_output[i]) == Catch::Approx(0.0).margin(1e-6)); + } + + result = R_ExaGeoStatMLOE_MMOM("univariate_matern_stationary", "eg", initial_theta, initial_theta, 8, 0, "2D", + train_data, test_data); + for (double i: result) { + REQUIRE((i - 0) == Catch::Approx(0.0).margin(1e-6)); + } + } + + SECTION("PREDICTION - IDW") { + + vector test_measurements = { + -1.05428, -1.47441 + }; + auto result = R_ExaGeoStatIDW(kernel, distance_matrix, estimated_theta, dts, lts, dimension, train_data, + test_data, test_measurements); + vector expected_output = {0.447903, 0.100866, 0.79494}; + for (int i = 0; i < result.size(); i++) { + REQUIRE((result[i] - expected_output[i]) == Catch::Approx(0.0).margin(1e-6)); + } + } +} + +TEST_CASE("Test R/Rcpp adapters in C++") { + TEST_DATA_GENERATION(); + TEST_ALL_R_METHODS(); +} \ No newline at end of file diff --git a/tests/cpp-tests/api/CMakeLists.txt b/tests/cpp-tests/api/CMakeLists.txt index 9748ef3d..4c8b2eeb 100644 --- a/tests/cpp-tests/api/CMakeLists.txt +++ b/tests/cpp-tests/api/CMakeLists.txt @@ -1,10 +1,10 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @author Sameh Abdulah # @date 2023-08-08 diff --git a/tests/cpp-tests/api/TestExaGeoStatApi.cpp b/tests/cpp-tests/api/TestExaGeoStatApi.cpp index 1241baa5..5edcf550 100644 --- a/tests/cpp-tests/api/TestExaGeoStatApi.cpp +++ b/tests/cpp-tests/api/TestExaGeoStatApi.cpp @@ -1,15 +1,15 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file TestExaGeoStatApi.cpp * @brief Test suite for the ExaGeoStat APIs data generation functionality. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah - * @date 2023-08-07 + * @date 2024-02-04 **/ #include @@ -18,8 +18,8 @@ using namespace std; using namespace exageostat::common; +using namespace exageostat::dataunits; using namespace exageostat::configurations; -using namespace exageostat::hardware; void TEST_GENERATE_DATA() { SECTION("Data generation - Observations") @@ -47,16 +47,15 @@ void TEST_GENERATE_DATA() { // initialize ExaGeoStat Hardware. auto hardware = ExaGeoStatHardware(EXACT_DENSE, 4, 0); // Or you could use configurations.GetComputation(). - exageostat::dataunits::ExaGeoStatData data; - exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, - data); + std::unique_ptr> data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(synthetic_data_configurations, data); // Define the expected output for desk Z 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, - DESCRIPTOR_Z).chameleon_desc; + auto *CHAM_descriptorZ = data->GetDescriptorData()->GetDescriptor(CHAMELEON_DESCRIPTOR, + DESCRIPTOR_Z).chameleon_desc; auto *A = (double *) CHAM_descriptorZ->mat; double diff; @@ -80,7 +79,7 @@ void TEST_MODEL_DATA(Computation aComputation) { configurations.SetDenseTileSize(dts); configurations.SetComputation(aComputation); configurations.SetMaxMleIterations(3); - configurations.SetTolerance(pow(10, -4)); + configurations.SetTolerance(4); vector lb{0.1, 0.1, 0.1}; configurations.SetLowerBounds(lb); @@ -108,8 +107,9 @@ 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,11 +133,11 @@ 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); + double log_likelihood = exageostat::api::ExaGeoStat::ExaGeoStatDataModeling(configurations, data, + z_matrix); REQUIRE((log_likelihood - expected) == Catch::Approx(0.0).margin(1e-6)); delete[] location_x; @@ -147,11 +147,9 @@ 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; - exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, configurations, - data); - double log_likelihood = exageostat::api::ExaGeoStat::ExaGeoStatDataModeling(hardware, configurations, - data); + std::unique_ptr> data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(configurations, data); + double log_likelihood = exageostat::api::ExaGeoStat::ExaGeoStatDataModeling(configurations, data); REQUIRE((log_likelihood - expected) == Catch::Approx(0.0).margin(1e-6)); } } @@ -167,7 +165,7 @@ void TEST_PREDICTION() { configurations.SetDenseTileSize(dts); configurations.SetComputation(EXACT_DENSE); configurations.SetMaxMleIterations(3); - configurations.SetTolerance(pow(10, -4)); + configurations.SetTolerance(4); vector lb{0.1, 0.1, 0.1}; configurations.SetLowerBounds(lb); @@ -181,7 +179,8 @@ 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,33 +202,33 @@ 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") { vector new_estimated_theta{0.9, 0.09, 0.4}; configurations.SetEstimatedTheta(new_estimated_theta); configurations.SetIsMSPE(true); - exageostat::api::ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data, z_matrix); + exageostat::api::ExaGeoStat::ExaGeoStatPrediction(configurations, data, z_matrix); }SECTION("Test Prediction - IDW ONLY") { configurations.SetIsMSPE(false); configurations.SetIsIDW(true); - exageostat::api::ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data, z_matrix); + exageostat::api::ExaGeoStat::ExaGeoStatPrediction(configurations, data, z_matrix); }SECTION("Test Prediction - MLOE_MMOM ONLY") { configurations.SetIsMSPE(false); configurations.SetIsIDW(false); vector new_estimated_theta{0.9, 0.09, 0.4}; configurations.SetEstimatedTheta(new_estimated_theta); configurations.SetIsMLOEMMOM(true); - exageostat::api::ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data, z_matrix); + exageostat::api::ExaGeoStat::ExaGeoStatPrediction(configurations, data, z_matrix); }SECTION("Test Prediction - FISHER\n") { configurations.SetIsMLOEMMOM(false); configurations.SetIsFisher(true); vector new_estimated_theta{0.9, 0.09, 0.4}; configurations.SetEstimatedTheta(new_estimated_theta); - exageostat::api::ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data, z_matrix); + exageostat::api::ExaGeoStat::ExaGeoStatPrediction(configurations, data, z_matrix); }SECTION("Test Prediction - ALL OPERATIONS") { vector new_estimated_theta{0.9, 0.09, 0.4}; configurations.SetEstimatedTheta(new_estimated_theta); @@ -239,16 +238,15 @@ void TEST_PREDICTION() { configurations.SetIsFisher(true); // Setting Estimated with initial theta will require mloe_mmom to be zero configurations.SetEstimatedTheta(initial_theta); - exageostat::api::ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data, z_matrix); + exageostat::api::ExaGeoStat::ExaGeoStatPrediction(configurations, data, z_matrix); }SECTION("Test Prediction - ALL MODULES") { configurations.SetIsMSPE(true); configurations.SetIsIDW(true); configurations.SetIsFisher(true); configurations.SetIsMLOEMMOM(true); - exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, configurations, - data); - exageostat::api::ExaGeoStat::ExaGeoStatDataModeling(hardware, configurations, data); - exageostat::api::ExaGeoStat::ExaGeoStatPrediction(hardware, configurations, data, z_matrix); + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(configurations, data); + exageostat::api::ExaGeoStat::ExaGeoStatDataModeling(configurations, data); + exageostat::api::ExaGeoStat::ExaGeoStatPrediction(configurations, data, z_matrix); } delete[] location_x; delete[] location_y; @@ -259,6 +257,8 @@ TEST_CASE("ExaGeoStat API tests") { TEST_GENERATE_DATA(); TEST_MODEL_DATA(EXACT_DENSE); TEST_MODEL_DATA(DIAGONAL_APPROX); +#ifdef USE_HICMA TEST_MODEL_DATA(TILE_LOW_RANK); +#endif TEST_PREDICTION(); } \ No newline at end of file diff --git a/tests/cpp-tests/configurations/data-generation/CMakeLists.txt b/tests/cpp-tests/configurations/CMakeLists.txt similarity index 65% rename from tests/cpp-tests/configurations/data-generation/CMakeLists.txt rename to tests/cpp-tests/configurations/CMakeLists.txt index bdcadc45..9b9999e2 100644 --- a/tests/cpp-tests/configurations/data-generation/CMakeLists.txt +++ b/tests/cpp-tests/configurations/CMakeLists.txt @@ -1,16 +1,16 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @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 58% rename from tests/cpp-tests/configurations/data-generation/concrete/TestSyntheticDataConfigurations.cpp rename to tests/cpp-tests/configurations/TestConfigurations.cpp index 0aa00c4e..6ea294f6 100644 --- a/tests/cpp-tests/configurations/data-generation/concrete/TestSyntheticDataConfigurations.cpp +++ b/tests/cpp-tests/configurations/TestConfigurations.cpp @@ -1,18 +1,18 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** -* @file 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.1.0 + * @author Mahmoud ElKarargy + * @date 2023-01-31 **/ #include @@ -25,6 +25,75 @@ 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() == pow(10, -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 +182,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/CMakeLists.txt b/tests/cpp-tests/data-generators/CMakeLists.txt index c3e1f4de..c84e7cfd 100644 --- a/tests/cpp-tests/data-generators/CMakeLists.txt +++ b/tests/cpp-tests/data-generators/CMakeLists.txt @@ -1,10 +1,10 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @date 2023-03-08 diff --git a/tests/cpp-tests/data-generators/concrete/TestCSVDataGenerator.cpp b/tests/cpp-tests/data-generators/concrete/TestCSVDataGenerator.cpp index a26be8d0..8585b837 100644 --- a/tests/cpp-tests/data-generators/concrete/TestCSVDataGenerator.cpp +++ b/tests/cpp-tests/data-generators/concrete/TestCSVDataGenerator.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @author Mahmoud ElKarargy * @date 2023-03-08 **/ @@ -19,14 +19,16 @@ #include #include #include +#include using namespace std; using namespace exageostat::generators; using namespace exageostat::dataunits; using namespace exageostat::common; -using namespace exageostat::configurations; using namespace exageostat::kernels; +using namespace exageostat::configurations; +using namespace exageostat::dataLoader::csv; void TEST_CSV_P_1() { int N = 16; @@ -36,7 +38,6 @@ void TEST_CSV_P_1() { read_path = read_path + +"tests/cpp-tests/data-generators/concrete/synthetic_ds/SYN_16_1"; Configurations configurations; - configurations.SetIsCSV(true); configurations.SetIsSynthetic(false); configurations.SetProblemSize(16); configurations.SetDenseTileSize(8); @@ -47,11 +48,12 @@ 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(), - configurations.GetGPUsNumbers()); + auto hardware = ExaGeoStatHardware(configurations.GetComputation(), + configurations.GetCoresNumber(), + configurations.GetGPUsNumbers()); //creating locations x and y. auto *location_x = new double[N]{0.193041886015106440, 0.330556191348134576, 0.181612878614480805, @@ -87,15 +89,12 @@ void TEST_CSV_P_1() { locations.SetLocationX(*location_x, N); locations.SetLocationY(*location_y, N); - exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N, p, write_path, locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + CSVLoader::GetInstance()->WriteData(*measurements_matrix, N, p, write_path, locations); + auto data = csv_reader->CreateData(configurations, *pKernel); - 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 z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z); + 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)); @@ -120,16 +119,13 @@ void TEST_CSV_P_1() { locations.SetLocationY(*location_y, N); locations.SetLocationZ(*location_z, N); - exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N, p, write_path, locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + CSVLoader::GetInstance()->WriteData(*measurements_matrix, N, p, write_path, locations); + auto data = csv_reader->CreateData(configurations, *pKernel); - 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 z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z); + 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 +133,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.") { @@ -155,16 +152,13 @@ void TEST_CSV_P_1() { locations.SetLocationY(*location_y, N); locations.SetLocationZ(*location_time, N); - exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N, p, write_path, locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + CSVLoader::GetInstance()->WriteData(*measurements_matrix, N, p, write_path, locations); + auto data = csv_reader->CreateData(configurations, *pKernel); - 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 z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z); + 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 +166,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; @@ -189,21 +183,20 @@ void TEST_CSV_P_2() { read_path = read_path + +"tests/cpp-tests/data-generators/concrete/synthetic_ds/SYN_16_1"; Configurations configurations; - configurations.SetIsCSV(true); 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(), - configurations.GetGPUsNumbers()); + auto hardware = ExaGeoStatHardware(configurations.GetComputation(), + configurations.GetCoresNumber(), + configurations.GetGPUsNumbers()); //creating locations x and y. auto *location_x = new double[N]{0.193041886015106440, 0.330556191348134576, 0.181612878614480805, @@ -250,16 +243,13 @@ void TEST_CSV_P_2() { locations.SetLocationX(*location_x, N); locations.SetLocationY(*location_y, N); - exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N * p, p, write_path, - locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + CSVLoader::GetInstance()->WriteData(*measurements_matrix, N * p, p, write_path, + locations); + auto data = csv_reader->CreateData(configurations, *pKernel); - 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 z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z); + 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)); @@ -287,17 +277,14 @@ void TEST_CSV_P_2() { locations.SetLocationY(*location_y, N); locations.SetLocationZ(*location_z, N); - exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N * p, p, write_path, - locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + CSVLoader::GetInstance()->WriteData(*measurements_matrix, N * p, p, write_path, + locations); + auto data = csv_reader->CreateData(configurations, *pKernel); - 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 z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z); + 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 +292,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.") { @@ -327,17 +314,14 @@ void TEST_CSV_P_2() { locations.SetLocationY(*location_y, N); locations.SetLocationZ(*location_time, N); - exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N * p, p, write_path, - locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + CSVLoader::GetInstance()->WriteData(*measurements_matrix, N * p, p, write_path, + locations); + auto data = csv_reader->CreateData(configurations, *pKernel); - 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 z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z); + 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 +329,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; @@ -362,23 +346,22 @@ void TEST_CSV_P_3() { read_path = read_path + +"tests/cpp-tests/data-generators/concrete/synthetic_ds/SYN_16_1"; Configurations configurations; - configurations.SetIsCSV(true); 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(), - configurations.GetGPUsNumbers()); + auto hardware = ExaGeoStatHardware(configurations.GetComputation(), + configurations.GetCoresNumber(), + configurations.GetGPUsNumbers()); //creating locations x and y. auto *location_x = new double[N]{0.193041886015106440, 0.330556191348134576, 0.181612878614480805, @@ -422,16 +405,13 @@ void TEST_CSV_P_3() { locations.SetLocationX(*location_x, N); locations.SetLocationY(*location_y, N); - exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N * p, p, write_path, - locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + CSVLoader::GetInstance()->WriteData(*measurements_matrix, N * p, p, write_path, + locations); + auto data = csv_reader->CreateData(configurations, *pKernel); - 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 z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z); + 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)); @@ -457,17 +437,14 @@ void TEST_CSV_P_3() { locations.SetLocationY(*location_y, N); locations.SetLocationZ(*location_z, N); - exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N * p, p, write_path, - locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + CSVLoader::GetInstance()->WriteData(*measurements_matrix, N * p, p, write_path, + locations); + auto data = csv_reader->CreateData(configurations, *pKernel); - 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 z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z); + 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 +453,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.") { @@ -494,17 +472,14 @@ void TEST_CSV_P_3() { locations.SetLocationY(*location_y, N); locations.SetLocationZ(*location_time, N); - exageostat::helpers::DiskWriter::WriteVectorsToDisk(*measurements_matrix, N * p, p, write_path, - locations); - auto data = *csv_reader->CreateData(configurations, hardware, *pKernel); + CSVLoader::GetInstance()->WriteData(*measurements_matrix, N * p, p, write_path, + locations); + auto data = csv_reader->CreateData(configurations, *pKernel); - 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 z_desc_mat = data->GetDescriptorData()->GetDescriptorMatrix(CHAMELEON_DESCRIPTOR, DESCRIPTOR_Z); + 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 +487,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..25e07650 100644 --- a/tests/cpp-tests/data-generators/concrete/TestSyntheticGenerator.cpp +++ b/tests/cpp-tests/data-generators/concrete/TestSyntheticGenerator.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @author Mahmoud ElKarargy * @date 2023-03-08 **/ @@ -20,6 +20,8 @@ #include #include #include +#include +#include using namespace std; @@ -27,8 +29,9 @@ using namespace exageostat::generators::synthetic; using namespace exageostat::generators; using namespace exageostat::dataunits; using namespace exageostat::common; -using namespace exageostat::configurations; using namespace exageostat::kernels; +using namespace exageostat::helpers; +using namespace exageostat::configurations; 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,19 +194,20 @@ 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(), - synthetic_data_configurations.GetCoresNumber(), - synthetic_data_configurations.GetGPUsNumbers()); + auto hardware = ExaGeoStatHardware(synthetic_data_configurations.GetComputation(), + synthetic_data_configurations.GetCoresNumber(), + synthetic_data_configurations.GetGPUsNumbers()); SECTION("2D Generation") { unique_ptr> synthetic_generator = DataGenerator::CreateGenerator( 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, *pKernel); double *x = data->GetLocations()->GetLocationX(); double *y = data->GetLocations()->GetLocationY(); @@ -213,15 +217,12 @@ void TEST_GENERATE_LOCATIONS() { REQUIRE(x[i] != 0); REQUIRE(y[i] != 0); } - delete data; - } - SECTION("3D Generation") + }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, - hardware, *pKernel); + auto data = synthetic_generator->CreateData(synthetic_data_configurations, *pKernel); double *x = data->GetLocations()->GetLocationX(); double *y = data->GetLocations()->GetLocationY(); @@ -232,16 +233,14 @@ void TEST_GENERATE_LOCATIONS() { REQUIRE(y[i] != 0); REQUIRE(z[i] != 0); } - delete data; - } - SECTION("ST Generation") + + }SECTION("ST Generation") { synthetic_data_configurations.SetDimension(DimensionST); synthetic_data_configurations.SetTimeSlot(2); unique_ptr> synthetic_generator = DataGenerator::CreateGenerator( synthetic_data_configurations); - auto *data = synthetic_generator->CreateData(synthetic_data_configurations, - hardware, *pKernel); + auto data = synthetic_generator->CreateData(synthetic_data_configurations, *pKernel); double *x = data->GetLocations()->GetLocationX(); double *y = data->GetLocations()->GetLocationY(); @@ -252,7 +251,7 @@ void TEST_GENERATE_LOCATIONS() { REQUIRE(y[i] != 0.0); REQUIRE(z[i] != 0.0); } - delete data; + } delete pKernel; @@ -269,7 +268,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 +276,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(); } } @@ -298,18 +297,19 @@ void TEST_GENERATION() { synthetic_data_configurations.SetDenseTileSize(1); synthetic_data_configurations.SetKernelName("UnivariateMaternStationary"); synthetic_data_configurations.SetComputation(exageostat::common::EXACT_DENSE); - auto hardware = exageostat::hardware::ExaGeoStatHardware(synthetic_data_configurations.GetComputation(), - synthetic_data_configurations.GetCoresNumber(), - synthetic_data_configurations.GetGPUsNumbers()); + auto hardware = ExaGeoStatHardware(synthetic_data_configurations.GetComputation(), + 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, *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 +320,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, *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 +329,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, *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..1bbfb1df --- /dev/null +++ b/tests/cpp-tests/data-units/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 1.1.0 +# @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..5f87d1a0 --- /dev/null +++ b/tests/cpp-tests/data-units/TestDescriptorData.cpp @@ -0,0 +1,64 @@ +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file 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.1.0 + * @author Mahmoud ElKarargy + * @date 2024-02-04 +**/ + +#include + +#include + +using namespace std; + +using namespace exageostat::linearAlgebra; +using namespace exageostat::common; +using namespace exageostat::dataunits; +using namespace exageostat::configurations; + +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(TILE_LOW_RANK, 1, 0); + auto linearAlgebraSolver = LinearAlgebraFactory::CreateLinearAlgebraSolver(EXACT_DENSE); + 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,DESCRIPTOR_C); + + // 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..c60a7043 --- /dev/null +++ b/tests/cpp-tests/hardware/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 1.1.0 +# @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..67e0e2a3 --- /dev/null +++ b/tests/cpp-tests/hardware/TestExaGeoStatHardware.cpp @@ -0,0 +1,111 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file 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.1.0 + * @author Mahmoud ElKarargy + * @date 2024-01-24 +**/ + +#include + +#include + +using namespace exageostat::common; + +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..c3f0158c 100644 --- a/tests/cpp-tests/helpers/CMakeLists.txt +++ b/tests/cpp-tests/helpers/CMakeLists.txt @@ -1,16 +1,16 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @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..2ffc65dc --- /dev/null +++ b/tests/cpp-tests/helpers/TestDiskWriter.cpp @@ -0,0 +1,83 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file 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.1.0 + * @author Mahmoud ElKarargy + * @date 2024-01-24 +**/ + +#include +#include + +#include +#include + +using namespace exageostat::dataunits; +using namespace exageostat::common; +using namespace exageostat::dataLoader::csv; + +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 + CSVLoader::GetInstance()->WriteData(*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..aae67a88 --- /dev/null +++ b/tests/cpp-tests/helpers/TestDistanceCalculationHelpers.cpp @@ -0,0 +1,144 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file 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.1.0 + * @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..40ea4ea0 100644 --- a/tests/cpp-tests/kernels/CMakeLists.txt +++ b/tests/cpp-tests/kernels/CMakeLists.txt @@ -1,35 +1,18 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @author Mahmoud ElKarargy # @date 2023-04-29 -set(EXAGEOSTAT_TESTFILES +# Automatically add all kernels tests in the concrete directory. +file(GLOB ALL_KERNELS ${CMAKE_CURRENT_SOURCE_DIR}/concrete/*.cpp) - ${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 - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternNuggetsStationary.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateSpacetimeMaternStationary.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDnu.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDbeta.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDdsigmaSquare.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDdsigmaSquareBeta.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDdsigmaSquareNu.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDdbetaBeta.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDdbetaNu.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestUnivariateMaternDdnuNu.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/concrete/TestBivariateSpacetimeMaternStationary.cpp - ${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 +set(EXAGEOSTAT_TESTFILES + ${ALL_KERNELS} ${EXAGEOSTAT_TESTFILES} PARENT_SCOPE - ) + ) \ No newline at end of file diff --git a/tests/cpp-tests/kernels/concrete/TestBivariateMaternFlexible.cpp b/tests/cpp-tests/kernels/concrete/TestBivariateMaternFlexible.cpp index 9ad99895..0189e7c5 100644 --- a/tests/cpp-tests/kernels/concrete/TestBivariateMaternFlexible.cpp +++ b/tests/cpp-tests/kernels/concrete/TestBivariateMaternFlexible.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-09 @@ -19,10 +19,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; -using namespace exageostat::hardware; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_BivariateMaternFlexible() { @@ -49,11 +48,10 @@ void TEST_KERNEL_GENERATION_BivariateMaternFlexible() { 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; + std::unique_ptr> data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(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[] = {-0.696887, -2.069051, -0.417382, -1.001165, -0.235721, -1.726871, -0.285059, diff --git a/tests/cpp-tests/kernels/concrete/TestBivariateMaternParsimonious.cpp b/tests/cpp-tests/kernels/concrete/TestBivariateMaternParsimonious.cpp index 497a979b..fd951ab6 100644 --- a/tests/cpp-tests/kernels/concrete/TestBivariateMaternParsimonious.cpp +++ b/tests/cpp-tests/kernels/concrete/TestBivariateMaternParsimonious.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -20,10 +20,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; -using namespace exageostat::hardware; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_BivariateMaternParsimonious() { @@ -50,11 +49,10 @@ void TEST_KERNEL_GENERATION_BivariateMaternParsimonious() { 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; + std::unique_ptr> data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(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.272336, -2.466950, 0.294719, -0.605327, 0.386028, -1.598090, 0.278897, diff --git a/tests/cpp-tests/kernels/concrete/TestBivariateSpacetimeMaternStationary.cpp b/tests/cpp-tests/kernels/concrete/TestBivariateSpacetimeMaternStationary.cpp index 81fde6bf..c03aa2ff 100644 --- a/tests/cpp-tests/kernels/concrete/TestBivariateSpacetimeMaternStationary.cpp +++ b/tests/cpp-tests/kernels/concrete/TestBivariateSpacetimeMaternStationary.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -20,10 +20,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; -using namespace exageostat::hardware; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_BivariateSpacetimeMaternStationary() { @@ -41,7 +40,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 +50,18 @@ void TEST_KERNEL_GENERATION_BivariateSpacetimeMaternStationary() { 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; + std::unique_ptr> data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(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.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..c412e4db 100644 --- a/tests/cpp-tests/kernels/concrete/TestTrivariateMaternParsimonious.cpp +++ b/tests/cpp-tests/kernels/concrete/TestTrivariateMaternParsimonious.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -20,10 +20,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; -using namespace exageostat::hardware; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_TrivariateMaternParsimonious() { @@ -48,11 +47,10 @@ void TEST_KERNEL_GENERATION_TrivariateMaternParsimonious() { 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; + std::unique_ptr> data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(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[] = { diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateExpNonGaussian.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateExpNonGaussian.cpp index 18abd91e..984f33be 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateExpNonGaussian.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateExpNonGaussian.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file TestUnivariateExpNonGaussian.cpp * @brief - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDbeta.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDbeta.cpp index 0ec31efd..43fba252 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDbeta.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDbeta.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -8,7 +8,7 @@ * @brief Unit tests for the TestUnivariateMaternDbeta kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateMaternDbeta 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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -18,8 +18,9 @@ #include using namespace std; -using namespace exageostat::configurations; + using namespace exageostat::common; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_UnivariateMaternDbeta() { diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdbetaBeta.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdbetaBeta.cpp index 9102f9b6..76e5cdea 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdbetaBeta.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdbetaBeta.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -8,7 +8,7 @@ * @brief Unit tests for the TestUnivariateMaternDdbetaBeta kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateMaternDdbetaBeta 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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -19,9 +19,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_UnivariateMaternDdbetaBeta() { diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdbetaNu.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdbetaNu.cpp index 903ef13a..3d7e03d4 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdbetaNu.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdbetaNu.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -8,7 +8,7 @@ * @brief Unit tests for the TestUnivariateMaternDdbetaNu kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateMaternDdbetaNu 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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -19,10 +19,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; -using namespace exageostat::hardware; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_UnivariateMaternDdbetaNu() { diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdnuNu.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdnuNu.cpp index 4e0b3a74..762208e4 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdnuNu.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdnuNu.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -8,7 +8,7 @@ * @brief Unit tests for the TestUnivariateMaternDdnuNu kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateMaternDdnuNu 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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -19,9 +19,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_UnivariateMaternDdnuNu() { diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdsigmaSquare.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdsigmaSquare.cpp index f3e9d072..775847ad 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdsigmaSquare.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdsigmaSquare.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -8,7 +8,7 @@ * @brief Unit tests for the TestUnivariateMaternDdsigmaSquare kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateMaternDdsigmaSquare 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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -17,11 +17,11 @@ #include #include -using namespace exageostat::configurations; +using namespace std; + using namespace exageostat::common; using namespace exageostat::api; - -using namespace std; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_UnivariateMaternDdsigmaSquare() { diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdsigmaSquareBeta.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdsigmaSquareBeta.cpp index 9f277794..657e1357 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdsigmaSquareBeta.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdsigmaSquareBeta.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -8,7 +8,7 @@ * @brief Unit tests for the TestUnivariateMaternDdsigmaSquareBetaBeta kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateMaternDdsigmaSquareBetaBeta 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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -18,9 +18,10 @@ #include using namespace std; -using namespace exageostat::configurations; + using namespace exageostat::api; using namespace exageostat::common; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_UnivariateMaternDdsigmaSquareBeta() { diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdsigmaSquareNu.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdsigmaSquareNu.cpp index 566786bc..785eb847 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdsigmaSquareNu.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDdsigmaSquareNu.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -8,7 +8,7 @@ * @brief Unit tests for the TestUnivariateMaternDdsigmaSquareNu kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateMaternDdsigmaSquareNu 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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -19,9 +19,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_UnivariateMaternDdsigmaSquareNu() { diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDnu.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDnu.cpp index 5d212512..cdfbbf2c 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDnu.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDnu.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -8,7 +8,7 @@ * @brief Unit tests for the TestUnivariateMaternDnu kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateMaternDnu 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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -19,9 +19,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_UnivariateMaternDnu() { SECTION("UnivariateMaternDnu") diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDsigmaSquare.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDsigmaSquare.cpp index dde48ff4..bb44c9bc 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDsigmaSquare.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternDsigmaSquare.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -8,7 +8,7 @@ * @brief Unit tests for the TestUnivariateMaternDdsigmaSquare kernel in the ExaGeoStat software package. * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariateMaternDdsigmaSquare 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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-29 @@ -19,9 +19,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_UnivariateMaternDsigmaSquare() { diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonGaussian.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonGaussian.cpp index daec5161..7252175e 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonGaussian.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonGaussian.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -19,10 +19,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; -using namespace exageostat::hardware; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_UnivariateMaternNonGaussian() { @@ -36,6 +35,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,11 +51,10 @@ void TEST_KERNEL_GENERATION_UnivariateMaternNonGaussian() { 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; + std::unique_ptr> data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(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[] = { @@ -60,7 +64,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/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..28bc9221 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNuggetsStationary.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNuggetsStationary.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -20,10 +20,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; -using namespace exageostat::hardware; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_UnivariateMaternNuggetsStationary() { @@ -48,11 +47,10 @@ void TEST_KERNEL_GENERATION_UnivariateMaternNuggetsStationary() { 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; + std::unique_ptr> data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(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[] = { diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternStationary.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternStationary.cpp index 461c0a20..c74cc623 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternStationary.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateMaternStationary.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-04-29 @@ -20,10 +20,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; -using namespace exageostat::hardware; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_UnivariateMaternStationary() { @@ -49,12 +48,11 @@ void TEST_KERNEL_GENERATION_UnivariateMaternStationary() { int seed = 0; srand(seed); - exageostat::dataunits::ExaGeoStatData data; - exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, - data); + std::unique_ptr> data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(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.475473, 0.545850, -0.120985, 0.242569, -1.544215, 0.098647, diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonStat.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariatePowExpStationary.cpp similarity index 55% rename from tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonStat.cpp rename to tests/cpp-tests/kernels/concrete/TestUnivariatePowExpStationary.cpp index a7382c04..e6c65c16 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateMaternNonStat.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariatePowExpStationary.cpp @@ -1,17 +1,17 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** - * @file 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 + * @file TestUnivariatePowExpStationary.cpp + * @brief Unit tests for the TestUnivariatePowExpStationary kernel in the ExaGeoStat software package. + * @details This file contains Catch2 unit tests that validate the functionality of the TestUnivariatePowExpStationary 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 + * @version 1.1.0 * @author Sameh Abdulah - * @date 2023-05-10 + * @author Mahmoud ElKarargy + * @date 2024-01-16 **/ #include @@ -20,28 +20,27 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; -using namespace exageostat::hardware; +using namespace exageostat::configurations; -void TEST_KERNEL_GENERATION_UnivariateMaternNonStat() { +void TEST_KERNEL_GENERATION_UnivariatePowExpStationary() { - SECTION("UnivariateMaternNonStat") + SECTION("UnivariatePowExpStationary") { // Create a new synthetic_data_configurations object with the provided command line arguments Configurations synthetic_data_configurations; - int N = 16; + int N = 9; synthetic_data_configurations.SetProblemSize(N); - synthetic_data_configurations.SetKernelName("UnivariateMaternNonStat"); + synthetic_data_configurations.SetKernelName("UnivariatePowExpStationary"); synthetic_data_configurations.SetDimension(Dimension2D); - vector initial_theta{0.04, 1.57, 0.33, -1, 0.8, 0.1, -0.5, 0.5}; + vector initial_theta{1, 0.1, 0.5}; synthetic_data_configurations.SetInitialTheta(initial_theta); - int dts = 3; + int dts = 5; synthetic_data_configurations.SetDenseTileSize(dts); synthetic_data_configurations.SetComputation(EXACT_DENSE); // initialize ExaGeoStat Hardware. @@ -49,18 +48,15 @@ void TEST_KERNEL_GENERATION_UnivariateMaternNonStat() { 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; + std::unique_ptr> data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(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 - }; + double expected_output_data[] = {-1.272336, -2.362813, 0.616384, -0.072468, 0.401498, -1.559690, 0.211848, + 0.776627, -1.524810}; for (size_t i = 0; i < N; i++) { double diff = A[i] - expected_output_data[i]; @@ -69,7 +65,7 @@ void TEST_KERNEL_GENERATION_UnivariateMaternNonStat() { } } -TEST_CASE("UnivariateMaternNonStat kernel test") { - TEST_KERNEL_GENERATION_UnivariateMaternNonStat(); +TEST_CASE("Univariate Pow-Exp Stationary kernel test") { + TEST_KERNEL_GENERATION_UnivariatePowExpStationary(); -} \ No newline at end of file +} diff --git a/tests/cpp-tests/kernels/concrete/TestUnivariateSpacetimeMaternStationary.cpp b/tests/cpp-tests/kernels/concrete/TestUnivariateSpacetimeMaternStationary.cpp index 365bcf7d..132d726f 100644 --- a/tests/cpp-tests/kernels/concrete/TestUnivariateSpacetimeMaternStationary.cpp +++ b/tests/cpp-tests/kernels/concrete/TestUnivariateSpacetimeMaternStationary.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). @@ -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.1.0 * @author Mahmoud ElKarargy * @author Sameh Abdulah * @date 2023-05-10 @@ -19,10 +19,9 @@ using namespace std; -using namespace exageostat::configurations; using namespace exageostat::api; using namespace exageostat::common; -using namespace exageostat::hardware; +using namespace exageostat::configurations; void TEST_KERNEL_GENERATION_UnivariateSpacetimeMaternStationary() { @@ -50,22 +49,17 @@ void TEST_KERNEL_GENERATION_UnivariateSpacetimeMaternStationary() { 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; + std::unique_ptr> data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(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.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..a50eb717 100644 --- a/tests/cpp-tests/linear-algebra-solvers/CMakeLists.txt +++ b/tests/cpp-tests/linear-algebra-solvers/CMakeLists.txt @@ -1,10 +1,10 @@ -# Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, # All rights reserved. # ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). # @file CMakeLists.txt -# @version 1.0.0 +# @version 1.1.0 # @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..9b31bbfb 100644 --- a/tests/cpp-tests/linear-algebra-solvers/concrete/TestChameleonImplementationDST.cpp +++ b/tests/cpp-tests/linear-algebra-solvers/concrete/TestChameleonImplementationDST.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file TestChameleonImplementationDST.cpp * @brief Unit tests for the Diagonal Super Tile computation in the ExaGeoStat software package. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @date 2023-04-09 **/ @@ -25,29 +25,26 @@ using namespace std; using namespace exageostat::linearAlgebra; using namespace exageostat::common; -using namespace exageostat::configurations; using namespace exageostat::dataunits; -using namespace exageostat::hardware; +using namespace exageostat::configurations; //Test that the function initializes the CHAM_descriptorC descriptor correctly. void TEST_CHAMELEON_DESCRIPTORS_VALUES_DST() { Configurations synthetic_data_configurations; - + int p = 1; SECTION("SINGLE") { // initialize Hardware. auto hardware = ExaGeoStatHardware(DIAGONAL_APPROX, 1, 0); auto linearAlgebraSolver = LinearAlgebraFactory::CreateLinearAlgebraSolver(DIAGONAL_APPROX); - linearAlgebraSolver->SetContext(hardware.GetChameleonContext()); - synthetic_data_configurations.SetProblemSize(64); 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 +52,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(); @@ -165,13 +162,11 @@ void TEST_CHAMELEON_DESCRIPTORS_VALUES_DST() { auto hardware = ExaGeoStatHardware(DIAGONAL_APPROX, 2, 0); auto linearAlgebraSolver = LinearAlgebraFactory::CreateLinearAlgebraSolver(DIAGONAL_APPROX); - linearAlgebraSolver->SetContext(hardware.GetChameleonContext()); - synthetic_data_configurations.SetProblemSize(32); 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 +176,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..d0d978a2 100644 --- a/tests/cpp-tests/linear-algebra-solvers/concrete/TestChameleonImplementationDense.cpp +++ b/tests/cpp-tests/linear-algebra-solvers/concrete/TestChameleonImplementationDense.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file TestChameleonImplmentationDense.cpp * @brief Unit tests for the Dense computation in the ExaGeoStat software package. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @date 2023-04-06 **/ @@ -25,15 +25,14 @@ using namespace std; using namespace exageostat::linearAlgebra; using namespace exageostat::common; -using namespace exageostat::configurations; using namespace exageostat::dataunits; -using namespace exageostat::hardware; +using namespace exageostat::configurations; //Test that the function initializes the CHAM_descriptorC descriptor correctly. void TEST_CHAMELEON_DESCRIPTORS_VALUES() { Configurations synthetic_data_configurations; - + int p = 1; SECTION("SINGLE") { @@ -41,13 +40,11 @@ void TEST_CHAMELEON_DESCRIPTORS_VALUES() { auto hardware = ExaGeoStatHardware(EXACT_DENSE, 1, 0); auto linearAlgebraSolver = LinearAlgebraFactory::CreateLinearAlgebraSolver(EXACT_DENSE); - linearAlgebraSolver->SetContext(hardware.GetChameleonContext()); - synthetic_data_configurations.SetProblemSize(4); 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 +52,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(); @@ -165,13 +162,11 @@ void TEST_CHAMELEON_DESCRIPTORS_VALUES() { auto hardware = ExaGeoStatHardware(EXACT_DENSE, 4, 0); auto linearAlgebraSolver = LinearAlgebraFactory::CreateLinearAlgebraSolver(EXACT_DENSE); - linearAlgebraSolver->SetContext(hardware.GetChameleonContext()); - synthetic_data_configurations.SetProblemSize(64); 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 +182,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..db014810 100644 --- a/tests/cpp-tests/linear-algebra-solvers/concrete/TestHiCMAImplementationTLR.cpp +++ b/tests/cpp-tests/linear-algebra-solvers/concrete/TestHiCMAImplementationTLR.cpp @@ -1,12 +1,12 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** * @file TestHiCMAImplementationTLR.cpp * @brief Unit tests for the Tile Low Rank computation in the ExaGeoStat software package. - * @version 1.0.0 + * @version 1.1.0 * @author Mahmoud ElKarargy * @date 2023-04-09 **/ @@ -18,99 +18,77 @@ using namespace std; using namespace exageostat::common; -using namespace exageostat::configurations; using namespace exageostat::dataunits; -using namespace exageostat::hardware; +using namespace exageostat::configurations; //Test that the function initializes the HICMA_descriptorC descriptor correctly. void TEST_HICMA_DESCRIPTORS_VALUES_TLR() { - Configurations synthetic_data_configurations; - synthetic_data_configurations.SetComputation(exageostat::common::TILE_LOW_RANK); - synthetic_data_configurations.SetMaxMleIterations(1); - synthetic_data_configurations.SetTolerance(pow(10, -4)); - - vector lb{0.1, 0.1, 0.1}; - synthetic_data_configurations.SetLowerBounds(lb); - synthetic_data_configurations.SetStartingTheta(lb); - vector ub{5, 5, 5}; - synthetic_data_configurations.SetUpperBounds(ub); - vector initial_theta{1, 0.1, 0.5}; - synthetic_data_configurations.SetInitialTheta(initial_theta); - vector estimated_theta{-1, -1, -1}; - synthetic_data_configurations.SetEstimatedTheta(estimated_theta); - synthetic_data_configurations.SetKernelName("UnivariateMaternStationary"); - synthetic_data_configurations.SetMaxRank(500); - synthetic_data_configurations.SetProblemSize(16); - synthetic_data_configurations.SetLowTileSize(8); - synthetic_data_configurations.SetDenseTileSize(8); - - SECTION("With Approximation mode ON") - { + SECTION("descriptors values") { + + Configurations synthetic_data_configurations; + synthetic_data_configurations.SetComputation(exageostat::common::TILE_LOW_RANK); + synthetic_data_configurations.SetMaxMleIterations(1); + synthetic_data_configurations.SetTolerance(4); + + vector lb{0.1, 0.1, 0.1}; + synthetic_data_configurations.SetLowerBounds(lb); + synthetic_data_configurations.SetStartingTheta(lb); + vector ub{5, 5, 5}; + synthetic_data_configurations.SetUpperBounds(ub); + vector initial_theta{1, 0.1, 0.5}; + synthetic_data_configurations.SetInitialTheta(initial_theta); + vector estimated_theta{-1, -1, -1}; + synthetic_data_configurations.SetEstimatedTheta(estimated_theta); + synthetic_data_configurations.SetKernelName("UnivariateMaternStationary"); + synthetic_data_configurations.SetMaxRank(500); + synthetic_data_configurations.SetProblemSize(16); + synthetic_data_configurations.SetLowTileSize(8); + synthetic_data_configurations.SetDenseTileSize(8); // initialize Hardware. auto hardware = ExaGeoStatHardware(TILE_LOW_RANK, 1, 0); synthetic_data_configurations.SetApproximationMode(1); - exageostat::dataunits::ExaGeoStatData data; - exageostat::api::ExaGeoStat::ExaGeoStatLoadData(hardware, synthetic_data_configurations, - data); - exageostat::api::ExaGeoStat::ExaGeoStatDataModeling(hardware, synthetic_data_configurations, data); + std::unique_ptr> data; + exageostat::api::ExaGeoStat::ExaGeoStatLoadData(synthetic_data_configurations, data); + exageostat::api::ExaGeoStat::ExaGeoStatDataModeling(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 lts = synthetic_data_configurations.GetLowTileSize(); - int pGrid = synthetic_data_configurations.GetPGrid(); - int qGrid = synthetic_data_configurations.GetQGrid(); - - if (approximationMode == 1) { - // Descriptor C. - REQUIRE(HICMA_descriptorC->m == N); - REQUIRE(HICMA_descriptorC->n == N); - REQUIRE(HICMA_descriptorC->mb == lts); - REQUIRE(HICMA_descriptorC->nb == lts); - REQUIRE(HICMA_descriptorC->bsiz == lts * lts); - REQUIRE(HICMA_descriptorC->i == 0); - REQUIRE(HICMA_descriptorC->j == 0); - REQUIRE(HICMA_descriptorC->mt == ceil((N * 1.0) / (lts * 1.0))); - REQUIRE(HICMA_descriptorC->nt == ceil((N * 1.0) / (lts * 1.0))); - REQUIRE(HICMA_descriptorC->lm == N); - REQUIRE(HICMA_descriptorC->ln == N); - REQUIRE(HICMA_descriptorC->p == pGrid); - REQUIRE(HICMA_descriptorC->q == qGrid); - } - }SECTION("With Approximation mode OFF") { - synthetic_data_configurations.SetApproximationMode(0); - - // initialize Hardware. - auto hardware = ExaGeoStatHardware(TILE_LOW_RANK, 1, 0); - - exageostat::dataunits::ExaGeoStatData 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(); - // Re-Run again but with approx mode OFF + // Descriptor C. + REQUIRE(HICMA_descriptorC->m == N); + REQUIRE(HICMA_descriptorC->n == N); + REQUIRE(HICMA_descriptorC->mb == lts); + REQUIRE(HICMA_descriptorC->nb == lts); + REQUIRE(HICMA_descriptorC->bsiz == lts * lts); + REQUIRE(HICMA_descriptorC->i == 0); + REQUIRE(HICMA_descriptorC->j == 0); + REQUIRE(HICMA_descriptorC->mt == ceil((N * 1.0) / (lts * 1.0))); + REQUIRE(HICMA_descriptorC->nt == ceil((N * 1.0) / (lts * 1.0))); + REQUIRE(HICMA_descriptorC->lm == N); + REQUIRE(HICMA_descriptorC->ln == N); + REQUIRE(HICMA_descriptorC->p == pGrid); + REQUIRE(HICMA_descriptorC->q == qGrid); 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, - DESCRIPTOR_Z_COPY).hicma_desc; - 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, - DESCRIPTOR_CUV).hicma_desc; - auto *HICMA_descriptorCrk = data.GetDescriptorData()->GetDescriptor(HICMA_DESCRIPTOR, - DESCRIPTOR_CRK).hicma_desc; + 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, + DESCRIPTOR_DETERMINANT).hicma_desc; + 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, + DESCRIPTOR_CRK).hicma_desc; // Descriptor CD. REQUIRE(HICMA_descriptorCD->m == N); @@ -211,10 +189,9 @@ void TEST_HICMA_DESCRIPTORS_VALUES_TLR() { REQUIRE(HICMA_descriptorDeterminant->ln == 1); REQUIRE(HICMA_descriptorDeterminant->p == pGrid); REQUIRE(HICMA_descriptorDeterminant->q == qGrid); - } } TEST_CASE("HiCMA Implementation TLR") { TEST_HICMA_DESCRIPTORS_VALUES_TLR(); -} \ No newline at end of file +} diff --git a/tests/cpp-tests/main.cpp b/tests/cpp-tests/main.cpp new file mode 100644 index 00000000..615c8555 --- /dev/null +++ b/tests/cpp-tests/main.cpp @@ -0,0 +1,23 @@ +#include + +#ifdef USE_MPI +#include +#endif + +int main(int argc, char* argv[]) { + +#ifdef USE_MPI + int provided = 0; + MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); +#endif + + int result = Catch::Session().run( argc, argv ); + +#ifdef USE_MPI + MPI_Finalize(); +#endif + + return result; +} + + diff --git a/tests/cpp-tests/prediction/CMakeLists.txt b/tests/cpp-tests/prediction/CMakeLists.txt new file mode 100644 index 00000000..f2d68617 --- /dev/null +++ b/tests/cpp-tests/prediction/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 1.1.0 +# @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..49605ed7 --- /dev/null +++ b/tests/cpp-tests/prediction/TestPrediction.cpp @@ -0,0 +1,202 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file 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.1.0 + * @author Mahmoud ElKarargy + * @date 2024-1-18 +**/ + +#include + +#include + +using namespace std; + +using namespace exageostat::common; +using namespace exageostat::prediction; +using namespace exageostat::results; +using namespace exageostat::configurations; + +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(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); + + // 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(); + Prediction::PredictMissingData(data, configurations, z_matrix, *pKernel); + + REQUIRE(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); + 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(); + Prediction::PredictMissingData(data, configurations, z_matrix, *pKernel); + for (int i = 0; i < 3; i++) { + REQUIRE(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); + + // 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(); + Prediction::PredictMissingData(data, configurations, z_matrix, *pKernel); + REQUIRE(Results::GetInstance()->GetMLOE() == Catch::Approx(0.004467).margin(0.001)); + REQUIRE(Results::GetInstance()->GetMMOM() == Catch::Approx(-0.0812376).margin(0.001)); + delete pKernel; + }SECTION("Test Prediction - MLOE_MMOM with equal estimated theta") { + configurations.SetIsMSPE(false); + configurations.SetIsIDW(false); + configurations.SetIsMLOEMMOM(true); + configurations.SetIsFisher(false); + + vector new_estimated_theta{1, 0.1, 0.5}; + configurations.SetEstimatedTheta(new_estimated_theta); + + // 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(); + Prediction::PredictMissingData(data, configurations, z_matrix, *pKernel); + REQUIRE(Results::GetInstance()->GetMLOE() == Catch::Approx(0).margin(0.001)); + REQUIRE(Results::GetInstance()->GetMMOM() == Catch::Approx(0).margin(0.001)); + 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); + // 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(); + Prediction::PredictMissingData(data, configurations, z_matrix, *pKernel); + + vector required_fisher = {0.1045891821, 0.0005116817, 0.0409307011, 0.0005116817, 0.1873553354, + -1.3659618079, 0.0409307011, -1.3659618079, 10.5564826575}; + for (int i = 0; i < Results::GetInstance()->GetFisherMatrix().size(); i++) { + double diff = required_fisher[i] - Results::GetInstance()->GetFisherMatrix()[i]; + REQUIRE(diff == Catch::Approx(0.0).margin(1e-6)); + } + 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(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 98% rename from tests/cpp-tests/helpers/TestPredictionHelpers.cpp rename to tests/cpp-tests/prediction/TestPredictionHelpers.cpp index b69b45fe..b16c9f6d 100644 --- a/tests/cpp-tests/helpers/TestPredictionHelpers.cpp +++ b/tests/cpp-tests/prediction/TestPredictionHelpers.cpp @@ -1,13 +1,13 @@ -// Copyright (c) 2017-2023 King Abdullah University of Science and Technology, +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, // All rights reserved. // ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). /** - * @file 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 + * @version 1.1.0 * @author Mahmoud ElKarargy * @date 2023-12-08 **/ @@ -243,7 +243,7 @@ void TEST_SORT_HELPER_FUNCTION() { } } -TEST_CASE("Prediction tests") { +TEST_CASE("Test Prediction Helpers") { TEST_SHUFFLE_HELPER_FUNCTIONS(); TEST_SORT_HELPER_FUNCTION(); diff --git a/tests/cpp-tests/results/CMakeLists.txt b/tests/cpp-tests/results/CMakeLists.txt new file mode 100644 index 00000000..03659365 --- /dev/null +++ b/tests/cpp-tests/results/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 1.1.0 +# @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..a5693222 --- /dev/null +++ b/tests/cpp-tests/results/TestResults.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file 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.1.0 + * @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") { + results_instacne->SetMLEIterations(0); + REQUIRE_THROWS(results_instacne->GetAverageModelingExecutionTime()); + + results_instacne->SetMLEIterations(2); + 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); + 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..2764f22b --- /dev/null +++ b/tests/heavy-tests/CMakeLists.txt @@ -0,0 +1,14 @@ + +# Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +# All rights reserved. +# ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +# @file CMakeLists.txt +# @version 1.1.0 +# @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..1cb91890 --- /dev/null +++ b/tests/heavy-tests/ExamplesTests.cpp @@ -0,0 +1,138 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file TestExaGeoStatApi.cpp + * @brief Test suite for the ExaGeoStat APIs data generation functionality. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2023-12-26 +**/ + +#include +#include + +#include + +using namespace std; +using namespace std::filesystem; + +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_Setup "; +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..61316f7a --- /dev/null +++ b/tests/heavy-tests/HeavyTests.cpp @@ -0,0 +1,254 @@ + +// Copyright (c) 2017-2024 King Abdullah University of Science and Technology, +// All rights reserved. +// ExaGeoStat is a software package, provided by King Abdullah University of Science and Technology (KAUST). + +/** + * @file TestExaGeoStatApi.cpp + * @brief Test suite for the ExaGeoStat APIs data generation functionality. + * @version 1.1.0 + * @author Mahmoud ElKarargy + * @date 2023-12-20 +**/ + +#include +#include + +#ifdef USE_CUDA +#include +#endif + +#include + +#include + +using namespace std; + +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 = 6; + int MAX_SIZE = 25; + int MAX_LTS = 18; + int lts = INT16_MAX; + uniform_int_distribution problem_size_distribution(LOWER_SIZE, MAX_SIZE); + int max_threads_size = static_cast(std::thread::hardware_concurrency()); + uniform_int_distribution cpu_size_distribution(1, max_threads_size - 5); + 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, MAX_LTS); + 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); + + // Since both Bivariate and Trivariate requires specific values. + 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(0, nDevices - 1); + 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", + "UnivariateMaternStationary", + "BivariateMaternParsimonious", + "BivariateSpacetimeMaternStationary", + "TrivariateMaternParsimonious", + "UnivariateExpNonGaussian", + "UnivariateMaternNonGaussian", + "UnivariateMaternNuggetsStationary", + "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..aca3623a --- /dev/null +++ b/tests/heavy-tests/README.md @@ -0,0 +1,3 @@ +# Heavy Tests Subdirectory + +This directory includes all the heavy tests for the project. It executes all project testing examples using a different set of configurations to guarantee the seamless functionality of every test. \ No newline at end of file

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�=QC5EX6}XjsHqgFqZ?^meJ3u6 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%0AYODn~X~V0Jij7kT ztL{Cv?S^CeY%GW*NXVQsy~vNh@@6ZGG!L4slA|^FPORKuCS@`wbs_y ztaK!)k#J=H@Lw-BGI)#w}-ZulFpL3sT%I1rG0RGx;`FRzNaV~465PS;JEyQou35X)W~6LLvj z6}y;;y1e){ja@~TjW&EGoBOOMk?;g^qZ+vDTU=jPYHnnBgvJ0Ks^z_bu^g^?TD}@S$O498^2!2szA*zHEs!>`7Zl=o)hD!+4NC(aRIBfq=@3Dw?NAhzIh8rP~w~U9w ziSX}^|KBDV#ZkT~WHK!YO}S@yK_3xh3-&f|eRc~iLoY&ma92y<-0+r}klfI*dm;N| zEKRUE4A4S}C~fdLpa=JiD@a~cJMn2l!f6XKdXT=-Gmn{9x*zQtB>Z)olu+*Jz> z8c0ZS)=Z0jq$OzXFfzyNfzqhO3cCy5K>Ph*0EQ&YSTuyFf_u%2T36gGqlx=cMBZx8 zh4YA6rhVCq$#J?jr1hgViHm9c*j5(&u3Cm3$|K>II&kkx*X!d2Ybiyguo8aA4TH>{ z8xy06x}CPaz#mdb%au*xzCA4ED@W?vTLoIJm`|W$?@`j+{adVFHF=IS#@cG`viyOn ztv8)Ni0Fxsw+!uT)d>1{BlQx;pt{3f6d-a;Fz;F1T5?z5-q763Qi?Qp2G0-oFzMQU zF-IBTW*I%WudnhphE>fyYGI1aeRep;vz&=qK=488dQ_t4!8r-zwVtM^<4m}iU9q`O zaE*P!q6`d-NpGzH03ZNKL_t)7f@YSf!N_q$b2qQJc(LHH(x52bV_8mdqNKT7#RP*n zqk{WRPTyiHxVLET%q89y(9F(86RiNZ#+%FV_ZgyB3A4FS`=Ur6wIZMvnPv1HR>9rS z+_{9#@X!I=+4j`s(%jMQUd(#!OrBx?--uK(x*;95S&Zweue5iJVSJAx#*Z)om2 za4F%MyV){sBg@1v>@+xy2%EdoA_3ISL7c9}rL>b-a!~6nEO)?BJ;A38kvB}{W(q^n z2;K+66fJ-?$nv`swAxsr%&qF`R6-Q zD@iGtXgB`-_LnbJ9>`k;L8j$->C7<*%TOva>T=9M_!ki-g&5F~3dZn;FC#66t&b20 zC8=(o8l$U5IL<7Swc+>O*MReum|k`N%OAd$0qzZYzAWinS14HWZjPhJvWzJNua?mb zxWii}yMvIkS)kr>%^eVR=qiAU{czMX63tj(mT9)Rr)v4=h$nwQn)^=8?>QJ}6Vjk( zWO#t4FnK6$xNPBpfpESCr^RT^k{KQjyD(ztXtIggYGGt}1@;T`fV2}uQ`|XzTvL=4 zTE~Jr<#C&P`oQ8J87X8f>Kue9o^}b38g6qRkXD9={i_E6cZbCi9jJ}yTWke)O>++l za36EI^5cnt#EykVEFCQtb`1 zL(1Cv%PJZrUY<{yQ&bYR9W(hMhO9SQY_P^#cZt@5@dn%eal%$OTds_hk zFSTk@KxF*r*7!+DrHcA%C7DjeRGSQ4nU?5rW*Lhl*+S17kp4e4q7-|sBk`9%yliOh zlrCph`*iu2KRUrj%r<<+M>7qHb_4FLxFkY8GX$FDd=R&5GQac%H4qqIwyds%mQv8f zmy{O$JBWG8neQl_)%zJsh=xHO{fF!(4WFnOTZ~&Y1o)FQq}_^qLZQ zt3y4#pL>U57oBBhvjfXgjs6aluyL?K{}AY?T!@pBpk`<#v;?i#0g}X@K9Ax&Rc-5l z9F^fUcd#=4{`#xGv}QE`rZwk{uQ3yLBy5nQ!hijJGo*j0LHy^sM!))lvsrUz zbxXf4|7u6AO-81!z`dozc#G;fbS~P+#rr^|YobL9A?T??qqUQ&;sc|TifH-j@{&}e zT{X~aCfIVR5o?KDv9)DdxW8nVoxuHaYVJaSc6T8&xSA!zO{#xdL`^u;Gl+>`8C|x8 zM`j)5YS2C$S+1ph(KE=Y=8p#cu}tm1{=Zw$UAt^F`;yj5&}{BJJ)m0P8>Oyp%wwrG z2G-XB_jBnwefQdJ$f#;_w-wH_Tz3m)z8(i~qj|lGMy;a~=mhTDDSBhPtf6^&>GE;; z)h{3YxJ+4Ul56Gvp6-& zzQ$LlNIAREDf@!+@{;C*bH**trB;RW{~6Q$nUd=S?w46}zx=lgMtAzgv1dr$JHk6DHXS+%Kuk z{Yu;ovlF%s0`-WWt#t|Ra{rp#4DNDisv63L_T)?`>h>k}-116XjwK?6Ze-x6ae~0T z8Pm0EjRtY*B(sc`f{1U`M&FA61VY3%sDBB$EZ}ZVPe!_wZt#-Lf5g}D$?16n`xvHP zjc`^H=mhSD=Kcm!b_#u%IsEbrmJRS!<;rlq$WqaIyyEuz@S$~mB;pwHxO@A`tXPWF zqwc;$qEy+lx}zhJo|$?SWf=AjmFdIP6}jT66yOnwl?p;BZR?>(oO9^a@wrwi)E64p z$A7{^kpF>Jh~6`{BDj=aEBGA-C+=i(%`zkshz? z_lBmhQe>zsr=}b^?_L=mi7WV?HH@>Zjs-Fw|z z1kKK`ehE`HGl%o$Bgx1)o1nRjgbTbt_$ctYEof zn$cNkJ|+?r{(`j!5Sk}ck>GAN!c&>67(7iDcLUt7;ypBYek}=f0QbxJg(~l*oG2>2 zO^`#6+@G1Ks{qV17V6k70ROcRjmrxyV6WvJ8^Nw$))_C)lIyC8v962{@KLJUW`@qA-iK+X7-SnvFQ)(^@<$U z(;or|`a=D(qdHegD}*DlV4&>{!R|G`g^OX&j9h0J zX6mf!sfXm5=uH1NSjL^nQ_*OpukMNN$rFXt)V!x&_xTD_y&aMx9Unm?%*A?H|78 zuOmk^cUBo)r=jyohv3p`MeV8Rhym_b`i2_JcQ1iX;C^|%W%fK+x_hdeVQjB}zRIB- z>=cN~{y=?v#$R{LnI%IiZ}CV z1J-r1PkAObVfy-)zZIq?*xZ#gg#eRNmX)}AaW&7Tj76;d&|u#H_l7Kt*iTvloxuI_ zdds8;^JF<^!jct)NI>_5&yip7<>b0sp3BKaY4&3g1wJ_0ve86S!a6FI45!2o^y1dzKei zWrg=vcGRPCeG1wtwCuh-+gbtO*O~Ko>8Xsz15Zh&x_L0DAw8)IjI>Y2mJEh ziYMmFkoqqO6TU-p?~4`+8EYN3XV}GIAt@=jQJA|01D%EaTQOPLxzMR|3A4dbu+Ad& z3Ac|~_b@3S*Jn~u7-}eICfK-YTG3sxyMG`kFa}SVuLZWZtSuwxMEu#p6-IYpd%?I)UBe6=tPh zd*++jK3U|T9u`lB9v&_E@-gO~2@1j)XvY~}sZI@nCWn3IDPe@5X6yLeh{uFUqe-Ot zi$`DSw%gNZoJCwNSJ5?eZf=+_8qDLIFxVA2bR{40hkU_EXb8aezlhkenmbkuPGtQZ z-%ixpm+|cNaWfqK2TGL9HAT*dx9W)ptjxA z()fDQ0&SB~brvU`SZn?E|U zvkgr_+@jn`56#Q3j;;=QQk|~z z<$nG=%WIw0D#jK+hq+z#mics1ZQ$isjTejKGCszN0L61Ma-m zigcvoMjHE`uU7+h}w_rU>` zxP4=#sK$>!WAl;YGmcALviQVml96mnlgE|rGR;|##=0!}vnkdI+%K=@&T?DKx3^WX zGHf}Dd*ul1E#eHP8J0H5&MISbd!~h;%qkJNC$NXlJY#!BYcFOW_vTP;Vca1@`FB() z#}VkCm*vXd7L4*+vx~C4xVL4uvcA0{>vf>Qd__)ssgYQJ5ytMty*V=62P*OwFL%B}Z0{d@{(N35t=HROvOhAR%1K)5mO*-PxpJX2m~HwpRqenj z!2JlKojtgB(A@0`$E}*X+L5l$(VDVnQcH~?sXS^?9A}4XBTI+P`N}@9lz8Ik;t?A^ zH4|ua6|aq}IT=Z5UQKv|bD1`^HG*CO9l-q(f1xV7CwM1h6Mf-BmIqocI+FL{ifb(* zRdkdL7ordf@`x$tE+y8u;eyYLA{7(>?o^vrq81fI>4p}>Q^lpA*~k(t9dm@s%vXQ- z?aO0wexxL&YuLQ=Yn|SX%j?I3JH8iKwiJ%Q+>gY4x6R5$KaELRXLa@3gL~Bz)vLIw z<~}BD0V%g?mKhqdVmpoz|3Cq|KUqgG-+?ePrnC_+7Y0U(vzjKGrh-Exz`2o1@9=v70|Qai4~!)9sD+rhzl5Jp+Xa$U%ewDS${*2ff7Dh#kpeZtFy0z%#3qt!kSsncW3|yT&N$6BUTI zmkv}Nox$$4(SZREiC5&S9JUZ1lcH4F2n`8z0QbxMg=!!C(J6T0eA{)Mso04ERd`X=4=NCfVO@q?6NGaN~2z2*C-WB+9Xkm7AawD z$}PeGz+GPz{3KlD(93Mem;>Z&xom9&)8b2mhl9C;Lm%HSyV36Y0nF(ZY_HwmSr7)e z`;tq%k84tbEm;se%)qESU0u7C~}5~8nz;5)dSaHe%(UV z!)QN0=)y)#JYVCmh47l>;a%bU7zdI-2XMc{U#K?j-4TRtWOax^H$Sf8acLc>beDxE z4mf(5ly~s`2x|LR|DBd3)&g81wRm$xmPgV#-LUPNAA3DdA|{TA__^tK&8337UkWj^vzW{fs=3@K zF(kIurgzU&O~R2vt~LNQIB;MSmjr2~wNfCnjJ|3vYhL3f2(K%{N;QBkvo2Y1TqoUi z8`L+(i4U#as6wj2Gm+(*JHULKqT{syBh5YH;%k9&MO>I=%x(e78J8E}J{rXSu%lRt zKHHC4E7|}gVtOuDTvWnGTes#U8>+>Yu~#dCdA3=_)-l=ucc%yJBP=g7mgHVMWgtG~ z>p5&9JZWsLO%l_GxAYe+@k?xTZ{hT^U%ve9AO7%{|9)w>?D_huU;gqhE#P;IpL>Jh zK6lo4(3_WMH7!Z z8;Xfy9cYG-SHa!w7uP_kerbhd9;^ACY)~!6a|ztN6dONKt^w|LB}!%)ebro+v1|^R zz&q#c03QPik`Lg{c>sR|?z(mX?$oZ1XF(a7I|zqyF-Kc?uS0Y94unVmrJ9>D#pWKa z#i+Qu76Q1_`0sZ?b04C#2`NPwrBj_a13EVHOw~UVeD-tCGH;gm! zOTe!4)UZ+u@@Ov0Ph4}ilsS|GW(sKvd0=+Vf_#f=p|AiZ5mqFJH=VYptxm_J z+db*XL2d0<3==NA9#{ySsTdQ*I1y;+5>LiKr@3=*ALbcU75q38t{6OZlQ^*L33q6L zE9dJRPv>G>bJw-2XzqHRIWYovwshcS(8SSiZgY3qQ|?rHmcUy9_uK*XBke|!ltix^ zF(1HvnL(xGGUOSY&6(le3E5IGK$|P+GmMZ9`0Zc5Rz3)Q6H>2T*YWb} zzx)B=FE444-{#O!b4O7t^OZa{OP1`nmp9m=C45@kDYON5r{9tt)`{gf%^g;G0#vpp zph=Q|+2vZuxvd(M8QEVD!Zk;M%2dWSYKPfmmTVHhCQja!aI&Nr3=$F(#d29*P4j!# zY3{--)2K>C*MQ4C8)(YDEFD-5lX+6k*OxdAz%n#k+FdyvxZBjO4guW9L<`v48>mahaXKN4^MqqMI9!`lzYZwWyndo3WoaiSljyZ zK%jP5a%`8&?s9B3OLmjVB!PR4yU>_P{oYWEF;PruM6bEqdFzVJU00QgIAF?lL>k)E!EuP~_mg)IM0 zgrmJ{>n+n#lq4j)NH5iqcv3&SZQ;22@)Y16bKK^Rl|dD!?i~Vmf=mR`+($*Rof;*;`BuTH?7d}EoX-~>5Zv9JpbIR)2`uiCv%mjSPu2Md=f!!sTT@eW_ssOPTzz%aQ4we^ zGULmtcc7LrPijJRx|^=nPebpcsZI)DeV3Q7bp>#Q8~Z2^U~RnSWyk}SdITn95p+qK z;R2Hr1<$Cwjl!V%xmE^23WYODj=yrM;$NZHE%7&)4qI)gqiR^8Kw5s;co?h$8B03n zRn+=tU|T(AX6w0{H&GU&Eg--|kn$-qsWmajVuci=>p$iV;Gr4~8Ak3S0**#q@L0OS zUgD~ln)gIx2D?Z)Ql+kk$LIz7XAKW}?3CWc)N5PDX{U57RZj_uXE8+qj78D}kJ3(l z6q7^UM-Yc2_y{^1_Px*@+0{EMlxqfB4j<*qw0KEc#3A=HJw}@p%SBTaZcW@f{qBDq z!jCaRW{6PmNV{RcAsmV_A;g9WaIO-n_D#$+)|{flG%$zcvwBrL;+gB__AqdIPz&@Ul?xS&}vHvLpSKsbatrapb8Ln#u?(!rY7UA)YL zkq5W4WG+W5MxXC5Ot_(+8qOM+lxfP8ZETpVH{Oh;9BXwJxLV_=|7`-mK>TG%di&@0 zDu4ENI_~k_Ly+baVfK=*rr_jJkXt~J%a`r&?w@bs@+kA#j9C+s1B)Y4W836wuE8$< zkf25E{_^lL56L?P)RRovHlzR=O2thbd&UNh0yYj%(%)$bYZ?+6wLa^()|h1}Fk&J^ z0dWtj5_@Fu9C*IhlvP=!)N$qb+&${7p)}C)L2i=8(iEQ|YN4|5_l5=FMiO1-$s*Nk zU|W_!?Oc*2GBBHOj6vsCeC18ImE@-cyvsUpG>->8{}n}b!TmH9fuVM5c(Onb)_V_2 zS{RdHf%mZ~(bZs_sl{shx86K8&tp|a&iS^N0UudXVjV!O(6Cyj@JGX6LCpvTM=*6Y zNcvO4LdyR&gq|+B7{xw-oYhgJz$Pyf82X$NI@ogZ$?FzG%o(W@7Ax;c98oQUv)p=hvr0a#kmhyyv4WK()g03juis340%?fZ;iL<^l2 zXFxRw6&s*LU*@``)Gx{bM|PI)U==)ch8p{I+)=M(mkM;yh-9R?b8*%UezqD4krbp-k0 zN5kQ&iB*D5bJ{PTQ^K@042wK?9KnnVRrJNHR5%JxM@x-XvZG3N>*eLY2HRzWUUhNH z+CHr^95XfW`8aDF@}`$gNsR_wxMnP_QSp8q?vBL1`(G&42U9B$vnzi7z2SfY)AaYF zw1+5Ytc_Gg(CEpibf}DB%o^vuEA}E%W2eforqRc1HfG^t*@a@YDbzk@LQ}XP$K70b zzfxx%V=!V-d^?@=US>U>1$*iOOG%I(mp9sXdYn-7&%GUl@c^|ZenqLiCKG4((MN8r zHKSN+guUL@g+)vy*rF}Z$M?xCuRo(65(X(wX-_aD86#NM?b7bJT)at%aZ8jK3*1v@ zJ-kNa#+f^Eo{Ti!B#o0q_>N?;coJrajqKs;h-9|IUh$@Vl|>zf0M6K=&T&*^u+OWz zK%Lsjg203fz6RxG8*Kr*FM0hQrwJ7L_lAv?@ogtE%&m(65ql@gf-96| z!&W!XBM{h_cxelNY4OTOK(Q!PtP(_e?eZ_@-RKsxx&>E^fi%1JLIw1Z{vw%Kdq~LP zPb7BG)jwb49V7Dnt9rnQ$ysLf7cNb=4kK;Hz;(y1c*)z-p5crvSmez&e1K~U3wOPo zNS{8fMP^oKkRnA3nzl1? zADWIvOjJx_cvy;X7O6o4wCzpOza3nc>66OL`WKp*Z7vGAyApPz*v;;RQ?fftqanY= z{1=B5qn~}3!{K~@jd&(A=%~<(Lt~>)KF^PXP|*f52yqO{MAO&!1Im$hD|pkhmNmGE zF?NTki81n?M|nXFZM2S5ht=FL-bL_e$iJKWO4#OqfQ}|W68{>FW8(XohU*CsM4$#_Wxt|+i`4}{Af1=cHrPr~Gv+}s<8F@Tnc(4}Fk{1J zfnwqu*!6MU#kdGTQ(uz?A~X4$uZmG#+SM2nM5QUx8>epTsdW;D)FU~K$<0Mbso#m> znleksr05MRxH)UX5wbf4@Xz+@)l1WdH^N^hok-{*-;DI%EuR}$XAa^PgSpJ^R}d^T z)1FD3%B5KYDySpo$ygas74D=tp{^gc(h&X)Vnw_C#-OW*e4dCpE3(qwqBF^kl>zYf zHnoqP!Yy(EdQRc%orwOq>B0vEiNKy1X1lx3SULy=`+f8>u5V;-(yAnd!1&<}^&Y^oNcRh79e%fB9E_FLXCV-)@p z5E`5ti^ZQJw;G>mIH{BI-5(B2-T7%=@neZ%QKdsMh)bH`d{)93f71b&s8X#{8QKwX%6gUl56geA5tr{;yn9 zZ*c#))U_6)#p0O3D;z22;37pdO`^V7c*dUviV6NKt{qBf11rY=3K?VYf(P^)8Lv`* z_b~27nH$UJ0HJdMwg^DYS|QMGc;L>Zs`8cLUiYNs6ua)>QjsBZ#NR;2>GTk0lQ9$_ zbzCx03A(dPRx4i+zs3hK4c?0p&+mRM`4#dCrk{F0pjwnB6EE9U9Ne=}{X@(+fSyEO z50plGv?k#zzrp_t{#!i6KcF`CS8b@B%eqY`1y+6jChQ3*2mfyo*#P-4%o?!%p1J5^ z3r4UL?|%Ot<}To;U19%-^gn~aVs4p7Q+G^r+kp<#wlbz0OUK@*`B?1KVY==A_o+Yz z`fCi*ukfie~J1cgx>tKX7Y{8bSbd z8Df&1WEE@7DB!Hnzw+wpO5S8dOGdwvRagq|x;fphg`l}lXfjMHAFe$W_c|*QWLK7!UHRGgY1ah!?r%J#l_!?=b^tgkM;yYCqf-EkrI*!RG8KS+XVF;KJdC1 zw*oE}mPM$)TOPMsomU%6NfXkCt_@#sbkhEAH&UPaKI6RRu5&tI$dNzAt#w~W#idn@ z3}P=uQ_jbq=EfHUM`c%jYT=JKvO$WUV8j2u z%+tO?Naoz~MZrRKxk;li7dmnySKL-Ki{`6F;M|5^%FV->2DY*7)K*(K%kb1jHcmr6 z`=s2b--S6If}M~$PqwnnmkT*2Sm5(??s}cnZdR|(Kd#bw_5I&RsT{lweQ;IqBYJuQ z3EEhILc%)5BXPFY5awXsL-e^}*q$51fyEUO<27KQ=cDS12<_Ftg_c2yo)nK975cNDqOd+&`iE2X0t$*D z*wHZ>8HC4-9)LEQ|QcdfLs=?9Lv4lE^m zx2T@X$z{KjO~I>vSkjCm6y|maX5o!*X+Z8Wg%q5f9DYLV#cydmb5*Kfz^CtS=fP(A zsxCiIn3qF0CFGarELhXVmLtvF7h&y)!(QfIGl8w3F#H4IjvzOX4IgW>*PDxXRaKc6 zX>SNA4o)bv+roY+WqDo(rn0q@wdNrcH~BdpPcHv^LS;5R^E|cE0ql~hSfhDi;5c~7QGN`33!gX!ikOq(D* zp3MayGB6q=mUay){|_KJgWe8()OPsJ>SzYle&`<8+L2Mx=kPh#i5{=Z@fKRcRhtCYE!yMi`cZ)IUAYRJuh~Pb zST2qu|EJjq#bjTEz+ZFJFo3#C1&GINH{4evbwaEr$|r4*$t`w~c=$4TMVMqtWFP`Nj1b3m(P#%UZkZM8k(!#TG%YLbOxKfzWMw)W znDLsO*VpTQrSr9%op3d*Ipo4SULPERc5K_%K1ITWhG>m*qtHSD;paIW2aY}Kr4SqH z+-E{_x7J;vr-_&|6rWoeG3vRNK=4;k&nQQu+d|oz6A*llK~;8>if~eAc|tP{qRxq zpi>PeRq69Rou*~fb!?9n$%PPpes_}1V$1@t9<^n^)l65U1S)^_bTec_R#alzj5N=K zPDfXfEra5Ro=!coN+@3_O{oIb>71-kDw?Uk)&fi^u^o&gOg7S;b9y=hGfBf>-%?3s zc1%;}uzEG2s^IuFo-Gg0BlRXZ3ds3-$&T2Z9P~<+XY+aK6iK}Sy8})r%%4g|H6EKI z9BvB!C8x#kYFbMd{;7=3W_s1GUrl6d^;6O&ksfIhsu@g8)q)lCKV3-ePxB(`vX?U6 z%qQ5ZkgXwm<<_5kLPPpX3-LXlEpa^tkp_2(4Hy2f+jAO|5P40|<~jUOao3sQ(*JF^ z>PR6rf|QPx|2j&LA-L@MIb4ozV33@%)hGm@wR)=rU)otqeLOH$K^CaT1*?%zIQx65 z2$t0V_5hO=wS0LxdKHe*wMpOWwx3GrUzTw6JyZLU>9H0jD$}I|Ps$-ihpAn+2DwPD zbO!Qo+gTNQa#6$`MX2LWHkY_&YE5oK>2z1I{OOKS@R3{S`g;ODDjir93!{ zo+^8L-|lE)VZ114z5CR)LLy4XGI$9Oe_mST~e(E6Bju z+Yu4UBeR+_V;(r)L?}W8^nBI*hNcnf;ewGL%HS&9Cj6Wg}KjQSp)Cth|G%#uO=~Wr~_EFZ@}f@fIpH+J(>XXoy1{DwENI_A}>M zVbtqpD6Q~EsXtfJ)iJoq!(i=BGDo*<>}iu7)glyY|r)93s} zjVcHVKgZgUylYTUPOK4D=x zpVYO6xyvv5=bmXHxfYi+@*m$!ehcSx5%;~2f z4nEt$7sc-9%;JF2`Oj~L5L%Y;t}oTC>%hqu7{kOH%%C<;?nae?rKu=I&E|GX&6WgI zhrd)O5Ekq(BV|1IvmPq}=-wmaLuRziz(!+kdI**(wyp)LHsSL%cja-+QG-La19&(c zk~On4b0@49h;|rohRd-M2MTwDT~i-Z5$2j%-8xJ`674xqL<4Uec3|mo;wpSo#34sG z82)KXW^0C7BRN&|j!tPL;IcZv5zI7-7{l9p)R1dMlJ}Zqo)s!6uNp(b1)~4~Ye`Au z#*vzLk>Lz%#uO1d*6(Ha@8!J?R^@~jyd&x0{&1>E zPX{bG?v-!>x}>a_*sPxIw4l9fzl2~*WLFpu`4qNanTO+u*{vd8#A^{rGi0zCugrwj3E9B#)_H2kup$n69Qqv07%?JZm)}8nRcOH$NHnM+Z21@L831j;9f0c)_-E zo=j5bSb0o*fvR$7HzbWJAKo6}Zmn1Yni|#wEfwSI-s*W8S1bYK~+T5s+dw#2T8Wt z6+}A?7Io*O^PjeQEJ8+n%w@S0!^{V)emT=_*WmSbukbQ;W5+IVjfrFL9Ggieu%q>7 z(rY_K*zcxqu>Trhrl6>wMlj39onNoV*5GIy0w^A$amm%~JNil2axu&07|{n`_F4B3 z)S%6KEX$mi+R>Qct+3fdmkyAFu=ILagr~{qdp9u@Nt7wL+fWd4vRvz=9O@G|jo7!M zL3H$isb{mN!22&-aF~PwO14=f^beOhgS~;vpSt!OGl)&iiJNA8%-5%ZhL(gI>~s}(8$iyktj3kZ5-v?vqBzb88hGyOB-V0y zN(dXkt{&ghilA?2D%TuvG2+4O=hvrnS4q(2I6$_5Ch#sL<>2UrL)0ysc|4K7giS(1 zfh;4?{EL2i{!bGhS6bYw)@-5RSd^?JM$IYt7Y$_h*gHKw!3cA$lWk$7DWz`NGK-(W zT*6#~(dgwYq^LQwJyo4$T^@7)he_6zORyFTbunexHe2v3Ei)_qsn3{|A6u0ssItW0 zvcvFjF{qF2r@L})z(cugl#PH}J+g5fPesH)UCQr=br?tS(;HX4IzIwRQeuiQpys5R z0vszhccO8+bO1P2!MZJZRJ~_S#IWtwQ0DVY?w@q>ghzA+Qk7PH3JSMnhe#FCmAwBR z|8T$--^1UhPGKf7)Y)xLe4*OcNu3o!7icf$I(5%i-(P0JYu|p!PcP}}`( zXVeMmuBqGati9=yOnmT&wbwl77-(z?5Z8I*S;WP$yU0;ADqt+HD8J9=POROhgIq|& zZX?Qjflb*>{Ir4jp(AG%RtLwzi^RdlcM^#kGYQ==;-h0CP^Gh2aZu&xWACxlTcyH1 zoa-eqt0ynUKc2|jmb2gULlAf~Szl)nTgOczqg5N<3Gu^v1bS)eTT86lT7moN#m`?e zm74RBPpWAr$e<*8#r*ScVhY4Wg<)_(1bP1F!lJ;Kq$GDMBi{suZ?zl04WDgZ)N;4m zZeh^;X(-=w74Lbw193X$J)8Fr9Qd3xyESp11lNK7iM^v7zq!4Itan@+{&*z5<0%%y zfsb0N*Xb`R_pckp#GmdFgM%fGF^y+TzN#0%8;HTW5ZlCbn-@g>LL-TSRd4HqZ0df zb?Xa0Whc6q-Iz*!=0MiQ$xU zz{g&C%X{4Mi1E}-bblX+LG|GD9Odnf_pyXC*uyJ1UgGrT3&_&dJ0X+f`x!^@huN-7 zyv_&c@>ADjyu)Rsi@Qnw&>6GrXSyr*)PYIRTut`!*~j2$IDnhyk@c+`$*bRb9Uoji z*hLMk1!DwZuHo@QCbur>EZ#?rG-N}Fm$Ozq#1vIKd`JiUJ8%NerI@+>n-po4jTTZU zL3On`{Zf5noA;_jPF`^1adw#6GX=S)a1I50lAqJ{^)UDvWa{p^cb|iQQk%tocrfC* z{_|69uh*sO`e`w3g(J1IT3K>?KcKet=IT@CRFrBa51OH0K<~(B%+F2+xHA|>msE64 z!w0A8y(5pY=z6%YnwqcLr_Rb)k}37hXeM$NS8uk9gN*8Q^%hqgc=1=2bn!8fF{W$= zZsVns=>w{vrk8$O-c=H};mH!#Y$Ec)Q$iNh$RkNPe!y|R{~7z6m205a z#B1$K^X}9RpB4h5bw#K8?;WWGOzT(*_mBTd|jI|)Zb&MLt9eCbwG1|k{X|N z4Qr?%Z3TKvt3v8y&!EmT6|Goxt6ti5gK21Z9%~GXYBXuMcbg&{Step#&h3aF^5L2& zJ?mq?nMU2<=H%V`9$W~yLjhy$nYs%xZU(<=uAa6~29dwEHhsh>|U+O;O8< z2U7+j$IsZ#8PJ?!L-Nprfy5=tRizU6pLs#~|g?_yCq@ z0^}9HNNiGm>WZ5^u?J|=*t+wk@^YXd7gWM^!FfNCD4~!Z_;R_kZ012cG^<{&+KF!^ zyCW>Wx8>dDSq*B}mbnDEooBTV%oDV7@Wn3gb_yJ`bB(+l^Gm}0mz634I!RIvJ+%1l zD0}sQF}T`;wA-i z%o6H6SU79U)dHb|wJ=bpU!eG|q#ZnJ%`UY%`s=5C#PQ+{PeAn7NCI}XeUCgG|HHn3 z^3Mi(*yUy@OC-x@q^Vy%h2E_*lfx8rN}XwL?l@f5&*Y9Hw4Z(xkE;ebM;%e5KUpkx zcbDP4D}J7?{=^l;c-Lp|zCGg}ux_NW`K3&Fdx(W9DgI!o;RYTrE@BN#tK z|P3E!A5h3X$!J6?ml3eca$w%HS4uDy@&+S`v-MLmGA(0 z6ge#sP6rXP2PW9{StYZFa9E45e&WVrvqFln$q8|{Q!3koPhBE2=~I{K4AZx2I*_h^ z;v|iGSw)$vK8t`8!CBh!@&b??hsWCmXvdd-5i^9eKeDyWlyLr|vzzNpOSQ6-d+81t zQcs9BIfw+=x#bW*iwVoNQP98ZcvSS{;w$DY)Xq<`v^KQRI|0^<($BmAG}e zsEQBa%F+s(f0K>clt;9%Fev0YMC*-YSN_+=MVkao#mT_*m-jnFt$2Z7Ck zgo0*e*3K3l4B4_MNb5E>#GTOM{E@7Q$FwnEe4=O5yTJODzMG|+PzIIKtHDhiJdYBn zvY`_(wZD&?`3$L5y(trxT$=k&1yCO?uAb0hBTtWreR;F z(|(yLK&Up4iYV&z*jh)ZdE8X%ttT1E)d8e{6pR+qCFn6IuIU+T^|8!ZR98lR;vB1! z3<%7RUzS}8rja^SBMi`@niywn(foh00EL_PAl`MZ8X_DYcjPCPfa_GeZcLqcQgdl)%J*P&;y=gc9I5v6 zS*GorkQ0fTHefec2tQu&3_F$tSLjY*Tu)x7}LneH#jK}y+DOuLa>=5s7N=B0JcbSP0Q!a=E$43M* zQ=5jyd(`23Psx|HF*L?hY#G6T#ji8YWkUPE?UxWD0xvMqpeu|l5A_NlR z5(GQ}UXm+$G2~EfnT_!6Gx~CjiR(RRL(MmhFAy7&%f}Soy@u=GQ9=?2|BNbv>IMos zk`Q74jAw=2-%5TgAQ=-Uz3n3>4lly!E9yjMED?2aROmqVDrLZu%BhFLn9Z7~-Uu7H zfWG7Vw6**EP(klw{KbG*KV*vwvf>lE z{cnUgA~F$ZM?ye0iyB%ACJL^h1`f@&zs7qGv;`Rs`HP$ml9EQ;Bhrh4Lqmor$r>C; zHC@e)V7SYF!_kmEQbM4?_P=(=ABAAarK=N>g?=Jr;a;~#k!SNfE`3fqSA58Q1%13N zpQ3{I-j1wy;rSs6b^YGJdPV(oLh?@e>pn5^Q(*6Mob&bScD^?uVEMcN@E&o~jU%ZO zDb#L#K!PLSf?R+Ad@b4u+5sJJBs#1W0Z7-z$GpS>T`xa+5g{$(YG3a@oKmk3=6Y?$ zS1U)NFM$Lp6uy_M^?=p3!>(yt@JOtuCPDXEy`-|m6Hlhf!2uApAl3(;gHSaDy#30* z3ve!2rHIgo2k+H8tbt>rzu!u&sU%TucSPAVrDOei-Kg z4D`kP$1I#wnn=zOlXAYwhMwCY~e39I}%k>`Wd{rAWu6==xsA z#2n~i)cuO_mo8!~Fc4Ou)oB-^Iw5t}0`MIW+wUqVYOvkKxO=R$ll;r=W3U^pYh6U8 zT)YTEB%<&$#SRR~u&n!}joRc0)i?5H2mROC@~&R{(-DQ=JOrxePT^m}_cS!^HP=Qd z`n?}l6T92NeV!%>&Ruod`2H`t|quf|LCk=H+CiQPg3l)D{Xw<>ZN zr3@wj>mHlUa990Bk>PZ&U~KKobc!x7M-g9CIHJE)kR@NJL3od7w;`U&7Z4r@!|H6a zwVk(nV*Jr%2hwW#)3|!g@NnYyxXl*G79hC>W7_KgTz7lCE(oVchve28M0maJZw`90 zR0=dDEUrg(_?UQ!L}kil?`6;T(48C|Sqo)Pmq#mpzm^ra>=arzellL^@!kF5CN9|r z|HFyW`TK|)s6hm&5`UZARs3c6HeWIN=`<(0fn2qF1>UlaP;$S|i)kgPC)HUVG(^83 z(!uKLs`0A)5D468QUnG49c+7NSP*SYjc2_q$7OmcJoi*Ra;nnLAeZY z*1>YXnbP^+A0OBLO33nX$#v+w7I$JXjQ~Yn3ip-cb@f;tkF9~FUI&RD5KDn06g*g% z!5+~rRBPFVv2b~g(ckvIuWpJ zbvsJT*@Ifp?fG}`sAU!rBK9`E_QgH>zT1@Am5jsZ)A3|VDGGiH&|82Gu_yowoD%u! zeZiq8;}Zfk;3t>9Eyq-9hb%NyNC9WmOsn42_@*v&S_=58p&WAb5%2vQ^`egOhHepNPx=iP<;6wYC)~5m5&j*t(XHXPgisAfMPx=<9+WjqFgonEydlt+rKb1 z6SQIfXf}Ec_#2gRd+wO^5^@QA$BTs-Z_f)M?3&-_?g|0jc>+bk!5nc-&*N*k_s_%0 zMWPPY;;c0?NgiP$K?1V`#ZICc@~y@WZ1%nI^~X8?djElPrDz=rgC0(~N9%sr=$gdx zzRXro$}OBMZ`pPS`k-jt6x~#q|5@mMa^*G;{BTT{UPOvd=I5uZ{f|Kx1K3*(w%$pmrCi{+QdPhl12{#Mmfuf%1_GBW1>B^u6 z|FOJ?>i)(TNu{-3Fr{?89<8}N2uQcU+acxB={x^|l~+{OCD!f#h`_wB>ar8u@yzjF zuKw0n5XNIB?#1b$aVCML}T?2L74`F`wt+A%l?3=H_o5%i{#BNK8_ z6|fI>I_mJ&!7`h9Iq!9F+3vUp38BpIc6&YU^%~?XcYB#cOBEEhBhfN$~Ha5u1G-=r;#@dV)AxZUgDxH$W_{j$$L$3=?Fn|ikUkwSI1e^RC~0pnug-YwS9KbxCc3bCT3 z0}|`PYkfXgM!f93-4Vf48|aO#dZDr{1JJNqZ};4;w!UH(0Vw#R#wt_rAH#omk7PxI zCvG=Zs04nBew@q!9zWA;ca7f7=NRWCzWVWDmZkK$@zA*z{db16@AhM?B{`6_zJM0wC%s+Fe0(u>6C4yf4Z5pVM9EG^V4vh;TyI4rA6FsrEpKPK zN!c-G0{TTKBdUT^ps;r616H|vd`OuTQg)Xv0V$zeI)3T>2-uOd+GtCFVw8j^<*r8a^Fe{Aw+qSdB#@67OJiU|-8-Xp5zRIOfqw7ls1CKL(jVO{*W_uBF z+HV@gDhc;?I`!>iOnMQtyrZOp{C0z)`Bj9C+t(>wX&x%LFkht57M2KPOwRW}k#I!p zgG7kjfd9#@CHV^12g;d5aY@bvm5Kq=LRYs~1R8=EP&U)Al)g_T9I2e~D3%%^7m^%5 zvggzx)r!1e=Hg>M6pRB^j?v^}o*3Y2g7nxW$1KL;jmcgPZhD5&Jn8GB5`gz6pKvRtL6UZr82#

i?fmYFwbtjRA~(f`j!?TjSP?OucxE_5O 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 D`EGsv literal 0 HcmV?d00001 diff --git a/docs/ExaGeoStatCPP-handout.png b/docs/ExaGeoStatCPP-handout.png new file mode 100644 index 0000000000000000000000000000000000000000..1bd401bcc80dda12375de4165a8784a72616c83c GIT binary patch literal 748012 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 PUlZbdYpfS8Y^urDefyr35K zInDOYUR;pNBLtWNgzwLeFfb5zLV*ocK8jTWIAf(Px-d0Rb}tP^qaID6C*HpvO77lI z*kR*yWA~d%k2YM$<)#MHxT$dEeH&nBIPdZ$Ranbpg##;GBOJ+bRrZwqSJmnX1MkVl z(}e?__){s#k5C{hAyFe67<=#6@Ba5=CIfi8eyqEmvT}p8 zYLE6OagG!V6eP|DsoI93{{od<%X4%VHWWA7O%Vm2PTeL5L5qHr}mbI)`D)sY^s zM5SS(q&SIo)jptJ57SfHJn~)GFCDzInW~}$Y&%&SAU4mcvj6Y3;JIH}p0V}9bBBjw z_T_gUKh(d!e~33NRQAf^A+}~kJoj7o-?)GO{#~sh2D>o#`6BzIb@Bc#KY8nkF(iWC zy@hfc4g%v^Q2cU{*Ih6?^Tm4XUXy_5x#QaEyjcsRVUD@uHs6xl9N`QM%Lncc6UIjM z?wv>O+;bQBEIFSv{?4UeUak4Xf5Tpv1E{osSA4`*gMpBuW=MT7SQb~ycTU}R z1#^!l0MS=3KOU|=e&lU&ugKcfOTxZ6HE2QXwH|`od-~H~Xk?(nBoU0Yvm=qVb4m;?#0teI%lx zqVH%tTbT+L3+y1%343J{Ai@8W{ms z(>NiYC14Im#fY)TlsiUq8|e+zyjG?T^+Ve@fx~_SIc~g1dF5OyUmaZBU^>%8_mzg$ zB*84{#~3Udyfy5{Lgmm%Z_?X&OI0J%9fBPd~W8_|-3(F!`iJ53`gMCJ{T3J8CC+hoIh8 ze?6M&;XC6Hye*F*$)v_^?8$slpZL4c1J|qEgKmne-B208kCwDT;$ceeumITijby)q{?2E`i!i zG-m_pY>|v%MJp$p%@d@3;@$Ifq1j1IE6MoLmO=x96O1PBjLzPBP?>wN_gHfVtkmb2 zm{7$rF;c1O6E0W;BnhAg6fFmP5#WfVvND^;`>qpWjFdU0R!k&2Y&x`^fakgE01}x8 zUK5D3Rj=CVU`-Sqe+1Z$h5%{}i)m-)x@*uJsizXO$7yn&n)|sBCqLDb(>q@CCN?u< z-pPNzuK*&zW%GaX^6)S{&pi$$!}A~U6um{&s4|wz4KSFO<_^!@tY+NI`v)2W!NHG* z%f)!(&)$BEYX7IK`=}6^lX0G|ztvqVRn7qGw&YvudUPB-cM49~^4@KBDxM^Z@!b8K zlV~9KR4%)~+#ds{YZcu3NBZvh*nWVS^~a%0&)pbZ?Ph@|>9atHX!)8Q$Bt+YK(kT>awj_f3rT z@*sMDU4_a0_vDs$#e7$E^kz6bTz^AJBSXMZq-BQMt3bZtK3zX?Z82YX$N@gV+z+>) z>n3E}Bhe_DP8Ixb2jh;(lV}F*HXU?&QH7Mn#0Qe+o@nmv9b@Zrey1@S(xfSs$~kUh zG8sh27F0d7ZU@aM&Y6#jO_i6*wtxCd$m+Yrzv=DMTMy&DNi?0Gp|aRU@LUBT3868p ztcoQg*ABBiGA?vs8YW}Bq=68eJ(_W@4R-3s>P#(wG#qMlPH?s}vD)@FEfjXDHp(GH z7y$@B#!>xV^Vu>j=M{ozj0DlM% zTW!OKB|D4nnNH*XfkdPURY;~XRKln&(t+u8HNnRyC`m*T^v!k1w0=W z$(!gQ7b84@M8x6p%{Hzy?ew~b*oD#Y@!)tcr~=1;!)VbDIP^sU<%8qn9_;BZ|ArX< z!l(jq1XVUHTu6i@51__X_b0eTVI0dE5l1?xO4E%1M^v&A@F&K!%Y~Xo+)z81&%mc2nWh`Yy2HK!tue-(n;A-gy`rTIB~k~&ZVr$4DL&)o_|Y?3 zE?gF@BC@u=S^})4cXHAyR7yZ}YTwRv;j@QTAAmqZT2;}IR$w~~Pg=(%JK?}#0v1ieAfzJm0+d(gf$!9DK z(TU{Xfu`d*@&WZB>Xj5lFlp6lctFdu|2{v6ErY8;(8d4Cp|SDYbH}xNWOkKspK7^B z1```8qo#Gu7FWz&Jn`VVInK{LI#@WA-nEGOUGy+_k%1dH`Ul?i8e~1hsdgcO+=5v@_uRvo`|I}~J|x_Rw+89|O1E@i2FvpUmaUqjmk1muswEEnFg~J2&lhIe@sxcZRxBF3XFo=4=@a z0gol`$O8ctJP>&9^P*rKjKZV0mIqz@fQJ+5aN%#bAsq0Bi;wxP;g3ft001BWNkl#vz3Dz(JMsBJyl=jZ zO&Xtm)<67&_j~TS4#_lJ`v zx=*CTY=Y~xH2!X)F+fVn4q%AK+eXb1i_HQov)lXRouA{iQ-Xpv$?V9+;5Ltr=%9xe zW{`F;9IqY6r{8>B_D>5tr)_&1d9HGTQG4>Rhn0j^m4sUwr=j{Op6D(vah;UD}5C_nDK_ zq#MWyUb@aFh98a7y|#}sdwqutWJQbV!{kog`C_@2!;iN2Yr}20O(84v;DgjsnM_W1 zc24o*kE;#i=mO1{g@={}ql1CRymRBs!gu||jl*+Bj6qNh&NWe&R^!HDJ#qOVpgiEF z{QT#G$hKUmSGCd(D(zm*OM|qtWgxMq~z|iMfZ93?OOmm-Lx>7lzXa*TV;r=9`7yaRev_ z_7KHOF6{VI*qmkfMTkQXG!Z2HpasvJ)5722nG}`XcvFSn<)FdnAIn+{m~DaT*!{b5wmWWR7^nUSG+Uxl*C3LBZQK?(!9$dz@0yRklprou4B^$Sg;6 zLaKY^v=xTP>wakv=V$%q+wU&VnVa{vOB`nEbcN9{D-I3h?o-fZ#!Fv>cxk4m9^vYJ zQW(H}ygc#6&|v&{9BOz>SyXKanN^(Scam{lMb!HCvlhHv6(sq6m?UQgQv^;nWtV|+XIoW|@kOra25UDq$&=heH;zl+q>mUNM*6>6eO+NKS=WqVzZ+~v^ zc97CYa@&6AlX_`)S7seB22%T{zw}HyKn^m&=^~P|Q%n$31|Tq)Y(9#5*C~=zNP#D} z16YOr7BXe}6*Bu|t1=~!mf4n)3C2Ce2;gEd3uF;QKi>M}xT=C93LRw>EyNBTyISnD z5Lc}1&hUpV(Do=mtCFxW(tg1j^{P97GKhy^+{G%-5#1BcOjLl0)j`|F$zYb+Kc&;s zR~J96obAH;?zd;jZJ?$HXbW%y7%Q-S)10Xp9r6LzWIfh|T)a zQMi&MUIjD69Z(Zt4L0-_lOTn)SRZX^QDaqM`pl-{>TRGILwishR6JP>kIsw*GpU3C zx!5#+CTzgyWjvEWx|oz~8f^t=H|Y%}x#@Fzitmo`jUADpwcu}Jr9m#J)}jMr!$N;O zZe`e`lOVx?6bpNII0I6|VXQk@ML>HUQF8aWfchgM{_sg1^#^F`5mJ+eYe+*ZjdPCH zCP?{eCQypDRcufkfo0_{ChFn_VQPu3xCpwnP zC8R4Y_|~Z31`oqTbNl`5h%w*+;C8EciTx`*%EvtNe8j->2z0jUC8B|_G4A5hlTJ@k zzC`ohTn_SO99riI4a2i}>i?rWjZ9rwcP9hEA1tplqdbW8@Z_VctBv z-+X{iF3cLAdd_qAQ*Y#*#oTi*3YP(uVReiA zx=vk#w}gs!6)|~>vIGZlQCcofJ5I6gEq;A@5X}~X$rX*w7whhwPGLTw38Nu>%Fx7> zgSaCENkhiYAM??T_vz&mpYN7$=ydSvgLI6kss9Wb3Q>6o)j=G~-O5Q7-x1y$ZwK|L z$!%wb(rw!Y)D=lYtayKUcdJ)A%42l|JYU!~3!vJzkLkdG#DEoDD{c)dySrJMA z?~nOMd(QF3`|n9pmZsS6e>mQ7-RRod{ySScFa8a7{g)VZK>2^5C!c5CkqQ1R|K8Tm z`i*kP0pTHN3L_LQaCECZque`Dqe(|*TH2|X*2wb(Hqmx%(G*CI7sd-*otp;}TrQgy ziqWXvzcCRFcK%5FOz$tpJ}03wYRApMIWAsUqV(`cjv=1mV;APPSi7rp5y!=&K;;^Opl zr#tK&w;QhOSX>!=QGf%i7jYBv18E#Z^m0HFbdGq*{L?}tO;^__rKD@)HO)q7y6>Fg z_Df6?^p~x;T$y%^x9WM4V&r)8CyW8}TS}5G)D3%n?&ZVa{p9y!+uz&Xo(-_>O?c-v zr+_d;Oj<%zic-FCG8|}h7z0FFYUoT*p(A*Sd^AZ_`W04VY=N)s(SoVx=B^ZyGj5xF*YD(QT z#-593IVJFU!BTlaNVBt3M|`2xt2SJ4CgJwFVhlUnC?RzUzP%^GDDkV3gGxKJ<&#ms z!OAX0T^xiZSfhEjNLC3x!dz2U5L@e=bTR*7QBjeCRugu9s%jIBTIL*~5Kn{f!mmTh1<~Snli6ZMN z{fVEyUMsE)KfGf|E%PlOvlou3of+@nOfmQ6(0Z7AoN1+7h5XI>p64#ohY%4K3nv~o zf9bi)@UO!^5!TIWm!Nz2-8;f{uAlPa{4M5~u3dygO@IGE#M0fq( zkS)y>F+V`W*5b#Tzl(b3P50^giJN2Si;R1%=2)TNT5sotIEK7TacrgP=V>$@@$;n8 zlsG`zk`n%E>q(X0iD8wf1hLM~hV+o6_Z+PQmXWmBFC^r0K=|In=kA|7Yje*%ZZuu6cHW}j@Z4qlmX730p8E>VeZG+auorvq zzF$_T2K>ca>$kK~Ex)Rb^cO8C#;iZXCa&%bezxJS)E4S+k=B{AmDWJw;fxj-t+$?k25QOzxT%}ojE>mQIAFmCf z`LkehZ$*9OCO&*~PQJH_>-Qgf=oY2Da5OzEZJ{D`(|uZ{-dyg~`-w_WQb(wMXZu|= zzyK9_iE+(glMha|im@Eb1&|AxMhJ14_78b8Rj`V}5J|CIeo8y}qdbs1Vln?4_RL_D zSjz5B8()93#*f49qz$M({`q@r?|Ih!=Re=yFSVy1zxdKHVt`?O`ROll*)i+?AVND0 zI6gKMcNuzqeu35@wmktAj+c{m*Er1ki2O;2H;n}bACP7s#GJJ6f#o_>54Q6$AZ~1c zv1458oH8T(hB={nv)b7@JekPltEk9_Tv(m1cMvcV2t&nzqQHNQ9}Hmzt43(j>dJfq z$zVHuYMq2}Z&G|!LhBtBS(#BOh&6h9lZ#!j5*+=075XK;oKQ(*29)3JSX5q3cDit{ zK@!w%jyWV=Ga>>K7RaS@7OSC&h+r+n1vNpglWfQVjbz$!P#=fOvv0e`L2v1M&3NiSDt6@iP&&4?zAXRQnbIN{zrK_ zpaRKL0G0$vAxO)TRIO7NoWbb^)`CR@4y|F}gtS9Uo8y#A2v~r3lb?{*dyI*Oz$NBZ zd+2tynF2FJAckVj%F3`}EzJo;W7%?>fMi6SYdoDIuc`3EWD9f`b@n`vJc6Wy^7%5Q z0Tf~ti^s>NjOUmi2P7}B?Wku6Qa78-@4tBtw7q!@G<{<886UARnHM4S)Z5u?j;Gt4 z4znwxuL(gl*&${z6=Ojb;t3=pAb%%Ec$DSS6R7k=Ld*e>YRq&(tZ>8VdSm?UUtjjz zIIPS_K zD|X*=)7>X`*6#`hHaqj~8|;qzX#Nsq7|b2havI zB0YIs9WUswzH{XRo_|Z4k{Km`GN1Y>EuiqJ$uF{|;kj z#+?)P=sem45R5Xj70>L(JeDr$f2?cn_4`h#{U=70IBfMeg+7;>ei&JGt zU_rPv+4c$EIZb;gD#Z4Q9EfT<1VvtJ+&7f{kn=@^eTIP7qcmgzoccJ?0OY{p8gi}(=%N;s)f^?KB+5?%KL;PjBTgu z&lc!yCZkRi=)qF7bWB){`GBnhvl*L2JR%#g@Z5F9=0&HrR>dm$CT#Yd(>>6UoxLvS zh&6!?O{x^fR<0zth9Ach?-Z^jYVG)JqWs|*r12BPPf9@J z%+QQ>h$O1He;N~>Pbo@5Y>d^IMl2!&WaE`~HecKf6dJEwC^9U?|M=y-( z*hB<7PX!rt9uSwTvF$_=F-T$Tz&ti8%C=Cz*{KsBQVK#%18`t6nrAd936biV6N7p0 z5HbOR1vj_3TYC7u|FY`2FJRV%=Z-W8j_vw=qjvtbj4g&hn7bT!Z{e2}<9^+9PqD(I zcb_f)0a-7xT=w9%Fj6?T*NZEC_?XxjFyO~;VB0(sv~o1RnBfrC4d$*f#KgT}450Dc zS#ybwn{2^7kCE=3byx{m54Db|W`CYy*b-?{NV5e8g6@%bt8 z&1XUS5?djX9~|zrffAz*P3hokt5lP(@+2N zf2O)gU<~pEh>H6k1UDZTvOB*QcDj`*ObWzIgn`1ghIMv`ZI=V(0q%5UMe7?71OIqh zJmkEw?aHsq9TfVY?{nkMkEBF}V4xp^Wk-1h_yo(2Z9kHf;D#T;U+DgrPkd7WQnY5C zR>&h-e2z7uOA`<@M%5|N3APEp4)2nfC4lO%g%&vOu7kY7P6eO~!<^d0$G4kyIa{7K ziqP{UenkWTppPI|IH1CtKvL&vAfto?4O7HWLb$;#F!ZUQ&ca)0WR#~4^O;xyp zW*>3-gAr);uv;jV$Q1+TSfJ!!If*<_Q&tAuSa-oQ{44NZpU$Lm-H|ab(*qAH zUdCeOP|jyCC9{Z-52^#Wz-RV_xApVF)K!`-1t2x>lmKtR@4Dg{E z{RqWW?1$0zO(9wVOuNy_A*Pa?lQIU!H&pe7&?4lK^xKF(VsW=@(P zCBtA8*XUD4uGG`r2@yz=vlT&PZrpX*OXGKW!6=9Y5R1^v5(i6ZbcSRO^3Zp{^i8!Y zH-r)mGaU$;(Y(DkLiH_}0;SI+9*mhjX_ZdJF94yY({vocypW8$T!J5H+^=EoDJ<3; zGUknq46!G7Ftd1*2OepogK_^BZJEm}Hb3F(t}X|2k8rsbd%KGVdIQnJPy3$Cs*pva?Wmm>$^%vh<9Ohm%0@GUV z`Rc+cFBfPzx8{GleIQ(K)pNhx>tX<}dG0F}s;h^va$?IYmb;G|M$vwGR3=n&7qkMU zTVefy!ZJ+*S{@DOG0F{t$eO@1W(#k3en#f82eTUyc~9US4FB=UWirkW6UKA*Hsb62 zJ}t+}JG8}c%@-daA=x#od$zRmq@7ngNX5aiBRiU@!W_tp3y!Xd-U3>s+H^9ahzId= zx>L}$;K<3+U(co=Po$QdP4)`YX&Q4&YiPQkQo!_pWMy`?TRFuyM!96~w0?T_0?dfYrxxtanEI|g~KA~3gJlFxV$UI9r?2q?)G*~k3+JS_>_oJKJH6JHc&OAV%0BS$J9cG+Y9tWNY zC>-1zgH9ofm@f}nPlf_#F}=hH2xei|n1o>Z0kzu>|1x&j^~Hn`6gt#lk7ZSgdkm-Ld-RFm*u8b>SH5T&mp_T^^bte9!3E zfgQUCSi#dG(cTQnN4)ZAI=Xhe)ivo3>Vr__;@s$fLEd+hIZhg2+@-OVrEr3zMA^{O z!O9dAE6sy(r_31hj%GV-B9s=$iGbe7pzerAl?h$aS zM7emfN9P&pd(+xdIusyJGWkS#Mr2@>Z;{|`9arX}o@SNw1ABsBfc%suiXm}rycPSh^efI3>$Vkmx?S+?m;dzxo8i%7Okj|A8IP4>I3>WY|6E#I3@?rK9crMPOCo;2wwW&g+$E z#kP7hf3>g-MEn$7)ojAP8j;`I~-){d^Dp?m>$m{X;V)sx8i*w8;!k8H_-_H$S zIZ?k0YbJcteY$?)%hRNXkEnt<(pk+>cTf(|UxCtcm;+;fxiP6%#NP(trHcY=4l8NT zXqq<55Gpg zDvW3`24a74dRnMd#cHGyHGB$l zNzzKC_Zg54>=b(UeH>E@9mg7Qjf3=8jFS2$b^L8x*-DZQ2t+d zq=Y|$SKX$RY1T&7phe3ejzdp9*$z7Plm#f*Yt8Du)B&^%_V@SUJ2shjm~|k;1ArJw zlZ?!x$~G}^7&5MxVk+e!06xMNxDNw3ZC5L2b%=nyQp3(T8Nx0>ILO$r82ir5r0p^8 zshbR*KZ0c!=nkZo$-4ON6{d41SL4-I$3A#NUQ4SwpbN%UJNF~QX*wk}5y8drr5kD# z<<16!(8s!4Ib^)h8cl$L<2xY2zcr*EA5$E8QGX8D2*WM?^+23DlCm#~0-7aqVT%F+ zo+tQ5Oo4*IS+E1Xa6% zE!R$H+lcpH0(rB=LA(`|O~aPGv>)$p1Tb327SDHfbuCy-EM!p3m5ZHbRz?lwa3}&TVEISx&r7GgSW$b@vY}ng$6M#W_`8pSTl33&0HI1<{!uGw zuvtO-n2!kKqA}wt_#ni-H1apxN^QbPUXHwWLJE|J@AB|hZ-#eP=Kd{CP_vUVPV?Wf zf8O~*2e}*$&W~06Jg$rNbmrzh=`60E_{yF^E-;+L?sf@9kerM=-jm=Dl9UrV&O>O7 z=KYYgk;TG*lR4YX%ev#)`Z0XCE{FXFo%B$JFP8vNnszXr9;f1xLc~9_qZ@%Z@a=TE zPpLb|%#>W|my#9GV$!8AP^7Js;m^#U zPw)yb_+VsODGZO-wxND!%e49a?ZpRs&%e4rpIE>?vlj0M>`S{0*QMC+_d9(gU!*`_ z7Gz`)lJOQ%9I^5Mgg|@0WfzPWW1>teW`p@kZaicV-ZS1W@_l%}F#JH*foIxK;7MnW zjuE%AMG3XISDrC9h7R*Sx0F}yo%dMyjlw=R0}*_*8ljyJ+AuiTgv2W59blPBiDDzH zJ5!|88JHh4E@K2BWs|d@xe1C|5-X_aBV-xU$yy30S;jpC*hE?to5)_dAONnYcUR&` zv^tq8LTJHL{8X;Or=%)qMr$rG5y32+u8g=jPi87!coOQlP)y^&ew0vP(H$m2OYv2) z3C7)lmdJ1Bukj>>t|pT!jKj+44doJ$&miwl=t{8~nr8%3F_0uimDfr2ND}#NfhO?@ z5xSlg>awbcL)Hfun!=eQWZf}}6v{H@G72|X1n(67+rPpiT;2QX&oAx#CDT6t>&>6O zwCNA|b;bI8`{paAe6ixUZ~N*~X1j0M^jrR94m{uQ0vK7GjQRfU+g_i(Uww|NyY;H1 zmY;mLjh3sw{KJhWZdSsM(GP(thsdmb(kiN5YA%$q=!cZcWZK~Aw3Eh-<_$r4&&T^- zs>6xNf|2raQRD$RtlGuyB{z{R04_PK_w6*!Dy5rBijrlAO8@{M07*naRH3wL2T`V_ z40RmLmOoRPbc%b4%#3l}zkxDy+U*t^xWC)5x+#?Br<_~P5EMtpYt`Nky>~J|AqjO= zih&Ke?E%pPj75}eQX4*>OYbM%u)Jh&@Y*uuZyQz)~o%W8KN3$al;xlDe~OW5rD&hzB=A02 z2ac9)PPPgqX3?Akb}b*1RddA6YDS5>(z2gyoV7=Lb!pShrCX&sVz zC`-ScM24~s+$U)1Oi|cZ>V{Z(TCEf7(Oi|RERUm%yXIN~77Q*I!Eq^>(_Mq9$~b^O zu`mk2Se$`svSi$K8_i^9u8;d{zH1J^s#}=+P@+LX9=261tWW@s4Z$kmtfkRrTPuo& z4ggiZjl?OJmB0~Tj+-K53BiCSB&xaP{E+M9&`6+ZVM6^Dlk1(r>#wgz;7>RLIe=-r zAzYYj^W@|>4}O}9ib6w2%nZKRL{T*>2x+C1$5+b_kZ+s;hrl=nob;uw2I9C)DzI52 z(-?I@BjB(E#}P7{h5E^0-xeyIwzju7a0FE}O-BWMccoE(`AxeDMoh&M*fQoCG-ZQ! z($t-fyC|132hM1UR6%H-BKt4h=YZrv$UrWiE(e2qtrUh5WJjLtNqc| zi7IeVahX(Ph4Ii4@M;2LN%*&7L>o`*nEq~eSm>ZJ(;$Zl%qz8Xw9*s>;$s@+8yVOH zZtNyQBIC|t%eUTR+G{kCSS4kJs-s- zc;I~3f>o7znp|t{ONw~_CxrWH5E@-BjCcHY`Smy~36baH3Aad<1k}qASqxgUg8Sgl zFuH^W^6HVCk!>GU^#HPfRBk5`xS3~CA*}k-W+I>t1J)>K%5RSL{d##l0{?;|05gF1 z9WNz=@K$HWlN+P2S$YFQ7K7wP#ffpT@?&A~^{*+t+NQ`uzs zsp&y5&($N2ai7w4Q}Q0vs&6Y%$;-_fN?WuDzPp%^U;c)2!UEVWpay+8$Umkj_d_TI zgaN-zBuW80#+c$F$`w>sof6@M&XXl)P22Uu(F}l;Qx5~@o}BIy!4r?*p__4?+w{5d z#^=MdWA^oOQ#)^xjov%!;IcFKfVgp~0C*S@$qSYl8Tik(a3AI;(E0QRlX17vKtGzb+m!+poPs9$(g%}C zFH_6pRaB{CP^JlD!@?h-up1>vR3Yi6gwTK_&5#~bWTFcsZy=HlRiJS=@HEgsvW<%n z{k>EYJ_Gq3q!=}12Tm;HQ>?ZSrarH2FlF~dJ0Ay=mO=#OQ^@c1z&jnMe z@vBQ{1((W(01Ac=T0<^dj8qGe9v&!RGvPADVbqG+)HRRMcpwK!ZL`|)SwJ&Hb`n?Q zxk}X}fGqP(&X%cDGcOS(1bS3}>r{eSSXxXcd2md-fEng!%_$Z$8~}*6<(aXt_YS^@ zflUldrzb!@KD+?)FnExTwg!GaN%WZ@1x<0^?BE=aXIq1;s|5fCwT>aWeM` zNdy858F%_{<@XsC2#_|H%IqW(uBKV_*TS%qYK_^=*T&t9`RgzLQX{~7gc0Nkk7OEK zy|&yEL_Y9od0MlLJ}D%s4x!o+WC{cbW6MFBr+M+%@JoGkVrUnL#+{H8PN(RzsW%pT zY~iwk!yfmLFDzBpYz(pFz0}{JW(@zwFF<4pCX=c(Dn>M$#VboYSs<5K*sXR7aL?N| zh7*P%a1oAsSsl~BHssj*eW4`U2)5eZ!GeTCC&#b}S93<$jj`U4z~vAM8slB{Vs^GO zfAbJn$C!0y3ca%I)F8W*tAz0(@!mv;%*wXYQVru?BN3~vqJT1{w@``p92f{gu7Lsw zeXkDRf@=I>>lh7#Gyr&;viS2a)JygGzx&D0aCD>geyLyB;opeFX}iHyQ~ct@#D&2t zRdnDuSP3kT!PTSo+W!7v|9GU1*9fnVFz}7WnoG(@Mh*cQh%$(klQtnygUQ0=bFp+A zQh8IOc+6zjW1A+-e>Hq1)(WQN{8E2IgY6q0JEJZ0J}DIVLy%br4%UvjsoDXlQ-B}Y zcRxvn=HQGfEt|M3#VC{Lq(fbg7PU>6WF##USrIS~00vmcb!ZL+KM0V76ppHB^%vT1 z41jhxE2Whzz;3}l;65_E0dTl{rco_mSBq{Lyxx&Or=L?c<{g`@6sz*4qAqI0%o65Q zyrJVVQz{~0P0Ez!*Q$wuz>SZ9`f`Lo*ml#MyPU7l5QL9&JTgozJkB+IavsdGf}jy< z*RWqpBRRP>g6YYSASrLoTG0wm7pWXh6%D%Mn@0DB0e}6`>k;_VjDSoZ#+~d@ z&fYp1AWs6`PQ4NwnHY@`aJ+2=)mQ?aT7NDaPm|B2SjoXJ!$*N524#S9|8ibfY1nm< z6C5G_YxpCuZb}90*aR^^nh;6BJbwgi0Pv1qUI1!F3z3#T8yl$y{zN_(-`q?)n7f(1 zR_zFHZW@}o>iuI6LKeO#?B`-51ILGt@R*603tL+Q7l70OLmSWl#Qw?s|v)!}3^B+G4mib>lKmWWwe>BP~ex;3~dTZ%sKF7rf%Iwh2Wk%DZjk#dgOY>dmyoIoE^ zlH&NTOu#j=#ONFgqR*n@2%!T}b9#u*C{W0-K@Bz&Iba-LQ&74Xi}`mVE91EbVTVF| z1k52>%095}Kw&x8W84$sB+w8e+uexj6qB_$IrlvB0_r-I&8l-WO90bI!lK@*x++Pa zjYz=7uV)Syzr3n247c7fGb>;kgh&>I(z!1iQKs&EBI7oWx3*eEn!k#^B555!6T%gt z?k16tV$oPF7pya#N=TM?s8fo$jycWCwyIVPv#r`F_Jtc0rO~W%sZ!CA^#)2pQ;706 z?#U*=JwkI?uywGdG7~Ry{AAg|2ARj}$LQ3RxePOnag!*m0_lrbSavwW$Gxq~=j^31 ze*Np~5%_bAz}&ctkL~vAJv@;ZbPmE;UQP!(+Hlgy0Aj{Sq2fxCIr9T+*C#U@W--Vj zt_)5}f2#!so*=3*F@O%APo(ZLMJljP znCog`jC&5Myf0KP4b_pUhCDo;T#i(5FwrcaMFx1$?vWtQ)evNf&MwZe>}da#Up1 zkIxwQF*3h|SsEOo7iolIpb>-fJFdtnng0Y(6Df)ErbYzjK9F&;RHGq6gG3~yi*x?hQGsSP4xQ51xG z@8H}z4h8lU4!~%e*u`#5Ue%q1%xf#vxwohSApv#VL4{#ruR#9NZ(Wy@g{XQBX z@2KU3$s(5aZ3rbCT>6XHNeUr>hb;F3Uk{;|X?7eX!3Efo%?tR1j8-pHWfhgH45q=u zXO#bUT-Ezf1s{%NEA_n#8}6z+_jx}+a1-;ZD5wrB5hGx}xcM@J-h$683vd3Q=$k6t z5MhZ!jzMKS35!6+vcNnD84@&oQX9YY=4Oy+A!9Mog(Pb}Sfdn)cwH?-sm4rV+<*7` z=jT7Y_{;Mj!vfviC0Z$TI%{iVc0zCu0HIJo9Yc>mK|mh3POO7|g0-X@1ZOjhej~FY zfdu1k)3)gt6rO%fqe`X9>Qv{OPz9LX7WHjZuzrRtYnu=(GYm8)=Rq7{&BAk0noA!(K6Icynh-|tYJxZe7%nS=@ zv|Zmpv6pBMDH;gl@K|U|+S@Ah(RR>W5y|b(XDAO+)sWjSq!SItG*sUYyZ z0EY6;);qm-fC*r5L;0qIy^K3AKAPfEnMCphZVHC0-K2jHjof%mIdUQao*rn1mFc3|%u~mxH(0O?G&m`DbB%=NWJyuWRem=S}r_3S` zkoT4kSjc@E4M1!Zz( zv>r{@P;=dl|!rpoA`gbC%>Wj;dbw3!zy zBD5_MAPFe{;3N000(EZLh*@AYS|N8ryh0>A*MhNQxE|wB;zn0KKcozVay=OSf#Ed4{)19*Bi1Ukl>i#C@o+abDZD2qSr$X64Jr=p(KM|VE0P=| zdXbP~m>98S@(pF**(|5#OjvFwOVheWm6}RS9&&`x6!GZ|^o}iMBFswthU=1L1?gsj zWg^6V2i3w&ZMf_&p%zubt*$L$JojI}|NbU+94n}6jONA5->*{$!Q2X>%*3%toe?4q zSa$%5SuKv)2AENY(JUfjTSeE(5Qh&kNSE4t)-qQk2f0=wm_nRovc(_C zYB0nEjCs6zZZa1R{LeX(D!1Wdjy|FP2f9X#2$3YyfKD86Ud2t9i@X)gIwNM%C}x&7 zSI8d(&S{A=bH|t^^LbRvsF^^;Ozlxgrt+vD5sV5jg|0-V4kf7jcp8jwIYL~B^A1;X zpP&i87?VA@=|DPX<_V?WW!r6@4W#7RCyDac#{JsE_4$f58)oN95qpI@F@$pc1M$ z;AP6U2E6@hELfUJ-AvX!H#q$t|I72ARc7to-;!!PnOrncQ^W2hxP}-Pfd9QS+&kGj zkYnWCDPmIF4LeEPvANDY*9$$BqJetf}bN`4fg;3wvo%5q0q_9>mTB}RXJ4J~?UwE41@TB9I^pcM zN3$%gO=itf2ii=R^lHC9=nn=XdSJ8gv+09<~}IIwjhlL_i_y9P@`+fOo z3r9ADxo1T2XY5H?HW))dkIoX_P zJm8cY#oi|jE|-}T)XmK@^;ojuD~qn?rpp4L<6grvpm*v)^)+jfG=Zl+WA=)UKN2}LlZ|H zlm7#aduNCQ(c+&cDb7U|yN{nfeLMv3@)jye=Kop+L>#X#;ZFDA(}$0T%Rd&DTWCv9 z1f9)Z-Z3AAI|q-SK0KJ~iC3>|N86maq#;a$h2T~E>b{3G6^$2$3z^);@bN=VeJ%?5 zt*h#Ebk>(r<}aVk)eChC?E2wBk>K51NNUYbkKa2(^yQaJmCIH)ruky&*Tmwt)r*O< z=HepJQg1PY4fSxmVUcDXO_+Oa+FSB@F^uyF4}zWDyLa#L zz_!Y!SR78Yjj->i5rvEr4u%|@HZXF?jQxg-WuQ}0GM9B|MYo;BxU1<6)+s2WoP>*N z>9r~#G9A+<{bC!i2D_3DZcDjco)m>FJA0?Ha_BmlC;%xz?C6AMmM*P8Rppr69wXb= zYaP4zh0B*pfVGS}{w$?2EWFz+9`-7}9Sd*=3kF3D3(y#ZTM~){;C>+DDEV$Sn~IML`+*fLXbY|R&Tk=L2LxHuaDZb9iLx`*UB zt6W@s#0HfL#i^5t8mI!n&<49~XZgp{G&$3b3RHLYOyLq)g%D5^{28WQ-E)EK6rI8t zpV_lgA8Jv(FsM>|fYMA#j7qN2qH0qM&9LeEN?^3j`VOs|`URLshYtbVXnhJ*DF#agWQ`7^?tHs9972!*oyW;nt3hz*-cGC3 zL{E;02`db*R-_Xiq*4>CNA_M{Nx;|OmxA-b5G5Z0LL%>-Dclq@8G%xMpTrff~obF9U?uet!mfGnzXG7EPXLq1}Dw^50YM8j2DL*K+%@Yd%pgr1@I>@XSaFt{x}kDFd^oI}bfQNp#{D zTWJ3Wuh=na44r3c$$V%1?KfJiv~ncxyyh~Kh?TF?`N-Ri*UWiw-fH3$e&dcg_mF#V zi{0Jfe{&+V-&;M6)m1@PJNIvsIsv&;TaD6&6Wzq6v*s1@AmS@E~q&fH<*RLL4>(2yA6tfYx3X zXBqpl9ftn~CV^*zv|5gGIm{K;~HnudFMw>xU0Pwn$c1*Szk8v0Jf4AEz;ukyg83Y4^GXjH1c2dSM zq`DzlUXTUB{J_F{fHRG9IVZ#CJxKcMSwTE^F!vzvTO6Je2s;yGpca#F${C$>=y=X2 zIKSw}KxfaF+l8HB(WUeI^36WC6~amofjQH6EN z=u@Kr#D*oU??7|~&Txnfln;(!GFixjQ_rOKv?$igGln_IrOCLH1;xwe#HAO2F_%06 zsfIbqhv6sAQM`jM&reL?6dpsB@c{+VX659>v_c2FLZDp>`u!IgGu*zr`1jB_ zh%MyX-+FrR7{PRU-5J-E7xvLJvtZ9wRn^S_-KSX8M-LxAeu_-`8=fFA#(ln5zTG}B zj^hnGj;mS5qlbV0@EN;RyP=l16~Ae_ySL{}NULbdd+nh(;xlu?d~i!E-+e?VF>g+) z?jm>Z;a_tij}%3`dewMbHs{^HKQM>(PVm~=zWcp9 z_ZC00Syu+Gy1Xgs@^P?mzpq?O9QAyJ>E}m60v`XL_JjAAG0+qKysFuVEC24D_1mU} z%KEMO4T|4%de7GHdN=J|hU0D1@+yAQeesTcZR~D3i)$-g4luXk*6l|KHQ(aC+`h$f zTQ{%~$(pffjCn0b()U18e*FNmlRJOu8vpQGl*(cl6w14WE|zn~E0)8P%{V|iv(d2Nh6uWs z_YaQ^&PLe#0JAv1U9ti!{E_)at|jjy?|m4AT97dQFPKIgKXtE1Q;7s~7o{t3ylKRZ zR$*&r0F^!ruOo_BX9n{Q|9+=GjRnT`n;z8`1{`1mkqF5E z%n5rVl%Z8QxEgi31CkXx7#@a?>!_*!H8jbHk1tN)8XTA8m7X*PPHj18f1UyW3q{eTDeMaCRSmB+My#`D(R#W? zB)P9AiqT?fJIaIdi9Vz9DHRygs+;@B^CITZ2BlqqY4E9loTxt|0GU?yh}({~$3BKd zv@K%Az0-?}S;W-DqMZs?v_?V%7*c&-_YQW7Q`~+t?edhSZX%j4pTJlDz{~muIrj*H z7MzY$DdjuAMKF!jWEGQiU#_8#&kAID^{+u&jQa~)WOf|l9evi3CTt{Qde!l%T6by& zlRmB_a{1_{9mlOl>-P~UXVVUrvPcACwxM;lHfLMTh=u;9_nw*FNBT{xU_{h!gHi5%7kuZTtJgmBc-{E&uUysm){i>6a2?v~EBf-;=wS0je(ck#LT;<@2F6Jrv-)K` z5xBSh=3-?|n3?1DvKy4&#k$VJmzOUlG2~BPTPVq`>&H;!!0Qmp{?upo%`442!Y+q> z>@oromwWN9Yfk0a_0!Wm;Ewsj5iXIxOEUk4`!YZ2Yh!oQSzKG`>b>B}4%E!E60xeS zR%u2(hCfpF#zMyZVsx@oGGjrz`mDKISO|OYbp1#78qkq>AuQfTg7FgsZ)Y=deirT; z?zvs<6Z{g&ssJ7+l5P}$4^Y;djS_VC-ehu$6G?BlD$U`r3{>RE>7|JRJIqh1`2iv- zRMiZKoM=rxD<%!-vq~LLr-@dfj5`&hxj>TE85noeSyy1T`6#{e8wIipa^0R2V0do<`IqaKq zqDHM08f0`lY4_?|`)i^m5#Rv0SmkM{Fl-IL%Y<5R*34T_8mZxGp{>X%LoAna4Y(T@ z3cQZkm_weP%xZ<41#=VU4-z8Y3U?3dzd`SIvLFx*sggp$Cl{^-U|_=d;heb!_*Ptk zVw5OTvjzEUJ1YO1aw;uRoBf28TuKNzCj)|0o+X6yqBwvTgdA#MZ&dg~cLnt;P)VS& zYA`OpZW8@kwgj!^bAb)C6qvw)otO{8YO@9NeNup~Z*-}d_L-Srr@r#J`_@0GeGhXk zPvktTqO0hAS`x7l=n}8xJ(*X%up9mjqk!jsd~1CLYNqAto%MTGgzF7qDKS-Dy%TEP zN%X=e?AV;aD|d_m$3Xjw>i?soa;rcO*qm+WR|Noa(4`feXX;rg?AuVUQxhJs4h{aE zYQkYN<{15**4KB8oTvNjX86D;i4bo7x2o2!&Sf@1M$na zuMg)Zb?@z$Jol%UJ&+3P`27d-6|Y{5+BOkpWV|EEb4MN{f-UyO*m`sQZgpdM8u|gx zw+rt#B*HawSXaBf@${a({fxPfu>~k>-1g4q`h8jK``XyubQafEy1W+~a~Rj$7gB(o ztqzsjel~2*wYm z6Sp-HOW;Aa2lYc$w9}`@8220)Pc24Yq<$GM^?Mk14u~ZYL_qK_EiRrFk^JexBzpyH z?C|)|*bW{C6_{~^-2vQfykW)fayt`J`i96u-7K7Vl5L16;QZ5;kK#>PV*@KyXbFw< z@9EiB&ykrqKSPHgPhf%;J=a;re#3H?epuO|5*Hegq#mfDq7t5Af%e$%FmIB2Wuy>L zz~2>GLh!Fv8M15yK{Hx@L&#|j6sk0CH%HA#%WnC7T@} zzM@JoUP_gAbnZ=?g&k<}mKql!L zS`aWO2?$8|FpELBM{F2uhRQc+=OpK`v{-YdFlI6p-;w9_`y`5BLGp=2gj2zWkz-); zqOvchD#s$f#h!iFb8Dy7VF3gA1r?1 zyY=YKeRuJ@AF~A1?AzeQog3!)pKjc-ppiLhJm1o+?K2MMVxJtMgI8Z&?TZ=@sn=;? zafrF+9=^M17Z)&&y|;%OS5*U1W1v|_sIYO}Z$2BXfo;4upQMN`Fv0TD@!X$20+=y} z0Z4zzbLRx-ZK{}Q*!6tSu3k(iG{g^IzxCMc#Pi%efBg*&YMAZ1D`*d&Fb*EV!k_)t z{q;vk+}(6~p$&}t;@*b2lW$u$-4}CQ9qIbmDQdWS7B{TKrYi#+jc@9{-~v%hh?0QR z9}`>yA2t9&-~$hzF&1|Y{E-JCj!3Q!F3m^w4ue3(iJWQ37s8mh@4d6tD!g#9&mQ25 z&F2+GmK{yQA*8>ZlN~(u9e!3Cmy%T^#V}vsFjy$H#59z}xMkT*OuH0okM~9Qp!h$B z+kh>V+YdG6q$h%!I1@S4Z2b{D_hcL2$qjD+gMQ~lJ+O(|;cSPQ6tFmC@>J`{@sU(O z!hM!xwqch}hNex3HPYX2P>!K6l|*&KA}Np%C_}+LxD@S9di0Z3T9!$Gbc2mIDrMXg ze0_S!Ui{?w7w7-u`G5G`^Up74NtfBrQu$KJsQZp4{YnX0UzFR|Feum#h61dZ-Va!= zytDSs7P12pXtzZr!KOoj0h2J}jM+-YV?KASQ$Il@nL;JFs{k^RM&T3@dI9WVGn_$; zJE>UB8E`>JitH3hROpEQLP@3;jQoejxEuSvJx1jX|61k1pdC2=Y3o=*%qSYOFmlYV zIPa7$ky5tDsDWmgn`2RC7)jzP{R&GGjEK$gsp-zNqiTPEc&1BE4pBN8_Yl7lk;L+) z(av7$xIxrlDw!~&Dxzjy+62UoTfPSm9QT;qJ~IS40VtX9Ji{O@hz+DM@)0bn=67bR zZ6$4V1p0)enG!=JV(Fa%xDO=LE0VfJzg@{)7KVm*4ks`ku$WH}sM}$cH7A{cQWQ%% zmQn&I=$#5S)XJ(DV|HRnga%9r-_EFtCKHr?#kSlN9{e9F`I~#W@g@MmJ)@WAJ=R!~ zr}!^=VV5|gjQhf9uoi!lBROAuEki!>y}9heJpaSZJ046tDpKUBGH#>O9 z6hy{yX{-1sguySQ=R03u?)Psky=Mzv&)h2Bw5ki*L7l;TaUUBJ&@0Y{l>ojw%e76T z>>`)^X#F7wvx#lu@hhIYU%g%LFYK~=`&Q#}(5_yL>FtVN?-5r#&mF7H0UvS%;)|y* z^uxx5!N!|M?4+<1EGf_mxmlZ{}uxPD(2LlD1V?5>~14J)w&<$>q-A`rlHZvj5% zn=sfLk(`~3;kj2Itv`t!jbk)r`XAOO8VeLR-dMkvr-y;us2OQNF@^0shG9&9q6AIu zhC|*>;!<1}U;!ZmU@@~PX}^lMj4GuzuIp6)co8guZ?dvl#%YS$af#QOyh|Vvl*iZz zePE_|Z@_=>A@QkTQ7d4^4-*GMu#EBCA>h#v&i6fydq#mYAS?C*9~G$r*d~Fv(G#H~ z2tY27HLhI_s%SV-R)^$f1}e{{Br#=JWBL7&J|p+rtn3Z;H!VKS&nm;iQIi=9V|Aje zY`)ok@zdwOKY#w!=f8jc`+t8iOG*EnXkKFNTDJ71+dV{{pxE3;BG(i>(j64cjL4tC z&hPiPx`#*++Hfv)aNh=nL#hb^*^v7h4uB6ZBO-54#4(n`3L?XO;1(bPfK4Jk#(G@CIcSh` zz+ojY2q{Wzg<<8U1gUbx2SrWWRJI zYP&MW(Y)ot>>cfwc>=+@v@ePWkhJlKDe0*1A%ir{*J%733~&*wg7kp_`j)Th_xM4W z`|9d?O;_5PhQrU+-vXp8tiQeV+yR8wTbJ8_3@jW}eHaGp#D=7?&X?=()6F~fSINY7 z<|~FY=b6PH{*RZC2HQ4n(r~w zv0rgE?3js#VOTB^Z)-gF#|lV>`one4o$Q1+1~}*U{0qyhS=H*@JCEe3FFbdG z2{n;VUp*$ z12=;#Zc$!{WA{J-(PPFU8sd@OdHWe|`au|!6-?=|EnL{8L`m`ZUIp`xBbSDioTUd4 zV2kWMi7;`labtmKvUXYR;>-d?1V>g2^bxFkC}2{F7)-?6dHdRm@xeEb*$d#YTuN-L zh0P@V9{?r{JA(!gwTN_=o_o+f9wJ4oD*WZ>{Lvo}hCx$6b|fXV83G$_AQU$o??S&_ z#-byB!#nJkI28K!6yDM%l#Jyj1y6$1Haec zy(6AWeKBnN_K5MM`(LwJ1{O$yktY2BVd67e3+$0VE$fAQo&@K<1P-))dPeT@&INLDC10J;J%t zH)?}K9<V)$1XB<d*;5f*oVCzy$obBsALTh+yA zhl#jDP)Z~tf+*9ztBZlaD*};%AC%-k&CoU?3}mwTqtD-sD=4A5`UhUb1zKS~mgx=~ z&wajDcnFolU3lAk_-y@=b?x9UyWWPIa>I^&%oOYI9u(&NrWa@81KhcEIt_T^58?X@ zlwT~ucJVjN;+tdc)%&nzo_1FV=H|~gtSYGB%7tsiSDX!hxV`>#b#2!RXz<)4q&MF( z;QkfQU2K^~$BZ5OeY!q;u=Lzz>Q*i$1m<4d;KRpQ>G;BPCy@$B9>MSzUK(7Gk!5tE zbJlX>>G|Ur_tgBXtHcHZ=da%vZx4LEY3#0@#Z4=*?aBZf&mAm4uKTc4rNkw<7>kV% z@>x%R^!W5`@EEM!VrLnU<*Z&sD(BB=xI}EtV=wDIk;3f$8lMpVV;Z=APtV=S|uAd7WRA|8ja)EIBKCl(MqYX~IqJOt zEZP{u92K+h8*4$jjT?Y|bUX!#Bk7q2!NX({WAONhVHkFr)e*W9gEgKXF;%er)Y>v@ zM{_kw$#lce++_wR6pB@~5T_|4P5??`Lc(*g?Ig(<7>eXkn8y+!La_wKms*atT7RG! zP2Ds6AdZ=5R1iAN>2)G4Z;`zq_(4Hl-U;Qw934cCvIAZ>)xw&42Kqejh1HzD_(j0DrAqd3g8{`KU}|k>Be5o z1Kc;ByDw5C*9jH<{?nnmIF*-E24>ZluhU!k6=xF<+||uv_tIJ1ywa7Nj4=1R+;%N@@7|rzH%?=bVJvvvLd{#Z zE5I_uS3JGNXS((9Zig-*u{~2|N4=t&>ujFv9$HYyj<>MRpbOH#;w2`>#yiX_z|Nq( zskQ||cZ#?-5@8GF$&Bf)^hJ*$&BxwiHG?cbWR|m5Zc?p-V~bvHgTnTNOYAd7p%t%d zj=8V(Xc3hKbJukH-4-k+=rtNDhKK_hFh`+M!a+ftdK%~;T&=99BvH^nYa&Zl%DQwI zB4WVih*Ec~N}42OMRFu_3D*bQNf?LxV9X%(P_<+lXd4qn^$k*v6KkHZZ@Y%1XijdP6;AI4H9Dn z8yB>VL6^_Y+yZnY*iW{du|R<`N25G+382|Z)ba#rvrHn+V5@wUb4nyI-?;6x@Sce@ z!_3KG#8v)avfBWQgH_w}-5yA@7Er9-FY}*ZU#J*MPKs8*uOw~B3p-y}^Ij1;z;f~7 z#Cq~Z*JSachd^T}X4@;K1S^beYzenqTzu^x&UVmGR znd_drA6!OPF$6c4aW|Lu^2Hd;eIr~2HsOSqo;%atGr0YRtiO7K@dlRh5|;7)bo1$f zxqAbvulMI^l56+na_2XV-Ld1r!sdi(ao9N7#_LBAMvPL=>vIksaIb*@47V83} zgLy#ayG_T2M4lc{0~={Um%crFydfue+O-@SiJ%?oP?yQX@q~#ifMp^U zi1HddG}j-naG7PtDu@CJ)d;|e!>)@DVnB1XIuV2b$i9uO0*Ro*)ui5KrvwrW6{!9i z+isRWkdN4~=(*`UMAbQ;57$H(wN z@=Sow@Bm5cLNj1SkjyD*{xL-i!i|t#091#A#O-9FOxJ>ARj2yI63G1*%?p$NWAN+Ac5o9+mehYkJ&RLgVH^_mffd zesE>W^?$*zG9D?h<1K|(?U)UDuOijqLjr>J+e_zNY?aoZaaSSu>1J$TS%OmC`My}BgR;ir|WP3 zBg%g8Qc@d{OyPh+Vco4zAUcM?GNP3;Tn<6)4`Py-rOI6ur zwc5@7{o;NRL6x2y$4Oy=yN|C*)GQzs1%$u`#X2}s)ncbmKdX<94IDwr4m5zaNR%&J zdhWsfUKh-r?(>?gzT*Ns3{jh7;T6+LCv5?xv{9((z~^*`zDYmg596H%0xp)C$iVVr z?{W7dxO)h@OYdG)IT*2eowg?Ui&chVfY-+#WqIrz^-i-3U>W@O|8#y@QiUjpK9aD} z9As=!Je5wA%k2r6ON^5mArLBzSF1p04;YbAyjy|J&;z0J3?w5-=2hHyIFo|b`HK@n zeSq{qG%lre)<8-ZCQ}Yq1s7P=pnB<;2>cj#X~P7_pYk30Amu^yYDGqvgzkI4p8MOJ;yCqFBId{`$e7_p(u_sD_xv5n!9HV{6&R%lrI(N`R$6LJ{nlLE;bqnMFRE}!Mdx@z z2ub9$Gp~^K7?C(>P3o(*=Q}=-S`Eydx!U|QFq({>@i6E6@P5a*7xer$aP%Lq{+YF~ zxSo^kKGkv$Hyh3!t~U}JS`Z1*7B}zMI|}}Sze6e18%oBS<;}O>T^`20zkZ*1fCV#k zso%2dj)S@1Tew;HVg7KVdmlG{@zD*dVsMt+ocS>q->#oc9Bz$BL(4_KbAH0yvDetG zd;Y)`&)u+P{C=A_T*YC?>ALjcFW4C%1-nuueG#_B%QV*ippumN+ zrBgwUz3drxVO063#v)V3bFbIYHcy)uArs+lDJ4LOAgpxp>cnN=UvudhcNEn{iVVcMEwi58P`3Aptl8N&Ffuk;|7EF z_sSjV6MoTfQXIkCg{A!1Xu=^GX3J0LQ1Ws$aesYv>{m3g4q>?BFg{(AOJ~3K~&Wc!YJV^p%+LaGBS`IbD1WtY8}CMXpz7L zH620LU8)3_jC7nv9AU0nN@-C05sqn~y04Kgyn}I<*Zzk;Y?vj@H0og8A??FfB|@NV zlf$9p^$q}9!-j(h`!ffG;n+oZ?8WKSqB52))1)Uc_-Nmt#m+4S_m5JQ#010eijhd9 zpa6-B_LCmpR`Qy=fi65~2oDh84Qbmvs0T9_u^gb1<}LyP$Sz#2KU=1MxOs+-d9rZe z%c><9T>SVi_fF3$)D!&l?37Sxzj!>saUj-_glIe&Jz|!WteRt?T5PO4BBK-)OIyCj zDP@R6JYFTwHD?K_o?%vfRGL8yF-?(8ArR;w56Oeb)!0bm!H?(0v@5M1k1M+UrSJY6 zuD;G7#h1=7e}MPk6>H8{64BkTW#oKPrWC;h9jxvk9>U%mUmxuSP^<`+t~IZO45@!3 z8)^NUcZ?*;9AaQ&%s*RdF*JGaM|}Pkew`L6#@t$ZtziztIeE*R=MMU8eiwoY&hgjt zzuvH_PV!dVaBG031So)qB0+ zWl|Ip;h>z}z~K!6+`{zHET)#sO~INMlu1q1xEcSmg7J z1+Nkw0x$#pj{#lrG$R`|$UN^#G>O+FL$6FZV?ga|4j?)&+LRtl#STqrRIa2<7S?=3 z6QTLS2dIglFy0>&OZZ-EKt33oS~7qMi(rq`=?D8p>|5XJ?N^DuX~`FXne4fs_)C~j zjJt=q*WT+r!E;Z;mig{4Re&g)a!&cbY{V>u->qy~7Qn;^j_@W&K(q7t#%PP$-FzI> zIN)%-aRPVSr9ElY4do(+57|cJH#sBai`W<>!8Ll#vPCRm+4f*^_QBctIa)H!sd9`1 zJId4qRo%faq6QMJFD!f@fV;+E>L+|tsOUB=@))KGlf*d9Koip7w$k{B*;E5VVnWmw;H+E% zGmdIHy`)VRl6VI~izE~Fk3}>gVF4GNX&||Y<;HK%lY)TD6N;4q?8)>p-{Y(c4I&?m z%8NW?upA{}{b1y4%rRS^)JJE;h|}rr>DSL+oSi@a8lixnV%=$Q_{GI>?~~KfF?bR9 zkA!MC7MTbnCC~y3Y?ye6=eaBh9VShKjxG*il&=;gHZT(tRlkV{>oJPV!A=CUovvjx z0V9hWzf&;rwOxzFp(F!wXrV!ZiK|gKp@BH7`P_@o2@S znq7d(FOcvMnWQ4`IXl2}hp3L!=i+GYO*_V*weWzwr7?GI`ArTc539G_yK}#Lz(4*2 zhHfm@*EyvZ>p+F%pbzgnS{zS?m1)UaZdjGmne)@Nigo`ENzqrG4J$D5D3h>QCg}V;niZ_UI|9|9 zTBJ^=QW;e6)iLaoUcnTrR{E8G>4MtKCZR3zAflOxEf-8e(mUe6nceRd;C_R`lbW@O zjAJ;_#Kr-YjO#?j-CptBl~Bd4kA3%-3S457w^JRaxC9~)@YP8PoiprIFr~sr7QaQb zJ=&tnTn0=Exk!A_5H^O2o7Pr;jS6%m-a*{ab&1+d+I=z$sq^R7kQ@Lh&TRe|BYSZs zls!=`z>RDpu@z%4X)A*#3B5YHE!+c&BJ&2uotN3Z`TbNn6 zMUE?{au4Gt%fcs&9UW+?;$*^uID(3gg{@IZP`@GCXjmO;Q-KE$XaR@|%u$VT2WtS9 z1NFys6{p*t**}LV^G*?Q6JbSG5Qlm@SI&~AWWE-AHH3i5b`XeK{wvJFB0Z@XCN~#5 z3dg8%?hZSRj6sUP?37qh5nFwNXl0l)hy#VNCOq*>12PR#qYc-9=ot4DvqU^9`^hiTgJMd=LsNp<3eO94QiXksxAc2`$1{K9$_A!#bNNZ= zu`%Vs+&wSZCrY!?n^~;mci&on!?^C|6XUr9go@!aD#?bs(4%5q26r86xDbN;!{ zWDA9*5k_2w#!-52vyMx?ArmA93^PrJjk>V|I;J&-xSnbp5`V6<$4dt7q}Y2H2-C!Fcg0 z+01w@gb#y$hdg)SRB)N<`u&YfjQgDfoErop`aJsL21dz&+@>Ig+YAT|x4>?+iNQ}M zqYCC-6lMXL5a*`TX@lNMu-qG^W`p>@(d5JC6ym#N5k18esM=^E8f$>M`%HD4P)4Zf zDXJ@xEvg3&o@@~~lBbR#t2FoA)4?_4xdS+?Oy~1qdgV6(&+>W=Jze_Ulp#`7395@> zg&Roe)>4=3XfT&V&#K>Mvl-TazTS}H?0p)(3XO+P z)JE&Rjgc-3K_m7c zlmg1hOZwO2w8P7hC@m9Hlq4hGySj>GNS?wQ6p2qo^GYLv0pU`GXu^WFrP2jFmW-kh zZQ}je3a&UhPkXX((J)i7_ug% zLGH9)7@`ef2^oimh;=8wE6fgM2Er2| z&XoxmvNzjdETo*zw3^nfp??WN!m$Lhl+mPP@6YxxMqpSwmD8`De{lZ!KcDZN?f%8* zpFcmRh3yOK0&E(nsA7qvE#7;W`ceWl=}HGT(KS|QE3qU^k~)%NieyBcr0yXX$4xxK zSX<$Z8Ycm5N$xzUXGAqYV(<)d;c$rdf_<7uZXH7kM)TLP@OYM{=atXjjekIXVBz0- zf3My~b7iqA#`KwRaCu|KbLT>!yUzP-5g*=hYHZc6j5CdBK++@sKSS zuaoCsn$tLt8_MG%2FYLX+|5-GIox8; zo}M?KSHFkKW*ey&`v}=W?v}|1;`n7m zR?ERr?xRCa?sLB(pC<3{KFSUd^xM)?qQ$dAgAExDmTXkLKd_-%3C|g4oOaRn{=NX& zI*R5aV0agl2T}v?oC?daMrHwj#ZoLi_dw9FW%8ko6;;UjAierqz=zQwl?sDVfNh`B zDN-w`gd=W|@=IRwObDY8!nmUf8>G@{uT{h%2h&M>=r*mzXZApPD&Xu+ zL#D#kHB!*IH!3BPu4|db+GsIuZ%1b@U>DKrDWML81EnC$Qr&NW#z#Tjk;8>EjV25O z=hCQx^dbojxJo267!mr9AckdtYtp8inzY1{Dap<=m^^5J2sylDmoA~uA}Ptl!ADa# zZ6#}l)9rWsvUEA)wBv!{G}CtlNIU>0^Uf#8vQ2gC48uRl9h7m$Q$w4PY8?uMxUfWy zQy@6N`j#Wym?#Iqs)+OY--e*Ty3rmJvAfH~8(?kOM~e#{0qxk3=0#VKiD(%>Zu)aW4++z9wZ^by>S zXb^+T;1Ntf-z8_t6%(Do=(44wtO{XL|1M>3NI4ug_Entia1gHNhZ%R+GWV}Mv8E98 zk#W;~8KU{S#=X@GJ73LDRsE%R$%kR~Av%Ws9xi~%i#vIhsIEWVxMTVGZ;^9ki45;v z$_vQBoL>+!TkkG$A{o*7i7Xfz+BWX7W&98B;X!*dQeya-?u*^(yW)oRuB#u#`7xEPH=drfWwaKHK&o|x9@p=Sw?h0?V`rwA`8uy$$$0BH zYnp#ewJHyMfIA+E5S&j=7-<~7gf|vZ&1_M-?@mu;ks5tzf*GO`jvqbqdURhx?-C+R z40%VOp@;<-Gle`t^SXVT_#dYb9WLC+ZH!t8&S^p2@0dIvq#&6CzyMC;f`e64PD$B8 z?*z`ggyS`R8hKw}ZAAnh@g79XMu|L!Md5Plw?_gDe96z8y?U z!+>@vAWAx#O*t-F@>7f-UMvzoeg!~#ld8>}sdKRc;5nk( z$-GpP-=K2QFV8(>Vcj2bxqtol+^yU2KnYZlq;W)qppp`8Mpzy$tck6|!#z4BF$v66 z-5(rdKY2?q^E5|A*`4e#N5%gli%9_p3rScyRKOFIx;sRKraGz#GZ`CmAW&MhqH>Bj znsl|W0V|$+w1kPsh7pflJV2|%fAi0z7zyi>4_ zbSEX3!lPPjy1RG&_4x-ETx|F7$&)RUhM<7!@bJlDci2T2YnK0r%a2JRG8|?yB%?9v zBK%7#5v&iF7zt#GL6ho1*zE%6XAy!NtL+;VM3{GAYQQ5UYNJg=UJkcP3V#TbScQ8I zAA|%3yK=DWCTYq|A`~JP8vpwJ?eV_apgtfYN@=m^K*+GR;*zDSdpdu0K@m)muE zk)M9?#n-2&|Bo-eK0AB-aPNYYP7*uJf*z3k@EjYWAT84#Ol>3_A~xyqkWYXTgM2;t zmdzx>5wwQK^n*Dvo(e3jaO@*;$m*fWUNW&7$L1LfS*6zAlX`_hDZCX3KhQbDOq0k| z{*VQ)`_W6=`7Mcmo8`_^87P(&&z+npCg@;gBal+B6O;HX_YX{M5ZW?V7CGlP?HCpf zZ}=^7K`4%z+jGys^p21L8(*SC?Bdzt*DDm52(U~}4k{WZ^X0Y|5NIzqt;)xdgS)J& zR!n!h#EKAH?c9{cT_1y2s&zHySjg`LNbTJFIjCSa6 za7IhaU1n9EURxqwWv4Fm-n^aQ4X5W{@!aQ8Nh5yKeew4Him|)mxxZ?FO;W>n?wD7e z6^+x6bb2fY`N8A$ANApf}^&h?cqaU&A?XJ{DoCI7u^s_NE zUO@-S)iKM^kXa&kd*FYe6CjldQzPCZpeIUf0}WiPv8j?dqiuoXg1q99JcLv0_$!=ibJ#5v5#TYAZMFF5b=b4 zTX!X0twj9?7Z}4U3{j`F6i@cK+4#^XF%HjMV+Nt8Jwqn$vc*TI%Bo?+rl& zNTJg4gmf>iDW;T~%yymp=y8MgtxAqy1EH`)NLkYtwE%C%p)3=gU$RC!6U9ZQG%M(f zIN8#mb$D{zmaa1UA|I`Zm7NkYflz4j1<1xMW8Kqf9QO~S`vchiR0-GOc*@K!C>db) z=xB};PwWJfoz2o1GZLn-$py{0iC7LYKARxiUa6nJDhFN?J`onbmAa%e@G002-?Is%pBL1{oKzhm-U&tR&lvAPP*xNsg=o*vk*8a{e@joM8a z>`)AlE-!>@ABIn*T~?=55E(3cIK)-kBL2Y2k!g=1Gnu!-sd1yXr6f5_QIHr)7wCz? zScyJ+%?5mz4|1)86~B1C1y=a+y=QMe?NS!+H=k9X98~9+yG+o*L3h=4=c7pH;OVnx zPf>&pSMbvI+-J-+cD;fEd9$m{uJ=nYUnycMldnnO$@ao^=@hJJdP2 z_w3odgU(VMjd8qodJN*?OxcDz!r9(;L$$SIx#^JU7({&Q6rEK*l6ePLxNF-~8*pe)f+;yfuV)K}qm~U~piHdHMVg z*kMQ_O==tpd*&F1JDRr;XfQ71n$k`>SA%(t{mcQxU>&JbVlo)?hQq^FVFIliO9@|s z1-F?uF{%6|c~s*Qse;}!?bra%bH@n{1f!-|hxI*;yRZc5k@vU2kpNkkd+=^$!+r4( z;)yoY<TLU)V&A|_fwXDHAkoDb0hI0(W$!^UmG-6wZwxD0-b4DCnIZNryF8Xsso zPeUSVcCegEs0wHYov#7lm<1O;IwqkCm!B?LEkwUK60o@%Mh8d~eD?9jAMZ}{a8+{g zO*~lLSqUqRmCILt04e~MK-O{mc2f>h~^0~pb6k}a4V_sJ%Q^) zl%#xn9KT(ndRams36k1Sftg(5VeXiXR>cXB4t3Z>IRvq&4a4X)w4)zp+zkQ4d$(7< zLVM8r08BRj5R1LCe}1zVx7CHtk&z8;Gv7i#F#@5G_n$%4S^wIOwGTC&M09PjsXh{1 ztMAx;%!T)p`O03+O9nj*zpLFGj{t!$kDHJOmiS;$-kuE_b;2(EF}%R*g`W z>+QN~-y=gEt6w>DyN^)%})D>~X1)w)O(u&zT6n^ft zqk#5;3_*@lM+_?Jx>7W6!-=4c5WPFFlDyt!#oI(>G{{r9jZsI1AgtIME*t&mgdgCv zaA3xT_ngj0ym=07+!+4rzrfP})r+PXdDkbt;P7sd}F^M~9>R zJYFfF07fwluI(~);j3mLcer7C%+f*BisG3M3ym0?mj~1_L7q#;vkicncHZ@e4K&?v z;{DDpUYvjN6I5n?|Ig1WS)ivZ2rY#?f~P6QXTiop!eii2%x%LmqF#$$(&}$SVN-pF z4nc^(;7?l*plSH1oP>9cYCL^9*f?g%E#(!|{=x}nDty~`423gkEkZmJ>SV@`$I1*P z<^E=&lnoDlThcN?i{uBH(h5X<6<-E$wS7V7voF8-=9`Z{gRMjC6bR-V;N=KT{TP6{ zby6sjx#VHs%+jc=k#_7=n-2HSPksO_hf=o-tb3oL-3KY2G$1WID!DM8B9p#6Iib}H z0SLDiC3^&Ld=`IY2e`=GTv&;)W^?okPf>cM@I(1pCMoHOakWsH>?43DrcVSMY{~Q} z)q0c!0%Twur5WJ2tN$JEFiCHR;VkvI^ZSHWQRe|<^|YpSa;7biF{V(}Zh_UuLzy%l zJ#%QcFaZAw0~djJ`SM_8Qj%bTW=f)!Q=CFGa!XukbHDimi`Fi4PqO?s?s&ys z{r5RN-=zWkV>=9ek9A+(*Q<|m#e%O)5HIiH<=?Mtr$1ghy=!Z{yo>*izvFQuiide$ zSVYYuK+dr+BCZhdiVd2}1)0Qg2?f{+Fc)S@esAxvRm9w6sK?)?YXkEnyTLq2_9I3a zX_}G|7fD=1NcQ&jezu48ru+}VD=5)g#^bfM;yY-dfX-_ z+zW+`7>#TI@U7mfZC*IIATsWpI8Gd%d%6~#?Y6dxYv{Ru_jf=_<7G9FKw_M*T3($m z9GxZefC&~?BI8bLiuNoX=3K(4*|Vge!_f|Wr&Jc(Gr-n6)kJF3M%}jxNjhq`5p&0| zz_N4uL%Mj+VkktEb|6X4XdOzI=`XPCzkmMu=U)tB8)o_@@j$3xa(tU8Ck9fQKs9iv zz0+30O{LNZ@?w%}`H$$<$ym)0GpAJthMj?eWF+c!cMHl6qBc36TFE2}5+Nc0+6o5p zyPu(F#w|-b9LU7;U^9?K$X7e$s}(^Z(#SGKE^H%0JMvitRr3nb$@b<3$;wF3+5Pg< zPe1+g<4j75FJXiTlCa$oeL+@D;RxN0AR5s`JRe0t0v)A{JW*QDQwDMq*^?ir zE%V>;?S8$h|Fe&PFiwT&-Z(%7RyvXLP^vX4$~ab96T_y3;N3WVkO5TyFKR~-g(m(S zg`o_CK|Bh=a>of#L9U=5qeX{J{38_k>chPgVrzObNqM7%j!BD}kF8G*+0C(}2_#9# z!2vxC&!YeUAOJ~3K~xHevj9hUzwtq#Wvi{RQmOJ6eVEfZ)Cf+)Ns|*LXrNtQ%+A8n zp?T5_|14IMgdo$xa^Y-1(tU)DNQ-C%{*q>vlEgQSol17rObT!b@t*P1^B}@O&) zrKZ0Y1RqF+B2*;OxD&{!KI}k941vm5>wxNv0XphMH(E=S+o#oOJ{iuJLpN; z$-~&B$dynCb_qEHfzHUKMDvu;2qvDE{oDA|nLL#6Ft-BCjGF%_ZZcf%9;gDou?!vH zI)MmeMrKOf&2kpBIJq%K&HdMS?g?x?MX+jbJDV}RrxN*KaQfvpzxc&3KE-#R(ZG)x zIL+NsoZa*_gHxUpO$##KcK+*zIz z)lX~204PULhjSNQkzWD6;6|~KD_5ay6J1F_E`lH!JBgGdua9&9K}Gyzz|34vV_o`Bm#5d!6TqBM){E4}`AcQXFZZi8N5|DSCH zcp)&FkjsQe3KNcrUJaP&8F%b95InvjwiNT;rXCNk4>wxV1Oe}2o-pTY%qdO5T~t8& z{mKZ%D|qncA3yXvoz8Kw2qzwsZjf~CVt%1MO#63PWWQODb3*@xYN3w|T}EBkM2Y5a zDqV?z-*ajtA;Fks+>=DnImP7@s(c1(fE+4l=L(rcpyMdpH;($ z(tydJTJ`iA@Ou&o7k>__3@v_oTZIOH%+oz}rwCbcGwQYrJCmsmVrw|lm1fSGU3~F> zVA~}kb`B*Q0}bqJQ$t_sGdxh;_t)0OYh&5Ec*u#At5qxwx(&3XvUT2Rk`P99%K%+U zO<-d=*(CR?QJjGO4%*B=823aOmIvBc!Z+eL!oXEz0HkZ92|(^P9x(F)PG~ZPt1B2e z=IQ;u|A%e)wK>0wj@BuTDaAU;=yrPg<)?r3SAX>jeD`T|8xY+`sTGEwicu!EmrC{CRRMXiN9W3t64$>Ael-XnsH z*oOan_#CD_in3$d$|;sH6Do5QZC)!V3pC1P?Kv{|9On*WbXw`FgGdqx5aUjOq?TYj z#v@Hcz~3x@@|5hFG7qVFR?CYA`MW&Cuh)4!0)LhfNJYnKy|3hzu z%nRoO4G>F2Lf3}0$ZvYTbarG*R~~A5LZrz|hBnf45;Fg&N-b4O)qbg8YD<`vi2=74 zmz{0dxt8yJk=g{NqMe6<$z+t1S=VCubJW&I8U}Cx$6vG$ifAC&1LmhGx@lIhox>io zi*mgP7&r@&XDnG)^1bw>>h{R1IY9ZC87m@1!den7-xJ6o=vn3L{T`%0raEkV$z|LS zqTTB^+|A8k)b6A0W#jr$LJ8ZWISWN*FTVKw?|=9F_s^ey@zaal&$#*-4LSz>4n1ZK z%YD=@7K`LjnK5(BN6c9JBVznIiC2iJBv5g76Lh!kZ4C>UT|r49ZcZwfW*D1D9<(ah zSBzW)vq!oDCS*EHc|QXBz-9QxtYLud4A8qeZV6HkV#~{Z%2Oj_dhD@m`?HufUkt7O z6GZGy!|ILc$KQPV3yk|OzWH+3*$(;>fz6agK8H}e>ddm*c@MzIj$)C?W?<~l{-R-0 z6QL{VqXE$q$r`WM~*9@j@kGODYStJ1^VbH zsS%lZu2-r)5J{7FVYdf$K{=6%Jwch-R017U$6dRfSG$rYAOR^E?tB|I9N zk{OCkv4}a^=Uko@g_f+2bq|FeAYB66#?)7$dM%h2U{`NJlz3Lg-R%8x+wcC9G44?; zxP5$b*lT0OVJ$qsl;Eu4wChw=VTi2*J>s?J#mBDMB}mIBC!M0@mZ_)AQ8`0uh$|zS zmw!hqrFQ*ftC9T()H(r6kAyB(1Q{!|+ehWRVfbOxao%X!fzipwNHR9j^TpTQ45mrT zZS_gNalGc}q}QY=c4qqGi{Jg;`0eN59iPoqHV?~tNb3&d(J(h?>438<|2(sCTPcvI z8VNE?7Z%~n1);`fg=zsw*K7?ZtVIPrg{5Sl8OaCbVrNS@Ikhyw8r(f2ua#3(KRAin zjN_Pgus`%d$r5%jGBHc7Q#T+O;-BU-8y~`zdH)Zoja-0fAsTfX9om{#noc+s5-Nk| z{#U>Fv4x z7qoPt;D(l)$&xk|t1CkIg+7^55*8Bx=f^K`YLZ|>Dug-Q>Njw9B>| z4aKkPV>6AtAAIxK%Xes5z#n2dRAXg8sE#Iu5vFo|0OP zYJ%_n1ixPM^$7fVMu56QWDxMOc-Qd8KA~MP=`(|Hd)A#_l2@f~_XB)(??~E`n49x)nT%juV{V}3 zA?OM)6E~_WyuT?zb`Nx6TA5bcMF0;vV>a*t@sJGxl0Y8AfWMZkDGAr6VPFFr4wjou z=Hcu~$u>u)rdF?%#k|yT?IHKsR-|#bW=kXkH-Un|GE{`$qd}aU za;0^XYYmu4m|cnZU|})b$(TbcIW$txo3(Le3AQvH0lBO560;TD%t%C125OW6xPf5< z*ud_Q!^RWF_#xpUA|x<10=$SXM$<@pau}3U*0AkDWrWLo^RcxZ%#3In=Wws^|w(>-6njql4GG~GI@6>yy>uVM)DwsT? z?y3&=bj`&lkszk!s{bLv^%W{KED}RjI*b#vd=Fm#@OlLPm5hL(6j42mbw{Eb!#yTn zB-CYL+{JEZ;mw#qdEp<5yrMcS zkq|uo!>(Vug7%VAfN$Hf?ohr_;PxCs4g-;J0|qyGQ&Uqm$RrMQtX)Aj?Jo*%8&p3U;MkDUWntUmY$jyOVGO&!$@|KrTwD9 z$qf-8AMNk2#c?N*P=_t56Ry&mPCyF6h55!YDrHz{I|^yYhm#s}DJNBT(Je}vv>vrg zhWMDm(9n@0gtf9lfNjTQwE^d+WgpZ(Y%@2(%7ih0`E8*xc=8*;?M+0nXgP&-?{MHk z@r40pjB)>RI;A?boOQTwCV8o5vz%3!gd*Jr5tbqE$ic$kcTj43^wd3Gll8=*rCn{D zRu@&wcZ+N*PO_OF$db}h75tw$g}cbLnNw7Ybf_(yqhK+#k3c^fwE1FFuo;H}CoOt@ zG>>bFXI^E30P-<5Ue=vkkd4T=`w&lT;;@01g$>_LwLP;{|h$TzAXSjO+uPz(^WN7K|r}0>pw#?Wm!GmeFSkTN~Tt zkhjP0zlU*;gfZ4>*g#NrrkS8xNHEtH1j6n=hwUIzmWNW<(iUKQ|JkgAHVT zNZNuI5n_Nw@rY!w=gB0(?aB?P39!h2w4awlZzmk zHbP!hl9yoI7SBx$w;vl^<`%1f7qTK2n@mEUI05HBOy3a*T@s`LMOP&-^8|m!b4QZj zh!0SDp>iqHBs=TCdX&uv>q>y?Tin>z)~HGXocb!*R6L+H@(K0@s{Ms#J}Z$-dRRrH z7pS12v`J8a5vS`FZO2-qRtNi%IHjl?_7c;gmqz-5kM!%!UXQ?^W(2~Hf?-S@mVy63 zZV|BtzBWgb9VJ_)Kaz%XES_Zk&Tqyt%95@)EEsq5o17RCEP+NKAbRkP7<#H1A*R*F z|EPE?!GxzGbKEC`G4U?X{T3osSC{~tY*dNkHn582!<$o6r}?CYJf2N ztYQo9JnfniHx6dkxl7HKb<~kXMABB=X4NmOyxr z)S`_au|z82&|Imob%@yp)Xt-(jvtGeV<$8h0Z$U{{(!O@D`XWr@D0f<*MO3R%)mp6 zGtNxX(tY3nS!^dN!pKb8Tq*VljjxRwhHe|j{k>E$5`iDIL9Q07nTZ6qo0ZDWZ+`g; zlBvJ=6x;q$261M5esu38e7}KN_pp87Z1Vvjr=DNXVl1JP- zmHi7E0vqC70;VUDcBMH}%`~XiO=NNsETeN1!4gS{W>d2Pjybt#gfTKMD4|njL@G@h zj%dK(hmF-2ia8iWte>%IpvX{!@!J7lxa&5$sEisdqBKp_Cxf=j?7l4sFJlo4;%KbA z2!EOv_4Qs~kHGgG0iom=X^4YZ>RiGxVu*gvxMSIQlOdL)|Aa?HEoTfs#EMW6iO+tO z1__^1AIh?`O9*383mHaIm*6m`l6+8YTWBI40)%xwuazjloOz$l+u?ZHM$r`zuw2_c8dBI%Ct@^v;z%O3PYba zEQNaO1w-^2qJ$pP0PIr+dM&Pju7gUK^Ss%O{&2EC1JOWSr_d@;lLg7B0b{N$h~8$_ z8H}S%xQN!8^kl1s_5m6pxGETchY_WX1t+C)0nj5_f1>oOMx~}w6CV+?4X}$`iUZq4 zF6tVxE65R2(vO<2=sV1v7S&-i1%#=i1{FA_exG4+;!iTa29U;avVg>Lf0z4+#vPe1*y|Mi>y`pq|Aem3<(brdjj#D@F;?FI8H zU>r(S&{cO)Kp%>L!tqT!@u)qOnlkmy*vCvrN81L;cA<`Qo5W4Ylkw%Tq6mSqBi&4r z^U5?Z1GOrY<3jh5Z3i7AObl63XRUfnsRX#hETBcNm_wpt5bR1UI& za+3=PG3xOlG0VL9ve3qct61Dy!*lTGrzg{HKIVPpp=Sf$GQCZXY&w=l&a%ky|INl7 z>@$q}MIZr*hyE788gzZ4>ls?C#Q!_|IGNB-xi>1(E@W+9+^8G@8c#`lN7*Lk7c!C9 zarJcuRdH#j1F!_|flqUq?i_M~0P%`icz-9Sy+%4^AMXIW06W{I0=@XCzf1+}YO7VU z$w&rr#S>Dj8255RB3eAz8gjm*+i{OD|wJ@ye5ybc)WJ@VLvH%8du;~Cn2WXQ? zRW*{TUk8)ZQ^+)M^=NAjK)ohRpf{M}qv}pk6GR@=TB~;Gv0A}dW{eZqOdl4I1P6R~ z%zG^E(5A`D0fGyWZA6$H3z?SV{{H(Ln?6t{M6+=G31estnmqcy{PI(z2Y&OL|MK~7 zD*dVm{nS~(jFL&+#JCHEA&afa#J^TNMvK2Ro5seQW}+j1O+CRDDFdVzh3zxMX-8u7 z)nh=CNrilCV1uVkj|66wGB$1`y+#b+fpd?rFOw2-2Rw!x6!{v>b8M>6N5-8pF7z;Y zG&u)+b?S?mGLee}$`||&>}H7VY|$?XY-bjin+=RZyFexrMCft9OHDE6^+X0zL>xhQ zQB3jb3eV|^%qg+@`Rzcxb%|v#gvu4bX=?>V5#1J^94(w zMXsT-{kUp;m&f+fcHi+=ZOJautgg96h-Zwtp#5s;xHoDEqmgl^5oxdZc$XeH zkfy!|W;?Ts&P}yn%HukXJPc1};DjdN{pSolxuv zr~xX@sfS2EDzl)pWEvw1W8a3XL+*hdAcFD94TuN{S%&UJL1woy?f!6Jq3e(}&wlyK zPk;60$1f_UJ6&4ibuM7yGf!Y?WvJ;r7yylyBfzC#eN{{LxX4uhGYj2Lo4I=sF0vQV z))Pcb1b>J*Er?(lvEBs!%NQ@6kD`uh%IGhgiQo)a7NG$5qM(Xe@xaK}$YF02afsEr z_1d_9#~1kZYJa{Fp!b0amW)`HN>$}otBTJ%1I!#h$R6Y2TsbKWJVeN7?8=AUFC=KO zC{{#Y_B=U;Bv^pAh!ZAv8XLBVOC{(j)?V$dMJ$gINk zfew*l#2#=dnx!!A^vFa39YYAb+HUP3xhvZaww!R-C2BXx96fu;RW{2x-t=023Z;GO z2G>T1{pl2+4aa@hFXKWIrZkYb!mcJlvE!4I3xpKY&B{)zI;QwExqVbR+Z*gB9ZY`0 zP1NER_9g;fhYl9;D9z|N4`}8gf*~Rase++rKC)--t5KrUxC&H1=uTJh<6C4LEBvR^E8F`k&}FrqXY^4tF) zJR*b%Ou!RDib6eYXP>|gE;pYe$fEQ^&q6qmJS!sUwXj=XVH418wetS{pAfpnOg=x>g zs@&GBgtP#)2{mM6)M^7Unjq~{4Jn=rQg=o44lw1u;Px0oz!+Ui#BZu>?k5|;xK9ob zC0vmqDNGzih{J>r_BQN3K@7Ee_3ilM&++RuUXQ?^d<4M4VN=U{Nu|`xBSc#=<5_cL zd9XE|fx!30VxD5wU`DtC%4ogCVm$N32Fvf7CA2KQ&wp8L^c}yOt-LQ{U6Ov3=Y}`8&E4v2K8><0djx3xKWDd~30fj(h!s!?Ue?pRwq+>*1$L&U)n`w!^LdKzu z19C5WlTtoo$ui~JScI~b-=FODrx~~=vqGWJhB^*E1Eglu#-Lg`yLU1HA`c(6M?00Z znmlNGAB1Q>N_C9iPr8>3|&F}<>(m$yn;>}-^(+$4Q)0XT97u>pBU^Ns(gqhyzgyPyq%Gm&s`q+c^Q zQ@3Z#UM8~rhhNKaAE!4G4?wp$n;d6O`O?Q<{_3y3`FI9?4tr*bO8OasS@lj4z@F4Y zlytDM?o3P$a|kK+jLAcyjTz&CkQhKB#lF(RpWZ8ta(29hEMAHmJ2RY0->>Ts}GALPA>Sq_9RZdSU zyOop41$ypGdU=atHF@pT20CQG@DcF#6d-<5Hv@OX9`s0DS1o9cXeNjqwi(;W(!+2&U`+Aw|f_P=3oz;So!5s{qvS+UeukWg@N&O4Y{nwQ>KB@9*o? z{(K_!p> zX5j~8N+8Km1?eRCIfnL$jJCiCvZtfH$&~8T0g*dYy(2Z*>z5HxAvmwLwvdD201kGU zqNbeB9<*8rs`zmo?Vj|wNTbq@WcJwwVu<{j#hQ@|+@>Ez5K;&zQ3f~+@*w?|VzcHk z?OjJg+Oc>M3v)l&;!GgY#3-{tM*%VX)&R`{q&S&m$%0c#>9au_h#*vsihGSetOdI- z)t;O|q9Ch7p+|NfEP860^3+sHRZ)=ytwuIHlVlks#5FV+}R}1yvuyRU|!v8n?0y%@TTI7*5WV z%m$wUvuH^Np!B1U5BCvT>XeHjd!YNrVYst_OvL3(C?lq{p*sC&c2VCuzxe9(>;G_m zRyo)^`{3edNaN5b;1fYRO|`U*Bw}eAKv84CW6J%pd|+fP!R=9zbwOoNy^GTy-48Re zzJn>3{>?ar@+h1i@OLqjNbk_XrLZ&Xh?qJ?6dNTb^!z0xrqToCmNXB)Htyg4+P?nl zzrYAU(Z#saQHJI6@VMTWzZhr+NMqHgFModZLmg$WIK%o!03Za!Ocaa#nj>C0%;GQK z{(ZjP{F`um??(iqsJ%CweLO+V51Ymz`J)UvE=tJViS&PdkoE6P7qaH9G|~e-Q%6W=n_leL4VT5-zkk zY`Yb0QxiE$MkA=lBb48nLZp+|zDvuXy|2IcG0b;--p$SJpoPPXUa~U0$h;d>`6IHh z2=)RiG)c_jN#boH0=ai8CZ%DYnD!E_k(5p(-wZul=vN>;M(ABKi%v|lDJCjovfweM zH^@H(0ojan&+$R=oEz`sxc?zlLr9D!9QfZr+>UP}f~d?dr4|Mc(82SCQJ78G$%|2o z_DQXN8<8y@7!nf>eLxr&sDM~dq$24$h+OiT8wfm*gpGV|+La1oYBO`H!?l6vh$mvs zjKBu0NjU;0Cf8wxkp8A&BbGB$3@w%YN^k&|Kxn^5Fz|!}#FgTY;xN;dd^9|vPhV-b zeR2Br=~q8Sck}$GKizxs!9PDgKYP(OTGJBl6vA$j88|1%i#be_5yxtlcF2d@QBuG7 zDkOC2qNvV&$n%30p|D1+X*gifJMh%Z(>$b)>%%45ILpk=8=af$l>hB@{z0-@@h+J{*4X zx1>}50P_(lsM_k~5?Q3$gPD)N{PY*!0LLKMpM`KlWtyeEC&Qi{!&<8NG&zo`1Q+)H$-s_@UL*23?lfnbwuM$d*`uvG z6miPW@)AEreGTbNRzSC*$B{%GMV$sYWstX2AUH-4ElqXrta3sp+U`!}?DX^uN#)-^ z|LTL&y|2FdKYsUjr<5XG%*t6y+Q&>iM&meYN%SBaNxO+@|H&TtiWv1%@Rb;pGz`f+ zncTwONyVnoHKnm|fvHv?VQ>NA5*DZAaZXNl)NT(d5`=mb)+Y2m+ZjwzMy7AA`I3HZ z+`so*{Ca~w^$6he@mykwW!x}>H$9{^{xmnro;6;8F~Z_+Izb76EPQ(~eYuyis`CYK z#2n>^8~4SY$f(L(u<)jmf21)M2NJJ`MMgQsF;dDXC{^e{<&OB}o?~a&1RiAxzkNis zO(O}=0j@F#It@JUSQ&e?(?XP;-B7wqdo`f)JnTn$_9UYZ8hzZb96yYsWJetYrb^E331Y53{s5FiJDV;hQ5 zBbv9I#DiLN>;ujL(>NiInHM2H?5ey55CBYAmNOW4kzYq`k@_Zr6(Dxzg#`X{(%z>h zQUMWSy6HibVa9;f!mPo6T!>ooQS>Rz{odcmbN?`dor4vW%_nJkkx6e`AAgDCj&a9l z2cwQA6A`q|!$_=Wno(pdGnLcr)k*!RXgrRI~I%0@+}G zM*54qIioXqfo=ck`B$GmfBwM-dpr7me!AOc8YREt_hW@MQp){`p-vujGgn1o7&M5$ z0^81WV$pMnJ|eX7&4t@waWkP1v?Gp<+FNPbbeNsl zzu5Zp8d*M*uYY(w0{==zfU;5Vxx{*7kWo&3<%#i{uo5vSi@v{lk!43B9KFV+iN~VP zCkVD?4&k7e{`af*^vC`p;|`9(KWq*9HQMLKhF)xmnwx`Qvdt0$Fj46eg+1yNL>;Tq zrRq1y^TB>5IVsvuP1c=>A`6OKq8KSGQsInt*Hdz6sDD?pz$U=#H0_AeMAGNX`oor} zi@AKY-UV^r^tr{INtOB*CljlpC)Tt=r0dR3FDgHNe*R*&@|UMSKHb~dIh{;8$9;O+ z*{)A%McmdH_9KR|j&f0D6vVNLO^0iv#)pHCTA1yI>RLtRQO`I2jBFY)ikCmNqT{5~ z=xpt@Xo1CtoDxH=PUYZL%&&|}l<|_NO?Dq1*`qBAsdJu~5US5S7bFbm(S+ih z<{Gn5i15dr)YpH1JpzC35x_GPBq7J#INP#s3;S-YuTX6*3a0f@n9<46Lx5G4!o zh2UaXkKnX9{4rkI9LAmV2!~VbgaUeOoHPdq_<3Z*YN3P?Ven%NL`5&7^xFd_wiMI@ zwbzT;kh<{{P=|q4jX{_9N_sGAx4NTQ47_7DKvl+$hG>(tGuo$i5y!P-K8npIKRN&6 zbobwWb$+qCvv+=u&^Xu5ZSdI!aZ>$uo39B`o$80!bvxBP5ywr7NGB$mwe%qm-S z&TAk)k8#IZ;me;OCXZi=iz!KU#~A~DyR^VKY)NF1Wo)ToE`&*pyC^`QFQ~bf%W0)k z|MrtZDD$%!#yyaf?TXD%asTv7s#3GD8o37tw-(V{4pz>D8Bo-0z*BYDk5k`T5_y_~7gbljq+t zuDhrom9r=|Lw+(6Ml~2ifa1tet{p?7uS~N*F~kr=GI3wPADf|1)FQXSgpdMZVK8US z;?7QQjS}FHW0hTHiYv{0D42#SM6s;W8dM!;Xy{a9?juluGTLmvrb5nN(%0Yq6^#I; zB&KGYQ^MPpW19jT_ZD)IOL)aN!7{E3+b+}kD&uTs1HFSrkN{lVFQ7)onF)lN*aQ;5 z^J9FEZ!5;#oP>7YhgvO+=kO40#rXax zaY?OQo;}&+pjz+HXKgGc1#I+8hCUy1vGHIrk|3E3I{@UugJX8U3yF7`_nH9 zSzWb&JV$pH=ptA${@q^kQbGd5T#tMi{`rIT88w;e193^o&`hKab0@Wl-EX#! zPo7Z2Hv1?S;we&v@vKQtzS5-C)kFAtc|8LEszv~dfI-(O`HcCK^$X6;yG${;IKvL) zJ;5mQ2zze0=Zj;%zvZEZHqR!D2>{=5K2uPCBQp8-UgrDqlxmE5$Drc@Zu3&g%<3bP zJHtCf(@$^($6TH-Y#Biwm=C&dU;YE{!$xb`#59iCJ)~HRM5pWwXw-iIh z?6+s6{r;b4|MvM;KYeljlk=~BYa_GhM90&1o6^gZA-wDcwY2G)8Vq5*nU5&TPvlig zNl6bbV>nvFlC*(lRHX@w0^P%HR!;Gg*NCQYPKic1Rp9e{)P8{wLt)TxBoe7e2GA!O zo0io%l~SW*D3W@Q3Z`voVeagR^D*Yyld;b}{?#|=x0h4?6pTMLG1;!gGHA!=vmpA8 zgTg&^Uyyf-{RwnM2!}Ib2H+GTCRH_|k(g~(C#XvHtG0@r#sSl-G(RQgQPUz|YfxE`@3&I_L|(f#IjEo}u7FstKn^q&n^z)O*A`Ti|DV zKj3-(-Y>xG4PKAH_Zk6gA7p85f*Ew=xi8HzmO*{6wMbgb7MtoD6D>BwGJuw4cWx4*SblS}Tp3)Ya264on@4qDfJa zoe1N2;=AFT_u7Mg^Oway^jOOzXKVDrC`(iPsRQwFjhb z=?SZ}f+lAb5CLA0BE)9Zk0r9`D1Z`|FsjO>IJTW-{GmMe54V|qdh`qF4;oEU3cGW_ zJ+r}*rU+OQ0f7;t$bdRALpNu>1GX1k5p_hv@x>sAo>m^ z2}%sYIg$-40l@%&uyQslPaQi>ue$lwE|O0eGpPi#!APcEU-{jso0A z3bVL}j60pTAOOYkzlDZGPIdK?H%x7mMTGb^3&|;8?nZ=koihK2o z{5FP(wjR5153#j@9EGEm2F*U{{Rt{NU0wKvjzjGLaNO;%5gSy&F+mtaT)zobL$EBU6==$R(3%9|R>QuPdYO$(54s zV2$p1-n^Hlni2`iELgF0Ad$PJJ$A}vF=Kzg3AOE)Gg8rN>V&ibzh=o zYT1P`Dl`MCqabi$Sf+ypC!7TA5@DWXG$md=il#8{M!!cw2su$5nL(peDZz=ax@d64 zm^5kZVOh*0oa$u26b2>fh~#JpwIRwu=`voboRYLGHC%9S@F8~3dhBU22&8viMi zVoKAPrZD@=*3F{jYdRKF!AP`QKc>W! z{yx}Hf^>Kl(vZa&jODCwd$QHDZTbQ+M`S5(KVAz)!|h6Uv~Q0Q3v5Ao6p=hzy9z;x@99vGeNZFxJ36QN>e{m zI~G)+qiPW%QMt6XO;PT{^oRu{oItDq11tol*E(cNDG3lB_!(kKj+B6&QED{Y>Q^zm zH1-e?hTJ42tF7*^H)tb{%(WA|SeZ=O=oP8TS1EMfeW7ou4|cGi;KiQ<2T4c7Lvp!ynM7Mn)xvt98$zIi6Iw0 z;(n4Q)}Gzh#{Ij$q_5X}Jp%uK_Wmx!kvmQIMb$>6QR^e9aG(!tp;>{?+80B>0Y^>r z8qLLME*487QS66yURU>r6@Z;l=_JHN5u1g z|Ihop&->eqz#80b>$fanJiJu`MsA}-1Q!Gl5bjT-=68Dh6n0i`XMJf+p z6xQY)ijV@IC|ZtD$A{P$V)WP;x!IWS)y5d^EEFpOctVne1@H z4=YPruMXOT>L8gYq#ou3pq-3Us16I-^tw|^A%a_!^~Bgf8VN`!>0W7t*Sd)DAk#xn zM1v68>jjlX3eT{={_DRcbVul3+1m?i^u`^ZVB(JL03-yAJ{efnB~pDmi2U-nipAp@ zAk_j>HC1Ab%wOHs7M$~VKrw9y)j=4}t7u~7VRMWH`*=QTtG5-!Vsgw}25p+=nN}Ar z^a$}hgG;1MpAS6WMwr**I8Wx5j5knAvk~&!coon!(h37eEg zqqIeSt-TE)OtKf)AkYLPL+V3&wUN-hT_82;lg^NEM4yj?!Qgn+ z4MX%LN<;?k3hp0tPhkgx&KiD1IYHNgbr_LN;Ja>PrV0CX<2Pt)O0o zwT^n6)=EWCc~~NQOEuFB4`NiBnSjQr!+B?}zS5+7@mY`8>7;}qJ?`(#X}{I8pnRmc zHzy_^!M)JV;I$Y7>nsIzB8{njjL~pqn>h$FKoW ztt1P1xdWQypxC09kkdwGQ|_L+ zd$S{YAW<5Gj01Nv!eVxUAlME7`=}qZ;Mdi%nJRb%q6DUCQ51zX&0AM=NsTk}5PsV7 zK9KYprUXJ8Q$`Z9G!P;fQVF zq_E|NMkzpQJH9P1(mWruX|wlR->jP#ZbslY8i9gE7M0sv9xHS^-I1so4h668A!;)yGOujLkkxwLku46dZO2!<0b<4upCVeTo3;% zhs<1}c5qw{l2k61;YJADGlf7xHpw)e6cfq^#kaoq(#g}(J{_vxZ ze*wRZ(51Rh8z)ecU1L9zgw@dE!4i&ydN;6Bxo5MfBQ+}do}zc?7Brg<{iW)dEJB)N z7I3(l@1i1I1nemcI{owZAhTxZ2Y2ztTvX_}YNaIa*BnNZk4333uLA5MGYJ7^1`Fc7 z_zZKG@$S6rc_hA>4N|b_N}+0qVsIjiN=j;8mQRv;<;c7;%VFP!XtPZj@4Sm)Pd=3~ z!Y@4|%>oV+|KkP%%50uYFx3E7v^_%H*=Ax*!*z{t&crA#B&|D}m1v++M%o#%yf!CD ze_;ajsDnjisq6{6y4=t*ztJ7KdGclie#;R614RxKe1ig%8p&j2hc?$T9zULzq!iB( zlV*2NivtIMyJ*}<9vMrzQtC_~87!ebAzruGS@j4~5k$|sg-kBHoSw`*Cjxq)b+$$a z^R}O-)x+?3*hT155?nM+u zuAUA-abj0g*HV1*@yLGItqdjn(}oNx31*R$M^ZS;fPr{)0iY3r^+Fq&o+|6rqngA4 z3RXGj;AvkdxcH#UD7QIZjSk_69kot{k^$fO3cSCG_3;91M<{cvJ3_#YUt_;dLq6>< z@9BkEnTTZ^Nf%*T2o z$#QJ`G5tE()8+^tA9--rsbK9$rb-1d?FzVoq*DoA_!c&K(UVvPkclHV$awFqwgrQRE&028l}{5A4=p zQfyVI^vrE1(8G_YV!?;YT^7evuVTe)IFa%)nu`&&rDOEzK)^`lKeNV=wZ8?p7n`R? zelimvom)8D@t|8A_j^Goi6R1RjJC8)Kr)CEJLsrxqE-@H+gLIYRM24F=yxj-usw?* zm5RtH6h$(Fuo3MEZ6ad%C@%-yk5|ZfY$r<455n;I&0!0*4%tOg490cAHnT_u;S885 ze4mc0xyT`Hl{Sd-^QK0=$c{G?(x`R>ia9A#*bJR}5dyp>GrUFtv z4)wZN7MlVlydD$kH+MRxzxS}#Ms&~kLlD85z;BeR6BH;?3tAaQO=|~K@7-#(xJ%E! zHXsduUf@hYzQdN#@7#3Pu2{^dd;lX+&sja3bdY>5Jf!+Y9ithBme`t+MXif$;iwJ9 zGcTf(k(8b>p~Y6$LNaPfql~6A0cGQ80-wX8WodVUK$ajtKJQi2V=oA{ru1ZLhj{Jd z9V4kdvy+?#u)Arn=wn$zjn^LKS=19St2HHcAAI>T{L*!~d0;aFn-Ta8Mj#UX{9VPp zEK*3HSgb5IRx<%(K z3|uDU*zg8ijK`yZoWdee1I#Tm#)KkKEt8r^YZApXWqD+t0b~KjG!qo__qO)X#*uC7` zrEZeufKcEFZiwZn=f}=6RESHe5(N-hz839SVZG^n#~={YN+m>raiEeL&|ii&&DR0< z*I(CH)G~&dv2m37@cY<>Z9}-&Rpf=JPfhJD$`kR)Q5bk*_`PCprHMp~8*H3a4 zqX{#&Grl0D&cStjw=%SsKxJYgKSc1Eb8tr&X=QrB@~}w>Xu--{#e{1+iVkvKmdbG1 z-NkS>jAdP%co!ZDKehG=4x8iUG8N!^X^A`5|D8Xr{QY)I=7lF|&W9;^Ens_SElrLL0Z)T0qn zrJWnH{0$0tIRbP%V>me&EXdGeV$b6e&Iow(S{c9z)1~9r_ej(L03ZNKL_t)vJm07(*P}A zc`>;HVsZNO;YK;?T%XX&TpA+BiO$GYY z(H-45ARiDFfY<5C!dxEac|U%lKpCDag~b8$smr52pos3{;i=pbiV^p=2-p(zK7IKYo|rEX5(C@E2$MVw2ZDe;_DNZ`#y zzKkNrj9Q%L{nk)+GWodE9_|iZf@Hvdju_j|&T@1%3RcGlw2n?@T2=Hb_I3=-M;{Hw z5qMwg%=bN7{w=G;VJ{j(-l$Y3`97JW6H8i)#qC?SZ(}r$E0*vQaId3GL2c9767GjQ zMuC2OuO5ri(y2^qy}*Xmh$tH%bRTy}VOl+wCHUwCHQbwGMQRuK3j+@oPWme{&%;F?L98vmZ zU^^2ylmPEidgjGvG?5jeSG%~P`S4)Mb<=jwO6FL|9ZqSMh2eg!%W48CYkdRmkMp+P zyw_#~MDO|t+$3=$1ec8&H?mgu5bfdys80&0M;RJ<2H@m_0N7t;j|{l;OF@c3l~+RK zNGOR+Vid6Qj;5ex?4UasS8=<_C2Hddy;JixCIb);$SAVtYAS$xv%Sm$?zCGa8y8Dd z7RAPJdF0lu(zw`NI&pVN><=xFXSSiZ-WYlLEGQC{+qdrAp=bzMd75bmRP!b7^8=i; zN-cpq{80pMch8O|LJW$@wPGtyS8t@;Xa~_~9uK;1F0YCl=>Mn>x?|-|Gr*;j5VWIr z-{GlnPLMMhe=n>oGH;5Mc^=!^KKOn$pUuO!fAk^X{(U7>DU3?mm=-HhK@bdsf{=YR z973lb93XswhS#ovn410s@M*{^rbfwgVv>!x$lGCahUgh#SvUYqPkzvbGly28pDIJk z>?9@!y8tF#e0V8Q%5xI+t|~jFXQ@o!Cj&}|Bon2UEGgcMY%6&Kszg1@N?;iwEDtnU zAf#s!Kwn=FTxZa(xHKGuAnJvM1gc3H4n&zl?Rt)0CCt~&`Kc<5qfAa(+F=+$0=4aP z0R+LQK~&Egpw9AuwFLqFvQF+mipsW29zKIjQP?8yOa2(+0azLenRN~}cjIORHY4y@ zM*!#eb8x3FF|TZ;Ktg;vxE{E@cB@>xLFb&|K8`FD$5U@<;&w&5f+s?Kh3;Telxk2k z>;qD1O42b0IJDL4Aao(fEA1YXMQ@+t>$}KQGKk!Pm*uq4ft5)jnpR?UJLgvx>Xsci z+r2*Cus3acuS=*O#PHsg=3)-L`>0dfVaa`h}Rl3Pq!KlcI zOPR{{#Iny0@1GpNGIbZOr(EjKfp&%NcW$XaM*zj45vt?A60yK{uX202FL?_z1YW|! za<|(8yHWo5xZR-5f%maO>I&rC1D#G6k>g`5!dQCfFEB89Y`1`Gb>C=Lt|qrtU&i#y z`UP=&Q^9)+3m&aVB-Ko&(&Vqjf>3u$`V?XXtA2_6w}kEx@4{GK3y^!VG_^u2M7*Qs zS_=K~iRXEpRZB@1mKL;m+5y}>`fpKRATvzNluq?r|WPF2dK=(DsS~ckgy39tt5(H1tZG!250(*k@u)Un`j+YM0 zaBfxV7=vYV+;@W`Nb=J4c^8r-=n~_FK!~%mw~f(zABP&!au%i}qjn64_PXOnX?f(Q zdxPB~AWtWsCh8hMi!c)}n?iv`6|%9+Ebjb0A@irVZx;%HdmOLDLPqnBdsHjlC@lJeWs4h_ExJO_XvkgU`>f23EDny*>7qYCB zR~Wh9xPAjTW+$iePWMi$MWqYR;D4z5q2N}{X{KzxRX(@Ph@V`6FGT>yWT za%0>I=$wtU#FD11q%Jt2*ghQG7?fsNqJ4N5nEN;mnwf}QN7?GJRDfvXB0ycwhvOq( zAXzb8BGRPJsy*H<;_56lzwLENmLe}r%-qAybso-NWkIB3r^&%CRuch*5Slx4^?GdM zE%P{U>dkv?MnEG#+SJ5MfO|}>HHg}M+WNQ^S+aH}%?aeK1bu41S*N~*qDm5#xC#GBLW|)DYg*BbO{75X$W;lTM$SWdUU8V6DPxi&Tt{^O}F8%HxZ2(BY4rs9c|y@BzAP@F&&Hpb2+->*dY66>^R&ri*p?5NYM)~Dot>Gbh!?da zJ~2ePlnbLpchnb(QI-;h$>?Zr4~qpVn8*QF=;}04wqk}p)y`7Q6pyJ{b&~_E8Q=N} zG)X{rjpY(=8ZyRwp|R58^X%TRg`qMFITj8q!%)NfSynKV(^gHfFWzt%1}oX_k$D}D zNs-r;WN-I(i&f9wkrTaJwEY1-%b>1sfH5o5+0w zNShIOyd!|}@gcZ_)c6lNbowmyr$bm$5`ohZ##!991|*5i=upREU8*^OdoCwqnP>vP zLl}tmlzwZ76ysS-J&16Vol>*dv!G{cof}Ix9Sdt1Js!e((5?X|Ew4N8&~~p*tU4&R zLle2TcN-<>pP=0s_dOIZfV*gUh-9DvB&($2JJ7j134uG|@~y>9PZq$`!a^czNBv$6 z%POFrPDr2{HU#Xcf>0zm=tW%W-4&~&4_rdq%HApV)9?r+bB2RK;aR3(% zI|CsEPm`%6-jn(fR){EA-tfcfFaGh<4?q6+ZxBMNhKaykbOeh67Ni626U8gtZT8R!aD7Kb=Kch$ehE-)#=)0;q}u0GbaCNokZj zO(xrxK%Y)1wzJH#3}V(Y?P6WlC^<+TH4INi#qUrm>?TNUG7fbHDVJbArLp#SFznJE z@D!u5{qlYM@zE-so>u40)6?#1z)2^&;?RpLpWkM6#>k1?!I@s(j+4QmYGN6|0ybz- ziA<02Z1-@w&mO|UQ9wmPmh!aLaF=ST3gjC;a!lP7OgV!kBAh0vVaz=_UA%ENKs(74 zSJ{C3a9dM#w2s^f zP}h+^jXT}ajpGrtsx`}6fEsRqZT!5K;Wpqs97EUC(_V?5dP@iGI8Ef@L1l>DOep8C zVXHpCyHK(U|#7B~lBxD7dJD6hPJE=9ef3%ui#FyfT} zP2XPKO10-rAFL?biC z1~d%<>=o&FQG*Ik?}&mTB?`JzfqG1LlwL^fktQR#fn6otI@ukR@h(8c$V2$3GXrA$ z)^8pkS4XF(_YZ#k$^M`ImtX(aPhR}>8z=Yp^}*@=$#L^O6A*p-eE6$4I-4~JWAi5W z82I*(69KqGQ=xmopt;c@K37|_iV}Ry$B6k+*ZK=ay9{>r|*>)-c(`<-!Xc-(4;yF_m`u$HAi^a_&{-kuL zz+Eo!fKZgr zq<$e_mq8fev}OkqtBjjP#i*G4c$OnYdOqn)cCV9VXdSkC0J?-U5xi)yuyn4<*nYRu zr-vUFzUV!fQ+s&_{~XF+OVS%b?z`w1ao9KBn>UcRRMbz8CCDsWPZt=P@$uAkuw_o9 z^O0?aAfdfO)71QL2hIB@zrIV$@w@;0v;XwTAO86MfB4lOJ-GkL$)vh}d%0~@Xk*B9 zV9F6pb~!5(2POrV4pBfpYneiU*>E|fg}Dlg*?V`;D3;x;4iuMDSg9iudzR>puvBJs zlFmk0c^sgbJo0cnAVgrx*jrnNs{xsa4Y)tv8+-F^n-O>v+`(uHR-(ODtJ`kN%>`J~ z+B}JkK;~*_!Dkrrs3dGJ_aYH7)j)!HXm^MNW1CKyDtv@mRj1LmkE_doc)NfMaq4FG z=(t%#u;S+vkQT}9d=E86&thrb1>Af1$Pl@AZ;SzVhlvpT zi(mZWPbcHzsJ-8IQ>nAaT^bNJhDRk;YAVX0u{@GM1O}!67qO^y>08mzHYk^|Dgf5y zpr6njfNdAPkPUVZ?*X68Y^ZevT6kR3J41E&AXp|)mqEMLYnK|V0u~;F!APkWUg2s6 z6vysTf<;<|$fh1h<)~cBUZ?Zw{gXfV(YzJ6g zc+l?b5tKMvmTW2B^K|x9wLbR23c=Y7wzEV)X9EQUwtw`I3YWB%s**a&PrW+YYV|64 zAlmrz82>e-FscS%#Ubv?0%}2OD?@uF8|&OwO_ff(xQTJR@Q@lOJugBHDnQQsM}Jg~ z06t!dbVv_sl(6_A?M(kBb=rgHM^L}06)~Y{SJ0|ZL?F`uR#P&Az=Iea5xGpqA^PXD zk@PSZL(Ba6$%_Q;cOSgCKRG!4-s$}l2pPC=SsCDo&uW7PdTBVAEIOH9_hjB&wa8%@ zjXuUP^l050oiv9%j%-iH!V{Jm*&Q;`Oayqy;|gh|v&brOkMs}?RoVb~Uy~B@dv@Aw zA5I6&4sI3YT5V%L@Oba*&AV+z;9M;Onvennx50B51avD10Ifm_7-K`Hm+aM1G>6o$ zlAEj3hE3_gke>GxxKLMGzW=V(&qthP_ZV7+6s*7>=V?;-e#XMOho;Ol;^CL(05I7FfB!+h%I{IoMvHvB>t$UeGNM0r&$n zFoV^|MaWK_~==Byr($u$w_3kHQ8$k&e`Y1&4T|O$L*h zz@4W+J!zz*Z`xiiZ&wda?mhVF-3Jfu@e^48>*ncA4lYAA13r-3vhY#YD_jI@^z@j- ztXeaUAsuSMm)emcrAf7gSQ2Aj%xiXstt{QU$qoSYSQ7W};-?h#13K}s)0IVE(L56< zQYyzlJNW|)lFKX>f{j{c14f$>c+4Xp%AB`^CSfy6W5K)#Y+^i=)HHiWZ7udCO=6CA z6$EtXo54%nrI0W@hM^1HG*!z_VLRqnX!!yp>+R}pv6YaR*`-g%O_PwDcMfOi5bU5T zhVG-C>ZyunfTd1rhSM(eP8%n13=e|kF=;~#ZlUSthan#byAaYQ4>udA?I3FsszmNL z1zpxQWQRoU*&MC+GL`*ir-V5<1P8^X!aw%gLP{fFvf@Mx5!^b_a}H}WuM-owbBw-oG2%}p>LvrLU-S%ooV^M4qyG!Pe z47fVW?$E=pSDH5O->4T4ZfF>m1< zfe(9+*5Tc@ok)6ub~Y9U%qn$hg=kQH@9y2ZKl|i|r$4^`!%y!1`ayMH@|F}k2_L5h z=^+zEHcqp?GMUy9K5G_U`MFpoWH4twavWqy5~t$bN#~`q%bW8HwQL8~8aV>aRJGY$ z&RECUy%L;^rXC6pvRLR>C&$OnGna9a{3O?yxdJy|HY2bZfp2aEh}nU9fj%1{Bmk}^ zdVm6@?M64LJ{BQ=@KI*>!23`O?jj|XEa$oR)dJa}QnWnTEfstpM{yTB*rgq*z;+DX zI0SBj_ba4&rQ_36w@$IC0e5)wFahV@sCk~fY$LoVz@Qh9WR?S*V;ro`sc2+6@sF0- zo#BpIl=h$$+HIU?a&g?p z@bf+HyAC`AtP=*4u*wvgW@#EkeB7L_$UfNby(dy8Uch+_!u{4Q(|764Z9b66Oyh;a z4)sg8z;uU$!F1jrgdeR&wYKJ|tBy>0NkKDuv=Ct?B>^DWeh5n$d7V^J1nd3f5krh@wSS;Y?t0hVj*QB&r zDCD<~XqQr?t;wjhwUv(`+yvS;;Qr0s(wleQjKF#X6uBz~Mv#&dX)SoSj5j1fBPmqw zUjC@EQh^0^ktF{5odKS-Xgy53hjhdX=>IdEj2DPJ;Dp`Aqk*M{%$+^>1iG6mZ7L9rAPP_=w6?LF1_G`qK5F$vX= zZo_(~Qn?seMb;8zRzY_UaIZ02U?xF^GR23%Z3EPeMsav}i2LK~@4UC2Qrwv|bo-}w(6uj6)sy~Q4_riocrY3g zeFaGKUjt$XPxpnVy88lP$s|d0X{?F~;*q)#$)m+FHV&9QN^jCC!Cf?`>V|@fh$JYj z0BywKaMNIC&n72IZo#79)jdR;f~b%zYhEn@$%NpyOyL>KE@&;9Zk}w16LP! z<^*(Gied}Q!b=>Hd>Yxc+ovbf>hgAZC<-2xJ3^lnwws#Ojf9kGh=?DOpC*W;b#1>+ z(jciWww(1rr&#VG+sR`eihNyRxfNxm$`2b&OwI}^D`?|Y*7liWgBIgarZpf&^%S>} z6E5~!Oq+RfI2&-^V9#a*es3dy+m^KBu*9lT0+qC&SCvr40vh6R@z>Hv5~72s?G>^` z%w&lP*+W1Tzp0%#^2cJEnjAWH9Li#Z67w40VKOi|03xDRYjC5wT*hMnkRtjV%_Dqw zd1Flel$>T`So0{8?BNcH+bx8RZ?m39*(lR2Rixhfdz^Na(UkN(&-_D_3^$RBMBV)k zw2Xu)EF}PU#nzO^X2}{rC(%(A*>xTW2Lk=1j;Q>H=Z{mf1|6bS--J{Uy~* zLD=fK%U_)?3ERQ;J)GNdK!b~;wpB8E?NVtATHi|I6ku5zW@-~ipwdY%>&&8f10jha z7m-n0Sh6H5(x$8@dicnd(WIhg@3YY8X?oD3v>or)(0=0BY~pt2$4%t^d%L?gAM`)< z2xRwmRO27V41GNg1bl{(hQP)z)@)hyc3Ryp+bf(%v^u9o$6z}KB8hqyOWiVsNmSHB zzX0OVd}}nGm!*{tWg$z%EO0-{M=}*$ePQWA6e9No^C>Pm6w6~;Nb3ov} zM?t1A(qRvfLK<(G#Z4^PNsf{UFyKyt7g}aef^vTtxn~9L@i^cPh_>h_)pgCHBuRLS z_&aFRG@`sP?WE%~MCFxC4n`>7o5kJ5yu@ZN96e62JQZh!69r=AyX%7(%c=mbX_HL%o(1Nla32#IVC5aF1*ANwuwuJpqS= zp>B*Y9p-{g$)*hjFM;I-QeYkMZRuA0*sPufZzxoir#DTK5aJ|Y25>D1w+J$|Ft--N z`6!5NqY@-?J#GxWsMIn8q&7BS(kF9h#}c8iCJojIp||5HQ1&CN7;oKzb?3hjtMQOH znErZM!@0|VMSDZbCV)5XN3m8ZgsFVeuFZF=ZJ!6B!0kvq7AfF^0J>MA+e~Wt1U5C; z)$F9H@Q-;c3|?2m)aO@=3f79oijuJX)@`6Y1&70-AOq)kw4n|~(F3_8*$rfj+itZ= zqtUb>OLv5lG8=%RK`p}!MMEo$-63qkjB^#4rzkHf^byY-o~j`okub4vGQU%gTLrh$ zr7UP(b}`76@|+H~vpjvQnk;idlt5UUrPQ+|0p-ESRVZ$vAPXY|f@V`8>Z!sPDU-ky zCKj)r%{)YY8d+oK>_j#V01YK8MSrxizlrp|gs@_~q4%o4& zXa6xaQk1%`VW;2|GOYQ(ZT1fZ>Ob{neikW5;zKI74VsaSvIe(ytQM<8c7QUfXfuzTVKIgI6zP&c8{2B?MBTG+KFV^ zH){`sQxN)6tFc$)R^)`VB*Ycb5p?E4YpCa#vVF43JDlDLC1Cq{z<*Z{ikm~8U}LOZ z_E2m1=w=FF?$lGSLv6LPUW>|+)~tx9;_3kAmYU1oYKK( zOGH5|BEJ`v3HL(Nj5yk7fvc<(=cgwDJ%!FgIb2H{BcM3-YWF~sTeS=f-cs}t<fo6dfbhG<`N&<-A*U?&#Stt<@rf=nyKS5J%my2J0jL#IqjQu?ZRzsf zncgUWCtX!+=I@bddbSFQBIgR^T%^vy=|!PW=Z~@K7OCKKWXT~5U!7$~wz!N1_wp*a zXw6=0f&e)AUtv4Mu-gbWtux{Ie)quNFCM3>Nv{M4F7Dfg(jW~|w)g}%u%Y{O&OqiB zjvJnd$1*$8OfQ4nxTCAMI6_WlZFaUDA`RtX#eiFh+|7n7|F^m9@M@ToaN(Z2TWM0c zZIsbu_`RSQZcHYguXQ^lNcQh<4X^ckQxloLn`o@2a>sd0?8G+V+uKf!U-r9JV$1fs zRDI=|ya(?(+cb0*c`{`N-mi+Z-I8=y5Y)0W1WUXtr%R|Kz=C>&P78FSIGq_p3;U~q&Bw5j{~=kmtX${juA`kMI$#o zXdztbEZm{;5tCbGxlclPS{j0Mq1^_e#0hT9*UC>V)~SOqk-s5|0uMMQOPW)Rs8xOy zD{8CDMP1TKDh9L2&ge?)<)s;m_LnC7NPKfd2Hl%Ubz&_4+%FPsj-yr=4Z`sk&r1`V zG)B_bP-|&cL{ki`0w#$TBLVOoNY|a9(pd3TpIo;p(L3e)ARL@=I$fAV(z=|!P0_g0 zmWuS+Y^&Yp02dxiP_F%3Z$%^li(uW6$+Z&$Zn)GLb{a>YLOpnmgHs*?T;OSu5 z55&qi9u&lkF(h^C$u+-S>Jam!8w$y;e@l|q2Tqr6Qok@MKV5Wp|3Rgpee!ej=`7iY z&z~X^@j|VEl@#@M_UI89a|~a{-clknrpIzz*v>^V7~oZEK>oQsolY<=?hUOc%h#{J z*7ip>NCW78Opz@8Nk8mq9qQpwqqCmDt+lCus4%cR|Cd{!;u`2Ph5I^V%~JeixQZ+* zX2VZw@9;aGu$9F87Kv)iS%yCo)h>&M{l_@H#pbY1f5#@k;BOXw#SdUS?b~#N;pz7f zEapRWoY9g3a7kMH>S$l{4MS6QZP6#eI$X)iFR=r${obtn7doa%c_Zlv+qte20C_%A zU_0c|fuaHfPSpg$GiFVKW1zq-r7$S3?1V>dOZJ7{4BZ6gsHJGWa-tEPFdpB+{oa{z z_Ac%y=nFg7INRY51wu+-OMvJ#ejg7gV?MsNb)Rdbugf@#GAh|xnsgpPl=^JCMQj1< zYlCEq&YvHLmLsO*4L<$vzcMpkz}zUupIlKLGLwS2Otu3APFjgj>rc_~hfUe#&n`+K zS1yZRjnfvL#h34i$hk*v`=nz*hFiBi)gf2@(Zw-}fz+AHsGldp`JV?n6x3BjnC_1B za`qH7c7^L?!-*RS&M-dh7ifozjm?cyg_oyrVIk*>TD6;+c>V>k1s*COz6iwB?G$ii zRo|VuYAx$EFgSe33`fmsZ{sN&a#PY4yOm_oM99~W`SD_C5Rwe(a7ZObv4)#mbY(yc z_`Ka|d!=}V+LQbd(IoxnK;&`2uMtrqO6lnt#lNYxFne+Kd8j2E;SI#&VBVN0K7~}p zvLV;5^C(U*L1u-Nb;T!|y4nBegyLmNc~3Zd5$UZ4R@B3wxuDo(xPCrb?%+2H)1z{q z1~4#o{1OtaEl+Zu)8=j5-|9a{*#`9C2ktsU%?k++O{1mCgTOm5zvLCjrAYBai*CuA ziU07C!z{I8!IBwinp?)>6I=2mvE^CLlu$Yv(L2Y*DX!TQc?@Im{Bdh| zYsE6z64qnTo}gKICP`Xmn&NyZ3Bb32h36why$82BN(yMlhRCnPr*nx3AZbf&zmJ9T{GBd(EKZSJm7^UB6-n|lS~1K{X)wRtW0TQMj1(rU{Y0v`ugTw9%>Gjn*=ON5y|L6YhzinY`SVsO!X2B>umpy^m zsyni>K*fgKh99*_d%~8xuxetyn6twIM|KQS@QL(&E33@OmZccLXGq^|ZR(jpxGiI0 z&+d*56-+MqRSrSPQMya1?Rq^ruB^N^YVE-W9Vd6fsxmFQ0@PN@nG6p6&35UIy8Zk- zaT(<$ov|uGfPF#Ta^&_{TNpG9u|;Om6PTS9N3gA>6*%PS994GG7AN5|iR4%gWkW7a zc*~(WeP*na@Z_@9X16uuoasJM7I)f3ZZGlmVrh8vdB3kXPtb6d^ufeSXH6tf5Av z${25XW70VySjqPHYp%B92WQY_OsQzZ^KCIt(>o}NJ2cw^Vhs=-9`06t=&0T5g=o~D zH@gcFZX+hW%hL^0Psq%a)dc*OYsV-BbJ8`Y^zf^E8FiS0FkoN#$S8V4xTR`{^Y6aN z-lK{L8}QSz)b82ATJ?Fsqueb>IRXmmJdgWnd=jos8`Z7( zXvo9S5OY;#x9LJb!Dn$|i_Lf%IUMyxTL>)UV~U&04s55NB9cm*X)RYVtsoO2$DW{c z$xANFPN#1och7XT#zW-ub8*l6WWyW!CA+Rxfz&W0?E~e9WshoNh6!dtZqbJ()qAJL ze|)1%76wIX1h5h$;a1taSPHhk-B_!?5BRFva8~DyP5#K2xD$4TgU+MG<5`Xup<>g6`Vy=HuUZ&GJ-f`u7nH z>ELhZiGVyuzh*Rm0VVZfV!JLnZ7`YICK;JV?a5{q()!n5Q}yEerGe)F@rUgN_&aQ3 zWe2SZc2G^@yMNC(ZKb^|(r388KWy}mz4zA#!r%qtdUHJko0fqc{{7Z8R!bHqb&X7+ zgu0U^b9w58iv-Kmre&o+svvc)3)*u$#o+%HZ1u>dF#SjT7)QE<|L&A09=)p9ob zd7NZt=Z}z=jtbAeB>@6!y}0%1{IE51z{wn$@D>f2t)+ceA(40E^umS-dm zqhE!9jIQMYxUIV@rDUAxh56AMDiO+Y2-4Z37Q4`w9zgjb)LG>bw-y*r?Y#lsHBGezMb_%__m@s96mfkgXF`-on(e^0%QO%v* zbE6?3pifJeA+%C$x!O=}jRpURxwAn$(|`Ul2AIluo;Aqc5~Ugo8d;ZIPFX9kF_IA# zw{NTmN;c}5Y0zGwJ#%3IJ!D0u>$;U@XDJ^3`uBDl8Qq3afrEaz_S440EzA|Ga2 zP$aN&iok~%^l2tJSejv+k#v0_`xL=3{{{QJiHjKBsFmRSL6elxy_f%WnrDB)_gHM( ze^sxLBGGkZDzW`c)vF&}J^WEEt@*23poEQqI(kV>-ccE;F3ov}87rYLL!0|-Rf(s- z3^p`@q%F?wd2Pp)UD7i)xfcA%6%1TnoE%?P^h=!!S*E)QCz+CjXtl;CoZ%zXW?C3u z?$c}=TDhh$sqv5MZZqTffCmj~8BelZ-4I3`VrZFq4XSs^Zcd&GLI);C8U&P)@u0$^ zozLwI%$n1(Xpf>5qtei}<|`w!L~3S%xKnCu8HGh}N8Bjw1pGM;0HKNSrY=<1=`$zO zmPoog#aX0f9kXfZgK+eJGi%&@Hy)3SXw71q5fBrB;msVd7%)*TXkWwsn27;0r)7lA z0@qY+*1yuYGGdPK#;BN;BhRG`sL2)>7Tj@G%&Qcm?I^6}-3+Xz@4$4}S8d%13M;r# zO%Uc7qcPyv5o0ZbWHS$Fc+nrMD4fUN$wTWRUE-%;vC)?(3;```X`wEU72)^(YlBYX zsR6X;$ZXaLm{c3DiLU2F3PD&R^;#NCC@;VHLpPRzY^{|zUGDt>JH4{HI*a?Frcaan z4iUKEkq~Kex>o9ytn#6#^#@;E0a4T}>K9hPL>XZHPTo-*`NjS=W32pzy_q^hdC#8J zIXTv20`n8E;{Sio)(iQp>F?KWXJE&1yDV7u0Y`a|HhMu$fcL zqnNfB$o-JV3RQd2DNrxp1kD#x1~dnXIl?Ae3qbaxIK)JHgW>V90#a=lW|WXn}3Cp>Tk>k3yjmYX$bbcmgcfc4yeM&%oG& z*%r!i!WoT+CKIrH;`Q|M=kqbQ|JP}*ZlJ_@cvDg#blU*2?dcstW_1a(E)SCf3!O?; z?Oa%NVwc~$k;mdCQdxCkoAvrX0p|QTsbjUwb7BPx6&rTugR*I?;(OK?$PDWGgN5c2 za5ldYh!Gf};v*ya^;DuTFXc8X{y7OH^KQ5o)dK#HPhl=9LkZ*h_Z8K=1?Z~mQx?4UtiU#vL`17UdnB#I1HD`F z5FlMd$MFu8y*d!ltTpuN+eGdT9*fSWIwoOP$Ss%2J=Gctx76OG7pW)0D)$O~)K??#`|`phkYJ;=?zpiI*?7)wy@RfL&xCv&kW6 z^(nU|B>vgqPMbU$2)~=SB)&Xwb7J(ZI>H;D@3QK4e^~6=}LaT~!XpjiT4nTnNg)EzpaEz(t; z6Q=MS(e12B2)at<7WwmQMF!G$s>oNxF{-rNozD}!qk#FFLe(uUUU zEXw*VnT&2A@dgxfcd1K5HC|mOTN9GN+~j%ivaG=OKtf|Wsuw?y9aE#YPp{e|e=Dx$ zUsq!~S0i>PHl|z0e}wR_LfYofl3Yg69G@stYT*4oa;o0EuI@D1tXXH|*0&A;9@H;7 z!~-u-n!=-HE#t0md+A-VLXo2Y?She8Eo^(K?b)MhgIoi=Ek<*E8+(C6XK40X?v9k!Dhk!lH!n`@KzOaj@O;0smF zVRHZm*s|7&cf;j|ys+{LBr?AvF_{M<`8b^}dcL_ov0&s2mw-zTf|bO;59 znO|_7|CD)^5h%s`)*|Moj)Dq1$(+?Tx_Z!F#n(61f(Ux82 z_2=GNYE<1qcd@2@`ZQ&SrxJs;pc(g*bJH{=kS=*c_u>YHXJGo zHDHQ3f3#Hl5V z%LAC`1g^SEPkJ_nD>5!!RtpWiVy?dZi3=?$4@fbmFqy~=C> z|FThqdo@L}#P2lTg~k8&8R^~h(n(8iByxM;Gt-XfAEAFkxO4M$JU5I&H7C0>hD#jr zzd60!+6SJcbZJl=s#c2$i!ReQ5wRMwWN{}jxyzC9Lu+MV^Tw1*F8lmkIZoza(xFpt z;`}%U$AP5rNywE%D0NDFVWQ_N@!h6FZlhl!MwMmU^lUF+lD3aeZye_oDO*t&gfJAn zK>lRWVQ0q9P@FJ46ynouy+v(?KjCtacm17NogVFqThD}kx5w_#9!EHlRfI2p{Zrd| zRLWo8Vo2E>p;pz!I|98i4o2Lg2vUn`{+%v#(G3EU9sFFjuYFw1y4P;t-It1c_iOs< zDP{CaxiKq!b0EuvJQSu>DM#K1CSlVSeftUHrm>7h>g0OSUVWPd)4~B3{nhXasaJFuA*}x(CyWEk%$7=)8rnGN;JW4_ctfC7V|5? zHk<&dQK!Qm61TW$6~w)rJdC)}lIProX{`kfJ(8@OKBu|;e(zXjZ@>LN_Q&%-w*9+W z!L|}l@O*K5^DBSD#V@R&=?tg5Rb8m1v6pD3K9CWy|9bMwdp z1AIJr^=g;PA|E%|-%IbK5;?E{%(ZM(d4JMWNPCiKLbG_c7hn(nUS<0(CN`CMokSbi zgaWXnWwVS+YYh=aPmgtTcUA$+Kgk5sFy~ZDT=EYdS>WCMvwCz5bkRHs1o097%mJ0ozt^qgADKSC{$QOM*EGHv&y4n zRA90uJoS(xc{jDLr&@CNh)G@~tM>&DmY$1$!xNeoQ?6_(yLdU9;IZ zJD3K*Rs_FwZT(r1(s_jWtds`c7WEQrgeA4xmU$>96iq<+%6uCbau^^Gja|j{LMJt~ zv%!#Fi5t+xYl|qLdq4&bAxB)oIx^m%w~VoWhesKy0+-9Yk?T4+gaJ<2Mnn-c=RPqn z$e;*J$Q`Ht#ZYSr<7goiK_NP{X3*Pk)|V(Lrkfy_J9iSdsfR4GW$p2KKREgRu1rEi z^sisI)8}dMy}!ffsl2?L3ZRtr%a+_o#kq<94*hQe*{p@^Cbwl%AP&b=xM_P>ljZ3% zFEHh9Y;!5uT3e2AY^5sY76}m@Iu$jmoFxzK{wTXW;%1vVVs4B|B3jh_d0+DD-3=FS zd@<&Lh@ujjgy_{SW{|K-i@;d+VSI3Mxp@|8m3wX!+ z1o0$M4ajSQvvSJ4N@;k3*;3D>l4MFDn2nbf)bm+POLqL>M5v@IC<*?=%3AagPY^xxm^iQ9N&X4F+T_#Ct8K6o%!dJYA zi2B4bP1b|^XmWFu(r0oRH;nX8D+l8H05L9j(%0O-H*3BfrTWSLeXr#82kF1(Kf7>CW^G%2)UtJi9O9ASKX?=nZaz9xOp8KsRwndw3~x0LKw_H3FJEnD%+t+DEjOj( zJ{(*bl_E#>3m?5DEtE#iRB;k-M*rqoAmH^I@fCS{n>X~d?6aVHNkta5BS{w+vAj)% zS_S~Qo^~|N=_9BG*2g3x2D9_&hznnKUroS)q9+4g#e&JO*?N;h;2x)mG~_ZO85lk0 zeP*N76-|cV@s}p|xlL~M-YUJAHbevk&a`MS5(8O~BHyW2ljEC2G!oj3ZN)oS16%P#%!kmVw zOZO~R+p+0^k7K*z65s=_IOEJpucgMip(~AJ2CR@%Dpd-kD87){wnF7+v?bk_*gGBqil zmvu}R;v(D{Xvv#$)*@L@GH=*MYn(@`SHu>%6Q02+9@f>?j4z?VC~)Yw06rDzOAh!FflNs^Ayq=v ze+0WezcuiC+sDUgdk{8qawQndpo`%#hyW861yJCXxmd&5@Q6&ZItmG^M?8<5JqS}p z+2!`l-t3tqpx$p9k~%kbZ_IwT%MdYEi}j-!7!e;YZybXIP} z@<(p*BvW-5#F@zd;{& z!dvgbOS;ufREuLD0hvHq`?qHnEU>?5+L6-Y zoxV8J%>i~LK@Cm*&Ei=@9tS;rNj~*^gT@SpyCZuNL*@S&1kJ_-G;CAJpnC@#54m%v z=H-3%_#ORYWU!mh4IyWIG$SOQfU8fm&B}5obwmZSsMhIt6-@*ilZ#4Zj!(h~fi3her|vlVOvsn|K8MycBDf{tBDOm$tOJ---OJ@=kwnw?#8sZwIM zzyv@#UBSvGbDN-vAAVjW5!)aqbLF6mA5`ij0v5snK9pCsA8iZqb<|Uq`w1)sW~LbrH)AA)ulsjN{%QL zM~tN)N-FXV7S(VlNxZ#B&g!9bVOXY4`;fkKm@eO>3B+c}55)Sj<*I;rq_LkDFNAK; z&>lQT6v!B{8_-fJsnE4NDPQmO``;{eZ+yIzqdxydeNtAeq9!GG8&DYL3z0M)n#>%l zaaDlNB$ywg3|iO3-Jl|#RGpPdPRd7V!(gHf_Wjz3%RHszi17g$gqLbR6iDF<@Y|*&U(7ENbJJCP2{XSh`Nt;YLlK^XZW{Q1 zJh18nW~rX-z{Io7IcGr1P{uXNe%A|G*_6QnH(RXYL>Z$k~^5e;3>xl0j@VV;`~t9?VeLQmInos(^?|X$)ZI*S}?_slvS>sK4kI z+(bYb58t@;Y^0J#E2@!|du8_(@f=3FNEC^)I)O#cJmhG!ren+>+?7`TCtZ*hz9M*5M_8@dD0CZ!C=-sf3PKEx*fteJnyXyq?EQM74Eo$xzJ|E4 zMg0JRgm-&)V^zSCGa{&)PD80jY;W-padb+l))LFGRKQE-P%v-=ewn-yr;Z_Zm-j!r?*76qUr6{ zxTC;JE%q;N72oQ9g1tJP@^LQsH5mx6EwD~ly)L@_@~*AfC-ETbF5M1IjLP0Uy68NI zs=2ZjfBDs0RxqKB{V?Ld2t!H> ziR#9CqiuClyYJUpIm0_xMd*6pU0AWHr9}8-^P%=ui5MbQkPR{Jd^#f}T+p1h87CAPRhBbo8(o_MuLgw+CUL8(0G+ zT~fXh(A_TM2)T0XlYm5h=S;4)7P>_>5eE=u`qqHLxyc>x(w{_sGg(!+LTgu86cMo- zXeA3of1>Yq7yn$6rIe+Ng#yS1hAo#Z1FdP!v`|62*<0_Qg3r;g9-sT4o;TsbZ{LKw z`$^*sAMQGdXV3MNOA|IvCuZBqc+N5`Ca6GB<7Elp*faU3CX`FNHU$1V03*esAuzcQg&h`pUv2wrd-UJQ3cndLIzHx z%ZEoVntHU;d7@tRa(Mb%Sb(?WCp_DB4>|1f&mh9US$u}v@Hrm$a&=Lr!G=VpuGqrg zjq{*hzb_ECE^w@U?3as?IpT4aeq3@OGX%o-ghXmO5TViTvWB*L!`4FgddqCX5)ZGAiX#bXIx zX<1=ndxf=`P4qDT}_qTLQe z&kDl% zU>l1U944A4^W1a&pt1rs#_|PDl}U6`ZmCn{<6gv8;|tcrTD^UVK>AwaV`Gd>SCRQF zX`y?rOXvgDKwu@ozI}4HaaCQ5@dQ1nwk6HfeQuj|!$yM-!fkkfsa>#zSgV`<#+qE$wrusqh zP0AoYr?5a{fIVqop^t*)|G0M@JbNucDy(*cm;tjlg2&Cu@KmZe9OgXI=_ZZA$!qPk z6Tq9pnS@favwFaJpM;tXha|a9>>5qRAxxfoehwaN@V(yY9UkWS;qUVJdiVQt<;VNV zMbu2QrAZ1O7oxwJieQn%d(%x?U~lj2scy!S$QW8{|I5khs&O~t)41~IEotTVq1~rL zWe3d~qP;kioHK0Z1Xdz~UH7ApzPcTgGI5Fg-wvI zleS3BuWD7rDdh>0A(X|z^YIBL(h(0R(Ae@gtwL>yhnGs_L0L29%d5kDCo-WQOBpkU zEMV9@h&a<3N^xyI*f}8zzjtwC2Pw8v{;njEFZ72PO_b?^+d=d6Yh|RbJo>dU#{RrQ z4Se7nM}J6alqeMl$54aFIF1`Wk}n-r_1!dCS2^}>h}+Uk2Kgu?sX zs*{adquD&`F$2()WEB|9>bSJ(<*eariIV;m-}BMX+qy+Y0h)IKD=$*;N(JF9t!*2W zRY24ijw+likBW0)8XA)CuF^~3l1wV+)fcp882(T>1Kl^o6Sf{V_llUqFBM|ukIt?! z0W6|yDyxNUxsPkyO?_fztE7hvn4YdK6f8*lm+GE#!ttKRdwWMEdc7W9yW492SWbK$ z>OuRUKz~8p%c%c*bN`oE*E20BR4mo{P%E$#IKj=1bD)W8e}05MBw}&sI{Xq46mpm0wX8 zINKVLWz4KF&TBCR9u+O zA`&-t+G`No)&bQc=fJb?sMfo5(l>uF3eN!RB@7LNRBkHiYJO*DAul%mY*^kIv-5wT z0udt_h&VU@+;2uc5HG>Xwf#YlV)X%y0%KvNiF(R4EvZuB&+8;@sQSL&fPvWlkQ+Wj z?gIvsy>xPb9z>2h0lWFo*@a@K5s6WaX?^H#}vyqqiv^WC2=Ge?&{RZnx$X6jUsNNRE$=zJa#w+wDXJ-jg5Ao7ao2 zG;};X-3^n9Y4S-e;5K%L2^BW89YDyQy$vPtu)adA(Ow{C2 zpWxzapr)|37!~ZVw2*b*?jSEWPXF5GQ+lOvG!-6n-_IoTtfgQ}2b8l)BbpQkS*2g| zpk^I26a3MgWV%KzPyLNPept(DP9U*?iip$RON|1ax3Ny#VZUApQ;#W87$ zWGw+op`})LCUb-aJzEMvJt>&!lWkh|0(2a4EsLRQ8*3-F~W)HDU%P`qs1~ z1ndHNL6|)u!i?;6tCT@4wMg=VQkgF*2kavp_trvK(AV;A_`e+41Y*DvyIbS7yfFXf zOfWToLv2C-82$*@@h0og*piy+C8)XYZWD^Hd-kbZ;ioEub2n349*QnTEigDANk>@M zs>3cUX>@%r`BHs`yA%5=F@d)o{t9g@jO9YS97Tch=$49@%lcByo7O?@ro z(n*M!yTrSsp;Dn+ms%^B`oz$3qq}u6AvaG6b(2FEWKx+r;?R9#BU>!z2WF1!0 zNc?-jVYt{u%>%wW34Y1T_3%!%A49T@0t!1d6^P#H!69onA_g%nvs|XrF<%0Y5elv- z#aKMnLOmC@uT@Ve3A&}bYF;rWbdiyYO(3zRZy0pfX@*1hUgmweF`sw2k>J-7`fXxe zoTtEI-(tA3)?JeZcVs*%<;Z+rTUri}@z0XV82cuc?MjEWEWG$Pi%s_^!AsKfYJe%c zrlJH0av(P?NZ|ty`xZLO?{oFzN-~OS;C~T#fpD?cP#{|o7CDpwJ~##z=8Uqf)!8vu zGO8crXRlp5t8l-sMSSYV)piDpbM>4F{XN;^WIGI;!%PogTE(!edZ}z)~&) zLh6@I>z6Csoph)`3e}k3jYWfx?NR&4T+^1==%o-rxal58R4r)M4;2GYnFF!-s?-wU zH?$p*bnI4G=MvkyZ^kxZ&&Nbd!cXrH4-WPHLIOE~%%9*aVRlY$Cw4J#H-qceg>uq# z!u4r3oLcAL$NDTO{Diq_3V$$=qt;JmgB$gJY6CN(TpR+=iOWW?vhrF|g{ELImfBZk zPjI$k+_4#ik5}e0Y{QhuYNl-mvE`eQX3w$07P_Vd05ptKAsSa z{qVnj;MrXdu3ZqOHn8{y*mQn!__Y3fd>X)^aPM-MclB|grH%6oM1l47_hHXOJ$(mS z-~6lE{Z{vfg;70hBjl_X`70DTv>ZBFOFY6<->FA8Vn?H5#SRfwRDH0 z>b+&&mE23+sZ|BLw~i@`etth{$tk74=4iw25cVCs8@;-nj-)p9$l&L#ojExBAh`*h zb35Bk$nUYRwG5LciNy^>2v|ptI`-29WYInEo}kM>TMr$z8KcFhZE6%KFT?zwhIygU ze?bLE)UbQ%1);M(7VT{Vig3*wWfr$jh92{SkNA!}e_&u$brJ^3P&&{oqI4Yy9fe6F zXP;)_0D0(S^Q-Tg+IvcQXfF0GTj9kgu(N@l_N9vO(~uPQVmyA1F%n_lgf4vipfOAb zljLL~RHYeFD6$i(Y;@BDR_J zzTfQh>Oc8;{{H8Dy7~n2Mdf=N_xQklN5OCIXswV(AXTmz%uOoJatf!X*s$0nzR35Z z(3bmS^D*gFuw_5Iy%(tzmL??;vNuUZh4M4=W+^VTTNF^{M>b)3Cb?1Bdc>ftNb?;| z+NuIyayZEc_7UX*?WD>KH!Ad=>#!f@DbflKB5;Te0wg%ln-<8Q{zQ`p_DoB)=S*Ox z)?`Y)*zz(gV>=l^y@Zj?US5R?S0mfLj^9MY&u9`rU?Bv%Iq3ItikUAyRD5du#2YWf zFDoHtoVLmcuT8bsASpdyS^^r_FrxUuRGEknYl&_>b;O>~S#Fh>5uGgPKEFx2+*2Yr z+=lc=t}J7o5jD%w@MjJ1I|A6ymECKc|NZ`N;V#X!|26LU&)t0Dx~8|1K)n-b3f+o6 znn#gjBjinQf%r1)be%qZVR}i_qZK1{L}0s60vlX#%`K}M0l7L-q-J5Ax6vzKC3XEA zG^E?^I4!Ct^Q3nEeM=$%n%w!CJ&KK*t5{MMm=86Cvcp(3kl9tk-p`8@CD)x&ko_U= zoc5};NQ{w;6yHIk6SI?zR*ld4MImYniB?HzN=5(LpVhJDD!5Yrs@(7U5B(9sf7k`I z)u$*~y-rm}l^_|UUQyDMJ;lXjol!e29Kd9yx_csVzO)~)THZ2a)4D|ht;M7;!ycCV zgT)C72Yc6G^#&dhaBk?-pH7Bp(eUD_QZzrgyoreZ4i;z`jzR<1t6mupG|#((!qNUq z1SJ)m`Z=zMC_mmo?}#{4keLv7!jgnCoFI|S+?I&fcFIub%FW64hdDcz9bceybMfHf z;P#h@iIJ`+U{ZAHdrz=ttjdoUl%^tEbm+5^*3_6$vM}|6Oxn;8m=@)`MW#`iP=b-~ ztb}q_R>G2Fo$HcHy=f*D| z%nmX~3w*qjgH(MiNdM=B+EE3+Jad6hzsHM{&HwxVi33A!ga$RiC7Ymvp~?l1!A5OB z?$fplI&JDfMj)Xn35hdfSX(o}Gs#f{=e3jz>Wre$(7`;E+^iW=QK3P^qpon|$(+|c zfhD;KXsfAvnC7GbGT0SyPIf2A4Bn=qNp56PH;iBx#eLQGzv>cCsn=244RV+0x>oLp z17Jjp#AYp98Vcq)SH$m4q7oE-t55z|6MBE1qx^)rg89sZ5bAQt-pfKLzpB;_rq(RO zJ_l50_nbFu`qn47h#bls+#9xUFz2T!ck6UjGv-BQqGhojmjEkcuaPR+0A`!@d0YKI zwjH<|VIFTZz*4;k=X(|H?90ngDl(xAVIH8?ty_Bx*$@Y23evzI(B>gQ$$w{Kpd~S+ za`)~{6+XK-9Lq75lctqoaq7=ib!6DIIMtD@W5W!^k5D>rU(ZcpPoX`FManf+jx?^o zn1KbcD7h}?C2~V<+{clM(%*#=UNTA(u#ua4AnyRq4-jtZ3{|1@a)~!5zTP@IN;c5K z%4vL)Il0Q^>(E=jHpywV2-I_;ZE|lbFDx)vU~M)Ld$tHjbY+ za|gZQdK1VUpK%_4PmaI*`iI~EFM{!(k z$OtB?Ox(If8F*@5W174JtYhu&I>l=EJf)Zp05J(Ej~qf)J$p8oG)h}1nI*MZX-vr% zgca}*9)r|_Skv_p8HD~?e+7LL*V)`~LzmGj{v(pI;xRiqMXww5eb(IK_B&PT)^Kl3 z*CKTr0^N6r&DL1Q_!6kcE8xfqf7$uXmMzIx+!N{iewlK~0=(ZPc?%(koi{PZ-i9t#2!}AQ>8Xq|k0H|C+=WCXf zstMaZ0X9lW^H<;&O_}Yr@Q_amr!~?*82|gvRplOK_w?%M;J9lnq}a!W+*O}mm);qe ztv?>CCl_DyyFYNx2zPK>=z|Lq@vVF@Zw1wOsj02|B(}~bwkba$ZkaBCP>Ky+ZC1w0 zHFWUQI^dsTd9hf;_ln$fT=p7~Cg}a5(?|{)23l99KZ?)y(G?Str?Jvpa!kZuRTEM) z=g>bT7kVgtohB>e;%JYlBL&Tgm~;W&xahzozlzhrPZLgYt@u0{RRtK!NsB0jMq>{P zoVYl!y&%PT|D|p(Ot`Qg{giij3*h-`r5Xh)!1I-2vdn;&fStmQJWHJ{&qtVYS@Rr) zEc`jyX+NatXE~@wS)njE^%hq{EBPSLZ#o*+yYIrJJYp9!7E3jZrXeQ4?-72sNPF=Iff1CQ+0Ve(!)9=Yn z%6lk$CitkhmYH(|TbZO#V;2*|<56m&#Q)6#GzNv*pzP%tjTv!)b;v)8?O^?BCSD_C z@UA|Tg2$4k`#Ijc1_B%AlSnhiT*=eO-Vg*>WF(%YgiDH4h2{~9D>n_)@UqhF3~xAn zF99<06X!|zrQQJk*dS*u9Vfw)LGQL3A{Tm5Y#?W7f5?Xa|HjI7U`PKJtf9EzaWwyLel2s3zSgFT# z^E}q~Vd6d8beo<3NWApLO}Yg=1F^w+Q*Qi`*POrhTku_>BT;}(9XqX!^I?wXY|qaQ z0ln|~@Eq8eC`Od%zTn1D_W z1k;q+&;wM^Z9=*{#qL`DueUt13s@NfSxjEDO0p`D2I`3Oc{6m>1&@CB9}H+~0so%N z#d<3u_if1~`847__0q7C84q0`v7nt#5JfVAa4ie8@dJ^#31lS)^X`#F09@f@V#Y;+ za@rX;hw@h>e#8Td(T>6;Z=>rliuDB{IfToabHVJ4jc4VtnAwg3{~xKz(z+2x0sSNO zJa$ND)aW*28z2b;+jD3|Jfd>O#!P0cL~;nkX%o$^le*+e5<-$U!2Aj&QFl3)Y3_@s zFaGS4@BOO!>-#UBR;&BVB_VeTv_q?TM1O0_Po)loiDCrkh2+9;@K8YFf^oK>yZ!d$ zWVD1!cO5Tk2mAAJ3tGlTKN*3BvZB2foI3>s@b92ErzV|`(REyFqbQRO0dWMNJzWHv zYPm8%RkVq5J5GfZ&XmW4QiiY`2+bnvbE%0`gGze zFQmTVj4{hI*Y0-Y;%OQ*aet8o&V;=x`b$@SV;L_@?8JNR;$(P)-_BJJE~XrY_!Ebf z(HvSRDKm#ul>22HT1Km=kM6YJqYFStb~hitIC5v+)s0L;DuFu}CkY8^4>=dqOT~SN_JILYOhd*M!947tohy5T?DAh|=6?$R-?H^7~dfFQ-IDV8H{ zrV$UY%=m!z7hUBSf7E)UY^wY9PpU;Sq6K{(Tr$wE8wrsiO6VM#Xg*S4pm3HD8KM}q z#M#Evh`=-Sq7zTg?(Apeekpdl`a+DlUE<8%NQvkCvERg$tec0JZ(u(7QL#JByRbb)te?G!#(a;+7;H1CMa|Ak&rxQ&FJDv4bwu2n z-*WU&(p2u_?b6+^R`1`x`%nLH_mfXf4qp7#>HPS?A3)JePunaNDhbqqNKr6jM>qnV zPlh6uNaX6IC-GuOFavIi^pX#ZjkKs5uAoy^rABhA&8 zM+C!6LskRg3*BkV2a=O}?tDVk5Y7mkI*x!Si9`x30}PoD8^?ndiWxyWvePuZu$U1t zj+bB($fIuOoT0$sOjG?zH*;#pBu)yYj%NnP$(TIBjcMDN)$2M8dW~~r9=uv-utg0o zz4mBln~T#Ay;w_=GD&&p>xmK)c`F~5nscm)W6(0p^SRtMB-%Q1U+z^r6);2BUkvV1 zYV6Q*5q%5Xx$FRUN~gZ|M)rnDkkij~=xh3lZzBcz^6CBee}t_aRzJKK&5R|fmLU*u(3lH}yPQ}GfKL(+-*wKvv_YDf6#%!rqlqGos)9QO7g_FX2Z&4|MbQ~hAGbVs zE~qD}j$MU~KeIBIG}2h!ns%aiiP?S~^@?^%E`(f}ICI5fuD5Ja%<5)C8m97Bd`52U z(=N|!954oAm{(Z{{QCHuBlQ;Zz~_thFYroQ^PwmtiF$ktTq$Tya5k}HVK>^NhMZg4 zWPF{gg&ylBB=%57+Xl`veyH`_*~Xp&Ug#59!=@_h%9%T|jwz7JeHI3dGg6m@BY7j`bYorv-$oHKY8%r^nUaB zzwI917}TJ)umye07cQEVw0VnI3>^DMsTOj4+=mr zc$Q2(UYwk{LW*1P%Uc*4`)w{KtlP|=KX;*in|=ZAIQ<+KNM)0b1B97oAMRnDdE1WB zNetu%I)D#0UE&-SN)KN6@TrgdKvT|04ib@0W`KKI?%sfhx!@mp)?@impt{~GR1d6& znW#X~i{9D*$HRHaT%}9{XTdN*BL``MM;_5r1?T5)vj%rUF?&4({88YpClL01d0Q`d zwCH*CAFo=!FY*lICBqvKGbuVpL8tpwAt?)XN)3Gpx0Sn8-yo!aA0-Nvf=tN-=y9{iX8^e;dC_5S|7f4ck058H=_UBIyche44jT>~R{ zY0)#urT+y>9dZ)&9E6mFE-r-y3_I5{vO*kMssRV$B*`rY`;&2x!*Zat6uD6~v7xyO&D%@ZQ`9GXMjOe$W0FM%;(P?oF4xZm;^)l@-kLNK&s zRgqot{^*^^Uu-9X05&PiAdH_MGxN|)HGqptbG#ul?)12UzDH~j)|HsJbEAe8bT~9H z=SOZ@20m|Zb;d&vC%CBJ!|JB(>I%!-CUW17b5|mlafqKQw@81`&9FjBTdM^>{T1M@ zFrAaIj%VOy90EG1o#>Y@`HLS31?~VPfxD;RQI%AlJe0q6TU6K9n&FM>Cf8~M=sMqk znDZZ*p14)kz{l0AjtXoK|N5=^0Um~Xi;51DdE+kQOlbJe5wjkHx+Dd}0x`!yiwxDl z=sa`UJ_Eo<4=Tw`loPF}`kE+f%WRC8@F7+{`qanqvlt@9>j;HeM@mC{(YvmrLS_O3 zu>`5ygOZi7)kV0_VNT!c{LWv@LFz!c^UYvzs2r?Dh1VNMHy?5#xP#7Yyvd`R31|&d z!62_M2EjSFh=q#SFoHSZr1=0cmM|_74$QZM%;KiB7!xgkl^x>!^NWAh3BAfQ~MyZ{$ojP0sP6!+g#xgbX zth_PV+QT`mglO5ENW4e}$PaLDs1Sh&UJxwG^v|R6v(yUq|LDQN z$@gA-aMEs{{OliodaspS9<^(w!7)AX$Zmp!Q5uYN<`^w-Wm__uVO2!cCOT0+N}CM> z?n%@#H0YqhlgK?9M=i5kp_jB2OI*kd6dsGyn&T7LFo)9LP6jRO$lW2B=4r`zFglpD zsjA8)Qv^{zGs_iJD4Cd8D9r^e9#|m)HzLOZ_^_DeD!cGT;V9<7uFsWXMI&^kpB7{eREf3Y#Dz#Hcvr{5T7LO4!A$`>zBwhLfqx27k5elkaG;uX*`66%&*b-UwZdfg5ZAR>3UFCYR$&5v|~^%UF zQ8<$9DRS?jh4LysUTmmVj9TVHbnX!P873+}@)h8&qc!Kj0D=%qG0PXu%)jz0FEiJG zuo4@GIusKh_piL*-|bJDy>x5yg#@#i%V;)C?DeHhDHU!1ZoB&RKiD8kn$nKT0rVRyLN2l@LI2NnePg7ry*Aco1}Cngs>d z*uW|~_m$W#G}f6h$EMZFBlvAl`}_;hD1QnS*=yq#A)@tpf#K!&li5KoTaNOgeI+LY zy~3AA{=sRmLLwKY!DY3pS8GYLooDXPuP-Ov2--nXT+|eiIfK4flyE1fDJC)RO}LDk zUgoMNxw6+T6&t%ZuJgw#wV7tSz1(kCtIgdTjS~HiD3(mZ)?%LmxL>b!AMU9H@=E$dSt<7pbdD-jb+B>JfEh!nwdy{) zv=pQ@_K+iX!+d;(9)@OlM=sdxX4y-SeIRnDLB?c4BfC6M#0}0c;$Xi^{|?aFl$~-}Q#Iz6j|W&Z zBo)hLk~5qD4!RXoAxZs}jk9U|f{X}ixzA#Q;xugG*xluk3E`0}{_4M6k)=aZrkVe)w^44VY*WG)2ms8XDu zI~bR?NRh(0weW=W0!=azq(Sp`CA$~UaxcqzZaZGM_0iuzy5CylnRZ}?6kI>NIv)Mu z^Wd&S(uJza^y_VmJvnNkLxoXVaF9RvmV&#&RKrV{Tb>~`v-kyv$sNMlo^f425uV^| z0(^Afz7;=5&cR)v&Ap|`3-ID+^f6}d&2EZwhZ}|b;NoHvzHzUU{r*?L-LUuYuS7r! zn!Z7BXY~yK69S3<%210j;QRrd8~~97$I4-tWBkGw1d04bU~V=M)S?~Ef7QWjBkTr< zF5HyiWYf2^|G|0*WY#cdz+FjsOkttJ0F3n~=_-l%p*mLQjTLR7S1UFq(`viD1p~{D zC$?iSDCxB1H3&kw1aFh$adR>rW48q%KNcZRZw)Q~ud>ck&`4j0uylRiHM=C>B&SF0 zo{!Y=ka2Ne87>MI`Ys<*gek=Vaqx2|GZ$c3vxO}o=)E(Cx~})|U&VF#&r@(8Xi}iC2<(#Vafexe^ThzAlRoDIK3c$GWF}^S zKmR3@%sQq=Xl*_rb14e~weyfQy+lKG5+>9it*fd?N+NF`lqxKslSGT|bY3-)JK)Zw zS;$nV&IjC+XW&j_s`4%^F%mIm544R;A4Qxh^Rx#v;O=C$RtLkDe+KT%4j>}nE)#fY zK!JNCf7G5{AL8yyxW3jID0HWRp=A+%J08Ahlv9nmDDCAmjDtWMlKu3P2S0xC{(q60 z^Ur^M_g{WUsgwlxDJ~5y>Oz>P0`*9AKvaYT5F^tOSzv`8o&N~u>Ftq(+9$D6@*NNsrlOP@OyirvR$A9R}f-NQZuAh_p%p}uG}MRCRwgE zC~>~l-xmfXzqg(LiVtE>p_@5*B*uX|_EGr(eg$qwP(rh5gMKT}s*5fnksNj|*GZbzh4s<(0q|6q zAJCobG^2$)5fcNtwd$@bw5y2n?>~6(vj_L@{`3F$?oR>uyT96RSztTa55n^urT``@ z7#0Nd7We^oiNevK(`Ajb zwkmd6aZ{nX_LkXxFY8gfn@oO1hql0&pkAoYq*Jc%jTi9}AxIcaR;#t&6_lBa9)) zMNj_S9wYLjhp;v$oj%{8i!L89L-CTiK9hOvzT#x;Sj@J*V$ZKz@!>i`EzbB(G;PCt z3h70+^8%@6cs<+t&#rmi~`}OV>en=!@}L=w4@f=ZvQcoH)>ZQiW-;>@6fS)$Y>OJ3@XTb>=wsD3nCv z2i5PoWpxv2c5rUQWWCdwW3+z3Cja6p`GV?jv^r#KyBNd+Ruai^jm6SAGZAtv8imCd zMifDfha8jsLN$6*4BJc&^*9ZTDvL~A#=1!)LeTLn2IPIaZ4(<~z&0-TqOon}4tF@O zx>@9I0{1l4`2|DE1Vrv?itS^eIo!pg#p06pGbuXPjf);0kP*U6x@5z31MVYNmqj#z zK8buNEJrtxT&5A@7-g6yEHtfr0;eKz6$@XtJY{tHrL8S`ZFuFA z2mj~y?mxIo5!TOs`qO^`+W+CF`%BcrAqjc(r8`_M7Q7tTUZoKhr4Ni(A)2NFDrzY) z(ikoA9ka}p!%b$l=bhCSR8od~IkXHtu?@KUrFo|uMv`#-O7L)#EL6lqIoYk-`{Nj}(g>U-JJjfLdNy_DC zNN30-*_CnwX^n60W{!m)IqxWpz%;CYeDk}QV3gk9%wGL&@5=e&rZS_B>T#Xj;|eg_ zI)p;@&A%jWuW)CE66OF|i=0WkFZy_j(PD^$iS0lZVrzr$fbTc30n(oRWQ}aAd2!_Ixt#E@&ib&sN6=^D1%3%64rqDKFrB;Ue5saURH=y3`yBzDoV$1r8APRF~ALFw>tYf%N&|K(5r>@NWIyZ`)W z5B~7(-T&iHmrj%l!0jBjSXwt@SfC4QXXu7>jFR00;z-hx;53Z^X@2PCxd4*#@CS)( zN}t-j?Ie>!KG~u`wVl!=9&^h0xfe)F;m^}Yho=Dql%F8uu8xTM0?&{b6C?!aU?+lBsEIgZQzUm7XCt=50%0LGJW__I{ z#K8oGbf*FFE+)|OGo?1VE z1ZdAT&4UT^!CWskSA%&IfxEbT8(9iVoh%U~Fr(QAPMrQnEgWCzu!eRJ)McII=V&dL-jP0_pBxjMDdEn7!%E32}WEQVe*{xdxds~ zc6_WMS}pjR5$w(L{9i0~@Mteq%Ok`-J#hl}9jxE6*#8hRvPhk!eaDeNZ&?s%eiT0uR@-A?3gz&&ZVrUx}{0O1xA zOTfL>z(~xA6Zz;2vm9A36xVe}WI603u|*vHaih^M?caNF_lFPuj3TVNcOU%WpWeUs z7x$}6gbkHKjudmk$>;5ag)z)zSgUaHAdTnBG^ua)pEe$3Q?2bJx1xeGXatrg#da?i z0o;?;A%I>XAYl%t-8s!V)L)M{Iz;G+L-R+bxypyQLHwKme&K(G&OOGRYm#sZKv)mR zb%U-UUweadH_Lx+7PLW(Rg7Y{^-c7(-{bf6L{OR=lKhAK3F*FzV!ugNfB7PqQEeZ3iRen{&{lLo686YZ>{DA&wmn2&3_ zXa|z{x&e3C9B4`ifLxBZzUZ01^JD8v+b1Uwr`nDsr^y*y^tKpkQ>8Cp^i@am!g*Fk0vNG!9LoBQ&9qG&BE3$(A`CgdCIFT?1T~vH zuX5mm-i47S(P2tdS#X%8O^!gC1(Ns~JsbRPtz=!ebfHPm@3RtuOb)q0VMo|WCIM9+ zve@MTqhEn*P`(W_K1(eC03ZNKL_t(;&?7!mCX1OwvQLgO=pLMmu#Sx2Hl9?Zp^e!D z`8lPcWm-bCLy0idGBtq&lW@?Up(QU?7Z#HRefE&mm%7qSGB4VBIA>Pb?1wIQz(qgu z!Gr;zEQ!>4ADYMnbt%1@UT^CmFRJbS$nZFpEsxdQLVKlp}tYcGml<)O##YO z@|UU7sTGitaG@fZUr-Pg__^&QYZ;;lxMv(?U~dqChE|OR;FUndLN-q5RkyAY1iqzg zq?-R2vd|1|}hic=v6(HnbSUIgU*y#GY$}@>boJR`YsMBeOY2m0^Qz>%ygYw{@ zWy9>~ZYM;xo%Y~(NTt#GDp5@wfdF{M9itd3OvbZE%cH|qjU;uaKkT0V!Gn7z1ndtU z{Pdq5oSZJ(<^4)PK%?Ho<`)C`J#~Gh)tghw>lkp?jLda9pouZyZUON8fxk-hLuE_9Tc>ZF(=v}7mP zaFzkTb!e=HKu`0K3d*zsI@`!}CRnGCQo#Noq$vk&uB)YCv(ae~%C2fH-a8D{X^{B& zqAeatc0u1>%JEZQIJzEWO{I*Kw&r2 zPOUj6O|+!pw2mdmBu;uH(|6FB$# z_wIx3Zmd@!6YgL2;Bc6pgR6x~3;VBWw?gk$bX6?u=+#FyH4`ir^D#U+6q?Gq)D@SAn|*)kJ^X z223QN7*!2RdSLPY*ZAsjMA`z@pY$)ssEEko;(6qvQ~rB=jEPjFdVV`c-X>;qZ!Z_! zG7RHn_xkmB-?+y1?zMN{y*_TvhxB5vcwkH&b59CC@=Rdfg*f7hZ~WwqH{L!t7|&Tns~IsjsBXiruz2IP27Xw=gEGQJJjJ(J z?OeD6zvF{cVGw4rDY-$pN>WV{bTnVuBH}&;9e|JzF0$bg-lgZx?)A4heQ&JK-ma8~ ztWr!_PQIR>C54bmj-H8dv{cQ}_b8|=mbVudU*;iN#L(575UqrvY5;|s+Qev`tpM1I zj0uRM76M2Y@aC#PD_B7aL5<|3qpQfJd=b}?rAwHqzw*Y6tpW|!8?>3zVRJ*ng&HM} zh?)uP)U#+vaye-Ia&cE) zSanQg+Q1A#zP2l-T~nP@lVF#EVXhx>yX&Aw(TsNLOB=wd5KyaIb`1)Ku~~AJt;iZ5 z9}lJ@Q=K1;Fwb4Mp%C%PY*Am(-IszlPc#%4K&CHL4PnsVH8$utmvn~`~%_SwTs6?7@jnR`OI=QE-vI> zOXO3zge>ixNcMD40^9*prZ9nQ9?4Cc1}DqUU+DTx15Rd@qG(&)%+YBcg@wv;|NevF zz59Ro;694TQ#3NstE5iYSPn5;Ib04*A9Lzv8CelEs?OcZA#H(_VIUAeYA!XpJ?0Q* zqdp!lm*{LaQDGp;7;I9QUGN-cdl1hbce-V4(+9vUV81d z*Epyv-?{Q1|F<8!_R>q&-gq15QI$WMz=k{cf)k}$UV(cEgKB~)R_rj?-we15c7bfB zB>iXpM{RJyrjktVb3#lLAbVcBOBv4FZ~T(er-RhS(Z2N3Pu^e>Lm#sAKu|ah(qVbH z#x;@3IOTGh1zY`HCWW`Z;v(PWa^Ahczwvn7=pc}&wLxuhKZMlE)oKTQw3VbZz@$u} zq>1#AjnRLLvDW+FIJj}3x6{Vkbvk{;x!87qXFe-%JPgd8%gqaf05eQStj)z?Be_P$ zk&pQFe;)Q6Xyng;tflXIX&mbemmg{3!$=TaBO!02T41_x-|#=N@>gm1vMw6K7J~t z76-(#=3;aw+;2C>eOGVdlRL+%My)_a8Pg_P>%;&<1LJ65*!Q5+86fhpak?*Tbqu(Z zKQ-5@G~x})Ksm3lrFE*G=*?7S7p+7+n-4492EDGWM1)>f%y>l6Dh92&{`NK`tj-*y zHi@1gJ+qb77PzwjOVCn}O44&$M$a<_GiTr~x7&iu7wD_UybEu>fB$|7gulOZ_qLe7 zIh`S_yfiXMsc>#vl!^z_uIr11g7-(E%b?-47B0#RL?wWK&*5olD1KT=t?0oQ&=k=U zxF5o^iO;6(be32SU@t_0h{bHdDqzu~;n&4az3An?$zzbK zS|_9gkY1%l^oLg9!kywyBjggCc&c>K{Ppg&zx=@uuDtT>v(H_=wBDY5_LWzz{NVkU zuDyFu>>~dLEW~R>V1)H@2^LKp7V%3ruD$gB``^9rGJolP{^>uqx88b-h0oi&FdTGy zQ!6Ca0NRLyfM+uu72q4*d;vYzhW-Mgdg^ zgX=v^L|`^xP{?1hfk#38kCm% z;%3gcrA3eCMqf${fbz835^Zq=oNLI!LLqy!M|`an4yH6Ecy$uAh(1-ogqB@m>^zN9 zyVKoi839!iS|AcJ6*rFC?Q~dt)FnC;xWlrTLWvOkzqbR82G_&< zl#gCbrLJygvlrhozyeQA0T7b=;VKd?I)8cPvbIZK<3IDn%TGL`C-Zc^e)l>_k}nR< zx8ZjZ5|(DyFs!sn#p`dp_5PJtp1%C#rOQtM>rbq=Cv_B0Jag$X5dRt|h$%C-Gbs)z zfp5bxd}$xR0V9Lr>J!cY#NFcC*S`CMS6|_ba9n(ShV2O**V*>Um6xu)-9Z(M$S!~3 z8cP{8#579y0j0OQ)ndQ(74yKCcIY>JfKXF}3@d(!q<&G>8q~R8_$EYzqyhvmL@TxN z+b{g+wJXmuajlQ-lFp$yLcYGDlXpP31i`yFU_a~Bg$;y$N_ZyH!Rp=DUNKK+^85UC z&ZD}H^&s;h6CzXM`|rQ-*4w*+cQotfEr_|eyV!5=H$$uCx2`;A-p;)4(lgo{4ZL|D z^LETWPd{fSSQZ#By>)GuNSBUF_6!h5BuQ%LVK!WTRpi*9`gwD(G)HAR?II}T3^@ox zp#VTe(*tA1!J+h{lAcrpWE5NlVY}u?@+5ApN?Nt;u_hw6Y}fiU>zGm{rE|+Qt!i=( zfeq}@rq5N86T9?G-d?Evf^c_!#sw2htM+2$CpoGrai>c zT+(lk22p4}0QbN7{)e>Nru`jEJHExd8F}ID6#nQ-tRSCPi*eo`hJ7j+<~-^vi|&2{ z&w9ip90qW1i@1PJu?jFB^=Nl^LmZ87o5)O*{8H&l>>ruj0rwbbXe;V$^(R$H-@#p+ zBFW(rLpYnx<%{gvR3Gl@w+)5om1C&{L!rDYPqoVcob`I|5H;#x~8+`xK zHB@Gmz~c_8>)QJEZLGVrUy3XMcX80WZ@u=)Gk^={DWu~y*J|_?IAPJ*WSN@aGMUx>Q9}M4pjVE!< znydVCm-;h|9Tz{VxF;?@adwS7^USlazVya!bwPKXjOK?N|3jlPWr(zE&)>Sj$TG^8 zo_hLe-j(;&eev?k>>2O&1h>Y^PrYn*mXo91`_WtPc1kWzP@qAYq^b4`zW^M}DXD^bpBjCbSeS6J+X7NP5`V3+1;twl8gDM>OYi%ZEKI6fQb_X^f1=BnGh$<4mC zLF^g_H+Au0q;DU)#>G-@bV?P3^EoD1^yF@7JTJSzdI1aQdITj+&FvvZ4B&L4c{^Bo z4P3>{)5TB-+?m>_@W1EgP&QfAhoY51WDu55=3O*(9K7@~oM&^8)PyZ7=;HMhZ0wEkiqVq;;A5GK{INK z){0`=Ygcy%TPy)Wso2s!Q)RiAQN?Xms#ex1l?*JY1UsBzVii(GOp)5as1(0C#gezx?v0%kS?lzLoSeUQ4+;D_DUD_$O!p z0v~P$BhG%i%uUFjFJFH4)$hK+LJg~Bg+Uiyv;WQy>K{6JFZRbV6P%*f9?qnpHIF$gI zU%&R+OYe45dWvgHr(nKC`h!)xxI*!3%&BT#2OZ|8VcfYh*AVKp zI*pZ}*kIH8oU5`iBpy^MJ#@R%$+YV^X)LJ#JcnAB9C_J9wAUTY#{*^&WZy}2lgsWY zs&|P08fSmGCac!z8kP%D^>JN`Idx$@x+RsUK+T5^lr;<39`%#x^vGYTcpprn)>TF~ zjdJ_K&@OV-UF|m8%Y055fHdG<0Nj86A?>zrBTz}Ij$j+$jH24Zy#eE}#`9aa)FbGs zbUSqB0Nc^jAlIhYY1Pp>g+vf%)sN4%5KXq1Hl?nN77_Wl(Pl=Mw1=f09+AO_M5zIH zQ;0+M2C_AWkMO>WWxSuUbRe7qOn~R}QP0etTrNU)CQ!IAen?gD=RDfO4GeZh@a@pj z)?=YDvok3?a2Ov(0@Qb4rW~(TYS0lydLHO}!mjlSl|(B+%%H&nHBr~}O!cvr60sTg z86~vYJcZN(ciNj%xP%=KS#N()Cd1GR9Hj1rJhT%lw7o2f8$-O)Qxiq6VQ zS6+E-4er|)eG&&ss*mOR^x)b{Ks$3Y==sExhE+Q|PIJS;BQffBmNERV0lVBz|Lc%f{{l@85lckc_1TSP3N(!heI_0r?Gn!Lg10GM2){ zy;!DFZ1kh7LVyA`opcxmz}=t~%l?qoZgZSr$$Nvea#VrmB_vN-63U>Hq4V`N%rZhg z5}-H^!^I5=QDeE7>sYES5XQxqlFv#iLzI&$aYqC_iBVJ<5ZXc?jqF_DIg zfv2$epNDvK*0>7B8Ib{ z%!-rW&MsrU)NHz{_5bJJeEpW|$Id@hzpd9*&~%a%6OeE_Zb#hm{B4loY@fB?|Jo*e zzx2vWZ{XV#pY7zo=Bv+PAUg}Ur02uMw6k@MW;SFTk(lKL7`4pF;$b~3r3ePt>i836tA*^P0w z#6LS}X1BHfYEj2qXH*1fmk(8E`k)u9butV7;HYHFSybM!@-cJ;nQS zVxGGE|f(A_H2gwGgPQ^qtUHRO@j z>Vs)_St*b$WnZH9*7IY;Q9)fTq*-vTI?Zmyp=?b08x*HVLdPAZ6}&sGf~v=SlBrQY z>^G+SZY;+;61m6l>yP@*ew98aWIh>E9UU7(%tgpce7tX9$nYy+_vo%dj}=ZDl~`UO zxs8}r8DX3BGJf>#g8tZw+ie`s3B<+0b0(M}j3)((R0croO2z>~IO2GoH8--RxWX!q zDeapI)dDO`mTrFCK0FRYkP1_bZ)Rd|Z$~x<+tI7J9AlaL3UF8MU%46Ge)w8oe9;IDZXd$OR%tHvMdNiF-#|j_vF{_{PszX+uXb+NvVccJ^1k>o-_igam8F7wzSF z*JOS#M~b<7@{|7vpDub-8yXVsHys!-0U~HKH{klux~nfe@$?UVGO1N&@g1&<^{#RM zseYO{wc^2ni5K&+Wn>OD_K_;)^tmn+kx6Dn@f$nJ)3s|~*bq0#r|&axH%E>#O_4K- zD;+$?Cb%?Xwmy8|&K#)52n{|>-C1%it3Q5UNj=Wl8sp5G3Wfp&5Xf$zjF^_B9@z5~ z)bP`1>yKSyy^ zF$acTOMlYQG6EbtcRAjEtg%&78six73)y4zbW&BoLQ@_E9bizNXrep+@h|_Q_Wbg9 z-q0ecPD;sl6eXoe^ubh;C?T5JV_`f{|sbSVzPl_@(+e7|C$#9Nai!c3j`MDqb z9# z?E7y+yc26Gcjj|?IV3yM>b&&|@1lr}hRz2o%0#l)E1E(j?)Eg7m2PMV3UGl-U#B7x;y>1)H8#S1 zkAfAVYTruNp`(yoFWupI7kr~?3$#n-DEh=w7w4N}4Bbzv`->$ypdjP(B1<=;-cXzB z*Gyqkj8+{s(|vZS>yi^m5tmq+9FUdt%{368sXKQ?4do`a#qy?0&9SLCX7^ZLKu46D z$2ho)W&#nZQq3$-%lyqpckV1JWN3X_o^oMuu0dn3&>JD$uVkQBdX?IwdCCNbUnuI3 zgcY(pz*pUpUn}V_%R;YSUXU8)nu2#w$d7In`+CVMVa6BxRfG|NxP11H{m;Nt7lP%y z*za+SXE!8ok5VwGL5D1Wa`hr-zj3^Dlmy|rSGhA8^s`rRB{6wLlp#&%xKmE{h%17) zq)@rNKOY~j4(X0dHRKGXHK)xRqb<%LgABWcfKQ7voDT*Q=Brc+0~;+* zX2>7Qivsf*hs^qUw~E08pummCeU(6(0~tiUKy>@e9rgS$J`XRCfIE#vh>skXC`4B~ z7pl1$fjho)C7$0&{PD9*f6>O%4J=-M>3R(1ri-+~^04^0?>){|4MC4`J}t?aG*F zScT#4FaP78TvB|;Z7AA;S;+)u<`}f7UmwiFZ%^u&o__TwH;dePLPdho)tPs8S#lL0I7)S3X$Sp-XTxJV)aE9e4Y;nSBc zJ^Mbi0E90KH|}^M9h&s&E~c|5tM}^eweNlhm;%;bxi$=#qu_u+Gqkr{*g9Mh#M&4a zrZW9em%c(HVLUSu=|Az6f_DTF3dDVT$ACN2I@354CL!s;wI7*K{F!H71>AvQ*i4qa z2HffLxh*v2J2Wl#`A^>ell3I5vqjEW!W52py*)gG<}nk9Klg*T4$2`~@|anbpgkdS zWadXL!@0d|I1;_V6HmSTG_#@^q?ex}WO?F=mtTJFvXY}_lc1DmU%qtZg*S?TyM>1j zwVYrZ?;G~UXW%Y$*ImQyfb7adK1`2i^bgYpgxUJ7d5Bx;>8D=3Hg35JRx$sv>vV4B zhJJYBVP?26z#8g!rp;jm{vb|oQ{%+S?F6`UA(@$_j2*5DGk& z0S{9E03ZNKL_t&!A@~?h9+DWHKGqu)(l23AAOpty>vRUIa;r@cPhHrO3iZ!z;1kLd zPO~=ki-lfh{sH;(tn`tr=o-MSmmW=!DD7!uJX)w71)j_#Z7 zc(4%XE^k9$?waZpMO@6vA_#h3YejsEu_NTiqIyhq51P@O>d`WVLjrgDM{#di3Gx+A ztKS(CxJ#XT#OMelFjh`_c8DJY3ACBQx;Jv1!wI=mEj63I52#nB4>m0AUy??J#Gbph0f{ zlCfga3l+KwRnImqB!-^2g2j}+tl`nXp`O8FOFhS_U?9GSctdssxU@^VZ@u~)N=FVs zcRz3k*l|=^pR70YE2zOCv2Z4c(=#tU_v$sADYA~F!7BI=$tDJpfU2|z1}L_5E$HHp<-r~91ys|+X1|@GZ@J1=iGcV6_tN?sqiA-_yKyTSmfr$JB#SRGu*$=OT ze37(no@Rex0hx(S5!1&XeoPTlB?4h@M3CwM$WpfFl{;A8lEja&u%r6E&0CoSb0JhV z6~;sNM>4^3XNfGbhBqbabHp~R9Gb(HQ4OW@SdD@A6qp?>fkTd$l}moc^@PKV-JSQ# zLFCLUS3^yNg6gOQft3PKh?~rvCcetikLEh(0*@+4V7z(024JS{D46{_=@6|hDJ1Y4 zbF?-ZbOKW@HN8a7PDBwwwx?8PxgjOQnjRT4$##+~YcSKN{D9CYQpaZ@kw1&vVdg=& z9>uFz+Z%A_m3TXXlmO2#SZIFxePZ#z}*S9R4&$Dx?8|m!U)<>J)I8;TU1a+W;V+Ko_A51;<6sC4$PkK31 zWR8oQtC#>#84Ds?N)Aa)0PZPt59EQVQsJxKmKW=J+6=h!Tyk&9>d`OeWpZWLrJx~U($cDpx7Lwps5Bw2kI%f&jD`Vsy>^?Aaw4%z zYy8%$PZ6yP+f8UoXlTd^0Tn=J4p(1vkowNwl~A~jQz~I2v?C-)z>r1A z_Ru<^xjt6?oo8_JF1>nfQlqxh7i$k=r|`;8^w*I)7y9|y(}dSgY0wnTKmE*8aN`PG zL^+!Lx}aKc|H@nA8hj#X%EH=2?uj#S*JY(oJUaz^zFwd`;r=mieRdwWPmEMmH_mHs z^m~3@YDB_Ub}cw^bYelxthxFbP=ZLSMw{f&r;!tbXED$`%&cjy2y?R}oG|RQK=)dk zE0EF|tZ>xG2|F#Mg-*6z9vpX8Xj#_wQ~I>Ex-U4yPJW8vZ&TZG^MGbhBxk2pZRIMR zI)wD?MNj_iY$i1gEFsDEwJhcOB!XvSy$OO^nHKd-rCtHmh`Lp=v8Nc;_8WaD_hg=c zp1T%WvqI#Kso@f8*N-Wb0xFRUs*_Y0i=@KkunCxp*o>tpUu%~;10+z6BB}@) z&`NjEdER9`!A)-EGpJMu+{F|*BqPL9XE3y%vSbh)#Pz)`gE~GOWe+5`Z^rR#kxX|L zrY3|qEJwKC)KHdVlVP?Jk?p!~MrmIT>iCI#5SsN(~eDEd5lc%|V&qoXMFL zE~yB4!0F0MAO=9Oj&Lbs%Ei%bDSC4I!fOH}sg#xv2A?tL}_wr3RX@)u26 z{8@`=bMQJE9(wXg5^03EZI+?Lw}889(csc^poCH!oIduKP@V+_e}PS=;*HHo?*?_uN!4M(DPMVu)IF0`1};1vlVSic_1m2{Ub~{29W~jpxxtL2__MvD01gy^U=D3&)y5+jRI`2o!1G589Vbq=7QkO^`R`}u3Rfp zgJLx9pO4&4M8rI$xj~GPHuLstOlNoWPl9}*yMiIMr(b)!z~4x8Ic; z!xKxa%a%eX@!TW_6`OavqbfZ)re|L65=>&3u**NpePzLbD_g6@`3A=+>Py6+Wr!|p zYQl)NELr6o(W)B|8wlMo_)*-3p{Q-Lt^Ll5*cAS6kEL0ZuS+6#bnZm%gf!eEKI=ig zF=rg152-DJKuzSj&1TuS64u&@;}4W(ti5us4nDL%fssN`pR zbhzVEh6%|WelR#ZsuaYdlJ(1x{7FNgQ`B2+=hwjqY9DZ%(FA7O{Z6R|sQ3v;Up+<) ziJXyn3Kvdx)7+N;EJuz4p%8UAWJIRaalvR+)cy}zh-C!wLsRn0>zNHO0oHp{s8pg^ zEeap$Tl^5$N@7p!=9MS#Qx?Ynl-QhGd@zSfOk`Dr>$j)#VQ)R%fR$$`ArL&jQ2uRj zeT794knB#bIb$;dYU}ab-FuAaiXj23)jVq6S6}WSA0r0xG*fjBJUOYcK zlMj!&wdBXf!AJrb#1Z0vGKPvsL?Oa zY1VQW-7|1!(xL%x_wARSz5E>iIJNwD32^t)65<&c*AH4Wan{ID8F1Isx)#PT$szsL zKSSN9mn#Rq9wlrB%$49IxME=^-PMiPSorAz(#3W8$t!P^9k88vh$~mZjf~U{Oci-F zaf{+L<}ciIA5|=vnK$t&T#+^@YH7ood$_D}q_hd>wG-j$ebj5^ClO zk)5E`D{QR*@a`hO^HBzQwB!Ja>vh@-fjx&)Y-L9+W23Mj=V7W?Sw)GkU=s<`hIc=6 zaBr6}+wAw{-aZ)gjm2-LDDO>rt+IaLmc{xUMg|+*L>Q9g!}k~63|j6jOwXBOJi>dO zJ$5%$==BHaX{q$*0>Lte;Mu5Ueoo|`0{aLrK)f6=8Ae}A#5^@T3Q$EtvrIMCO4?J~ zija`hLC@NT_#^!sRxlPgboc1;8&VVGv{&;%w^Hb_bY!ukRW{=Lzj}U22A7mR1yoj^ z`X3Z6!Rd59a-rPMMp!o=_Yz7M*rS@nOC&U)xHapf$QcK)G6Hwb#2UQxbmB)#u%F7{ z4tILGj~D(BGvGtlak$PQbYQlHBNXmTju{MGNkGN8X#jVb;k25Ak<0Qd zbTUyIdUIX5!vSXe#6bf0kOq9iEi+Yuj#@bQQJ=`_Hv#w0Mege;NS7kyGj=N&m3)ou zkN^0U7Y?Z6!vcsq(`+KgL0|5EC>S7$0TL{n?bw;=D1fF~V*a4Hfb}!ruE7+b5fy^% z4i#}Gp?Qvb2Gl@*o)5O`3+Feg7eLVHwYrC+G^okux2?eIPOg0iu=;Fj(ha91@YB!Y zB=f=xzr;l3g%_{{`Ob4x66(0krkh%K;H6i7IcX8j(yR|W+wn~ z{sZ{e2e77{4Z3^Wj$hsgBw=LCV1Vnqjo_V``wN?9J-AL1*&;kd(h zsknto67HEDzx32|2mxPs>zCL;vi;=RTQ9tHg+l|V47Q^NK_B!KKs6?Gcj(cm$i1L= zCkME{_T*&&(;2!8+;isaX><{V`5Y?vOlMxuH^5nr(gFiJ6rx z)g_MDz4ezbz4W73Uy&3@@5c2jFg4)*^mkqu*O>nWgcQEWcP}GahNLG?Tu1ItQ1!$$ zE~_DZXM6TJtp+qX@G0Q7_LA#GdDbh}Iyl!BkfRv2%tOxoVdTzEFstgF%$f~Y_vaS&6bPF96hw#!&GiroL^<2&?;i~5|MG;J@9^1umjD8@Dm{Pugb&U6&$ zmQq*o3MQbSerQ={p-+!$tWQhrBkGs5lu3pt_#vJ=NT2w&A*Vsq>GUwW*x%m*UBUPe zX{eM*1jE?7DE`)_YnRZHIzX?@e&V6PVw5@4EY2BniG+BniQI)&hEl`Q zXocyHAmIy~>ofroSz?wa=uHr}>JpA51*&Gp&%c-$@BEjC-*txyL=`H1rj}XX913T& zedh-t-@mfG@D_$hZ~Z0z1Cg-P3fvXB!_XQ91;fnQCvsO3i0m5w)(kXZsV`9GYL*us z%bPVKoMWS21)32rvT0CtRX^N#FED~9=n=ig`YPiA20%~dfpi_viX%jxzwz37kzww6 zb6DJ9PYVElf-Tep3l6-0-+tRz&M4M0uFm(dTnZ0ZeKnOkqMa!(M%P)AQK$2cEWm3VZ(96LnO|RdOeqX9(T}@aq5~ zhs`-0chK5>>sevD;z4l&#H3fKzrRk;v?;`CiMXpXdH32&|Cc`z^a=aK8GwG|8{h4F zPAD-70!8E$xNR@GZ~s8Z3A_t>pM3J!p9}-~km>9xqS0msoZy@t zy8(ANH)1@5maL!57IMw=5NDe*(QB`2c#V)&Gs&xP?#W~-3`Cx2Bw;LzfvKZF+?rzi zObRjtmH{z1c-VJ>P>E|u^a&Jorqu^Dxs8UKZ95VptjGRwM7P%g4(@b&9ktDyWSDz& z6Us0=5zY6&XB)GdQL|raVVf<12Ya~&_nrbzo=XIji+iYLJ`(4C3v)vX={@|ol&n!n z8#&WZ?+Bw#MUunJ#Kk~)?XX!y3ZvRo$XnkkbXikiB#+I2m5NyMw_Y{F)Wb11cI$)}dU> zpTWcw}`a5Q8=zEhV4N9a1 z06WG@R|uz*JDEG5HP#w)^#{T5dM6A}m`KIMeZojxwYi*Lu0ImA5T~+nb!sytJEwZR zrF6eOJRG4Uj4+X*(4A?79|Z1Jo3PI;k9BuKH?3na6}h~7y@A1$7OIs+VbLxRJJ+xM z=)BsH`xr1Z_x>|~^2^lwT=pNaKTu&JLkm8@wU#?w5E^~jobPt*FG4%2ci`A>W@xCx@jc7cZ zA|}UV1vIESD+Z`_u$(CFGZSzTWkh^}N9JO4Bxd^2B3v8gA3Ev$Pju;9f}C9FmfwAa zy5iUR|#v(A}F{z|$nUUwP@;0UhKNh|*@h zRvtE~x#T66BAWeCJMJe}anSFRn*J8;XB4r#@P z$mU(@rx%9KKbO&Pxtp-M9$nk4AuHF;d=tPI)PWAG{8VMP^*iq63iS9 zSDIEM#D;v4uNni72BzFE!mZQj2UW<pn^LRtt9X>a5$ z{_{`&`44{hM?ZWKbT3e|mCkRK2K^o!q(K=5k4u^3r1u9>claaMMMN)pTbBzECRUVK zSr$GiYc6yGM`?5D6ZVmWx3S#yiy2 zimKxJR<=e7CbEHYebliNxpU1&eSA@w3WlwU&n-pHJ{`1&+9yASQx5qmJx>X*N49?x z+|MI-6=dl8Q}koLy>Osx`Tw7@{|Rj@P1Ai*I}i?ROIlbVENeT2YU{d+rp^@E|^(heGdP$oS zD_6K2(82&RZ%f4Pl*&z;YKQer09l(T(VCY;y4I+h%{n9MO2TF_D#M;NVFr zdx4L}T^e{)9{*3!uq1~~9 zk}#UNU^%3?_Zae0v~V6imK4iE2RoM3r8ynitg_rk&H=ziS=-+!IS6ydq+>3$3D zc?#Hp9XoZpktzmA=t#p*3xd&S4e6!`#PVp2hiv;uR10Ed?)RpuWZ@Q zX7)}eD02vf%c(6C!I%xEK&nWDWk)$47xyw7fE$DplEpKyQE5l|9*R5gX%=U|#~u0L zxD&EZl{$w%`s~$zd-3AMKVMyCXnjbh)`_I(ni^!Gj7AXulHRJgKIKzzRlOf%_r5+9 zQgFasrYfbne#jIsKZ(d3es%u!`TzRgzWn<9szXcir-W7Vu+?Se7^grM4atm$ggKR75szgprll*IW;yrydXk05KlSlTwXD3+Ds@0W5PZG zmt$S%Js2}Klzg7aPV!jW12w}j%2$GO#jWP{0yo0J{fH<{u6XmT#+qY$r5b|w{@MA*aR#t{wR+rBD7%fsTnKmwMRhtBjatDy-SPh z5%v=wZU%R~yG4?m32L?nyl|2zGU#D{8pwByd)^KfoYBAH2O2(st0D}rEF*h8EL0h* zhTwAh_V#5rgMZ4xa;a@27oaM;F!QLnEAewc#epg$XL8L1;11l9zQ-+c2WHFJ!7f9E zUC(Z)381hH^k9uC2N-e+yLf}QP&m0gF4NpxyUCmR`x3ENwTk{6E$CN1; zahHtc4$u8%G{!zTHcd$+@=l&*_`#au@$7MR-m#!D$IW(dXC~KcCm>}2Ed;&HbYORe zX1&@xGw99+;Kb9}pBJj#0x37s`(0}^W~h)e5C&wr%W**0CK4qzhSo0h6iqMac?hx8 z*N1DHiell*n&~5SU&swMIsvZ)|9I-}TJDM)^;k0)sGLJm#;URbNy(a`i~~W)*(S_R zrJK3;%TLbl6SV#MM?XU0ihu(W32w+Ags&KBDr!I={yMpTT1aCg2TjX0l7l25IrL0) z@G8EeV#pVnNTPo324*@uJ#Lv}Jxc@lF{ z^#%l`0z~qqbv6OE2gZOp65Ij}=$X^*XeZMm6wj7T${1j?U4H6~?CkzlHUi@YIw0OF z4U~{GAj}QBhE1B&;1j%gy#3wvZ?rwhTITlNu-uvPROpS&n!9Uz9TW5=rab!3eAWkk z!fq%0Vbf(|3FlptqTBNyxdbK_@lzq3O4JEg0q(FV1n&H)UK^rwtiGj?o{-1%EPZGA zMy3nd8Zk!{gJSXkKPxMg0E6(xe1!gQ(y)XDzz|I>DzlOG#ZV1hgFCBO@ax~H5R}o% z99duT*D?EAq9=^P*FmmQ*u}#Q_=}livX6iW#;q)OgYI{*?K)B7GUCue@6>oQCn$+f zs8Um!@3{^+!e+(M^GSD)xog5w*CYPcXC@|TeesxyS7P+AKEZbV9U)9}7I@+0)i^Il zXjwOHIiV4mcfwNsIMS{P+j(G)%MWFVOQlvq11xYC_R1`aX7_qhLv&DzPZ;});E>|8 zL3JOq_zRZ>xU&O-?aE&Y8f$fbi2Ia%BXH*f*T#)-VcNX8MDugl2ON0uN)`y?1 z7C+i=87(u_V$L-MeVt?tZoYHL_y|i&KN+OrY*=vjus7M+cu#@5+ZWlYl5VKoyBt2HwFoJ4PygV*t84*v?1(fOBt(4T)%s<@GYN53J0ECWx(X)l)@g0X|foXNHvpsPH66nm`I6wz9R) zW>K7ASePmB8Q9Z|{{w|z=h0krwreIS)(nWk!98&hjIqNJB0P|3PLq^I#i*|*>dh(G z0eqNv5J-gXS)seF+!Gb{tJI2&VY$o6LUjaj84{|W|4%;r&(G<%_dM+#3zX?KlgNf= zAI;50vKt#z1F0kZxi+{y#fAQ+Y&whRW)ywDXEo`{jZ*`w0!{LCtc0rsDT{m70OOy0Np4SM7 zFfnnUjJwKmhFCAFJ(?m9{^gJU;z#Fy`IldP{nc0S1c6^32KFb-IEc>Ym3K`S$)#qg z6X4e|{upncmCR=OC>ThmT8SMDcC|}oZzD2c+cb(hs&ftGh1u%s5zV9BGj!d5ztD0%3FST^%O2Y33^? zsreOu&pPBqKn)u_f5JXs1p;M{JCBu4L`&_^uuUnwz*^u2fzOZy;Ds0?CZ|W{uaTbs z`C3 zZ$*|r-)i<1lc2l9eoBL1ar|iI-~ii#mjK!3H0)f$c6PXO zwtZp@cL)D&&&*#oI?tjeqR8GI#BL{ZEk`hrPFBcE%EniWgTMqSg{ev@J|=%kxeczw z7bzGjiS8Nf;k66I+(RbY#$)8#^sHw!T=^LCNq)NYXsg9&gA9QQ#6uH@0u~s}Ma`H( z@3G+SX+9bzti~q~$EUfiz=_#(HN?55bYO6wJjRhA_rf<^bv#vpDZ_5VRU2n=o)Av2 zo3&h+_B;=!)Fic0LF82#PSCxUo1fw4jNhTpq!xOs1wCqU?6rcGP$g$R0(a7?yTd{R z4@{@iE{5yCX;)UTMLYG%2_Ydf6b@;IOmi>M3A-fp!tD93<<9T#M~E8+;{B&+7y=bf zWq)upajM~KIf)R6JkJH*(e2(n&a58uW(feSu5q6mc~5up8}A|yUjz)BY; z7Ou^?!u*mV`kfATy2TsQM=qi6N$_9+CpK=Y)4BS$fBT$&`tM)GuPt}9Wn{P;%Uw%uskc|g{KK%rFn{+SnM2l!%m*eRilsb%z&%9h2#n^% z42yF(*#cu3v0_+Wz>*#dwk5Ci5=tlIEj}bODd6|mtQrlufR6Kd7?2>5A1yihloMCy zzW5~C7V%vt5JIL3Z{DKLeg zV2mM#%|v`(KaA@yXu6KTPzW1;%&nj)f8+7$1HOukV1tNeN5uA?6t-*6H0zz~HcO4N zK1kaJ+_^U$Gr0>YImD}AS7i9W0EU~l!E%fshlp(Ah!AO@dumWZSdE>DO_A4PY?j*a z1a%PD&}$WQC(&bJMB{uJLs^PSa5NY#W<}TrEu7U&S)w23hx;}Mqani(7Z+BXxoMM< z0_ezGbW%-VPCzGnmpS*u$Pb`k=I8m5JP|*e!GJyi9sqp3f+mQgPON7+x3|bC+#HDGv?33WMIOa4!02ko27 z-5YS9UO5QaomMlqh((~2F(&v&GcyF;!?aBkTZ?7-cFY~`LY6zT8__PLP$)|D`-opj zIRJr^QU!frPQ|>^m2uqKu4OXkU;SU*^VZ?j%T~7RXV~5acbbqEPKnNX${tKvnNgD= zyjTa^spudW$^!x1JqICptMN{u4p3sfll9{#3=9r+Xl{j&fErqbWqFGkxdp9-=n>Ii zMa~JK;hFmV#HKXif_mHlyoWR(b6Ts8Llae)=(5t~0v%LQrs-e~he@n5Kd1}Ecn1FM z38V<}{yBY~J6^vJ3~wQ-g7xoUdzr;dz@Hvc zt&MD%ECco((!Ocz^!v1Z^3SotKst*Su`pG_h~xr=b9s8zS#D1!+e)MeLS23BVEc>T zULE#{%82}4uXmz|D|0W3B#*XHuARLs8o?uzmvQe#T z7vN5w6`v=D(T1s>jksr(U?eOR4hYUu>SQ4gk#MBH>@u#cODA|0YT&95R{a&gHoC_ zGBIdPFa~tOfFJ^iEx?4v>&_-QHcsmsr^%fp8J!}vVVbPq3$u&WNrOkg!5qMCJOVUm z9XV<-EKXtjfF!!sk30)rY34MxDEGn-e6xY_#-K_7KY~Q#23Sgp0zq@} zQRXZ=6#(M`(nWDLc24U_6?>pgrBxk`h`q*DnXLAF<@T@OdBtT0uJvvg~Um%3+* zdbHmjC(TS6VM&$!F}q{5g)9xvWKe4()DYZSxX2*As`L>%DRz!V4DXVqu6xE~*K-zK zg^RAUZZ_(=_G}gs63^VW^pXI!z6?$6i27?8KAC2Y%MiRe7e3y62@Hyf%%1IoDklHO z<&I_>xEq8qj5Ln+g1d`rgL=nek1&JBJ6lQCwMAHDB~Sd-VyxgcDM~0(rzxqpGqc%iWUhYw)yuC^hcB=G;&g&5 zB;d;`;?B%Yu4x$yl;OG;(6#dWpT^uQ9xx(*4epXrGSe3zrso&~9F1g?_5FGs#sDZb z7JEp@a(ac8%rr9B(McEezzp-9scQR4mWYi=0@a`A{!Lfq>kE)eiq+^$VT>j)AB15B zqS$=8e|icxRGC#?2DrOXBv1gqK#un#d1wMtoe=y_U@ zc*t%SSt#s1RD*C9C`D|~T&|mbs)=L=5H(P(YC%l91MpP=XBvXw=$H{sq7Ajhp$B6UhYlT2^ca=(UM_EL#77Z zwWx@R?l$)cpUVsesf;VmLROlCgP$qLS4h-|v_4QN|6O`EVcRX_nj2v^L#_1&Vqy-1 z=$5$)FB2{dBqtM%O1C{2vM za~J!iBV7Tr0djzX#X)-g73k!GFa}sViae20Jvw7T*VKOSe3j%&4pPW&N8(!8W6J$ z$Z+S6?kw#NmQU-{krsVN(gJXNhf$YsXB~DsmQk-uYHZJwjk0IJ%D; z8_IdgzmjRrGF7M#tw`o825>q;Rb?H`fjYGH2)W!jdUV>BjU&p!&;q>PTv$vpYV;1y zkMZ>wYocy&FHcFW!tiGO$;H-2&ff{$3C6&xk3>LytCLNL!Xt&I>B!T$l@+fyN)$*J z!ojr^;8>!5llF$K2qeflg-pye*grd@hvB;hXok%}?3ztZ>0-3HAXf#1?c}Usm;sCe zcWS-#!<|+pOTBoyfB5p{%a8v0M?bpaB~J7JUIK@MR6oYP3wtq090qW=Vr8x{f=vfmfN7o&Ak}e7*Kh68 zGOf7qw~ikK_ctwfnQW56z<7OdXRQ(84MczV?my)iXvoI+ReJ7Hu$Wl}) zUH&;ow*oyZP5=wiozl`VnQ$Hk^8Q{|uj(FGj=TJ;R8}`8!X&-$C0X1agh&{%c)xR) zs0=Qsv^-HgJ*9s?$vt^;cDB~54J(Nac*nAmndPMOWPWqMoL&waW$U9XoXTa`v5&{E=sduQg0*69e5Xb^VUw=?P_)R zglpU0J(*hTH3#%F`R>UY1JF*eTD5r1N;19@SDoCFlz6wfwxB?|TtwUiV*6`@%EuLc zr72KmZYz@<^rNk?z=I>+WU!r=FCc^N^~&E8+F;5M4z^i4z_w=LWW3Y3M95Ss{X}JE z=I0kt2U;y)B*b`rs`foaTLz{MY$45bq>}{hVWMZiDqVM&oR<7R^6{$N$37sx4h>U7 z%<*6exvw+=DU_z)V7YUxYwH~l#->2>6haSokG00KKnw}b47*{8Yop!adk;vbin)cB z%5y52y65-LGe>Z6=rBXQ$QzbB8v{XtiH-M@_(EmX#e}#%1GbvNua`UELA(KX5*Qb$ zJbNnffMi_HK&Gn0DuV_ioebg&xMM^>3^(!!XG)nA+q@R&;psBneFb3Df-BJOh6h49~5Ev%_=5m@`DXLu9k!0C(NKc4wR40WM?8m8D?}8C)`y^qpa^gZs~3XGT<{>|cEeWQ+5k*#n~WOoh-9Wt z914*s4(A2#F=7SfWGhpO5FJo|*Zy-{qN`M&+z+=kc66#`=>^e@8BFlQggF>Z6Y7ky zpRB$w+dWRW0Ep#%gefj8CCbI*sdCnrUy&gB(N|x7_0{3aotF_N9@SKol=y{gU=L4> zfh3>4b!6KZcRZu~9OC?}m>7;JzE@ba3q^)oIY%BQ9LZS+++7gePbVbsPeZ`zN3*oz zVT(|_5|8N`M&7{q*FU@do%#IlTkgzeX8zh<5jn4$1jz|IgTivRdFnAgYnSOjR+2|j z*l0gKt5&NgQ&T5XeC8`kChG(MN41LVhuFXH^N(xhW#%>di)xj12#jg>$2TOds|nc2 zoDVM6cDJbu2a)C%>4>n%zXer_@16jo#WNiYBnO1Nbt%ehYcG)2Rv4lg6OTE^!Q>g>K@xv#H#@ec6hziIt06r$v1Dusi6Xw@C~tmj_#Q zLpLO${5$vF<8J2f3fvJMCvuC8*=K8EEs-vAz}>-Z?vwWQHYGNsXEiR9vg+Pg-wcEE z9d$K$N>~7B%S>94auLcR&`Z>pyTd7EyT>PR!He`_O>)olKP?J_k*_+PO zva#jQ7%M-dePK*I8{RjZt;2=`9^>{HR#V*HDHfx6G^V_qd@918V$?{#1phY%xND=- zn!-q+(^6q;^)$v@YL`&t;e{CPlX(|>5GFY( zkUTlau$rl!79(YY?Qmy&V6wJ4u~NEY`RpTqpsK-KM3w`Snis{paro**3zxDMmfxs*EN6VKpBeP7~%%yCWfJn z#1uVCBB-aMt|37u=iqDDYjnUO{{eAECN^7@=`Cy^kyjZp4iI6u%KpVDfWIL;NFtY= z%--O`lX1FHC=e`b@74oIA4?CA_2U5F*J^54!u-Y9fKo^#A3rikpRVL!cj49p$DNic z_so3mB0*4QIY`?R>@FTC&(~JuAdIaNbH&D}o1s`EOG7u=pLhnt3Oy&2NwV>HUIg@b zp<EiJM0eZ8o)nYiITvXw_t^~Ug0+k+5{ zv6rF9*^n+<+(3Lt`8rZt2R*_F&fzz92_L>AZQ)Zi<|xl1ZmAgaRrL2Ju2}zR7}9l zV!88N`NVjcDYHpZ1aFlY1&o9eHC+(D2Hc61-MvK=BTKOrSVx@LJVNF=A)c6d6cs<&nsuIkYP5iD^p>mJRM(n?d0jv)p;o z3c(O~2Yy2!8?x=Pb;;k*j03A)E5w``jIcrk_b~7yk)xE-s|w-}sK)ZOsRZSeqeGUv z6GxTN92h2c*VIHQbd4Yk$>m7X;R3N$X_emPC%>v9e`DiM%_N815GmF_AgK`PB zXTeWgBg|^l(IYYZBYwKmCkRd-6lyoZO#VQWIGVsc9VQe-*4FnFt5l|)?o6|X1Iry6 z12?Oz>PC`4GU$%xI-a+QHeg4HiqkLdAcx#aT%jqGc}W~EMxMfN$hZEt8`}(6dkZtqtz1*^LPOFIRyzJvel?@7q~0DX=3NF!27CzCkxFKWAo#;`AIwL!bPj*>>U*jLO?Yyw{#a3`!tkY0Nk8Y#G*4Jr>eon|JI zk#r!7fGTlS`fk=Ls$y|w&)XjrGSpx|h27a3YI_hrPvAbHaR~jyn_i^mO3n#y4I4>S zLwSNu2HgF{(%^&V{%@37W;mNRUml+mYO;CsWFZP>soQ zH{n21i0oCWbmjddo+)%U;BK%FjMvXiIG^e$XDvW?VpnVT&NdfS=EVRT)0T%LhM}(9 z{E2#Tw=#WYon34M7AXUYYsJH3W5#dle%unUt(-)2001BWNklimwrkMN4 zaxVhzg$==76k+a1@b?7nE7L(Moo(;Ra))NGm^%i`=E?C6NhS*HGt}57C+LLAtr+9% z+CG!dL%<_S+;MRKdqXX+cRMB-H2fK60PD5XPhVZLy_6m*OGid`r8=0N3N6cpe+3*!$y z2iN69$Y?HAP7@N}#}beFmk*Nl1QPM3V&sVW-NO!byC8d}MbIDX9D9~b9ojgjS<)>B zmQAQ;eLq>iztFZAvZ)~FM#N#34TtT<{)x}Ak!2?$ONUhZoQNCfLQuw4KO*)6#n=u% z4C7492I4M$&pZg10AN6$ze^bh+>Pa~YMpCvC*eZp4axA*<(j>Y6ad=>K}-2CY*+A5 zL)Ju*Vl+gXO7%wSd7oE+9X3ZeTpr5@mt|H$?SncVE$%pJhTx+W;2!l?Ak8xiqmE_l zX26)5BDN|4Lb4D)Tj1{J`JrqEU8amaPJkxnD^kQvL*a?oD76u==XKgaoo!!F=k+Ym zH?NO3!ZO#EJK+eHrQijdN^5ToGf-BoiNTpU^z8=#ktYne^QPq2^r*4OLHcb-%CJ5R5f?@xUnOTj21sK5;1U>#{z}*wMF{O0Z}YwE`pWRYaK@2PVXVb z7-a!7KNVh4sWb;?;5i%=HZ~F_7~!IbHsr>92Nm^08XsGY!<#qXtQi~I}{LYiMJ$&QiIfw4(iC_2}l zi+NF*Bi~9iL&_7%JDV}(sWEEWOm$718x=(Y^fVEm&W>>s<)U;xkn+1mScm?C`_+?? z55eD%wIx22t2Hvj!DyIa45dd5?5>9k+96LQ1&XF!J&GJW%7YhXzCb$V|FnCxT~sHSFF9@0U2GYn5Mzd@5J1> zSS=B6){M`loS8fsI&QwKiyWc-8;7cDD?)=9u5+v>Ldq#9=U{%}!?Q zZWj)K8}D5HIE4UgrDfn9R8h3XE|PNJ=H)DW)`r@$AbA;Mk|H`WoNsWIngcUo61853Q1KJbo0ES z*Nt^x$4jjX`2g3&M4$(Hw9Y@%{|~3$bR=HfMg@oNicCP67_9kacT~Iyy@Qq#$AhJX zvq3gWY>40?Pjr%im!7Pi1#hV)Qfy*EcptN?Tt-PlxdaY7EL((32m+&QJ|Pgm3Wp~{ z@lxhu>c^~Ab>1|GZpK)ed?I7VvGC;bywrh*2TjZa9}UU67!)Izarh>)E*RhE7bon5 z#!u%=1dGkNOvnO@T)P@aZtW8^H{C(z3RGTI6v%L5mv8i>Hprp=%L-u-k*L-Ndvz5L zGKQ>XvBuStR*_aJ3EU#86V#4#`?8S9LQc;`Fi>UsbKT~t3B`0T&fw{rC5&d2^<;p8 zqw(xHPX_6C`nB>)LS<$jP;{D^LkxxB0}ox^%Oy`Hic!3hM<0o{QIwGC#B3uRsu0NxPCZv^fL+bfI@d=YPZgw6*`UVJ@t#K*`Aws1A1%qHrh zHaj%VXr_QEeFM*3Ri_w4#o2yoXA7Lx9-0SqWZglQ@LJJK+o&&VMQ}gNd4!jS0!O)CKGyfkz1DemX7;StIc+-Ip0%48X-HtNYG!3Rupl-1xXgFW<7AZ zl%8>s3ABad{)a?~BNK)92{lL#2EZY-_XwLYuZ=M;1XS7|EH3qsIP4hXB_%-d*HD#}rS zJF)X7s3N9?U)s|(HM5)<>7BI`F*~lootl$ z(?0r!u-EaR3A8YL>A>=VB)wTOUR32#*yKtn(qbH(qm+W@OM?3S)1yebgWQ(L&Ir$w zcx4NdqX|++!*-qtM7&|AC59+305n9y8pDlJ1(skm9HD%+R0J@wB6tyXyxK?MV)C`M z>_bzsvKD&)_j## zU6{FNcAQu=bFr;ht%=zh$ldIHOsyg_-wc`2(;(BORnMkQ;+WsbuhIb{cbQLO(!iu9 z?8KTOCnKv4ro^L1v*C0Q0gUFEIU+LfaHOPeO_Le