diff --git a/packages/tpetra/core/test/CrsMatrix/CMakeLists.txt b/packages/tpetra/core/test/CrsMatrix/CMakeLists.txt index 4a95212376ec..914cf4910d57 100644 --- a/packages/tpetra/core/test/CrsMatrix/CMakeLists.txt +++ b/packages/tpetra/core/test/CrsMatrix/CMakeLists.txt @@ -490,6 +490,16 @@ TRIBITS_ADD_EXECUTABLE_AND_TEST( STANDARD_PASS_OUTPUT ) +TRIBITS_ADD_EXECUTABLE_AND_TEST( + CrsMatrix_MatvecFence + SOURCES + CrsMatrix_MatvecFence.cpp + ${TEUCHOS_STD_UNIT_TEST_MAIN} + COMM mpi + STANDARD_PASS_OUTPUT + ) + + if ( # supported TPLs ( diff --git a/packages/tpetra/core/test/CrsMatrix/CrsMatrix_MatvecFence.cpp b/packages/tpetra/core/test/CrsMatrix/CrsMatrix_MatvecFence.cpp new file mode 100644 index 000000000000..c6f1cfc6c9b2 --- /dev/null +++ b/packages/tpetra/core/test/CrsMatrix/CrsMatrix_MatvecFence.cpp @@ -0,0 +1,245 @@ +/* +// @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_TestingUtilities.hpp" +#include "Tpetra_MultiVector.hpp" +#include "Tpetra_CrsMatrix.hpp" +#include "Tpetra_CrsMatrixMultiplyOp.hpp" +#include "Tpetra_Apply_Helpers.hpp" +#include "TpetraUtils_MatrixGenerator.hpp" +#include "Tpetra_Details_Profiling.hpp" +#include "Tpetra_Details_KokkosCounter.hpp" +#include "Tpetra_Details_Behavior.hpp" +#include // std::is_same + +#include + +namespace { + + // no ScalarTraits<>::eps() for integer types + + + using std::endl; + + using Teuchos::as; + using Teuchos::FancyOStream; + using Teuchos::RCP; + using Teuchos::ArrayRCP; + using Teuchos::rcp; + using Teuchos::arcp; + using Teuchos::outArg; + using Teuchos::broadcast; + using Teuchos::OrdinalTraits; + using Teuchos::ScalarTraits; + using Teuchos::Comm; + using Teuchos::Array; + using Teuchos::ArrayView; + using Teuchos::tuple; + using Teuchos::null; + using Teuchos::VERB_NONE; + using Teuchos::VERB_LOW; + using Teuchos::VERB_MEDIUM; + using Teuchos::VERB_HIGH; + using Teuchos::VERB_EXTREME; + using Teuchos::ETransp; + using Teuchos::NO_TRANS; + using Teuchos::TRANS; + using Teuchos::CONJ_TRANS; + using Teuchos::EDiag; + using Teuchos::UNIT_DIAG; + using Teuchos::NON_UNIT_DIAG; + using Teuchos::EUplo; + using Teuchos::UPPER_TRI; + using Teuchos::LOWER_TRI; + using Teuchos::ParameterList; + using Teuchos::parameterList; + + using Tpetra::Map; + using Tpetra::MultiVector; + using Tpetra::Vector; + using Tpetra::Operator; + using Tpetra::CrsMatrix; + using Tpetra::CrsGraph; + using Tpetra::RowMatrix; + using Tpetra::Import; + using Tpetra::global_size_t; + using Tpetra::createContigMapWithNode; + + + // + // UNIT TESTS + // + + TEUCHOS_UNIT_TEST_TEMPLATE_4_DECL( CrsMatrix, MatvecFence, LO, GO, Scalar, Node ) + { + + typedef ScalarTraits ST; + typedef CrsMatrix MAT; + typedef MultiVector MV; + typedef typename ST::magnitudeType Mag; + + // This code is left in in case people want to debug future issues using the Kokkos profiling + // hooks in Tpetra + RCP > comm = Tpetra::getDefaultComm(); + Teuchos::RCP stacked_timer = rcp(new Teuchos::StackedTimer("TransferPerf")); + Teuchos::TimeMonitor::setStackedTimer(stacked_timer); + int numRanks = comm->getSize(); + + const size_t nsize=3; + + /* Create the identity matrix, three rows per proc */ + RCP A1 = Tpetra::Utils::MatrixGenerator::generate_miniFE_matrix(nsize, comm); + if(!A1->isFillComplete()) A1->fillComplete(); + auto map = A1->getRowMap(); + + RCP X = rcp(new MV(map,1)); + RCP Y = rcp(new MV(map,1)); + X->putScalar(Teuchos::ScalarTraits::one()); + Y->putScalar(Teuchos::ScalarTraits::zero()); + + Teuchos::Array normX(1); + + const Scalar alpha = Teuchos::ScalarTraits::one(), beta = Teuchos::ScalarTraits::zero(); + + { + Tpetra::Details::ProfilingRegion r ("Sacrificial Matvec"); + A1->apply(*X,*Y,Teuchos::NO_TRANS, alpha, beta); + } + + + // Check to make sure we have the right number of H2D/D2H transfers + using namespace Tpetra::Details; + FenceCounter::reset(); + FenceCounter::start(); + size_t iter_num = 10; + + { + Tpetra::Details::ProfilingRegion r ("Matvec Loop"); + + for (size_t i = 0; i < iter_num; i ++) { + A1->apply(*X,*Y,Teuchos::NO_TRANS, alpha, beta); + X->update(-1.0, *Y, 1.0); + X->norm2(normX()); + } + } + FenceCounter::stop(); + + auto exec_space = typename Node::execution_space(); + size_t expectedGlobalCount = 0; + size_t expectedInstanceCount = 0; + if (numRanks == 1) { + expectedGlobalCount = 0; + if (Node::is_cpu) { + expectedInstanceCount = iter_num; + } else { + expectedInstanceCount = 2*iter_num; + } + } else { +#if defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_SERIAL) + // OpenMP in a Serial+OpenMP build + if (Node::is_cpu && !Node::is_serial) +#else + // OpenMP in an OpenMP build, Serial in a Serial or Serial+Cuda build + if (Node::is_cpu) +#endif + { + if (Tpetra::Details::Behavior::assumeMpiIsGPUAware()) { + expectedGlobalCount = iter_num; + } else { + expectedGlobalCount = 0; + } + if (Tpetra::Details::Behavior::debug()) { + expectedInstanceCount = 3*iter_num; + } else { + expectedInstanceCount = 2*iter_num; + } + } +#ifdef HAVE_TPETRA_INST_OPENMP + // Serial in a OpenMP+Serial build + else if (Node::is_serial) { + // Did not test the case of Serial node in build with Serial and OpenMP and GPU-aware + expectedGlobalCount = iter_num; + if (Tpetra::Details::Behavior::debug()) { + expectedInstanceCount = 4*iter_num; + } else { + expectedInstanceCount = 3*iter_num; + } + } +#endif + else { + if (Tpetra::Details::Behavior::assumeMpiIsGPUAware()) { + expectedGlobalCount = iter_num; + } else { + expectedGlobalCount = 6 * iter_num; + } + if (Tpetra::Details::Behavior::debug()) { + expectedInstanceCount = 5*iter_num; + } else { + expectedInstanceCount = 3*iter_num; + } + } + } + + TEST_EQUALITY(FenceCounter::get_count_global(exec_space.name()), expectedGlobalCount); + TEST_EQUALITY(FenceCounter::get_count_instance(exec_space.name()), expectedInstanceCount); + + stacked_timer->stopBaseTimer(); + Teuchos::StackedTimer::OutputOptions options; + options.output_fraction = options.output_histogram = options.output_minmax = true; + stacked_timer->report(out, comm, options); + + } + + +// +// INSTANTIATIONS +// + +#define UNIT_TEST_GROUP( SCALAR, LO, GO, NODE ) \ + TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT( CrsMatrix, MatvecFence, LO, GO, SCALAR, NODE ) + + TPETRA_ETI_MANGLING_TYPEDEFS() + + TPETRA_INSTANTIATE_SLGN( UNIT_TEST_GROUP ) + +}