diff --git a/cmake/ctest/drivers/ascicgpu031/CMakeLists.txt b/cmake/ctest/drivers/ascicgpu031/CMakeLists.txt index 99e07ec7c074..2c3d7f1305dc 100644 --- a/cmake/ctest/drivers/ascicgpu031/CMakeLists.txt +++ b/cmake/ctest/drivers/ascicgpu031/CMakeLists.txt @@ -1,7 +1,7 @@ TRILINOS_DRIVER_SETUP() TRILINOS_DRIVER_ADD_DASHBOARD( - DEBUG_CUDA_NOUVM_NODEPRECATED_CRS + DEBUG_CUDA_NOUVM_NODEPRECATED_DEV ctest_linux_nightly_mpi_debug_nouvm_ascicgpu031_crs.cmake CTEST_INSTALLER_TYPE debug RUN_SERIAL @@ -9,7 +9,7 @@ TRILINOS_DRIVER_ADD_DASHBOARD( ) TRILINOS_DRIVER_ADD_DASHBOARD( - DEBUG_CUDA_UVM_NODEPRECATED_CRS + DEBUG_CUDA_UVM_NODEPRECATED_DEV ctest_linux_nightly_mpi_debug_uvm_nodeprecated_ascicgpu031_crs.cmake CTEST_INSTALLER_TYPE debug RUN_SERIAL @@ -17,34 +17,11 @@ TRILINOS_DRIVER_ADD_DASHBOARD( ) TRILINOS_DRIVER_ADD_DASHBOARD( - DEBUG_CUDA_UVM_DEPRECATED_CRS + DEBUG_CUDA_UVM_DEPRECATED_DEV ctest_linux_nightly_mpi_debug_uvm_deprecated_ascicgpu031_crs.cmake CTEST_INSTALLER_TYPE debug RUN_SERIAL TIMEOUT_MINUTES 420 ) -TRILINOS_DRIVER_ADD_DASHBOARD( - DEBUG_CUDA_NOUVM_NODEPRECATED_SAKE - ctest_linux_nightly_mpi_debug_nouvm_ascicgpu031_sake.cmake - CTEST_INSTALLER_TYPE debug - RUN_SERIAL - TIMEOUT_MINUTES 420 - ) - -TRILINOS_DRIVER_ADD_DASHBOARD( - DEBUG_CUDA_UVM_NODEPRECATED_SAKE - ctest_linux_nightly_mpi_debug_uvm_nodeprecated_ascicgpu031_sake.cmake - CTEST_INSTALLER_TYPE debug - RUN_SERIAL - TIMEOUT_MINUTES 420 - ) - -TRILINOS_DRIVER_ADD_DASHBOARD( - DEBUG_CUDA_UVM_DEPRECATED_SAKE - ctest_linux_nightly_mpi_debug_uvm_deprecated_ascicgpu031_sake.cmake - CTEST_INSTALLER_TYPE debug - RUN_SERIAL - TIMEOUT_MINUTES 420 - ) TRILINOS_ADD_REQUIRED_CMAKE_INSTALLS() diff --git a/cmake/ctest/drivers/ascicgpu031/TrilinosCTestDriverCore.ascicgpu031.gcc-cuda.crs.cmake b/cmake/ctest/drivers/ascicgpu031/TrilinosCTestDriverCore.ascicgpu031.gcc-cuda.crs.cmake index 5b86056ffd7b..e1ec160d29f4 100644 --- a/cmake/ctest/drivers/ascicgpu031/TrilinosCTestDriverCore.ascicgpu031.gcc-cuda.crs.cmake +++ b/cmake/ctest/drivers/ascicgpu031/TrilinosCTestDriverCore.ascicgpu031.gcc-cuda.crs.cmake @@ -71,7 +71,7 @@ MACRO(TRILINOS_SYSTEM_SPECIFIC_CTEST_DRIVER) ENDIF() SET(Trilinos_REPOSITORY_LOCATION_NIGHTLY_DEFAULT "git@gitlab-ex.sandia.gov:trilinos-project/Trilinos.git") - SET(Trilinos_BRANCH "tpetraCrsRefactor" ) + SET(Trilinos_BRANCH "develop" ) SET(CTEST_DASHBOARD_ROOT "${TRILINOS_CMAKE_DIR}/../../${BUILD_DIR_NAME}" ) SET(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}" ) diff --git a/cmake/std/PullRequestLinuxCuda10.1.105uvmOffTestingSettings.cmake b/cmake/std/PullRequestLinuxCuda10.1.105uvmOffTestingSettings.cmake index 2900e923c603..0de8d2ac8767 100644 --- a/cmake/std/PullRequestLinuxCuda10.1.105uvmOffTestingSettings.cmake +++ b/cmake/std/PullRequestLinuxCuda10.1.105uvmOffTestingSettings.cmake @@ -152,7 +152,6 @@ set (Kokkos_ENABLE_TESTS OFF CACHE BOOL "Turn off tests for non-UVM build") set (KokkosKernels_ENABLE_TESTS OFF CACHE BOOL "Turn off tests for non-UVM build") set (MueLu_ENABLE_TESTS OFF CACHE BOOL "Turn off tests for non-UVM build") set (NOX_ENABLE_TESTS OFF CACHE BOOL "Turn off tests for non-UVM build") -set (Phalanx_ENABLE_TESTS OFF CACHE BOOL "Turn off tests for non-UVM build") set (ROL_ENABLE_TESTS OFF CACHE BOOL "Turn off tests for non-UVM build") set (Sacado_ENABLE_TESTS OFF CACHE BOOL "Turn off tests for non-UVM build") set (SEACAS_ENABLE_TESTS OFF CACHE BOOL "Turn off tests for non-UVM build") diff --git a/cmake/tribits/core/installation/TribitsProjectConfigTemplate.cmake.in b/cmake/tribits/core/installation/TribitsProjectConfigTemplate.cmake.in index 0d71cd0b206f..cdbdda2bb959 100644 --- a/cmake/tribits/core/installation/TribitsProjectConfigTemplate.cmake.in +++ b/cmake/tribits/core/installation/TribitsProjectConfigTemplate.cmake.in @@ -67,14 +67,14 @@ SET(${PROJECT_NAME}_Fortran_COMPILER "${CMAKE_Fortran_COMPILER_FOR_CONFIG_FILE}" SET(${PROJECT_NAME}_CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}") -SET(${PROJECT_NAME}_CXX_COMPILER_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}") +SET(${PROJECT_NAME}_CXX_COMPILER_FLAGS [[${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}]]) -SET(${PROJECT_NAME}_C_COMPILER_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}}") +SET(${PROJECT_NAME}_C_COMPILER_FLAGS [[${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}}]]) -SET(${PROJECT_NAME}_Fortran_COMPILER_FLAGS "${CMAKE_Fortran_FLAGS} ${CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}}") +SET(${PROJECT_NAME}_Fortran_COMPILER_FLAGS [[${CMAKE_Fortran_FLAGS} ${CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}}]]) ## Extra link flags (e.g., specification of fortran libraries) -SET(${PROJECT_NAME}_EXTRA_LD_FLAGS "${${PROJECT_NAME}_EXTRA_LINK_FLAGS}") +SET(${PROJECT_NAME}_EXTRA_LD_FLAGS [[${${PROJECT_NAME}_EXTRA_LINK_FLAGS}]]) ## This is the command-line entry used for setting rpaths. In a build ## with static libraries it will be empty. diff --git a/packages/belos/src/BelosBiCGStabIter.hpp b/packages/belos/src/BelosBiCGStabIter.hpp index 0410dc8ec068..396890f01346 100644 --- a/packages/belos/src/BelosBiCGStabIter.hpp +++ b/packages/belos/src/BelosBiCGStabIter.hpp @@ -57,7 +57,6 @@ #include "BelosOperatorTraits.hpp" #include "BelosMultiVecTraits.hpp" -#include "Teuchos_BLAS.hpp" #include "Teuchos_SerialDenseMatrix.hpp" #include "Teuchos_SerialDenseVector.hpp" #include "Teuchos_ScalarTraits.hpp" diff --git a/packages/belos/src/BelosBiCGStabSolMgr.hpp b/packages/belos/src/BelosBiCGStabSolMgr.hpp index c35e35426751..647a3ba08932 100644 --- a/packages/belos/src/BelosBiCGStabSolMgr.hpp +++ b/packages/belos/src/BelosBiCGStabSolMgr.hpp @@ -58,16 +58,14 @@ #include "BelosStatusTestCombo.hpp" #include "BelosStatusTestOutputFactory.hpp" #include "BelosOutputManager.hpp" -#include "Teuchos_BLAS.hpp" -#include "Teuchos_LAPACK.hpp" #ifdef BELOS_TEUCHOS_TIME_MONITOR #include "Teuchos_TimeMonitor.hpp" #endif -/** \example BiCGStab/BiCGStabEpetraExFile.cpp +/** \example BiCGStab/BiCGStabExFile.cpp This is an example of how to use the Belos::BiCGStabSolMgr solver manager. */ -/** \example BiCGStab/PseudoBlockPrecCGEpetraExFile.cpp +/** \example BiCGStab/PrecBiCGStabExFile.cpp This is an example of how to use the Belos::BiCGStabSolMgr solver manager with an Ifpack preconditioner. */ @@ -95,16 +93,6 @@ namespace Belos { BiCGStabSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg) {}}; - /** \brief BiCGStabSolMgrOrthoFailure is thrown when the orthogonalization manager is - * unable to generate orthonormal columns from the initial basis vectors. - * - * This std::exception is thrown from the BiCGStabSolMgr::solve() method. - * - */ - class BiCGStabSolMgrOrthoFailure : public BelosError {public: - BiCGStabSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg) - {}}; - template class BiCGStabSolMgr : public SolverManager { @@ -630,8 +618,6 @@ ReturnType BiCGStabSolMgr::solve () setParameters (params_); } - Teuchos::BLAS blas; - TEUCHOS_TEST_FOR_EXCEPTION (! problem_->isProblemSet (), BiCGStabSolMgrLinearProblemFailure, "Belos::BiCGStabSolMgr::solve: Linear problem is not ready. " diff --git a/packages/belos/src/BelosBlockCGIter.hpp b/packages/belos/src/BelosBlockCGIter.hpp index 765c9b12bbbf..c3330e1acdcb 100644 --- a/packages/belos/src/BelosBlockCGIter.hpp +++ b/packages/belos/src/BelosBlockCGIter.hpp @@ -57,7 +57,6 @@ #include "BelosOperatorTraits.hpp" #include "BelosMultiVecTraits.hpp" -#include "Teuchos_BLAS.hpp" #include "Teuchos_LAPACK.hpp" #include "Teuchos_SerialDenseMatrix.hpp" #include "Teuchos_SerialDenseVector.hpp" diff --git a/packages/belos/src/BelosBlockCGSolMgr.hpp b/packages/belos/src/BelosBlockCGSolMgr.hpp index 5f20986f8f2e..486edfa18a6d 100644 --- a/packages/belos/src/BelosBlockCGSolMgr.hpp +++ b/packages/belos/src/BelosBlockCGSolMgr.hpp @@ -61,7 +61,6 @@ #include "BelosStatusTestCombo.hpp" #include "BelosStatusTestOutputFactory.hpp" #include "BelosOutputManager.hpp" -#include "Teuchos_BLAS.hpp" #include "Teuchos_LAPACK.hpp" #ifdef BELOS_TEUCHOS_TIME_MONITOR # include "Teuchos_TimeMonitor.hpp" @@ -102,17 +101,6 @@ namespace Belos { BlockCGSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg) {}}; - /** \brief BlockCGSolMgrOrthoFailure is thrown when the orthogonalization manager is - * unable to generate orthonormal columns from the initial basis vectors. - * - * This std::exception is thrown from the BlockCGSolMgr::solve() method. - * - */ - class BlockCGSolMgrOrthoFailure : public BelosError {public: - BlockCGSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg) - {}}; - - template::value> @@ -840,7 +828,6 @@ ReturnType BlockCGSolMgr::solve() { setParameters(Teuchos::parameterList(*getValidParameters())); } - Teuchos::BLAS blas; Teuchos::LAPACK lapack; TEUCHOS_TEST_FOR_EXCEPTION( !problem_->isProblemSet(), diff --git a/packages/belos/src/BelosBlockGCRODRSolMgr.hpp b/packages/belos/src/BelosBlockGCRODRSolMgr.hpp index 00d8b8ade503..e990f300d1fd 100644 --- a/packages/belos/src/BelosBlockGCRODRSolMgr.hpp +++ b/packages/belos/src/BelosBlockGCRODRSolMgr.hpp @@ -59,7 +59,6 @@ #include "BelosStatusTestCombo.hpp" #include "BelosStatusTestOutputFactory.hpp" #include "BelosOutputManager.hpp" -#include "Teuchos_BLAS.hpp" #include "Teuchos_LAPACK.hpp" #include "Teuchos_as.hpp" #ifdef BELOS_TEUCHOS_TIME_MONITOR diff --git a/packages/belos/src/BelosBlockGmresSolMgr.hpp b/packages/belos/src/BelosBlockGmresSolMgr.hpp index 93d47e92b646..00754540b721 100644 --- a/packages/belos/src/BelosBlockGmresSolMgr.hpp +++ b/packages/belos/src/BelosBlockGmresSolMgr.hpp @@ -63,7 +63,6 @@ #include "BelosStatusTestOutput.hpp" #include "BelosStatusTestOutputFactory.hpp" #include "BelosOutputManager.hpp" -#include "Teuchos_BLAS.hpp" #ifdef BELOS_TEUCHOS_TIME_MONITOR #include "Teuchos_TimeMonitor.hpp" #endif @@ -889,8 +888,6 @@ ReturnType BlockGmresSolMgr::solve() { setParameters(Teuchos::parameterList(*getValidParameters())); } - Teuchos::BLAS blas; - TEUCHOS_TEST_FOR_EXCEPTION(problem_ == Teuchos::null,BlockGmresSolMgrLinearProblemFailure, "Belos::BlockGmresSolMgr::solve(): Linear problem is not a valid object."); diff --git a/packages/belos/src/BelosFixedPointIteration.hpp b/packages/belos/src/BelosFixedPointIteration.hpp index eb9976383da8..00f8f18f827f 100644 --- a/packages/belos/src/BelosFixedPointIteration.hpp +++ b/packages/belos/src/BelosFixedPointIteration.hpp @@ -100,26 +100,6 @@ namespace Belos { FixedPointIterateFailure(const std::string& what_arg) : BelosError(what_arg) {}}; - /** \brief FixedPointIterationOrthoFailure is thrown when the FixedPointIteration object is unable to - * compute independent direction vectors in the FixedPointIteration::iterate() routine. - * - * This std::exception is thrown from the FixedPointIteration::iterate() method. - * - */ - class FixedPointIterationOrthoFailure : public BelosError {public: - FixedPointIterationOrthoFailure(const std::string& what_arg) : BelosError(what_arg) - {}}; - - /** \brief FixedPointIterationLAPACKFailure is thrown when a nonzero return value is passed back - * from an LAPACK routine. - * - * This std::exception is thrown from the FixedPointIteration::iterate() method. - * - */ - class FixedPointIterationLAPACKFailure : public BelosError {public: - FixedPointIterationLAPACKFailure(const std::string& what_arg) : BelosError(what_arg) - {}}; - //@} diff --git a/packages/belos/src/BelosFixedPointSolMgr.hpp b/packages/belos/src/BelosFixedPointSolMgr.hpp index 5eee19fdc1f0..72fbe3ec6880 100644 --- a/packages/belos/src/BelosFixedPointSolMgr.hpp +++ b/packages/belos/src/BelosFixedPointSolMgr.hpp @@ -59,8 +59,6 @@ #include "BelosStatusTestCombo.hpp" #include "BelosStatusTestOutputFactory.hpp" #include "BelosOutputManager.hpp" -#include "Teuchos_BLAS.hpp" -#include "Teuchos_LAPACK.hpp" #ifdef BELOS_TEUCHOS_TIME_MONITOR # include "Teuchos_TimeMonitor.hpp" #endif @@ -600,9 +598,6 @@ ReturnType FixedPointSolMgr::solve() { setParameters(Teuchos::parameterList(*getValidParameters())); } - Teuchos::BLAS blas; - Teuchos::LAPACK lapack; - TEUCHOS_TEST_FOR_EXCEPTION( !problem_->isProblemSet(), FixedPointSolMgrLinearProblemFailure, "Belos::FixedPointSolMgr::solve(): Linear problem is not ready, setProblem() " diff --git a/packages/belos/src/BelosLSQRIter.hpp b/packages/belos/src/BelosLSQRIter.hpp index f40fd64d3879..06a21fd91ccc 100644 --- a/packages/belos/src/BelosLSQRIter.hpp +++ b/packages/belos/src/BelosLSQRIter.hpp @@ -55,9 +55,7 @@ #include "BelosStatusTest.hpp" #include "BelosOperatorTraits.hpp" #include "BelosMultiVecTraits.hpp" -//#include "BelosMatOrthoManager.hpp" (needed for blocks) -//#include "Teuchos_BLAS.hpp" (needed for blocks) #include "Teuchos_SerialDenseMatrix.hpp" #include "Teuchos_SerialDenseVector.hpp" #include "Teuchos_ScalarTraits.hpp" diff --git a/packages/belos/src/BelosLSQRIteration.hpp b/packages/belos/src/BelosLSQRIteration.hpp index 7f3f497e7cfc..ab9cc04a0bf4 100644 --- a/packages/belos/src/BelosLSQRIteration.hpp +++ b/packages/belos/src/BelosLSQRIteration.hpp @@ -130,26 +130,6 @@ class LSQRIterateFailure : public BelosError {public: LSQRIterateFailure(const std::string& what_arg) : BelosError(what_arg) {}}; - /** \brief LSQRIterationOrthoFailure is thrown when the LSQRIteration object is unable to - * compute independent direction vectors in the iterate() routine. - * - * This std::exception is thrown from the iterate() method. - * - */ -class LSQRIterationOrthoFailure : public BelosError {public: - LSQRIterationOrthoFailure(const std::string& what_arg) : BelosError(what_arg) - {}}; - - /** \brief LSQRIterationLAPACKFailure is thrown when a nonzero return value is passed back - * from an LAPACK routine. - * - * This std::exception is thrown from the iterate() method. - * - */ -class LSQRIterationLAPACKFailure : public BelosError {public: - LSQRIterationLAPACKFailure(const std::string& what_arg) : BelosError(what_arg) - {}}; - //@} } // end Belos namespace diff --git a/packages/belos/src/BelosLSQRSolMgr.hpp b/packages/belos/src/BelosLSQRSolMgr.hpp index 57aaef7389a7..ff40bb83b384 100644 --- a/packages/belos/src/BelosLSQRSolMgr.hpp +++ b/packages/belos/src/BelosLSQRSolMgr.hpp @@ -59,8 +59,6 @@ #include "BelosStatusTestOutputFactory.hpp" #include "BelosOutputManager.hpp" #include "Teuchos_as.hpp" -#include "Teuchos_BLAS.hpp" -#include "Teuchos_LAPACK.hpp" #ifdef BELOS_TEUCHOS_TIME_MONITOR #include "Teuchos_TimeMonitor.hpp" @@ -85,21 +83,6 @@ class LSQRSolMgrLinearProblemFailure : public BelosError { {} }; -/** \brief LSQRSolMgrOrthoFailure is thrown when the orthogonalization manager is - * unable to generate orthonormal columns from the initial basis vectors. - * - * \warning DO NOT USE; DEPRECATED. - * - * This std::exception is thrown from the LSQRSolMgr::solve() method. - * - */ -class LSQRSolMgrOrthoFailure : public BelosError { -public: - LSQRSolMgrOrthoFailure(const std::string& what_arg) - : BelosError(what_arg) - {} -}; - /** \brief LSQRSolMgrBlockSizeFailure is thrown when the linear problem has * more than one RHS. This is unique to single vector methods. * diff --git a/packages/belos/src/BelosMinresIter.hpp b/packages/belos/src/BelosMinresIter.hpp index 4ca2de6e82ea..191f0fc36055 100644 --- a/packages/belos/src/BelosMinresIter.hpp +++ b/packages/belos/src/BelosMinresIter.hpp @@ -74,7 +74,6 @@ #include "Teuchos_ScalarTraits.hpp" #include "Teuchos_ParameterList.hpp" #include "Teuchos_TimeMonitor.hpp" -#include "Teuchos_BLAS.hpp" namespace Belos { @@ -465,8 +464,6 @@ class MinresIter : virtual public MinresIteration { initialize(); } - Teuchos::BLAS blas; - // Create convenience variables for zero and one. const ScalarType one = SCT::one(); const ScalarType zero = SCT::zero(); diff --git a/packages/belos/src/BelosMinresIteration.hpp b/packages/belos/src/BelosMinresIteration.hpp index 0cc61f789466..dd8118947bab 100644 --- a/packages/belos/src/BelosMinresIteration.hpp +++ b/packages/belos/src/BelosMinresIteration.hpp @@ -117,26 +117,6 @@ namespace Belos { MinresIterateFailure(const std::string& what_arg) : BelosError(what_arg) {}}; - /** \brief MinresIterationOrthoFailure is thrown when the MinresIteration object is unable to - * compute independent direction vectors in the MinresIteration::iterate() routine. - * - * This std::exception is thrown from the MinresIteration::iterate() method. - * - */ - class MinresIterationOrthoFailure : public BelosError {public: - MinresIterationOrthoFailure(const std::string& what_arg) : BelosError(what_arg) - {}}; - - /** \brief MinresIterationLAPACKFailure is thrown when a nonzero return value is passed back - * from an LAPACK routine. - * - * This std::exception is thrown from the MinresIteration::iterate() method. - * - */ - class MinresIterationLAPACKFailure : public BelosError {public: - MinresIterationLAPACKFailure(const std::string& what_arg) : BelosError(what_arg) - {}}; - //@} diff --git a/packages/belos/src/BelosMinresSolMgr.hpp b/packages/belos/src/BelosMinresSolMgr.hpp index 906e79d60fff..7bc01bc63077 100644 --- a/packages/belos/src/BelosMinresSolMgr.hpp +++ b/packages/belos/src/BelosMinresSolMgr.hpp @@ -57,8 +57,6 @@ #include "BelosStatusTestCombo.hpp" #include "BelosStatusTestOutputFactory.hpp" #include "BelosOutputManager.hpp" -#include "Teuchos_BLAS.hpp" -#include "Teuchos_LAPACK.hpp" #ifdef BELOS_TEUCHOS_TIME_MONITOR #include "Teuchos_TimeMonitor.hpp" #endif diff --git a/packages/belos/src/BelosPCPGIter.hpp b/packages/belos/src/BelosPCPGIter.hpp index 91696c65400e..d2da5541366d 100644 --- a/packages/belos/src/BelosPCPGIter.hpp +++ b/packages/belos/src/BelosPCPGIter.hpp @@ -56,8 +56,6 @@ #include "BelosOperatorTraits.hpp" #include "BelosMultiVecTraits.hpp" -#include "Teuchos_BLAS.hpp" -#include "Teuchos_LAPACK.hpp" #include "Teuchos_SerialDenseMatrix.hpp" #include "Teuchos_SerialDenseVector.hpp" #include "Teuchos_ScalarTraits.hpp" @@ -156,8 +154,6 @@ namespace Belos { PCPGIterateFailure(const std::string& what_arg) : BelosError(what_arg) {}}; - - /** \brief PCPGIterOrthoFailure is thrown when the PCPGIter object is unable to * compute independent direction vectors in the PCPGIter::iterate() routine. * @@ -167,20 +163,7 @@ namespace Belos { class PCPGIterOrthoFailure : public BelosError {public: PCPGIterOrthoFailure(const std::string& what_arg) : BelosError(what_arg) {}}; - - /** \brief PCPGIterLAPACKFailure is thrown when a nonzero return value is passed back - * from an LAPACK routine. - * - * This std::exception is thrown from the PCPGIter::iterate() method. - * - */ - class PCPGIterLAPACKFailure : public BelosError {public: - PCPGIterLAPACKFailure(const std::string& what_arg) : BelosError(what_arg) - {}}; - - //@} - - + template class PCPGIter : virtual public Iteration { @@ -233,7 +216,7 @@ namespace Belos { * -# the search direction P is projected into a complement of the seed space U. * * The status test is queried at the beginning of the iteration. - * Potential CG exceptions include IterationInit, Iterate and IterationLAPACKFailure + * Potential CG exceptions include IterationInit, Iterate * */ void iterate(); diff --git a/packages/belos/src/BelosPCPGSolMgr.hpp b/packages/belos/src/BelosPCPGSolMgr.hpp index 0bc7890d22d9..faf2f87130ed 100644 --- a/packages/belos/src/BelosPCPGSolMgr.hpp +++ b/packages/belos/src/BelosPCPGSolMgr.hpp @@ -59,7 +59,6 @@ #include "BelosStatusTestCombo.hpp" #include "BelosStatusTestOutputFactory.hpp" #include "BelosOutputManager.hpp" -#include "Teuchos_BLAS.hpp" #include "Teuchos_LAPACK.hpp" #ifdef BELOS_TEUCHOS_TIME_MONITOR # include "Teuchos_TimeMonitor.hpp" @@ -738,7 +737,6 @@ ReturnType PCPGSolMgr::solve() { // Set the current parameters if are not set already. if (!isSet_) { setParameters( params_ ); } - Teuchos::BLAS blas; Teuchos::LAPACK lapack; ScalarType one = Teuchos::ScalarTraits::one(); ScalarType zero = Teuchos::ScalarTraits::zero(); diff --git a/packages/belos/src/BelosPseudoBlockCGIter.hpp b/packages/belos/src/BelosPseudoBlockCGIter.hpp index af08d55d2da2..f754ff417ba2 100644 --- a/packages/belos/src/BelosPseudoBlockCGIter.hpp +++ b/packages/belos/src/BelosPseudoBlockCGIter.hpp @@ -57,7 +57,6 @@ #include "BelosOperatorTraits.hpp" #include "BelosMultiVecTraits.hpp" -#include "Teuchos_BLAS.hpp" #include "Teuchos_SerialDenseMatrix.hpp" #include "Teuchos_SerialDenseVector.hpp" #include "Teuchos_ScalarTraits.hpp" diff --git a/packages/belos/src/BelosPseudoBlockCGSolMgr.hpp b/packages/belos/src/BelosPseudoBlockCGSolMgr.hpp index 83eb1d08ac8f..4ec6b0ee49ea 100644 --- a/packages/belos/src/BelosPseudoBlockCGSolMgr.hpp +++ b/packages/belos/src/BelosPseudoBlockCGSolMgr.hpp @@ -60,7 +60,6 @@ #include "BelosStatusTestCombo.hpp" #include "BelosStatusTestOutputFactory.hpp" #include "BelosOutputManager.hpp" -#include "Teuchos_BLAS.hpp" #include "Teuchos_LAPACK.hpp" #ifdef BELOS_TEUCHOS_TIME_MONITOR #include "Teuchos_TimeMonitor.hpp" diff --git a/packages/belos/src/BelosPseudoBlockGmresSolMgr.hpp b/packages/belos/src/BelosPseudoBlockGmresSolMgr.hpp index 0c485fbda3af..4772885ef065 100644 --- a/packages/belos/src/BelosPseudoBlockGmresSolMgr.hpp +++ b/packages/belos/src/BelosPseudoBlockGmresSolMgr.hpp @@ -57,7 +57,6 @@ #include "BelosStatusTestFactory.hpp" #include "BelosStatusTestOutputFactory.hpp" #include "BelosOutputManager.hpp" -#include "Teuchos_BLAS.hpp" #ifdef BELOS_TEUCHOS_TIME_MONITOR #include "Teuchos_TimeMonitor.hpp" #endif @@ -1195,8 +1194,6 @@ ReturnType PseudoBlockGmresSolMgr::solve() { // then didn't set any parameters using setParameters(). if (!isSet_) { setParameters( params_ ); } - Teuchos::BLAS blas; - TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isProblemSet(),PseudoBlockGmresSolMgrLinearProblemFailure, "Belos::PseudoBlockGmresSolMgr::solve(): Linear problem is not ready, setProblem() has not been called."); diff --git a/packages/belos/src/BelosPseudoBlockStochasticCGIter.hpp b/packages/belos/src/BelosPseudoBlockStochasticCGIter.hpp index 51ed360ce847..ada1e1b9100b 100644 --- a/packages/belos/src/BelosPseudoBlockStochasticCGIter.hpp +++ b/packages/belos/src/BelosPseudoBlockStochasticCGIter.hpp @@ -57,7 +57,6 @@ #include "BelosOperatorTraits.hpp" #include "BelosMultiVecTraits.hpp" -#include "Teuchos_BLAS.hpp" #include "Teuchos_SerialDenseMatrix.hpp" #include "Teuchos_SerialDenseVector.hpp" #include "Teuchos_SerialDenseHelpers.hpp" diff --git a/packages/belos/src/BelosPseudoBlockStochasticCGSolMgr.hpp b/packages/belos/src/BelosPseudoBlockStochasticCGSolMgr.hpp index 2508bb6f661b..ce9324907824 100644 --- a/packages/belos/src/BelosPseudoBlockStochasticCGSolMgr.hpp +++ b/packages/belos/src/BelosPseudoBlockStochasticCGSolMgr.hpp @@ -58,7 +58,6 @@ #include "BelosStatusTestCombo.hpp" #include "BelosStatusTestOutputFactory.hpp" #include "BelosOutputManager.hpp" -#include "Teuchos_BLAS.hpp" #ifdef BELOS_TEUCHOS_TIME_MONITOR #include "Teuchos_TimeMonitor.hpp" #endif @@ -87,16 +86,6 @@ namespace Belos { PseudoBlockStochasticCGSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg) {}}; - /** \brief PseudoBlockStochasticCGSolMgrOrthoFailure is thrown when the orthogonalization manager is - * unable to generate orthonormal columns from the initial basis vectors. - * - * This std::exception is thrown from the PseudoBlockStochasticCGSolMgr::solve() method. - * - */ - class PseudoBlockStochasticCGSolMgrOrthoFailure : public BelosError {public: - PseudoBlockStochasticCGSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg) - {}}; - template class PseudoBlockStochasticCGSolMgr : public SolverManager { @@ -629,8 +618,6 @@ ReturnType PseudoBlockStochasticCGSolMgr::solve() { // then didn't set any parameters using setParameters(). if (!isSet_) { setParameters( params_ ); } - Teuchos::BLAS blas; - TEUCHOS_TEST_FOR_EXCEPTION(!problem_->isProblemSet(),PseudoBlockStochasticCGSolMgrLinearProblemFailure, "Belos::PseudoBlockStochasticCGSolMgr::solve(): Linear problem is not ready, setProblem() has not been called."); diff --git a/packages/belos/src/BelosPseudoBlockTFQMRIter.hpp b/packages/belos/src/BelosPseudoBlockTFQMRIter.hpp index 7b2fd1173bf6..cf8d70ad956f 100644 --- a/packages/belos/src/BelosPseudoBlockTFQMRIter.hpp +++ b/packages/belos/src/BelosPseudoBlockTFQMRIter.hpp @@ -67,7 +67,6 @@ #include "BelosOperatorTraits.hpp" #include "BelosMultiVecTraits.hpp" -#include "Teuchos_BLAS.hpp" #include "Teuchos_ScalarTraits.hpp" #include "Teuchos_ParameterList.hpp" #include "Teuchos_TimeMonitor.hpp" diff --git a/packages/belos/src/BelosPseudoBlockTFQMRSolMgr.hpp b/packages/belos/src/BelosPseudoBlockTFQMRSolMgr.hpp index cd91a92d30d7..cd2099a3d7e3 100644 --- a/packages/belos/src/BelosPseudoBlockTFQMRSolMgr.hpp +++ b/packages/belos/src/BelosPseudoBlockTFQMRSolMgr.hpp @@ -90,16 +90,6 @@ namespace Belos { PseudoBlockTFQMRSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg) {}}; - /** \brief PseudoBlockTFQMRSolMgrOrthoFailure is thrown when the orthogonalization manager is - * unable to generate orthonormal columns from the initial basis vectors. - * - * This std::exception is thrown from the PseudoBlockTFQMRSolMgr::solve() method. - * - */ - class PseudoBlockTFQMRSolMgrOrthoFailure : public BelosError {public: - PseudoBlockTFQMRSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg) - {}}; - template class PseudoBlockTFQMRSolMgr : public SolverManager { diff --git a/packages/belos/src/BelosRCGIter.hpp b/packages/belos/src/BelosRCGIter.hpp index 32973046a07e..3af56939939d 100644 --- a/packages/belos/src/BelosRCGIter.hpp +++ b/packages/belos/src/BelosRCGIter.hpp @@ -56,7 +56,6 @@ #include "BelosOperatorTraits.hpp" #include "BelosMultiVecTraits.hpp" -#include "Teuchos_BLAS.hpp" #include "Teuchos_LAPACK.hpp" #include "Teuchos_SerialDenseMatrix.hpp" #include "Teuchos_SerialDenseVector.hpp" @@ -169,16 +168,6 @@ namespace Belos { RCGIterFailure(const std::string& what_arg) : BelosError(what_arg) {}}; - /** \brief RCGIterOrthoFailure is thrown when the RCGIter object is unable to - * compute independent direction vectors in the RCGIter::iterate() routine. - * - * This std::exception is thrown from the RCGIter::iterate() method. - * - */ - class RCGIterOrthoFailure : public BelosError {public: - RCGIterOrthoFailure(const std::string& what_arg) : BelosError(what_arg) - {}}; - /** \brief RCGIterLAPACKFailure is thrown when a nonzero return value is passed back * from an LAPACK routine. * diff --git a/packages/belos/src/BelosRCGSolMgr.hpp b/packages/belos/src/BelosRCGSolMgr.hpp index d681dce69a57..b813da2f7407 100644 --- a/packages/belos/src/BelosRCGSolMgr.hpp +++ b/packages/belos/src/BelosRCGSolMgr.hpp @@ -58,7 +58,6 @@ #include "BelosStatusTestCombo.hpp" #include "BelosStatusTestOutputFactory.hpp" #include "BelosOutputManager.hpp" -#include "Teuchos_BLAS.hpp" #include "Teuchos_LAPACK.hpp" #include "Teuchos_as.hpp" #ifdef BELOS_TEUCHOS_TIME_MONITOR diff --git a/packages/belos/src/BelosTFQMRIter.hpp b/packages/belos/src/BelosTFQMRIter.hpp index 55cd6387724b..491332aa0510 100644 --- a/packages/belos/src/BelosTFQMRIter.hpp +++ b/packages/belos/src/BelosTFQMRIter.hpp @@ -67,7 +67,6 @@ #include "BelosOperatorTraits.hpp" #include "BelosMultiVecTraits.hpp" -#include "Teuchos_BLAS.hpp" #include "Teuchos_SerialDenseMatrix.hpp" #include "Teuchos_SerialDenseVector.hpp" #include "Teuchos_ScalarTraits.hpp" diff --git a/packages/belos/src/BelosTFQMRSolMgr.hpp b/packages/belos/src/BelosTFQMRSolMgr.hpp index b6ba1942488a..ec69b4a3da80 100644 --- a/packages/belos/src/BelosTFQMRSolMgr.hpp +++ b/packages/belos/src/BelosTFQMRSolMgr.hpp @@ -90,16 +90,6 @@ namespace Belos { TFQMRSolMgrLinearProblemFailure(const std::string& what_arg) : BelosError(what_arg) {}}; - /** \brief TFQMRSolMgrOrthoFailure is thrown when the orthogonalization manager is - * unable to generate orthonormal columns from the initial basis vectors. - * - * This std::exception is thrown from the TFQMRSolMgr::solve() method. - * - */ - class TFQMRSolMgrOrthoFailure : public BelosError {public: - TFQMRSolMgrOrthoFailure(const std::string& what_arg) : BelosError(what_arg) - {}}; - template class TFQMRSolMgr : public SolverManager { diff --git a/packages/belos/src/BelosTsqrOrthoManagerImpl.hpp b/packages/belos/src/BelosTsqrOrthoManagerImpl.hpp index 3ee88f1164f4..191d7d061b13 100644 --- a/packages/belos/src/BelosTsqrOrthoManagerImpl.hpp +++ b/packages/belos/src/BelosTsqrOrthoManagerImpl.hpp @@ -50,7 +50,6 @@ #include "BelosOrthoManager.hpp" // OrthoError, etc. #include "Teuchos_as.hpp" -#include "Teuchos_LAPACK.hpp" #include "Teuchos_ParameterList.hpp" #include "Teuchos_ParameterListAcceptorDefaultBase.hpp" #ifdef BELOS_TEUCHOS_TIME_MONITOR diff --git a/packages/intrepid2/src/Cell/Intrepid2_CellGeometry.hpp b/packages/intrepid2/src/Cell/Intrepid2_CellGeometry.hpp index b3fb08fa2c71..2fadab29d3e3 100644 --- a/packages/intrepid2/src/Cell/Intrepid2_CellGeometry.hpp +++ b/packages/intrepid2/src/Cell/Intrepid2_CellGeometry.hpp @@ -233,14 +233,14 @@ namespace Intrepid2 KOKKOS_INLINE_FUNCTION int hypercubeComponentNodeNumber(int hypercubeNodeNumber, int d) const; - //! Initialize the internal orientations_ member with the orientations of each member cell. These are used for projected geometry, and have a nominal shape (C). + //! Initialize the internal orientations_ member with the orientations of each member cell. These are used for projected geometry, and have a logical shape (C). void initializeOrientations(); - //! Returns the nominal extent of the container in the specified dimension; the shape of CellGeometry is always (C,N,D), where C is the number of cells, N is the number of nodes per cell (may be more than the number of vertices, in the case of curvilinear geometry), and D is the spatial dimension. + //! Returns the logical extent of the container in the specified dimension; the shape of CellGeometry is always (C,N,D), where C is the number of cells, N is the number of nodes per cell (may be more than the number of vertices, in the case of curvilinear geometry), and D is the spatial dimension. KOKKOS_INLINE_FUNCTION size_t extent(const int& r) const; - //! Returns the nominal extent of the container in the specified dimension as an int; the shape of CellGeometry is always (C,N,D), where C is the number of cells, N is the number of nodes per cell (may be more than the number of vertices, in the case of curvilinear geometry), and D is the spatial dimension. + //! Returns the logical extent of the container in the specified dimension as an int; the shape of CellGeometry is always (C,N,D), where C is the number of cells, N is the number of nodes per cell (may be more than the number of vertices, in the case of curvilinear geometry), and D is the spatial dimension. template KOKKOS_INLINE_FUNCTION typename std::enable_if::value, int>::type @@ -273,7 +273,7 @@ namespace Intrepid2 KOKKOS_INLINE_FUNCTION PointScalar gridCellCoordinate(const int &gridCellOrdinal, const int &localNodeNumber, const int &dim) const; - //! Returns the nominal rank of this container. This is always 3. + //! Returns the logical rank of this container. This is always 3. KOKKOS_INLINE_FUNCTION unsigned rank() const; diff --git a/packages/intrepid2/src/Cell/Intrepid2_CellTools.hpp b/packages/intrepid2/src/Cell/Intrepid2_CellTools.hpp index 3747aa45b85b..fb9b7f2073cb 100644 --- a/packages/intrepid2/src/Cell/Intrepid2_CellTools.hpp +++ b/packages/intrepid2/src/Cell/Intrepid2_CellTools.hpp @@ -214,7 +214,7 @@ namespace Intrepid2 { \param jacobian [out] - rank-4 array with dimensions (C,P,D,D) with the Jacobians \param points [in] - rank-2/3 array with dimensions (P,D)/(C,P,D) with the evaluation points - \param cellWorkset [in] - rank-3 container with nominal dimensions (C,N,D) with the nodes of the cell workset + \param cellWorkset [in] - rank-3 container with logical dimensions (C,N,D) with the nodes of the cell workset \param basis [in] - HGrad basis for reference to physical cell mapping \param startCell [in] - first cell index in cellWorkset for which we should compute the Jacobian; corresponds to the 0 index in Jacobian and/or points container. Default: 0. \param endCell [in] - first cell index in cellWorkset that we do not process; endCell - startCell must equal the extent of the Jacobian container in dimension 0. Default: -1, a special value that indicates the extent of the cellWorkset should be used. @@ -259,7 +259,7 @@ namespace Intrepid2 { or not the points are inside a reference cell. \param jacobian [out] - rank-4 array with dimensions (C,P,D,D) with the Jacobians - \param cellWorkset [in] - rank-3 container with nominal dimensions (C,N,D) with the nodes of the cell workset + \param cellWorkset [in] - rank-3 container with logical dimensions (C,N,D) with the nodes of the cell workset \param gradients [in] - rank-3/4 array with dimensions (N,P,D)/(C,N,P,D) with the gradients of the physical-to-cell mapping \param startCell [in] - first cell index in cellWorkset for which we should compute the Jacobian; corresponds to the 0 index in Jacobian and/or points container. Default: 0. \param endCell [in] - first cell index in cellWorkset that we do not process; endCell - startCell must equal the extent of the Jacobian container in dimension 0. Default: -1, a special value that indicates the extent of the cellWorkset should be used. @@ -913,7 +913,7 @@ namespace Intrepid2 { \param physPoints [out] - rank-3 array with dimensions (C,P,D) with the images of the ref. points \param refPoints [in] - rank-3/2 array with dimensions (C,P,D)/(P,D) with points in reference frame - \param cellWorkset [in] - rank-3 container with nominal dimensions (C,N,D) with the nodes of the cell workset + \param cellWorkset [in] - rank-3 container with logical dimensions (C,N,D) with the nodes of the cell workset \param basis [in] - pointer to HGrad basis used in reference-to-physical cell mapping */ diff --git a/packages/intrepid2/src/Discretization/FunctionSpaceTools/Intrepid2_FunctionSpaceTools.hpp b/packages/intrepid2/src/Discretization/FunctionSpaceTools/Intrepid2_FunctionSpaceTools.hpp index ebc9476c2b02..8beeaeb32b05 100644 --- a/packages/intrepid2/src/Discretization/FunctionSpaceTools/Intrepid2_FunctionSpaceTools.hpp +++ b/packages/intrepid2/src/Discretization/FunctionSpaceTools/Intrepid2_FunctionSpaceTools.hpp @@ -85,8 +85,8 @@ namespace Intrepid2 { public: /** \brief Transformation of a gradient field in the H-grad space, defined at points on a reference cell, stored in the user-provided container inputVals - and nominally indexed by (F,P,D). The returned object contains the transformed gradient field, - defined on cells in physical space and nominally indexed by (C,F,P,D). The transformations are + and indexed by (F,P,D). The returned object contains the transformed gradient field, + defined on cells in physical space and indexed by (C,F,P,D). The transformations are computed on entry access; algorithms such as sum factorization rely on having access to the reference-space basis values as well as the transformation operator; both are stored in the returned TransformedVectorData object. diff --git a/packages/intrepid2/src/Discretization/Integration/Intrepid2_IntegrationTools.hpp b/packages/intrepid2/src/Discretization/Integration/Intrepid2_IntegrationTools.hpp index e9b02869a11e..727dd28c2a98 100644 --- a/packages/intrepid2/src/Discretization/Integration/Intrepid2_IntegrationTools.hpp +++ b/packages/intrepid2/src/Discretization/Integration/Intrepid2_IntegrationTools.hpp @@ -80,12 +80,12 @@ namespace Intrepid2 { /** \brief Allocates storage for the contraction of \a vectorDataLeft and \a vectorDataRight containers on point and space dimensions, weighting each point according to cellMeasures. - \param vectorDataRight [in] - Left input container, with nominal shape (C,F,P,D) - \param cellMeasures [in] - Point weight container, with nominal shape (C,P) - \param vectorDataLeft [in] - Right input container with nominal shape (C,F,P,D) + \param vectorDataRight [in] - Left input container, with logical shape (C,F,P,D) + \param cellMeasures [in] - Point weight container, with logical shape (C,P) + \param vectorDataLeft [in] - Right input container with logical shape (C,F,P,D) \param sumInto [in] - If TRUE, sum into given output array, otherwise overwrite it. Default: FALSE. - \return integrals, a container with nominal shape (C,F,F), suitable for passing as the first argument to the integrate() variant that takes an Intrepid2::Data object as its first, integrals, argument. + \return integrals, a container with logical shape (C,F,F), suitable for passing as the first argument to the integrate() variant that takes an Intrepid2::Data object as its first, integrals, argument. */ template static Data allocateIntegralData(const TransformedVectorData vectorDataLeft, @@ -96,10 +96,10 @@ namespace Intrepid2 { point and space dimensions, weighting each point according to cellMeasures, and stores the result in \a outputValues. The integrals container can be constructed using allocateIntegralData(). - \param outputValues [out] - Output array, with nominal shape (C,F,F) - \param vectorDataRight [in] - Left input container, with nominal shape (C,F,P,D) - \param cellMeasures [in] - Point weight container, with nominal shape (C,P) - \param vectorDataLeft [in] - Right input container with nominal shape (C,F,P,D) + \param outputValues [out] - Output array, with logical shape (C,F,F) + \param vectorDataRight [in] - Left input container, with logical shape (C,F,P,D) + \param cellMeasures [in] - Point weight container, with logical shape (C,P) + \param vectorDataLeft [in] - Right input container with logical shape (C,F,P,D) \param sumInto [in] - If TRUE, sum into given output array, otherwise overwrite it. Default: FALSE. \param approxFlops [in] - if not NULL, the double pointed to will be set with an estimated number of floating point operations. Intended for performance assessment purposes. */ diff --git a/packages/intrepid2/src/Discretization/Integration/Intrepid2_IntegrationToolsDef.hpp b/packages/intrepid2/src/Discretization/Integration/Intrepid2_IntegrationToolsDef.hpp index f02256131951..041ab6d45c49 100644 --- a/packages/intrepid2/src/Discretization/Integration/Intrepid2_IntegrationToolsDef.hpp +++ b/packages/intrepid2/src/Discretization/Integration/Intrepid2_IntegrationToolsDef.hpp @@ -2241,8 +2241,8 @@ void IntegrationTools::integrate(Data integrals, { auto functor = Impl::F_IntegratePointValueCache(integrals, leftComponent, composedTransform, rightComponent, cellMeasures, a_offset, b_offset, leftFieldOrdinalOffset, rightFieldOrdinalOffset); - const int maxTeamSize = policy.team_size_max(functor,Kokkos::ParallelForTag()); - const int teamSize = functor.teamSize(maxTeamSize); + const int recommendedTeamSize = policy.team_size_recommended(functor,Kokkos::ParallelForTag()); + const int teamSize = functor.teamSize(recommendedTeamSize); policy = Kokkos::TeamPolicy(cellDataExtent,teamSize,vectorSize); @@ -2257,8 +2257,8 @@ void IntegrationTools::integrate(Data integrals, { auto functor = Impl::F_Integrate(integrals, leftComponent, composedTransform, rightComponent, cellMeasures, a_offset, b_offset, leftFieldOrdinalOffset, rightFieldOrdinalOffset, forceNonSpecialized); - const int maxTeamSize = policy.team_size_max(functor,Kokkos::ParallelForTag()); - const int teamSize = functor.teamSize(maxTeamSize); + const int recommendedTeamSize = policy.team_size_recommended(functor,Kokkos::ParallelForTag()); + const int teamSize = functor.teamSize(recommendedTeamSize); policy = Kokkos::TeamPolicy(cellDataExtent,teamSize,vectorSize); @@ -2276,8 +2276,8 @@ void IntegrationTools::integrate(Data integrals, { auto functor = Impl::F_IntegratePointValueCache(integrals, leftComponent, composedTransform, rightComponent, cellMeasures, a_offset, b_offset, leftFieldOrdinalOffset, rightFieldOrdinalOffset); - const int maxTeamSize = policy.team_size_max(functor,Kokkos::ParallelForTag()); - const int teamSize = functor.teamSize(maxTeamSize); + const int recommendedTeamSize = policy.team_size_recommended(functor,Kokkos::ParallelForTag()); + const int teamSize = functor.teamSize(recommendedTeamSize); policy = Kokkos::TeamPolicy(cellDataExtent,teamSize,vectorSize); @@ -2292,8 +2292,8 @@ void IntegrationTools::integrate(Data integrals, { auto functor = Impl::F_Integrate(integrals, leftComponent, composedTransform, rightComponent, cellMeasures, a_offset, b_offset, leftFieldOrdinalOffset, rightFieldOrdinalOffset, forceNonSpecialized); - const int maxTeamSize = policy.team_size_max(functor,Kokkos::ParallelForTag()); - const int teamSize = functor.teamSize(maxTeamSize); + const int recommendedTeamSize = policy.team_size_recommended(functor,Kokkos::ParallelForTag()); + const int teamSize = functor.teamSize(recommendedTeamSize); policy = Kokkos::TeamPolicy(cellDataExtent,teamSize,vectorSize); diff --git a/packages/intrepid2/src/Shared/Intrepid2_Data.hpp b/packages/intrepid2/src/Shared/Intrepid2_Data.hpp index 1495bee47c3e..f437849d5424 100644 --- a/packages/intrepid2/src/Shared/Intrepid2_Data.hpp +++ b/packages/intrepid2/src/Shared/Intrepid2_Data.hpp @@ -37,11 +37,11 @@ namespace Intrepid2 { }; /** \struct Intrepid2::DimensionInfo - \brief Struct expressing all variation information about a Data object in a single dimension, including its nominal extent and storage extent. + \brief Struct expressing all variation information about a Data object in a single dimension, including its logical extent and storage extent. */ struct DimensionInfo { - int nominalExtent; + int logicalExtent; DataVariationType variationType; int dataExtent; int variationModulus; // should be equal to dataExtent variationType other than MODULAR and CONSTANT @@ -52,9 +52,9 @@ namespace Intrepid2 { KOKKOS_INLINE_FUNCTION DimensionInfo combinedDimensionInfo(const DimensionInfo &myData, const DimensionInfo &otherData) { - const int myNominalExtent = myData.nominalExtent; + const int myNominalExtent = myData.logicalExtent; #ifdef HAVE_INTREPID2_DEBUG - INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(myNominalExtent != otherData.nominalExtent, std::invalid_argument, "both Data objects must match in their nominal extent in the specified dimension"); + INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(myNominalExtent != otherData.logicalExtent, std::invalid_argument, "both Data objects must match in their logical extent in the specified dimension"); #endif const DataVariationType & myVariation = myData.variationType; const DataVariationType & otherVariation = otherData.variationType; @@ -66,7 +66,7 @@ namespace Intrepid2 { int otherDataExtent = otherData.dataExtent; DimensionInfo combinedDimensionInfo; - combinedDimensionInfo.nominalExtent = myNominalExtent; + combinedDimensionInfo.logicalExtent = myNominalExtent; switch (myVariation) { @@ -333,7 +333,7 @@ namespace Intrepid2 { for (int d=numActiveDims_; d<7; d++) { // for *inactive* dims, the activeDims_ map just is the identity - // (this allows getEntry() to work even when the nominal rank of the Data object is lower than that of the underlying View. This can happen for gradients in 1D.) + // (this allows getEntry() to work even when the logical rank of the Data object is lower than that of the underlying View. This can happen for gradients in 1D.) activeDims_[d] = d; } for (int d=0; d<7; d++) @@ -434,7 +434,6 @@ namespace Intrepid2 { storeInPlaceCombination(const Data &A, const Data &B, BinaryOperator binaryOperator) { auto policy = dataExtentRangePolicy(); - using PolicyType = decltype(policy); // shallow copy of this to avoid implicit references to this in calls to getWritableEntry() below Data thisData = *this; @@ -875,7 +874,7 @@ namespace Intrepid2 { } } - //! Returns an l-value reference to the specified nominal entry in the underlying view. Note that for variation types other than GENERAL, multiple valid argument sets will refer to the same memory location. Intended for Intrepid2 developers and expert users only. + //! Returns an l-value reference to the specified logical entry in the underlying view. Note that for variation types other than GENERAL, multiple valid argument sets will refer to the same memory location. Intended for Intrepid2 developers and expert users only. template KOKKOS_INLINE_FUNCTION reference_type getWritableEntry(const IntArgs... intArgs) const @@ -1023,7 +1022,7 @@ namespace Intrepid2 { } } - //! Constructor in terms of DimensionInfo for each nominal dimension; does not require a View to be specified. Will allocate a View of appropriate rank, zero-filled. + //! Constructor in terms of DimensionInfo for each logical dimension; does not require a View to be specified. Will allocate a View of appropriate rank, zero-filled. Data(std::vector dimInfoVector) : // initialize member variables as if default constructor; if dimInfoVector is empty, we want default constructor behavior. @@ -1039,7 +1038,7 @@ namespace Intrepid2 { for (int d=0; d getExtents() const { @@ -1357,7 +1356,7 @@ namespace Intrepid2 { { DimensionInfo dimInfo; - dimInfo.nominalExtent = extent_int(dim); + dimInfo.logicalExtent = extent_int(dim); dimInfo.variationType = variationType_[dim]; dimInfo.dataExtent = getDataExtent(dim); dimInfo.variationModulus = variationModulus_[dim]; @@ -1767,19 +1766,19 @@ namespace Intrepid2 { return false; // statement should be unreachable; included because compilers don't necessarily recognize that fact... } - //! Constructs a container suitable for storing the result of an in-place combination of the two provided data containers. The two containers must have the same nominal shape. + //! Constructs a container suitable for storing the result of an in-place combination of the two provided data containers. The two containers must have the same logical shape. //! \see storeInPlaceCombination() //! \param A [in] - the first data container. - //! \param B [in] - the second data container. Must have the same nominal shape as A. - //! \return A container with the same nominal shape as A and B, with underlying View storage sufficient to store the result of A + B (or any other in-place combination). + //! \param B [in] - the second data container. Must have the same logical shape as A. + //! \return A container with the same logical shape as A and B, with underlying View storage sufficient to store the result of A + B (or any other in-place combination). static Data allocateInPlaceCombinationResult( const Data &A, const Data &B ) { - INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(A.rank() != B.rank(), std::invalid_argument, "A and B must have the same nominal shape"); + INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(A.rank() != B.rank(), std::invalid_argument, "A and B must have the same logical shape"); const int rank = A.rank(); std::vector dimInfo(rank); for (int d=0; d result(dimInfo); @@ -1788,13 +1787,13 @@ namespace Intrepid2 { //! Constructs a container suitable for storing the result of a matrix-vector multiply corresponding to the two provided containers. //! \see storeMatMat() - //! \param A_MatData [in] - nominally (...,D1,D2)-dimensioned container, where D1,D2 correspond to matrix dimensions. + //! \param A_MatData [in] - logically (...,D1,D2)-dimensioned container, where D1,D2 correspond to matrix dimensions. //! \param transposeA [in] - if true, A will be transposed prior to being multiplied by B (or B's transpose). - //! \param B_MatData [in] - nominally (...,D3,D4)-dimensioned container, where D3,D4 correspond to matrix dimensions. + //! \param B_MatData [in] - logically (...,D3,D4)-dimensioned container, where D3,D4 correspond to matrix dimensions. //! \param transposeB [in] - if true, B will be transposed prior to the multiplication by A (or A's transpose). static Data allocateMatMatResult( const bool transposeA, const Data &A_MatData, const bool transposeB, const Data &B_MatData ) { - // we treat last two nominal dimensions of matData as the matrix; last dimension of vecData as the vector + // we treat last two logical dimensions of matData as the matrix; last dimension of vecData as the vector INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(A_MatData.rank() != B_MatData.rank(), std::invalid_argument, "AmatData and BmatData have incompatible ranks"); const int D1_DIM = A_MatData.rank() - 2; @@ -1976,7 +1975,7 @@ namespace Intrepid2 { //! \see storeMatVec() static Data allocateMatVecResult( const Data &matData, const Data &vecData ) { - // we treat last two nominal dimensions of matData as the matrix; last dimension of vecData as the vector + // we treat last two logical dimensions of matData as the matrix; last dimension of vecData as the vector INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(matData.rank() != vecData.rank() + 1, std::invalid_argument, "matData and vecData have incompatible ranks"); const int vecDim = vecData.extent_int(vecData.rank() - 1); const int matRows = matData.extent_int(matData.rank() - 2); @@ -2151,11 +2150,11 @@ namespace Intrepid2 { using ExecutionSpace = typename DeviceType::execution_space; #ifdef INTREPID2_HAVE_DEBUG - // check nominal extents + // check logical extents for (int d=0; dextent_int(d), std::invalid_argument, "A, B, and this must agree on all nominal extents"); - INTREPID2_TEST_FOR_EXCEPTION(B.extent_int(d) != this->extent_int(d), std::invalid_argument, "A, B, and this must agree on all nominal extents"); + INTREPID2_TEST_FOR_EXCEPTION(A.extent_int(d) != this->extent_int(d), std::invalid_argument, "A, B, and this must agree on all logical extents"); + INTREPID2_TEST_FOR_EXCEPTION(B.extent_int(d) != this->extent_int(d), std::invalid_argument, "A, B, and this must agree on all logical extents"); } // TODO: add some checks that data extent of this suffices to accept combined A + B data. #endif @@ -2301,16 +2300,16 @@ namespace Intrepid2 { //! Places the result of a matrix-matrix multiply corresponding to the two provided containers into this Data container. This Data container should have been constructed by a call to allocateMatMatResult(), or should match such a container in underlying data extent and variation types. //! \see allocateMatMat() - //! \param A_MatData [in] - nominally (...,D1,D2)-dimensioned container, where D1,D2 correspond to matrix dimensions. + //! \param A_MatData [in] - logically (...,D1,D2)-dimensioned container, where D1,D2 correspond to matrix dimensions. //! \param transposeA [in] - if true, A will be transposed prior to being multiplied by B (or B's transpose). - //! \param B_MatData [in] - nominally (...,D3,D4)-dimensioned container, where D3,D4 correspond to matrix dimensions. + //! \param B_MatData [in] - logically (...,D3,D4)-dimensioned container, where D3,D4 correspond to matrix dimensions. //! \param transposeB [in] - if true, B will be transposed prior to the multiplication by A (or A's transpose). void storeMatMat( const bool transposeA, const Data &A_MatData, const bool transposeB, const Data &B_MatData ) { // TODO: add a compile-time (SFINAE-type) guard against DataScalar types that do not support arithmetic operations. (We support Orientation as a DataScalar type; it might suffice just to compare DataScalar to Orientation, and eliminate this method for that case.) // TODO: check for invalidly shaped containers. - // we treat last two nominal dimensions of matData as the matrix; last dimension of vecData as the vector + // we treat last two logical dimensions of matData as the matrix; last dimension of vecData as the vector INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(A_MatData.rank() != B_MatData.rank(), std::invalid_argument, "AmatData and BmatData have incompatible ranks"); const int D1_DIM = A_MatData.rank() - 2; diff --git a/packages/intrepid2/src/Shared/Intrepid2_TensorData.hpp b/packages/intrepid2/src/Shared/Intrepid2_TensorData.hpp index 4a9293e26c3f..f42846072a67 100644 --- a/packages/intrepid2/src/Shared/Intrepid2_TensorData.hpp +++ b/packages/intrepid2/src/Shared/Intrepid2_TensorData.hpp @@ -117,7 +117,7 @@ namespace Intrepid2 \param [in] tensorComponents - the data components that will be multiplied together. May not have more than Parameters::MaxTensorComponents entries. \param [in] separateFirstComponent - if true, indicates that the first component will be indexed separately (this is used when the first index corresponds to a cell ordinal) - When separateFirstComponent is false, TensorData has rank equal to the maximum rank of the components in tensorComponents, and the nominal index in rank r is a function of the indices in rank r of its components, where the function is such that the fastest-moving component index is the one for the final component. Components that have rank less than r are understood to have index 0 in that dimension. + When separateFirstComponent is false, TensorData has rank equal to the maximum rank of the components in tensorComponents, and the logical index in rank r is a function of the indices in rank r of its components, where the function is such that the fastest-moving component index is the one for the final component. Components that have rank less than r are understood to have index 0 in that dimension. When separateFirstComponent is true, all components are required to have rank 1, and TensorData has rank 2, with the first argument reserved for the first component. The second argument is indexed precisely as described above, omitting the first component. */ @@ -140,7 +140,7 @@ namespace Intrepid2 \param [in] tensorComponents - the data components that will be multiplied together. May not have more than Parameters::MaxTensorComponents entries. \param [in] separateFirstComponent - if true, indicates that the first component will be indexed separately (this is used when the first index corresponds to a cell ordinal) - When separateFirstComponent is false, TensorData has rank equal to the maximum rank of the components in tensorComponents, and the nominal index in rank r is a function of the indices in rank r of its components, where the function is such that the fastest-moving component index is the one for the final component. Components that have rank less than r are understood to have index 0 in that dimension. + When separateFirstComponent is false, TensorData has rank equal to the maximum rank of the components in tensorComponents, and the logical index in rank r is a function of the indices in rank r of its components, where the function is such that the fastest-moving component index is the one for the final component. Components that have rank less than r are understood to have index 0 in that dimension. When separateFirstComponent is true, all components are required to have rank 1, and TensorData has rank 2, with the first argument reserved for the first component. The second argument is indexed precisely as described above, omitting the first component. */ @@ -161,7 +161,7 @@ namespace Intrepid2 \brief Simple constructor for the case of trivial tensor-product structure (single component) \param [in] tensorComponent - the data component. - Simple constructor for trivial tensor-product structure. The TensorData object will have precisely the same nominal data layout as the provided tensorComponent. + Simple constructor for trivial tensor-product structure. The TensorData object will have precisely the same logical data layout as the provided tensorComponent. */ TensorData(Data tensorComponent) : @@ -461,10 +461,10 @@ namespace Intrepid2 return value; } - /** \brief Returns the nominal extent in the requested dimension + /** \brief Returns the logical extent in the requested dimension \param [in] d - the dimension - \return nominal extent as an integer + \return logical extent as an integer */ template KOKKOS_INLINE_FUNCTION @@ -473,10 +473,10 @@ namespace Intrepid2 return extents_[d]; } - /** \brief Returns the nominal extent in the requested dimension + /** \brief Returns the logical extent in the requested dimension \param [in] d - the dimension - \return the nominal extent in the requested dimension. + \return the logical extent in the requested dimension. */ template KOKKOS_INLINE_FUNCTION constexpr diff --git a/packages/intrepid2/src/Shared/Intrepid2_TensorPoints.hpp b/packages/intrepid2/src/Shared/Intrepid2_TensorPoints.hpp index 9d444db7fc1b..3dac45917282 100644 --- a/packages/intrepid2/src/Shared/Intrepid2_TensorPoints.hpp +++ b/packages/intrepid2/src/Shared/Intrepid2_TensorPoints.hpp @@ -279,10 +279,10 @@ namespace Intrepid2 { return pointTensorComponents_[component](componentPointOrdinal,d); } - /** \brief Returns the nominal extent in the requested dimension. + /** \brief Returns the logical extent in the requested dimension. \param [in] r - the dimension - \return the nominal extent in the requested dimension, as an int. (This will be 1 for r >= 2, as this is a rank-2 container.) + \return the logical extent in the requested dimension, as an int. (This will be 1 for r >= 2, as this is a rank-2 container.) */ template KOKKOS_INLINE_FUNCTION @@ -302,10 +302,10 @@ namespace Intrepid2 { } } - /** \brief Returns the nominal extent in the requested dimension. + /** \brief Returns the logical extent in the requested dimension. \param [in] r - the dimension - \return the nominal extent in the requested dimension. (This will be 1 for r >= 2, as this is a rank-2 container.) + \return the logical extent in the requested dimension. (This will be 1 for r >= 2, as this is a rank-2 container.) */ template KOKKOS_INLINE_FUNCTION constexpr diff --git a/packages/intrepid2/src/Shared/Intrepid2_TransformedVectorData.hpp b/packages/intrepid2/src/Shared/Intrepid2_TransformedVectorData.hpp index 93e223210a20..197e3ed17e21 100644 --- a/packages/intrepid2/src/Shared/Intrepid2_TransformedVectorData.hpp +++ b/packages/intrepid2/src/Shared/Intrepid2_TransformedVectorData.hpp @@ -72,8 +72,8 @@ namespace Intrepid2 { /** \brief Standard constructor. - \param [in] transform - the transformation matrix, with nominal shape (C,P,D,D) - \param [in] vectorData - the reference-space data to be transformed, with nominal shape (F,P,D) + \param [in] transform - the transformation matrix, with logical shape (C,P,D,D) + \param [in] vectorData - the reference-space data to be transformed, with logical shape (F,P,D) */ TransformedVectorData(const Data &transform, const VectorData &vectorData) : @@ -85,7 +85,7 @@ namespace Intrepid2 { /** \brief Constructor for the case of an identity transform. - \param [in] vectorData - the reference-space data, with nominal shape (F,P,D) + \param [in] vectorData - the reference-space data, with logical shape (F,P,D) */ TransformedVectorData(const VectorData &vectorData) : @@ -126,25 +126,25 @@ namespace Intrepid2 { return transform_.getVariationTypes()[0]; } - //! Returns the nominal extent in the cell dimension, which is the 0 dimension in this container. + //! Returns the logical extent in the cell dimension, which is the 0 dimension in this container. KOKKOS_INLINE_FUNCTION int numCells() const { return transform_.extent_int(0); } - //! Returns the nominal extent in the fields dimension, which is the 1 dimension in this container. + //! Returns the logical extent in the fields dimension, which is the 1 dimension in this container. KOKKOS_INLINE_FUNCTION int numFields() const { return vectorData_.numFields(); } - //! Returns the nominal extent in the points dimension, which is the 2 dimension in this container. + //! Returns the logical extent in the points dimension, which is the 2 dimension in this container. KOKKOS_INLINE_FUNCTION int numPoints() const { return vectorData_.numPoints(); } - //! Returns the nominal extent in the space dimension, which is the 3 dimension in this container. + //! Returns the logical extent in the space dimension, which is the 3 dimension in this container. KOKKOS_INLINE_FUNCTION int spaceDim() const { return vectorData_.spaceDim(); diff --git a/packages/intrepid2/src/Shared/Intrepid2_Utils.hpp b/packages/intrepid2/src/Shared/Intrepid2_Utils.hpp index 4caa057d795b..01922bc8a243 100644 --- a/packages/intrepid2/src/Shared/Intrepid2_Utils.hpp +++ b/packages/intrepid2/src/Shared/Intrepid2_Utils.hpp @@ -350,7 +350,7 @@ namespace Intrepid2 { //! \brief Creates and returns a view that matches the provided view in Kokkos Layout. //! \param [in] view - the view to match //! \param [in] label - a string label for the view to be created - //! \param [in] dims - dimensions to use for the view (the nominal dimensions; this method handles adding the derivative dimension required for Fad types). + //! \param [in] dims - dimensions to use for the view (the logical dimensions; this method handles adding the derivative dimension required for Fad types). //! //! This method is particularly useful because we use LayoutStride as the Kokkos Layout in a number of places, and LayoutStride //! views cannot be instantiated without also providing stride information. diff --git a/packages/intrepid2/src/Shared/Intrepid2_VectorData.hpp b/packages/intrepid2/src/Shared/Intrepid2_VectorData.hpp index edea330388b5..5544c20cee6d 100644 --- a/packages/intrepid2/src/Shared/Intrepid2_VectorData.hpp +++ b/packages/intrepid2/src/Shared/Intrepid2_VectorData.hpp @@ -477,7 +477,7 @@ namespace Intrepid2 { KOKKOS_INLINE_FUNCTION int extent_int(const int &r) const { - // nominally (F,P,D) container + // logically (F,P,D) container if (r == 0) return numFields(); else if (r == 1) return numPoints(); else if (r == 2) return totalDimension_; @@ -491,7 +491,7 @@ namespace Intrepid2 { KOKKOS_INLINE_FUNCTION unsigned rank() const { - // nominally (F,P,D) container + // logically (F,P,D) container return 3; } diff --git a/packages/intrepid2/unit-test/MonolithicExecutable/DataTests.cpp b/packages/intrepid2/unit-test/MonolithicExecutable/DataTests.cpp index 63d9fe7c75bf..1305831c79a9 100644 --- a/packages/intrepid2/unit-test/MonolithicExecutable/DataTests.cpp +++ b/packages/intrepid2/unit-test/MonolithicExecutable/DataTests.cpp @@ -57,12 +57,12 @@ namespace { using namespace Intrepid2; -/** \brief Data has facilities for in-place combinations of logical data. Suppose you have two containers of nominal shape (C,P), one of which is constant across cells, the other of which is constant across points. To combine these (e.g., sum them together entrywise), you want a container that varies in both cells and points. The test below exercises the facility for allocation of the combined container. +/** \brief Data has facilities for in-place combinations of logical data. Suppose you have two containers of logical shape (C,P), one of which is constant across cells, the other of which is constant across points. To combine these (e.g., sum them together entrywise), you want a container that varies in both cells and points. The test below exercises the facility for allocation of the combined container. */ TEUCHOS_UNIT_TEST( Data, AllocateInPlaceCombinationResult ) { // test allocateInPlaceCombinationResult() - // Use two Data objects A and B, each with nominal shape (5,9,15) -- (C,F,P), say. + // Use two Data objects A and B, each with logical shape (5,9,15) -- (C,F,P), say. // with A having variation types of GENERAL, MODULAR, and CONSTANT, // and B having variation types of CONSTANT, CONSTANT, and GENERAL. // Result should have variation types of GENERAL, MODULAR, GENERAL. @@ -131,9 +131,9 @@ namespace DimensionInfo B_dimInfo; DimensionInfo AB_dimInfo; - A_dimInfo.nominalExtent = 15; - B_dimInfo.nominalExtent = 15; - AB_dimInfo.nominalExtent = 15; + A_dimInfo.logicalExtent = 15; + B_dimInfo.logicalExtent = 15; + AB_dimInfo.logicalExtent = 15; A_dimInfo.blockPlusDiagonalLastNonDiagonal = -1; B_dimInfo.blockPlusDiagonalLastNonDiagonal = -1; @@ -147,9 +147,9 @@ namespace B_dimInfo.variationType = CONSTANT; AB_dimInfo.variationType = GENERAL; - A_dimInfo.dataExtent = A_dimInfo.nominalExtent / ( A_dimInfo.nominalExtent / A_dimInfo.variationModulus); - B_dimInfo.dataExtent = B_dimInfo.nominalExtent / ( B_dimInfo.nominalExtent / B_dimInfo.variationModulus); - AB_dimInfo.dataExtent = AB_dimInfo.nominalExtent / (AB_dimInfo.nominalExtent / AB_dimInfo.variationModulus); + A_dimInfo.dataExtent = A_dimInfo.logicalExtent / ( A_dimInfo.logicalExtent / A_dimInfo.variationModulus); + B_dimInfo.dataExtent = B_dimInfo.logicalExtent / ( B_dimInfo.logicalExtent / B_dimInfo.variationModulus); + AB_dimInfo.dataExtent = AB_dimInfo.logicalExtent / (AB_dimInfo.logicalExtent / AB_dimInfo.variationModulus); // combinedDimensionInfo should commute, so let's test both directions: DimensionInfo AB_dimInfoActual_LR = combinedDimensionInfo(A_dimInfo, B_dimInfo); @@ -159,7 +159,7 @@ namespace for (const auto & dimInfoActual : actualCombinations) { - TEST_EQUALITY(dimInfoActual.nominalExtent, AB_dimInfo.nominalExtent); + TEST_EQUALITY(dimInfoActual.logicalExtent, AB_dimInfo.logicalExtent); TEST_EQUALITY(dimInfoActual.dataExtent, AB_dimInfo.dataExtent); TEST_EQUALITY(dimInfoActual.variationType, AB_dimInfo.variationType); TEST_EQUALITY(dimInfoActual.variationModulus, AB_dimInfo.variationModulus); @@ -213,7 +213,7 @@ namespace testFloatingEquality2(expectedView, data, relTol, absTol, out, success); } -/** \brief Data has facilities for in-place combinations of logical data. Suppose you have two containers of nominal shape (C,P), one of which is constant across cells, the other of which is constant across points. To combine these (e.g., sum them together entrywise), you want a container that varies in both cells and points. The test below exercises the facility for allocation of the combined container. +/** \brief Data has facilities for in-place combinations of logical data. Suppose you have two containers of logical shape (C,P), one of which is constant across cells, the other of which is constant across points. To combine these (e.g., sum them together entrywise), you want a container that varies in both cells and points. The test below exercises the facility for allocation of the combined container. */ TEUCHOS_UNIT_TEST( Data, InPlaceSum ) @@ -221,7 +221,7 @@ namespace double relTol = 1e-13; double absTol = 1e-13; - // Use two Data objects A and B, each with nominal shape (5,9,15) -- (C,F,P), say. + // Use two Data objects A and B, each with logical shape (5,9,15) -- (C,F,P), say. // with A having variation types of GENERAL, MODULAR, and CONSTANT, // and B having variation types of CONSTANT, CONSTANT, and GENERAL. // Result should have variation types of GENERAL, MODULAR, GENERAL. @@ -293,7 +293,7 @@ namespace AB_actual.storeInPlaceSum(A, B); - // test AB_actual equals AB_expected. (This will iterate over the nominal extents.) + // test AB_actual equals AB_expected. (This will iterate over the logical extents.) testFloatingEquality3(AB_actual, AB_expected, relTol, absTol, out, success); } diff --git a/packages/intrepid2/unit-test/performance/DataCombination/DataCombinationPerformance.cpp b/packages/intrepid2/unit-test/performance/DataCombination/DataCombinationPerformance.cpp index b965e28b1cb4..aa57b4e2536c 100644 --- a/packages/intrepid2/unit-test/performance/DataCombination/DataCombinationPerformance.cpp +++ b/packages/intrepid2/unit-test/performance/DataCombination/DataCombinationPerformance.cpp @@ -44,7 +44,7 @@ /** \file DataCombinationPerformance.cpp \brief Main for performance tests comparing performance when combining Intrepid2 Data objects (as sums and products) with the performance of (expanded) Kokkos View objects. - Specifically, we consider a few use cases, each with nominal shape (C,P): + Specifically, we consider a few use cases, each with logical shape (C,P): 1. Constant data. This case favors Data objects most heavily, since redundancy in the Views will be maximal. 2. "Affine" data. This has shape (C,P), but only varies in the cell dimension. 3. General data. There is no redundancy in the data. This case favors the View objects most heavily, and will maximally expose overhead from the Data implementation. diff --git a/packages/intrepid2/unit-test/performance/StructuredIntegration/StructuredIntegrationPerformance.cpp b/packages/intrepid2/unit-test/performance/StructuredIntegration/StructuredIntegrationPerformance.cpp index 7522a659da34..80e37693833e 100644 --- a/packages/intrepid2/unit-test/performance/StructuredIntegration/StructuredIntegrationPerformance.cpp +++ b/packages/intrepid2/unit-test/performance/StructuredIntegration/StructuredIntegrationPerformance.cpp @@ -495,6 +495,7 @@ int main( int argc, char* argv[] ) Calibration, Test, BestSerial, + BestOpenMP_16, BestCuda }; Mode mode; @@ -573,6 +574,10 @@ int main( int argc, char* argv[] ) { mode = BestSerial; } + else if (modeChoiceString == "BestOpenMP_16") + { + mode = BestOpenMP_16; + } else if (modeChoiceString == "Test") { mode = Test; @@ -699,8 +704,6 @@ int main( int argc, char* argv[] ) standardWorksetForPolyOrder[8] = 1; // Non-Affine Tensor - // it turns out 4096 is the best choice for the PointValueCache algorithm for any polyOrder from 1 to 5 - // this likely means we're not exposing enough parallelism within the cell. map nonAffineTensorWorksetForPolyOrder; nonAffineTensorWorksetForPolyOrder[1] = 256; nonAffineTensorWorksetForPolyOrder[2] = 256; @@ -721,7 +724,73 @@ int main( int argc, char* argv[] ) affineTensorWorksetForPolyOrder[7] = 1; affineTensorWorksetForPolyOrder[8] = 1; - // for the cases that we have not tried yet, we try to choose sensible guesses for workset size: + // for the cases that we have not tried yet (polyOrder > 8), we try to choose sensible guesses for workset size: + // 1 is best, we think, for polyOrder 8, so it'll be the best for the rest. + int worksetSize = 1; + for (int polyOrder=9; polyOrder <= polyOrderMax; polyOrder++) + { + nonAffineTensorWorksetForPolyOrder[polyOrder] = worksetSize; + affineTensorWorksetForPolyOrder[polyOrder] = worksetSize; + standardWorksetForPolyOrder[polyOrder] = worksetSize; + } + + int numCells = 1; + for (int d=0; d{polyOrder,meshWidth,worksetForAlgorithmChoice} ); + } + } + break; + + case BestOpenMP_16: + { + // manually calibrated workset sizes on iMac Pro (2.3 GHz Xeon W, 18-core, running with OpenMP, OMP_NUM_THREADS=16) + // Calibration for sum factorization cases was run while usePointCacheForRank3Tensor = true. + // (these were calibrated without much tuning for the affine tensor case; if/when that happens, will want to recalibrate.) + + map standardWorksetForPolyOrder; + standardWorksetForPolyOrder[1] = 1024; + standardWorksetForPolyOrder[2] = 128; + standardWorksetForPolyOrder[3] = 128; + standardWorksetForPolyOrder[4] = 256; + standardWorksetForPolyOrder[5] = 8; + standardWorksetForPolyOrder[6] = 2; + standardWorksetForPolyOrder[7] = 2; + standardWorksetForPolyOrder[8] = 1; + + // Non-Affine Tensor + map nonAffineTensorWorksetForPolyOrder; + nonAffineTensorWorksetForPolyOrder[1] = 512; + nonAffineTensorWorksetForPolyOrder[2] = 128; + nonAffineTensorWorksetForPolyOrder[3] = 256; + nonAffineTensorWorksetForPolyOrder[4] = 128; + nonAffineTensorWorksetForPolyOrder[5] = 32; + nonAffineTensorWorksetForPolyOrder[6] = 16; + nonAffineTensorWorksetForPolyOrder[7] = 16; + nonAffineTensorWorksetForPolyOrder[8] = 16; + + map affineTensorWorksetForPolyOrder; + affineTensorWorksetForPolyOrder[1] = 4096; + affineTensorWorksetForPolyOrder[2] = 256; + affineTensorWorksetForPolyOrder[3] = 512; + affineTensorWorksetForPolyOrder[4] = 128; + affineTensorWorksetForPolyOrder[5] = 64; + affineTensorWorksetForPolyOrder[6] = 32; + affineTensorWorksetForPolyOrder[7] = 16; + affineTensorWorksetForPolyOrder[8] = 64; + + // for the cases that we have not tried yet (polyOrder > 8), we try to choose sensible guesses for workset size: // 1 is best, we think, for polyOrder 8, so it'll be the best for the rest. int worksetSize = 1; for (int polyOrder=9; polyOrder <= polyOrderMax; polyOrder++) @@ -766,8 +835,8 @@ int main( int argc, char* argv[] ) standardWorksetForPolyOrder[8] = 1; // Non-Affine Tensor - // it turns out 4096 is the best choice for the PointValueCache algorithm for any polyOrder from 1 to 5 - // this likely means we're not exposing enough parallelism within the cell. + // For CUDA, 4096 is the best choice for the PointValueCache algorithm for any polyOrder from 1 to 5. + // This likely means we're not exposing enough parallelism within the cell. map nonAffineTensorWorksetForPolyOrder; nonAffineTensorWorksetForPolyOrder[1] = 4096; nonAffineTensorWorksetForPolyOrder[2] = 4096; @@ -778,7 +847,7 @@ int main( int argc, char* argv[] ) nonAffineTensorWorksetForPolyOrder[7] = 512; nonAffineTensorWorksetForPolyOrder[8] = 512; - // for the cases that we have not tried yet, we try to choose sensible guesses for workset size: + // for the cases that we have not tried yet (polyOrder > 8), we try to choose sensible guesses for workset size: int nonAffineWorksetSize = 256; // divide by 2 for each polyOrder beyond 8 int standardWorksetSize = 1; // 1 is best, we think, for polyOrder 8, so it'll be the best for the rest. for (int polyOrder=9; polyOrder <= polyOrderMax; polyOrder++) diff --git a/packages/kokkos/CMakeLists.txt b/packages/kokkos/CMakeLists.txt index d154aebc289f..600b7bff9506 100644 --- a/packages/kokkos/CMakeLists.txt +++ b/packages/kokkos/CMakeLists.txt @@ -208,15 +208,16 @@ IF (KOKKOS_HAS_TRILINOS) # Because Tribits doesn't use lists, it uses spaces for the list of CXX flags # we have to match the annoying behavior, also we have to preserve quotes # which needs another workaround. - IF (KOKKOS_ENABLE_SYCL) - SET(KOKKOS_COMPILE_OPTIONS_TMP) - FOREACH(OPTION ${KOKKOS_COMPILE_OPTIONS}) - LIST(APPEND KOKKOS_COMPILE_OPTIONS_TMP \"${OPTION}\") - ENDFOREACH() - STRING(REPLACE ";" " " KOKKOSCORE_COMPILE_OPTIONS "${KOKKOS_COMPILE_OPTIONS_TMP}") - ELSE() - STRING(REPLACE ";" " " KOKKOSCORE_COMPILE_OPTIONS "${KOKKOS_COMPILE_OPTIONS}") - ENDIF() + SET(KOKKOS_COMPILE_OPTIONS_TMP) + FOREACH(OPTION ${KOKKOS_COMPILE_OPTIONS}) + STRING(FIND "${OPTION}" " " OPTION_HAS_WHITESPACE) + IF(OPTION_HAS_WHITESPACE EQUAL -1) + LIST(APPEND KOKKOS_COMPILE_OPTIONS_TMP "${OPTION}") + ELSE() + LIST(APPEND KOKKOS_COMPILE_OPTIONS_TMP "\"${OPTION}\"") + ENDIF() + ENDFOREACH() + STRING(REPLACE ";" " " KOKKOSCORE_COMPILE_OPTIONS "${KOKKOS_COMPILE_OPTIONS_TMP}") LIST(APPEND KOKKOS_ALL_COMPILE_OPTIONS ${KOKKOS_COMPILE_OPTIONS}) IF (KOKKOS_ENABLE_CUDA) LIST(APPEND KOKKOS_ALL_COMPILE_OPTIONS ${KOKKOS_CUDA_OPTIONS}) diff --git a/packages/muelu/src/CMakeLists.txt b/packages/muelu/src/CMakeLists.txt index 21cd0c294c10..31c42c2d5a57 100644 --- a/packages/muelu/src/CMakeLists.txt +++ b/packages/muelu/src/CMakeLists.txt @@ -72,6 +72,9 @@ ENDIF() IF (${PACKAGE_NAME}_ENABLE_Experimental) INCLUDE_DIRECTORIES(${DIR}/../research/regionMG/src) ENDIF() +IF (${PACKAGE_NAME}_ENABLE_Stratimikos) + INCLUDE_DIRECTORIES(${DIR}/../adapters/stratimikos) +ENDIF() # Function to generate ETI (explicit template instantiation) files # from a template and list of class names diff --git a/packages/muelu/src/Smoothers/MueLu_StratimikosSmoother_decl.hpp b/packages/muelu/src/Smoothers/MueLu_StratimikosSmoother_decl.hpp index 7f36a308f1f9..d497a70a99e0 100644 --- a/packages/muelu/src/Smoothers/MueLu_StratimikosSmoother_decl.hpp +++ b/packages/muelu/src/Smoothers/MueLu_StratimikosSmoother_decl.hpp @@ -249,6 +249,15 @@ namespace MueLu { private: void SetupStratimikos (Level& currentLevel); + /*! + @brief Filter out any matrix connections that corresponds to coupling along a vertical grid line + + Builds a special filtered matrix for meshes that are structured in at least one direction (the z direction). Specifically + the new matrix has all the vertical connections removed. + */ + void ExperimentalDropVertConnections(RCP & filteredA, Level& currentLevel); + + //@} std::string type_; @@ -257,6 +266,7 @@ namespace MueLu { //! matrix, used in apply if solving residual equation RCP A_; + bool recurMgOnFilteredA_ = false; }; // class StratimikosSmoother } // namespace MueLu diff --git a/packages/muelu/src/Smoothers/MueLu_StratimikosSmoother_def.hpp b/packages/muelu/src/Smoothers/MueLu_StratimikosSmoother_def.hpp index eea606e58132..998c8b684938 100644 --- a/packages/muelu/src/Smoothers/MueLu_StratimikosSmoother_def.hpp +++ b/packages/muelu/src/Smoothers/MueLu_StratimikosSmoother_def.hpp @@ -61,12 +61,15 @@ #include "MueLu_FactoryManagerBase.hpp" #include "MueLu_Utilities.hpp" #include "MueLu_Monitor.hpp" +#include "Stratimikos_MueLuHelpers.hpp" #include #include "Teuchos_AbstractFactoryStd.hpp" #if defined(HAVE_MUELU_THYRATPETRAADAPTERS) && defined(HAVE_MUELU_IFPACK2) #include #endif +#include +#include namespace MueLu { @@ -75,6 +78,12 @@ namespace MueLu { StratimikosSmoother::StratimikosSmoother(const std::string type, const Teuchos::ParameterList& paramList) : type_(type) { + ParameterList& pList = const_cast(paramList); + + if (pList.isParameter("smoother: recurMgOnFilteredA")) { + recurMgOnFilteredA_ = true; + pList.remove("smoother: recurMgOnFilteredA"); + } bool isSupported = type == "STRATIMIKOS"; this->declareConstructionOutcome(!isSupported, "Stratimikos does not provide the smoother '" + type_ + "'."); if (isSupported) @@ -102,12 +111,26 @@ namespace MueLu { } template - void StratimikosSmoother::SetupStratimikos(Level& /* currentLevel */) { + void StratimikosSmoother::SetupStratimikos(Level& currentLevel) { - RCP > thyraA = Xpetra::ThyraUtils::toThyra(Teuchos::rcp_dynamic_cast(A_)->getCrsMatrix()); + RCP > thyraA; + if (recurMgOnFilteredA_) { + RCP filteredA; + ExperimentalDropVertConnections(filteredA, currentLevel); + thyraA = Xpetra::ThyraUtils::toThyra(Teuchos::rcp_dynamic_cast(filteredA)->getCrsMatrix()); + } + else thyraA = Xpetra::ThyraUtils::toThyra(Teuchos::rcp_dynamic_cast(A_)->getCrsMatrix()); // Build Stratimikos solver Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder; + if (recurMgOnFilteredA_) { +#ifdef MUELU_RECURMG + Stratimikos::enableMueLu(linearSolverBuilder); +#else + TEUCHOS_TEST_FOR_EXCEPTION( true , Exceptions::RuntimeError, "MueLu::StratimikosSmoother:: must compile with MUELU_RECURMG defined. Unfortunately, cmake does not always produce a proper link.txt file (which sometimes requires libmuelu.a before and after libmuelu-interface.a). After configuring, run script muelu/utils/misc/patchLinkForRecurMG to change link.txt files manually. If you want to create test example, add -DMUELU_RECURMG=ON to cmake arguments."); +#endif + } + typedef Thyra::PreconditionerFactoryBase Base; #if defined(HAVE_MUELU_THYRATPETRAADAPTERS) && defined(HAVE_MUELU_IFPACK2) typedef Thyra::Ifpack2PreconditionerFactory > Impl; @@ -119,6 +142,112 @@ namespace MueLu { // Build a new "solver factory" according to the previously specified parameter list. RCP > solverFactory = Thyra::createLinearSolveStrategy(linearSolverBuilder); solver_ = Thyra::linearOpWithSolve(*solverFactory, thyraA); +#ifdef dumpOutRecurMGDebug +char mystring[120]; +sprintf(mystring,"for i in A_[0123456789].m P_[0123456789].m; do T=Xecho $i | sed Xs/.m$/%d.m/XX; mv $i $T; done", (int) currentLevel.GetLevelID()); fflush(stdout); +mystring[50]='`'; mystring[65]='"'; mystring[76]='"'; mystring[77]='`'; +system(mystring); +#endif + } + + template + void StratimikosSmoother::ExperimentalDropVertConnections(RCP & filteredA, Level& currentLevel) { + + // strip out the veritcal connections. + // + // There is some code, which is currently turned off (via sumDropped). That + // makes things more complicated. I want to keep it for now, and so it is + // explained here. The basic idea is to try and maintain the character + // of the horizontal stencil by summing dropped entries appropriately. + // However, this does not correspond to plane relexation, and so I am + // not sure it is really justified. Anyway, the picture below + // gives a situation with a 15-pt stencil + // + // a + // / + // / + // b ----c----- d + // / + // / + // e + // f dropped a & l summed into f + // / dropped b & m summed into g + // / dropped c & n summed into i + // g ----i----- j dropped d & o summed into j + // / dropped e & p summed into k + // / + // k + // l + // / + // / + // m ----n----- o + // / + // / + // p + // To do this, we use umap to record locations within the middle layer associated + // with each line ID (e.g. g corresponds to the 13th line). Then, when dropping (in a 2nd pass) we + // use lineId and umap to find where dropped entries should be summed (e.g., b corresponds to the + // 13th line and umap[13] points at location for g). + using TST = typename Teuchos::ScalarTraits; + + bool sumDropped = false; + + LO dofsPerNode = A_->GetFixedBlockSize(); + + + RCP fillCompleteParams(new ParameterList); // This code taken from Build method + fillCompleteParams->set("No Nonlocal Changes", true); // within MueLu_FilteredAFactory_def + filteredA = MatrixFactory::Build(A_->getCrsGraph()); + filteredA->resumeFill(); + + ArrayView inds; + ArrayView valsA; + ArrayView vals; + Teuchos::ArrayRCP TVertLineId = Factory::Get< Teuchos::ArrayRCP > (currentLevel, "LineDetection_VertLineIds"); + Teuchos::ArrayRCP TLayerId = Factory::Get< Teuchos::ArrayRCP > (currentLevel, "LineDetection_Layers"); + LocalOrdinal* VertLineId = TVertLineId.getRawPtr(); + LocalOrdinal* LayerId = TLayerId.getRawPtr(); + TEUCHOS_TEST_FOR_EXCEPTION( (LayerId == NULL) || (VertLineId == NULL), Exceptions::RuntimeError, "MueLu::StratimikosSmoother:: no line information found on this level. Cannot use recurMgOnFilteredA on this level."); + + Scalar ZERO = Teuchos::ScalarTraits::zero(); + for (size_t i = 0; i < A_->getRowMap()->getNodeNumElements(); i++) { + A_->getLocalRowView(i, inds, valsA); + size_t nnz = inds.size(); + ArrayView vals1; + filteredA->getLocalRowView(i, inds, vals1); + vals = ArrayView(const_cast(vals1.getRawPtr()), nnz); + memcpy(vals.getRawPtr(), valsA.getRawPtr(), nnz*sizeof(Scalar)); + size_t inode, jdof, jnode, jdof_offset; + inode = i/dofsPerNode; + + std::unordered_map umap; // umap[k] indicates where the dropped entry + // corresponding to kth line should be added + // within the row. See comments above. + if (sumDropped) { + for (size_t j = 0; j < nnz; j++) { + jdof = inds[j]; + jnode = jdof/dofsPerNode; + jdof_offset = jdof - jnode*dofsPerNode; + if ( LayerId[jnode] == LayerId[inode] ) umap[dofsPerNode*VertLineId[jnode]+jdof_offset] = j; + } + } + + // drop non-middle layer entries. When sumDropped=true, sum dropped entries to corresponding mid-layer entry + for (size_t j = 0; j < nnz; j++) { + jdof = inds[j]; + jnode = jdof/dofsPerNode; + jdof_offset = jdof - jnode*dofsPerNode; + if ( LayerId[jnode] != LayerId[inode] ) { + if (sumDropped) { + if (umap.find(dofsPerNode*VertLineId[jnode + jdof_offset]) != umap.end()) + vals[umap[dofsPerNode*VertLineId[jnode + jdof_offset]]] += vals[j]; + } + vals[j] = ZERO; + } + } + } + filteredA->fillComplete(fillCompleteParams); + } template @@ -138,7 +267,8 @@ namespace MueLu { typedef Teuchos::ScalarTraits TST; RCP Residual = Utilities::Residual(*A_, X, B); - RCP< Thyra::MultiVectorBase > thyraCor = Teuchos::rcp_const_cast >(Xpetra::ThyraUtils::toThyraMultiVector(rcpFromRef(X))); + RCP Cor = Xpetra::MultiVectorFactory::Build(X.getMap(),X.getNumVectors(), true); + RCP< Thyra::MultiVectorBase > thyraCor = Teuchos::rcp_const_cast >(Xpetra::ThyraUtils::toThyraMultiVector(Cor)); RCP > thyraRes = Xpetra::ThyraUtils::toThyraMultiVector(Residual); Thyra::SolveStatus status = Thyra::solve(*solver_, Thyra::NOTRANS, *thyraRes, thyraCor.ptr()); RCP thyXpCor = Xpetra::ThyraUtils::toXpetra(thyraCor, X.getMap()->getComm()); @@ -147,6 +277,7 @@ namespace MueLu { } + template RCP > StratimikosSmoother::Copy() const { RCP smoother = rcp(new StratimikosSmoother(*this) ); diff --git a/packages/muelu/src/Transfers/SemiCoarsen/MueLu_SemiCoarsenPFactory_def.hpp b/packages/muelu/src/Transfers/SemiCoarsen/MueLu_SemiCoarsenPFactory_def.hpp index 8f423d086ef5..6d2db40fc888 100644 --- a/packages/muelu/src/Transfers/SemiCoarsen/MueLu_SemiCoarsenPFactory_def.hpp +++ b/packages/muelu/src/Transfers/SemiCoarsen/MueLu_SemiCoarsenPFactory_def.hpp @@ -814,12 +814,12 @@ namespace MueLu { if (nnz != 0) vals = ArrayView(const_cast(vals1.getRawPtr()), nnz); LO largestIndex = -1; - Scalar largestValue = 0.0; + Scalar largestValue = ZERO; /* find largest value in row and change that one to a 1 while the others are set to 0 */ LO rowDof = i%BlkSize; for (size_t j =0; j < nnz; j++) { - if (Teuchos::ScalarTraits::magnitude(vals[ j ]) > Teuchos::ScalarTraits::magnitude(largestValue)) { + if (Teuchos::ScalarTraits::magnitude(vals[ j ]) >= Teuchos::ScalarTraits::magnitude(largestValue)) { if ( inds[j]%BlkSize == rowDof ) { largestValue = vals[j]; largestIndex = (int) j; @@ -828,8 +828,10 @@ namespace MueLu { vals[j] = ZERO; } if (largestIndex != -1) vals[largestIndex] = ONE; - else + else TEUCHOS_TEST_FOR_EXCEPTION(nnz > 0, Exceptions::RuntimeError, "no nonzero column associated with a proper dof within node."); + + if (Teuchos::ScalarTraits::magnitude(largestValue) == Teuchos::ScalarTraits::magnitude(ZERO)) vals[largestIndex] = ZERO; } } diff --git a/packages/muelu/test/scaling/CMakeLists.txt b/packages/muelu/test/scaling/CMakeLists.txt index a91a7771e2d3..1e089dc43537 100644 --- a/packages/muelu/test/scaling/CMakeLists.txt +++ b/packages/muelu/test/scaling/CMakeLists.txt @@ -63,7 +63,7 @@ IF (${PACKAGE_NAME}_HAVE_TPETRA_SOLVER_STACK OR ${PACKAGE_NAME}_HAVE_EPETRA_SOLV ) TRIBITS_COPY_FILES_TO_BINARY_DIR(Driver_cp - SOURCE_FILES scaling.xml scaling.yaml scaling-complex.xml scaling-withglobalconstants.xml scaling-complex-withglobalconstants.xml circ_nsp_dependency.xml isorropia.xml iso_poisson.xml conchas_milestone_zoltan.xml conchas_milestone_zoltan2.xml conchas_milestone_zoltan2_complex.xml sa_with_ilu.xml sa_with_Ifpack2_line_detection.xml rap.xml smoother.xml smoother_complex.xml tripleMatrixProduct.xml scaling-ml.xml elasticity3D.xml amgx.json amgx.xml scaling-with-rerun.xml scaling_distance2_agg.xml smooVec.mm smooVecCoalesce.xml pairwise.xml sa_enforce_constraints.xml + SOURCE_FILES scaling.xml scaling.yaml scaling-complex.xml scaling-withglobalconstants.xml scaling-complex-withglobalconstants.xml circ_nsp_dependency.xml isorropia.xml iso_poisson.xml conchas_milestone_zoltan.xml conchas_milestone_zoltan2.xml conchas_milestone_zoltan2_complex.xml sa_with_ilu.xml sa_with_Ifpack2_line_detection.xml rap.xml smoother.xml smoother_complex.xml tripleMatrixProduct.xml scaling-ml.xml elasticity3D.xml amgx.json amgx.xml scaling-with-rerun.xml scaling_distance2_agg.xml smooVec.mm smooVecCoalesce.xml pairwise.xml sa_enforce_constraints.xml recurMG.xml CATEGORIES BASIC PERFORMANCE ) @@ -440,6 +440,15 @@ IF (${PACKAGE_NAME}_HAVE_TPETRA_SOLVER_STACK) NUM_MPI_PROCS 3 COMM mpi ) + IF ( MUELU_RECURMG ) + MUELU_ADD_SERIAL_AND_MPI_TEST( + Driver + NAME "RecursiveMGWithSemiCoarsening" + ARGS "--linAlgebra=Tpetra --xml=recurMG.xml --matrixType=Elasticity3D --nx=12 --ny=12 --nz=99 --belosType=\"Pseudoblock GMRES\" --noscale --its=50 --tol=1e-5" + NUM_MPI_PROCS 4 + COMM serial mpi + ) + ENDIF() ENDIF() diff --git a/packages/muelu/test/scaling/recurMG.xml b/packages/muelu/test/scaling/recurMG.xml new file mode 100644 index 000000000000..f22f517c5aee --- /dev/null +++ b/packages/muelu/test/scaling/recurMG.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/muelu/utils/misc/patchLinkForRecurMG b/packages/muelu/utils/misc/patchLinkForRecurMG new file mode 100755 index 000000000000..6822d999a29d --- /dev/null +++ b/packages/muelu/utils/misc/patchLinkForRecurMG @@ -0,0 +1,8 @@ +#!/bin/bash +# +# change all the link.txt files found in the build sub-tree starting from where patchLinkForRecurMG is invoked so that a libmuelu.a is added just before libmuelu-interface.a. +# This script needs to be re-run each time after configure is exectuted. +# +find . -name link.txt -exec sed -i "s, \([\./ ]*\)/src/Interface/libmuelu-interface\.a, \1/src/libmuelu.a \1/src/Interface/libmuelu-interface\.a," {} \; +find . -name link.txt -exec sed -i "s, \([\./ ]*\)/muelu/src/Interface/libmuelu-interface\.a, \1/muelu/src/libmuelu.a \1/muelu/src/Interface/libmuelu-interface\.a," {} \; + diff --git a/packages/seacas/applications/epu/EP_ExodusFile.C b/packages/seacas/applications/epu/EP_ExodusFile.C index 8576e0d78880..7cc75396d3a4 100644 --- a/packages/seacas/applications/epu/EP_ExodusFile.C +++ b/packages/seacas/applications/epu/EP_ExodusFile.C @@ -1,5 +1,5 @@ /* - * Copyright(C) 1999-2020 National Technology & Engineering Solutions + * Copyright(C) 1999-2021 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * @@ -10,6 +10,7 @@ #include "EP_Internals.h" #include "EP_ParallelDisks.h" #include "EP_SystemInterface.h" +#include "fmt/color.h" #include "fmt/ostream.h" #include "smart_assert.h" #include @@ -38,6 +39,7 @@ int Excn::ExodusFile::cpuWordSize_ = 0; int Excn::ExodusFile::mode64bit_ = 0; std::string Excn::ExodusFile::outputFilename_; bool Excn::ExodusFile::keepOpen_ = false; +bool Excn::ExodusFile::verifyValidFile_ = false; int Excn::ExodusFile::maximumNameLength_ = 32; Excn::ExodusFile::ExodusFile(int processor) : myProcessor_(processor) @@ -101,6 +103,32 @@ void Excn::ExodusFile::close_all() ex_close(outputId_); outputId_ = -1; } + + // We have had some issues with file corruption. Everything seems to be + // working fine, but when the file is opened later after EPU has completed, + // one or more of the output files (in subcyle mode) report being invalid. + // Here, if the user requests, we try to reopen the file and report an + // error if there is a problem. This might still not catch all bad files, + // but will hopefully catch some at the point that it happens... + if (verifyValidFile_) { + float version = 0.0; + int cpu_word_size = cpuWordSize_; + int io_word_size_var = ioWordSize_; + int mode = EX_READ; + mode |= mode64bit_; + int exoid = ex_open(outputFilename_.c_str(), mode, &cpu_word_size, &io_word_size_var, &version); + if (exoid < 0) { + ex_get_err(nullptr, nullptr, &exoid); + fmt::print(stderr, fmt::fg(fmt::color::red), + "EPU: Exodus error ({}) {}.\n" + "Output File verification failed for '{}'. Could not reopen output file after " + "closing it\n", + exoid, ex_strerror(exoid), outputFilename_); + } + else { + ex_close(exoid); + } + } } void Excn::ExodusFile::unlink_temporary_files() @@ -135,6 +163,8 @@ bool Excn::ExodusFile::initialize(const SystemInterface &si, int start_part, int mode64bit_ |= EX_ALL_INT64_DB; } + verifyValidFile_ = si.verify_valid_file(); + // See if we can keep files open int max_files = get_free_descriptor_count(); if (partCount_ <= max_files) { @@ -191,7 +221,7 @@ bool Excn::ExodusFile::initialize(const SystemInterface &si, int start_part, int mode |= mode64bit_; int exoid = ex_open(filenames_[p].c_str(), mode, &cpu_word_size, &io_word_size_var, &version); if (exoid < 0) { - fmt::print(stderr, "Cannot open file '{}'\n", filenames_[p]); + fmt::print(stderr, fmt::fg(fmt::color::red), "Cannot open file '{}'\n", filenames_[p]); return false; } @@ -226,7 +256,7 @@ bool Excn::ExodusFile::initialize(const SystemInterface &si, int start_part, int fileids_[p] = ex_open(filenames_[p].c_str(), mode, &cpuWordSize_, &io_word_size_var, &version); if (fileids_[p] < 0) { - fmt::print(stderr, "Cannot open file '{}'\n", filenames_[p]); + fmt::print(stderr, fmt::fg(fmt::color::red), "Cannot open file '{}'\n", filenames_[p]); return false; } ex_set_max_name_length(fileids_[p], maximumNameLength_); @@ -310,7 +340,7 @@ bool Excn::ExodusFile::create_output(const SystemInterface &si, int cycle) outputId_ = ex_create(outputFilename_.c_str(), mode, &cpuWordSize_, &ioWordSize_); } if (outputId_ < 0) { - fmt::print(stderr, "Cannot open file '{}'\n", outputFilename_); + fmt::print(stderr, fmt::fg(fmt::color::red), "Cannot open file '{}'\n", outputFilename_); return false; } diff --git a/packages/seacas/applications/epu/EP_ExodusFile.h b/packages/seacas/applications/epu/EP_ExodusFile.h index 3cf5038f749d..b1af04be02ec 100644 --- a/packages/seacas/applications/epu/EP_ExodusFile.h +++ b/packages/seacas/applications/epu/EP_ExodusFile.h @@ -1,5 +1,5 @@ /* - * Copyright(C) 1999-2020 National Technology & Engineering Solutions + * Copyright(C) 1999-2021 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * @@ -46,6 +46,7 @@ namespace Excn { static int cpuWordSize_; static std::string outputFilename_; static bool keepOpen_; + static bool verifyValidFile_; static int maximumNameLength_; static int mode64bit_; }; diff --git a/packages/seacas/applications/epu/EP_SystemInterface.C b/packages/seacas/applications/epu/EP_SystemInterface.C index e5e20462ecd9..6974a559939d 100644 --- a/packages/seacas/applications/epu/EP_SystemInterface.C +++ b/packages/seacas/applications/epu/EP_SystemInterface.C @@ -93,6 +93,13 @@ void Excn::SystemInterface::enroll_options() "\t\tthey are automatically deleted unless -keep_temporary is specified.", nullptr); + options_.enroll( + "verify_valid_file", GetLongOption::NoValue, + "Reopen the output file right after closing it to verify that the file is valid.\n" + "\t\tThis tries to detect file corruption immediately instead of later. Mainly useful in " + "large subcycle runs.", + nullptr); + options_.enroll( "add_nodal_communication_map", GetLongOption::NoValue, "In subcycle mode, add the `nodal communication map` data to the output files.\n" @@ -328,10 +335,11 @@ bool Excn::SystemInterface::parse_options(int argc, char **argv) sumSharedNodes_ = options_.retrieve("sum_shared_nodes") != nullptr; append_ = options_.retrieve("append") != nullptr; - subcycle_ = options_.get_option_value("subcycle", subcycle_); - cycle_ = options_.get_option_value("cycle", cycle_); - subcycleJoin_ = options_.retrieve("join_subcycles") != nullptr; - keepTemporary_ = options_.retrieve("keep_temporary") != nullptr; + subcycle_ = options_.get_option_value("subcycle", subcycle_); + cycle_ = options_.get_option_value("cycle", cycle_); + subcycleJoin_ = options_.retrieve("join_subcycles") != nullptr; + keepTemporary_ = options_.retrieve("keep_temporary") != nullptr; + verifyValidFile_ = options_.retrieve("verify_valid_file") != nullptr; if (options_.retrieve("map") != nullptr) { mapIds_ = true; diff --git a/packages/seacas/applications/epu/EP_SystemInterface.h b/packages/seacas/applications/epu/EP_SystemInterface.h index 7c368d520f40..09c52aee415f 100644 --- a/packages/seacas/applications/epu/EP_SystemInterface.h +++ b/packages/seacas/applications/epu/EP_SystemInterface.h @@ -75,6 +75,7 @@ namespace Excn { bool output_shared_nodes() const { return outputSharedNodes_; } bool is_auto() const { return auto_; } bool keep_temporary() const { return keepTemporary_; } + bool verify_valid_file() const { return verifyValidFile_; } int max_open_files() const { return maxOpenFiles_; @@ -149,6 +150,7 @@ namespace Excn { bool outputSharedNodes_{false}; bool auto_{false}; bool keepTemporary_{false}; + bool verifyValidFile_{false}; bool addNodalCommunicationMap_{false}; StringIdVector globalVarNames_; diff --git a/packages/seacas/applications/epu/EP_Version.h b/packages/seacas/applications/epu/EP_Version.h index cd412043efb8..841ba1a102ae 100644 --- a/packages/seacas/applications/epu/EP_Version.h +++ b/packages/seacas/applications/epu/EP_Version.h @@ -10,8 +10,8 @@ static char const *qainfo[] = { "epu -- E Pluribus Unum", - "2021/05/06", - "5.07", + "2021/05/28", + "5.08", }; #endif // SEACAS_Version_h diff --git a/packages/seacas/applications/exodiff/MinMaxData.h b/packages/seacas/applications/exodiff/MinMaxData.h index 2184d1258a0d..8ea7a51c79fd 100644 --- a/packages/seacas/applications/exodiff/MinMaxData.h +++ b/packages/seacas/applications/exodiff/MinMaxData.h @@ -3,6 +3,9 @@ // NTESS, the U.S. Government retains certain rights in this software. // // See packages/seacas/LICENSE for details +#ifndef MINMAXDATA_H +#define MINMAXDATA_H + #include enum class ToleranceType { @@ -77,3 +80,4 @@ class MinMaxData ToleranceType type{ToleranceType::mm_unknown}; }; +#endif diff --git a/packages/seacas/applications/mapvar-kd/optkd.h b/packages/seacas/applications/mapvar-kd/optkd.h index bac815ccfae9..2b8b630b2711 100644 --- a/packages/seacas/applications/mapvar-kd/optkd.h +++ b/packages/seacas/applications/mapvar-kd/optkd.h @@ -5,6 +5,8 @@ * * See packages/seacas/LICENSE for details */ +#ifndef OPTKD_H +#define OPTKD_H #define BUCKETSIZE 100 typedef struct optkdnode @@ -15,3 +17,4 @@ typedef struct optkdnode struct optkdnode *loson, *hison; int lopt, hipt; } optkdNode; +#endif diff --git a/packages/seacas/applications/nem_spread/ps_pario.h b/packages/seacas/applications/nem_spread/ps_pario.h index f481c4571457..338ba3e9b6c4 100644 --- a/packages/seacas/applications/nem_spread/ps_pario.h +++ b/packages/seacas/applications/nem_spread/ps_pario.h @@ -5,6 +5,10 @@ * * See packages/seacas/LICENSE for details */ + +#ifndef PS_PARIO_H +#define PS_PARIO_H + #include "ps_pario_const.h" double PIO_Time_Array[26]; /* Vector for timings */ @@ -12,3 +16,4 @@ double PIO_Time_Array[26]; /* Vector for timings */ struct Parallel_IO PIO_Info; std::string Par_Nem_File_Name; /* The par nemesis file name. */ +#endif diff --git a/packages/seacas/applications/nem_spread/rf_allo.h b/packages/seacas/applications/nem_spread/rf_allo.h index 084fb6ac9052..bf52c4caadbd 100644 --- a/packages/seacas/applications/nem_spread/rf_allo.h +++ b/packages/seacas/applications/nem_spread/rf_allo.h @@ -6,8 +6,11 @@ * See packages/seacas/LICENSE for details */ +#ifndef RF_ALLO_H +#define RF_ALLO_H /* function declarations for dynamic array allocation */ extern void *array_alloc(const char *file, int lineno, int numdim, ...); extern void safe_free(void **ptr); +#endif diff --git a/packages/seacas/applications/nem_spread/rf_io.h b/packages/seacas/applications/nem_spread/rf_io.h index 82c829fc43c4..605dfad31b84 100644 --- a/packages/seacas/applications/nem_spread/rf_io.h +++ b/packages/seacas/applications/nem_spread/rf_io.h @@ -5,15 +5,9 @@ * * See packages/seacas/LICENSE for details */ -/* - * - * - * - * Include file for I/O global variables used in FEM - * problem specification - * - */ +#ifndef RF_IO_H +#define RF_IO_H std::string ExoFile; /* Exodus II File containing problem definition. */ /* This name is the root name. */ std::string Output_File_Base_Name; /* Base name of output file. If it has a suffix, it will be @@ -45,3 +39,4 @@ int Num_Nset_Var = 0; /* The number of nodeset variables to reserve */ /* space in the output file for. */ int Num_Sset_Var = 0; /* The number of sideset variables to reserve */ /* space in the output file for. */ +#endif diff --git a/packages/seacas/applications/nem_spread/sort_utils.h b/packages/seacas/applications/nem_spread/sort_utils.h index 69bea11eee77..5f7759bb93b2 100644 --- a/packages/seacas/applications/nem_spread/sort_utils.h +++ b/packages/seacas/applications/nem_spread/sort_utils.h @@ -5,8 +5,11 @@ * * See packages/seacas/LICENSE for details */ +#ifndef SORT_UTILS_H +#define SORT_UTILS_H template void gds_iqsort(INT v[], INT iv[], size_t N); template void gds_qsort(INT v[], size_t N); template void indexed_sort(INT v[], INT iv[], size_t N); +#endif diff --git a/packages/seacas/libraries/aprepro_lib/apr_stats.h b/packages/seacas/libraries/aprepro_lib/apr_stats.h index e1d6b4dcbaa4..85af60e4e084 100644 --- a/packages/seacas/libraries/aprepro_lib/apr_stats.h +++ b/packages/seacas/libraries/aprepro_lib/apr_stats.h @@ -5,6 +5,9 @@ * * See packages/seacas/LICENSE for details */ +#ifndef APR_STATS_H +#define APR_STATS_H + #include "apr_util.h" // for check_valid_var, new_string, etc namespace SEAMS { @@ -24,3 +27,4 @@ namespace SEAMS { double StdDev{0.0}; }; } // namespace SEAMS +#endif diff --git a/packages/seacas/libraries/exoIIv2for32/test/CMakeLists.txt b/packages/seacas/libraries/exoIIv2for32/test/CMakeLists.txt index 59a7b1eb1c67..ca69091ee856 100644 --- a/packages/seacas/libraries/exoIIv2for32/test/CMakeLists.txt +++ b/packages/seacas/libraries/exoIIv2for32/test/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright(C) 1999-2020 National Technology & Engineering Solutions +# Copyright(C) 1999-2021 National Technology & Engineering Solutions # of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with # NTESS, the U.S. Government retains certain rights in this software. # @@ -37,9 +37,13 @@ IF ( NETCDF_NCDUMP_BINARY ) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/testall.in - ${CMAKE_CURRENT_BINARY_DIR}/testall + ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/testall @ONLY ) + # now copy the temporary into the final destination, setting the permissions + file(COPY ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/testall + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} + FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) # NOTE: The "LINKER_LANGUAGE CXX" is used to workaround an issue with # the trilinos cmake adding the pamgen and pamgen_extras libraries as @@ -50,45 +54,43 @@ IF ( NETCDF_NCDUMP_BINARY ) TRIBITS_ADD_EXECUTABLE( f32_${testName} NOEXEPREFIX NOEXESUFFIX LINKER_LANGUAGE Fortran SOURCES ${testName}.f) ENDFOREACH ( testName ) - TRIBITS_ADD_ADVANCED_TEST( - exodus_unit_tests - TEST_0 CMND /bin/bash ARGS ${CMAKE_CURRENT_BINARY_DIR}/testall - OUTPUT_FILE exodus_unit_tests.out - PASS_ANY - TEST_1 CMND diff ARGS ${CMAKE_CURRENT_SOURCE_DIR}/exodus_unit_tests.gold - ${CMAKE_CURRENT_BINARY_DIR}/exodus_unit_tests.out + TRIBITS_ADD_TEST( + testall + NOEXEPREFIX + NOEXESUFFIX + NAME exodus_unit_tests_for32 COMM mpi serial - OVERALL_NUM_MPI_PROCS 1 - FINAL_PASS_REGULAR_EXPRESSION + NUM_MPI_PROCS 1 ) + if ( TPL_Netcdf_Enables_Netcdf4 ) - CONFIGURE_FILE( - ${CMAKE_CURRENT_SOURCE_DIR}/testall_i64.in - ${CMAKE_CURRENT_BINARY_DIR}/testall_i64 - @ONLY - ) + CONFIGURE_FILE( + ${CMAKE_CURRENT_SOURCE_DIR}/testall_i64.in + ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/testall_i64 + @ONLY + ) + # now copy the temporary into the final destination, setting the permissions + file(COPY ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/testall_i64 + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} + FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) - TRIBITS_ADD_ADVANCED_TEST( - exodus_unit_tests_nc4_env - TEST_0 CMND /bin/bash ARGS ${CMAKE_CURRENT_BINARY_DIR}/testall netcdf4 - OUTPUT_FILE exodus_unit_tests.out - PASS_ANY - TEST_1 CMND diff ARGS ${CMAKE_CURRENT_SOURCE_DIR}/exodus_unit_tests.gold - ${CMAKE_CURRENT_BINARY_DIR}/exodus_unit_tests.out - COMM mpi serial - FINAL_PASS_REGULAR_EXPRESSION + TRIBITS_ADD_TEST( + testall + NOEXEPREFIX + NOEXESUFFIX + NAME exodus_unit_tests_for32_64 + ARGS netcdf4 + COMM mpi serial + NUM_MPI_PROCS 1 ) - TRIBITS_ADD_ADVANCED_TEST( - exodus_nc4_unit_tests - TEST_0 CMND /bin/bash ARGS ${CMAKE_CURRENT_BINARY_DIR}/testall_i64 - OUTPUT_FILE exodus_i64_unit_tests.out - PASS_ANY - TEST_1 CMND diff ARGS ${CMAKE_CURRENT_SOURCE_DIR}/exodus_i64_unit_tests.gold - ${CMAKE_CURRENT_BINARY_DIR}/exodus_i64_unit_tests.out - COMM mpi serial - OVERALL_NUM_MPI_PROCS 1 - FINAL_PASS_REGULAR_EXPRESSION + TRIBITS_ADD_TEST( + testall_i64 + NOEXEPREFIX + NOEXESUFFIX + NAME exodus_nc4_unit_tests_for32 + COMM mpi serial + NUM_MPI_PROCS 1 ) endif() ELSE() diff --git a/packages/seacas/libraries/exoIIv2for32/test/exodus_i64_unit_tests.gold b/packages/seacas/libraries/exoIIv2for32/test/exodus_i64_unit_tests.gold deleted file mode 100644 index f14692b5fbd2..000000000000 --- a/packages/seacas/libraries/exoIIv2for32/test/exodus_i64_unit_tests.gold +++ /dev/null @@ -1,12 +0,0 @@ -************************************************************************ -************************************************************************ -testwt ... -testrddi64 ... -testwtd ... -testrddi64 ... -testwtdi64 ... -testrddi64 ... -testrdd ... -testrd ... -************************************************************************ -************************************************************************ diff --git a/packages/seacas/libraries/exoIIv2for32/test/exodus_unit_tests.gold b/packages/seacas/libraries/exoIIv2for32/test/exodus_unit_tests.gold deleted file mode 100644 index c98081cbd0d8..000000000000 --- a/packages/seacas/libraries/exoIIv2for32/test/exodus_unit_tests.gold +++ /dev/null @@ -1,10 +0,0 @@ -************************************************************************ -************************************************************************ -testwt ... -testrd ... -testrdd ... -testwtd ... -testrdd ... -testrd ... -************************************************************************ -************************************************************************ diff --git a/packages/seacas/libraries/exoIIv2for32/test/testall.in b/packages/seacas/libraries/exoIIv2for32/test/testall.in index eec885246858..e1c8e35e0295 100644 --- a/packages/seacas/libraries/exoIIv2for32/test/testall.in +++ b/packages/seacas/libraries/exoIIv2for32/test/testall.in @@ -1,5 +1,5 @@ #! /usr/bin/env bash -# Copyright(C) 1999-2020 National Technology & Engineering Solutions +# Copyright(C) 1999-2021 National Technology & Engineering Solutions # of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with # NTESS, the U.S. Government retains certain rights in this software. # @@ -30,6 +30,8 @@ SRCDIR=@CMAKE_CURRENT_SOURCE_DIR@ NCDUMP=@NETCDF_NCDUMP@ DIFF="diff -w" +ret_status=0 + # testwt - single precision write test echo "************************************************************************" echo "************************************************************************" @@ -37,32 +39,40 @@ rm -f test.output echo "testwt ..." echo "begin testwt" > test.output ${PREFIX} ${BINDIR}/f32_testwt${SUFFIX} >> test.output +ret_status=$((ret_status+$?)) echo "end testwt" >> test.output ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/test.dmp | tee testwt.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) # testrd - single precision read test echo "testrd ..." ${PREFIX} ${BINDIR}/f32_testrd${SUFFIX} | grep -v version | grep -v _FillValue | grep -v "word size" |${DIFF} - ${SRCDIR}/testrd.dmp | tee testrd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) # testrdd - double precision read of single precision file echo "testrdd ..." ${PREFIX} ${BINDIR}/f32_testrdd${SUFFIX} | grep -v version | grep -v _FillValue | grep -v "word size" | ${DIFF} - ${SRCDIR}/testrdd.dmp | tee testrdd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) # testwtd - double precision write test echo "testwtd ..." echo "begin testwtd" >> test.output ${PREFIX} ${BINDIR}/f32_testwtd${SUFFIX} >> test.output -echo "end testwtd" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testd.dmp | tee testwtd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) # testrdd - double precision read test echo "testrdd ..." ${PREFIX} ${BINDIR}/f32_testrdd${SUFFIX} | grep -v version | grep -v _FillValue | grep -v "word size" | ${DIFF} - ${SRCDIR}/testrdd.dmp | tee testrdd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) # testrd - single precision read of double precision file echo "testrd ..." ${PREFIX} ${BINDIR}/f32_testrd${SUFFIX} | grep -v version | grep -v _FillValue | grep -v "word size" | ${DIFF} - ${SRCDIR}/testrd.dmp | tee testrd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) echo "************************************************************************" echo "************************************************************************" +exit $ret_status diff --git a/packages/seacas/libraries/exoIIv2for32/test/testall_i64.in b/packages/seacas/libraries/exoIIv2for32/test/testall_i64.in index 88882819fb25..faec96e6bda1 100644 --- a/packages/seacas/libraries/exoIIv2for32/test/testall_i64.in +++ b/packages/seacas/libraries/exoIIv2for32/test/testall_i64.in @@ -1,5 +1,5 @@ #! /usr/bin/env bash -# Copyright(C) 1999-2020 National Technology & Engineering Solutions +# Copyright(C) 1999-2021 National Technology & Engineering Solutions # of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with # NTESS, the U.S. Government retains certain rights in this software. # @@ -22,6 +22,8 @@ SRCDIR=@CMAKE_CURRENT_SOURCE_DIR@ NCDUMP=@NETCDF_NCDUMP@ DIFF="diff -w" +ret_status=0 + # testwt - single precision write test echo "************************************************************************" echo "************************************************************************" @@ -29,43 +31,55 @@ rm -f test.output echo "testwt ..." echo "begin testwt" > test.output ${PREFIX} ${BINDIR}/f32_testwt${SUFFIX} >> test.output -echo "end testwt" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/test.dmp | tee testwt.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testwt, status = $ret_status" >> test.output # testrdd - double precision read test with 64-bit integers echo "testrddi64 ..." ${PREFIX} ${BINDIR}/f32_testrddi64${SUFFIX} | grep -v version | grep -v _FillValue | grep -v "word size" | ${DIFF} - ${SRCDIR}/testrddi64.dmp | tee testrddi64.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) # testwtd - double precision write test echo "testwtd ..." echo "begin testwtd" >> test.output ${PREFIX} ${BINDIR}/f32_testwtd${SUFFIX} >> test.output -echo "end testwtd" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testd.dmp | tee testwtd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testwtd, status = $ret_status" >> test.output # testrdd - double precision read test with 64-bit integers echo "testrddi64 ..." ${PREFIX} ${BINDIR}/f32_testrddi64${SUFFIX} | grep -v version | grep -v _FillValue | grep -v "word size" | ${DIFF} - ${SRCDIR}/testrddi64.dmp | tee testrddi64.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) # testwtdi64 - double precision write test with 64-bit integers echo "testwtdi64 ..." echo "begin testwtdi64" >> test.output ${PREFIX} ${BINDIR}/f32_testwtdi64${SUFFIX} >> test.output -echo "end testwtdi64" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testdi64.dmp | tee testwtd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testwtdi64, status = $ret_status" >> test.output # testrdd - double precision read test with 64-bit integers echo "testrddi64 ..." ${PREFIX} ${BINDIR}/f32_testrddi64${SUFFIX} | grep -v version | grep -v _FillValue | grep -v "word size" | ${DIFF} - ${SRCDIR}/testrddi64.dmp | tee testrddi64.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) # testrdd - double precision read test echo "testrdd ..." ${PREFIX} ${BINDIR}/f32_testrdd${SUFFIX} | grep -v version | grep -v _FillValue | grep -v "word size" | ${DIFF} - ${SRCDIR}/testrdd.dmp | tee testrdd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) # testrd - single precision read of double precision file echo "testrd ..." ${PREFIX} ${BINDIR}/f32_testrd${SUFFIX} | grep -v version | grep -v _FillValue | grep -v "word size" | ${DIFF} - ${SRCDIR}/testrd.dmp | tee testrd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) echo "************************************************************************" echo "************************************************************************" +exit $ret_status diff --git a/packages/seacas/libraries/exodus/test/CMakeLists.txt b/packages/seacas/libraries/exodus/test/CMakeLists.txt index 7262b9df7d1b..357a1efa5b86 100644 --- a/packages/seacas/libraries/exodus/test/CMakeLists.txt +++ b/packages/seacas/libraries/exodus/test/CMakeLists.txt @@ -124,16 +124,24 @@ IF ( NETCDF_NCDUMP_BINARY ) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/testall.in - ${CMAKE_CURRENT_BINARY_DIR}/testall + ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/testall @ONLY ) + # now copy the temporary into the final destination, setting the permissions + file(COPY ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/testall + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} + FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) if ( TPL_Netcdf_Enables_Netcdf4 ) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/testnc4.in - ${CMAKE_CURRENT_BINARY_DIR}/testnc4 + ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/testnc4 @ONLY ) + # now copy the temporary into the final destination, setting the permissions + file(COPY ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/testnc4 + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} + FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) endif() # NOTE: The "LINKER_LANGUAGE CXX" is used to workaround an issue with @@ -149,53 +157,45 @@ IF ( NETCDF_NCDUMP_BINARY ) TRIBITS_ADD_EXECUTABLE( testwt-localization NOEXEPREFIX NOEXESUFFIX SOURCES testwt-localization.C LINKER_LANGUAGE CXX) IF (NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") - TRIBITS_ADD_ADVANCED_TEST( - exodus_unit_tests - TEST_0 CMND /bin/bash ARGS ${CMAKE_CURRENT_BINARY_DIR}/testall - OUTPUT_FILE exodus_unit_tests.out - PASS_ANY - TEST_1 CMND diff ARGS ${CMAKE_CURRENT_SOURCE_DIR}/exodus_unit_tests.gold${TS} - ${CMAKE_CURRENT_BINARY_DIR}/exodus_unit_tests.out + TRIBITS_ADD_TEST( + testall + NOEXEPREFIX + NOEXESUFFIX + NAME exodus_unit_tests COMM mpi serial - OVERALL_NUM_MPI_PROCS 1 - FINAL_PASS_REGULAR_EXPRESSION + NUM_MPI_PROCS 1 ) if ( TPL_Netcdf_Enables_Netcdf4 ) - TRIBITS_ADD_ADVANCED_TEST( - exodus_unit_tests_nc4_env - TEST_0 CMND /bin/bash ARGS ${CMAKE_CURRENT_BINARY_DIR}/testall netcdf4 - OUTPUT_FILE exodus_unit_tests.out - PASS_ANY - TEST_1 CMND diff ARGS ${CMAKE_CURRENT_SOURCE_DIR}/exodus_unit_tests.gold${TS} - ${CMAKE_CURRENT_BINARY_DIR}/exodus_unit_tests.out + TRIBITS_ADD_TEST( + testall + NOEXEPREFIX + NOEXESUFFIX + NAME exodus_unit_tests_nc4_env + ARGS netcdf4 COMM mpi serial - FINAL_PASS_REGULAR_EXPRESSION + NUM_MPI_PROCS 1 ) - TRIBITS_ADD_ADVANCED_TEST( - exodus_nc4_unit_tests - TEST_0 CMND /bin/bash ARGS ${CMAKE_CURRENT_BINARY_DIR}/testnc4 - OUTPUT_FILE exodus_nc4_unit_tests.out - PASS_ANY - TEST_1 CMND diff ARGS ${CMAKE_CURRENT_SOURCE_DIR}/exodus_nc4_unit_tests.gold - ${CMAKE_CURRENT_BINARY_DIR}/exodus_nc4_unit_tests.out + TRIBITS_ADD_TEST( + testnc4 + NOEXEPREFIX + NOEXESUFFIX + NAME exodus_nc4_unit_tests COMM mpi serial - OVERALL_NUM_MPI_PROCS 1 - FINAL_PASS_REGULAR_EXPRESSION + NUM_MPI_PROCS 1 ) endif() # if ( TPL_Netcdf_Enables_Netcdf5 ) - TRIBITS_ADD_ADVANCED_TEST( - exodus_unit_tests_nc5_env - TEST_0 CMND /bin/bash ARGS ${CMAKE_CURRENT_BINARY_DIR}/testall netcdf5 - OUTPUT_FILE exodus_unit_tests.out - PASS_ANY - TEST_1 CMND diff ARGS ${CMAKE_CURRENT_SOURCE_DIR}/exodus_unit_tests.gold${TS} - ${CMAKE_CURRENT_BINARY_DIR}/exodus_unit_tests.out - COMM mpi serial - FINAL_PASS_REGULAR_EXPRESSION + TRIBITS_ADD_TEST( + testall + NOEXEPREFIX + NOEXESUFFIX + NAME exodus_unit_tests_nc5_env + ARGS netcdf5 + COMM mpi serial + NUM_MPI_PROCS 1 ) # endif() endif() diff --git a/packages/seacas/libraries/exodus/test/exodus_nc4_unit_tests.gold b/packages/seacas/libraries/exodus/test/exodus_nc4_unit_tests.gold deleted file mode 100644 index 1d485c75ff44..000000000000 --- a/packages/seacas/libraries/exodus/test/exodus_nc4_unit_tests.gold +++ /dev/null @@ -1 +0,0 @@ -testwt-compress - verify can create compressed netcdf-4 files... diff --git a/packages/seacas/libraries/exodus/test/exodus_unit_tests.gold b/packages/seacas/libraries/exodus/test/exodus_unit_tests.gold deleted file mode 100644 index 02e0c11b40d7..000000000000 --- a/packages/seacas/libraries/exodus/test/exodus_unit_tests.gold +++ /dev/null @@ -1,61 +0,0 @@ -testwt - single precision write test... - -Exodus Library Warning/Error: [ex_put_name] in file 'test.exo' - ERROR: element block id 10 not found in file id 65536 -testrd - single precision read test... -testcp_ss - single-to-single precision copy test... -testcp_sd - single-to-double precision copy test... -testcp_nl - normal_model to large_model single precision copy test... -testcp_transient - copy mesh and transient data... -testwt_clb - single precision write test using concatenated puts... -testwtd - double precision write test... -testrdd - double precision read test... -testcp_dd - double-to-double precision copy test... -testcp_ds - double-to-single precision copy test... -testwt1 - single precision write files with several side sets... -testwt1 ... [Expect WEDGE6 warning from this test] -testrd1 - single precision read test of a file with several side sets... -testrd1 ... [Expect file create failure error, NOCLOBBER] -testrd1 ... [Expect failure locating elem var 1 for elem block 12] - -Exodus Library Warning/Error: [ex_create_int] - ERROR: file create failed for test.exo - NetCDF: File exists && NC_NOCLOBBER - -Exodus Library Warning/Error: [ex_get_var] in file 'test.exo' - ERROR: failed to locate element block 12 var 1 in file id 65536 - NetCDF: Variable not found -testwt_ss - write files to test side sets... -testwt_ss ... [Expect WEDGE6 warning from this test] -testrd_ss - read test of a file with several side sets... -testrd_ss ... [Expect warning for NULL sidesets 30 and 31] -testwt2 - single precision write 2 files (simultaneously open) test... -testrdwt - read from one and write to another (simultaneously open) file... -testwt_nc - write x y z components of coordinates separately... -testrd_nc - read x y z components of coordinates separately... -testwt-zeron - write file with zero nodes and elements... -testrd - read test of file with zero nodes and elements... -testwt-zeroe - write file with zero elements... -testrd - read test of file with zero elements... -testwt-one-attrib - read/write test of element attributes - read one at a time... -testwt-nsided - write file with nsided elements... -testrd-nsided - read file with nsided elements... -testwt-nfaced - write file with nfaced elements... -testrd-nfaced - read file with nfaced elements... -testwt-long-name - write file with long (64-character) names... -testrd - read long name file truncating to 32 characters on read... -testrd-long-name - read long name file... -test_nemesis - read long name file... -test-empty - read an empty (only ex_create called) exodus file... - -Exodus Library Warning/Error: [ex_get_init_ext] in file 'test.exo' - Warning: no title in file id 65536 - NetCDF: Attribute not found -testwt-results - write EXPERIMENTAL file with only transient data; no mesh bulk data... -testwt-assembly - write file containing assembly data -testrd-assembly - read file containing assembly data -test-add-assembly - add an assembly to an existing file -testwt-blob - write file containing blob data -testrd-blob - read file containing blob data -testwt-oned - write 1D mesh... -testrd - read test of 1D file... diff --git a/packages/seacas/libraries/exodus/test/exodus_unit_tests.gold_ts b/packages/seacas/libraries/exodus/test/exodus_unit_tests.gold_ts deleted file mode 100644 index e59f17d93282..000000000000 --- a/packages/seacas/libraries/exodus/test/exodus_unit_tests.gold_ts +++ /dev/null @@ -1,67 +0,0 @@ -testwt - single precision write test... - -Exodus Library Warning/Error: [ex_put_name] in file 'test.exo' - ERROR: element block id 10 not found in file id 65536 -testrd - single precision read test... -testcp_ss - single-to-single precision copy test... -testcp_sd - single-to-double precision copy test... -testcp_nl - normal_model to large_model single precision copy test... -testcp_transient - copy mesh and transient data... -testwt_clb - single precision write test using concatenated puts... -testwtd - double precision write test... -testrdd - double precision read test... -testcp_dd - double-to-double precision copy test... -testcp_ds - double-to-single precision copy test... -testwt1 - single precision write files with several side sets... -testwt1 ... [Expect WEDGE6 warning from this test] -testrd1 - single precision read test of a file with several side sets... -testrd1 ... [Expect file create failure error, NOCLOBBER] -testrd1 ... [Expect failure locating elem var 1 for elem block 12] - -Exodus Library Warning/Error: [ex_create_int] - ERROR: file create failed for test.exo - NetCDF: File exists && NC_NOCLOBBER - -Exodus Library Warning/Error: [ex_get_var] in file 'test.exo' - ERROR: failed to locate element block 12 var 1 in file id 65536 - NetCDF: Variable not found -testwt_ss - write files to test side sets... -testwt_ss ... [Expect WEDGE6 warning from this test] -testrd_ss - read test of a file with several side sets... -testrd_ss ... [Expect warning for NULL sidesets 30 and 31] -testwt2 - single precision write 2 files (simultaneously open) test... -testrdwt - read from one and write to another (simultaneously open) file... -testwt_nc - write x y z components of coordinates separately... -testrd_nc - read x y z components of coordinates separately... -testwt-zeron - write file with zero nodes and elements... -testrd - read test of file with zero nodes and elements... -testwt-zeroe - write file with zero elements... -testrd - read test of file with zero elements... -testwt-one-attrib - read/write test of element attributes - read one at a time... -testwt-nsided - write file with nsided elements... -testrd-nsided - read file with nsided elements... -testwt-nfaced - write file with nfaced elements... -testrd-nfaced - read file with nfaced elements... -testwt-long-name - write file with long (64-character) names... -testrd - read long name file truncating to 32 characters on read... -testrd-long-name - read long name file... -test_nemesis - read long name file... -test-empty - read an empty (only ex_create called) exodus file... - -Exodus Library Warning/Error: [ex_get_init_ext] in file 'test.exo' - Warning: no title in file id 65536 - NetCDF: Attribute not found -testwt-results - write EXPERIMENTAL file with only transient data; no mesh bulk data... -testwt-assembly - write file containing assembly data -testrd-assembly - read file containing assembly data -test-add-assembly - add an assembly to an existing file -testwt-blob - write file containing blob data -testrd-blob - read file containing blob data -testwt-oned - write 1D mesh... -testrd - read test of 1D file... -test_ts_nvar - each thread writes data for a single nodal variable... -test_ts_nvar_rd - each thread reads data for a single nodal variable... -test_ts_partial_nvar - each thread writes data for a single nodal variable... -test_ts_partial_nvar_rd - each thread reads data for a single nodal variable... -test_ts_files - each thread creates its own file... -test_ts_errval - multiple threads calling ex_err and ex_get_err... diff --git a/packages/seacas/libraries/exodus/test/testall.in b/packages/seacas/libraries/exodus/test/testall.in old mode 100644 new mode 100755 index 2804d389ca26..d696503f0ff5 --- a/packages/seacas/libraries/exodus/test/testall.in +++ b/packages/seacas/libraries/exodus/test/testall.in @@ -33,298 +33,385 @@ THREAD_SAFE=@SEACASExodus_ENABLE_THREADSAFE@ DIFF="diff -w" +ret_status=0 rm -f test.output echo "testwt - single precision write test..." echo "begin testwt" > test.output ${PREFIX} ${BINDIR}/testwt${SUFFIX} >> test.output -echo "end testwt" >> test.output +ret_status=$((ret_status+$?)) # Filter out the "maximum_name_length" attribute. Moves around in ncdump output for nc4 vs nc3 ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue |grep -v maximum_name_length | ${DIFF} - ${SRCDIR}/test.dmp | tee testwt.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) +echo "end testwt, status = $ret_status" >> test.output echo "testrd - single precision read test..." echo "begin testrd" >> test.output ${PREFIX} ${BINDIR}/testrd${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrd.dmp | tee testrd.res -echo "end testrd" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrd, status = $ret_status" >> test.output echo "testcp_ss - single-to-single precision copy test..." echo "begin testcp_ss" >> test.output ${PREFIX} ${BINDIR}/testcp${SUFFIX} >> test.output -echo "end testcp_ss" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 testcp.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testcp_ss.dmp | tee testcp_ss.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testcp_ss, status = $ret_status" >> test.output echo "testcp_sd - single-to-double precision copy test..." echo "begin testcp_sd" >> test.output ${PREFIX} ${BINDIR}/testcpd${SUFFIX} >> test.output -echo "end testcp_sd" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 testcpd.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testcp_sd.dmp | tee testcp_sd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testcp_sd, status = $ret_status" >> test.output echo "testcp_nl - normal_model to large_model single precision copy test..." echo "begin testcp_nl" >> test.output ${PREFIX} ${BINDIR}/testcp_nl${SUFFIX} >> test.output -echo "end testcp_nl" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 testcp_nl.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testcp_nl.dmp | tee testcp_nl.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testcp_nl, status = $ret_status" >> test.output echo "testcp_transient - copy mesh and transient data..." echo "begin testcp_tran" >> test.output ${PREFIX} ${BINDIR}/testcp_tran${SUFFIX} >> test.output -echo "end testcp_tran" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 testcp.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testcp_tran.dmp | tee testcp_tran.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testcp_tran, status = $ret_status" >> test.output echo "testwt_clb - single precision write test using concatenated puts..." echo "begin testwt_clb" >> test.output ${PREFIX} ${BINDIR}/testwt_clb${SUFFIX} >> test.output -echo "end testwt_clb" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/test_clb.dmp | tee testwt_clb.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testwt_clb, status = $ret_status" >> test.output echo "testwtd - double precision write test..." echo "begin testwtd" >> test.output ${PREFIX} ${BINDIR}/testwtd${SUFFIX} >> test.output -echo "end testwtd" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testd.dmp | tee testwtd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testwtd, status = $ret_status" >> test.output echo "testrdd - double precision read test..." echo "begin testrdd" >> test.output ${PREFIX} ${BINDIR}/testrdd${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrdd.dmp | tee testrdd.res -echo "end testrdd" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrdd, status = $ret_status" >> test.output echo "testcp_dd - double-to-double precision copy test..." echo "begin testcp_dd" >> test.output ${PREFIX} ${BINDIR}/testcpd${SUFFIX} >> test.output -echo "end testcp_dd" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 testcpd.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testcp_dd.dmp | tee testcp_dd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testcp_dd, status = $ret_status" >> test.output echo "testcp_ds - double-to-single precision copy test..." echo "begin testcp_ds" >> test.output ${PREFIX} ${BINDIR}/testcp${SUFFIX} >> test.output -echo "end testcp_ds" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 testcp.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testcp_ds.dmp | tee testcp_ds.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testcp_ds, status = $ret_status" >> test.output echo "testwt1 - single precision write files with several side sets..." echo "testwt1 ... [Expect WEDGE6 warning from this test]" echo "begin testwt1" >> test.output ${PREFIX} ${BINDIR}/testwt1${SUFFIX} >> test.output -echo "end testwt1" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/test1.dmp | tee testwt1.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testwt1, status = $ret_status" >> test.output echo "testrd1 - single precision read test of a file with several side sets..." echo "testrd1 ... [Expect file create failure error, NOCLOBBER]" echo "testrd1 ... [Expect failure locating elem var 1 for elem block 12]" echo "begin testrd1" >> test.output ${PREFIX} ${BINDIR}/testrd1${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrd1.dmp | tee testrd1.res -echo "end testrd1" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrd1, status = $ret_status" >> test.output echo "testwt_ss - write files to test side sets..." echo "testwt_ss ... [Expect WEDGE6 warning from this test]" echo "begin testwt_ss" >> test.output ${PREFIX} ${BINDIR}/testwt_ss${SUFFIX} >> test.output -echo "end testwt_ss" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testwt_ss.dmp | tee testwt_ss.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testwt_ss, status = $ret_status" >> test.output echo "testrd_ss - read test of a file with several side sets..." echo "testrd_ss ... [Expect warning for NULL sidesets 30 and 31]" echo "begin testrd_ss" >> test.output ${PREFIX} ${BINDIR}/testrd_ss${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrd_ss.dmp | tee testrd_ss.res -echo "end testrd_ss" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrd_ss, status = $ret_status" >> test.output echo "testwt2 - single precision write 2 files (simultaneously open) test..." echo "begin testwt2" >> test.output ${PREFIX} ${BINDIR}/testwt2${SUFFIX} >> test.output -echo "end testwt2" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/test2-1.dmp | tee testwt2-1.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) ${NCDUMP} -d5,5 test2.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/test2-2.dmp | tee testwt2-2.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testwt2, status = $ret_status" >> test.output echo "testrdwt - read from one and write to another (simultaneously open) file..." echo "begin testrdwt" >> test.output ${PREFIX} ${BINDIR}/testrdwt${SUFFIX} >> test.output -echo "end testrdwt" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test2.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/test2.dmp | tee testrdwt.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testrdwt, status = $ret_status" >> test.output echo "testwt_nc - write x y z components of coordinates separately..." echo "begin testwt_nc" >> test.output ${PREFIX} ${BINDIR}/testwt_nc${SUFFIX} >> test.output -echo "end testwt_nc" >> test.output +ret_status=$((ret_status+$?)) # Filter out the "maximum_name_length" attribute. Moves around in ncdump output for nc4 vs nc3 ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | grep -v maximum_name_length | ${DIFF} - ${SRCDIR}/test.dmp | tee testwt_nc.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) +echo "end testwt_nc, status = $ret_status" >> test.output echo "testrd_nc - read x y z components of coordinates separately..." echo "begin testrd_nc" >> test.output ${PREFIX} ${BINDIR}/testrd_nc${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrd_nc.dmp | tee testrd_nc.res -echo "end testrd" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrd, status = $ret_status" >> test.output echo "testwt-zeron - write file with zero nodes and elements..." echo "begin testwt-zeron" >> test.output ${PREFIX} ${BINDIR}/testwt-zeron${SUFFIX} >> test.output -echo "end testwt-zeron" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testwt-zeron.dmp | tee testwt-zeron.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testwt-zeron, status = $ret_status" >> test.output echo "testrd - read test of file with zero nodes and elements..." echo "begin testrd zero nodes" >> test.output ${PREFIX} ${BINDIR}/testrd${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrd_zeron.dmp | tee testrd_zeron.res -echo "end testrd zero nodes" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrd zero nodes, status = $ret_status" >> test.output echo "testwt-zeroe - write file with zero elements..." echo "begin testwt-zeroe" >> test.output ${PREFIX} ${BINDIR}/testwt-zeroe${SUFFIX} >> test.output -echo "end testwt-zeroe" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testwt-zeroe.dmp | tee testwt-zeroe.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testwt-zeroe, status = $ret_status" >> test.output echo "testrd - read test of file with zero elements..." echo "begin testrd zero elements" >> test.output ${PREFIX} ${BINDIR}/testrd${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrd_zeroe.dmp | tee testrd_zeroe.res -echo "end testrd zero elements" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrd zero elements, status = $ret_status" >> test.output echo "testwt-one-attrib - read/write test of element attributes - read one at a time..." echo "begin testwt-one-attrib - read attributes one at a time" >> test.output -${PREFIX} ${BINDIR}/testwt-one-attrib${SUFFIX} | tee testrd_zeroe.res -echo "end testwt-one-attrib - read attributes one at a time" >> test.output +${PREFIX} ${BINDIR}/testwt-one-attrib${SUFFIX} >> test.output +ret_status=$((ret_status+$?)) +echo "end testwt-one-attrib - read attributes one at a time, status = $ret_status" >> test.output echo "testwt-nsided - write file with nsided elements..." echo "begin testwt-nsided" >> test.output ${PREFIX} ${BINDIR}/testwt-nsided${SUFFIX} >> test.output -echo "end testwt-nsided" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test-nsided.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testwt-nsided.dmp | tee testwt-nsided.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testwt-nsided, status = $ret_status" >> test.output echo "testrd-nsided - read file with nsided elements..." echo "begin testrd-nsided" >> test.output ${PREFIX} ${BINDIR}/testrd-nsided${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrd-nsided.dmp | tee testrd-nsided.res -echo "end testrd-nsided" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrd-nsided, status = $ret_status" >> test.output echo "testwt-nfaced - write file with nfaced elements..." echo "begin testwt-nfaced" >> test.output ${PREFIX} ${BINDIR}/testwt-nfaced${SUFFIX} >> test.output -echo "end testwt-nfaced" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test-nfaced.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testwt-nfaced.dmp | tee testwt-nfaced.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testwt-nfaced, status = $ret_status" >> test.output echo "testrd-nfaced - read file with nfaced elements..." echo "begin testrd-nfaced" >> test.output ${PREFIX} ${BINDIR}/testrd-nfaced${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrd-nfaced.dmp | tee testrd-nfaced.res -echo "end testrd-nfaced" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrd-nfaced, status = $ret_status" >> test.output echo "testwt-long-name - write file with long (64-character) names..." echo "begin testwt-long-name" >> test.output # Filter out the "maximum_name_length" attribute. Moves around in ncdump output for nc4 vs nc3 ${PREFIX} ${BINDIR}/testwt-long-name${SUFFIX} >> test.output -echo "end testwt-long-name" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue |grep -v "maximum_name_length" | ${DIFF} - ${SRCDIR}/testwt-long-name.dmp | tee testwt-long-name.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3]})) +echo "end testwt-long-name, status = $ret_status" >> test.output echo "testrd - read long name file truncating to 32 characters on read..." echo "begin testrd (truncate)" >> test.output ${PREFIX} ${BINDIR}/testrd${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrd-nm32.dmp | tee testrd-nm32.res -echo "end testrd (truncate)" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrd (truncate), status = $ret_status" >> test.output echo "testrd-long-name - read long name file..." echo "begin testrd-long-name" >> test.output ${PREFIX} ${BINDIR}/testrd-long-name${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrd-long-name.dmp | tee testrd-long-name.res -echo "end testrd-long-name" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrd-long-name, status = $ret_status" >> test.output echo "test_nemesis - read long name file..." echo "begin test_nemesis" >> test.output ${PREFIX} ${BINDIR}/test_nemesis${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/test_nemesis.dmp | tee test_nemesis.res -echo "end test_nemesis" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end test_nemesis, status = $ret_status" >> test.output echo "test-empty - read an empty (only ex_create called) exodus file..." echo "begin test-empty" >> test.output ${PREFIX} ${BINDIR}/test-empty${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/test-empty.dmp | tee test-empty.res -echo "end test-empty" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end test-empty, status = $ret_status" >> test.output echo "testwt-results - write EXPERIMENTAL file with only transient data; no mesh bulk data..." echo "begin testwt-results" >> test.output ${PREFIX} ${BINDIR}/testwt-results${SUFFIX} >> test.output -echo "end testwt-results" >> test.output +ret_status=$((ret_status+$?)) # Filter out the "maximum_name_length" attribute. Moves around in ncdump output for nc4 vs nc3 -${NCDUMP} -d5,5 test-results.exo | grep -v version | grep -v _FillValue |grep -v "maximum_name_length" | ${DIFF} - ${SRCDIR}/testwt-results.dmp | tee testwt-results.res +${NCDUMP} -d5,5 test-results.exo | grep -v version | grep -v _FillValue |grep -v "maximum_name_length" | ${DIFF} - ${SRCDIR}/testwt-results.dmp | tee testwt-results.re +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) +echo "end testwt-results, status = $ret_status" >> test.output echo "testwt-assembly - write file containing assembly data" echo "begin testwt-assembly" >> test.output ${PREFIX} ${BINDIR}/testwt-assembly${SUFFIX} >> test.output -echo "end testwt-assembly" >> test.output +ret_status=$((ret_status+$?)) # Filter out the "maximum_name_length" attribute. Moves around in ncdump output for nc4 vs nc3 ${NCDUMP} -d5,5 test-assembly.exo | grep -v version | grep -v _FillValue |grep -v "maximum_name_length" | ${DIFF} - ${SRCDIR}/testwt-assembly.dmp | tee testwt-assembly.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) +echo "end testwt-assembly, status = $ret_status" >> test.output echo "testrd-assembly - read file containing assembly data" echo "begin testrd-assembly" >> test.output ${PREFIX} ${BINDIR}/testrd-assembly${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrd-assembly.dmp | tee testrd-assembly.res -echo "end testrd-assembly" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrd-assembly, status = $ret_status" >> test.output echo "test-add-assembly - add an assembly to an existing file" echo "begin test-add-assembly" >> test.output ${PREFIX} ${BINDIR}/test-add-assembly${SUFFIX} >> test.output +ret_status=$((ret_status+$?)) # Filter out the "maximum_name_length" attribute. Moves around in ncdump output for nc4 vs nc3 ${NCDUMP} -d5,5 test-assembly.exo | grep -v version | grep -v _FillValue |grep -v "maximum_name_length" | ${DIFF} - ${SRCDIR}/test-add-assembly.dmp | tee test-add-assembly.res -echo "end test-add-assembly" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) +echo "end test-add-assembly, status = $ret_status" >> test.output echo "testwt-blob - write file containing blob data" echo "begin testwt-blob" >> test.output ${PREFIX} ${BINDIR}/testwt-blob${SUFFIX} >> test.output -echo "end testwt-blob" >> test.output +ret_status=$((ret_status+$?)) # Filter out the "maximum_name_length" attribute. Moves around in ncdump output for nc4 vs nc3 ${NCDUMP} -d5,5 test-blob.exo | grep -v version | grep -v _FillValue |grep -v "maximum_name_length" | ${DIFF} - ${SRCDIR}/testwt-blob.dmp | tee testwt-blob.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) +echo "end testwt-blob, status = $ret_status" >> test.output echo "testrd-blob - read file containing blob data" echo "begin testrd-blob" >> test.output ${PREFIX} ${BINDIR}/testrd-blob${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrd-blob.dmp | tee testrd-blob.res -echo "end testrd-blob" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrd-blob, status = $ret_status" >> test.output echo "testwt-oned - write 1D mesh..." echo "begin testwt-oned" >> test.output ${PREFIX} ${BINDIR}/testwt-oned${SUFFIX} >> test.output -echo "end testwt-oned" >> test.output +ret_status=$((ret_status+$?)) # Filter out the "maximum_name_length" attribute. Moves around in ncdump output for nc4 vs nc3 ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue |grep -v "maximum_name_length" | ${DIFF} - ${SRCDIR}/testwt-oned.dmp | tee testwt-oned.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) +echo "end testwt-oned, status = $ret_status" >> test.output echo "testrd - read test of 1D file..." echo "begin testrd 1D" >> test.output ${PREFIX} ${BINDIR}/testrd${SUFFIX} | grep -v version | ${DIFF} - ${SRCDIR}/testrd-oned.dmp | tee testrd-oned.res -echo "end testrd 1D" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testrd 1D, status = $ret_status" >> test.output if [ "$THREAD_SAFE" == "YES" ]; then echo "test_ts_nvar - each thread writes data for a single nodal variable..." echo "begin test_ts_nvar" >> test.output ${PREFIX} ${BINDIR}/test_ts_nvar${SUFFIX} >> test.output -echo "end test_ts_nvar" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue |grep -v "maximum_name_length" | ${DIFF} - ${SRCDIR}/test_ts_nvar.dmp | tee testwt-long-name.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) +echo "end test_ts_nvar, status = $ret_status" >> test.output echo "test_ts_nvar_rd - each thread reads data for a single nodal variable..." echo "begin test_ts_nvar_rd" >> test.output ${PREFIX} ${BINDIR}/test_ts_nvar_rd${SUFFIX} | ${DIFF} - ${SRCDIR}/test_ts_nvar_rd.dmp | tee test_ts_nvar_rd.res -echo "end test_ts_nvar_rd" >> test.output +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end test_ts_nvar_rd, status = $ret_status" >> test.output echo "test_ts_partial_nvar - each thread writes data for a single nodal variable..." echo "begin test_ts_partial_nvar" >> test.output ${PREFIX} ${BINDIR}/test_ts_partial_nvar${SUFFIX} >> test.output -echo "end test_ts_partial_nvar" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue |grep -v "maximum_name_length" | ${DIFF} - ${SRCDIR}/test_ts_partial_nvar.dmp | tee testwt-long-name.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) +echo "end test_ts_partial_nvar, status = $ret_status" >> test.output echo "test_ts_partial_nvar_rd - each thread reads data for a single nodal variable..." echo "begin test_ts_partial_nvar_rd" >> test.output ${PREFIX} ${BINDIR}/test_ts_partial_nvar${SUFFIX} >> test.output -echo "end test_ts_partial_nvar_rd" >> test.output +ret_status=$((ret_status+$?)) ${PREFIX} ${BINDIR}/test_ts_partial_nvar_rd${SUFFIX} | ${DIFF} - ${SRCDIR}/test_ts_partial_nvar_rd.dmp | tee test_ts_partial_nvar_rd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[1]})) +echo "end test_ts_partial_nvar_rd, status = $ret_status" >> test.output + echo "test_ts_files - each thread creates its own file..." echo "begin test_ts_files" >> test.output ${PREFIX} ${BINDIR}/test_ts_files${SUFFIX} >> test.output -echo "end test_ts_files" >> test.output +ret_status=$((ret_status+$?)) mv test0.exo test.exo ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue |grep -v maximum_name_length | ${DIFF} - ${SRCDIR}/test.dmp | tee test_ts_files0.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) mv test1.exo test.exo ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue |grep -v maximum_name_length | ${DIFF} - ${SRCDIR}/test.dmp | tee test_ts_files1.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) mv test2.exo test.exo ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue |grep -v maximum_name_length | ${DIFF} - ${SRCDIR}/test.dmp | tee test_ts_files2.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) mv test3.exo test.exo ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue |grep -v maximum_name_length | ${DIFF} - ${SRCDIR}/test.dmp | tee test_ts_files3.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) mv test4.exo test.exo ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue |grep -v maximum_name_length | ${DIFF} - ${SRCDIR}/test.dmp | tee test_ts_files4.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) mv test5.exo test.exo ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue |grep -v maximum_name_length | ${DIFF} - ${SRCDIR}/test.dmp | tee test_ts_files5.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) mv test6.exo test.exo ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue |grep -v maximum_name_length | ${DIFF} - ${SRCDIR}/test.dmp | tee test_ts_files6.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) mv test7.exo test.exo ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue |grep -v maximum_name_length | ${DIFF} - ${SRCDIR}/test.dmp | tee test_ts_files7.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[4]})) +echo "end test_ts_files, status = $ret_status" >> test.output + echo "test_ts_errval - multiple threads calling ex_err and ex_get_err..." echo "begin test_ts_errval" >> test.output ${PREFIX} ${BINDIR}/test_ts_errval${SUFFIX} >> test.output -echo "end test_ts_errval" >> test.output +ret_status=$((ret_status+$?)) +echo "end test_ts_errval, status = $ret_status" >> test.output fi +exit $ret_status diff --git a/packages/seacas/libraries/exodus/test/testnc4.in b/packages/seacas/libraries/exodus/test/testnc4.in old mode 100644 new mode 100755 index fd884c7f366e..0e6e21d48a9a --- a/packages/seacas/libraries/exodus/test/testnc4.in +++ b/packages/seacas/libraries/exodus/test/testnc4.in @@ -1,4 +1,5 @@ -# Copyright(C) 1999-2020 National Technology & Engineering Solutions +#! /usr/bin/env bash +# Copyright(C) 1999-2021 National Technology & Engineering Solutions # of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with # NTESS, the U.S. Government retains certain rights in this software. # @@ -17,9 +18,13 @@ SRCDIR=@CMAKE_CURRENT_SOURCE_DIR@ NCDUMP=@NETCDF_NCDUMP@ DIFF="diff -w" +ret_status=0 rm -f test.output echo "testwt-compress - verify can create compressed netcdf-4 files..." echo "begin testwt-compress" >> test.output ${PREFIX} ${BINDIR}/testwt-compress${SUFFIX} >> test.output -echo "end testwt-compress" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -h -s test-compress.exo | grep Deflate | ${DIFF} - ${SRCDIR}/test-compress.dmp | tee test-compress.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[2]})) +echo "end testwt-compress, status = $ret_status" >> test.output +exit $ret_status diff --git a/packages/seacas/libraries/exodus_for/test/CMakeLists.txt b/packages/seacas/libraries/exodus_for/test/CMakeLists.txt index 105f6edca434..331e2f9bbb84 100644 --- a/packages/seacas/libraries/exodus_for/test/CMakeLists.txt +++ b/packages/seacas/libraries/exodus_for/test/CMakeLists.txt @@ -38,9 +38,13 @@ IF ( NETCDF_NCDUMP_BINARY ) CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/testall.in - ${CMAKE_CURRENT_BINARY_DIR}/testall + ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/testall @ONLY ) + # now copy the temporary into the final destination, setting the permissions + file(COPY ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/testall + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} + FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) # NOTE: The "LINKER_LANGUAGE CXX" is used to workaround an issue with # the trilinos cmake adding the pamgen and pamgen_extras libraries as @@ -51,17 +55,15 @@ IF ( NETCDF_NCDUMP_BINARY ) TRIBITS_ADD_EXECUTABLE( f_${testName} NOEXEPREFIX NOEXESUFFIX LINKER_LANGUAGE Fortran SOURCES ${testName}.f) ENDFOREACH ( testName ) - TRIBITS_ADD_ADVANCED_TEST( - exodus_unit_tests - TEST_0 CMND /bin/bash ARGS ${CMAKE_CURRENT_BINARY_DIR}/testall - OUTPUT_FILE exodus_unit_tests.out - PASS_ANY - TEST_1 CMND diff ARGS ${CMAKE_CURRENT_SOURCE_DIR}/exodus_unit_tests.gold - ${CMAKE_CURRENT_BINARY_DIR}/exodus_unit_tests.out + TRIBITS_ADD_TEST( + testall + NOEXEPREFIX + NOEXESUFFIX + NAME exodus_unit_tests_fortran COMM mpi serial - OVERALL_NUM_MPI_PROCS 1 - FINAL_PASS_REGULAR_EXPRESSION + NUM_MPI_PROCS 1 ) + ELSE() MESSAGE(STATUS "WARNING: ${PACKAGE_NAME}: Exodus unit tests will not be run due to failure finding ncdump executable.") diff --git a/packages/seacas/libraries/exodus_for/test/exodus_unit_tests.gold b/packages/seacas/libraries/exodus_for/test/exodus_unit_tests.gold deleted file mode 100644 index 49d53883eef9..000000000000 --- a/packages/seacas/libraries/exodus_for/test/exodus_unit_tests.gold +++ /dev/null @@ -1,19 +0,0 @@ -************************************************************************ -************************************************************************ -testwt ... -testrd ... -testrd ... [Expect ex_create NOCLOBBER error from this test] -testcp_ss ... -testcpnl ... -testwt1 ... -testwt1 ... [Expect WEDGE6 warning from this test] -testrd1 ... -testrd1 ... [Expect failure locating elem var 1 for elem block 12] -testwtd ... -testrdd ... -testwt2 ... -testwt_nsid ... -testrd_nsid ... -test_nem ... -************************************************************************ -************************************************************************ diff --git a/packages/seacas/libraries/exodus_for/test/testall.in b/packages/seacas/libraries/exodus_for/test/testall.in index 47a8cf9eb89d..66a1458bf9a9 100644 --- a/packages/seacas/libraries/exodus_for/test/testall.in +++ b/packages/seacas/libraries/exodus_for/test/testall.in @@ -1,5 +1,5 @@ #! /usr/bin/env bash -# Copyright(C) 1999-2020 National Technology & Engineering Solutions +# Copyright(C) 1999-2021 National Technology & Engineering Solutions # of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with # NTESS, the U.S. Government retains certain rights in this software. # @@ -18,6 +18,8 @@ SRCDIR=@CMAKE_CURRENT_SOURCE_DIR@ NCDUMP=@NETCDF_NCDUMP@ DIFF="diff -w" +ret_status=0 + # testwt - single precision write test echo "************************************************************************" echo "************************************************************************" @@ -25,8 +27,10 @@ rm -f test.output echo "testwt ..." echo "begin testwt" > test.output ${PREFIX} ${BINDIR}/f_testwt${SUFFIX} >> test.output -echo "end testwt" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/test.dmp | tee testwt.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3})) +echo "end testwt, status = $ret_status" >> test.output # testrd - single precision read test echo "testrd ..." @@ -37,62 +41,80 @@ ${PREFIX} ${BINDIR}/f_testrd${SUFFIX} | grep -v version | grep -v _FillValue | $ echo "testcp_ss ..." echo "begin testcp_ss" >> test.output ${PREFIX} ${BINDIR}/f_testcp${SUFFIX} >> test.output -echo "end testcp_ss" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 testcp.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testcp_ss.dmp | tee testcp_ss.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3})) +echo "end testcp_ss, status = $ret_status" >> test.output # testcpnl - single-to-single, normal to large copy test echo "testcpnl ..." echo "begin testcpnl" >> test.output ${PREFIX} ${BINDIR}/f_testcpnl${SUFFIX} >> test.output -echo "end testcpnl" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 testcpnl.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testcpnl.dmp | tee testcpnl.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3})) +echo "end testcpnl, status = $ret_status" >> test.output # testwt1 - single precision write test with multiple side sets echo "testwt1 ..." echo "testwt1 ... [Expect WEDGE6 warning from this test]" echo "begin testwt1" >> test.output ${PREFIX} ${BINDIR}/f_testwt1${SUFFIX} >> test.output -echo "end testwt1" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/test1.dmp | tee testwt1.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3})) +echo "end testwt1, status = $ret_status" >> test.output # testrd1 - single precision read test with multiple side sets echo "testrd1 ..." echo "testrd1 ... [Expect failure locating elem var 1 for elem block 12]" ${PREFIX} ${BINDIR}/f_testrd1${SUFFIX} | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testrd1.dmp | tee testrd1.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3})) # testwtd - double precision write test echo "testwtd ..." echo "begin testwtd" >> test.output ${PREFIX} ${BINDIR}/f_testwtd${SUFFIX} >> test.output -echo "end testwtd" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testd.dmp | tee testwtd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3})) +echo "end testwtd, status = $ret_status" >> test.output # testrdd - double precision read test echo "testrdd ..." ${PREFIX} ${BINDIR}/f_testrdd${SUFFIX} | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testrdd.dmp | tee testrdd.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3})) # testwt2 - single precision write 2 files (simultaneously open) test echo "testwt2 ..." echo "begin testwt2" >> test.output ${PREFIX} ${BINDIR}/f_testwt2${SUFFIX} >> test.output | grep -v "property name string" -echo "end testwt2" >> test.output ${NCDUMP} -d5,5 test.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/test2-1.dmp | tee testwt2-1.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3})) ${NCDUMP} -d5,5 test2.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/test2-2.dmp | tee testwt2-2.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3})) +echo "end testwt2, status = $ret_status" >> test.output echo "testwt_nsid ..." -echo "begin testwt_nsid" > test.output +echo "begin testwt_nsid" >> test.output ${PREFIX} ${BINDIR}/f_testwt_nsid${SUFFIX} >> test.output -echo "end testwt_nsid" >> test.output +ret_status=$((ret_status+$?)) ${NCDUMP} -d5,5 test-nsided.exo | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/test-nsided.dmp | tee testwt_nsid.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3})) +echo "end testwt_nsid, status = $ret_status" >> test.output # testrd_nsid - single precision read test echo "testrd_nsid ..." ${PREFIX} ${BINDIR}/f_testrd_nsid${SUFFIX} | grep -v version | grep -v _FillValue | ${DIFF} - ${SRCDIR}/testrd_nsid.dmp | tee testrd_nsid.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[3})) # test_nem - nemesis routines echo "test_nem ..." ${PREFIX} ${BINDIR}/f_test_nem${SUFFIX} | ${DIFF} -w - ${SRCDIR}/test_nem.dmp | tee test_nem.res +ret_status=$((ret_status+${PIPESTATUS[0]}+${PIPESTATUS[1})) +echo "end test_nem, status = $ret_status" >> test.output echo "************************************************************************" echo "************************************************************************" +exit $ret_status diff --git a/packages/seacas/libraries/ioss/src/Ioss_CopyDatabase.C b/packages/seacas/libraries/ioss/src/Ioss_CopyDatabase.C index 94046b4d4da7..0eaf9d4a2278 100644 --- a/packages/seacas/libraries/ioss/src/Ioss_CopyDatabase.C +++ b/packages/seacas/libraries/ioss/src/Ioss_CopyDatabase.C @@ -19,7 +19,7 @@ #if defined(_WIN32) #define WIN32_LEAN_AND_MEAN #define NOMINMAX -#include +#include #undef IN #undef OUT #endif @@ -96,37 +96,43 @@ namespace { void set_owned_node_count(Ioss::Region ®ion, int my_processor, INT dummy); template - size_t calculate_maximum_field_size(const std::vector &entities, size_t max_field_size) + std::pair + calculate_maximum_field_size(const std::vector & entities, + std::pair &max_field) { - size_t max_size = max_field_size; + size_t max_size = max_field.first; + std::string max_name = max_field.second; for (const auto &entity : entities) { Ioss::NameList fields; entity->field_describe(&fields); for (const auto &field_name : fields) { Ioss::Field field = entity->get_field(field_name); - max_size = std::max(field.get_size(), max_size); + if (field.get_size() > max_size) { + max_size = field.get_size(); + max_name = field_name; + } } } - return max_size; + return std::make_pair(max_size, max_name); } - size_t calculate_maximum_field_size(const Ioss::Region ®ion) + std::pair calculate_maximum_field_size(const Ioss::Region ®ion) { - size_t max_field_size = 0; - max_field_size = calculate_maximum_field_size(region.get_node_blocks(), max_field_size); - max_field_size = calculate_maximum_field_size(region.get_edge_blocks(), max_field_size); - max_field_size = calculate_maximum_field_size(region.get_face_blocks(), max_field_size); - max_field_size = calculate_maximum_field_size(region.get_element_blocks(), max_field_size); - max_field_size = calculate_maximum_field_size(region.get_sidesets(), max_field_size); - max_field_size = calculate_maximum_field_size(region.get_nodesets(), max_field_size); - max_field_size = calculate_maximum_field_size(region.get_edgesets(), max_field_size); - max_field_size = calculate_maximum_field_size(region.get_facesets(), max_field_size); - max_field_size = calculate_maximum_field_size(region.get_elementsets(), max_field_size); - max_field_size = calculate_maximum_field_size(region.get_commsets(), max_field_size); - max_field_size = calculate_maximum_field_size(region.get_structured_blocks(), max_field_size); - max_field_size = calculate_maximum_field_size(region.get_assemblies(), max_field_size); - max_field_size = calculate_maximum_field_size(region.get_blobs(), max_field_size); - return max_field_size; + std::pair max_field{}; + max_field = calculate_maximum_field_size(region.get_node_blocks(), max_field); + max_field = calculate_maximum_field_size(region.get_edge_blocks(), max_field); + max_field = calculate_maximum_field_size(region.get_face_blocks(), max_field); + max_field = calculate_maximum_field_size(region.get_element_blocks(), max_field); + max_field = calculate_maximum_field_size(region.get_sidesets(), max_field); + max_field = calculate_maximum_field_size(region.get_nodesets(), max_field); + max_field = calculate_maximum_field_size(region.get_edgesets(), max_field); + max_field = calculate_maximum_field_size(region.get_facesets(), max_field); + max_field = calculate_maximum_field_size(region.get_elementsets(), max_field); + max_field = calculate_maximum_field_size(region.get_commsets(), max_field); + max_field = calculate_maximum_field_size(region.get_structured_blocks(), max_field); + max_field = calculate_maximum_field_size(region.get_assemblies(), max_field); + max_field = calculate_maximum_field_size(region.get_blobs(), max_field); + return max_field; } template @@ -225,13 +231,14 @@ void Ioss::copy_database(Ioss::Region ®ion, Ioss::Region &output_region, int rank = dbi->util().parallel_rank(); // Minimize number of times that we grow the memory buffer used for transferring field data. - size_t max_field_size = calculate_maximum_field_size(region); + auto max_field = calculate_maximum_field_size(region); if (options.verbose && rank == 0) { - fmt::print(Ioss::DEBUG(), "\n Maximum Field size = {:L} bytes.\n", max_field_size); + fmt::print(Ioss::DEBUG(), "\n Maximum Field size = {:L} bytes for field '{}'.\n", + max_field.first, max_field.second); } DataPool data_pool; - data_pool.data.resize(max_field_size); + data_pool.data.resize(max_field.first); if (options.verbose && rank == 0) { fmt::print(Ioss::DEBUG(), " Resize finished...\n"); } @@ -771,10 +778,10 @@ namespace { #ifndef _MSC_VER struct timespec delay; delay.tv_sec = (int)options.delay; - delay.tv_nsec = (options.delay - delay.tv_sec) * 1000000000L; + delay.tv_nsec = (options.delay - delay.tv_sec) * 1'000'000'000L; nanosleep(&delay, nullptr); #else - Sleep((int)(options.delay * 1000)); + Sleep((int)(options.delay * 1'000)); #endif } } diff --git a/packages/seacas/libraries/ioss/src/Ioss_DatabaseIO.C b/packages/seacas/libraries/ioss/src/Ioss_DatabaseIO.C index f3ccc84e710d..1bf938c97eec 100644 --- a/packages/seacas/libraries/ioss/src/Ioss_DatabaseIO.C +++ b/packages/seacas/libraries/ioss/src/Ioss_DatabaseIO.C @@ -129,6 +129,40 @@ namespace { ymin = ymax = 0.0; } } + + void calc_bounding_box(size_t ndim, size_t node_count, std::vector &coordinates, + double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, + double &zmax) + { + xmin = DBL_MAX; + ymin = DBL_MAX; + zmin = DBL_MAX; + + xmax = -DBL_MAX; + ymax = -DBL_MAX; + zmax = -DBL_MAX; + + for (size_t i = 0; i < node_count; i++) { + xmin = my_min(xmin, coordinates[ndim * i + 0]); + xmax = my_max(xmax, coordinates[ndim * i + 0]); + + if (ndim > 1) { + ymin = my_min(ymin, coordinates[ndim * i + 1]); + ymax = my_max(ymax, coordinates[ndim * i + 1]); + } + + if (ndim > 2) { + zmin = my_min(zmin, coordinates[ndim * i + 2]); + zmax = my_max(zmax, coordinates[ndim * i + 2]); + } + } + if (ndim < 3) { + zmin = zmax = 0.0; + } + if (ndim < 2) { + ymin = ymax = 0.0; + } + } } // namespace namespace Ioss { @@ -1089,6 +1123,32 @@ namespace Ioss { return elementBlockBoundingBoxes[eb->name()]; } + AxisAlignedBoundingBox DatabaseIO::get_bounding_box(const Ioss::NodeBlock *nb) const + { + std::vector coordinates; + nb->get_field_data("mesh_model_coordinates", coordinates); + ssize_t nnode = nb->entity_count(); + ssize_t ndim = nb->get_property("component_degree").get_int(); + + double xmin, ymin, zmin, xmax, ymax, zmax; + calc_bounding_box(ndim, nnode, coordinates, xmin, ymin, zmin, xmax, ymax, zmax); + + std::vector minmax; + minmax.reserve(6); + minmax.push_back(xmin); + minmax.push_back(ymin); + minmax.push_back(zmin); + minmax.push_back(-xmax); + minmax.push_back(-ymax); + minmax.push_back(-zmax); + + util().global_array_minmax(minmax, Ioss::ParallelUtils::DO_MIN); + + AxisAlignedBoundingBox bbox(minmax[0], minmax[1], minmax[2], -minmax[3], -minmax[4], + -minmax[5]); + return bbox; + } + AxisAlignedBoundingBox DatabaseIO::get_bounding_box(const Ioss::StructuredBlock *sb) const { ssize_t ndim = sb->get_property("component_degree").get_int(); diff --git a/packages/seacas/libraries/ioss/src/Ioss_DatabaseIO.h b/packages/seacas/libraries/ioss/src/Ioss_DatabaseIO.h index f296484c1e1a..33de177fc5bc 100644 --- a/packages/seacas/libraries/ioss/src/Ioss_DatabaseIO.h +++ b/packages/seacas/libraries/ioss/src/Ioss_DatabaseIO.h @@ -1,4 +1,4 @@ -// Copyright(C) 1999-2020 National Technology & Engineering Solutions +// Copyright(C) 1999-2021 National Technology & Engineering Solutions // of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with // NTESS, the U.S. Government retains certain rights in this software. // @@ -445,6 +445,7 @@ namespace Ioss { return compute_block_membership__(efblock, block_membership); } + AxisAlignedBoundingBox get_bounding_box(const Ioss::NodeBlock *nb) const; AxisAlignedBoundingBox get_bounding_box(const Ioss::ElementBlock *eb) const; AxisAlignedBoundingBox get_bounding_box(const Ioss::StructuredBlock *sb) const; diff --git a/packages/seacas/libraries/ioss/src/Ioss_FileInfo.C b/packages/seacas/libraries/ioss/src/Ioss_FileInfo.C index f4b0ebf5f376..b51a9e8b1151 100644 --- a/packages/seacas/libraries/ioss/src/Ioss_FileInfo.C +++ b/packages/seacas/libraries/ioss/src/Ioss_FileInfo.C @@ -325,10 +325,10 @@ namespace Ioss { struct stat st; if (stat(path_root.c_str(), &st) != 0) { - const int mode = 0777; // Users umask will be applied to this. #ifdef _WIN32 if (mkdir(path_root.c_str()) != 0 && errno != EEXIST) { #else + const int mode = 0777; // Users umask will be applied to this. if (mkdir(path_root.c_str(), mode) != 0 && errno != EEXIST) { #endif errmsg << "ERROR: Cannot create directory '" << path_root << "': " << std::strerror(errno) diff --git a/packages/seacas/libraries/ioss/src/Ioss_Initializer.h b/packages/seacas/libraries/ioss/src/Ioss_Initializer.h index db41f1969c7d..a5dfd8152208 100644 --- a/packages/seacas/libraries/ioss/src/Ioss_Initializer.h +++ b/packages/seacas/libraries/ioss/src/Ioss_Initializer.h @@ -3,6 +3,8 @@ // NTESS, the U.S. Government retains certain rights in this software. // // See packages/seacas/LICENSE for details +#ifndef IOSS_INITIALIZER_H +#define IOSS_INITIALIZER_H namespace Ioss { class Initializer @@ -13,3 +15,4 @@ namespace Ioss { // Copy constructor }; } // namespace Ioss +#endif diff --git a/packages/seacas/libraries/ioss/src/Ioss_NodeBlock.C b/packages/seacas/libraries/ioss/src/Ioss_NodeBlock.C index 88849a738f55..4f1158b8036e 100644 --- a/packages/seacas/libraries/ioss/src/Ioss_NodeBlock.C +++ b/packages/seacas/libraries/ioss/src/Ioss_NodeBlock.C @@ -1,4 +1,4 @@ -// Copyright(C) 1999-2020 National Technology & Engineering Solutions +// Copyright(C) 1999-2021 National Technology & Engineering Solutions // of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with // NTESS, the U.S. Government retains certain rights in this software. // @@ -92,6 +92,11 @@ int64_t Ioss::NodeBlock::internal_put_field_data(const Ioss::Field &field, void return get_database()->put_field(this, field, data, data_size); } +Ioss::AxisAlignedBoundingBox Ioss::NodeBlock::get_bounding_box() const +{ + return get_database()->get_bounding_box(this); +} + bool Ioss::NodeBlock::operator==(const Ioss::NodeBlock &rhs) const { return Ioss::EntityBlock::operator==(rhs); diff --git a/packages/seacas/libraries/ioss/src/Ioss_NodeBlock.h b/packages/seacas/libraries/ioss/src/Ioss_NodeBlock.h index bbf098ad20ba..50b88060cd80 100644 --- a/packages/seacas/libraries/ioss/src/Ioss_NodeBlock.h +++ b/packages/seacas/libraries/ioss/src/Ioss_NodeBlock.h @@ -1,4 +1,4 @@ -// Copyright(C) 1999-2020 National Technology & Engineering Solutions +// Copyright(C) 1999-2021 National Technology & Engineering Solutions // of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with // NTESS, the U.S. Government retains certain rights in this software. // @@ -7,12 +7,13 @@ #ifndef IOSS_Ioss_NodeBlock_h #define IOSS_Ioss_NodeBlock_h -#include "Ioss_EntityType.h" // for EntityType, etc -#include "Ioss_Property.h" // for Property +#include #include -#include // for size_t -#include // for int64_t -#include // for string +#include // for EntityType, etc +#include // for Property +#include // for size_t +#include // for int64_t +#include // for string namespace Ioss { class DatabaseIO; } // namespace Ioss @@ -57,9 +58,10 @@ namespace Ioss { // An example would be 'element_block_count' for a region. Property get_implicit_property(const std::string &my_name) const override; - bool operator!=(const Ioss::NodeBlock &rhs) const; - bool operator==(const Ioss::NodeBlock &rhs) const; - bool equal(const Ioss::NodeBlock &rhs) const; + AxisAlignedBoundingBox get_bounding_box() const; + bool operator!=(const Ioss::NodeBlock &rhs) const; + bool operator==(const Ioss::NodeBlock &rhs) const; + bool equal(const Ioss::NodeBlock &rhs) const; protected: int64_t internal_get_field_data(const Field &field, void *data, diff --git a/packages/seacas/libraries/ioss/src/Ioss_Utils.C b/packages/seacas/libraries/ioss/src/Ioss_Utils.C index 49ba8ad30d83..95a166f94419 100644 --- a/packages/seacas/libraries/ioss/src/Ioss_Utils.C +++ b/packages/seacas/libraries/ioss/src/Ioss_Utils.C @@ -5,6 +5,7 @@ // See packages/seacas/LICENSE for details #include +#include #include #include @@ -1308,6 +1309,38 @@ int Ioss::Utils::term_width() return cols != 0 ? cols : 100; } +std::string Ioss::Utils::get_type_from_file(const std::string &filename) +{ + Ioss::FileInfo file(filename); + auto extension = file.extension(); + + // If the extension is numeric, then we are probably dealing with a single file of a + // set of FPP decomposed files (e.g. file.cgns.32.17). In that case, we tokenize + // with "." as delimiter and see if last two tokens are all digits and if there + // are at least 4 tokens (basename.extension.#proc.proc)... + bool all_dig = extension.find_first_not_of("0123456789") == std::string::npos; + if (all_dig) { + auto tokens = Ioss::tokenize(filename, "."); + if (tokens.size() >= 4) { + auto proc_count = tokens[tokens.size() - 2]; + if (proc_count.find_first_not_of("0123456789") == std::string::npos) { + extension = tokens[tokens.size() - 3]; + } + } + } + + if (extension == "e" || extension == "g" || extension == "gen" || extension == "exo") { + return "exodus"; + } + else if (extension == "cgns") { + return "cgns"; + } + else { + // "exodus" is default... + return "exodus"; + } +} + void Ioss::Utils::info_fields(const Ioss::GroupingEntity *ige, Ioss::Field::RoleType role, const std::string &header, const std::string &suffix) { diff --git a/packages/seacas/libraries/ioss/src/Ioss_Utils.h b/packages/seacas/libraries/ioss/src/Ioss_Utils.h index 594abe52187f..63fb2ecbb56f 100644 --- a/packages/seacas/libraries/ioss/src/Ioss_Utils.h +++ b/packages/seacas/libraries/ioss/src/Ioss_Utils.h @@ -30,6 +30,7 @@ namespace Ioss { } // namespace Ioss #define IOSS_ERROR(errmsg) throw std::runtime_error((errmsg).str()) +using namespace std::string_literals; namespace { // SEE: http://lemire.me/blog/2017/04/10/removing-duplicates-from-lists-quickly @@ -116,6 +117,9 @@ namespace Ioss { } } + /** \brief guess file type from extension */ + static std::string get_type_from_file(const std::string &filename); + template static void uniquify(std::vector &vec, bool skip_first = false) { auto it = vec.begin(); diff --git a/packages/seacas/libraries/ioss/src/Ioss_VariableType.C b/packages/seacas/libraries/ioss/src/Ioss_VariableType.C index d0cc206d5213..41f1fb4d5df4 100644 --- a/packages/seacas/libraries/ioss/src/Ioss_VariableType.C +++ b/packages/seacas/libraries/ioss/src/Ioss_VariableType.C @@ -1,4 +1,4 @@ -// Copyright(C) 1999-2020 National Technology & Engineering Solutions +// Copyright(C) 1999-2021 National Technology & Engineering Solutions // of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with // NTESS, the U.S. Government retains certain rights in this software. // @@ -167,7 +167,7 @@ namespace Ioss { { size_t size = suffices.size(); // Maximum suffix size is currently 5. - assert(size < 100000); + assert(size < 100'000); const VariableType *ivt = nullptr; if (size <= 1) { return nullptr; // All storage types must have at least 2 components. @@ -297,7 +297,7 @@ namespace Ioss { std::string VariableType::numeric_label(int which, int ncomp, const std::string &name) { - if (ncomp >= 100000) { + if (ncomp >= 100'000) { std::ostringstream errmsg; fmt::print(errmsg, "ERROR: Variable '{}' has {:L} components which is larger than the current maximum" diff --git a/packages/seacas/libraries/ioss/src/cgns/Iocgns_DatabaseIO.C b/packages/seacas/libraries/ioss/src/cgns/Iocgns_DatabaseIO.C index d7351c19383d..432b7dfaf765 100644 --- a/packages/seacas/libraries/ioss/src/cgns/Iocgns_DatabaseIO.C +++ b/packages/seacas/libraries/ioss/src/cgns/Iocgns_DatabaseIO.C @@ -30,7 +30,9 @@ #include #include #include +#ifndef _WIN32 #include +#endif #include #include @@ -44,7 +46,7 @@ #include "Ioss_SmartAssert.h" #include "Ioss_SubSystem.h" -//extern char hdf5_access[64]; +// extern char hdf5_access[64]; namespace { size_t global_to_zone_local_idx(size_t i, const Ioss::Map *block_map, const Ioss::Map &nodeMap, @@ -1250,8 +1252,29 @@ namespace Iocgns { for (auto &conn : block->m_zoneConnectivity) { if (conn.m_donorZone < 0) { auto donor_iter = m_zoneNameMap.find(conn.m_donorName); - SMART_ASSERT(donor_iter != m_zoneNameMap.end()); - conn.m_donorZone = (*donor_iter).second; + if (donor_iter == m_zoneNameMap.end()) { + if (proc_count == 1) { + // This is most likely a parallel decomposed model, but only a single + // part is being accessed. Do the best we can without being able to + // access the data on the other processor files... + auto zname_proc = Iocgns::Utils::decompose_name(conn.m_donorName, true); + conn.m_donorProcessor = zname_proc.second; + auto donor_block = get_region()->get_structured_block(zname_proc.first); + if (donor_block != nullptr) { + conn.m_donorZone = Iocgns::Utils::get_db_zone(donor_block); + } + else { + // Since we are only accessing a single file in a decomposed + // set of fpp files, we can't access the donor zone on the + // other processor(s), so we have to set the ZGC to inactive. + conn.m_isActive = false; + } + } + } + else { + SMART_ASSERT(donor_iter != m_zoneNameMap.end()); + conn.m_donorZone = (*donor_iter).second; + } } if (proc_count > 1) { int offset = (conn.m_donorProcessor * blocks.size() + (conn.m_donorZone - 1)) * 3; diff --git a/packages/seacas/libraries/ioss/src/cgns/Iocgns_Utils.C b/packages/seacas/libraries/ioss/src/cgns/Iocgns_Utils.C index f273c5fa92c9..84566abe3aa8 100644 --- a/packages/seacas/libraries/ioss/src/cgns/Iocgns_Utils.C +++ b/packages/seacas/libraries/ioss/src/cgns/Iocgns_Utils.C @@ -57,6 +57,17 @@ Iocgns::Utils::cgns_error(file_ptr, __FILE__, __func__, __LINE__, -1); \ } +#ifdef _WIN32 +char *strcasestr(char *haystack, const char *needle) +{ + char *c; + for (c = haystack; *c; c++) + if (!strncasecmp(c, needle, strlen(needle))) + return c; + return 0; +} +#endif + namespace { int power_2(int count) { @@ -547,7 +558,12 @@ int Iocgns::Utils::get_db_zone(const Ioss::GroupingEntity *entity) IOSS_ERROR(errmsg); } -size_t Iocgns::Utils::index(const Ioss::Field &field) { return field.get_index() & 0xffffffff; } +namespace { + const size_t CG_CELL_CENTER_FIELD_ID = 1ul << 30; + const size_t CG_VERTEX_FIELD_ID = 1ul << 31; +} + +size_t Iocgns::Utils::index(const Ioss::Field &field) { return field.get_index() & 0x00ffffff; } void Iocgns::Utils::set_field_index(const Ioss::Field &field, size_t index, CG_GridLocation_t location) @@ -1238,7 +1254,7 @@ size_t Iocgns::Utils::common_write_meta_data(int file_ptr, const Ioss::Region &r std::set zgc_names; for (const auto &zgc : sb->m_zoneConnectivity) { - if (zgc.is_valid() && zgc.is_active()) { + if (zgc.is_valid() && (zgc.is_active() || (!is_parallel && zgc.m_donorProcessor != zgc.m_ownerProcessor))) { int zgc_idx = 0; std::array owner_range{{zgc.m_ownerRangeBeg[0], zgc.m_ownerRangeBeg[1], zgc.m_ownerRangeBeg[2], zgc.m_ownerRangeEnd[0], diff --git a/packages/seacas/libraries/ioss/src/cgns/Iocgns_Utils.h b/packages/seacas/libraries/ioss/src/cgns/Iocgns_Utils.h index 6eb4adb687ce..5993b4068c8f 100644 --- a/packages/seacas/libraries/ioss/src/cgns/Iocgns_Utils.h +++ b/packages/seacas/libraries/ioss/src/cgns/Iocgns_Utils.h @@ -66,9 +66,6 @@ namespace Iocgns { Utils() = default; ~Utils() = default; - static const size_t CG_CELL_CENTER_FIELD_ID = 1ul << 33; - static const size_t CG_VERTEX_FIELD_ID = 1ul << 34; - static std::pair decompose_name(const std::string &name, bool is_parallel); static std::string decompose_sb_name(const std::string &name); diff --git a/packages/seacas/libraries/ioss/src/exodus/Ioex_IOFactory.C b/packages/seacas/libraries/ioss/src/exodus/Ioex_IOFactory.C index 5d6b9fb7cd97..71a4cfd256fd 100644 --- a/packages/seacas/libraries/ioss/src/exodus/Ioex_IOFactory.C +++ b/packages/seacas/libraries/ioss/src/exodus/Ioex_IOFactory.C @@ -1,4 +1,4 @@ -// Copyright(C) 1999-2020 National Technology & Engineering Solutions +// Copyright(C) 1999-2021 National Technology & Engineering Solutions // of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with // NTESS, the U.S. Government retains certain rights in this software. // @@ -16,6 +16,7 @@ #include #include #include // for string +#include #include "Ioss_CodeTypes.h" // for MPI_Comm #include "Ioss_DBUsage.h" // for DatabaseUsage @@ -115,6 +116,10 @@ namespace Ioex { fmt::print(config, "\tZoltan Library is Available for Parallel Decomposition.\n\n"); #else fmt::print(config, "\tZoltan Library is NOT Available for Parallel Decomposition.\n\n"); +#endif +#if defined(ZLIBNG_VERSION) + fmt::print(config, "\tZlib-NG library version {} being used for accelerated compression.\n\n", + ZLIBNG_VERSION); #endif return config.str(); } diff --git a/packages/seacas/libraries/ioss/src/exodus/Ioex_Utils.C b/packages/seacas/libraries/ioss/src/exodus/Ioex_Utils.C index 69bdf77a40b8..d1c155eaeac3 100644 --- a/packages/seacas/libraries/ioss/src/exodus/Ioex_Utils.C +++ b/packages/seacas/libraries/ioss/src/exodus/Ioex_Utils.C @@ -242,7 +242,7 @@ namespace Ioex { const char *s = substring; const char *t = type.c_str(); - assert(s != nullptr && t != nullptr); + SMART_ASSERT(s != nullptr && t != nullptr); while (*s != '\0' && *t != '\0') { if (*s++ != tolower(*t++)) { return false; @@ -309,7 +309,7 @@ namespace Ioex { // later... auto *new_entity = const_cast(entity); new_entity->property_erase(id_prop); - assert(!entity->property_exists(id_prop)); + SMART_ASSERT(!entity->property_exists(id_prop))(id_prop); } } return succeed; @@ -434,7 +434,7 @@ namespace Ioex { void fix_bad_name(char *name) { - assert(name != nullptr); + SMART_ASSERT(name != nullptr); size_t len = std::strlen(name); for (size_t i = 0; i < len; i++) { @@ -655,8 +655,8 @@ namespace Ioex { } if (block == nullptr || !block->contains(elem_id)) { block = region->get_element_block(elem_id); - assert(block != nullptr); - assert(!Ioss::Utils::block_is_omitted(block)); // Filtered out above. + SMART_ASSERT(block != nullptr); + SMART_ASSERT(!Ioss::Utils::block_is_omitted(block)); // Filtered out above. // nullptr if hetero sides on element common_ftopo = block->topology()->boundary_type(0); @@ -668,9 +668,19 @@ namespace Ioex { if (common_ftopo == nullptr && sides[iel] != current_side) { current_side = sides[iel]; - assert(current_side > 0 && current_side <= block->topology()->number_boundaries()); + if (current_side <= 0 || current_side > block->topology()->number_boundaries()) { + std::ostringstream errmsg; + fmt::print( + errmsg, + "ERROR: In sideset/surface '{}' for the element with id {:L} of topology '{}';\n\t" + "an invalid face index '{}' is specified.\n\tFace indices " + "must be between 1 and {}. ({})", + surface_name, elem_id, block->topology()->name(), current_side, + block->topology()->number_boundaries(), __func__); + IOSS_ERROR(errmsg); + } topo = block->topology()->boundary_type(sides[iel]); - assert(topo != nullptr); + SMART_ASSERT(topo != nullptr); } std::pair name_topo; if (split_type == Ioss::SPLIT_BY_TOPOLOGIES) { diff --git a/packages/seacas/libraries/ioss/src/faodel/Iofaodel_PropertySerialization.h b/packages/seacas/libraries/ioss/src/faodel/Iofaodel_PropertySerialization.h index c37fd7f9c9b6..e1fad5da5039 100644 --- a/packages/seacas/libraries/ioss/src/faodel/Iofaodel_PropertySerialization.h +++ b/packages/seacas/libraries/ioss/src/faodel/Iofaodel_PropertySerialization.h @@ -4,6 +4,9 @@ // // See packages/seacas/LICENSE for details +#ifndef Iofaodel_PropertySerialization_h +#define Iofaodel_PropertySerialization_h + #include "Iofaodel_Utils.h" #include #include @@ -60,3 +63,5 @@ namespace Iofaodel { std::string property_get_string(lunasa::DataObject ldo); } // namespace Iofaodel + +#endif diff --git a/packages/seacas/libraries/ioss/src/fmt b/packages/seacas/libraries/ioss/src/fmt deleted file mode 120000 index 6e3182ffa420..000000000000 --- a/packages/seacas/libraries/ioss/src/fmt +++ /dev/null @@ -1 +0,0 @@ -private_copy_fmt/fmt \ No newline at end of file diff --git a/packages/seacas/libraries/ioss/src/main/CMakeLists.txt b/packages/seacas/libraries/ioss/src/main/CMakeLists.txt index 6e2d7e0821a9..5905107b74ad 100644 --- a/packages/seacas/libraries/ioss/src/main/CMakeLists.txt +++ b/packages/seacas/libraries/ioss/src/main/CMakeLists.txt @@ -607,21 +607,12 @@ TRIBITS_ADD_ADVANCED_TEST(pamgen_to_unstructured_cgns ENDIF() endif() +if (CGNS_CGNSDIFF_BINARY) TRIBITS_ADD_ADVANCED_TEST(structured_cgns_assembly_copy TEST_0 EXEC io_shell ARGS ${CMAKE_CURRENT_SOURCE_DIR}/test/assemblies.cgns assemblies-out.cgns NUM_MPI_PROCS 1-4 NOEXEPREFIX NOEXESUFFIX - TEST_1 EXEC io_info ARGS ${CMAKE_CURRENT_SOURCE_DIR}/test/assemblies.cgns - OUTPUT_FILE gold.info.txt - NUM_MPI_PROCS 1 - NOEXEPREFIX NOEXESUFFIX - TEST_2 EXEC io_info ARGS assemblies-out.cgns - OUTPUT_FILE created.info.txt - NUM_MPI_PROCS 1 - NOEXEPREFIX NOEXESUFFIX - TEST_3 CMND grep ARGS -v Database gold.info.txt OUTPUT_FILE clean.gold.info.txt - TEST_4 CMND grep ARGS -v Database created.info.txt OUTPUT_FILE clean.created.info.txt - TEST_5 CMND diff ARGS clean.gold.info.txt clean.created.info.txt + TEST_1 CMND ${CGNS_CGNSDIFF_BINARY} ARGS -d ${CMAKE_CURRENT_SOURCE_DIR}/test/assemblies.cgns assemblies-out.cgns NUM_MPI_PROCS 1 COMM mpi ) @@ -634,21 +625,12 @@ if (TPL_ENABLE_MPI) TEST_1 EXEC io_shell ARGS --external assemblies-fpp-out.cgns assemblies-fpp-join.cgns NUM_MPI_PROCS 1-4 NOEXEPREFIX NOEXESUFFIX - TEST_2 EXEC io_info ARGS ${CMAKE_CURRENT_SOURCE_DIR}/test/assemblies.cgns - OUTPUT_FILE fpp-gold.info.txt - NUM_MPI_PROCS 1 - NOEXEPREFIX NOEXESUFFIX - TEST_3 EXEC io_info ARGS assemblies-fpp-join.cgns - OUTPUT_FILE fpp-created.info.txt - NUM_MPI_PROCS 1 - NOEXEPREFIX NOEXESUFFIX - TEST_4 CMND grep ARGS -v Database fpp-gold.info.txt OUTPUT_FILE clean.fpp-gold.info.txt - TEST_5 CMND grep ARGS -v Database fpp-created.info.txt OUTPUT_FILE clean.fpp-created.info.txt - TEST_6 CMND diff ARGS clean.fpp-gold.info.txt clean.fpp-created.info.txt + TEST_2 CMND ${CGNS_CGNSDIFF_BINARY} ARGS -d ${CMAKE_CURRENT_SOURCE_DIR}/test/assemblies.cgns assemblies-fpp-join.cgns NUM_MPI_PROCS 1 COMM mpi ) endif(TPL_ENABLE_MPI) +endif(CGNS_CGNSDIFF_BINARY) ENDIF(TPL_ENABLE_CGNS) diff --git a/packages/seacas/libraries/ioss/src/main/cgns_decomp.C b/packages/seacas/libraries/ioss/src/main/cgns_decomp.C index 29652b17c8d9..f1387eff3b67 100644 --- a/packages/seacas/libraries/ioss/src/main/cgns_decomp.C +++ b/packages/seacas/libraries/ioss/src/main/cgns_decomp.C @@ -22,7 +22,9 @@ #include #include #include +#ifndef _WIN32 #include +#endif #include #include #include diff --git a/packages/seacas/libraries/ioss/src/main/info_interface.C b/packages/seacas/libraries/ioss/src/main/info_interface.C index e2f264560e42..fae489c5ae92 100644 --- a/packages/seacas/libraries/ioss/src/main/info_interface.C +++ b/packages/seacas/libraries/ioss/src/main/info_interface.C @@ -1,36 +1,22 @@ /* - * Copyright(C) 1999-2020 National Technology & Engineering Solutions + * Copyright(C) 1999-2021 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * * See packages/seacas/LICENSE for details */ #include "Ioss_CodeTypes.h" -#include "Ioss_FileInfo.h" #include "Ioss_GetLongOpt.h" // for GetLongOption, etc +#include "Ioss_Utils.h" #include "fmt/ostream.h" #include "info_interface.h" + #include // for nullptr #include // for exit, EXIT_SUCCESS, getenv #include // for operator<<, basic_ostream, etc #include // for char_traits, string namespace { - std::string get_type_from_file(const std::string &filename) - { - Ioss::FileInfo file(filename); - auto extension = file.extension(); - if (extension == "e" || extension == "g" || extension == "gen" || extension == "exo") { - return "exodus"; - } - else if (extension == "cgns") { - return "cgns"; - } - else { - // "exodus" is default... - return "exodus"; - } - } } // namespace Info::Interface::Interface() { enroll_options(); } @@ -323,7 +309,7 @@ bool Info::Interface::parse_options(int argc, char **argv) } if (filetype_ == "unknown") { - filetype_ = get_type_from_file(filename_); + filetype_ = Ioss::Utils::get_type_from_file(filename_); } } diff --git a/packages/seacas/libraries/ioss/src/main/io_info.C b/packages/seacas/libraries/ioss/src/main/io_info.C index 89f9c38d1dc4..747b3954652f 100644 --- a/packages/seacas/libraries/ioss/src/main/io_info.C +++ b/packages/seacas/libraries/ioss/src/main/io_info.C @@ -190,7 +190,14 @@ namespace { info_aliases(region, &nb, false, true); } Ioss::Utils::info_fields(&nb, Ioss::Field::ATTRIBUTE, prefix + "\tAttributes: "); - Ioss::Utils::info_fields(&nb, Ioss::Field::TRANSIENT, prefix + "\tTransient: "); + Ioss::Utils::info_fields(&nb, Ioss::Field::TRANSIENT, prefix + "\tTransient: "); + + if (interFace.compute_bbox()) { + Ioss::AxisAlignedBoundingBox bbox = nb.get_bounding_box(); + fmt::print("\tBounding Box: Minimum X,Y,Z = {:12.4e}\t{:12.4e}\t{:12.4e}\n" + "\t Maximum X,Y,Z = {:12.4e}\t{:12.4e}\t{:12.4e}\n", + bbox.xmin, bbox.ymin, bbox.zmin, bbox.xmax, bbox.ymax, bbox.zmax); + } } void info_nodeblock(Ioss::Region ®ion, const Info::Interface &interFace) diff --git a/packages/seacas/libraries/ioss/src/main/modify_interface.C b/packages/seacas/libraries/ioss/src/main/modify_interface.C index 34067eda04f5..48c4f2782639 100644 --- a/packages/seacas/libraries/ioss/src/main/modify_interface.C +++ b/packages/seacas/libraries/ioss/src/main/modify_interface.C @@ -1,5 +1,5 @@ /* - * Copyright(C) 1999-2020 National Technology & Engineering Solutions + * Copyright(C) 1999-2021 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * @@ -7,33 +7,16 @@ */ #include "Ioss_CodeTypes.h" -#include "Ioss_FileInfo.h" -#include "Ioss_GetLongOpt.h" // for GetLongOption, etc +#include "Ioss_GetLongOpt.h" +#include "Ioss_Utils.h" #include "fmt/ostream.h" #include "modify_interface.h" + #include // for nullptr #include // for exit, EXIT_SUCCESS, getenv #include // for operator<<, basic_ostream, etc #include // for char_traits, string -namespace { - std::string get_type_from_file(const std::string &filename) - { - Ioss::FileInfo file(filename); - auto extension = file.extension(); - if (extension == "e" || extension == "g" || extension == "gen" || extension == "exo") { - return "exodus"; - } - else if (extension == "cgns") { - return "cgns"; - } - else { - // "exodus" is default... - return "exodus"; - } - } -} // namespace - Modify::Interface::Interface() { enroll_options(); } Modify::Interface::~Interface() = default; @@ -151,7 +134,7 @@ bool Modify::Interface::parse_options(int argc, char **argv) } if (filetype_ == "unknown") { - filetype_ = get_type_from_file(filename_); + filetype_ = Ioss::Utils::get_type_from_file(filename_); } return true; diff --git a/packages/seacas/libraries/ioss/src/main/shell_interface.C b/packages/seacas/libraries/ioss/src/main/shell_interface.C index 1d2212dc911c..4ea3bb8213b5 100644 --- a/packages/seacas/libraries/ioss/src/main/shell_interface.C +++ b/packages/seacas/libraries/ioss/src/main/shell_interface.C @@ -6,7 +6,6 @@ * See packages/seacas/LICENSE for details */ #include "Ioss_CodeTypes.h" -#include "Ioss_FileInfo.h" #include "Ioss_GetLongOpt.h" // for GetLongOption, etc #include "Ioss_Sort.h" #include "Ioss_Utils.h" // for Utils @@ -22,24 +21,6 @@ #include // for string, char_traits #include // for vector -namespace { - std::string get_type_from_file(const std::string &filename) - { - Ioss::FileInfo file(filename); - auto extension = file.extension(); - if (extension == "e" || extension == "g" || extension == "gen" || extension == "exo") { - return "exodus"; - } - else if (extension == "cgns") { - return "cgns"; - } - else { - // "exodus" is default... - return "exodus"; - } - } -} // namespace - IOShell::Interface::Interface(const std::string &app_version) : version(app_version) { enroll_options(); @@ -665,10 +646,10 @@ bool IOShell::Interface::parse_options(int argc, char **argv, int my_processor) // If inFileType and/or outFileType not specified, see if can infer from file suffix type... if (inFiletype == "unknown") { - inFiletype = get_type_from_file(inputFile[0]); + inFiletype = Ioss::Utils::get_type_from_file(inputFile[0]); } if (outFiletype == "unknown") { - outFiletype = get_type_from_file(outputFile); + outFiletype = Ioss::Utils::get_type_from_file(outputFile); } return true; } diff --git a/packages/seacas/libraries/ioss/src/main/skinner_interface.C b/packages/seacas/libraries/ioss/src/main/skinner_interface.C index 2a57114926e2..b1265d517349 100644 --- a/packages/seacas/libraries/ioss/src/main/skinner_interface.C +++ b/packages/seacas/libraries/ioss/src/main/skinner_interface.C @@ -1,11 +1,10 @@ /* - * Copyright(C) 1999-2020 National Technology & Engineering Solutions + * Copyright(C) 1999-2021 National Technology & Engineering Solutions * of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with * NTESS, the U.S. Government retains certain rights in this software. * * See packages/seacas/LICENSE for details */ -#include "Ioss_FileInfo.h" #include "Ioss_GetLongOpt.h" // for GetLongOption, etc #include "Ioss_Utils.h" #include "skinner_interface.h" @@ -15,24 +14,6 @@ #include // for operator<<, basic_ostream, etc #include // for char_traits, string -namespace { - std::string get_type_from_file(const std::string &filename) - { - Ioss::FileInfo file(filename); - auto extension = file.extension(); - if (extension == "e" || extension == "g" || extension == "gen" || extension == "exo") { - return "exodus"; - } - else if (extension == "cgns") { - return "cgns"; - } - else { - // "exodus" is default... - return "exodus"; - } - } -} // namespace - Skinner::Interface::Interface() { enroll_options(); } Skinner::Interface::~Interface() = default; @@ -318,10 +299,10 @@ bool Skinner::Interface::parse_options(int argc, char **argv) // If inFileType and/or outFileType not specified, see if can infer from file suffix type... if (inFiletype_ == "unknown") { - inFiletype_ = get_type_from_file(inputFile_); + inFiletype_ = Ioss::Utils::get_type_from_file(inputFile_); } if (!noOutput_ && outFiletype_ == "unknown") { - outFiletype_ = get_type_from_file(outputFile_); + outFiletype_ = Ioss::Utils::get_type_from_file(outputFile_); } return true; } diff --git a/packages/seacas/libraries/ioss/src/main/volume.C b/packages/seacas/libraries/ioss/src/main/volume.C index 2d74cfd7a4ab..15c917370950 100644 --- a/packages/seacas/libraries/ioss/src/main/volume.C +++ b/packages/seacas/libraries/ioss/src/main/volume.C @@ -1,4 +1,4 @@ -// Copyright(C) 1999-2020 National Technology & Engineering Solutions +// Copyright(C) 1999-2021 National Technology & Engineering Solutions // of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with // NTESS, the U.S. Government retains certain rights in this software. // @@ -193,7 +193,7 @@ void hex_volume_internal(Ioss::ElementBlock *block, const std::vector &c "{:5.3f} micro-sec.\n", block->name(), *std::min_element(volume.begin(), volume.end()), *std::max_element(volume.begin(), volume.end()), nelem, - 1000000 * double(t2 - t1) / nelem); + 1'000'000 * double(t2 - t1) / nelem); } } diff --git a/packages/seacas/libraries/ioss/src/utest/Utst_structured_decomp.h b/packages/seacas/libraries/ioss/src/utest/Utst_structured_decomp.h index 7358df996f8d..c0492e9a5388 100644 --- a/packages/seacas/libraries/ioss/src/utest/Utst_structured_decomp.h +++ b/packages/seacas/libraries/ioss/src/utest/Utst_structured_decomp.h @@ -5,6 +5,9 @@ * * See packages/seacas/LICENSE for details */ +#ifndef Utst_structured_decomp_h +#define Utst_structured_decomp_h + #include #include @@ -12,3 +15,5 @@ void cleanup(std::vector &zones); void check_split_assign(std::vector &zones, double load_balance_tolerance, size_t proc_count, double min_toler = 0.9, double max_toler = 1.0); + +#endif diff --git a/packages/seacas/libraries/ioss/src/visualization/utils/Iovs_Utils.C b/packages/seacas/libraries/ioss/src/visualization/utils/Iovs_Utils.C index 99372a6ea27f..b3b38b854e2c 100644 --- a/packages/seacas/libraries/ioss/src/visualization/utils/Iovs_Utils.C +++ b/packages/seacas/libraries/ioss/src/visualization/utils/Iovs_Utils.C @@ -18,6 +18,11 @@ #include #include +#ifdef _WIN32 +#include +#endif + + namespace Iovs { std::string persistentLdLibraryPathEnvForCatalyst = ""; @@ -332,7 +337,11 @@ namespace Iovs { else { persistentLdLibraryPathEnvForCatalyst = paraviewPythonZipFilePath + ":" + existingPythonpath; } +#ifdef _WIN32 + SetEnvironmentVariableA("PYTHONPATH", persistentLdLibraryPathEnvForCatalyst.c_str()); +#else setenv("PYTHONPATH", persistentLdLibraryPathEnvForCatalyst.c_str(), 1); +#endif } std::string Utils::getCatalystPythonDriverPath() @@ -373,7 +382,11 @@ namespace Iovs { IOSS_ERROR(errmsg); } - char * cbuf = realpath(sierraInsDir.c_str(), nullptr); +#ifdef _WIN32 + char *cbuf = _fullpath(nullptr, sierraInsDir.c_str(), _MAX_PATH); +#else + char *cbuf = realpath(sierraInsDir.c_str(), nullptr); +#endif std::string sierraInsPath = cbuf; free(cbuf); diff --git a/packages/seacas/libraries/suplib_c/add_to_log.h b/packages/seacas/libraries/suplib_c/add_to_log.h index bfa6520b7d58..cd66740ab4cd 100644 --- a/packages/seacas/libraries/suplib_c/add_to_log.h +++ b/packages/seacas/libraries/suplib_c/add_to_log.h @@ -5,6 +5,9 @@ * * See packages/seacas/LICENSE for details */ +#ifndef ADD_TO_LOG_H +#define ADD_TO_LOG_H + #ifdef __cplusplus extern "C" { #endif @@ -14,3 +17,5 @@ extern void add_to_log(const char *my_name, double elapsed); #ifdef __cplusplus } /* close brackets on extern "C" declaration */ #endif + +#endif diff --git a/packages/seacas/libraries/suplib_cpp/to_string.h b/packages/seacas/libraries/suplib_cpp/to_string.h index 1ac34d99b6f8..9ab96017e690 100644 --- a/packages/seacas/libraries/suplib_cpp/to_string.h +++ b/packages/seacas/libraries/suplib_cpp/to_string.h @@ -3,5 +3,10 @@ // NTESS, the U.S. Government retains certain rights in this software. // // See packages/seacas/LICENSE for details +#ifndef TO_STRING_H +#define TO_STRING_H + #include std::string to_string(int t) { return std::to_string(t); } + +#endif diff --git a/packages/seacas/libraries/svdi/cgi/cdrcom.h b/packages/seacas/libraries/svdi/cgi/cdrcom.h index 3699665a7d6a..44cccccbb6ec 100644 --- a/packages/seacas/libraries/svdi/cgi/cdrcom.h +++ b/packages/seacas/libraries/svdi/cgi/cdrcom.h @@ -7,8 +7,9 @@ */ /* cdrcom.h - external structure is used to hook up with fortran * common block /cdrcom/ - * 9 Sep, 1989 - date last modified */ +#ifndef CDRCOM_H +#define CDRCOM_H extern struct cdr { @@ -23,4 +24,4 @@ extern struct cdr int KCOMTP; } cdrcom; -/* end cdrcom.h */ +#endif diff --git a/packages/seacas/libraries/svdi/cgi/cgidef.h b/packages/seacas/libraries/svdi/cgi/cgidef.h index 6f94a77d3d44..d10ef2643e02 100644 --- a/packages/seacas/libraries/svdi/cgi/cgidef.h +++ b/packages/seacas/libraries/svdi/cgi/cgidef.h @@ -6,10 +6,11 @@ * See packages/seacas/LICENSE for details */ /* cgidef.h CGI enumerated type definitions for C programs - * 8 Sep 1989, last date modified - * Pat McGee, jpm@lanl.gov */ +#ifndef CGIDEF_H +#define CGIDEF_H + /* escape enumerations */ #define XEMFNM -28372 /* metafile name */ #define XEAGMD -23671 /* alpha/graphics mode */ @@ -195,4 +196,4 @@ #define CVALL 1 #define CVSOME 2 -/* end cgidef.h */ +#endif diff --git a/packages/seacas/libraries/svdi/cgi/devid.h b/packages/seacas/libraries/svdi/cgi/devid.h index 0dc18784f791..570ca54662ec 100644 --- a/packages/seacas/libraries/svdi/cgi/devid.h +++ b/packages/seacas/libraries/svdi/cgi/devid.h @@ -7,8 +7,10 @@ */ /* devid.h - these functions are used to map SVDI device code numbers * to device code character strings and vice versa - * Debbie Campbell */ +#ifndef DEVID_H +#define DEVID_H + struct device_ids { char *devid_char; @@ -54,4 +56,5 @@ static char *get_devid_char(float number) return (0); } #endif -/* end devid.h */ + +#endif diff --git a/packages/seacas/libraries/svdi/cgi/ifdefx.h b/packages/seacas/libraries/svdi/cgi/ifdefx.h index 3be958c80ef5..46b5d7c0ab5e 100644 --- a/packages/seacas/libraries/svdi/cgi/ifdefx.h +++ b/packages/seacas/libraries/svdi/cgi/ifdefx.h @@ -20,6 +20,9 @@ * This include file is used by MDCGI.C and all CGISxxx.C files. */ +#ifndef IFDEFX_H +#define IFDEFX_H + #if defined(ADDC_) #endif #if !defined(CRA) && !defined(ADDC_) && !defined(COUGAR) @@ -79,4 +82,4 @@ #define cgifsq_ CGIFSQ #endif -/* end ifdefx.h */ +#endif diff --git a/packages/seacas/libraries/svdi/cgi/mdcgi.h b/packages/seacas/libraries/svdi/cgi/mdcgi.h index c7d1e5c370fc..57126deabdf2 100644 --- a/packages/seacas/libraries/svdi/cgi/mdcgi.h +++ b/packages/seacas/libraries/svdi/cgi/mdcgi.h @@ -6,6 +6,11 @@ * See packages/seacas/LICENSE for details */ +#ifndef MDCGI_H +#define MDCGI_H + #include "cgi.h" // for device_struct, MAX_DEVICES, etc void xcoon_(anything **surface_id); /* which surface to turn output on for*/ void xcact_(void (*device_fn)(), anything **p_surface_id); + +#endif diff --git a/packages/seacas/libraries/svdi/cgi/vdicgi.h b/packages/seacas/libraries/svdi/cgi/vdicgi.h index e61b69c1137e..162feb9ceeb3 100644 --- a/packages/seacas/libraries/svdi/cgi/vdicgi.h +++ b/packages/seacas/libraries/svdi/cgi/vdicgi.h @@ -5,6 +5,10 @@ * * See packages/seacas/LICENSE for details */ + +#ifndef VDICGI_H +#define VDICGI_H + void vdicgi_errh(char errmsg[]) void vdinit_ (float *aspect, int *justif) void vdiqdc_ (int *index, float *value) @@ -36,3 +40,5 @@ void vdakgl_ (int *charac, float *x, float *y) void vdstla_ (float *x, float *y) void vdstos_ (float attr_array[]) void vdfram_(int itype) + +#endif diff --git a/packages/seacas/scripts/tests/exomerge_unit_test.e b/packages/seacas/scripts/tests/exomerge_unit_test.e new file mode 100644 index 000000000000..d40e8ffb9fc4 Binary files /dev/null and b/packages/seacas/scripts/tests/exomerge_unit_test.e differ diff --git a/packages/seacas/scripts/tests/exomerge_unit_test.py b/packages/seacas/scripts/tests/exomerge_unit_test.py new file mode 100644 index 000000000000..7f77e3f781ba --- /dev/null +++ b/packages/seacas/scripts/tests/exomerge_unit_test.py @@ -0,0 +1,1854 @@ +""" +This file performs unit tests of functions within Exomerge. + +Copyright 2018, 2021 National Technology and Engineering Solutions of Sandia. Under +the terms of Contract DE-NA-0003525, there is a non-exclusive license for use +of this work by or on behalf of the U.S. Government. Export of this program +may require a license from the United States Government. + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + +Author: Tim Kostka (tdkostk@sandia.gov) +Created: May 3, 2012 + +This module runs unit tests in a randomized fashion. To run: + +$ python exomerge_unit_test.py 1000 + +Although the tests performed and randomly generated, since the random number is +seeded with a static value, the *same* sequence of randomly generated tests is +run each time. Processor speed can dictate how many tests are run, so setting +min_tests and max_tests to the same value or calling this script with an +argument can be used to prevent this. + +""" + +# standard libraries +import random +import inspect +import time +import copy +import os +import sys +import re +import math + +# import the exomerge module +import exomerge + + +def compares_equal_with_nan(one, two): + """ + Return True if the two objects are equal, assuming NaN == NaN. + + Objects can include lists, dictionaries, floats, integers, strings, and/or + floats. They can be nested. + + """ + if type(one) != type(two): + return False + if type(one) is dict: + if sorted(one.keys()) != sorted(two.keys()): + return False + return all(compares_equal_with_nan(one[x], two[x]) + for x in list(one.keys())) + elif type(one) is list: + return (len(one) == len(two) and + all(compares_equal_with_nan(x, y) + for x, y in zip(one, two))) + else: + # string, integer, or float + if type(one) is float: + return one == two or (math.isnan(one) and math.isnan(two)) + else: + return one == two + + +class DummyFile(object): + """Dummy class used to suppress output.""" + + def write(self, x): + """Ignore the write command.""" + pass + + +class OutputSuppression: + """ + This class is used to suppress output to stdout. + + + Example: + >>> std.stdout('Hello world!\n') + Hello world! + >>> print('Hello world!') + Hello world! + >>> with OutputSuppression(): + >>> std.stdout('This will not appear\n') + >>> print('Hello world!') + + """ + + def __enter__(self): + """Initialzation routine.""" + self.old_stdout = sys.stdout + sys.stdout = DummyFile() + + def __exit__(self, type_, value, tracebackself): + """Destructor routine.""" + sys.stdout = self.old_stdout + + +class ExomergeUnitTester: + """ + A class to perform unit tests of the exomerge module. + + """ + + # identifiers used to create names + RANDOM_IDENTIFIERS = ('abcdefghijklmnopqrstuvwxyz' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + '0123456789') + + def __init__(self): + # store the exodus model + self.model = exomerge.ExodusModel() + # run tests for up to this amount of time in seconds + self.time_limit = 60 + # run at least this many tests + self.min_tests = 3000 + # run up to this many tests + self.max_tests = 3000 + # only this many IO tests will be run + self.remaining_io_tests = 40 + # set the maximum number of each object to prevent self.model from + # growing too large + self.maximum_objects = 10 + + def _random_element(self, the_list): + """ + Return a random element from the list or None if none exist. + + """ + if not the_list: + return None + return the_list[random.randint(0, len(the_list) - 1)] + + def _random_boolean(self): + """ + Return one of True or False at random. + + """ + return [True, False][random.randint(0, 1)] + + def _random_subset(self, the_list, count=None): + """ + Return a random subset of elements from the list. + + """ + if count is None: + if len(the_list) == 0: + count = 0 + else: + count = random.randint(1, len(the_list)) + return random.sample(the_list, count) + + def _random_scalar(self): + """ + Return a random scalar. + + """ + return random.uniform(0.5, 2) + + def _random_vector(self): + """ + Return a random vector. + + """ + vector = [self._random_scalar() for _ in range(3)] + return vector + + def _random_identifier(self): + """ + Return a random name. + + """ + return ''.join([self._random_element(self.RANDOM_IDENTIFIERS) + for _ in range(6)]) + + def _random_timestep(self): + """ + Return a random timestep. + + """ + if not self.model.timesteps: + return None + return random.choice(self.model.timesteps) + + def _random_field_name(self): + """ + Return a random field name. + + """ + return 'field_' + self._random_identifier() + + def _new_node_field_name(self): + """ + Return a new node field name. + + """ + name = self._random_field_name() + while name in self.model.get_node_field_names(): + name = self._random_field_name() + return name + + def _new_global_variable_name(self): + """ + Return a new global variable name. + + """ + name = self._random_field_name() + while name in self.model.get_global_variable_names(): + name = self._random_field_name() + return name + + def _new_element_field_name(self): + """ + Return a new element field name. + + """ + name = self._random_field_name() + while name in self.model.get_element_field_names(): + name = self._random_field_name() + return name + + def _new_node_set_field_name(self): + """ + Return a new node set field name. + + """ + name = self._random_field_name() + while name in self.model.get_node_set_field_names(): + name = self._random_field_name() + return name + + def _new_side_set_field_name(self): + """ + Return a new side set field name. + + """ + name = self._random_field_name() + while name in self.model.get_side_set_field_names(): + name = self._random_field_name() + return name + + def _new_timestep(self): + """ + Return a new timestep. + + """ + value = random.random() + while value in self.model.timesteps: + value = random.random() + return value + + def _new_id(self): + """ + Return a new id. + + """ + return random.randint(0, 9999) + + def _new_element_block_id(self): + """ + Return a new element block id. + + """ + value = self._new_id() + while value in self.model.get_element_block_ids(): + value = self._new_id() + return value + + def _new_node_set_id(self): + """ + Return a new node set id. + + """ + value = self._new_id() + while value in self.model.get_node_set_ids(): + value = self._new_id() + return value + + def _new_side_set_id(self): + """ + Return a new side set id. + + """ + value = self._new_id() + while value in self.model.get_side_set_ids(): + value = self._new_id() + return value + + def _random_element_field_name(self): + """ + Return one element field name or None if none exist in the form + (id_, name). + + """ + ids = self.model.get_element_block_ids() + random.shuffle(ids) + for id_ in ids: + fields = self.model._get_element_block_fields(id_) + names = list(fields.keys()) + random.shuffle(names) + if names: + return (id_, names[0]) + return None + + def _random_node_field_name(self): + """ + Return one node field name or None. + + """ + return self._random_element(self.model.get_node_field_names()) + + def _random_node_set_field_name(self): + """ + Return one node set field name or None in the form (id_, name). + + """ + ids = self.model.get_node_set_ids() + random.shuffle(ids) + for id_ in ids: + fields = self.model._get_node_set_fields(id_) + names = list(fields.keys()) + random.shuffle(names) + if names: + return (id_, names[0]) + return None + + def _random_side_set_field_name(self): + """ + Return one side set field name or None in the form (id_, name). + + """ + ids = self.model.get_side_set_ids() + random.shuffle(ids) + for id_ in ids: + fields = self.model._get_side_set_fields(id_) + names = list(fields.keys()) + random.shuffle(names) + if names: + return (id_, names[0]) + return None + + def _random_global_variable_name(self): + """ + Return one global variable name or None. + + """ + return self._random_element(self.model.get_global_variable_names()) + + def _random_element_block_id(self): + """Return a random element block id or name, or None if none exist.""" + ids = self.model.get_element_block_ids() + ids.extend(self.model.get_all_element_block_names()) + if not ids: + return None + return self._random_element(ids) + + def _random_element_block_ids(self): + """Return a random subset of element block ids or names.""" + ids = self._random_subset(self.model.get_element_block_ids()) + for i, id_ in enumerate(ids): + if random.randint(0, 1) == 0: + continue + name = self.model.get_element_block_name(id_) + if not name: + continue + ids[i] = name + return ids + + def _random_side_set_id(self): + """Return a random side set id or name, or None if none exist.""" + ids = self.model.get_side_set_ids() + ids.extend(self.model.get_all_side_set_names()) + return self._random_element(ids) + + def _random_side_set_ids(self): + """Return a random subset of side set ids or name.""" + ids = self._random_subset(self.model.get_side_set_ids()) + for i, id_ in enumerate(ids): + if random.randint(0, 1) == 0: + continue + name = self.model.get_side_set_name(id_) + if not name: + continue + ids[i] = name + return ids + + def _random_node_set_id(self): + """Return a random side set id or name, or None if none exist.""" + ids = self.model.get_node_set_ids() + ids.extend(self.model.get_all_node_set_names()) + return self._random_element(ids) + + def _random_node_set_ids(self): + """Return a random subset of node set ids or name.""" + ids = self._random_subset(self.model.get_node_set_ids()) + for i, id_ in enumerate(ids): + if random.randint(0, 1) == 0: + continue + name = self.model.get_node_set_name(id_) + if not name: + continue + ids[i] = name + return ids + + def _truncate_element_blocks(self, number=None): + """ + Delete element blocks until only the given number exist. + + """ + if number is None: + number = self.maximum_objects + objects = self.model.get_element_block_ids() + count = len(objects) + if count > number: + self.model.delete_element_block( + self._random_subset(objects, count - number)) + + def _truncate_timesteps(self, number=None): + """ + Delete timesteps until only the given number exist. + + """ + if number is None: + number = self.maximum_objects + objects = self.model.get_timesteps() + count = len(objects) + if count > number: + self.model.delete_timestep( + self._random_subset(objects, count - number)) + + def _truncate_node_sets(self, number=None): + """ + Delete node sets until only the given number exist. + + """ + if number is None: + number = self.maximum_objects + objects = self.model.get_node_set_ids() + count = len(objects) + if count > number: + self.model.delete_node_set( + self._random_subset(objects, count - number)) + + def _truncate_side_sets(self, number=None): + """ + Delete side sets until only the given number exist. + + """ + if number is None: + number = self.maximum_objects + objects = self.model.get_side_set_ids() + count = len(objects) + if count > number: + self.model.delete_side_set( + self._random_subset(objects, count - number)) + + def _truncate_node_fields(self, number=None): + """ + Delete random node fields until only the given number exist. + + """ + if number is None: + number = self.maximum_objects + objects = self.model.get_node_field_names() + count = len(objects) + if count > number: + self.model.delete_node_field( + self._random_subset(objects, count - number)) + + def _truncate_global_variables(self, number=None): + """ + Delete random global variables until only the given number exist. + + """ + if number is None: + number = self.maximum_objects + objects = self.model.get_global_variable_names() + count = len(objects) + if count > number: + self.model.delete_global_variable( + self._random_subset(objects, count - number)) + + def _truncate_element_fields(self, number=None): + """ + Delete random element fields until only the given number exist. + + """ + if number is None: + number = self.maximum_objects + while len(self.model.get_element_field_names()) > number: + (id_, name) = self._random_element_field_name() + self.model.delete_element_field(name, id_) + + def _truncate_node_set_fields(self, number=None): + """ + Delete random node set fields until only the given number exist. + + """ + if number is None: + number = self.maximum_objects + while len(self.model.get_node_set_field_names()) > number: + (id_, name) = self._random_node_set_field_name() + self.model.delete_node_set_field(name, id_) + + def _truncate_side_set_fields(self, number=None): + """ + Delete random side set fields until only the given number exist. + + """ + if number is None: + number = self.maximum_objects + while len(self.model.get_side_set_field_names()) > number: + (id_, name) = self._random_side_set_field_name() + self.model.delete_side_set_field(name, id_) + + def _create_hex8_element_block(self, + origin=None): + """ + Create a 2-element hex8 element block of dimension 2x1x1 with the + given minimum coordinates and return the element block id. + + """ + new_nodes = [[0.0, 0.0, 0.0], + [1.0, 0.0, 0.0], + [1.0, 1.0, 0.0], + [0.0, 1.0, 0.0], + [0.0, 0.0, 1.0], + [1.0, 0.0, 1.0], + [1.0, 1.0, 1.0], + [0.0, 1.0, 1.0], + [2.0, 0.0, 0.0], + [2.0, 1.0, 0.0], + [2.0, 0.0, 1.0], + [2.0, 1.0, 1.0]] + if origin is None: + origin = [0, 0, 0] + new_nodes = [[x + y for x, y in zip(node, origin)] + for node in new_nodes] + connectivity = list(range(8)) + connectivity.extend([1, 8, 9, 2, 5, 10, 11, 6]) + connectivity = [x + len(self.model.nodes) for x in connectivity] + self.model.create_nodes(new_nodes) + info = ['hex8', 2, 8, 0] + element_block_id = self._new_element_block_id() + self.model.create_element_block(element_block_id, + info, + connectivity) + return element_block_id + + def _topology_test(self): + """ + Test the topology defitions to ensure they are consistent. + + FACE_MAPPING, INVERTED_CONNECTIVITY, DIMENSION + + """ + # see if keys are defined for all places + self.model._assert( + (set(self.model.FACE_MAPPING.keys()) == + set(self.model.INVERTED_CONNECTIVITY.keys()))) + self.model._assert( + (set(self.model.FACE_MAPPING.keys()) == + set(self.model.DIMENSION.keys()))) + self.model._assert( + (set(self.model.FACE_MAPPING.keys()) == + set(self.model.NODES_PER_ELEMENT.keys()))) + # faces should be 1 dimension less than their element + for element_type, face_list in list(self.model.FACE_MAPPING.items()): + element_dimension = self.model._get_dimension(element_type) + for face_type, _ in face_list: + self.model._assert( + self.model._get_dimension(face_type) + 1 == + element_dimension) + # all 2D elements should be able to be triangulated + for element_type in self.model.STANDARD_ELEMENT_TYPES: + if self.model.DIMENSION[element_type] == 2: + self.model._assert( + element_type in self.model.TRIANGULATED_FACES) + + # The following functions are unit tests of public functions within + # exomerge. For each public_function, a unit test of the name + # _test_public_function should exist here. If there is not a one to + # one mapping between the two, warning messages will appear when running + # this module. + # + # Tests sould return None if successful (no return statement needed) + # Tests should return False if the test was unable to be run. + # Tests should raise an exception or exit(1) if unsuccessful. + + def _test_calculate_element_volumes(self): + ids = self.model._get_standard_element_block_ids() + if not ids: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + self.model.calculate_element_volumes( + self._new_element_field_name(), + ids) + + def _test_get_element_block_centroid(self): + ids = self._random_element_block_ids() + if not ids: + return False + self.model.get_element_block_centroid(ids) + + def _test_get_element_block_volume(self): + ids = self._random_element_block_ids() + if not ids: + return False + self.model.get_element_block_volume(ids) + + def _test_convert_element_blocks(self): + id_ = self._random_element( + self.model._get_standard_element_block_ids()) + if not id_: + return False + element_type = self.model._get_element_type(id_) + if element_type not in self.model.ELEMENT_CONVERSIONS: + return False + scheme = self.model.ELEMENT_CONVERSIONS[element_type] + if not scheme: + return False + new_element_type = self._random_element(list(scheme.keys())) + self.model.convert_element_blocks(id_, new_element_type) + + def _test_make_elements_linear(self): + ids = [] + for id_ in self.model._get_standard_element_block_ids(): + element_type = self.model._get_element_type(id_) + if self.model.ELEMENT_ORDER[element_type] == 1: + continue + if element_type not in self.model.ELEMENT_CONVERSIONS: + continue + scheme = self.model.ELEMENT_CONVERSIONS[element_type] + if 1 not in [self.model.ELEMENT_ORDER[x] + for x in list(scheme.keys())]: + continue + ids.append(id_) + ids = self._random_subset(ids) + if not ids: + return False + self.model.make_elements_linear(ids) + + def _test_make_elements_quadratic(self): + ids = [] + for id_ in self.model._get_standard_element_block_ids(): + element_type = self.model._get_element_type(id_) + if self.model.ELEMENT_ORDER[element_type] == 2: + continue + if element_type not in self.model.ELEMENT_CONVERSIONS: + continue + scheme = self.model.ELEMENT_CONVERSIONS[element_type] + if 2 not in [self.model.ELEMENT_ORDER[x] + for x in list(scheme.keys())]: + continue + ids.append(id_) + ids = self._random_subset(ids) + if not ids: + return False + self.model.make_elements_quadratic(ids) + + def _test_convert_hex8_block_to_tet4_block(self): + ids = [x + for x in self.model.get_element_block_ids() + if self.model._get_element_type(x) == 'hex8'] + if not ids: + return False + self.model.convert_hex8_block_to_tet4_block( + self._random_element(ids)) + + def _test_duplicate_element_block(self): + old_id = self._random_element_block_id() + if old_id is None: + return False + new_id = self._new_element_block_id() + self.model.duplicate_element_block(old_id, new_id) + + def _test_to_lowercase(self): + self.model.to_lowercase() + + def _test_reflect_element_blocks(self): + id_ = self._create_hex8_element_block() + self.model.reflect_element_blocks(id_, + [0, 0, 0], + [1, -1, 0]) + + def _test_combine_element_blocks(self): + id_one = self._create_hex8_element_block() + id_two = self._create_hex8_element_block([2, 0, 0]) + self.model.combine_element_blocks([id_one, id_two]) + + def _test_create_side_set_from_expression(self): + new_nodes = [[0.0, 0.0, 0.0], + [1.0, 0.0, 0.0], + [1.0, 1.0, 0.0], + [0.0, 1.0, 0.0], + [0.0, 0.0, 1.0], + [1.0, 0.0, 1.0], + [1.0, 1.0, 1.0], + [0.0, 1.0, 1.0]] + connectivity = list(range(8)) + connectivity = [x + len(self.model.nodes) for x in connectivity] + self.model.create_nodes(new_nodes) + info = ['hex8', 1, 8, 0] + element_block_id = self._new_element_block_id() + self.model.create_element_block(element_block_id, + info, + connectivity) + self.model.create_side_set_from_expression( + self._new_side_set_id(), + 'Z = 0 || Z == 1 || X == 1', + element_block_ids=element_block_id, + timesteps='none') + + def _test_convert_side_set_to_cohesive_zone(self): + new_nodes = [[0.0, 0.0, 0.0], + [1.0, 0.0, 0.0], + [1.0, 1.0, 0.0], + [0.0, 1.0, 0.0], + [0.0, 0.0, 1.0], + [1.0, 0.0, 1.0], + [1.0, 1.0, 1.0], + [0.0, 1.0, 1.0], + [2.0, 0.0, 0.0], + [2.0, 1.0, 0.0], + [2.0, 0.0, 1.0], + [2.0, 1.0, 1.0]] + connectivity = list(range(8)) + connectivity.extend([1, 8, 9, 2, 5, 10, 11, 6]) + connectivity = [x + len(self.model.nodes) for x in connectivity] + self.model.create_nodes(new_nodes) + info = ['hex8', 2, 8, 0] + element_block_id = self._new_element_block_id() + self.model.create_element_block(element_block_id, + info, + connectivity) + side_set_id = self._new_side_set_id() + self.model.create_side_set(side_set_id, + [(element_block_id, 1, 3)]) + self.model.convert_side_set_to_cohesive_zone( + side_set_id, + self._new_element_block_id()) + + def _test_calculate_global_variable(self): + if not self.model.timesteps: + self.model.create_timestep(0.0) + variable_names = set(['time']) + variable_names.update(self.model.get_global_variable_names()) + expression = "%s = %s" % (self._new_global_variable_name(), + ' + '.join(variable_names)) + self.model.calculate_global_variable(expression) + + def _test_calculate_node_field(self): + if not self.model.timesteps: + self.model.create_timestep(0.0) + variable_names = set(['time']) + variable_names.update(self.model.get_global_variable_names()) + variable_names.update(self.model.get_node_field_names()) + expression = "%s = %s" % (self._new_node_field_name(), + ' + '.join(variable_names)) + self.model.calculate_node_field(expression) + + def _test_calculate_element_field(self): + if not self.model.timesteps: + self.model.create_timestep(0.0) + info = self._random_element_field_name() + if info is None: + return False + (id_, name) = info + variable_names = set(['time']) + variable_names.update(self.model.get_global_variable_names()) + variable_names.update(self.model.get_element_field_names(id_)) + expression = "%s = %s" % (self._new_element_field_name(), + ' + '.join(variable_names)) + self.model.calculate_element_field(expression, id_) + + def _test_calculate_element_field_maximum(self): + info = self._random_element_field_name() + if info is None or len(info[1]) + 13 > 32: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + (id_, name) = info + block_ids = [x + for x in self.model.get_element_block_ids() + if self.model.element_field_exists(name, x)] + block_ids = self._random_subset(block_ids) + if self.model.get_element_count(block_ids) == 0: + return False + self.model.delete_global_variables(name + '_*') + self.model.calculate_element_field_maximum( + name, + element_block_ids=block_ids, + calculate_location=self._random_boolean(), + calculate_block_id=self._random_boolean()) + + def _test_calculate_element_field_minimum(self): + info = self._random_element_field_name() + if info is None or len(info[1]) + 13 > 32: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + (id_, name) = info + block_ids = [x + for x in self.model.get_element_block_ids() + if self.model.element_field_exists(name, x)] + block_ids = self._random_subset(block_ids) + if self.model.get_element_count(block_ids) == 0: + return False + self.model.delete_global_variables(name + '_*') + self.model.calculate_element_field_minimum( + name, + element_block_ids=block_ids, + calculate_location=self._random_boolean(), + calculate_block_id=self._random_boolean()) + + def _test_calculate_node_field_minimum(self): + if not self.model.nodes: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + name = self._random_node_field_name() + if name is None or len(name) + 6 > 32: + return False + self.model.delete_global_variables(name + '_*') + if self._random_boolean(): + self.model.calculate_node_field_minimum( + name, + calculate_location=self._random_boolean()) + else: + block_ids = self._random_element_block_ids() + if not self.model.get_nodes_in_element_block(block_ids): + return False + self.model.calculate_node_field_minimum( + name, + element_block_ids=block_ids, + calculate_location=self._random_boolean()) + + def _test_calculate_node_field_maximum(self): + if not self.model.nodes: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + name = self._random_node_field_name() + if name is None or len(name) + 6 > 32: + return False + self.model.delete_global_variables(name + '_*') + self.model.calculate_node_field_maximum( + name, + calculate_location=self._random_boolean()) + + def _test_output_global_variables(self): + filename = 'temp.csv' if self._random_boolean() else None + if self.remaining_io_tests <= 0: + filename = None + if filename is not None: + self.remaining_io_tests -= 1 + with OutputSuppression(): + self.model.output_global_variables(filename) + if filename: + os.remove(filename) + + def _test_calculate_node_set_field(self): + info = self._random_node_set_field_name() + if info is None: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + (id_, name) = info + variable_names = set(['time']) + variable_names.update(self.model.get_global_variable_names()) + variable_names.update(self.model.get_node_field_names()) + variable_names.update(self.model.get_node_set_field_names(id_)) + expression = "%s = %s" % (self._new_node_set_field_name(), + ' + '.join(variable_names)) + self.model.calculate_node_set_field(expression, id_) + + def _test_calculate_side_set_field(self): + info = self._random_side_set_field_name() + if info is None: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + (id_, name) = info + variable_names = set(['time']) + variable_names.update(self.model.get_global_variable_names()) + variable_names.update(self.model.get_side_set_field_names(id_)) + expression = "%s = %s" % (self._new_side_set_field_name(), + ' + '.join(variable_names)) + self.model.calculate_side_set_field(expression, id_) + + def _test_merge_nodes(self): + if not self.model.nodes: + return False + self.model._duplicate_nodes( + self._random_subset(range(len(self.model.nodes)), 1), + []) + x = len(self.model.nodes) + self.model.merge_nodes(suppress_warnings=True) + assert len(self.model.nodes) < x + + def _test_unmerge_element_blocks(self): + if len(self.model.element_blocks) < 2: + return False + (id1, id2) = self._random_subset(self.model.get_element_block_ids(), + count=2) + connectivity_1 = self.model.get_connectivity(id1) + connectivity_2 = self.model.get_connectivity(id2) + if not connectivity_1 or not connectivity_2: + return False + connectivity_2[0] = connectivity_1[0] + self.model.unmerge_element_blocks([id1, id2]) + assert not (set(self.model.get_connectivity(id1)) & + set(self.model.get_connectivity(id2))) + + def _test_get_length_scale(self): + self.model.get_length_scale() + + def _test_get_input_deck(self): + self.model.info_records = ['asdf', + 'begin', + ' begin statement', + ' end statement', + 'end sierra', + 'other stuff'] + assert len(self.model.get_input_deck().split('\n')) == 4 + + def _test_create_interpolated_timestep(self): + if len(self.model.timesteps) < 2: + return False + steps = self.model.get_timesteps() + new_time = steps[0] + random.random() * (steps[-1] - steps[0]) + if self.model.timestep_exists(new_time): + return False + self.model.create_interpolated_timestep(new_time) + + def _test_rename_element_block(self): + id_ = self._random_element_block_id() + if id_ is None: + return False + self.model.rename_element_block(id_, self._new_element_block_id()) + + def _test_rename_side_set(self): + id_ = self._random_side_set_id() + if id_ is None: + return False + self.model.rename_side_set(id_, self._new_side_set_id()) + + def _test_rename_node_set(self): + id_ = self._random_node_set_id() + if id_ is None: + return False + self.model.rename_node_set(id_, self._new_node_set_id()) + + def _test_rename_global_variable(self): + name = self._random_global_variable_name() + if name is None: + return False + self.model.rename_global_variable(name, + self._new_global_variable_name()) + + def _test_rename_node_field(self): + name = self._random_node_field_name() + if name is None: + return False + self.model.rename_node_field(name, self._new_node_field_name()) + + def _test_rename_node_set_field(self): + info = self._random_node_set_field_name() + if info is None: + return False + (id_, name) = info + self.model.rename_node_set_field(name, + self._new_node_set_field_name(), + id_) + + def _test_rename_side_set_field(self): + info = self._random_side_set_field_name() + if info is None: + return False + (id_, name) = info + self.model.rename_side_set_field(name, + self._new_side_set_field_name(), + id_) + + def _test_delete_node_set_field(self): + info = self._random_node_set_field_name() + if info is None: + self._test_create_node_set_field() + info = self._random_node_set_field_name() + if info is None: + return False + (id_, name) = info + self.model.delete_node_set_field(name, id_) + + def _test_delete_side_set_field(self): + info = self._random_side_set_field_name() + if info is None: + return False + (id_, name) = info + self.model.delete_side_set_field(name, id_) + + def _test_calculate_element_centroids(self): + if not self.model.element_blocks: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + for id_ in self.model.get_element_block_ids(): + for name in ['centroid_x', 'centroid_y', 'centroid_z']: + if self.model.element_field_exists(name, id_): + self.model.delete_element_field(name, id_) + self.model.calculate_element_centroids() + self._truncate_element_fields() + + def _test_convert_element_field_to_node_field(self): + field = self._random_element_field_name() + if field is None: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + self.model.convert_element_field_to_node_field( + field[1], + self._new_node_field_name()) + self._truncate_node_fields() + + def _test_convert_node_field_to_element_field(self): + field = self._random_node_field_name() + if field is None: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + self.model.convert_node_field_to_element_field( + field, + self._new_element_field_name()) + self._truncate_element_fields() + + def _test_create_averaged_element_field(self): + self._truncate_element_fields() + id_ = self._random_element_block_id() + if id_ is None: + return False + field_names = self.model.get_element_field_names(id_) + if not field_names: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + field = self._random_subset(field_names) + self.model.create_averaged_element_field( + field, + self._new_element_field_name(), + id_) + + def _test_create_displacement_field(self): + if not self.model.timesteps: + self.model.create_timestep(0.0) + self.model.create_displacement_field() + self._truncate_node_fields() + + def _test_create_element_block(self): + for _ in range(random.randint(1, self.maximum_objects)): + new_nodes = [[0.0, 0.0, 0.0], + [1.0, 0.0, 0.0], + [1.0, 1.0, 0.0], + [0.0, 1.0, 0.0], + [0.0, 0.0, 1.0], + [0.0, 0.0, 1.0], + [0.0, 1.0, 1.0], + [0.0, 1.0, 1.0], + [2.0, 0.0, 0.0], + [2.0, 1.0, 0.0], + [2.0, 0.0, 1.0], + [2.0, 1.0, 1.0]] + connectivity = list(range(8)) + connectivity.extend([1, 8, 9, 2, 5, 10, 11, 6]) + connectivity = [x + len(self.model.nodes) for x in connectivity] + self.model.create_nodes(new_nodes) + info = ['hex8', 2, 8, 0] + self.model.create_element_block(self._new_element_block_id(), + info, + connectivity) + self._truncate_element_blocks() + + def _test_create_element_field(self): + if not self.model.timesteps: + self.model.create_timestep(0.0) + for _ in range(random.randint(1, self.maximum_objects)): + ids = self._random_element_block_ids() + if ids: + self.model.create_element_field(self._new_element_field_name(), + ids, + random.random()) + self._truncate_element_fields() + + def _test_create_global_variable(self): + for _ in range(random.randint(1, self.maximum_objects)): + self.model.create_global_variable(self._new_global_variable_name()) + self._truncate_global_variables() + + def _test_create_node_field(self): + if not self.model.timesteps: + self.model.create_timestep(0.0) + for _ in range(random.randint(1, self.maximum_objects)): + self.model.create_node_field(self._new_node_field_name(), + random.random()) + self._truncate_node_fields() + + def _test_add_nodes_to_node_set(self): + self._truncate_node_sets() + if not self.model.nodes or not self.model.node_sets: + return False + id_ = self._random_node_set_id() + current_members = self.model.get_node_set_members(id_) + members = [random.randint(0, len(self.model.nodes) - 1) + for _ in range(20)] + members = sorted(set(members)) + new_members = [] + for member in members: + if member not in current_members: + new_members.append(member) + self.model.add_nodes_to_node_set(id_, new_members) + + def _test_create_node_set(self): + if not self.model.nodes: + return False + for _ in range(random.randint(1, self.maximum_objects)): + members = [random.randint(0, len(self.model.nodes) - 1) + for _ in range(20)] + members = sorted(set(members)) + self.model.create_node_set(self._new_node_set_id(), members) + self._truncate_node_sets() + + def _test_create_node_set_field(self): + for _ in range(random.randint(1, self.maximum_objects)): + id_ = self._random_node_set_id() + if id_ is None: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + self.model.create_node_set_field(self._new_node_set_field_name(), + id_, + random.random()) + self._truncate_node_set_fields() + + def _test_create_node_set_from_side_set(self): + id_ = self._random_side_set_id() + if id_ is not None: + self.model.create_node_set_from_side_set(self._new_node_set_id(), + id_) + self._truncate_node_sets() + + def _test_create_nodes(self): + new_nodes = [] + for _ in range(7): + new_nodes.append([random.random() for _ in range(3)]) + self.model.create_nodes(new_nodes) + + def _test_create_side_set(self): + if not self.model.element_blocks: + return False + for _ in range(random.randint(1, self.maximum_objects)): + members = [] + for _ in range(20): + id_ = self._random_element(self.model.get_element_block_ids()) + element_count = self.model.get_element_count(id_) + if element_count == 0: + continue + element_index = random.randint(0, element_count - 1) + side_index = random.randint(0, 3) + members.append((id_, element_index, side_index)) + members = sorted(set(members)) + self.model.create_side_set(self._new_side_set_id(), members) + self._truncate_side_sets() + + def _test_add_faces_to_side_set(self): + self._truncate_side_sets() + if not self.model.element_blocks: + return False + if not self.model.side_sets: + return False + members = [] + for _ in range(20): + id_ = self._random_element(self.model.get_element_block_ids()) + element_count = self.model.get_element_count(id_) + if element_count == 0: + continue + element_index = random.randint(0, element_count - 1) + side_index = random.randint(0, 3) + members.append((id_, element_index, side_index)) + members = sorted(set(members)) + id_ = self._random_side_set_id() + current_members = self.model.get_side_set_members(id_) + new_members = [] + for member in members: + if member not in current_members: + new_members.append(member) + self.model.add_faces_to_side_set(id_, new_members) + + def _test_create_side_set_field(self): + for _ in range(random.randint(1, self.maximum_objects)): + id_ = self._random_side_set_id() + if id_ is None: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + self.model.create_side_set_field(self._new_side_set_field_name(), + id_, + random.random()) + self._truncate_side_set_fields() + + def _test_create_timestep(self): + for _ in range(random.randint(1, self.maximum_objects)): + self.model.create_timestep(self._new_timestep()) + self._truncate_timesteps() + + def _test_copy_timestep(self): + step = self._random_timestep() + if step is None: + return False + self.model.copy_timestep(step, self._new_timestep()) + self._truncate_timesteps() + + def _test_delete_element_block(self): + ids = self._random_element_block_ids() + if not ids: + return False + self.model.delete_element_block(ids) + + def _test_delete_element_field(self): + names = self._random_subset(self.model.get_element_field_names()) + if not names: + return False + self.model.delete_element_field(names) + + def _test_delete_empty_node_sets(self): + self.model.create_node_set(self._new_node_set_id(), []) + self.model.delete_empty_node_sets() + + def _test_delete_empty_side_sets(self): + self.model.create_side_set(self._new_side_set_id(), []) + self.model.delete_empty_side_sets() + + def _test_delete_global_variable(self): + names = self._random_subset(self.model.get_global_variable_names()) + if not names: + return False + self.model.delete_global_variable(names) + + def _test_delete_node_field(self): + names = self._random_subset(self.model.get_node_field_names()) + if not names: + return False + self.model.delete_node_field(names) + + def _test_delete_node_set(self): + ids = self._random_node_set_ids() + if not ids: + return False + self.model.delete_node_set(ids) + + def _test_delete_side_set(self): + ids = self._random_side_set_ids() + if not ids: + return False + self.model.delete_side_set(ids) + + def _test_delete_timestep(self): + times = self._random_subset(self.model.get_timesteps()) + if not times: + return False + self.model.delete_timestep(times) + + def _test_delete_unused_nodes(self): + self.model.create_nodes([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]]) + node_count = len(self.model.nodes) + self.model.delete_unused_nodes() + assert len(self.model.nodes) <= node_count - 2 + + def _test_displace_element_blocks(self): + ids = self._random_element_block_ids() + if not ids: + return False + if not self.model.timesteps: + return False + self.model.unmerge_element_blocks() + self.model.displace_element_blocks(ids, self._random_vector()) + + def _test_displacement_field_exists(self): + self.model.displacement_field_exists() + + def _test_element_block_exists(self): + id_ = self._random_element_block_id() + if id_ is None: + assert not self.model.element_block_exists(0) + else: + assert self.model.element_block_exists(id_) + + def _test_element_field_exists(self): + id_ = self._random_element_block_id() + if not id_: + return False + name = self._random_element(self.model.get_element_field_names(id_)) + if name is None: + assert not self.model.element_field_exists('temp', id_) + else: + assert self.model.element_field_exists(name, id_) + + def _test_export_model(self): + if self.remaining_io_tests <= 0: + return False + self.remaining_io_tests -= 1 + self.model.export_model('temp.e') + # make sure the exported model is equal + model2 = exomerge.import_model('temp.e') + model2.qa_records = model2.qa_records[:-1] + one = self.model + two = model2 + assert one.nodes == two.nodes + assert one.timesteps == two.timesteps + # There is some odd bug here where characters get added sometimes + # but not often. To avoid this, we don't compare info records. This + # does not appear to be a bug within exomerge.py or exodus.py. It may + # be within ctypes, but more likely is within the exodus library + # itself. + # exported: ['asdf', 'begin', ' begin statement', ...] + # imported: ['asdf\x7f\xf8', 'begin', ' begin statement', ...] + # assert one.info_records == two.info_records + assert one.title == two.title + assert one.qa_records == two.qa_records + assert one.title == two.title + assert compares_equal_with_nan(one.node_fields, + two.node_fields) + assert compares_equal_with_nan(one.global_variables, + two.global_variables) + assert compares_equal_with_nan(one.side_sets, + two.side_sets) + assert compares_equal_with_nan(one.node_sets, + two.node_sets) + # There is a bug/feature within exodus.py where element types are + # renamed to uppercase. To avoid this, we don't compare the info + # field within each block + for id_ in list(one.element_blocks.keys()): + assert compares_equal_with_nan(one.element_blocks[id_][0], + two.element_blocks[id_][0]) + # assert compares_equal_with_nan(one.element_blocks[id_][1], + # two.element_blocks[id_][1]) + assert compares_equal_with_nan(one.element_blocks[id_][2], + two.element_blocks[id_][2]) + assert compares_equal_with_nan(one.element_blocks[id_][3], + two.element_blocks[id_][3]) + os.remove('temp.e') + + def _test_export_stl_file(self): + if self.remaining_io_tests <= 0: + return False + self.remaining_io_tests -= 1 + self.model.export_stl_file('temp.stl') + os.remove('temp.stl') + + def _test_export_wrl_model(self): + if self.remaining_io_tests <= 0: + return False + self.remaining_io_tests -= 1 + if not self.model.timesteps: + self.model.create_timestep(0.0) + if not self.model.element_blocks: + self._create_hex8_element_block() + node_field_name = self._new_node_field_name() + self.model.calculate_node_field(node_field_name + ' = X + Y + Z') + self.model.export_wrl_model('temp.wrl', node_field_name) + os.remove('temp.wrl') + os.remove('temp_wrl.e') + + def _test_export(self): + if self.remaining_io_tests <= 0: + return False + self.remaining_io_tests -= 1 + filename = 'temp.' + self._random_element(['e', 'stl']) + self.model.export(filename) + os.remove(filename) + + def _test_get_element_block_connectivity(self): + id_ = self._random_element_block_id() + if id_ is None: + return False + self.model.get_element_block_connectivity(id_) + + def _test_get_nodes_per_element(self): + id_ = self._random_element_block_id() + if id_ is None: + return False + self.model.get_nodes_per_element(id_) + + def _test_get_element_block_ids(self): + self.model.get_element_block_ids() + + def _test_get_element_count(self): + ids = self._random_element_block_ids() + if ids is None: + return False + self.model.get_element_count(ids) + + def _test_get_element_field_names(self): + ids = self._random_element_block_ids() + if ids is None: + return False + self.model.get_element_field_names() + + def _test_get_element_field_values(self): + field = self._random_element_field_name() + if field is None: + return False + if not self.model.timesteps: + return False + self.model.get_element_field_values(field[1], field[0]) + + def _test_get_global_variable_names(self): + self.model.get_global_variable_names() + + def _test_get_node_field_names(self): + self.model.get_node_field_names() + + def _test_get_node_field_values(self): + name = self._random_node_field_name() + if name is None: + return False + if not self.model.timesteps: + return False + self.model.get_node_field_values(name) + + def _test_get_node_set_field_names(self): + self.model.get_node_set_field_names() + + def _test_get_node_set_ids(self): + self.model.get_node_set_ids() + + def _test_get_node_set_members(self): + id_ = self._random_node_set_id() + if id_ is None: + return False + self.model.get_node_set_members(id_) + + def _test_get_nodes_in_element_block(self): + ids = self._random_element_block_ids() + if ids is None: + return False + self.model.get_nodes_in_element_block(ids) + + def _test_get_nodes_in_side_set(self): + id_ = self._random_side_set_id() + if id_ is None: + return False + self.model.get_nodes_in_side_set(id_) + + def _test_get_side_set_ids(self): + self.model.get_side_set_ids() + + def _test_get_side_set_field_names(self): + self.model.get_side_set_field_names() + + def _test_node_set_field_exists(self): + info = self._random_node_set_field_name() + if info is None: + return False + id_, name = info + assert self.model.node_set_field_exists(name, id_) + + def _test_get_node_set_field_values(self): + if not self.model.timesteps: + return False + info = self._random_node_set_field_name() + if info is None: + return False + id_, name = info + self.model.get_node_set_field_values(name, id_) + + def _test_get_side_set_field_values(self): + if not self.model.timesteps: + return False + info = self._random_side_set_field_name() + if info is None: + return False + id_, name = info + self.model.get_side_set_field_values(name, id_) + + def _test_side_set_field_exists(self): + info = self._random_side_set_field_name() + if info is None: + return False + id_, name = info + assert self.model.side_set_field_exists(name, id_) + + def _test_get_timesteps(self): + self.model.get_timesteps() + + def _test_global_variable_exists(self): + name = self._random_global_variable_name() + if name is None: + assert not self.model.global_variable_exists('temp') + else: + assert self.model.global_variable_exists(name) + + def _test_import_model(self): + if self.remaining_io_tests <= 0: + return False + self.remaining_io_tests -= 1 + new_id = random.randint(1, 5) + if self.model.element_block_exists(new_id): + self.model.delete_element_block(new_id) + self.model.import_model( + 'exomerge_unit_test.e', + element_block_ids=new_id, + side_set_ids='none', + node_set_ids='none', + global_variable_names='none', + element_field_names='none', + node_field_names='none', + node_set_field_names='none', + side_set_field_names='none', + timesteps='none') + self._truncate_element_blocks() + + def _test_node_field_exists(self): + name = self._random_node_field_name() + if name is None: + assert not self.model.node_field_exists('temp') + else: + assert self.model.node_field_exists(name) + + def _test_node_set_exists(self): + id_ = self._random_node_set_id() + if id_ is None: + assert not self.model.node_set_exists(0) + else: + assert self.model.node_set_exists(id_) + + def _test_process_element_fields(self): + if not self.model.element_blocks: + return False + if not self.model.timesteps: + self.model.create_timestep(0.0) + self.model.delete_element_field('all') + self.model.create_element_field(self.model._new_element_field_name(), + self._random_element_block_id()) + for name in ['eqps_' + str(x) for x in range(1, 9)]: + self.model.create_element_field(name, 'all') + self.model.create_element_field(self.model._new_element_field_name(), + self._random_element_block_id()) + for name in ['theta_' + str(x) for x in range(1, 10)]: + self.model.create_element_field(name, 'all') + self.model.create_element_field(self.model._new_element_field_name(), + self._random_element_block_id()) + if self.model.get_node_field_names(): + self.model.delete_node_field('all') + self.model.process_element_fields() + self._truncate_node_fields() + + def _test_rename_element_field(self): + field = self._random_element_field_name() + if field is None: + return False + self.model.rename_element_field(field[1], + self._new_element_field_name(), + field[0]) + + def _test_scale_element_blocks(self): + ids = self._random_element_block_ids() + if ids is None: + return False + self.model.unmerge_element_blocks() + self.model.scale_element_blocks(ids, self._random_scalar()) + + def _test_rotate_element_blocks(self): + ids = self._random_element_block_ids() + if ids is None: + return False + self.model.unmerge_element_blocks() + self.model.rotate_element_blocks(ids, [1, 0, 0], 90) + + def _test_rotate_geometry(self): + self.model.rotate_geometry([1, 0, 0], 90) + + def _test_scale_geometry(self): + self.model.scale_geometry(self._random_scalar()) + + def _test_side_set_exists(self): + id_ = self._random_side_set_id() + if id_ is None: + assert not self.model.side_set_exists(0) + else: + assert self.model.side_set_exists(id_) + + def _test_summarize(self): + with OutputSuppression(): + self.model.summarize() + + def _test_timestep_exists(self): + timestep = self._random_element(self.model.timesteps) + if timestep is None: + assert not self.model.timestep_exists(0.0) + else: + assert self.model.timestep_exists(timestep) + + def _test_translate_element_blocks(self): + ids = self._random_element_block_ids() + if not ids: + return False + self.model.unmerge_element_blocks() + self.model.translate_element_blocks(ids, self._random_vector()) + + def _test_translate_geometry(self): + self.model.translate_geometry(self._random_vector()) + + def _test_threshold_element_blocks(self): + id_ = self._create_hex8_element_block() + assert self.model.get_element_count(id_) == 2 + self.model.calculate_element_centroids(element_block_ids=[id_]) + self.model.threshold_element_blocks('centroid_x>1', + element_block_ids=[id_]) + assert self.model.get_element_count(id_) == 1 + + def _test_count_degenerate_elements(self): + ids = self._random_element_block_ids() + if not ids: + return False + self.model.count_degenerate_elements(ids) + + def _test_delete_duplicate_elements(self): + id_ = self._random_element_block_id() + if id_ is None: + return False + new_id = self._new_element_block_id() + element_count = self.model.get_element_count(id_) + if element_count == 0: + return False + self.model.duplicate_element_block(id_, + new_id, + duplicate_nodes=False) + self.model.combine_element_blocks([id_, new_id], + target_element_block_id=id_) + self.model.delete_duplicate_elements(id_) + assert self.model.get_element_count(id_) <= element_count + + def _test_get_closest_node_distance(self): + self.model.get_closest_node_distance() + + def _test_get_connectivity(self): + id_ = self._random_element_block_id() + if id_ is None: + return False + self.model.get_connectivity(id_) + + def _test_get_element_block_dimension(self): + id_ = self._random_element_block_id() + if id_ is None: + return False + self.model.get_element_block_dimension(id_) + + def _test_get_element_block_extents(self): + ids = self._random_element_block_ids() + if not ids: + return False + self.model.get_element_block_extents(ids) + + def _test_get_element_block_name(self): + id_ = self._random_element_block_id() + if id_ is None: + return False + self.model.get_element_block_name(id_) + + def _test_get_all_element_block_names(self): + self.model.get_all_element_block_names() + + def _test_get_element_edge_length_info(self): + ids = self._random_element_block_ids() + if not ids: + return False + self.model.get_element_edge_length_info(ids) + + def _test_get_node_set_name(self): + id_ = self._random_node_set_id() + if id_ is None: + return False + self.model.get_node_set_name(id_) + + def _test_get_all_node_set_names(self): + self.model.get_all_node_set_names() + + def _test_get_side_set_area(self): + id_ = self._random_side_set_id() + if id_ is None: + return False + self.model.get_side_set_area(id_) + + def _test_get_side_set_members(self): + id_ = self._random_side_set_id() + if id_ is None: + return False + self.model.get_side_set_members(id_) + + def _test_get_side_set_name(self): + id_ = self._random_side_set_id() + if id_ is None: + return False + self.model.get_side_set_name(id_) + + def _test_get_all_side_set_names(self): + self.model.get_all_side_set_names() + + def _test_build_hex8_cube(self): + new_id = self._new_element_block_id() + self.model.build_hex8_cube(new_id) + + def _test_count_disconnected_blocks(self): + ids = self._random_element_block_ids() + if not ids: + return False + self.model.count_disconnected_blocks(ids) + + # End of unit test functions. + + @staticmethod + def _source_calls_target(source, target): + """ + Return True if the source function calls target somewhere. + + """ + source_code = inspect.getsource(source) + return bool( + re.search('[^A-Za-z0-9_]' + target.__name__ + '[ \t\n\r]*\(', + source_code)) + + def test(self): + """ + Run the unit tests. + + """ + random.seed(0) + exomerge.EXIT_ON_WARNING = True + # get list of all unit tests + tests = inspect.getmembers(self, inspect.ismethod) + unit_tests = [] + for test in tests: + if test[0].startswith('_test_'): + unit_tests.append(test) + # get a list of all public functions in exomerge + public_functions = [] + + for (function, _) in inspect.getmembers(exomerge.ExodusModel, inspect.isfunction): + if not function.startswith('_'): + public_functions.append(function) + print(('We found %d unit tests and %d public functions.' + % (len(unit_tests), len(public_functions)))) + # If a test exists that doesn't match a public function, issue a + # warning message and remove that unit test. + print('\nVerifying each unit test matches a public exomerge function.') + unmatched = [] + matched_unit_tests = [] + for unit_test in unit_tests: + (test, _) = unit_test + if not test[6:] in public_functions: + unmatched.append(test) + else: + matched_unit_tests.append(unit_test) + if unmatched: + print(('\nWARNING: Found %d unit test(s) without a matching ' + 'public function\nUnit tests:\n %s' + % (len(unmatched), '\n '.join(unmatched)))) + print('') + unit_tests = matched_unit_tests + # If a public function exists without a unit test, issue a warning + # message + print('\nVerifying public function has a matching unit test.') + unmatched = [] + unit_test_names = [x[0] for x in unit_tests] + for name in public_functions: + if not '_test_' + name in unit_test_names: + unmatched.append(name) + if unmatched: + print(('\nWARNING: Found %d public functions without a matching ' + 'unit test\nPublic functions:\n %s' + % (len(unmatched), '\n '.join(unmatched)))) + print('') + # make sure unit tests call the appropriate function + # i.e. _test_create_nodes better call create_nodes somewhere + print('\nVerifying each unit test calls the appropriate function.') + bad_unit_tests = [] + for name, function in unit_tests: + target = eval('exomerge.ExodusModel.' + name[6:]) + if not self._source_calls_target(function, target): + bad_unit_tests.append(name) + if bad_unit_tests: + print(('\nWARNING: Found %d unit tests which do not call their ' + 'corresponding public functions:\n %s' + % (len(bad_unit_tests), '\n '.join(bad_unit_tests)))) + print('') + # start off the model + self.model = exomerge.import_model('exomerge_unit_test.e') + # run for the given amount of walltime or the number of tests + # is sufficient + start_time = time.time() + end_time = time.time() + self.time_limit + tests = 0 + next_tests_to_run = [] + passed_tests = set() + while tests < self.max_tests and (time.time() < end_time or + tests < self.min_tests): + if not next_tests_to_run: + for _ in range(5): + next_tests_to_run.extend(copy.copy(unit_tests)) + random.shuffle(next_tests_to_run) + tests += 1 + test = next_tests_to_run[0] + del next_tests_to_run[0] + print(('[%d] %s' % (tests, test[0]))) + if test[1]() is None: + passed_tests.add(test[0]) + if tests % 123 == 0: + self.model._verify(allow_aliased_lists=False) + # if some tests did not successfully run, not that + if len(passed_tests) != len(unit_tests): + untested = [] + for (x, _) in unit_tests: + if x not in passed_tests: + untested.append(x) + print(('\nWARNING: Some unit tests were unable to be run:\n ' + + '\n '.join(untested))) + print(('\nRan %d tests in %g seconds.' + % (tests, time.time() - start_time))) + print('\nSuccess') + + +# if this module is executed (as opposed to imported), run the tests +if __name__ == '__main__': + if len(sys.argv) > 2: + sys.stderr.write('Invalid syntax.\n') + exit(1) + tester = ExomergeUnitTester() + tester._topology_test() + if len(sys.argv) == 2: + tester.min_tests = int(sys.argv[1]) + tester.max_tests = tester.min_tests + tester.test() diff --git a/packages/stk/cmake/Dependencies.cmake b/packages/stk/cmake/Dependencies.cmake index dd4250d1584a..80e2cb062ee2 100644 --- a/packages/stk/cmake/Dependencies.cmake +++ b/packages/stk/cmake/Dependencies.cmake @@ -1,5 +1,6 @@ SET(SUBPACKAGES_DIRS_CLASSIFICATIONS_OPTREQS Util stk_util PT OPTIONAL + Emend stk_emend PT OPTIONAL Coupling stk_coupling PT OPTIONAL Math stk_math PT OPTIONAL Simd stk_simd PT OPTIONAL diff --git a/packages/stk/stk_balance/Jamfile b/packages/stk/stk_balance/Jamfile index 3fcacf6498b3..487e81314c49 100644 --- a/packages/stk/stk_balance/Jamfile +++ b/packages/stk/stk_balance/Jamfile @@ -171,6 +171,7 @@ lib stk_balance_lib [ glob $(stk_balance-root)/stk_balance/*.cpp $(stk_balance-root)/stk_balance/internal/*.cpp + $(stk_balance-root)/stk_balance/m2n/*.cpp $(stk_balance-root)/stk_balance/mesh/*.cpp $(stk_balance-root)/stk_balance/io/*.cpp $(stk_balance-root)/stk_balance/setup/*.cpp diff --git a/packages/stk/stk_balance/stk_balance/CMakeLists.txt b/packages/stk/stk_balance/stk_balance/CMakeLists.txt index 76a6cec7b87b..6a49f0aadd68 100644 --- a/packages/stk/stk_balance/stk_balance/CMakeLists.txt +++ b/packages/stk/stk_balance/stk_balance/CMakeLists.txt @@ -69,6 +69,9 @@ FILE(GLOB SOURCES *.cpp FILE(GLOB HEADERS_INTERNAL ${CMAKE_CURRENT_SOURCE_DIR}/internal/*.hpp) FILE(GLOB SOURCES_INTERNAL ${CMAKE_CURRENT_SOURCE_DIR}/internal/*.cpp) +FILE(GLOB HEADERS_M2N ${CMAKE_CURRENT_SOURCE_DIR}/m2n/*.hpp) +FILE(GLOB SOURCES_M2N ${CMAKE_CURRENT_SOURCE_DIR}/m2n/*.cpp) + FILE(GLOB HEADERS_SETUP ${CMAKE_CURRENT_SOURCE_DIR}/setup/*.hpp) FILE(GLOB SOURCES_SETUP ${CMAKE_CURRENT_SOURCE_DIR}/setup/*.cpp) @@ -90,8 +93,8 @@ ENDIF() TRIBITS_ADD_LIBRARY( stk_balance_lib - NOINSTALLHEADERS ${HEADERS} ${HEADERS_INTERNAL} ${HEADERS_SETUP} ${HEADERS_SEARCH_TOLERANCE} ${HEADERS_SEARCH_TOLERANCE_ALGS} - SOURCES ${SOURCES} ${SOURCES_INTERNAL} ${SOURCES_SETUP} ${SOURCES_SEARCH_TOLERANCE_ALGS} + NOINSTALLHEADERS ${HEADERS} ${HEADERS_INTERNAL} ${HEADERS_M2N} ${HEADERS_SETUP} ${HEADERS_SEARCH_TOLERANCE} ${HEADERS_SEARCH_TOLERANCE_ALGS} + SOURCES ${SOURCES} ${SOURCES_INTERNAL} ${SOURCES_M2N} ${SOURCES_SETUP} ${SOURCES_SEARCH_TOLERANCE_ALGS} ) IF(TPL_ENABLE_Boost) @@ -114,6 +117,8 @@ INSTALL(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX}/${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}/stk_balance) INSTALL(FILES ${HEADERS_INTERNAL} DESTINATION ${CMAKE_INSTALL_PREFIX}/${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}/stk_balance/internal) +INSTALL(FILES ${HEADERS_M2N} DESTINATION + ${CMAKE_INSTALL_PREFIX}/${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}/stk_balance/m2n) INSTALL(FILES ${HEADERS_SETUP} DESTINATION ${CMAKE_INSTALL_PREFIX}/${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}/stk_balance/setup) INSTALL(FILES ${HEADERS_SEARCH_TOLERANCE} DESTINATION diff --git a/packages/stk/stk_balance/stk_balance/internal/SubdomainFileWriter.cpp b/packages/stk/stk_balance/stk_balance/internal/SubdomainFileWriter.cpp deleted file mode 100644 index 3cb9e24145bd..000000000000 --- a/packages/stk/stk_balance/stk_balance/internal/SubdomainFileWriter.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -namespace stk { -namespace balance { -namespace internal { - -std::tuple get_included_and_num_target_procs(stk::mesh::BulkData &bulk, stk::ParallelMachine comm) -{ - int includeMe = 0; - { - if(stk::mesh::count_selected_entities(bulk.mesh_meta_data().locally_owned_part(), bulk.buckets(stk::topology::ELEM_RANK))>0) - includeMe = 1; - } - - int numTarget = 0; - stk::all_reduce_sum(comm, &includeMe, &numTarget, 1); - - return std::make_tuple(includeMe, numTarget); -} - -int get_subdomain_index(int includeMe, stk::ParallelMachine comm) -{ - std::vector myData {includeMe}; - std::vector globalData(stk::parallel_machine_size(comm)); - stk::parallel_vector_concat(comm, myData, globalData); - int mySubdomain = -1; - if(includeMe) - { - mySubdomain = 0; - for(int i = 0; i < stk::parallel_machine_rank(comm); ++i) - { - if(globalData[i] > 0) - mySubdomain++; - } - } - return mySubdomain; -} - -void write_subdomain_files(stk::mesh::BulkData &bulk, int numTarget, int mySubdomain, const std::string& outputMesh) -{ - stk::balance::internal::SubdomainCreator subdomainCreator(bulk, numTarget); - subdomainCreator.declare_all_final_subdomain_parts(); - stk::mesh::EntityVector elements; - stk::mesh::get_entities(bulk, stk::topology::ELEM_RANK, - bulk.mesh_meta_data().locally_owned_part(), elements); - bulk.modification_begin(); - if (mySubdomain >= 0) { - subdomainCreator.move_entities_into_final_subdomain_part(mySubdomain, elements); - } - bulk.modification_end(); - - std::vector counts; - stk::mesh::comm_mesh_counts(bulk, counts); - int global_num_nodes = counts[stk::topology::NODE_RANK]; - int global_num_elems = counts[stk::topology::ELEM_RANK]; - - if (mySubdomain >= 0) { - subdomainCreator.create_subdomain_and_write(outputMesh, mySubdomain, global_num_nodes, global_num_elems); - } -} - -}}} - - diff --git a/packages/stk/stk_balance/stk_balance/internal/SubdomainFileWriter.hpp b/packages/stk/stk_balance/stk_balance/internal/SubdomainFileWriter.hpp deleted file mode 100644 index 7cd662fb2d44..000000000000 --- a/packages/stk/stk_balance/stk_balance/internal/SubdomainFileWriter.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef STK_STK_BALANCE_STK_BALANCE_INTERNAL_SUBDOMAINFILEWRITER_HPP_ -#define STK_STK_BALANCE_STK_BALANCE_INTERNAL_SUBDOMAINFILEWRITER_HPP_ -#include -#include -#include - -namespace stk { namespace mesh { class BulkData; }} - -namespace stk { -namespace balance { -namespace internal { - -std::tuple get_included_and_num_target_procs(stk::mesh::BulkData &bulk, stk::ParallelMachine comm); - -int get_subdomain_index(int includeMe, stk::ParallelMachine comm); - -void write_subdomain_files(stk::mesh::BulkData &bulk, int numTarget, int mySubdomain, const std::string& outputMesh); - -}}} -#endif /* STK_STK_BALANCE_STK_BALANCE_INTERNAL_SUBDOMAINFILEWRITER_HPP_ */ diff --git a/packages/stk/stk_balance/stk_balance/internal/privateDeclarations.cpp b/packages/stk/stk_balance/stk_balance/internal/privateDeclarations.cpp index 4e4617646987..46d886cdae42 100644 --- a/packages/stk/stk_balance/stk_balance/internal/privateDeclarations.cpp +++ b/packages/stk/stk_balance/stk_balance/internal/privateDeclarations.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include @@ -175,34 +175,6 @@ void addBoxForFace(stk::mesh::BulkData &stkMeshBulkData, stk::mesh::Entity face, } } -void addEdgeAndVertexWeightsForSearchResult(stk::mesh::BulkData& stkMeshBulkData, - const BalanceSettings &balanceSettings, - stk::mesh::EntityId element1Id, - stk::mesh::EntityId element2Id, - unsigned owningProcElement2, - std::vector& graphEdges) -{ - stk::mesh::EntityKey entityKeyElement1(stk::topology::ELEMENT_RANK, element1Id); - stk::mesh::Entity element1 = stkMeshBulkData.get_entity(entityKeyElement1); - ThrowRequireWithSierraHelpMsg(stkMeshBulkData.entity_rank(element1) == stk::topology::ELEMENT_RANK); - - if(stkMeshBulkData.is_valid(element1) && stkMeshBulkData.bucket(element1).owned() && element1Id != element2Id) - { - stk::mesh::EntityKey entityKeyElement2(stk::topology::ELEMENT_RANK, element2Id); - stk::mesh::Entity element2 = stkMeshBulkData.get_entity(entityKeyElement2); - - bool anyIntersections = false; - if (stkMeshBulkData.is_valid(element2)) { - anyIntersections = stk::balance::internal::has_common_nodes_between_elements(stkMeshBulkData, element1, element2); - } - - if (!anyIntersections) { - double edge_weight = balanceSettings.getGraphEdgeWeightForSearch(); - graphEdges.push_back(GraphEdge(element1, element2Id, owningProcElement2, edge_weight, true)); - } - } -} - void addSearchResultsToGraphEdges(stk::mesh::BulkData & bulk, const BalanceSettings & balanceSettings, diff --git a/packages/stk/stk_balance/stk_balance/internal/M2NDecomposer.cpp b/packages/stk/stk_balance/stk_balance/m2n/M2NDecomposer.cpp similarity index 91% rename from packages/stk/stk_balance/stk_balance/internal/M2NDecomposer.cpp rename to packages/stk/stk_balance/stk_balance/m2n/M2NDecomposer.cpp index 83b9806cd9df..3cd63fcb196b 100644 --- a/packages/stk/stk_balance/stk_balance/internal/M2NDecomposer.cpp +++ b/packages/stk/stk_balance/stk_balance/m2n/M2NDecomposer.cpp @@ -39,7 +39,7 @@ namespace stk { namespace balance { -namespace internal { +namespace m2n { M2NDecomposer::M2NDecomposer(stk::mesh::BulkData & bulkData, const stk::balance::M2NBalanceSettings & balanceSettings) @@ -117,17 +117,6 @@ M2NDecomposerNested::get_partition() return decomp; } -stk::mesh::EntityProcVec -M2NDecomposerNested::get_partition_for_subdomain(int subdomainId) -{ - stk::mesh::EntityProcVec decomp; - std::vector selectors = { *m_bulkData.mesh_meta_data().get_part(get_initial_subdomain_part_name(subdomainId)) }; - stk::balance::internal::calculateGeometricOrGraphBasedDecomp(m_bulkData, selectors, - m_bulkData.parallel(), m_numFinalSubdomainsPerProc, - m_balanceSettings, decomp); - return decomp; -} - std::vector M2NDecomposerNested::map_new_subdomains_to_original_processors() { diff --git a/packages/stk/stk_balance/stk_balance/internal/M2NDecomposer.hpp b/packages/stk/stk_balance/stk_balance/m2n/M2NDecomposer.hpp similarity index 97% rename from packages/stk/stk_balance/stk_balance/internal/M2NDecomposer.hpp rename to packages/stk/stk_balance/stk_balance/m2n/M2NDecomposer.hpp index 1f210babb2ba..17d041c789f7 100644 --- a/packages/stk/stk_balance/stk_balance/internal/M2NDecomposer.hpp +++ b/packages/stk/stk_balance/stk_balance/m2n/M2NDecomposer.hpp @@ -41,7 +41,7 @@ namespace stk { namespace balance { class M2NBalanceSettings; } } namespace stk { namespace balance { -namespace internal { +namespace m2n { class M2NDecomposer { @@ -73,7 +73,6 @@ class M2NDecomposerNested : public M2NDecomposer virtual std::vector map_new_subdomains_to_original_processors() override; private: - stk::mesh::EntityProcVec get_partition_for_subdomain(int subdomainId); std::string get_initial_subdomain_part_name(int subdomainId); void declare_all_initial_subdomain_parts(); void move_entities_into_initial_subdomain_part(); diff --git a/packages/stk/stk_balance/stk_balance/internal/MtoNRebalancer.cpp b/packages/stk/stk_balance/stk_balance/m2n/MtoNRebalancer.cpp similarity index 75% rename from packages/stk/stk_balance/stk_balance/internal/MtoNRebalancer.cpp rename to packages/stk/stk_balance/stk_balance/m2n/MtoNRebalancer.cpp index 3747219b788e..2381f8d489ce 100644 --- a/packages/stk/stk_balance/stk_balance/internal/MtoNRebalancer.cpp +++ b/packages/stk/stk_balance/stk_balance/m2n/MtoNRebalancer.cpp @@ -5,8 +5,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -14,16 +14,14 @@ namespace stk { namespace balance { -namespace internal { +namespace m2n { MtoNRebalancer::MtoNRebalancer(stk::io::StkMeshIoBroker& ioBroker, - stk::mesh::Field& targetField, M2NDecomposer& decomposer, const M2NBalanceSettings& balanceSettings) : m_bulkData(ioBroker.bulk_data()), m_subdomainCreator(ioBroker, balanceSettings.get_num_output_processors()), m_decomposer(decomposer), - m_inputMeshTargetDecompField(targetField), m_balanceSettings(balanceSettings) { std::vector counts; @@ -43,7 +41,7 @@ MtoNRebalancer::rebalance(int numSteps, double timeStep) for (const std::vector & targetSubdomains : targetSubdomainsForEachBatch) { OutputMesh outputMesh = clone_target_subdomains(targetSubdomains); - move_subdomain_to_owning_processor(outputMesh); + move_subdomain_to_owning_processor(outputMesh, targetSubdomains); create_subdomain_and_write(m_balanceSettings.get_input_filename(), targetSubdomains, outputMesh, numSteps, timeStep); } } @@ -62,7 +60,6 @@ MtoNRebalancer::map_new_subdomains_to_original_processors() void MtoNRebalancer::store_final_decomp_on_elements() { - store_off_target_proc_on_elements_before_moving_subdomains(); move_entities_into_mapped_subdomain_parts(); } @@ -106,18 +103,18 @@ MtoNRebalancer::clone_target_subdomains(const std::vector & targetSubd } void -MtoNRebalancer::move_subdomain_to_owning_processor(OutputMesh & outputMesh) +MtoNRebalancer::move_subdomain_to_owning_processor(OutputMesh & outputMesh, const std::vector & targetSubdomains) { - stk::mesh::Field & outputMeshTargetDecompField = - *reinterpret_cast *>(outputMesh.meta().get_field(stk::topology::ELEM_RANK, - m_inputMeshTargetDecompField.name())); - stk::mesh::EntityProcVec subdomainDecomp; - const stk::mesh::Part & locallyOwned = outputMesh.meta().locally_owned_part(); - for (const stk::mesh::Bucket * bucket : outputMesh.bulk().get_buckets(stk::topology::ELEM_RANK, locallyOwned)) { - for (const stk::mesh::Entity & elem : *bucket) { - const unsigned * destination = stk::mesh::field_data(outputMeshTargetDecompField, elem); - subdomainDecomp.emplace_back(elem, *destination); + for (unsigned subdomain : targetSubdomains) { + if (stk::transfer_utils::is_valid_subdomain(subdomain)) { + const stk::mesh::Selector & locallyOwnedSubdomain = outputMesh.meta().locally_owned_part() & + *outputMesh.meta().get_part(m_subdomainCreator.get_subdomain_part_name(subdomain)); + for (const stk::mesh::Bucket * bucket : outputMesh.bulk().get_buckets(stk::topology::ELEM_RANK, locallyOwnedSubdomain)) { + for (const stk::mesh::Entity & elem : *bucket) { + subdomainDecomp.emplace_back(elem, subdomain); + } + } } } @@ -135,27 +132,12 @@ void MtoNRebalancer::move_entities_into_mapped_subdomain_parts() m_bulkData.modification_end(); } -stk::mesh::BulkData& MtoNRebalancer::get_bulk() -{ - return m_bulkData; -} - SubdomainCreator& MtoNRebalancer::get_subdomain_creator() { return m_subdomainCreator; } -stk::mesh::MetaData& MtoNRebalancer::get_meta() -{ - return m_bulkData.mesh_meta_data(); -} - -void MtoNRebalancer::store_off_target_proc_on_elements_before_moving_subdomains() -{ - stk::balance::internal::put_entity_data_to_field(m_decomp, &m_inputMeshTargetDecompField); -} - void MtoNRebalancer::create_subdomain_and_write(const std::string &filename, const std::vector & targetSubdomains, OutputMesh & outputMesh, int numSteps, double timeStep) { @@ -163,9 +145,4 @@ void MtoNRebalancer::create_subdomain_and_write(const std::string &filename, con outputMesh, m_globalNumNodes, m_globalNumElems, numSteps, timeStep); } -int MtoNRebalancer::get_num_target_subdomains() -{ - return m_subdomainCreator.get_num_final_subdomains(); -} - }}} diff --git a/packages/stk/stk_balance/stk_balance/internal/MtoNRebalancer.hpp b/packages/stk/stk_balance/stk_balance/m2n/MtoNRebalancer.hpp similarity index 90% rename from packages/stk/stk_balance/stk_balance/internal/MtoNRebalancer.hpp rename to packages/stk/stk_balance/stk_balance/m2n/MtoNRebalancer.hpp index c4fdf00fe767..07eb9a41f197 100644 --- a/packages/stk/stk_balance/stk_balance/internal/MtoNRebalancer.hpp +++ b/packages/stk/stk_balance/stk_balance/m2n/MtoNRebalancer.hpp @@ -45,18 +45,17 @@ namespace stk { namespace mesh { class BulkData; }} namespace stk { namespace mesh { class FieldBase; }} namespace stk { namespace mesh { class Bucket; }} namespace stk { namespace balance { class M2NParsedOptions; }} -namespace stk { namespace balance { namespace internal { class M2NDecomposer; }}} +namespace stk { namespace balance { namespace m2n { class M2NDecomposer; }}} namespace stk { namespace io { class StkMeshIoBroker; }} namespace stk { namespace balance { -namespace internal { +namespace m2n { class MtoNRebalancer { public: MtoNRebalancer(stk::io::StkMeshIoBroker& ioBroker, - stk::mesh::Field &targetField, M2NDecomposer &decomposer, const M2NBalanceSettings &balanceSettings); @@ -72,22 +71,17 @@ class MtoNRebalancer OutputMesh clone_target_subdomains(const std::vector & targetSubdomains); - void move_subdomain_to_owning_processor(OutputMesh & outputMesh); + void move_subdomain_to_owning_processor(OutputMesh & outputMesh, const std::vector & targetSubdomains); void create_subdomain_and_write(const std::string &filename, const std::vector & targetSubdomains, OutputMesh & outputMesh, int numSteps = -1, double timeStep = 0.0); - stk::mesh::MetaData& get_meta(); - stk::mesh::BulkData& get_bulk(); SubdomainCreator& get_subdomain_creator(); - int get_num_target_subdomains(); - const std::vector & get_owner_for_each_final_subdomain() const { return m_ownerForEachFinalSubdomain; } private: void move_entities_into_mapped_subdomain_parts(); - void store_off_target_proc_on_elements_before_moving_subdomains(); MtoNRebalancer( const MtoNRebalancer& other ); MtoNRebalancer& operator=( const MtoNRebalancer& other ); @@ -95,7 +89,6 @@ class MtoNRebalancer stk::mesh::BulkData &m_bulkData; SubdomainCreator m_subdomainCreator; M2NDecomposer &m_decomposer; - stk::mesh::Field &m_inputMeshTargetDecompField; const M2NBalanceSettings &m_balanceSettings; stk::mesh::EntityProcVec m_decomp; std::vector m_ownerForEachFinalSubdomain; diff --git a/packages/stk/stk_balance/stk_balance/internal/MxNutils.cpp b/packages/stk/stk_balance/stk_balance/m2n/MxNutils.cpp similarity index 88% rename from packages/stk/stk_balance/stk_balance/internal/MxNutils.cpp rename to packages/stk/stk_balance/stk_balance/m2n/MxNutils.cpp index cd451b6b91cb..92d7291dbd5f 100644 --- a/packages/stk/stk_balance/stk_balance/internal/MxNutils.cpp +++ b/packages/stk/stk_balance/stk_balance/m2n/MxNutils.cpp @@ -43,14 +43,6 @@ namespace stk { namespace balance { namespace internal { -std::vector assign_target_subdomains_roundrobin_to_procs(unsigned num_procs_M, unsigned num_procs_N) -{ - std::vector targetSubdomainsToProc(num_procs_N, std::numeric_limits::max()); - for(unsigned i = 0; i < num_procs_N; i++) - targetSubdomainsToProc[i] = i % num_procs_M; - return targetSubdomainsToProc; -} - void fill_decomp(const int num_partitions, stk::mesh::BulkData& bulk, const stk::balance::BalanceSettings &graphSettings, stk::mesh::EntityProcVec &decomp) { std::vector selectors = { bulk.mesh_meta_data().universal_part() }; diff --git a/packages/stk/stk_balance/stk_balance/internal/MxNutils.hpp b/packages/stk/stk_balance/stk_balance/m2n/MxNutils.hpp similarity index 95% rename from packages/stk/stk_balance/stk_balance/internal/MxNutils.hpp rename to packages/stk/stk_balance/stk_balance/m2n/MxNutils.hpp index 633aaa1db80f..bf4e90bab6e0 100644 --- a/packages/stk/stk_balance/stk_balance/internal/MxNutils.hpp +++ b/packages/stk/stk_balance/stk_balance/m2n/MxNutils.hpp @@ -46,7 +46,6 @@ namespace stk { namespace balance { namespace internal { -std::vector assign_target_subdomains_roundrobin_to_procs(unsigned num_procs_M, unsigned num_procs_N); void fill_decomp(const int num_partitions, stk::mesh::BulkData& bulk, const stk::balance::BalanceSettings &graphSettings, stk::mesh::EntityProcVec &decomp); stk::mesh::EntityProcVec get_element_decomp(const int num_partitions, stk::mesh::BulkData& bulk, const stk::balance::BalanceSettings &graphSettings); diff --git a/packages/stk/stk_balance/stk_balance/internal/SubdomainCreator.cpp b/packages/stk/stk_balance/stk_balance/m2n/SubdomainCreator.cpp similarity index 80% rename from packages/stk/stk_balance/stk_balance/internal/SubdomainCreator.cpp rename to packages/stk/stk_balance/stk_balance/m2n/SubdomainCreator.cpp index e51c589b2123..06911ecae9f6 100644 --- a/packages/stk/stk_balance/stk_balance/internal/SubdomainCreator.cpp +++ b/packages/stk/stk_balance/stk_balance/m2n/SubdomainCreator.cpp @@ -41,7 +41,7 @@ namespace stk { namespace balance { -namespace internal { +namespace m2n { constexpr unsigned SubdomainCreator::INVALID_SUBDOMAIN; @@ -87,13 +87,6 @@ stk::mesh::Part* SubdomainCreator::get_subdomain_part(size_t subdomain) return m_subdomainParts[subdomain]; } -void SubdomainCreator::move_entities_into_final_subdomain_part(size_t i, const stk::mesh::EntityVector &entities) -{ - stk::mesh::PartVector partVector = get_parts_to_add_for_subdomain(i); - for(size_t j = 0; j < entities.size(); j++) - m_inputBulk.change_entity_parts(entities[j], partVector); -} - stk::mesh::PartVector SubdomainCreator::get_parts_to_add_for_subdomain(size_t subdomain_num) { stk::mesh::Part* part = get_subdomain_part(subdomain_num); @@ -126,23 +119,6 @@ void SubdomainCreator::fill_shared_node_info_for_this_subdomain(const unsigned t } } -stk::io::EntitySharingInfo SubdomainCreator::get_node_sharing_info(unsigned subdomain) -{ - stk::io::EntitySharingInfo nodeSharingInfo; - if (stk::transfer_utils::is_valid_subdomain(subdomain)) { - stk::mesh::EntityVector sharedNodes; - std::vector procsForSharedNodes; - fill_shared_node_info_for_this_subdomain(subdomain, sharedNodes, procsForSharedNodes); - - for(size_t nodeIndex = 0; nodeIndex < sharedNodes.size(); nodeIndex++) - { - stk::mesh::EntityId nodeId = m_inputBulk.identifier(sharedNodes[nodeIndex]); - nodeSharingInfo.push_back({nodeId, procsForSharedNodes[nodeIndex]}); - } - } - return nodeSharingInfo; -} - struct SubdomainNodeSharing { std::vector nodes; std::vector subdomain; @@ -153,7 +129,6 @@ struct SubdomainNodeSharing { } }; - stk::io::EntitySharingInfo SubdomainCreator::get_node_sharing_info(unsigned mySubdomain, const std::vector& subdomainsInBatch, const std::vector& ownerForEachFinalSubdomain) @@ -217,31 +192,6 @@ stk::io::EntitySharingInfo SubdomainCreator::get_node_sharing_info(unsigned mySu return nodeSharingInfo; } -void SubdomainCreator::create_subdomain_and_write(const std::string &filename, unsigned subdomain, - int global_num_nodes, int global_num_elems, - int numSteps, double timeStep) -{ - stk::mesh::MetaData newMeta; - stk::transfer_utils::M2NOutputSerializerBulkData newBulkData(newMeta, MPI_COMM_SELF); - - const stk::mesh::Selector subdomainSelector = stk::transfer_utils::is_valid_subdomain(subdomain) ? *m_inputMeta.get_part(get_subdomain_part_name(subdomain)) - : stk::mesh::Selector(); - stk::tools::copy_mesh(m_inputBulk, subdomainSelector, newBulkData); - - stk::io::EntitySharingInfo nodeSharingInfo = get_node_sharing_info(subdomain); - - if (m_transientIo == nullptr) { - if (stk::transfer_utils::is_valid_subdomain(subdomain)) { - stk::io::write_file_for_subdomain(filename, subdomain, m_numFinalSubdomains, global_num_nodes, global_num_elems, - newBulkData, nodeSharingInfo, numSteps, timeStep); - } - } - else { - m_transientIo->setup_subdomain(newBulkData, filename, subdomain, nodeSharingInfo, global_num_nodes, global_num_elems); - m_transientIo->transfer_and_write_transient_data(subdomain); - } -} - void SubdomainCreator::create_subdomain_and_write(const std::string &filename, const std::vector & targetSubdomains, const std::vector & ownerForEachFinalSubdomain, OutputMesh & outputMesh, unsigned globalNumNodes, unsigned globalNumElems, diff --git a/packages/stk/stk_balance/stk_balance/internal/SubdomainCreator.hpp b/packages/stk/stk_balance/stk_balance/m2n/SubdomainCreator.hpp similarity index 90% rename from packages/stk/stk_balance/stk_balance/internal/SubdomainCreator.hpp rename to packages/stk/stk_balance/stk_balance/m2n/SubdomainCreator.hpp index 4c4bb54bdcf2..8dd383eab853 100644 --- a/packages/stk/stk_balance/stk_balance/internal/SubdomainCreator.hpp +++ b/packages/stk/stk_balance/stk_balance/m2n/SubdomainCreator.hpp @@ -46,7 +46,7 @@ namespace stk { namespace io { class StkMeshIoBroker; }} namespace stk { namespace balance { -namespace internal { +namespace m2n { class OutputMesh { @@ -76,20 +76,12 @@ class SubdomainCreator SubdomainCreator(stk::io::StkMeshIoBroker& ioBroker, int numTarget); ~SubdomainCreator(); - int get_num_final_subdomains() const { return m_numFinalSubdomains; } const stk::mesh::PartVector & declare_all_final_subdomain_parts(); - void move_entities_into_final_subdomain_part(size_t i, const stk::mesh::EntityVector &entities); - - stk::io::EntitySharingInfo get_node_sharing_info(unsigned subdomain); stk::io::EntitySharingInfo get_node_sharing_info(unsigned mySubdomain, const std::vector & targetSubdomains, const std::vector & ownerForEachFinalSubdomain); - void create_subdomain_and_write(const std::string &filename, unsigned subdomain, - int global_num_nodes, int global_num_elems, - int numSteps = -1, double timeStep = 0.0); - void create_subdomain_and_write(const std::string &filename, const std::vector & targetSubdomains, const std::vector & ownerForEachFinalSubdomain, OutputMesh & outputMesh, unsigned globalNumNodes, unsigned globalNumElems, diff --git a/packages/stk/stk_balance/stk_balance/internal/balanceMtoN.cpp b/packages/stk/stk_balance/stk_balance/m2n/balanceMtoN.cpp similarity index 84% rename from packages/stk/stk_balance/stk_balance/internal/balanceMtoN.cpp rename to packages/stk/stk_balance/stk_balance/m2n/balanceMtoN.cpp index ce48b82a0202..33e22ec210bb 100644 --- a/packages/stk/stk_balance/stk_balance/internal/balanceMtoN.cpp +++ b/packages/stk/stk_balance/stk_balance/m2n/balanceMtoN.cpp @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include @@ -48,31 +48,30 @@ namespace stk { namespace balance { -namespace internal { +namespace m2n { -using DecomposerPtr = std::shared_ptr; +using DecomposerPtr = std::shared_ptr; DecomposerPtr make_decomposer(stk::mesh::BulkData& bulkData, const stk::balance::M2NBalanceSettings& balanceSettings) { DecomposerPtr decomposer; if (balanceSettings.get_use_nested_decomp()) { - decomposer = std::make_shared(bulkData, balanceSettings); + decomposer = std::make_shared(bulkData, balanceSettings); } else { - decomposer = std::make_shared(bulkData, balanceSettings); + decomposer = std::make_shared(bulkData, balanceSettings); } return decomposer; } bool rebalanceMtoN(stk::io::StkMeshIoBroker& ioBroker, - stk::mesh::Field &targetDecompField, const stk::balance::M2NBalanceSettings & balanceSettings, int numSteps, double timeStep) { DecomposerPtr decomposer = make_decomposer(ioBroker.bulk_data(), balanceSettings); - MtoNRebalancer m2nRebalancer(ioBroker, targetDecompField, *decomposer, balanceSettings); + MtoNRebalancer m2nRebalancer(ioBroker, *decomposer, balanceSettings); m2nRebalancer.rebalance(numSteps, timeStep); return true; diff --git a/packages/stk/stk_balance/stk_balance/internal/balanceMtoN.hpp b/packages/stk/stk_balance/stk_balance/m2n/balanceMtoN.hpp similarity index 96% rename from packages/stk/stk_balance/stk_balance/internal/balanceMtoN.hpp rename to packages/stk/stk_balance/stk_balance/m2n/balanceMtoN.hpp index 5b6fe96805a2..636990ea73da 100644 --- a/packages/stk/stk_balance/stk_balance/internal/balanceMtoN.hpp +++ b/packages/stk/stk_balance/stk_balance/m2n/balanceMtoN.hpp @@ -43,10 +43,9 @@ namespace stk { namespace balance { class M2NBalanceSettings; } } namespace stk { namespace balance { -namespace internal { +namespace m2n { bool rebalanceMtoN(stk::io::StkMeshIoBroker& ioBroker, - stk::mesh::Field &targetDecompField, const stk::balance::M2NBalanceSettings & balanceSettings, int numSteps = -1, double timeStep = 0.0); diff --git a/packages/stk/stk_balance/stk_balance/m2n_main/m2nMain.cpp b/packages/stk/stk_balance/stk_balance/m2n_main/m2nMain.cpp index 42d9664353bb..f0d67a07bf5b 100644 --- a/packages/stk/stk_balance/stk_balance/m2n_main/m2nMain.cpp +++ b/packages/stk/stk_balance/stk_balance/m2n_main/m2nMain.cpp @@ -1,9 +1,9 @@ #include "mpi.h" #include #include -#include +#include +#include #include -#include #include #include @@ -43,13 +43,10 @@ void rebalance_m_to_n(stk::balance::M2NBalanceSettings &balanceSettings, MPI_Com stk::mesh::MetaData meta; stk::mesh::BulkData bulk(meta, comm); - stk::mesh::Field &field = meta.declare_field >(stk::topology::ELEMENT_RANK, "TargetDecomp", 1); - stk::mesh::put_field_on_mesh(field, meta.universal_part(), static_cast(nullptr)); - stk::io::StkMeshIoBroker ioBroker; stk::io::fill_mesh_preexisting(ioBroker, balanceSettings.get_input_filename(), bulk); - stk::balance::internal::rebalanceMtoN(ioBroker, field, balanceSettings); + stk::balance::m2n::rebalanceMtoN(ioBroker, balanceSettings); } } diff --git a/packages/stk/stk_emend/CMakeLists.txt b/packages/stk/stk_emend/CMakeLists.txt new file mode 100644 index 000000000000..1296d78b477f --- /dev/null +++ b/packages/stk/stk_emend/CMakeLists.txt @@ -0,0 +1,39 @@ +# Copyright 2002 - 2008, 2010, 2011 National Technology Engineering +# Solutions of Sandia, LLC (NTESS). Under the terms of Contract +# DE-NA0003525 with NTESS, the U.S. Government retains certain rights +# in this software. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# * Neither the name of NTESS nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +TRIBITS_SUBPACKAGE(Emend) + +ADD_SUBDIRECTORY(stk_emend) + +TRIBITS_SUBPACKAGE_POSTPROCESS() diff --git a/packages/stk/stk_emend/Jamfile b/packages/stk/stk_emend/Jamfile index 08f71aee2566..23abc5dac028 100644 --- a/packages/stk/stk_emend/Jamfile +++ b/packages/stk/stk_emend/Jamfile @@ -60,7 +60,7 @@ import os ; local stk_emend-root-inc ; stk_emend-root-inc = [ ifuserbuild $(sierra-root)/stk/stk_emend/include ] - [ ifdevbuild $(stk_emend-root)/independent_set_lib ] ; + [ ifdevbuild $(stk_emend-root)/independent_set ] ; project votd : requirements @@ -92,7 +92,7 @@ install install-user-jamfile explicit install-user-include ; install install-user-include - : [ path.glob-tree $(stk_emend-root)/independent_set_lib : *.h *.hpp ] + : [ path.glob-tree $(stk_emend-root)/stk_emend/independent_set : *.h *.hpp ] : $(install-root)/stk/stk_emend/include ; @@ -130,5 +130,5 @@ alias independent_set_lib : # No build requirements : # No default build : - $(stk_emend-root-inc) + $(stk_emend-root-inc)/.. ; diff --git a/packages/stk/stk_emend/cmake/Dependencies.cmake b/packages/stk/stk_emend/cmake/Dependencies.cmake new file mode 100644 index 000000000000..a529c7f54db6 --- /dev/null +++ b/packages/stk/stk_emend/cmake/Dependencies.cmake @@ -0,0 +1,9 @@ +SET(LIB_REQUIRED_DEP_PACKAGES STKUtil) +SET(LIB_OPTIONAL_DEP_PACKAGES) +SET(TEST_REQUIRED_DEP_PACKAGES) +SET(TEST_OPTIONAL_DEP_PACKAGES) +SET(LIB_REQUIRED_DEP_TPLS) +SET(LIB_OPTIONAL_DEP_TPLS) +SET(TEST_REQUIRED_DEP_TPLS) +SET(TEST_OPTIONAL_DEP_TPLS) + diff --git a/packages/stk/stk_emend/stk_emend/CMakeLists.txt b/packages/stk/stk_emend/stk_emend/CMakeLists.txt new file mode 100644 index 000000000000..bbe7394f0b1c --- /dev/null +++ b/packages/stk/stk_emend/stk_emend/CMakeLists.txt @@ -0,0 +1 @@ +ADD_SUBDIRECTORY(independent_set) diff --git a/packages/stk/stk_emend/stk_emend/independent_set/CMakeLists.txt b/packages/stk/stk_emend/stk_emend/independent_set/CMakeLists.txt new file mode 100644 index 000000000000..99f9282d5cde --- /dev/null +++ b/packages/stk/stk_emend/stk_emend/independent_set/CMakeLists.txt @@ -0,0 +1,54 @@ +# Copyright 2002 - 2008, 2010, 2011 National Technology Engineering +# Solutions of Sandia, LLC (NTESS). Under the terms of Contract +# DE-NA0003525 with NTESS, the U.S. Government retains certain rights +# in this software. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# * Neither the name of NTESS nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +# +# A) Package-specific configuration options +# + +# +# B) Define the header and source files (and directories) +# + +# +# src +# + +SET(HEADERS "") + +FILE(GLOB HEADERS *.hpp) + +INSTALL(FILES ${HEADERS} DESTINATION + ${CMAKE_INSTALL_PREFIX}/${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}/stk_emend/) + diff --git a/packages/stk/stk_emend/independent_set_lib/IndependentSetFinder.hpp b/packages/stk/stk_emend/stk_emend/independent_set/IndependentSetFinder.hpp similarity index 99% rename from packages/stk/stk_emend/independent_set_lib/IndependentSetFinder.hpp rename to packages/stk/stk_emend/stk_emend/independent_set/IndependentSetFinder.hpp index 43b6eb0a3bc7..7fdffe204f9d 100644 --- a/packages/stk/stk_emend/independent_set_lib/IndependentSetFinder.hpp +++ b/packages/stk/stk_emend/stk_emend/independent_set/IndependentSetFinder.hpp @@ -1,6 +1,6 @@ #ifndef NGS_INDEPENDENT_SET_LIB_INDEPENDENTSETFINDER_HPP_ #define NGS_INDEPENDENT_SET_LIB_INDEPENDENTSETFINDER_HPP_ -#include +#include #include #include #include diff --git a/packages/stk/stk_emend/independent_set_lib/IndependentSetInfoToInfoGraph.hpp b/packages/stk/stk_emend/stk_emend/independent_set/IndependentSetInfoToInfoGraph.hpp similarity index 100% rename from packages/stk/stk_emend/independent_set_lib/IndependentSetInfoToInfoGraph.hpp rename to packages/stk/stk_emend/stk_emend/independent_set/IndependentSetInfoToInfoGraph.hpp diff --git a/packages/stk/stk_integration_tests/stk_balance/IntegrationTestLoadBalanceMxN.cpp b/packages/stk/stk_integration_tests/stk_balance/IntegrationTestLoadBalanceMxN.cpp index f42944eb35c5..60b3f3f7a722 100644 --- a/packages/stk/stk_integration_tests/stk_balance/IntegrationTestLoadBalanceMxN.cpp +++ b/packages/stk/stk_integration_tests/stk_balance/IntegrationTestLoadBalanceMxN.cpp @@ -8,13 +8,13 @@ #include #include #include -#include -#include +#include +#include #include #include #include +#include -#include namespace { @@ -49,7 +49,6 @@ class TestBalanceMxNRebalanceUsingInputFiles : public MeshFixtureMxNRebalance void setup_initial_mesh_from_last_time_step(stk::mesh::BulkData::AutomaticAuraOption auraOption) { - create_target_decomp_field_on_entire_mesh(); setup_mesh_from_last_time_step(get_input_mesh_file_name(), auraOption); } diff --git a/packages/stk/stk_integration_tests/stk_balance/IntegrationTestLoadBalanceSmallToLargeProc.cpp b/packages/stk/stk_integration_tests/stk_balance/IntegrationTestLoadBalanceSmallToLargeProc.cpp index 39dc3317f158..252408a3ee72 100644 --- a/packages/stk/stk_integration_tests/stk_balance/IntegrationTestLoadBalanceSmallToLargeProc.cpp +++ b/packages/stk/stk_integration_tests/stk_balance/IntegrationTestLoadBalanceSmallToLargeProc.cpp @@ -1,7 +1,6 @@ -#include #include -#include -#include +#include +#include #include "stk_unit_test_utils/getOption.h" #include "stk_mesh/base/Comm.hpp" @@ -54,118 +53,7 @@ TEST_F(TestBalanceMtoM, MxM_decompositionWithoutAura) if(stk::parallel_machine_size(get_comm()) == static_cast(get_num_procs_initial_decomp())) { setup_initial_mesh(stk::mesh::BulkData::NO_AUTO_AURA); stk::balance::M2NBalanceSettings balanceSettings(get_output_filename(), get_num_procs_target_decomp()); - EXPECT_NO_THROW(stk::balance::internal::rebalanceMtoN(m_ioBroker, *targetDecompField, balanceSettings)); - } -} - -class Mesh1x1x4 : public MeshFixtureMxNRebalance -{ -protected: - virtual unsigned get_x() const { return 1; } - virtual unsigned get_y() const { return 1; } - virtual unsigned get_z() const { return 4; } - - virtual unsigned get_num_procs_initial_decomp() const { return 2; } - virtual unsigned get_num_procs_target_decomp() const { return 4; } - virtual std::string get_output_filename() const { return "junk.g"; } -}; - -TEST_F(Mesh1x1x4, read2procsWrite4procsFilesUsingGeneratedMesh) -{ - if(stk::parallel_machine_size(get_comm()) == 2) - { - std::vector goldSharedNodesPerSubdomain = - { - {{ 5, 1}, { 6, 1}, { 7, 1}, { 8, 1}}, - {{ 5, 0}, { 6, 0}, { 7, 0}, { 8, 0}, { 9, 2}, {10, 2}, {11, 2}, {12, 2}}, - {{ 9, 1}, {10, 1}, {11, 1}, {12, 1}, {13, 3}, {14, 3}, {15, 3}, {16, 3}}, - {{13, 2}, {14, 2}, {15, 2}, {16, 2}} - }; - - setup_initial_mesh(stk::mesh::BulkData::NO_AUTO_AURA); - - stk::balance::M2NBalanceSettings balanceSettings(get_output_filename(), get_num_procs_target_decomp()); - balanceSettings.setDecompMethod("rcb"); - - stk::balance::internal::M2NDecomposer decomposer(get_bulk(), balanceSettings); - stk::balance::internal::MtoNRebalancer rebalancer(m_ioBroker, *targetDecompField, decomposer, balanceSettings); - - rebalancer.decompose_mesh(); - rebalancer.map_new_subdomains_to_original_processors(); - rebalancer.store_final_decomp_on_elements(); - - for(unsigned subdomain = 0; subdomain < rebalancer.get_owner_for_each_final_subdomain().size(); subdomain++) { - const stk::mesh::Entity elem = get_bulk().get_entity(stk::topology::ELEM_RANK, subdomain+1); - if (get_bulk().is_valid(elem)) { - stk::io::EntitySharingInfo nodeSharingInfo = rebalancer.get_subdomain_creator().get_node_sharing_info(subdomain); - EXPECT_EQ(goldSharedNodesPerSubdomain[subdomain], nodeSharingInfo); - } - } - } -} - -void expect_and_unlink_file(const std::string& baseName, int numProc, int procId) -{ - std::string file0Name = baseName + "." + std::to_string(numProc) + "." + std::to_string(procId); - std::ifstream file0(file0Name); - EXPECT_TRUE(!file0.fail()); - unlink(file0Name.c_str()); -} - -TEST(SomeProcessorsWithNoElements, writeSubdomains_onlyProcsWithElementsWrite) -{ - stk::ParallelMachine comm = MPI_COMM_WORLD; - - const std::string inputMesh = "generated:1x1x4"; - const std::string outputMesh = "reduced.g"; - - if(stk::parallel_machine_size(comm) == 4) - { - stk::mesh::MetaData meta; - stk::mesh::Field &targetDecompField = meta.declare_field >(stk::topology::ELEMENT_RANK, "junk", 1); - stk::mesh::put_field_on_mesh(targetDecompField, meta.universal_part(), static_cast(nullptr)); - stk::mesh::BulkData bulk(meta, comm); - stk::io::fill_mesh(inputMesh, bulk); - - stk::mesh::EntityVector elementsToDestroy; - if(stk::parallel_machine_rank(comm)==0 || stk::parallel_machine_rank(comm)==3) - { - stk::mesh::get_selected_entities(meta.locally_owned_part(), bulk.buckets(stk::topology::ELEM_RANK), elementsToDestroy); - } - stk::mesh::destroy_elements(bulk, elementsToDestroy); - - int includeMe = 0; - int numTarget = 0; - std::tie(includeMe, numTarget) = stk::balance::internal::get_included_and_num_target_procs(bulk, comm); - - EXPECT_EQ(2, numTarget); - - int mySubdomain = stk::balance::internal::get_subdomain_index(includeMe, comm); - - if(stk::parallel_machine_rank(comm)==2) - { - EXPECT_EQ(1, includeMe); - EXPECT_EQ(1, mySubdomain); - } - else if(stk::parallel_machine_rank(comm)==1) - { - EXPECT_EQ(1, includeMe); - EXPECT_EQ(0, mySubdomain); - } - else - { - EXPECT_EQ(0, includeMe); - EXPECT_EQ(-1, mySubdomain); - } - - stk::balance::internal::write_subdomain_files(bulk, numTarget, mySubdomain, outputMesh); - - stk::parallel_machine_barrier(comm); - if(stk::parallel_machine_rank(comm)==0) - { - expect_and_unlink_file(outputMesh, numTarget, 0); - expect_and_unlink_file(outputMesh, numTarget, 1); - } + EXPECT_NO_THROW(stk::balance::m2n::rebalanceMtoN(m_ioBroker, balanceSettings)); } } diff --git a/packages/stk/stk_integration_tests/test_utils/MeshFixtureMxNRebalance.hpp b/packages/stk/stk_integration_tests/test_utils/MeshFixtureMxNRebalance.hpp index f93d8d7d267f..1458f70cc4b9 100644 --- a/packages/stk/stk_integration_tests/test_utils/MeshFixtureMxNRebalance.hpp +++ b/packages/stk/stk_integration_tests/test_utils/MeshFixtureMxNRebalance.hpp @@ -49,8 +49,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -69,7 +69,7 @@ class MeshFixtureMxNRebalance : public stk::unit_test_util::MeshFixture { setup_initial_mesh(stk::mesh::BulkData::NO_AUTO_AURA); stk::balance::M2NBalanceSettings balanceSettings(get_output_filename(), get_num_procs_target_decomp()); - stk::balance::internal::rebalanceMtoN(m_ioBroker, *targetDecompField, balanceSettings); + stk::balance::m2n::rebalanceMtoN(m_ioBroker, balanceSettings); } void setup_initial_mesh(stk::mesh::BulkData::AutomaticAuraOption auraOption) @@ -78,27 +78,10 @@ class MeshFixtureMxNRebalance : public stk::unit_test_util::MeshFixture stk::unit_test_util::generated_mesh_to_file_in_serial(get_generated_mesh_spec(), tempInputFilename); allocate_bulk(auraOption); - create_target_decomp_field_on_entire_mesh(); m_ioBroker.property_add(Ioss::Property("DECOMPOSITION_METHOD", "RCB")); stk::io::fill_mesh_preexisting(m_ioBroker, tempInputFilename, get_bulk()); } - void create_field_on_entire_mesh(const std::string& fieldName) - { - targetDecompField = &get_meta().declare_field >(stk::topology::ELEMENT_RANK, fieldName, 1); - stk::mesh::put_field_on_mesh(*targetDecompField, get_meta().universal_part(), static_cast(nullptr)); - } - - void create_target_decomp_field_on_entire_mesh() - { - create_field_on_entire_mesh(get_target_decomp_field_name()); - } - - const std::string get_target_decomp_field_name() - { - return "Target_Decomp"; - } - void test_decomp() { // Make sure all procs have written their files before p0 tries to read them @@ -213,7 +196,6 @@ class MeshFixtureMxNRebalance : public stk::unit_test_util::MeshFixture virtual unsigned get_num_procs_initial_decomp() const = 0; virtual unsigned get_num_procs_target_decomp() const = 0; - stk::mesh::Field *targetDecompField; stk::io::StkMeshIoBroker m_ioBroker; }; diff --git a/packages/stk/stk_math/stk_math/SideGeometry.cpp b/packages/stk/stk_math/stk_math/SideGeometry.cpp index 3c5bd29a2368..62155c321ff2 100644 --- a/packages/stk/stk_math/stk_math/SideGeometry.cpp +++ b/packages/stk/stk_math/stk_math/SideGeometry.cpp @@ -58,6 +58,14 @@ LineGeometry::LineGeometry(const stk::math::Vector3d & n0, : SideGeometry(2), m_nodeData{n0, n1} {} + +#ifdef __GNUC__ +# if (__GNUC__ == 11) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Warray-bounds" +# define SIERRA_GCC_POP_DIAG +# endif +#endif const stk::math::Vector3d & LineGeometry::node(int index) const @@ -65,6 +73,10 @@ LineGeometry::node(int index) const ThrowAssert(index>=0 && index < 2); return m_nodeData[index]; } + +#ifdef SIERRA_GCC_POP_DIAG +#pragma GCC diagnostic pop +#endif stk::math::Vector3d LineGeometry::centroid() const diff --git a/packages/stk/stk_mesh/stk_mesh/base/BulkData.cpp b/packages/stk/stk_mesh/stk_mesh/base/BulkData.cpp index 863dd790a968..748f32c2475b 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/BulkData.cpp +++ b/packages/stk/stk_mesh/stk_mesh/base/BulkData.cpp @@ -2060,8 +2060,7 @@ void BulkData::dump_all_mesh_info(std::ostream& out) const // Dump output for metadata first m_mesh_meta_data.dump_all_meta_info(out); - out << "BulkData " - << " info...(ptr=" << this << ")\n"; + out << "BulkData (ptr=" << this << ")\n"; // Iterate all buckets for all ranks... const std::vector & rank_names = m_mesh_meta_data.entity_rank_names(); @@ -2722,28 +2721,30 @@ void BulkData::internal_change_entity_owner( const std::vector & arg impl::OnlyVisitGhostsOnce only_visit_ghosts_once(*this); impl::StoreEntity store_entity(*this); - impl::VisitAuraClosureGeneral(*this,ghosted_change.begin(),ghosted_change.end(),store_entity,only_visit_ghosts_once); - impl::VisitAuraClosureGeneral(*this,shared_change.begin(),shared_change.end(),store_entity,only_visit_ghosts_once); - impl::VisitAuraClosureGeneral(*this,send_closure.begin(),send_closure.end(),store_entity,only_visit_ghosts_once); + std::vector& allChanges = ghosted_change; + allChanges.reserve(allChanges.size()+shared_change.size()+send_closure.size()); + allChanges.insert(allChanges.end(), shared_change.begin(), shared_change.end()); + allChanges.insert(allChanges.end(), local_change.begin(), local_change.end()); + impl::VisitAuraClosureGeneral(*this,allChanges.begin(),allChanges.end(),store_entity,only_visit_ghosts_once); std::vector remove_modified_ghosts; - std::vector keysThatAreBothSharedAndCustomGhosted; - store_entity.split_shared(keysThatAreBothSharedAndCustomGhosted, remove_modified_ghosts); - - for (size_t i=0;i empty_add ; + std::vector removesForThisGhosting; + removesForThisGhosting.reserve(remove_modified_ghosts.size()); + const bool notAddingSendGhosts = true; // Skip 'm_ghosting[0]' which is the shared subset. - for ( std::vector::iterator - ig = m_ghosting.begin() + 1; ig != m_ghosting.end() ; ++ig ) { - // parallel synchronous: - internal_change_ghosting( **ig , empty_add , remove_modified_ghosts ); + for (unsigned i=1; i &remove_receive, - std::vector &recvGhosts, std::vector& ghostStatus) +void BulkData::filter_ghosting_remove_receives(const stk::mesh::Ghosting &ghosting, + const std::vector &remove_receive, + std::vector &removeRecvGhosts, + std::vector& ghostStatus) { - // Remove any entities that are in the remove list. - - for ( Entity rmEntity : remove_receive) { - if (is_valid(rmEntity) && in_receive_ghost(ghosting, rmEntity)) { - ghostStatus[rmEntity.local_offset()] = true; - } + for ( Entity rmEntity : remove_receive) { + if (is_valid(rmEntity) && in_receive_ghost(ghosting, rmEntity)) { + ghostStatus[rmEntity.local_offset()] = true; } + } - // Iterate over all entities with communication information, adding - // the entity if it's a ghost on this process. recvGhosts will contain - // all received-ghosts on this process by the end of the loop. - for ( EntityCommListInfoVector::const_iterator - i = internal_comm_list().begin() ; i != internal_comm_list().end() ; ++i ) { - const bool inRemoveReceive = ghostStatus[i->entity.local_offset()]; - if ( is_valid(i->entity) && !inRemoveReceive && in_receive_ghost(ghosting, i->entity) ) { - recvGhosts.push_back(i->entity); - ghostStatus[i->entity.local_offset()] = true; + // Iterate over all entities with communication information, adding + // the entity if it's a ghost on this process. recvGhosts will contain + // all received-ghosts on this process by the end of the loop. + EntityVector recvGhosts; + for ( const EntityCommListInfo& info : internal_comm_list()) { + if (info.entity_comm && info.entity_comm->isGhost) { + const bool inRemoveReceive = ghostStatus[info.entity.local_offset()]; + if ( is_valid(info.entity) && !inRemoveReceive && in_receive_ghost(ghosting, info.entity) ) { + recvGhosts.push_back(info.entity); + ghostStatus[info.entity.local_offset()] = true; } else { - ghostStatus[i->entity.local_offset()] = false; + ghostStatus[info.entity.local_offset()] = false; } } + } - //Add back in the closure-entities of each recv-ghost, if those closure-entities were - //removed due to being in the remove_receive list - // - impl::OnlyRecvGhosts org(*this,ghosting,ghostStatus); - impl::VecPushBack vpb(recvGhosts, ghostStatus); - - unsigned len = recvGhosts.size(); - for (unsigned ii=0; ii stk::topology::ELEM_RANK) { - impl::VisitClosureGeneral(*this, *rels_i, vpb, org); - } - else { - if ( is_valid(*rels_i) && - in_receive_ghost( ghosting , *rels_i ) && !ghostStatus[(*rels_i).local_offset()] ) - { - recvGhosts.push_back(*rels_i); - ghostStatus[(*rels_i).local_offset()] = true; - } + //Add back in the closure-entities of each recv-ghost, if those closure-entities were + //removed due to being in the remove_receive list + impl::OnlyRecvGhosts org(*this,ghosting,ghostStatus); + impl::VecPushBack vpb(recvGhosts, ghostStatus); + + unsigned len = recvGhosts.size(); + for (unsigned ii=0; ii stk::topology::ELEM_RANK) { + impl::VisitClosureGeneral(*this, *rels_i, vpb, org); + } + else { + if ( is_valid(*rels_i) && + in_receive_ghost( ghosting , *rels_i ) && !ghostStatus[(*rels_i).local_offset()] ) + { + recvGhosts.push_back(*rels_i); + ghostStatus[(*rels_i).local_offset()] = true; } } } } + } + + removeRecvGhosts.clear(); + removeRecvGhosts.reserve(remove_receive.size()); + for(Entity entity : remove_receive) { + if (in_receive_ghost(ghosting, entity) && !ghostStatus[entity.local_offset()]) { + removeRecvGhosts.push_back(entity); + } + } } void BulkData::delete_unneeded_entries_from_the_comm_list() @@ -3581,34 +3591,13 @@ void BulkData::internal_change_ghosting( Ghosting & ghosting , const std::vector & add_send , const std::vector & remove_receive, - bool is_full_regen) + bool add_send_is_globally_empty) { m_modSummary.track_change_ghosting(ghosting, add_send, remove_receive); - //------------------------------------ - // Copy ghosting lists into more efficiently edited container. - // The send and receive lists must be in entity rank-order. - - std::set sendGhosts(EntityLess(*this)); - std::vector recvGhosts; - std::vector ghostStatus(get_size_of_entity_index_space(), false); - - //------------------------------------ - // Insert the current ghost receives and then remove from that list. - - // This if-check is an optimization; if doing a full regen then we are - // removing all ghosting information and recvGhosts should be left empty. - if ( !is_full_regen ) { - generate_ghosting_receive_list(ghosting, remove_receive, recvGhosts, ghostStatus); - - // Initialize sendGhosts from recvGhosts - stk::mesh::impl::send_entity_keys_to_owners(*this , recvGhosts , sendGhosts); - } - - //------------------------------------ - // Add the specified entities and their closure to sendGhosts - - impl::StoreInEntityProcSet sieps(*this, sendGhosts); + // put add_send entities and their closure in newSendGhosts + std::set newSendGhosts(EntityLess(*this)); + impl::StoreInEntityProcSet sieps(*this, newSendGhosts); impl::OnlyGhosts og(*this); for ( const EntityProc& entityProc : add_send ) { og.proc = entityProc.second; @@ -3616,84 +3605,70 @@ void BulkData::internal_change_ghosting( impl::VisitClosureGeneral(*this,entityProc.first,sieps,og); } - // Synchronize the send and receive list. - // If the send list contains a not-owned entity - // inform the owner and receiver to add that entity - // to their ghost send and receive lists. + //remove newSendGhosts that are already in comm-list: + for (auto sendGhost = newSendGhosts.begin(); sendGhost != newSendGhosts.end();) { + const EntityKey key = entity_key(sendGhost->first); + const int proc = sendGhost->second; + if (in_send_ghost(ghosting, key, proc)) { + sendGhost = newSendGhosts.erase(sendGhost); + } + else { + ++sendGhost; + } + } + + std::vector removeRecvGhosts; + std::vector ghostStatus(get_size_of_entity_index_space(), false); + filter_ghosting_remove_receives(ghosting, remove_receive, removeRecvGhosts, ghostStatus); - stk::mesh::impl::comm_sync_send_recv( *this , sendGhosts , recvGhosts, ghostStatus ); + std::set removeSendGhosts; - // The sendGhosts list is now parallel complete and parallel accurate - // recvGhosts has those ghost entities that are to be kept. + stk::mesh::impl::comm_sync_send_recv(*this , removeRecvGhosts, newSendGhosts, removeSendGhosts); + + // The newSendGhosts list is now complete //------------------------------------ - // Remove the ghost entities that will not remain. - // If the last reference to the receive ghost entity then delete it. + // Remove comm-info for the send-ghost and receive-ghost entities that will not remain. + // If it is the last reference to the receive-ghost entity then delete it. + + for (const EntityKeyProc& rmSendEntityKeyProc : removeSendGhosts) { + const EntityKey key = rmSendEntityKeyProc.first; + entity_comm_map_erase(key, EntityCommInfo(ghosting.ordinal(), rmSendEntityKeyProc.second)); + } OrdinalVector addParts; OrdinalVector removeParts(1, m_ghost_parts[ghosting.ordinal()]->mesh_meta_data_ordinal()); OrdinalVector scratchOrdinalVec, scratchSpace; - bool removed = false ; - - std::vector comm_ghost ; - for ( EntityCommListInfoVector::reverse_iterator - i = m_entity_comm_list.rbegin() ; i != m_entity_comm_list.rend() ; ++i) { - - if (!i->entity_comm || !i->entity_comm->isGhost) { - continue; - } - - const bool is_owner = parallel_owner_rank(i->entity) == parallel_rank() ; - const bool remove_recv = ( ! is_owner ) && - !ghostStatus[i->entity.local_offset()] && in_receive_ghost(ghosting, i->entity); - - if(is_valid(i->entity)) - { - if ( is_owner ) { - // Is owner, potentially removing ghost-sends - // Have to make a copy - const PairIterEntityComm ec = internal_entity_comm_map(i->entity, ghosting); - comm_ghost.assign( ec.first , ec.second ); - - for ( ; ! comm_ghost.empty() ; comm_ghost.pop_back() ) { - const EntityCommInfo tmp = comm_ghost.back(); - - std::set::iterator iter = - sendGhosts.find(EntityProc(i->entity, tmp.proc)); + std::sort(removeRecvGhosts.begin(), removeRecvGhosts.end(), EntityLess(*this)); - if ( iter == sendGhosts.end() ) { - entity_comm_map_erase(i->key, tmp); - } - else { - sendGhosts.erase(iter); - } - } - } - else if ( remove_recv ) { - entity_comm_map_erase(i->key, ghosting); - internal_change_entity_parts(i->entity, addParts, removeParts, scratchOrdinalVec, scratchSpace); - } + for (unsigned i=0; ientity).empty() ) { - removed = true ; - i->key = EntityKey(); // No longer communicated - if ( remove_recv ) { - ThrowRequireMsg( internal_destroy_entity_with_notification( i->entity, remove_recv ), - "P[" << this->parallel_rank() << "]: FAILED attempt to destroy entity: " - << entity_key(i->entity) ); - } - } + if (internal_entity_comm_map(rmEntity).empty()) { + ThrowRequireMsg( internal_destroy_entity_with_notification(rmEntity, true), "P"<comm_map.empty()) { + info.key = EntityKey(); + } } + delete_unneeded_entries_from_the_comm_list(); - ghost_entities_and_fields(ghosting, sendGhosts, is_full_regen); + if (!add_send_is_globally_empty) { + ghost_entities_and_fields(ghosting, newSendGhosts, false); + } + else { + ThrowRequireMsg(newSendGhosts.empty(), "internal_change_ghosting: add_send_is_globally_empty but newSendGhosts not empty"); + } } //---------------------------------------------------------------------- @@ -3704,12 +3679,6 @@ void BulkData::fill_list_of_entities_to_send_for_aura_ghosting(EntityProcMapping { const EntityRank end_rank = static_cast(m_mesh_meta_data.entity_rank_count()); - std::vector ranks = {stk::topology::NODE_RANK, stk::topology::EDGE_RANK}; - const MetaData& meta = mesh_meta_data(); - if (meta.side_rank() > stk::topology::EDGE_RANK) { - ranks.push_back(meta.side_rank()); - } - // Iterate over all shared entities, ensure that upwardly related // entities to each shared entity will be ghosted to the sharing proc. Selector shared = mesh_meta_data().globally_shared_part(); diff --git a/packages/stk/stk_mesh/stk_mesh/base/BulkData.hpp b/packages/stk/stk_mesh/stk_mesh/base/BulkData.hpp index 7db421126ee7..ee16ffbdaa93 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/BulkData.hpp +++ b/packages/stk/stk_mesh/stk_mesh/base/BulkData.hpp @@ -1050,7 +1050,7 @@ void get_entities(EntityRank rank, Selector const& selector, EntityVector& outpu void internal_change_ghosting( Ghosting & ghosts, const std::vector & add_send , const std::vector & remove_receive, - bool is_full_regen = false); // Mod Mark + bool add_send_is_globally_empty = false); void internal_change_ghosting( Ghosting & ghosts, EntityProcMapping& entityProcMapping, @@ -1290,7 +1290,7 @@ void get_entities(EntityRank rank, Selector const& selector, EntityVector& outpu void delete_buckets(const stk::mesh::BucketVector & buckets); void mark_entities_as_deleted(stk::mesh::Bucket * bucket); - void generate_ghosting_receive_list(const stk::mesh::Ghosting &ghosting, const std::vector &remove_receive, + void filter_ghosting_remove_receives(const stk::mesh::Ghosting &ghosting, const std::vector &remove_receive, std::vector &recvGhosts, std::vector& ghostStatus); void verify_and_filter_add_send(Ghosting & ghosts, const std::vector & add_send, bool &need_to_change_ghosting, diff --git a/packages/stk/stk_mesh/stk_mesh/base/FieldBase.cpp b/packages/stk/stk_mesh/stk_mesh/base/FieldBase.cpp index 7a5af39430cc..365daaa57c25 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/FieldBase.cpp +++ b/packages/stk/stk_mesh/stk_mesh/base/FieldBase.cpp @@ -57,11 +57,7 @@ std::ostream & operator << ( std::ostream & s , const FieldBase & field ) } s << ">" ; - s << "[ name: \"" ; - s << field.name() ; - s << "\" , #states: " ; - s << field.number_of_states(); - s << " ]" ; + s << "[\"" << field.name() << "\", #states: " << field.number_of_states() << "]" ; return s ; } diff --git a/packages/stk/stk_mesh/stk_mesh/baseImpl/MeshImplUtils.cpp b/packages/stk/stk_mesh/stk_mesh/baseImpl/MeshImplUtils.cpp index 3769e8396be0..047bf469d0ff 100644 --- a/packages/stk/stk_mesh/stk_mesh/baseImpl/MeshImplUtils.cpp +++ b/packages/stk/stk_mesh/stk_mesh/baseImpl/MeshImplUtils.cpp @@ -956,8 +956,6 @@ void send_entity_keys_to_owners( } } -// Synchronize the send list to the receive list. - void comm_sync_send_recv( BulkData & mesh , std::set< EntityProc , EntityLess > & sendGhosts , @@ -976,7 +974,7 @@ void comm_sync_send_recv( all.send_buffer( i->second ).skip(1).skip(1); if ( owner != parallel_rank ) { all.send_buffer( owner ).skip(1).skip(1); - } + } } all.allocate_buffers(); @@ -1009,10 +1007,10 @@ void comm_sync_send_recv( // The iterator passed to the erase method will be invalidated. std::set< EntityProc , EntityLess >::iterator jrem = i ; ++i ; sendGhosts.erase( jrem ); - } - else { + } + else { ++i ; - } + } } all.communicate(); @@ -1052,101 +1050,149 @@ void comm_sync_send_recv( } } -void comm_sync_send_recv( - BulkData & mesh , - std::set< EntityProc , EntityLess > & sendGhosts , - std::vector & recvGhosts, - std::vector& ghostStatus ) -{ - const int parallel_rank = mesh.parallel_rank(); - const int parallel_size = mesh.parallel_size(); +struct OwnerEntityReceiver { + OwnerEntityReceiver(int o, Entity e, int r) : owner(o), entity(e), receiver(r){} + int owner; + Entity entity; + int receiver; +}; - stk::CommSparse all( mesh.parallel() ); - - // Communication sizing: +class GhostCommHelper +{ +public: + GhostCommHelper(const BulkData& mesh, + const std::vector& removeRecvGhosts, + std::set< EntityProc, EntityLess> & newSendGhosts) + : m_mesh(mesh), + m_commSparse(mesh.parallel()), + m_rmRecvCounts(mesh.parallel_size(), 0), + m_nonOwnedSendCounts(mesh.parallel_size(), 0), + m_nonOwnedSends() + { + const int myRank = mesh.parallel_rank(); - for ( std::set< EntityProc , EntityLess >::iterator - i = sendGhosts.begin() ; i != sendGhosts.end() ; ++i ) { - const int owner = mesh.parallel_owner_rank(i->first); - all.send_buffer( i->second ).skip(1).skip(1); - if ( owner != parallel_rank ) { - all.send_buffer( owner ).skip(1).skip(1); + for(Entity entity : removeRecvGhosts) { + ++m_rmRecvCounts[mesh.parallel_owner_rank(entity)]; } - } - all.allocate_buffers(); - - // Loop thru all entities in sendGhosts, send the entity key to the sharing/ghosting proc - // Also, if the owner of the entity is NOT me, also send the entity key to the owing proc - - // Communication packing (with message content comments): - for ( std::set< EntityProc , EntityLess >::iterator - i = sendGhosts.begin() ; i != sendGhosts.end() ; ) { - const int owner = mesh.parallel_owner_rank(i->first); - - // Inform receiver of ghosting, the receiver does not own - // and does not share this entity. - // The ghost either already exists or is a to-be-done new ghost. - // This status will be resolved on the final communication pass - // when new ghosts are packed and sent. + for(auto iter = newSendGhosts.begin(); iter != newSendGhosts.end();) { + int owner = mesh.parallel_owner_rank(iter->first); + if (owner != myRank) { + ++m_nonOwnedSendCounts[owner]; + m_nonOwnedSends.emplace_back(owner,iter->first,iter->second); + iter = newSendGhosts.erase(iter); + } + else { + ++iter; + } + } - const Entity entity = i->first; - const EntityKey entity_key = mesh.entity_key(entity); - const int proc = i->second; + auto isLess = [](const OwnerEntityReceiver& lhs, const OwnerEntityReceiver& rhs) + { return lhs.owner < rhs.owner; }; + std::sort(m_nonOwnedSends.begin(), m_nonOwnedSends.end(), isLess); + } - all.send_buffer( proc ).pack(entity_key).pack(proc); + void setup_send_buffers() + { + for(int p=0; p(1); + if (m_rmRecvCounts[p] > 0) { + m_commSparse.send_buffer(p).skip(m_rmRecvCounts[p]); + } + m_commSparse.send_buffer(p).skip(1); + if (m_nonOwnedSendCounts[p] > 0) { + for(unsigned i=0; i(1); + m_commSparse.send_buffer(p).skip(1); + } + } + } - if ( owner != parallel_rank ) { - // I am not the owner of this entity. - // Inform the owner of this ghosting need. - all.send_buffer( owner ).pack(entity_key).pack(proc); + m_commSparse.allocate_buffers(); + } + + void pack_and_communicate_buffers(const std::vector& removeRecvGhosts) + { + unsigned idx = 0; - // Erase it from my processor's ghosting responsibility: - // The iterator passed to the erase method will be invalidated. - std::set< EntityProc , EntityLess >::iterator jrem = i ; ++i ; - sendGhosts.erase( jrem ); + for(int p=0; p(m_rmRecvCounts[p]); + if (m_rmRecvCounts[p] > 0) { + for(Entity entity : removeRecvGhosts) { + int owner = m_mesh.parallel_owner_rank(entity); + if (p == owner) { + buf.pack(m_mesh.entity_key(entity)); + } + } + } + + buf.pack(m_nonOwnedSendCounts[p]); + if (m_nonOwnedSendCounts[p] > 0) { + for(unsigned i=idx; i(m_mesh.entity_key(ent)); + buf.pack(proc); + } + idx += m_nonOwnedSendCounts[p]; + } } - else { - ++i ; + + m_commSparse.communicate(); + } + + void unpack_recv_buffers(std::set& newSendGhosts, + std::set& removeSendGhosts) + { + for ( int p = 0 ; p < m_commSparse.parallel_size() ; ++p ) { + CommBuffer & buf = m_commSparse.recv_buffer(p); + unsigned numRemoveSends = 0; + buf.unpack(numRemoveSends); + + for(unsigned i=0; i(key); + removeSendGhosts.insert(EntityKeyProc(key,p)); + } + + unsigned numReferredSends = 0; + buf.unpack(numReferredSends); + for(unsigned i=0; i(key); + int proc = 0; + buf.unpack(proc); + Entity entity = m_mesh.get_entity(key); + ThrowRequireMsg(m_mesh.is_valid(entity), "Recvd invalid entity key"); + newSendGhosts.insert(EntityProc(entity,proc)); + } } } - all.communicate(); - - // Loop thru all the buffers, and insert ghosting request for entity e to other proc - // if the proc sending me the data is me, then insert into recvGhosts. - // Communication unpacking: - for ( int p = 0 ; p < parallel_size ; ++p ) { - CommBuffer & buf = all.recv_buffer(p); - while ( buf.remaining() ) { - - EntityKey entity_key; - int proc = 0; +private: + const BulkData& m_mesh; + CommSparse m_commSparse; + std::vector m_rmRecvCounts; + std::vector m_nonOwnedSendCounts; + std::vector m_nonOwnedSends; +}; + +void comm_sync_send_recv(const BulkData & mesh , + const std::vector& removeRecvGhosts, + std::set< EntityProc, EntityLess> & newSendGhosts, + std::set< EntityKeyProc> & removeSendGhosts) +{ + GhostCommHelper commHelper(mesh, removeRecvGhosts, newSendGhosts); - buf.unpack(entity_key).unpack(proc); + commHelper.setup_send_buffers(); - Entity const e = mesh.get_entity( entity_key ); + commHelper.pack_and_communicate_buffers(removeRecvGhosts); - if ( parallel_rank != proc ) { - // Receiving a ghosting need for an entity I own. - // Add it to my send list. - ThrowRequireMsg(mesh.is_valid(e), - "Unknown entity key: " << - mesh.mesh_meta_data().entity_rank_name(entity_key.rank()) << - "[" << entity_key.id() << "]"); - EntityProc tmp( e , proc ); - sendGhosts.insert( tmp ); - } - else if ( mesh.is_valid(e) ) { - // I am the receiver for this ghost. - // If I already have it add it to the receive list, - // otherwise don't worry about it - I will receive - // it in the final new-ghosting communication. - recvGhosts.push_back( e ); - ghostStatus[e.local_offset()] = true; - } - } - } + commHelper.unpack_recv_buffers(newSendGhosts, removeSendGhosts); } void comm_sync_aura_send_recv( diff --git a/packages/stk/stk_mesh/stk_mesh/baseImpl/MeshImplUtils.hpp b/packages/stk/stk_mesh/stk_mesh/baseImpl/MeshImplUtils.hpp index e8f45534e9c2..f066b1fd622d 100644 --- a/packages/stk/stk_mesh/stk_mesh/baseImpl/MeshImplUtils.hpp +++ b/packages/stk/stk_mesh/stk_mesh/baseImpl/MeshImplUtils.hpp @@ -207,10 +207,10 @@ void comm_sync_send_recv( std::set< EntityKey > & new_recv ); void comm_sync_send_recv( - BulkData & mesh , - std::set< EntityProc , EntityLess > & new_send , - std::vector & new_recv, - std::vector& ghostStatus ); + const BulkData & mesh , + const std::vector& removeRecvGhosts, + std::set< EntityProc, EntityLess> & newSendGhosts, + std::set< EntityKeyProc> & removeSendGhosts); void comm_sync_aura_send_recv( BulkData & mesh , diff --git a/packages/stk/stk_mesh/stk_mesh/baseImpl/MeshPrintUtils.cpp b/packages/stk/stk_mesh/stk_mesh/baseImpl/MeshPrintUtils.cpp index b41d3daa3370..100a2c2e1f68 100644 --- a/packages/stk/stk_mesh/stk_mesh/baseImpl/MeshPrintUtils.cpp +++ b/packages/stk/stk_mesh/stk_mesh/baseImpl/MeshPrintUtils.cpp @@ -100,7 +100,7 @@ void print_field_data_for_entity(const BulkData& mesh, const MeshIndex& meshInde unsigned data_size = field_meta_data.m_bytes_per_entity; if (data_size > 0) { // entity has this field? void* data = field_meta_data.m_data + field_meta_data.m_bytes_per_entity * b_ord; - out << " For field: " << *field << ", has data: "; + out << " " << *field << ", "; field->print_data(out, data, data_size); out << std::endl; } @@ -133,7 +133,7 @@ void print_entity_connectivity(const BulkData& mesh, const MeshIndex& meshIndex, if (b_rank != stk::topology::NODE_RANK) { Permutation const *permutations = bucket->begin_permutations(b_ord, r); if (permutations) { - out << " permutation index " << permutations[c_itr]; + out << " permutation " << permutations[c_itr]; } } } @@ -145,7 +145,7 @@ void print_entity_connectivity(const BulkData& mesh, const MeshIndex& meshIndex, void print_bucket_parts(const BulkData& mesh, const Bucket* bucket, std::ostream& out) { - out << " Found bucket " << bucket->bucket_id() << " with superset parts: { "; + out << " bucket " << bucket->bucket_id() << " parts: { "; const PartVector& supersets = bucket->supersets(); for(const Part* part : supersets) { out << part->name() << " "; diff --git a/packages/stk/stk_mesh/stk_mesh/baseImpl/elementGraph/ElemElemGraph.cpp b/packages/stk/stk_mesh/stk_mesh/baseImpl/elementGraph/ElemElemGraph.cpp index 403dfa29410c..58dc370527ee 100644 --- a/packages/stk/stk_mesh/stk_mesh/baseImpl/elementGraph/ElemElemGraph.cpp +++ b/packages/stk/stk_mesh/stk_mesh/baseImpl/elementGraph/ElemElemGraph.cpp @@ -137,21 +137,21 @@ void ElemElemGraph::fill_from_mesh() GraphInfo graphInfo(m_graph, m_parallelInfoForGraphEdges, m_element_topologies); remove_graph_edges_blocked_by_shell(graphInfo); - update_number_of_parallel_edges(); m_modCycleWhenGraphModified = m_bulk_data.synchronized_count(); } -void ElemElemGraph::update_number_of_parallel_edges() +size_t ElemElemGraph::num_parallel_edges() const { - m_num_parallel_edges = 0; + size_t numParallelEdges = 0; for (size_t i = 0; i < m_graph.get_num_elements_in_graph(); ++i) { const GraphEdgesForElement& graphEdges = m_graph.get_edges_for_element(i); for (const GraphEdge& graphEdge : graphEdges) { if (!graphEdge.is_elem2_local()) { - ++m_num_parallel_edges; + ++numParallelEdges; } } } + return numParallelEdges; } ElemElemGraph::~ElemElemGraph() {} @@ -243,7 +243,6 @@ int ElemElemGraph::size_data_members() m_idMapper.initialize(m_bulk_data); - m_num_parallel_edges = 0; return numElems; } @@ -253,7 +252,6 @@ void ElemElemGraph::clear_data_members() m_idMapper.clear(); m_element_topologies.clear(); m_any_shell_elements_exist = false; - m_num_parallel_edges = 0; m_parallelInfoForGraphEdges.clear(); m_modCycleWhenGraphModified = m_bulk_data.synchronized_count(); m_deleted_element_local_id_pool.clear(); @@ -1296,7 +1294,6 @@ void ElemElemGraph::delete_elements(const stk::mesh::impl::DeletedElementInfoVec reconnect_volume_elements_across_deleted_shells(shellConnectivityList); } - update_number_of_parallel_edges(); m_modCycleWhenGraphModified = m_bulk_data.synchronized_count(); } @@ -1454,7 +1451,6 @@ void ElemElemGraph::add_elements(const stk::mesh::EntityVector &allUnfilteredEle unpack_remote_edge_across_shell(comm); } - update_number_of_parallel_edges(); m_modCycleWhenGraphModified = m_bulk_data.synchronized_count(); } diff --git a/packages/stk/stk_mesh/stk_mesh/baseImpl/elementGraph/ElemElemGraph.hpp b/packages/stk/stk_mesh/stk_mesh/baseImpl/elementGraph/ElemElemGraph.hpp index c9657430e468..a26ffa85cb07 100644 --- a/packages/stk/stk_mesh/stk_mesh/baseImpl/elementGraph/ElemElemGraph.hpp +++ b/packages/stk/stk_mesh/stk_mesh/baseImpl/elementGraph/ElemElemGraph.hpp @@ -136,7 +136,7 @@ class ElemElemGraph size_t num_edges() const; - size_t num_parallel_edges() const { return m_num_parallel_edges; } + size_t num_parallel_edges() const; void add_elements(const stk::mesh::EntityVector &elements); @@ -223,7 +223,6 @@ class ElemElemGraph protected: void fill_graph(); - void update_number_of_parallel_edges(); void fill_parallel_graph(impl::ElemSideToProcAndFaceId & elementSidesToSend, SideNodeToReceivedElementDataMap & elementSidesReceived); void create_parallel_graph_edge(const impl::ParallelElementData &elementData, const stk::mesh::impl::ParallelElementData &remoteElementData, @@ -311,7 +310,6 @@ class ElemElemGraph std::vector m_element_topologies; bool m_any_shell_elements_exist; std::vector m_deleted_elem_pool; - size_t m_num_parallel_edges; impl::SparseGraph m_coincidentGraph; impl::ElementLocalIdMapper m_idMapper; private: diff --git a/packages/stk/stk_performance_tests/stk_mesh/NgpMeshUpdate.cpp b/packages/stk/stk_performance_tests/stk_mesh/NgpMeshUpdate.cpp index 9793947fc29e..29adad4a96ce 100644 --- a/packages/stk/stk_performance_tests/stk_mesh/NgpMeshUpdate.cpp +++ b/packages/stk/stk_performance_tests/stk_mesh/NgpMeshUpdate.cpp @@ -65,6 +65,13 @@ class NgpMeshChangeElementPartMembership : public stk::unit_test_util::MeshFixtu stk::mesh::get_updated_ngp_mesh(get_bulk()); } + void batch_change_element_part_membership(int cycle) + { + get_bulk().batch_change_entity_parts(stk::mesh::EntityVector{get_element(cycle)}, + stk::mesh::PartVector{get_part()}, {}); + stk::mesh::get_updated_ngp_mesh(get_bulk()); + } + private: stk::mesh::Entity get_element(int cycle) { @@ -72,7 +79,7 @@ class NgpMeshChangeElementPartMembership : public stk::unit_test_util::MeshFixtu return get_bulk().get_entity(stk::topology::ELEM_RANK, elemId); } - const stk::mesh::Part* get_part() + stk::mesh::Part* get_part() { return get_meta().get_part(newPartName); } @@ -153,7 +160,7 @@ class NgpMeshGhosting : public stk::unit_test_util::MeshFixture TEST_F( NgpMeshChangeElementPartMembership, Timing ) { - if (get_parallel_size() != 1) return; + if (get_parallel_size() != 1) { GTEST_SKIP(); } const int NUM_RUNS = 200; @@ -168,6 +175,23 @@ TEST_F( NgpMeshChangeElementPartMembership, Timing ) timer.print_timing(NUM_RUNS); } +TEST_F( NgpMeshChangeElementPartMembership, TimingBatch ) +{ + if (get_parallel_size() != 1) { GTEST_SKIP(); } + + const int NUM_RUNS = 200; + + stk::performance_tests::Timer timer(get_comm()); + timer.start_timing(); + setup_host_mesh(); + + for (int i=0; i &entityRanks) - : m_inputBroker(inputBroker), - m_numSubDomain(numSubDomain), - m_entityRanks(entityRanks) -{ -} - MtoNTransientFieldTransferById::~MtoNTransientFieldTransferById() { for (auto & writerPair : m_subdomainWriters) { diff --git a/packages/stk/stk_tools/stk_tools/transfer_utils/MtoNTransientFieldTransferById.hpp b/packages/stk/stk_tools/stk_tools/transfer_utils/MtoNTransientFieldTransferById.hpp index 8d313945d898..cd91a2ec26c0 100644 --- a/packages/stk/stk_tools/stk_tools/transfer_utils/MtoNTransientFieldTransferById.hpp +++ b/packages/stk/stk_tools/stk_tools/transfer_utils/MtoNTransientFieldTransferById.hpp @@ -250,9 +250,6 @@ class MtoNTransientFieldTransferById public: MtoNTransientFieldTransferById(stk::io::StkMeshIoBroker &inputBroker, unsigned numSubDomain); - MtoNTransientFieldTransferById(stk::io::StkMeshIoBroker &inputBroker, unsigned numSubDomain, - const std::vector &entityRanks); - ~MtoNTransientFieldTransferById(); void setup_subdomain(M2NOutputSerializerBulkData& bulk, const std::string &filename, diff --git a/packages/stk/stk_tools/stk_tools/transfer_utils/TransientFieldTransferById.cpp b/packages/stk/stk_tools/stk_tools/transfer_utils/TransientFieldTransferById.cpp index 256e5e10dee2..16226fcaeccf 100644 --- a/packages/stk/stk_tools/stk_tools/transfer_utils/TransientFieldTransferById.cpp +++ b/packages/stk/stk_tools/stk_tools/transfer_utils/TransientFieldTransferById.cpp @@ -109,15 +109,6 @@ TransientFieldTransferById::TransientFieldTransferById(stk::io::StkMeshIoBroker } } -TransientFieldTransferById::TransientFieldTransferById(stk::io::StkMeshIoBroker &brokerA, - stk::io::StkMeshIoBroker &brokerB, - const std::vector &entityRanks) - : mBrokerA(brokerA), - mBrokerB(brokerB) -{ - initialize(entityRanks); -} - TransientFieldTransferById::~TransientFieldTransferById() { for (unsigned i = 0; i < mTransfers.size(); i++) { diff --git a/packages/stk/stk_tools/stk_tools/transfer_utils/TransientFieldTransferById.hpp b/packages/stk/stk_tools/stk_tools/transfer_utils/TransientFieldTransferById.hpp index cac02b7677e8..2452d02b2247 100644 --- a/packages/stk/stk_tools/stk_tools/transfer_utils/TransientFieldTransferById.hpp +++ b/packages/stk/stk_tools/stk_tools/transfer_utils/TransientFieldTransferById.hpp @@ -182,8 +182,6 @@ class TransientFieldTransferById public: TransientFieldTransferById(stk::io::StkMeshIoBroker &brokerA, stk::io::StkMeshIoBroker &brokerB); - TransientFieldTransferById(stk::io::StkMeshIoBroker &brokerA, stk::io::StkMeshIoBroker &brokerB, const std::vector &entityRanks); - ~TransientFieldTransferById(); void writeFields(size_t aOutFileIndex, std::vector & aTransientFields, std::vector & aGlobalVariableNames); diff --git a/packages/stk/stk_topology/stk_topology/topology_detail/fill_container.hpp b/packages/stk/stk_topology/stk_topology/topology_detail/fill_container.hpp index 7f44ef1306f0..2553d29f28b9 100644 --- a/packages/stk/stk_topology/stk_topology/topology_detail/fill_container.hpp +++ b/packages/stk/stk_topology/stk_topology/topology_detail/fill_container.hpp @@ -83,6 +83,14 @@ struct fill_ordinal_container< std::vector > typename std::vector::iterator m_itr; }; + +#ifdef __GNUC__ +# if (__GNUC__ == 11) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Warray-bounds" +# define SIERRA_GCC_POP_DIAG +# endif +#endif template struct fill_node_container { @@ -101,6 +109,10 @@ struct fill_node_container { const NodeArray & m_nodes; NodeOutputIterator m_itr; }; + +#ifdef SIERRA_GCC_POP_DIAG +#pragma GCC diagnostic pop +#endif template struct fill_node_container > { diff --git a/packages/stk/stk_unit_tests/stk_balance/MeshFixtureM2NDecomposer.hpp b/packages/stk/stk_unit_tests/stk_balance/MeshFixtureM2NDecomposer.hpp index 34ecd2ae6b33..b0ecd0d0496f 100644 --- a/packages/stk/stk_unit_tests/stk_balance/MeshFixtureM2NDecomposer.hpp +++ b/packages/stk/stk_unit_tests/stk_balance/MeshFixtureM2NDecomposer.hpp @@ -35,9 +35,9 @@ #define MESHFIXTUREM2NDECOMPOSER_HPP #include -#include +#include #include -#include +#include #include #include #include @@ -111,7 +111,7 @@ class MeshFixtureM2NDecomposer : public stk::unit_test_util::MeshFixture return stk::is_true_on_all_procs(get_comm(), isNested); } - stk::balance::internal::M2NDecomposer * m_decomposer; + stk::balance::m2n::M2NDecomposer * m_decomposer; stk::balance::M2NBalanceSettings m_balanceSettings; }; diff --git a/packages/stk/stk_unit_tests/stk_balance/MeshFixtureM2NRebalance.hpp b/packages/stk/stk_unit_tests/stk_balance/MeshFixtureM2NRebalance.hpp index 5528bfd11838..c72791a93c97 100644 --- a/packages/stk/stk_unit_tests/stk_balance/MeshFixtureM2NRebalance.hpp +++ b/packages/stk/stk_unit_tests/stk_balance/MeshFixtureM2NRebalance.hpp @@ -35,7 +35,7 @@ #define MESHFIXTUREM2NREBALANCE_HPP #include -#include +#include #include #include #include diff --git a/packages/stk/stk_unit_tests/stk_balance/UnitTestM2NNestedDecomposition.cpp b/packages/stk/stk_unit_tests/stk_balance/UnitTestM2NNestedDecomposition.cpp index df0792fe804e..256fe895361b 100644 --- a/packages/stk/stk_unit_tests/stk_balance/UnitTestM2NNestedDecomposition.cpp +++ b/packages/stk/stk_unit_tests/stk_balance/UnitTestM2NNestedDecomposition.cpp @@ -43,7 +43,7 @@ class M2NDefaultDecomposer : public MeshFixtureM2NDecomposer m_balanceSettings.set_input_filename("junk.g"); m_balanceSettings.set_num_output_processors(numFinalProcs); - m_decomposer = new stk::balance::internal::M2NDecomposer(get_bulk(), m_balanceSettings); + m_decomposer = new stk::balance::m2n::M2NDecomposer(get_bulk(), m_balanceSettings); } }; @@ -102,7 +102,7 @@ class M2NNestedDecomposer : public MeshFixtureM2NDecomposer m_balanceSettings.set_input_filename("junk.g"); m_balanceSettings.set_num_output_processors(numFinalProcs); - m_decomposer = new stk::balance::internal::M2NDecomposerNested(get_bulk(), m_balanceSettings); + m_decomposer = new stk::balance::m2n::M2NDecomposerNested(get_bulk(), m_balanceSettings); } }; @@ -204,7 +204,7 @@ class M2NDefaultRebalance : public MeshFixtureM2NRebalance balanceSettings.setDecompMethod("rcb"); stk::EnvData::instance().m_outputP0 = &stk::EnvData::instance().m_outputNull; - stk::balance::internal::rebalanceMtoN(m_ioBroker, *m_targetDecompField, balanceSettings); + stk::balance::m2n::rebalanceMtoN(m_ioBroker, balanceSettings); stk::EnvData::instance().m_outputP0 = &std::cout; } }; @@ -249,7 +249,7 @@ class M2NNestedRebalance : public MeshFixtureM2NRebalance balanceSettings.setDecompMethod("rcb"); stk::EnvData::instance().m_outputP0 = &stk::EnvData::instance().m_outputNull; - stk::balance::internal::rebalanceMtoN(m_ioBroker, *m_targetDecompField, balanceSettings); + stk::balance::m2n::rebalanceMtoN(m_ioBroker, balanceSettings); stk::EnvData::instance().m_outputP0 = &std::cout; } }; diff --git a/packages/stk/stk_unit_tests/stk_balance/UnitTestM2NRebalance.cpp b/packages/stk/stk_unit_tests/stk_balance/UnitTestM2NRebalance.cpp index 0019d5244e84..b74c10b20cd6 100644 --- a/packages/stk/stk_unit_tests/stk_balance/UnitTestM2NRebalance.cpp +++ b/packages/stk/stk_unit_tests/stk_balance/UnitTestM2NRebalance.cpp @@ -47,7 +47,7 @@ class M2NRebalance : public MeshFixtureM2NRebalance balanceSettings.setDecompMethod("rcb"); stk::EnvData::instance().m_outputP0 = &stk::EnvData::instance().m_outputNull; - stk::balance::internal::rebalanceMtoN(m_ioBroker, *m_targetDecompField, balanceSettings); + stk::balance::m2n::rebalanceMtoN(m_ioBroker, balanceSettings); stk::EnvData::instance().m_outputP0 = &std::cout; } }; diff --git a/packages/stk/stk_unit_tests/stk_balance/UnitTestM2NRebalanceTransientFieldData.cpp b/packages/stk/stk_unit_tests/stk_balance/UnitTestM2NRebalanceTransientFieldData.cpp index 171f31a905d7..96ae96660921 100644 --- a/packages/stk/stk_unit_tests/stk_balance/UnitTestM2NRebalanceTransientFieldData.cpp +++ b/packages/stk/stk_unit_tests/stk_balance/UnitTestM2NRebalanceTransientFieldData.cpp @@ -47,7 +47,7 @@ class M2NRebalanceTransientFieldData : public MeshFixtureM2NRebalance balanceSettings.setDecompMethod("rcb"); stk::EnvData::instance().m_outputP0 = &stk::EnvData::instance().m_outputNull; - stk::balance::internal::rebalanceMtoN(m_ioBroker, *m_targetDecompField, balanceSettings); + stk::balance::m2n::rebalanceMtoN(m_ioBroker, balanceSettings); stk::EnvData::instance().m_outputP0 = &std::cout; } }; diff --git a/packages/stk/stk_unit_tests/stk_mesh/UnitTestBulkData_new.cpp b/packages/stk/stk_unit_tests/stk_mesh/UnitTestBulkData_new.cpp index 2172954adb7a..8f35f0b2e9c0 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/UnitTestBulkData_new.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/UnitTestBulkData_new.cpp @@ -74,18 +74,6 @@ using namespace stk::mesh; namespace { -void new_insert_transitive_closure( BulkData& bulk_data, std::set & , - const EntityProc & entry ); -void new_comm_sync_send_recv( - BulkData & mesh , - std::set< EntityProc , EntityLess > & new_send , - std::set< Entity , EntityLess > & new_recv ); - -void new_comm_recv_to_send( - BulkData & mesh , - const std::set< Entity , EntityLess > & new_recv , - std::set< EntityProc , EntityLess > & new_send ); - /** * The customized box fixture used in this file for testing. This fixture * is similar to the BoxFixture it inherits from, with the only difference @@ -753,221 +741,6 @@ TEST ( UnitTestBulkData_new , verifyBoxGhosting ) } } -TEST ( UnitTestBulkData_new , testEntityComm ) -{ - //08-18-14 Patrick Xavier, Flint Pierce - This test needs to be rewritten as it tests nothing after comm - //Test on unpack_field_values in EntityComm.cpp - //code based on ../base/BulkDataGhosting.cpp - //Create a simple mesh. Add nodes one element and some parts. - - const int spatial_dimension = 3; - - MetaData fem_meta(spatial_dimension); - - stk::mesh::Part & part_a = fem_meta.declare_part_with_topology( "block_a", stk::topology::TET_4 ); - stk::mesh::Part & part_b = fem_meta.declare_part_with_topology( "block_b", stk::topology::TET_4 ); - - stk::mesh::Part & part_a_0 = fem_meta.declare_part_with_topology( "block_a_0", stk::topology::NODE ); - - typedef Field ScalarFieldType; - - ScalarFieldType & volume = - fem_meta.declare_field < ScalarFieldType > ( stk::topology::ELEMENT_RANK, "volume" , 4 ); - ScalarFieldType & temperature = - fem_meta.declare_field < ScalarFieldType > ( stk::topology::ELEMENT_RANK, "temperature" , 4 ); - Part & universal = fem_meta.universal_part (); - put_field_on_mesh ( volume , universal , - (stk::mesh::FieldTraits::data_type*) nullptr); - put_field_on_mesh ( temperature , universal , - (stk::mesh::FieldTraits::data_type*) nullptr); - - fem_meta.commit(); - - PartVector create_vector; - PartVector empty_vector; - create_vector.push_back ( &part_a ); - create_vector.push_back ( &part_b ); - - BulkData bulk ( fem_meta , MPI_COMM_WORLD , stk::mesh::BulkData::AUTO_AURA ); - - bulk.modification_begin(); - - Ghosting &ghosts = bulk.create_ghosting ( "Ghost 1" ); - - int size2 = stk::parallel_machine_size( MPI_COMM_WORLD ); - int rank_count2 = stk::parallel_machine_rank( MPI_COMM_WORLD ); - int new_id2 = size2 + rank_count2; - - Entity elem2 = bulk.declare_element(new_id2+1 ,create_vector); - ASSERT_EQ( bulk.bucket(elem2).member ( part_a ), true ); - - int size = stk::parallel_machine_size( MPI_COMM_WORLD ); - int rank_count = stk::parallel_machine_rank( MPI_COMM_WORLD ); - - int id_base = 0; - for ( id_base = 0 ; id_base < 99 ; ++id_base ) - { - int new_id = size * id_base + rank_count; - Entity new_node = bulk.declare_node(new_id+1 , empty_vector); - ASSERT_EQ( bulk.bucket(new_node).member ( part_a_0 ), false ); - } - - //Create a bucket of nodes for sending - - std::vector add_send; - - const BucketVector & buckets = bulk.buckets( stk::topology::NODE_RANK ); - - BucketVector::const_iterator cur_bucket; - - cur_bucket = buckets.begin(); - - int send_rank = 0; - while ( cur_bucket != buckets.end() ) - { - Bucket::iterator cur_entity = (*cur_bucket)->begin(); - while ( cur_entity != (*cur_bucket)->end() ) - { - if ( bulk.parallel_owner_rank(*cur_entity) == rank_count ) - { - if ( send_rank == size ) send_rank = 0; - if ( send_rank != rank_count ) - add_send.push_back ( std::make_pair ( *cur_entity , send_rank ) ); - ++send_rank; - } - ++cur_entity; - } - ++cur_bucket; - } - - EntityLess entless(bulk); - std::set< EntityProc , EntityLess > new_send(entless) ; - std::set< Entity , EntityLess > new_recv(entless) ; - - // Keep the closure of the remaining received ghosts. - // Working from highest-to-lowest key (rank entity type) - // results in insertion of the transitive closure. - // Insertion will not invalidate the associative container's iterator. - - for ( std::set< Entity , EntityLess >::iterator - i = new_recv.end() ; i != new_recv.begin() ; ) { - --i ; - - const EntityRank erank = bulk.entity_rank(*i); - - MeshIndex mesh_idx = bulk.mesh_index(*i); - Bucket &bkt = *mesh_idx.bucket; - Ordinal bkt_ordinal = mesh_idx.bucket_ordinal; - - for (EntityRank irank = stk::topology::BEGIN_RANK; - irank < erank; - ++irank) - { - Entity const *irels_itr = bkt.begin(bkt_ordinal, irank); - Entity const *irels_end = bkt.end(bkt_ordinal, irank); - for (; irels_itr != irels_end; ++irels_itr) - { - if (bulk.in_receive_ghost( ghosts , bulk.entity_key(*irels_itr) ) ) - { - new_recv.insert( *irels_itr ); - } - } - } - } - - // Initialize the new_send from the new_recv - new_comm_recv_to_send( bulk , new_recv , new_send ); - - //------------------------------------ - // Add the specified entities and their closure to the send ghosting - - for ( std::vector< EntityProc >::const_iterator - i = add_send.begin() ; i != add_send.end() ; ++i ) { - new_insert_transitive_closure( bulk, new_send , *i ); - } - - // Synchronize the send and receive list. - // If the send list contains a not-owned entity - // inform the owner and receiver to ad that entity - // to their ghost send and receive lists. - - new_comm_sync_send_recv( bulk , new_send , new_recv ); - - //------------------------------------ - // Push newly ghosted entities to the receivers and update the comm list. - // Unpacking must proceed in entity-rank order so that higher ranking - // entities that have relations to lower ranking entities will have - // the lower ranking entities unpacked first. The higher and lower - // ranking entities may be owned by different processes, - // as such unpacking must be performed in rank order. - - //Start of CommSparse section: - { - stk::CommSparse comm(MPI_COMM_WORLD); - - for ( std::set< EntityProc , EntityLess >::iterator - j = new_send.begin(); j != new_send.end() ; ++j ) { - Entity entity = j->first ; - if ( ! bulk.in_ghost( ghosts , bulk.entity_key(entity) , j->second ) ) { - // Not already being sent , must send it. - stk::CommBuffer & buf = comm.send_buffer( j->second ); - buf.pack( bulk.entity_rank(entity) ); - pack_entity_info(bulk, buf , entity ); - pack_field_values(bulk, buf , entity ); - } - } - - comm.allocate_buffers(); - - for ( std::set< EntityProc , EntityLess >::iterator - j = new_send.begin(); j != new_send.end() ; ++j ) { - Entity entity = j->first; - if ( ! bulk.in_ghost( ghosts , bulk.entity_key(entity) , j->second ) ) { - // Not already being sent , must send it. - stk::CommBuffer & buf = comm.send_buffer( j->second ); - buf.pack( bulk.entity_rank(entity) ); - pack_entity_info(bulk, buf , entity ); - pack_field_values(bulk, buf , entity ); - - } - } - - comm.communicate(); - - std::ostringstream error_msg ; - - for ( int rank = 0 ; rank < rank_count ; ++rank ) { - - for ( int p = 0 ; p < size ; ++p ) { - - stk::CommBuffer & buf = comm.recv_buffer(p); - - while ( buf.remaining() ) { - - // Only unpack if of the current entity rank. - // If not the current entity rank, break the iteration - // until a subsequent entity rank iteration. - { - int this_rank = ~0u ; - buf.peek( this_rank ); - if ( this_rank != rank ) break ; - - buf.unpack( this_rank ); - } - - // FIXME for Carol; the code below did not work with -np 4 - //ASSERT_EQ( unpack_field_values( buf , elem2 , error_msg ), false); - //std::cout << "Error message for unpack_field_values = " << error_msg.str() << std::endl ; - - } - } - - } - }//end of CommSparse section - - //bulk.modification_end (); -} - TEST ( UnitTestBulkData_new , testUninitializedMetaData ) { stk::ParallelMachine pm = MPI_COMM_WORLD; @@ -984,167 +757,6 @@ TEST ( UnitTestBulkData_new , testUninitializedMetaData ) ASSERT_THROW( bulk.declare_node(1, PartVector()), std::logic_error); } -namespace { - -void new_insert_transitive_closure( BulkData& bulk_data, std::set & new_send , - const EntityProc & entry ) -{ - // Do not insert if I can determine that this entity is already - // owned or shared by the receiving processor. - - if ( entry.second != bulk_data.parallel_owner_rank(entry.first) && - ! bulk_data.in_shared( bulk_data.entity_key(entry.first), entry.second ) ) { - - std::pair< std::set::iterator , bool > - result = new_send.insert( entry ); - - if ( result.second ) { - // A new insertion, must also insert the closure - - const EntityRank erank = bulk_data.entity_rank(entry.first); - - for (EntityRank irank = stk::topology::BEGIN_RANK; irank < erank; ++irank) - { - Entity const *rels_i = bulk_data.begin(entry.first, irank); - Entity const *rels_e = bulk_data.end(entry.first, irank); - for ( ; rels_i != rels_e; ++rels_i) - { - EntityProc tmp( *rels_i , entry.second ); - new_insert_transitive_closure( bulk_data, new_send , tmp ); - } - } - } - } -} - - -// Synchronize the send list to the receive list. - -void new_comm_sync_send_recv( - BulkData & mesh , - std::set< EntityProc , EntityLess > & new_send , - std::set< Entity , EntityLess > & new_recv ) -{ - const int parallel_rank = mesh.parallel_rank(); - const int parallel_size = mesh.parallel_size(); - - stk::CommSparse all( mesh.parallel() ); - - // Communication sizing: - - for ( std::set< EntityProc , EntityLess >::iterator - i = new_send.begin() ; i != new_send.end() ; ++i ) { - const int owner = mesh.parallel_owner_rank(i->first); - all.send_buffer( i->second ).skip(1).skip(1); - if ( owner != parallel_rank ) { - all.send_buffer( owner ).skip(1).skip(1); - } - } - - all.allocate_buffers(); - - // Communication packing (with message content comments): - for ( std::set< EntityProc , EntityLess >::iterator - i = new_send.begin() ; i != new_send.end() ; ) { - const int owner = mesh.parallel_owner_rank(i->first); - - // Inform receiver of ghosting, the receiver does not own - // and does not share this entity. - // The ghost either already exists or is a to-be-done new ghost. - // This status will be resolved on the final communication pass - // when new ghosts are packed and sent. - - const EntityKey entity_key = mesh.entity_key(i->first); - const int proc = i->second; - - all.send_buffer( i->second ).pack(entity_key).pack(proc); - - if ( owner != parallel_rank ) { - // I am not the owner of this entity. - // Inform the owner of this ghosting need. - all.send_buffer( owner ).pack(entity_key).pack(proc); - - // Erase it from my processor's ghosting responsibility: - // The iterator passed to the erase method will be invalidated. - std::set< EntityProc , EntityLess >::iterator jrem = i ; ++i ; - new_send.erase( jrem ); - } - else { - ++i ; - } - } - - all.communicate(); - - // Communication unpacking: - for ( int p = 0 ; p < parallel_size ; ++p ) { - stk::CommBuffer & buf = all.recv_buffer(p); - while ( buf.remaining() ) { - - EntityKey entity_key; - int proc = 0; - - buf.unpack(entity_key).unpack(proc); - - Entity const e = mesh.get_entity( entity_key ); - - if ( parallel_rank != proc ) { - // Receiving a ghosting need for an entity I own. - // Add it to my send list. - ASSERT_TRUE( mesh.is_valid(e) ); - EntityProc tmp( e , proc ); - new_send.insert( tmp ); - } - else if ( mesh.is_valid(e) ) { - // I am the receiver for this ghost. - // If I already have it add it to the receive list, - // otherwise don't worry about it - I will receive - // it in the final new-ghosting communication. - new_recv.insert( e ); - } - } - } -} - -void new_comm_recv_to_send( - BulkData & mesh , - const std::set< Entity , EntityLess > & new_recv , - std::set< EntityProc , EntityLess > & new_send ) -{ - const int parallel_size = mesh.parallel_size(); - - stk::CommSparse all( mesh.parallel() ); - - for ( std::set< Entity , EntityLess >::const_iterator - i = new_recv.begin() ; i != new_recv.end() ; ++i ) { - const int owner = mesh.parallel_owner_rank(*i); - all.send_buffer( owner ).skip(1); - } - - all.allocate_buffers(); - - for ( std::set< Entity , EntityLess >::const_iterator - i = new_recv.begin() ; i != new_recv.end() ; ++i ) { - const int owner = mesh.parallel_owner_rank(*i); - const EntityKey key = mesh.entity_key(*i); - all.send_buffer( owner ).pack( & key , 1 ); - } - - all.communicate(); - - for ( int p = 0 ; p < parallel_size ; ++p ) { - stk::CommBuffer & buf = all.recv_buffer(p); - while ( buf.remaining() ) { - EntityKey key ; - buf.unpack( & key , 1 ); - EntityProc tmp( mesh.get_entity( key.rank(), key.id() ) , p ); - new_send.insert( tmp ); - } - } -} - -} - TEST ( UnitTestBulkData_new , testGhostHandleRemainsValidAfterRefresh ) { // diff --git a/packages/stk/stk_unit_tests/stk_mesh/UnitTestCEO.cpp b/packages/stk/stk_unit_tests/stk_mesh/UnitTestCEO.cpp index b8d32a918354..baec7613ab67 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/UnitTestCEO.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/UnitTestCEO.cpp @@ -51,9 +51,6 @@ #include "UnitTestCEO4ElemEdge.hpp" #include "UnitTestCEO4ElemRotate.hpp" #include "UnitTestCEO8Elem.hpp" -#include "mpi.h" // for MPI_COMM_WORLD, etc -#include "stk_io/DatabasePurpose.hpp" // for DatabasePurpose::READ_MESH -#include "stk_io/StkMeshIoBroker.hpp" // for StkMeshIoBroker #include "stk_mesh/base/Bucket.hpp" // for Bucket #include "stk_mesh/base/BulkDataInlinedMethods.hpp" #include "stk_mesh/base/Entity.hpp" // for Entity @@ -193,7 +190,7 @@ void test_change_entity_owner_3Elem3Proc_WithCustomGhosts(stk::mesh::BulkData::A int psize = stk::parallel_machine_size(communicator); int prank = stk::parallel_machine_rank(communicator); if(psize == 3) - { // Skip unless we're on 2 processors + { // Skip unless we're on 3 processors const int spatialDim = 3; std::vector rankNames; @@ -201,31 +198,14 @@ void test_change_entity_owner_3Elem3Proc_WithCustomGhosts(stk::mesh::BulkData::A rankNames.push_back("edge"); rankNames.push_back("face"); rankNames.push_back("elem"); - rankNames.push_back("comst"); + rankNames.push_back("const"); stk::mesh::MetaData stkMeshMetaData(spatialDim, rankNames); - //stk::mesh::Part &part = stkMeshMetaData.declare_part("constraints", stk::topology::CONSTRAINT_RANK); stk::mesh::BulkData stkMeshBulkData(stkMeshMetaData, communicator, autoAuraOption); const std::string generatedMeshSpecification = "generated:1x1x6"; - // STK IO module will be described in separate chapter. - // It is used here to read the mesh data from the Exodus file and populate an STK Mesh. - // The order of the following lines in {} are important - { - stk::io::StkMeshIoBroker exodusFileReader(communicator); - - // Inform STK IO which STK Mesh objects to populate later - exodusFileReader.set_bulk_data(stkMeshBulkData); - - exodusFileReader.add_mesh_database(generatedMeshSpecification, stk::io::READ_MESH); - - // Populate the MetaData which has the descriptions of the Parts and Fields. - exodusFileReader.create_input_mesh(); - - // Populate entities in STK Mesh from Exodus file - exodusFileReader.populate_bulk_data(); - } + stk::io::fill_mesh(generatedMeshSpecification, stkMeshBulkData); ///////////////////////// stkMeshBulkData.modification_begin(); @@ -263,6 +243,7 @@ void test_change_entity_owner_3Elem3Proc_WithCustomGhosts(stk::mesh::BulkData::A { stk::mesh::Entity node1 = stkMeshBulkData.get_entity(stk::topology::NODE_RANK, 1); EXPECT_TRUE(stkMeshBulkData.bucket(node1).shared()); + EXPECT_TRUE(stkMeshBulkData.in_receive_ghost(ghosting, node1)); } if(prank==0 || prank==2) @@ -292,6 +273,11 @@ void test_change_entity_owner_3Elem3Proc_WithCustomGhosts(stk::mesh::BulkData::A { stk::mesh::Entity elem1 = stkMeshBulkData.get_entity(stk::topology::ELEM_RANK, 1); EXPECT_TRUE(stkMeshBulkData.parallel_owner_rank(elem1) == 2); + stk::mesh::Entity node1 = stkMeshBulkData.get_entity(stk::topology::NODE_RANK, 1); + ASSERT_TRUE(stkMeshBulkData.is_valid(node1)); + EXPECT_FALSE(stkMeshBulkData.in_receive_ghost(ghosting, node1)); + stk::mesh::Part& ghostingPart = stkMeshBulkData.ghosting_part(ghosting); + EXPECT_FALSE(stkMeshBulkData.bucket(node1).member(ghostingPart)); } } } diff --git a/packages/stk/stk_unit_tests/stk_mesh/ngp/UnitTestNgpDebugFieldSync_PartialSync.cpp b/packages/stk/stk_unit_tests/stk_mesh/ngp/UnitTestNgpDebugFieldSync_PartialSync.cpp index 8f1f82383943..58899ae027cc 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/ngp/UnitTestNgpDebugFieldSync_PartialSync.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/ngp/UnitTestNgpDebugFieldSync_PartialSync.cpp @@ -883,6 +883,29 @@ TEST_F(NgpDebugFieldSync_PartialSync, DeviceToHost_ScalarPartial_WriteAll_SyncSe check_no_warnings(stdoutString); } +TEST_F(NgpDebugFieldSync_PartialSync, HostToDevice_ScalarPartial_SyncOutsideSelector_WarnOutsideSelector) +{ + if (stk::parallel_machine_size(MPI_COMM_WORLD) != 1) return; + create_parts({"Part1", "Part2", "Part3"}); + declare_scalar_field("doubleScalarField", {"Part2", "Part3"}); + build_mesh({{"Part1", 2}, {"Part2", 2}, {"Part3", 2}}); + stk::mesh::Field & stkField = initialized_field("doubleScalarField"); + stk::mesh::Selector selector = *get_meta().get_part("Part1") + | *get_meta().get_part("Part2") + | *get_meta().get_part("Part3"); + + testing::internal::CaptureStdout(); + write_scalar_field_on_host_using_entity(stkField, stk::mesh::Selector(stkField), 3.14); + stkField.modify_on_host(selector); + stkField.sync_to_device(); + + read_scalar_field_on_device(stkField); + + std::string stdoutString = testing::internal::GetCapturedStdout(); + extract_warning(stdoutString, 1, "*** WARNING: Marked field doubleScalarField modified with selector ((Part1 | Part2) | Part3) that includes buckets outside the subset of the mesh that the field is defined on."); + check_no_warnings(stdoutString); +} + TEST_F(NgpDebugFieldSync_PartialSync, DeviceToHost_ScalarPartial_SyncOutsideSelector_WarnOutsideSelector) { if (stk::parallel_machine_size(MPI_COMM_WORLD) != 1) return; diff --git a/packages/stk/stk_util/stk_util/registry/ProductRegistry.cpp b/packages/stk/stk_util/stk_util/registry/ProductRegistry.cpp index 8ae284da8589..80b50f1276a4 100644 --- a/packages/stk/stk_util/stk_util/registry/ProductRegistry.cpp +++ b/packages/stk/stk_util/stk_util/registry/ProductRegistry.cpp @@ -42,7 +42,7 @@ //In Sierra, STK_VERSION_STRING is provided on the compile line by bake. //For Trilinos stk snapshots, the following macro definition gets populated with //the real version string by the trilinos_snapshot.sh script. -#define STK_VERSION_STRING "5.1.2-412-g6bc16ca5" +#define STK_VERSION_STRING "5.1.3-550-g5afc1675" #endif namespace stk { diff --git a/packages/stk/stk_util/stk_util/util/Array.hpp b/packages/stk/stk_util/stk_util/util/Array.hpp index f8692b59ac6e..883685781590 100644 --- a/packages/stk/stk_util/stk_util/util/Array.hpp +++ b/packages/stk/stk_util/stk_util/util/Array.hpp @@ -200,7 +200,7 @@ class Array : public FArray Trunc; //---------------------------------------- - /** Dimensions defined at contruction */ + /** Dimensions defined at construction */ const unsigned * dimension() const { return BaseType::dimension(); diff --git a/packages/tempus/src/Tempus_Integrator.hpp b/packages/tempus/src/Tempus_Integrator.hpp index 4dbcd4a2f79d..e74bce208240 100644 --- a/packages/tempus/src/Tempus_Integrator.hpp +++ b/packages/tempus/src/Tempus_Integrator.hpp @@ -75,6 +75,8 @@ class Integrator virtual int getIndex() const = 0; /// Get the Status virtual Tempus::Status getStatus() const = 0; + /// Set the Status + virtual void setStatus(const Tempus::Status st) = 0; /// Get the stepper virtual Teuchos::RCP > getStepper() const = 0; /// Return a copy of the Tempus ParameterList diff --git a/packages/tempus/src/Tempus_IntegratorAdjointSensitivity_decl.hpp b/packages/tempus/src/Tempus_IntegratorAdjointSensitivity_decl.hpp index 7780cb750c7f..8a3729c83631 100644 --- a/packages/tempus/src/Tempus_IntegratorAdjointSensitivity_decl.hpp +++ b/packages/tempus/src/Tempus_IntegratorAdjointSensitivity_decl.hpp @@ -101,6 +101,8 @@ class IntegratorAdjointSensitivity : virtual int getIndex() const override; /// Get Status virtual Status getStatus() const override; + /// Set Status + virtual void setStatus(const Status st) override; /// Get the Stepper virtual Teuchos::RCP > getStepper() const override; /// Return a copy of the Tempus ParameterList diff --git a/packages/tempus/src/Tempus_IntegratorAdjointSensitivity_impl.hpp b/packages/tempus/src/Tempus_IntegratorAdjointSensitivity_impl.hpp index b33e26d13289..66294abaf655 100644 --- a/packages/tempus/src/Tempus_IntegratorAdjointSensitivity_impl.hpp +++ b/packages/tempus/src/Tempus_IntegratorAdjointSensitivity_impl.hpp @@ -247,6 +247,12 @@ getStatus() const return PASSED; } +template +void IntegratorAdjointSensitivity::setStatus(const Status st) { + state_integrator_->setStatus(st); + adjoint_integrator_->setStatus(st); +} + template Teuchos::RCP > IntegratorAdjointSensitivity:: diff --git a/packages/tempus/src/Tempus_IntegratorBasicOld_decl.hpp b/packages/tempus/src/Tempus_IntegratorBasicOld_decl.hpp index b28288b2fae4..c31db04f3323 100644 --- a/packages/tempus/src/Tempus_IntegratorBasicOld_decl.hpp +++ b/packages/tempus/src/Tempus_IntegratorBasicOld_decl.hpp @@ -90,6 +90,8 @@ class IntegratorBasicOld /// Get Status virtual Status getStatus() const override {return integratorStatus_;} + /// Set Status + virtual void setStatus(const Status st) override { integratorStatus_ = st; } /// Get the Stepper virtual Teuchos::RCP > getStepper() const override {return stepper_;} diff --git a/packages/tempus/src/Tempus_IntegratorBasicOld_impl.hpp b/packages/tempus/src/Tempus_IntegratorBasicOld_impl.hpp index 68c0379e70ec..671174e2739d 100644 --- a/packages/tempus/src/Tempus_IntegratorBasicOld_impl.hpp +++ b/packages/tempus/src/Tempus_IntegratorBasicOld_impl.hpp @@ -358,7 +358,7 @@ void IntegratorBasicOld::startIntegrator() if (isInitialized_ == false) { Teuchos::OSTab ostab(out,1,"StartIntegrator"); *out << "Failure - IntegratorBasicOld is not initialized." << std::endl; - integratorStatus_ = Status::FAILED; + setStatus(Status::FAILED); return; } @@ -375,7 +375,7 @@ void IntegratorBasicOld::startIntegrator() // update initial time step timeStepControl_->setInitTimeStep(initDt); timeStepControl_->initialize(); - integratorStatus_ = WORKING; + setStatus(WORKING); } @@ -465,7 +465,7 @@ void IntegratorBasicOld::checkTimeStep() *out << "Failure - Stepper has failed more than the maximum allowed.\n" << " (nFailures = "<getNFailures()<< ") >= (nFailuresMax = " << timeStepControl_->getMaxFailures()<<")" << std::endl; - integratorStatus_ = Status::FAILED; + setStatus(Status::FAILED); return; } if (ws->getNConsecutiveFailures() @@ -478,7 +478,7 @@ void IntegratorBasicOld::checkTimeStep() << ") >= (nConsecutiveFailuresMax = " << timeStepControl_->getMaxConsecFailures() << ")" << std::endl; - integratorStatus_ = Status::FAILED; + setStatus(Status::FAILED); return; } @@ -529,7 +529,7 @@ void IntegratorBasicOld::endIntegrator() Status::FAILED || integratorStatus_ == Status::FAILED) { exitStatus = "Time integration FAILURE!"; } else { - integratorStatus_ = Status::PASSED; + setStatus(Status::PASSED); exitStatus = "Time integration complete."; } diff --git a/packages/tempus/src/Tempus_IntegratorBasic_decl.hpp b/packages/tempus/src/Tempus_IntegratorBasic_decl.hpp index 1170b5f65146..90fb96924922 100644 --- a/packages/tempus/src/Tempus_IntegratorBasic_decl.hpp +++ b/packages/tempus/src/Tempus_IntegratorBasic_decl.hpp @@ -82,6 +82,8 @@ class IntegratorBasic : virtual public Tempus::Integrator /// Get Status virtual Status getStatus() const override {return integratorStatus_;} + /// Set Status + virtual void setStatus(const Status st) override { integratorStatus_ = st; } /// Get the Stepper virtual Teuchos::RCP > getStepper() const override {return stepper_;} diff --git a/packages/tempus/src/Tempus_IntegratorBasic_impl.hpp b/packages/tempus/src/Tempus_IntegratorBasic_impl.hpp index a38565776c35..226ce810cace 100644 --- a/packages/tempus/src/Tempus_IntegratorBasic_impl.hpp +++ b/packages/tempus/src/Tempus_IntegratorBasic_impl.hpp @@ -298,7 +298,7 @@ void IntegratorBasic::startIntegrator() if (isInitialized_ == false) { Teuchos::OSTab ostab(out,1,"StartIntegrator"); *out << "Failure - IntegratorBasic is not initialized." << std::endl; - integratorStatus_ = Status::FAILED; + setStatus(Status::FAILED); return; } @@ -315,7 +315,7 @@ void IntegratorBasic::startIntegrator() // update initial time step timeStepControl_->setInitTimeStep(initDt); timeStepControl_->initialize(); - integratorStatus_ = WORKING; + setStatus(WORKING); } @@ -405,7 +405,7 @@ void IntegratorBasic::checkTimeStep() *out << "Failure - Stepper has failed more than the maximum allowed.\n" << " (nFailures = "<getNFailures()<< ") >= (nFailuresMax = " << timeStepControl_->getMaxFailures()<<")" << std::endl; - integratorStatus_ = Status::FAILED; + setStatus(Status::FAILED); return; } if (ws->getNConsecutiveFailures() @@ -419,7 +419,7 @@ void IntegratorBasic::checkTimeStep() << ") >= (nConsecutiveFailuresMax = " << timeStepControl_->getMaxConsecFailures() << ")" << std::endl; - integratorStatus_ = Status::FAILED; + setStatus(Status::FAILED); return; } @@ -471,7 +471,7 @@ void IntegratorBasic::endIntegrator() Status::FAILED || integratorStatus_ == Status::FAILED) { exitStatus = "Time integration FAILURE!"; } else { - integratorStatus_ = Status::PASSED; + setStatus(Status::PASSED); exitStatus = "Time integration complete."; } diff --git a/packages/tempus/src/Tempus_IntegratorForwardSensitivity_decl.hpp b/packages/tempus/src/Tempus_IntegratorForwardSensitivity_decl.hpp index c556e796a6dd..492d66d96246 100644 --- a/packages/tempus/src/Tempus_IntegratorForwardSensitivity_decl.hpp +++ b/packages/tempus/src/Tempus_IntegratorForwardSensitivity_decl.hpp @@ -136,6 +136,10 @@ class IntegratorForwardSensitivity /// Get Status virtual Status getStatus() const override { return integrator_->getStatus(); } + // Set Status + virtual void setStatus(const Status st) override { + integrator_->setStatus(st); + } /// Get the Stepper virtual Teuchos::RCP > getStepper() const override { return integrator_->getStepper(); } diff --git a/packages/tempus/src/Tempus_IntegratorPseudoTransientAdjointSensitivity_decl.hpp b/packages/tempus/src/Tempus_IntegratorPseudoTransientAdjointSensitivity_decl.hpp index ec2430a47cbf..ab0c3fde1e42 100644 --- a/packages/tempus/src/Tempus_IntegratorPseudoTransientAdjointSensitivity_decl.hpp +++ b/packages/tempus/src/Tempus_IntegratorPseudoTransientAdjointSensitivity_decl.hpp @@ -102,6 +102,8 @@ class IntegratorPseudoTransientAdjointSensitivity virtual int getIndex() const override; /// Get Status virtual Status getStatus() const override; + /// Set Status + virtual void setStatus(const Status st) override; /// Get the Stepper virtual Teuchos::RCP > getStepper() const override; /// Return a copy of the Tempus ParameterList diff --git a/packages/tempus/src/Tempus_IntegratorPseudoTransientAdjointSensitivity_impl.hpp b/packages/tempus/src/Tempus_IntegratorPseudoTransientAdjointSensitivity_impl.hpp index 0867093373e6..8a05927ba0a9 100644 --- a/packages/tempus/src/Tempus_IntegratorPseudoTransientAdjointSensitivity_impl.hpp +++ b/packages/tempus/src/Tempus_IntegratorPseudoTransientAdjointSensitivity_impl.hpp @@ -130,6 +130,13 @@ getStatus() const return PASSED; } +template +void IntegratorPseudoTransientAdjointSensitivity::setStatus( + const Status st) { + state_integrator_->setStatus(st); + sens_integrator_->setStatus(st); +} + template Teuchos::RCP > IntegratorPseudoTransientAdjointSensitivity:: diff --git a/packages/tempus/src/Tempus_IntegratorPseudoTransientForwardSensitivity_decl.hpp b/packages/tempus/src/Tempus_IntegratorPseudoTransientForwardSensitivity_decl.hpp index 01dfd1996e73..79a72b85c463 100644 --- a/packages/tempus/src/Tempus_IntegratorPseudoTransientForwardSensitivity_decl.hpp +++ b/packages/tempus/src/Tempus_IntegratorPseudoTransientForwardSensitivity_decl.hpp @@ -116,6 +116,8 @@ class IntegratorPseudoTransientForwardSensitivity virtual int getIndex() const override; /// Get Status virtual Status getStatus() const override; + /// Set Status + virtual void setStatus(const Status st) override; /// Get the Stepper virtual Teuchos::RCP > getStepper() const override; /// Return a copy of the Tempus ParameterList diff --git a/packages/tempus/src/Tempus_IntegratorPseudoTransientForwardSensitivity_impl.hpp b/packages/tempus/src/Tempus_IntegratorPseudoTransientForwardSensitivity_impl.hpp index 142c007f06ac..617afc13227f 100644 --- a/packages/tempus/src/Tempus_IntegratorPseudoTransientForwardSensitivity_impl.hpp +++ b/packages/tempus/src/Tempus_IntegratorPseudoTransientForwardSensitivity_impl.hpp @@ -143,6 +143,13 @@ getStatus() const return PASSED; } +template +void IntegratorPseudoTransientForwardSensitivity::setStatus( + const Status st) { + state_integrator_->setStatus(st); + sens_integrator_->setStatus(st); +} + template Teuchos::RCP > IntegratorPseudoTransientForwardSensitivity:: diff --git a/packages/tempus/test/Integrator/Tempus_IntegratorTest.cpp b/packages/tempus/test/Integrator/Tempus_IntegratorTest.cpp index 565823eaadee..fe5b07c1338a 100644 --- a/packages/tempus/test/Integrator/Tempus_IntegratorTest.cpp +++ b/packages/tempus/test/Integrator/Tempus_IntegratorTest.cpp @@ -138,6 +138,13 @@ TEUCHOS_UNIT_TEST(IntegratorBasic, Describe) TEST_ASSERT(npos != testS.find("--- Stepper ---")); TEST_ASSERT(npos != testS.find("stepperType_ = Forward Euler")); TEST_ASSERT(npos != testS.find("--- StepperExplicit ---")); + + integrator->setStatus(Tempus::Status::FAILED); + TEST_ASSERT(integrator->getStatus() == Tempus::Status::FAILED); + integrator->setStatus(Tempus::Status::WORKING); + TEST_ASSERT(integrator->getStatus() == Tempus::Status::WORKING); + integrator->setStatus(Tempus::Status::PASSED); + TEST_ASSERT(integrator->getStatus() == Tempus::Status::PASSED); } diff --git a/packages/tpetra/CMakeLists.txt b/packages/tpetra/CMakeLists.txt index cec378d3b15a..5382bebc2d99 100644 --- a/packages/tpetra/CMakeLists.txt +++ b/packages/tpetra/CMakeLists.txt @@ -33,7 +33,12 @@ ENDIF () # objects for CUDA. See Trilinos GitHub issue #1939. ASSERT_DEFINED(TPL_ENABLE_CUDA) + +ASSERT_DEFINED(Kokkos_ENABLE_OPENMP) +ASSERT_DEFINED(Kokkos_ENABLE_PTHREAD) +ASSERT_DEFINED(Kokkos_ENABLE_SERIAL) ASSERT_DEFINED(Kokkos_ENABLE_CUDA) +ASSERT_DEFINED(Kokkos_ENABLE_SYCL) IF (TPL_ENABLE_CUDA AND Kokkos_ENABLE_CUDA) SET (Tpetra_ENABLE_CUDA_DEFAULT ON) @@ -362,10 +367,7 @@ GLOBAL_SET(HAVE_TPETRA_INST_SERIAL_DEFAULT OFF) GLOBAL_SET(HAVE_TPETRA_INST_PTHREAD_DEFAULT OFF) GLOBAL_SET(HAVE_TPETRA_INST_OPENMP_DEFAULT OFF) GLOBAL_SET(HAVE_TPETRA_INST_CUDA_DEFAULT OFF) - -ASSERT_DEFINED(Kokkos_ENABLE_OPENMP) -ASSERT_DEFINED(Kokkos_ENABLE_PTHREAD) -ASSERT_DEFINED(Kokkos_ENABLE_SERIAL) +GLOBAL_SET(HAVE_TPETRA_INST_SYCL_DEFAULT OFF) # We already have a separate Tpetra_ENABLE_CUDA option that we defined # above, so we don't have to check Kokkos_ENABLE_CUDA here. @@ -509,7 +511,7 @@ ELSE () # NOT Tpetra_INST_CUDA ENDIF () # Tpetra_INST_CUDA # Kokkos::HIP (Kokkos::Compat::KokkosHIPWrapperNode) -GLOBAL_SET(HAVE_TPETRA_INST_HIP_DEFAULT off) +GLOBAL_SET(HAVE_TPETRA_INST_HIP_DEFAULT OFF) TRIBITS_ADD_OPTION_AND_DEFINE( Tpetra_INST_HIP HAVE_TPETRA_INST_HIP @@ -529,6 +531,28 @@ ELSE () # NOT Tpetra_INST_HIP MESSAGE(STATUS "NOTE: Kokkos::HIP is ON (the CMake option Kokkos_ENABLE_HIP is ON), but the corresponding Tpetra Node type is disabled. If you want to enable instantiation and use of Kokkos::HIP in Tpetra, please also set the CMake option Tpetra_INST_HIP:BOOL=ON. If you use the Kokkos::HIP version of Tpetra without doing this, you will get link errors!") ENDIF () ENDIF () # Tpetra_INST_HIP + +# Kokkos::SYCL (Kokkos::Compat::KokkosSYCLWrapperNode) +TRIBITS_ADD_OPTION_AND_DEFINE( + Tpetra_INST_SYCL + HAVE_TPETRA_INST_SYCL + "Instantiate and/or test Tpetra classes over Node = Kokkos::Compat::KokkosSYCLWrapperNode. If ETI is OFF, enable tests for that Node type. This option is ${HAVE_TPETRA_INST_SYCL_DEFAULT} by default." + ${HAVE_TPETRA_INST_SYCL_DEFAULT} + ) +GLOBAL_SET(HAVE_TPETRA_SYCL ${Tpetra_INST_SYCL}) +IF (Tpetra_INST_SYCL) + IF (NOT Kokkos_ENABLE_SYCL) + MESSAGE(FATAL_ERROR "Tpetra: The Kokkos::SYCL execution space is disabled, but you enabled the corresponding Tpetra Node type by setting Tpetra_INST_SYCL=ON. If you want to enable instantiation and use of Kokkos::SYCL in Tpetra, you must enable the Kokkos::SYCL execution space by setting Kokkos_ENABLE_SYCL=ON.") + ENDIF () +ELSE () # NOT Tpetra_INST_SYCL + IF (HAVE_TPETRA_DEFAULTNODE_SYCLWRAPPERNODE) + MESSAGE(FATAL_ERROR "Tpetra: Node = Kokkos::Compat::KokkosSYCLWrapperNode is disabled (since Tpetra_INST_SYCL=OFF), but you set it as the default Node type. Try setting the CMake options Kokkos_ENABLE_SYCL:BOOL=ON and Tpetra_INST_SYCL:BOOL=ON. If you are building with a SYCL-capable compiler and Kokkos can detect that, then you are unlikely to see this message, since both Kokkos and Tpetra enable SYCL support by default in that case.") + ENDIF() + IF (Kokkos_ENABLE_SYCL) + MESSAGE(STATUS "NOTE: Kokkos::SYCL is ON (the CMake option Kokkos_ENABLE_SYCL is ON), but the corresponding Tpetra Node type is disabled. If you want to enable instantiation and use of Kokkos::SYCL in Tpetra, please also set the CMake option Tpetra_INST_SYCL:BOOL=ON. If you use the Kokkos::SYCL version of Tpetra without doing this, you will get link errors!") + ENDIF () +ENDIF () # Tpetra_INST_SYCL + # # Check that users did not attempt to enable both the OpenMP and # Pthreads back-ends. @@ -567,6 +591,13 @@ IF(Tpetra_INST_HIP) LIST(APPEND ${PACKAGE_NAME}_ETI_DEVICES "Kokkos::Device") LIST(APPEND ${PACKAGE_NAME}_ETI_NODES "Kokkos::Compat::KokkosHIPWrapperNode") ENDIF() +IF(Tpetra_INST_SYCL) + # TpetraCore currently requires UVM, so it doesn't make sense to + # instantiate over Kokkos::SYCLDeviceUSMSpace as well as + # Kokkos::SYCLSharedUSMSpace. + LIST(APPEND ${PACKAGE_NAME}_ETI_DEVICES "Kokkos::Device") + LIST(APPEND ${PACKAGE_NAME}_ETI_NODES "Kokkos::Compat::KokkosSYCLWrapperNode") +ENDIF() # Tell users what Nodes are enabled. MESSAGE(STATUS "Tpetra execution space availability (ON means available): ") @@ -575,11 +606,12 @@ MESSAGE(STATUS " - Threads: ${HAVE_TPETRA_PTHREAD}") MESSAGE(STATUS " - OpenMP: ${HAVE_TPETRA_OPENMP}") MESSAGE(STATUS " - Cuda: ${HAVE_TPETRA_CUDA}") MESSAGE(STATUS " - HIP: ${HAVE_TPETRA_HIP}") +MESSAGE(STATUS " - SYCL: ${HAVE_TPETRA_SYCL}") # Fix Github Issue #190 by making sure that users enabled at least one # Node type. -IF(NOT Tpetra_INST_SERIAL AND NOT Tpetra_INST_PTHREAD AND NOT Tpetra_INST_OPENMP AND NOT Tpetra_INST_CUDA AND NOT Tpetra_INST_HIP) - MESSAGE(FATAL_ERROR "It appears that you have disabled all of Tpetra's Node types. This is a bad idea; please don't do this. This may have happened either if all Kokkos execution spaces got disabled, or if you explicitly disabled some Tpetra Node types. To fix this, look in your CMake configuration to see if you set any of the following variables to OFF explicitly: Kokkos_ENABLE_CUDA, Kokkos_ENABLE_OPENMP, Kokkos_ENABLE_SERIAL, Kokkos_ENABLE_PTHREAD, Tpetra_INST_SERIAL, Tpetra_INST_PTHREAD, Tpetra_INST_OPENMP, or Tpetra_INST_CUDA.") +IF(NOT Tpetra_INST_SERIAL AND NOT Tpetra_INST_PTHREAD AND NOT Tpetra_INST_OPENMP AND NOT Tpetra_INST_CUDA AND NOT Tpetra_INST_HIP AND NOT Tpetra_INST_SYCL) + MESSAGE(FATAL_ERROR "It appears that you have disabled all of Tpetra's Node types. This is a bad idea; please don't do this. This may have happened either if all Kokkos execution spaces got disabled, or if you explicitly disabled some Tpetra Node types. To fix this, look in your CMake configuration to see if you set any of the following variables to OFF explicitly: Kokkos_ENABLE_SYCL, Kokkos_ENABLE_HIP, Kokkos_ENABLE_CUDA, Kokkos_ENABLE_OPENMP, Kokkos_ENABLE_SERIAL, Kokkos_ENABLE_PTHREAD, Tpetra_INST_SERIAL, Tpetra_INST_PTHREAD, Tpetra_INST_OPENMP, Tpetra_INST_HIP, Tpetra_INST_SYCL or Tpetra_INST_CUDA.") ENDIF() # ============================================================ diff --git a/packages/tpetra/classic/NodeAPI/CMakeLists.txt b/packages/tpetra/classic/NodeAPI/CMakeLists.txt index a78b8b52bfa8..204395a1121f 100644 --- a/packages/tpetra/classic/NodeAPI/CMakeLists.txt +++ b/packages/tpetra/classic/NodeAPI/CMakeLists.txt @@ -71,7 +71,15 @@ ENDIF() # performance of users' own threads -- OpenMP doesn't have # that problem). -IF (Tpetra_DefaultNode STREQUAL "Kokkos::Compat::KokkosHIPWrapperNode") +IF (Tpetra_DefaultNode STREQUAL "Kokkos::Compat::KokkosSYCLWrapperNode") + IF (NOT Kokkos_ENABLE_SYCL) + MESSAGE (FATAL_ERROR "Kokkos_ENABLE_SYCL is OFF, but you set Tpetra's default Node type to Kokkos::Compat::KokkosSYCLWrapperNode.") + ENDIF () + IF (NOT Tpetra_INST_SYCL) + MESSAGE (FATAL_ERROR "Tpetra_INST_SYCL is OFF, but you set Tpetra's default Node type to Kokkos::Compat::KokkosSYCLWrapperNode.") + ENDIF () + SET (HAVE_TPETRA_DEFAULTNODE_SYCLWRAPPERNODE ON CACHE BOOL "") +ELSEIF (Tpetra_DefaultNode STREQUAL "Kokkos::Compat::KokkosHIPWrapperNode") IF (NOT Kokkos_ENABLE_HIP) MESSAGE (FATAL_ERROR "Kokkos_ENABLE_HIP is OFF, but you set Tpetra's default Node type to Kokkos::Compat::KokkosHIPWrapperNode.") ENDIF () @@ -115,7 +123,14 @@ ELSEIF (Tpetra_DefaultNode STREQUAL "") # # The user didn't set Tpetra_DefaultNode, so we need to pick it. # - IF (Tpetra_INST_HIP) + IF (Tpetra_INST_SYCL) + IF(NOT Kokkos_ENABLE_SYCL) + MESSAGE(FATAL_ERROR "Tpetra_INST_SYCL is ON, but Kokkos_ENABLE_SYCL is OFF.") + ENDIF() + MESSAGE(STATUS "Setting default Node to Kokkos::Compat::KokkosSYCLWrapperNode.") + SET(Tpetra_DefaultNode "Kokkos::Compat::KokkosSYCLWrapperNode") + SET(HAVE_TPETRA_DEFAULTNODE_SYCLWRAPPERNODE ON CACHE BOOL "") + ELSEIF (Tpetra_INST_HIP) IF(NOT Kokkos_ENABLE_HIP) MESSAGE(FATAL_ERROR "Tpetra_INST_HIP is ON, but Kokkos_ENABLE_HIP is OFF.") ENDIF() diff --git a/packages/tpetra/classic/NodeAPI/KokkosCompat_ClassicNodeAPI_Wrapper.cpp b/packages/tpetra/classic/NodeAPI/KokkosCompat_ClassicNodeAPI_Wrapper.cpp index 7b7b0ca4c4df..3e0d7732d19c 100644 --- a/packages/tpetra/classic/NodeAPI/KokkosCompat_ClassicNodeAPI_Wrapper.cpp +++ b/packages/tpetra/classic/NodeAPI/KokkosCompat_ClassicNodeAPI_Wrapper.cpp @@ -40,6 +40,14 @@ namespace Kokkos { } #endif // KOKKOS_ENABLE_HIP +#ifdef KOKKOS_ENABLE_SYCL + template<> + std::string KokkosDeviceWrapperNode::name() { + return std::string("SYCL/Wrapper"); + } +#endif // KOKKOS_ENABLE_SYCL + + } // namespace Compat } // namespace Kokkos diff --git a/packages/tpetra/classic/NodeAPI/KokkosCompat_ClassicNodeAPI_Wrapper.hpp b/packages/tpetra/classic/NodeAPI/KokkosCompat_ClassicNodeAPI_Wrapper.hpp index 59a5755bdd42..811c0217b1ca 100644 --- a/packages/tpetra/classic/NodeAPI/KokkosCompat_ClassicNodeAPI_Wrapper.hpp +++ b/packages/tpetra/classic/NodeAPI/KokkosCompat_ClassicNodeAPI_Wrapper.hpp @@ -49,6 +49,10 @@ class KokkosDeviceWrapperNode { static std::string name (); }; +#ifdef KOKKOS_ENABLE_SYCL + typedef KokkosDeviceWrapperNode KokkosSYCLWrapperNode; +#endif + #ifdef KOKKOS_ENABLE_HIP typedef KokkosDeviceWrapperNode KokkosHIPWrapperNode; #endif diff --git a/packages/tpetra/classic/NodeAPI/Kokkos_DefaultNode.hpp b/packages/tpetra/classic/NodeAPI/Kokkos_DefaultNode.hpp index 5cab6d261da6..fbd9eb740a2a 100644 --- a/packages/tpetra/classic/NodeAPI/Kokkos_DefaultNode.hpp +++ b/packages/tpetra/classic/NodeAPI/Kokkos_DefaultNode.hpp @@ -68,7 +68,9 @@ namespace KokkosClassic { /// \endcode class DefaultNode { public: -#if defined(HAVE_TPETRA_DEFAULTNODE_HIPWRAPPERNODE) +#if defined(HAVE_TPETRA_DEFAULTNODE_SYCLWRAPPERNODE) + typedef ::Kokkos::Compat::KokkosSYCLWrapperNode DefaultNodeType; +#elif defined(HAVE_TPETRA_DEFAULTNODE_HIPWRAPPERNODE) typedef ::Kokkos::Compat::KokkosHIPWrapperNode DefaultNodeType; #elif defined(HAVE_TPETRA_DEFAULTNODE_CUDAWRAPPERNODE) typedef ::Kokkos::Compat::KokkosCudaWrapperNode DefaultNodeType; diff --git a/packages/tpetra/classic/NodeAPI/cmake/KokkosClassic_DefaultNode_config.h.in b/packages/tpetra/classic/NodeAPI/cmake/KokkosClassic_DefaultNode_config.h.in index 64404a72dc53..e1aacda8032e 100644 --- a/packages/tpetra/classic/NodeAPI/cmake/KokkosClassic_DefaultNode_config.h.in +++ b/packages/tpetra/classic/NodeAPI/cmake/KokkosClassic_DefaultNode_config.h.in @@ -6,6 +6,13 @@ // For backwards compatibility ONLY. #define KOKKOSCLASSIC_DEFAULTNODE TPETRA_DEFAULTNODE +// Defined if and only if Tpetra's default execution space is Kokkos::SYCL. +#cmakedefine HAVE_TPETRA_DEFAULTNODE_SYCLWRAPPERNODE +// For backwards compatibility ONLY. +#ifdef HAVE_TPETRA_DEFAULTNODE_SYCLWRAPPERNODE +# define HAVE_KOKKOSCLASSIC_DEFAULTNODE_SYCLWRAPPERNODE 1 +#endif // HAVE_TPETRA_DEFAULTNODE_SYCLWRAPPERNODE + // Defined if and only if Tpetra's default execution space is Kokkos::HIP. #cmakedefine HAVE_TPETRA_DEFAULTNODE_HIPWRAPPERNODE // For backwards compatibility ONLY. diff --git a/packages/tpetra/core/cmake/TpetraCore_config.h.in b/packages/tpetra/core/cmake/TpetraCore_config.h.in index e6f36e918cb4..a27be27a67aa 100644 --- a/packages/tpetra/core/cmake/TpetraCore_config.h.in +++ b/packages/tpetra/core/cmake/TpetraCore_config.h.in @@ -145,6 +145,7 @@ #cmakedefine HAVE_TPETRA_INST_OPENMP #cmakedefine HAVE_TPETRA_INST_CUDA #cmakedefine HAVE_TPETRA_INST_HIP +#cmakedefine HAVE_TPETRA_INST_SYCL #cmakedefine HAVE_TPETRA_INT_INT #cmakedefine HAVE_TPETRA_INT_LONG @@ -165,6 +166,7 @@ #cmakedefine HAVE_TPETRA_OPENMP #cmakedefine HAVE_TPETRA_CUDA #cmakedefine HAVE_TPETRA_HIP +#cmakedefine HAVE_TPETRA_SYCL #cmakedefine HAVE_TPETRA_THREADED_MKL diff --git a/packages/tpetra/core/example/BlockCrs/Tpetra_TestBlockCrs.cpp b/packages/tpetra/core/example/BlockCrs/Tpetra_TestBlockCrs.cpp index 9b49fa8cd2c9..49e5ae8dc852 100644 --- a/packages/tpetra/core/example/BlockCrs/Tpetra_TestBlockCrs.cpp +++ b/packages/tpetra/core/example/BlockCrs/Tpetra_TestBlockCrs.cpp @@ -238,7 +238,7 @@ int main (int argc, char *argv[]) // uses a different device. An easy check is device configuration for // 4 mpi nodes as the typical number of GPUs per node is 4. if (commTest->getRank () < 4) { - exec_space::print_configuration (std::cout, false); + exec_space{}.print_configuration (std::cout, false); } if (debug) { @@ -281,7 +281,8 @@ int main (int argc, char *argv[]) // - all internal views are allocated on device; mirror as mesh database is constructed on host const auto mesh_gids_host = mesh.getElementGlobalIDs(); const auto mesh_gids = - Kokkos::create_mirror_view_and_copy (typename exec_space::memory_space(), mesh_gids_host); + Kokkos::create_mirror_view_and_copy (typename map_type::node_type::memory_space{}, + mesh_gids_host); // for convenience, separate the access to owned and remote gids const auto owned_gids = @@ -477,7 +478,7 @@ int main (int argc, char *argv[]) { TimeMonitor timerMultiVectorFill(*TimeMonitor::getNewTimer("4) MultiVectorFill")); - auto value = X->getLocalView(Tpetra::Access::OverwriteAll); + auto value = X->getLocalViewDevice(Tpetra::Access::OverwriteAll); auto map = X->getMap()->getLocalMap(); Kokkos::parallel_for (value.extent(0), KOKKOS_LAMBDA(const LO i) { diff --git a/packages/tpetra/core/src/Tpetra_BlockCrsMatrix_decl.hpp b/packages/tpetra/core/src/Tpetra_BlockCrsMatrix_decl.hpp index 0d99f522355c..0e88adf60118 100644 --- a/packages/tpetra/core/src/Tpetra_BlockCrsMatrix_decl.hpp +++ b/packages/tpetra/core/src/Tpetra_BlockCrsMatrix_decl.hpp @@ -896,15 +896,16 @@ class BlockCrsMatrix : // to run on device then, so we should sync to device. static constexpr bool value = std::is_same::value; -#else // Gonna badly fake this here for other execspaces - #if defined(KOKKOS_ENABLE_HIP) +#elif defined(KOKKOS_ENABLE_HIP) static constexpr bool value = std::is_same::value; - #else +#elif defined(KOKKOS_ENABLE_SYCL) + static constexpr bool value = + std::is_same::value; +#else static constexpr bool value = false; - #endif -#endif // defined(KOKKOS_ENABLE_CUDA) +#endif }; public: diff --git a/packages/tpetra/core/src/Tpetra_CrsGraph_def.hpp b/packages/tpetra/core/src/Tpetra_CrsGraph_def.hpp index 7557b09a28a6..6a3df5701921 100644 --- a/packages/tpetra/core/src/Tpetra_CrsGraph_def.hpp +++ b/packages/tpetra/core/src/Tpetra_CrsGraph_def.hpp @@ -5020,7 +5020,6 @@ namespace Tpetra { using LO = local_ordinal_type; using GO = global_ordinal_type; using this_type = CrsGraph; - using row_graph_type = RowGraph; const char tfecfFuncName[] = "copyAndPermute: "; const bool verbose = verbose_; @@ -5698,8 +5697,6 @@ namespace Tpetra { using std::endl; using crs_graph_type = CrsGraph; - using row_graph_type = - RowGraph; const char tfecfFuncName[] = "packAndPrepare: "; ProfilingRegion region_papn ("Tpetra::CrsGraph::packAndPrepare"); diff --git a/packages/tpetra/core/src/Tpetra_CrsMatrix_decl.hpp b/packages/tpetra/core/src/Tpetra_CrsMatrix_decl.hpp index ec397c885c3d..fca7491e1fce 100644 --- a/packages/tpetra/core/src/Tpetra_CrsMatrix_decl.hpp +++ b/packages/tpetra/core/src/Tpetra_CrsMatrix_decl.hpp @@ -437,6 +437,8 @@ namespace Tpetra { using device_type = typename Node::device_type; //! The Kokkos execution space. using execution_space = typename device_type::execution_space; + //! The Kokkos memory space. + using memory_space = typename device_type::memory_space; /// \brief This class' Kokkos Node type. /// @@ -3792,9 +3794,9 @@ namespace Tpetra { /// /// \pre The graph is not already storage optimized: /// isStorageOptimized() == false - size_t - mergeRowIndicesAndValues (crs_graph_type& graph, - const RowInfo& rowInfo); + /// \return The new row length, after merging. + static size_t + mergeRowIndicesAndValues (size_t rowLen, local_ordinal_type* cols, impl_scalar_type* vals); /// \brief Sort and merge duplicate local column indices in all /// rows on the calling process, along with their corresponding diff --git a/packages/tpetra/core/src/Tpetra_CrsMatrix_def.hpp b/packages/tpetra/core/src/Tpetra_CrsMatrix_def.hpp index 5a380cf1f95e..fb742c8bef7f 100644 --- a/packages/tpetra/core/src/Tpetra_CrsMatrix_def.hpp +++ b/packages/tpetra/core/src/Tpetra_CrsMatrix_def.hpp @@ -1867,7 +1867,6 @@ namespace Tpetra { const Teuchos::ArrayView& values) { using std::endl; - typedef impl_scalar_type IST; const char tfecfFuncName[] = "insertLocalValues: "; TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC @@ -1965,7 +1964,6 @@ namespace Tpetra { const impl_scalar_type vals[], const size_t numInputEnt) { - typedef impl_scalar_type IST; #ifdef HAVE_TPETRA_DEBUG const char tfecfFuncName[] = "insertGlobalValuesImpl: "; const size_t origNumEnt = graph.getNumEntriesInLocalRow (rowInfo.localRow); @@ -3284,7 +3282,6 @@ namespace Tpetra { #endif // HAVE_TPETRA_DEBUG range_type range (rowinfo.offset1D, rowinfo.offset1D + rowinfo.allocSize); - typedef View subview_type; // mfh 23 Nov 2015: Don't just create a subview of k_values1D_ // directly, because that first creates a _managed_ subview, // then returns an unmanaged version of that. That touches the @@ -3806,7 +3803,6 @@ CrsMatrix:: CrsMatrix:: scale (const Scalar& alpha) { - typedef LocalOrdinal LO; const char tfecfFuncName[] = "scale: "; const impl_scalar_type theAlpha = static_cast (alpha); @@ -5014,40 +5010,18 @@ CrsMatrix:: } template - size_t - CrsMatrix:: - mergeRowIndicesAndValues (crs_graph_type& graph, - const RowInfo& rowInfo) + size_t CrsMatrix:: + mergeRowIndicesAndValues (size_t rowLen, LocalOrdinal* cols, impl_scalar_type* vals) { -#ifdef HAVE_TPETRA_DEBUG - const char tfecfFuncName[] = "mergeRowIndicesAndValues: "; -#endif // HAVE_TPETRA_DEBUG - - auto rowValues = this->getValuesViewHostNonConst (rowInfo); - typedef typename std::decay::type value_type; - value_type* rowValueIter = rowValues.data (); - - auto inds_view = graph.getLocalIndsViewHostNonConst (rowInfo); - + impl_scalar_type* rowValueIter = vals; // beg,end define a half-exclusive interval over which to iterate. - LocalOrdinal* beg = inds_view.data (); - LocalOrdinal* end = inds_view.data () + rowInfo.numEntries; - -#ifdef HAVE_TPETRA_DEBUG - TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC - (rowInfo.allocSize != static_cast (inds_view.extent (0)) || - rowInfo.allocSize != static_cast (rowValues.extent (0)), - std::runtime_error, "rowInfo.allocSize = " << rowInfo.allocSize - << " != inds_view.extent(0) = " << inds_view.extent (0) - << " || rowInfo.allocSize = " << rowInfo.allocSize - << " != rowValues.extent(0) = " << rowValues.extent (0) << "."); -#endif // HAVE_TPETRA_DEBUG - + LocalOrdinal* beg = cols; + LocalOrdinal* end = cols + rowLen; LocalOrdinal* newend = beg; if (beg != end) { LocalOrdinal* cur = beg + 1; - value_type* vcur = rowValueIter + 1; - value_type* vend = rowValueIter; + impl_scalar_type* vcur = rowValueIter + 1; + impl_scalar_type* vend = rowValueIter; cur = beg+1; while (cur != end) { if (*cur != *newend) { @@ -5067,10 +5041,7 @@ CrsMatrix:: } ++newend; // one past the last entry, per typical [beg,end) semantics } - const size_t mergedEntries = newend - beg; - graph.k_numRowEntries_(rowInfo.localRow) = mergedEntries; - const size_t numDups = rowInfo.numEntries - mergedEntries; - return numDups; + return newend - beg; } template @@ -5083,7 +5054,6 @@ CrsMatrix:: typedef typename Kokkos::View::HostMirror::execution_space host_execution_space; typedef Kokkos::RangePolicy range_type; - //typedef Kokkos::RangePolicy range_type; const char tfecfFuncName[] = "sortAndMergeIndicesAndValues: "; ProfilingRegion regionSAM ("Tpetra::CrsMatrix::sortAndMergeIndicesAndValues"); @@ -5103,22 +5073,28 @@ CrsMatrix:: crs_graph_type& graph = * (this->myGraph_); const LO lclNumRows = static_cast (this->getNodeNumRows ()); size_t totalNumDups = 0; - // FIXME (mfh 10 May 2017) This may assume CUDA UVM. - Kokkos::parallel_reduce (range_type (0, lclNumRows), - [this, &graph, sorted, merged] (const LO& lclRow, size_t& numDups) { - const RowInfo rowInfo = graph.getRowInfo (lclRow); - if (! sorted) { - auto lclColInds = graph.getLocalIndsViewHostNonConst (rowInfo); - auto vals = this->getValuesViewHostNonConst (rowInfo); - - sort2 (lclColInds.data (), - lclColInds.data () + rowInfo.numEntries, - vals.data ()); - } - if (! merged) { - numDups += this->mergeRowIndicesAndValues (graph, rowInfo); - } - }, totalNumDups); + { + //Accessing host unpacked (4-array CRS) local matrix. + auto rowBegins_ = graph.rowPtrsUnpacked_host_; + auto rowLengths_ = graph.k_numRowEntries_; + auto vals_ = this->valuesUnpacked_wdv.getHostView(Access::ReadWrite); + auto cols_ = graph.lclIndsUnpacked_wdv.getHostView(Access::ReadWrite); + Kokkos::parallel_reduce ("sortAndMergeIndicesAndValues", range_type (0, lclNumRows), + [=] (const LO lclRow, size_t& numDups) { + size_t rowBegin = rowBegins_(lclRow); + size_t rowLen = rowLengths_(lclRow); + LO* cols = cols_.data() + rowBegin; + impl_scalar_type* vals = vals_.data() + rowBegin; + if (! sorted) { + sort2 (cols, cols + rowLen, vals); + } + if (! merged) { + size_t newRowLength = mergeRowIndicesAndValues (rowLen, cols, vals); + rowLengths_(lclRow) = newRowLength; + numDups += rowLen - newRowLength; + } + }, totalNumDups); + } if (! sorted) { graph.indicesAreSorted_ = true; // we just sorted every row } @@ -5895,7 +5871,6 @@ CrsMatrix:: // Currently, the source object must be a RowMatrix with the same // four template parameters as the target CrsMatrix. We might // relax this requirement later. - typedef RowMatrix row_matrix_type; const row_matrix_type* srcRowMat = dynamic_cast (&source); return (srcRowMat != nullptr); @@ -5991,7 +5966,7 @@ CrsMatrix:: if (refill_num_row_entries) { // unpacked storage // We can't assume correct *this capture until C++17, and it's // likely more efficient just to capture what we need anyway. - num_row_entries_d = create_mirror_view_and_copy(execution_space(), + num_row_entries_d = create_mirror_view_and_copy(memory_space(), myGraph_->k_numRowEntries_); Kokkos::parallel_for ("Fill end row pointers", range_policy(0, N), @@ -6622,7 +6597,6 @@ CrsMatrix:: std::cerr << os.str (); } - using row_matrix_type = RowMatrix; const row_matrix_type* srcRowMat = dynamic_cast (&source); TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC @@ -7034,8 +7008,6 @@ CrsMatrix:: using LO = LocalOrdinal; using GO = GlobalOrdinal; using ST = impl_scalar_type; - using HES = - typename View::HostMirror::execution_space; const char tfecfFuncName[] = "packNonStaticNew: "; const bool verbose = Behavior::verbose("CrsMatrix"); @@ -7854,8 +7826,6 @@ CrsMatrix:: using std::endl; using LO = local_ordinal_type; using GO = global_ordinal_type; - using row_matrix_type = - RowMatrix; using crs_matrix_type = CrsMatrix; const char errPfx[] = "Tpetra::CrsMatrix::add: "; diff --git a/packages/tpetra/core/src/Tpetra_Details_DefaultTypes.hpp b/packages/tpetra/core/src/Tpetra_Details_DefaultTypes.hpp index 3da5e7b263de..5ce86ae6dd46 100644 --- a/packages/tpetra/core/src/Tpetra_Details_DefaultTypes.hpp +++ b/packages/tpetra/core/src/Tpetra_Details_DefaultTypes.hpp @@ -87,7 +87,10 @@ namespace DefaultTypes { /// \typedef execution_space /// \brief Default Tpetra execution space and Node type. -#if defined(HAVE_TPETRA_DEFAULTNODE_HIPWRAPPERNODE) +#if defined(HAVE_TPETRA_DEFAULTNODE_SYCLWRAPPERNODE) + using execution_space = ::Kokkos::Experimental::SYCL; + using node_type = ::Kokkos::Compat::KokkosSYCLWrapperNode; +#elif defined(HAVE_TPETRA_DEFAULTNODE_HIPWRAPPERNODE) using execution_space = ::Kokkos::Experimental::HIP; using node_type = ::Kokkos::Compat::KokkosHIPWrapperNode; #elif defined(HAVE_TPETRA_DEFAULTNODE_CUDAWRAPPERNODE) @@ -132,6 +135,14 @@ namespace DefaultTypes { }; #endif +#ifdef KOKKOS_ENABLE_SYCL + template<> + struct CommBufferMemorySpace + { + using type = Kokkos::Experimental::SYCLDeviceUSMSpace; + }; +#endif + template using comm_buffer_memory_space = typename CommBufferMemorySpace::type; diff --git a/packages/tpetra/core/src/Tpetra_Details_FixedHashTable_SYCL.cpp b/packages/tpetra/core/src/Tpetra_Details_FixedHashTable_SYCL.cpp new file mode 100644 index 000000000000..df2f40b32e5c --- /dev/null +++ b/packages/tpetra/core/src/Tpetra_Details_FixedHashTable_SYCL.cpp @@ -0,0 +1,86 @@ +/* +// @HEADER +// *********************************************************************** +// +// Tpetra: Templated Linear Algebra Services Package +// Copyright (2008) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact Michael A. Heroux (maherou@sandia.gov) +// +// ************************************************************************ +// @HEADER +*/ + +#include "Tpetra_Details_FixedHashTable_decl.hpp" + +#if defined(HAVE_TPETRA_EXPLICIT_INSTANTIATION) && defined(KOKKOS_ENABLE_SYCL) + +#include "TpetraCore_ETIHelperMacros.h" +#include "Tpetra_Details_FixedHashTable_def.hpp" + +namespace Tpetra { +namespace Details { + + TPETRA_ETI_MANGLING_TYPEDEFS() + + using sycl_device_type = typename Kokkos::Compat::KokkosSYCLWrapperNode::device_type; + +#define TPETRA_DETAILS_FIXEDHASHTABLE_INSTANT_SYCL( LO, GO ) \ + TPETRA_DETAILS_FIXEDHASHTABLE_INSTANT( LO, GO, sycl_device_type ) + + TPETRA_INSTANTIATE_LG( TPETRA_DETAILS_FIXEDHASHTABLE_INSTANT_SYCL) + + // mfh 26 Sep 2015: Make sure that the {KeyType = LO, ValueType = + // LO} and {KeyType = int, ValueType = LO} specializations get + // built, since Directory needs them. + + // KeyType = int doesn't get built if GO = int is disabled. +#ifndef HAVE_TPETRA_INST_INT_INT +# define TPETRA_DETAILS_FIXEDHASHTABLE_INSTANT_SYCL_INT( LO ) \ + TPETRA_DETAILS_FIXEDHASHTABLE_INSTANT( LO, int, sycl_device_type ) \ + + TPETRA_INSTANTIATE_L( TPETRA_DETAILS_FIXEDHASHTABLE_INSTANT_SYCL_INT) + + // FIXME (mfh 26 Sep 2015) Once it becomes possible to disable LO = + // int, add an instantiation here for {KeyType = LO, ValueType = + // LO}. However, this case has likely already been covered above, + // since disabling LO = int leaves LO = GO = long or long long as + // the most reasonable options. (It would be silly to use LO = long + // and GO = long long if sizeof(long) = sizeof(long long).) + +#endif // HAVE_TPETRA_INST_INT_INT + +} // namespace Details +} // namespace Tpetra + +#endif // defined(HAVE_TPETRA_EXPLICIT_INSTANTIATION) && defined(KOKKOS_ENABLE_SYCL) diff --git a/packages/tpetra/core/src/Tpetra_Details_StaticView.cpp b/packages/tpetra/core/src/Tpetra_Details_StaticView.cpp index 0eeae70f65b9..2691fe283269 100644 --- a/packages/tpetra/core/src/Tpetra_Details_StaticView.cpp +++ b/packages/tpetra/core/src/Tpetra_Details_StaticView.cpp @@ -123,6 +123,33 @@ void finalize_hip_host_pinned_memory () } #endif // KOKKOS_ENABLE_HIP +#ifdef KOKKOS_ENABLE_SYCL + +void* sycl_memory_ = nullptr; +size_t sycl_memory_size_ = 0; + +void finalize_sycl_memory () +{ + if (sycl_memory_ != nullptr) { + Kokkos::kokkos_free (sycl_memory_); + sycl_memory_ = nullptr; + sycl_memory_size_ = 0; + } +} + +void* sycl_shared_memory_ = nullptr; +size_t sycl_shared_memory_size_ = 0; + +void finalize_sycl_shared_memory () +{ + if (sycl_shared_memory_ != nullptr) { + Kokkos::kokkos_free (sycl_shared_memory_); + sycl_shared_memory_ = nullptr; + sycl_shared_memory_size_ = 0; + } +} +#endif // KOKKOS_ENABLE_SYCL + void* host_memory_ = nullptr; size_t host_memory_size_ = 0; @@ -265,6 +292,60 @@ resize (Kokkos::Experimental::HIPHostPinnedSpace /* space */, #endif // KOKKOS_ENABLE_HIP +#ifdef KOKKOS_ENABLE_SYCL + +template <> +void* +StaticKokkosAllocation:: +resize (Kokkos::Experimental::SYCLDeviceUSMSpace /* space */, + const size_t size) +{ + using memory_space = Kokkos::Experimental::SYCLDeviceUSMSpace; + static bool created_finalize_hook = false; + + if (size > sycl_memory_size_) { + if (sycl_memory_ != nullptr) { + Kokkos::kokkos_free (sycl_memory_); + } + const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size; + sycl_memory_ = Kokkos::kokkos_malloc (req_size); + sycl_memory_size_ = size; + } + if (! created_finalize_hook) { + Kokkos::push_finalize_hook (finalize_sycl_memory); + created_finalize_hook = true; + } + + return sycl_memory_; +} + +template <> +void* +StaticKokkosAllocation:: +resize (Kokkos::Experimental::SYCLSharedUSMSpace /* space */, + const size_t size) +{ + using memory_space = Kokkos::Experimental::SYCLSharedUSMSpace; + static bool created_finalize_hook = false; + + const size_t req_size = size > minimum_initial_size ? size : minimum_initial_size; + if (req_size > sycl_shared_memory_size_) { + if (sycl_shared_memory_ != nullptr) { + Kokkos::kokkos_free (sycl_shared_memory_); + } + sycl_shared_memory_ = Kokkos::kokkos_malloc (req_size); + sycl_shared_memory_size_ = req_size; + } + if (! created_finalize_hook) { + Kokkos::push_finalize_hook (finalize_sycl_shared_memory); + created_finalize_hook = true; + } + + return sycl_shared_memory_; +} + +#endif // KOKKOS_ENABLE_SYCL + void* StaticKokkosAllocation:: resize (Kokkos::HostSpace /* space */, diff --git a/packages/tpetra/core/src/Tpetra_Details_unpackCrsMatrixAndCombine_def.hpp b/packages/tpetra/core/src/Tpetra_Details_unpackCrsMatrixAndCombine_def.hpp index 7bd5f5d507ea..93ebba9a8ca6 100644 --- a/packages/tpetra/core/src/Tpetra_Details_unpackCrsMatrixAndCombine_def.hpp +++ b/packages/tpetra/core/src/Tpetra_Details_unpackCrsMatrixAndCombine_def.hpp @@ -284,22 +284,28 @@ struct UnpackCrsMatrixAndCombineFunctor { if (expected_num_bytes > num_bytes) { +// FIXME_SYCL Enable again once a SYCL conforming printf implementation is available. +#ifndef KOKKOS_ENABLE_SYCL printf( "*** Error: UnpackCrsMatrixAndCombineFunctor: " "At row %d, the expected number of bytes (%d) != number of unpacked bytes (%d)\n", (int) lid_no, (int) expected_num_bytes, (int) num_bytes ); +#endif Kokkos::atomic_compare_exchange_strong(error_code.data(), 0, 21); return; } if (offset > buf_size || offset + num_bytes > buf_size) { +// FIXME_SYCL Enable again once a SYCL conforming printf implementation is available. +#ifndef KOKKOS_ENABLE_SYCL printf( "*** Error: UnpackCrsMatrixAndCombineFunctor: " "At row %d, the offset (%d) > buffer size (%d)\n", (int) lid_no, (int) offset, (int) buf_size ); +#endif Kokkos::atomic_compare_exchange_strong(error_code.data(), 0, 22); return; } @@ -332,11 +338,14 @@ struct UnpackCrsMatrixAndCombineFunctor { (void)PackTraits::unpackValue(num_ent_out, num_ent_in); if (static_cast(num_ent_out) != num_entries_in_row) { +// FIXME_SYCL Enable again once a SYCL conforming printf implementation is available. +#ifndef KOKKOS_ENABLE_SYCL printf( "*** Error: UnpackCrsMatrixAndCombineFunctor: " "At row %d, number of entries (%d) != number of entries unpacked (%d)\n", (int) lid_no, (int) num_entries_in_row, (int) num_ent_out ); +#endif Kokkos::atomic_compare_exchange_strong(error_code.data(), 0, 23); } @@ -389,10 +398,13 @@ struct UnpackCrsMatrixAndCombineFunctor { ); } else { // should never get here +// FIXME_SYCL Enable again once a SYCL conforming printf implementation is available. +#ifndef KOKKOS_ENABLE_SYCL printf( "*** Error: UnpackCrsMatrixAndCombineFunctor: " "At row %d, an unknown error occurred during unpack\n", (int) lid_no ); +#endif Kokkos::atomic_compare_exchange_strong(error_code.data(), 0, 31); } } diff --git a/packages/tpetra/core/test/Block/BlockCrsMatrix.cpp b/packages/tpetra/core/test/Block/BlockCrsMatrix.cpp index 16612e53fbf2..d2af14252322 100644 --- a/packages/tpetra/core/test/Block/BlockCrsMatrix.cpp +++ b/packages/tpetra/core/test/Block/BlockCrsMatrix.cpp @@ -1022,6 +1022,7 @@ namespace { using local_inds_host_view_type = typename BCM::local_inds_host_view_type; using values_host_view_type = typename BCM::values_host_view_type; + using nonconst_values_host_view_type = typename BCM::nonconst_values_host_view_type; int lclSuccess = 1; int gblSuccess = 1; @@ -1183,10 +1184,10 @@ namespace { lclRowInd <= meshRowMap.getMaxLocalIndex (); ++lclRowInd) { const GO gblRowInd = meshRowMap.getGlobalElement (lclRowInd); local_inds_host_view_type lclColInds; - values_host_view_type myVals; + nonconst_values_host_view_type myVals; LO numEnt = 0; - blockMat.getLocalRowView (lclRowInd, lclColInds, myVals); numEnt = lclColInds.extent(0); - + blockMat.getLocalRowViewNonConst (lclRowInd, lclColInds, myVals); numEnt = lclColInds.extent(0); + // Fill the diagonal block D such that D(i,j) = (lclRowInd+1) * // (1 + i + j*blockSize). Fill the off-diagonal block with -1. // This ensures that we can tell we got the right blocks, and diff --git a/packages/tpetra/core/test/CrsMatrix/CMakeLists.txt b/packages/tpetra/core/test/CrsMatrix/CMakeLists.txt index f64990731af1..e99066f08e68 100644 --- a/packages/tpetra/core/test/CrsMatrix/CMakeLists.txt +++ b/packages/tpetra/core/test/CrsMatrix/CMakeLists.txt @@ -103,6 +103,19 @@ ENDIF() # We split the CrsMatrix_WithGraph test by execution space. # This speeds up the build. +ASSERT_DEFINED (Tpetra_INST_SYCL) +IF (Tpetra_INST_SYCL) + TRIBITS_ADD_EXECUTABLE_AND_TEST( + CrsMatrix_WithGraph_SYCL + SOURCES + CrsMatrix_WithGraph_SYCL + ${TEUCHOS_STD_UNIT_TEST_MAIN} + ARGS ${ARGS} + COMM serial mpi + STANDARD_PASS_OUTPUT + ) +ENDIF () + ASSERT_DEFINED (Tpetra_INST_CUDA) IF (Tpetra_INST_CUDA) TRIBITS_ADD_EXECUTABLE_AND_TEST( diff --git a/packages/tpetra/core/test/CrsMatrix/CrsMatrix_UnitTests.cpp b/packages/tpetra/core/test/CrsMatrix/CrsMatrix_UnitTests.cpp index 9ece51e37250..3e3f4119591b 100644 --- a/packages/tpetra/core/test/CrsMatrix/CrsMatrix_UnitTests.cpp +++ b/packages/tpetra/core/test/CrsMatrix/CrsMatrix_UnitTests.cpp @@ -424,12 +424,21 @@ namespace { // (anonymous) // INSTANTIATIONS // +// FIXME_SYCL +#ifdef KOKKOS_ENABLE_SYCL +#define UNIT_TEST_GROUP( SCALAR, LO, GO, NODE ) \ + TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT( CrsMatrix, TheEyeOfTruth, LO, GO, SCALAR, NODE ) \ + TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT( CrsMatrix, ZeroMatrix, LO, GO, SCALAR, NODE ) \ + TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT( CrsMatrix, BadCalls, LO, GO, SCALAR, NODE ) \ + TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT( CrsMatrix, SimpleEigTest, LO, GO, SCALAR, NODE ) +#else #define UNIT_TEST_GROUP( SCALAR, LO, GO, NODE ) \ TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT( CrsMatrix, TheEyeOfTruth, LO, GO, SCALAR, NODE ) \ TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT( CrsMatrix, ZeroMatrix, LO, GO, SCALAR, NODE ) \ TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT( CrsMatrix, ImbalancedRowMatrix, LO, GO, SCALAR, NODE ) \ TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT( CrsMatrix, BadCalls, LO, GO, SCALAR, NODE ) \ TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT( CrsMatrix, SimpleEigTest, LO, GO, SCALAR, NODE ) +#endif TPETRA_ETI_MANGLING_TYPEDEFS() diff --git a/packages/tpetra/core/test/CrsMatrix/CrsMatrix_WithGraph_SYCL.cpp b/packages/tpetra/core/test/CrsMatrix/CrsMatrix_WithGraph_SYCL.cpp new file mode 100644 index 000000000000..2af141bc5c4c --- /dev/null +++ b/packages/tpetra/core/test/CrsMatrix/CrsMatrix_WithGraph_SYCL.cpp @@ -0,0 +1,73 @@ +/* +// @HEADER +// *********************************************************************** +// +// Tpetra: Templated Linear Algebra Services Package +// Copyright (2008) Sandia Corporation +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact Michael A. Heroux (maherou@sandia.gov) +// +// ************************************************************************ +// @HEADER +*/ + +// Include here just the bare minimum needed for the outer #if. +// Only include more once we know we need the test. +#include "TpetraCore_config.h" + +#if defined(HAVE_TPETRA_SYCL) + +#include "Tpetra_Test_CrsMatrix_WithGraph.hpp" + +namespace Tpetra { +namespace Test { + +// +// INSTANTIATIONS +// + +TPETRA_ETI_MANGLING_TYPEDEFS() + +// Declare a colon- and comma-free typedef, to avoid macro issues. +typedef Kokkos::Compat::KokkosSYCLWrapperNode sycl_node_type; + +#define UNIT_TEST_GROUP_SYCL( SCALAR, LO, GO ) \ + UNIT_TEST_GROUP( SCALAR, LO, GO, sycl_node_type ) + +TPETRA_INSTANTIATE_SLG_NO_ORDINAL_SCALAR( UNIT_TEST_GROUP_SYCL ) + +} // namespace Test +} // namespace Tpetra + +#endif // defined(HAVE_TPETRA_SYCL) + diff --git a/packages/tpetra/core/test/CrsMatrix/assembleElement.cpp b/packages/tpetra/core/test/CrsMatrix/assembleElement.cpp index 55681470be25..b14021c5ef4c 100644 --- a/packages/tpetra/core/test/CrsMatrix/assembleElement.cpp +++ b/packages/tpetra/core/test/CrsMatrix/assembleElement.cpp @@ -608,7 +608,10 @@ namespace { // (anonymous) TPETRA_ETI_MANGLING_TYPEDEFS() +// FIXME_SYCL +#ifndef KOKKOS_ENABLE_SYCL UNIT_TEST_GROUP( double ) +#endif //TPETRA_INSTANTIATE_S_NO_ORDINAL_SCALAR( UNIT_TEST_GROUP ) } // namespace (anonymous) diff --git a/packages/tpetra/core/test/MatrixMatrix/FECrs_MatrixMatrix_UnitTests.cpp b/packages/tpetra/core/test/MatrixMatrix/FECrs_MatrixMatrix_UnitTests.cpp index 78ed6208bece..974c9d692532 100644 --- a/packages/tpetra/core/test/MatrixMatrix/FECrs_MatrixMatrix_UnitTests.cpp +++ b/packages/tpetra/core/test/MatrixMatrix/FECrs_MatrixMatrix_UnitTests.cpp @@ -384,6 +384,9 @@ TEUCHOS_UNIT_TEST_TEMPLATE_4_DECL (Tpetra_MatMat, FECrsMatrix, SC, LO, GO, NT) TPETRA_ETI_MANGLING_TYPEDEFS() +// FIXME_SYCL +#ifndef KOKKOS_ENABLE_SYCL TPETRA_INSTANTIATE_SLGN_NO_ORDINAL_SCALAR( UNIT_TEST_GROUP_SC_LO_GO_NO ) +#endif } // anonymous namespace diff --git a/packages/tpetra/core/test/PerformanceCGSolve/cg_solve_file.cpp b/packages/tpetra/core/test/PerformanceCGSolve/cg_solve_file.cpp index f39dcfa0cff5..d211cbbbc954 100644 --- a/packages/tpetra/core/test/PerformanceCGSolve/cg_solve_file.cpp +++ b/packages/tpetra/core/test/PerformanceCGSolve/cg_solve_file.cpp @@ -69,7 +69,6 @@ bool cg_solve (Teuchos::RCP A, Teuchos::RCP b, Teuchos::RCP::value, "The CrsMatrix and Vector template parameters must have the same scalar_type."); @@ -83,16 +82,6 @@ bool cg_solve (Teuchos::RCP A, Teuchos::RCP b, Teuchos::RCP(A->getRangeMap()); Ap = Tpetra::createVector(A->getRangeMap()); - { - TimeMonitor t(*TimeMonitor::getNewTimer(replaceValsName)); - int length = r->getLocalLength(); - for(int i = 0;ireplaceLocalValue(i,0); - r->replaceLocalValue(i,1); - Ap->replaceLocalValue(i,1); - } - } - magnitude_type normr = 0; magnitude_type rtrans = 0; magnitude_type oldrtrans = 0; @@ -216,8 +205,6 @@ int run() typedef Tpetra::Vector vec_type; typedef Tpetra::Map map_type; - typedef typename vec_type::mag_type mag_type; - // // Get the communicator and node // @@ -268,8 +255,7 @@ int run() map); } else { typedef Tpetra::Utils::MatrixGenerator gen_type; - b = gen_type::generate_miniFE_vector (nsize, map->getComm () - ); + b = gen_type::generate_miniFE_vector (nsize, map->getComm ()); } // The vector x on input is the initial guess for the CG solve. diff --git a/packages/tpetra/core/test/TpetraUtils_MatrixGenerator.hpp b/packages/tpetra/core/test/TpetraUtils_MatrixGenerator.hpp index 12540a462e23..d7117f946d71 100644 --- a/packages/tpetra/core/test/TpetraUtils_MatrixGenerator.hpp +++ b/packages/tpetra/core/test/TpetraUtils_MatrixGenerator.hpp @@ -688,21 +688,23 @@ namespace Tpetra { } private: - template - static void miniFE_vector_generate_block(S* vec, int nx, S a, S b, int& count,int start,int end){ + template + static void miniFE_vector_generate_block(Vec& vec, int nx, S a, S b, int& count,int start,int end){ if((count>=start) && (count=start) && (count=start) && (count=start) && (count - static void miniFE_vector_generate_superblock(S* vec, int nx, S a,S b,S c, int& count,int start,int end){ + template + static void miniFE_vector_generate_superblock(Vec& vec, int nx, S a,S b,S c, int& count,int start,int end){ miniFE_vector_generate_block(vec,nx,0.0,0.0,count,start,end); miniFE_vector_generate_block(vec,nx,a,b,count,start,end); for(int i = 0;i STS; // unused //typedef typename STS::magnitudeType MT; // unused //typedef Teuchos::ScalarTraits STM; // unused - typedef Tpetra::Vector MV; + typedef Tpetra::Vector Vec; Tuple dims; dims[0] = (nx+1)*(nx+1)*(nx+1); @@ -740,22 +742,18 @@ namespace Tpetra { const global_size_t numRows = static_cast (dims[0]); // const size_t numCols = static_cast (dims[1]); - RCP map = createUniformContigMapWithNode (numRows, pComm - ); - int start = map->getMinGlobalIndex(); - int end = map->getMaxGlobalIndex()+1; + RCP map = createUniformContigMapWithNode (numRows, pComm); + int start = map->getIndexBase(); + int end = start + map->getGlobalNumElements(); - // Make a multivector X owned entirely by Proc 0. - RCP X = createVector (map); - ArrayRCP X_view = X->get1dViewNonConst (); - ST* vec = &X_view[0]; + RCP X = createVector (map); int count = 0; - miniFE_vector_generate_superblock(vec,nx,0.0,0.0,0.0,count,start,end); - miniFE_vector_generate_superblock(vec,nx,1.0,5.0/12,8.0/12,count,start,end); + miniFE_vector_generate_superblock(*X,nx,0.0,0.0,0.0,count,start,end); + miniFE_vector_generate_superblock(*X,nx,1.0,5.0/12,8.0/12,count,start,end); for(int i = 0; i mueLuFactory(amgList); + MueLu::ParameterListInterpreter mueLuFactory(amgList); RCP > H = mueLuFactory.CreateHierarchy(); H->setVerbLevel(Teuchos::VERB_HIGH); H->GetLevel(0)->Set("A", mueluA); diff --git a/packages/xpetra/src/BlockedCrsMatrix/Xpetra_MapExtractor_def.hpp b/packages/xpetra/src/BlockedCrsMatrix/Xpetra_MapExtractor_def.hpp index c69ed6fb4e91..ac9046b071d1 100644 --- a/packages/xpetra/src/BlockedCrsMatrix/Xpetra_MapExtractor_def.hpp +++ b/packages/xpetra/src/BlockedCrsMatrix/Xpetra_MapExtractor_def.hpp @@ -502,7 +502,7 @@ const RCP > vv = Xpetra:: // WCMCLEN - ETI: but BlockedMultiVector::setMultiVector() does... should this be using bfull. full->setMultiVector(block, partial, bThyraMode); #else - throw std::runtime_error("Xpetra::MultiVector::setMultiVector() doesn't exist."); + throw std::runtime_error("Xpetra::MultiVector::setMultiVector() doesn't exist in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); #endif } } diff --git a/packages/xpetra/src/CrsMatrix/Xpetra_TpetraBlockCrsMatrix_def.hpp b/packages/xpetra/src/CrsMatrix/Xpetra_TpetraBlockCrsMatrix_def.hpp index ebd97660bb35..b914953f11e9 100644 --- a/packages/xpetra/src/CrsMatrix/Xpetra_TpetraBlockCrsMatrix_def.hpp +++ b/packages/xpetra/src/CrsMatrix/Xpetra_TpetraBlockCrsMatrix_def.hpp @@ -58,7 +58,7 @@ namespace Xpetra { size_t maxNumEntriesPerRow, const Teuchos::RCP< Teuchos::ParameterList > ¶ms) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in"+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -69,7 +69,7 @@ namespace Xpetra { const ArrayRCP< const size_t > &NumEntriesPerRowToAlloc, const Teuchos::RCP< Teuchos::ParameterList > ¶ms) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in"+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -81,7 +81,7 @@ namespace Xpetra { size_t maxNumEntriesPerRow, const Teuchos::RCP< Teuchos::ParameterList > ¶ms) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in"+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -93,7 +93,7 @@ namespace Xpetra { const ArrayRCP< const size_t > &NumEntriesPerRowToAlloc, const Teuchos::RCP< Teuchos::ParameterList > ¶ms) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in"+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -105,7 +105,7 @@ namespace Xpetra { // : mtx_(Teuchos::rcp(new Tpetra::BlockCrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node >(toTpetra(graph), params))) // * there is no Tpetra::BlockCrsMatrix(graph, params) c'tor. We throw anyways here so no need to set mtx_. { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in"+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -127,7 +127,7 @@ namespace Xpetra { const Teuchos::RCP >& rangeMap, const Teuchos::RCP& params) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in"+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -140,7 +140,7 @@ namespace Xpetra { const Teuchos::RCP >& rangeMap, const Teuchos::RCP& params) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in"+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -154,7 +154,7 @@ namespace Xpetra { const Teuchos::RCP >& rangeMap, const Teuchos::RCP& params) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in"+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -168,7 +168,7 @@ namespace Xpetra { const Teuchos::RCP >& rangeMap, const Teuchos::RCP& params) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in"+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -189,7 +189,7 @@ namespace Xpetra { const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in"+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -201,7 +201,7 @@ namespace Xpetra { const ArrayView< const LocalOrdinal > &cols, const ArrayView< const Scalar > &vals) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in"+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -213,7 +213,7 @@ namespace Xpetra { const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in"+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -244,7 +244,7 @@ namespace Xpetra { TpetraBlockCrsMatrix:: scale(const Scalar &alpha) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -255,7 +255,7 @@ namespace Xpetra { TpetraBlockCrsMatrix:: allocateAllValues(size_t numNonZeros,ArrayRCP & rowptr, ArrayRCP & colind, ArrayRCP & values) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -265,7 +265,7 @@ namespace Xpetra { TpetraBlockCrsMatrix:: setAllValues(const ArrayRCP & rowptr, const ArrayRCP & colind, const ArrayRCP & values) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -277,7 +277,7 @@ namespace Xpetra { ArrayRCP& colind, ArrayRCP& values) const { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } //! Gets the 1D pointer arrays of the graph (not implemented) @@ -286,7 +286,7 @@ namespace Xpetra { TpetraBlockCrsMatrix:: getAllValues(ArrayRCP& values) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -332,7 +332,7 @@ namespace Xpetra { replaceDomainMapAndImporter(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > >& newDomainMap, Teuchos::RCP > & newImporter) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -345,7 +345,7 @@ namespace Xpetra { const RCP > &exporter, const RCP ¶ms) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } //@} @@ -377,7 +377,7 @@ namespace Xpetra { TpetraBlockCrsMatrix:: getCrsGraph() const { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -642,7 +642,7 @@ namespace Xpetra { getLocalDiagCopy(Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &diag, const Teuchos::ArrayView &offsets) const { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -690,7 +690,7 @@ namespace Xpetra { TpetraBlockCrsMatrix:: replaceDiag(const Vector &diag) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix::replaceDiag: function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix::replaceDiag: function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -699,7 +699,7 @@ namespace Xpetra { TpetraBlockCrsMatrix:: leftScale (const Vector& x) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -708,7 +708,7 @@ namespace Xpetra { TpetraBlockCrsMatrix:: rightScale (const Vector& x) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -728,7 +728,7 @@ namespace Xpetra { doImport(const DistObject &source, const Import< LocalOrdinal, GlobalOrdinal, Node > &importer, CombineMode CM) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -739,7 +739,7 @@ namespace Xpetra { doExport(const DistObject &dest, const Import< LocalOrdinal, GlobalOrdinal, Node >& importer, CombineMode CM) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -750,7 +750,7 @@ namespace Xpetra { doImport(const DistObject &source, const Export< LocalOrdinal, GlobalOrdinal, Node >& exporter, CombineMode CM) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -761,7 +761,7 @@ namespace Xpetra { doExport(const DistObject &dest, const Export< LocalOrdinal, GlobalOrdinal, Node >& exporter, CombineMode CM) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -770,7 +770,7 @@ namespace Xpetra { TpetraBlockCrsMatrix:: removeEmptyProcessesInPlace (const Teuchos::RCP >& newMap) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix function not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } @@ -819,7 +819,7 @@ typename CrsMatrix::local_matrix_type TpetraBlockCrsMatrix:: getLocalMatrixDevice () const { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support getLocalMatrix due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support getLocalMatrix due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); #ifndef __NVCC__ local_matrix_type ret; @@ -833,7 +833,7 @@ typename CrsMatrix::local_matrix_type::H TpetraBlockCrsMatrix:: getLocalMatrixHost () const { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support getLocalMatrix due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support getLocalMatrix due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); #ifndef __NVCC__ typename local_matrix_type::HostMirror ret; @@ -850,7 +850,7 @@ setAllValues (const typename local_matrix_type::row_map_type& ptr, const typename local_matrix_type::StaticCrsGraphType::entries_type::non_const_type& ind, const typename local_matrix_type::values_type& val) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support setAllValues due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support setAllValues due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } #endif // HAVE_XPETRA_TPETRA @@ -1187,7 +1187,7 @@ setAllValues (const typename local_matrix_type::row_map_type& ptr, typedef typename Xpetra::CrsMatrix::local_matrix_type local_matrix_type; local_matrix_type getLocalMatrix () const { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support getLocalMatrix due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support getLocalMatrix due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); local_matrix_type ret; return ret; // make compiler happy } @@ -1196,7 +1196,7 @@ setAllValues (const typename local_matrix_type::row_map_type& ptr, const typename local_matrix_type::StaticCrsGraphType::entries_type::non_const_type& ind, const typename local_matrix_type::values_type& val) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support setAllValues due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support setAllValues due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } #endif // HAVE_XPETRA_TPETRA #endif // HAVE_XPETRA_KOKKOS_REFACTOR @@ -1530,7 +1530,7 @@ setAllValues (const typename local_matrix_type::row_map_type& ptr, typedef typename Xpetra::CrsMatrix::local_matrix_type local_matrix_type; local_matrix_type getLocalMatrix () const { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support getLocalMatrix due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support getLocalMatrix due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); local_matrix_type ret; TEUCHOS_UNREACHABLE_RETURN(ret); } @@ -1539,7 +1539,7 @@ setAllValues (const typename local_matrix_type::row_map_type& ptr, const typename local_matrix_type::StaticCrsGraphType::entries_type::non_const_type& ind, const typename local_matrix_type::values_type& val) { - throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support setAllValues due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation"); + throw std::runtime_error("Xpetra::TpetraBlockCrsMatrix does not support setAllValues due to missing Kokkos::CrsMatrix in Tpetra's experimental implementation in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } #endif // HAVE_XPETRA_TPETRA #endif // HAVE_XPETRA_KOKKOS_REFACTOR diff --git a/packages/xpetra/src/Map/Xpetra_EpetraMap.hpp b/packages/xpetra/src/Map/Xpetra_EpetraMap.hpp index c04c895c2138..1b24410e9835 100644 --- a/packages/xpetra/src/Map/Xpetra_EpetraMap.hpp +++ b/packages/xpetra/src/Map/Xpetra_EpetraMap.hpp @@ -245,7 +245,7 @@ namespace Xpetra { using local_map_type = typename Map::local_map_type; /// \brief Get the local Map for Kokkos kernels. local_map_type getLocalMap () const { - throw std::runtime_error("Xpetra::EpetraMap::getLocalMap is not implemented."); + throw std::runtime_error("Xpetra::EpetraMap::getLocalMap is not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } #else #ifdef __GNUC__ @@ -656,7 +656,7 @@ namespace Xpetra { //! Replace this Map's communicator with a subset communicator. RCP > replaceCommWithSubset(const Teuchos::RCP< const Teuchos::Comm< int > > &/* newComm */) const { - throw std::runtime_error("Xpetra::EpetraMapT::replaceCommWithSubset has not yet been implemented."); + throw std::runtime_error("Xpetra::EpetraMapT::replaceCommWithSubset has not yet been implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); TEUCHOS_UNREACHABLE_RETURN(Teuchos::null); } @@ -698,7 +698,7 @@ namespace Xpetra { using local_map_type = typename Map::local_map_type; /// \brief Get the local Map for Kokkos kernels. local_map_type getLocalMap () const { - throw std::runtime_error("Xpetra::EpetraMap::getLocalMap is not implemented."); + throw std::runtime_error("Xpetra::EpetraMap::getLocalMap is not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } private: @@ -1092,7 +1092,7 @@ namespace Xpetra { //! Replace this Map's communicator with a subset communicator. RCP > replaceCommWithSubset(const Teuchos::RCP< const Teuchos::Comm< int > > &/* newComm */) const { - throw std::runtime_error("Xpetra::EpetraMapT::replaceCommWithSubset has not yet been implemented."); + throw std::runtime_error("Xpetra::EpetraMapT::replaceCommWithSubset has not yet been implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); // return Teuchos::null; // unreachable } @@ -1132,7 +1132,7 @@ namespace Xpetra { using local_map_type = typename Map::local_map_type; /// \brief Get the local Map for Kokkos kernels. local_map_type getLocalMap () const { - throw std::runtime_error("Xpetra::EpetraMap::getLocalMap is not implemented."); + throw std::runtime_error("Xpetra::EpetraMap::getLocalMap is not implemented in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); } private: diff --git a/packages/xpetra/src/MultiVector/Xpetra_EpetraIntMultiVector.hpp b/packages/xpetra/src/MultiVector/Xpetra_EpetraIntMultiVector.hpp index 8360acb75de6..624432c78742 100644 --- a/packages/xpetra/src/MultiVector/Xpetra_EpetraIntMultiVector.hpp +++ b/packages/xpetra/src/MultiVector/Xpetra_EpetraIntMultiVector.hpp @@ -334,7 +334,7 @@ const Epetra_IntMultiVector & toEpetra(const MultiVector::dual_view_type dual_view_type; typename dual_view_type::t_host_um getHostLocalView () const { - throw std::runtime_error("EpetraIntVector does not support device views! Must be implemented extra..."); + throw std::runtime_error("EpetraIntVector does not support device views! Must be implemented extra... in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); #ifndef __NVCC__ //prevent nvcc warning typename dual_view_type::t_host_um ret; #endif @@ -342,7 +342,7 @@ const Epetra_IntMultiVector & toEpetra(const MultiVector &) typedef typename Xpetra::MultiVector::dual_view_type dual_view_type; typename dual_view_type::t_host_um getHostLocalView () const { - throw std::runtime_error("EpetraIntVector does not support device views! Must be implemented extra..."); + throw std::runtime_error("EpetraIntVector does not support device views! Must be implemented extra... in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); #ifndef __NVCC__ //prevent nvcc warning typename dual_view_type::t_host_um ret; #endif @@ -320,7 +320,7 @@ const Epetra_IntVector & toEpetra(const Vector &) } typename dual_view_type::t_dev_um getDeviceLocalView() const { - throw std::runtime_error("Epetra does not support device views!"); + throw std::runtime_error("Epetra does not support device views! in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); #ifndef __NVCC__ //prevent nvcc warning typename dual_view_type::t_dev_um ret; #endif @@ -730,7 +730,7 @@ const Epetra_IntVector & toEpetra(const Vector &) } typename dual_view_type::t_dev_um getDeviceLocalView() const { - throw std::runtime_error("Epetra does not support device views!"); + throw std::runtime_error("Epetra does not support device views! in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); #ifndef __NVCC__ //prevent nvcc warning typename dual_view_type::t_dev_um ret; #endif @@ -1168,7 +1168,7 @@ const Epetra_IntVector & toEpetra(const Vector &) } typename dual_view_type::t_dev_um getDeviceLocalView() const { - throw std::runtime_error("Epetra does not support device views!"); + throw std::runtime_error("Epetra does not support device views! in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); #ifndef __NVCC__ //prevent nvcc warning typename dual_view_type::t_dev_um ret; #endif diff --git a/packages/xpetra/src/Vector/Xpetra_EpetraVector.hpp b/packages/xpetra/src/Vector/Xpetra_EpetraVector.hpp index 5241c9e14db5..7149b5832d31 100644 --- a/packages/xpetra/src/Vector/Xpetra_EpetraVector.hpp +++ b/packages/xpetra/src/Vector/Xpetra_EpetraVector.hpp @@ -201,7 +201,7 @@ class EpetraVectorT } typename dual_view_type::t_dev_um getDeviceLocalView() const { - throw std::runtime_error("Epetra does not support device views!"); + throw std::runtime_error("Epetra does not support device views! in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); #ifndef __NVCC__ //prevent nvcc warning typename dual_view_type::t_dev ret; #endif @@ -401,7 +401,7 @@ class EpetraVectorT } typename dual_view_type::t_dev_um getDeviceLocalView() const { - throw std::runtime_error("Epetra does not support device views!"); + throw std::runtime_error("Epetra does not support device views! in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); #ifndef __NVCC__ //prevent nvcc warning typename dual_view_type::t_dev ret; #endif @@ -597,7 +597,7 @@ class EpetraVectorT } typename dual_view_type::t_dev_um getDeviceLocalView() const { - throw std::runtime_error("Epetra does not support device views!"); + throw std::runtime_error("Epetra does not support device views! in "+std::string(__FILE__)+":"+std::to_string(__LINE__)); #ifndef __NVCC__ //prevent nvcc warning typename dual_view_type::t_dev ret; #endif