Skip to content

Commit

Permalink
Merge Pull Request #4747 from mhoemmen/Trilinos/Fix-4633-4639
Browse files Browse the repository at this point in the history
Automatically Merged using Trilinos Pull Request AutoTester
PR Title: Tpetra: Fix #4633 & #4639
PR Author: mhoemmen
  • Loading branch information
trilinos-autotester authored Mar 28, 2019
2 parents f488851 + 6a0d926 commit b44c2b2
Show file tree
Hide file tree
Showing 18 changed files with 1,014 additions and 509 deletions.
6 changes: 2 additions & 4 deletions packages/belos/tpetra/src/solvers/Belos_Tpetra_Cg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@ class Cg: public Krylov <SC, MV, OP> {
using base_type = Krylov<SC, MV, OP>;

public:
Cg () :
base_type::Krylov ()
{}
Cg () = default;

Cg (const Teuchos::RCP<const OP>& A) :
base_type::Krylov (A)
{}

virtual ~Cg () {}
virtual ~Cg () = default;

protected:
using vec_type = typename base_type::vec_type;
Expand Down
6 changes: 2 additions & 4 deletions packages/belos/tpetra/src/solvers/Belos_Tpetra_CgPipeline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@ class CgPipeline : public Krylov<SC, MV, OP> {
using base_type = Krylov<SC, MV, OP>;

public:
CgPipeline () :
base_type::Krylov ()
{}
CgPipeline () = default;

CgPipeline (const Teuchos::RCP<const OP>& A) :
base_type::Krylov (A)
{}

virtual ~CgPipeline () {}
virtual ~CgPipeline () = default;

protected:
using vec_type = typename base_type::vec_type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@ class CgSingleReduce: public Krylov<SC, MV, OP> {
using base_type = Krylov<SC, MV, OP>;

public:
CgSingleReduce () :
base_type::Krylov ()
{}
CgSingleReduce () = default;

CgSingleReduce (const Teuchos::RCP<const OP>& A) :
base_type::Krylov (A)
{}

virtual ~CgSingleReduce () {}
virtual ~CgSingleReduce () = default;

protected:
using vec_type = typename base_type::vec_type;
Expand Down
7 changes: 2 additions & 5 deletions packages/belos/tpetra/src/solvers/Belos_Tpetra_Gmres.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,16 +260,13 @@ class Gmres : public Krylov<SC, MV, OP> {
using dense_vector_type = Teuchos::SerialDenseVector<LO, SC>;

public:
Gmres () :
Krylov<SC, MV, OP>::Krylov ()
{}
Gmres () = default;

Gmres (const Teuchos::RCP<const OP>& A) :
Krylov<SC, MV, OP>::Krylov (A)
{}

virtual ~Gmres()
{}
virtual ~Gmres () = default;

virtual void
getParameters (Teuchos::ParameterList& params,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ class GmresPipeline : public Gmres<SC, MV, OP> {
this->input_.computeRitzValues = true;
}

virtual ~GmresPipeline ()
{}
virtual ~GmresPipeline () = default;

private:
SolverOutput<SC>
Expand Down
7 changes: 2 additions & 5 deletions packages/belos/tpetra/src/solvers/Belos_Tpetra_GmresS.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,13 @@ class GmresS : public Gmres<SC, MV, OP> {
using vec_type = typename Krylov<SC, MV, OP>::vec_type;

public:
GmresS () :
base_type::Gmres ()
{}
GmresS () = default;

GmresS (const Teuchos::RCP<const OP>& A) :
base_type::Gmres (A)
{}

virtual ~GmresS ()
{}
virtual ~GmresS () = default;

virtual void
setParameters (Teuchos::ParameterList& params) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ class GmresSingleReduce : public Gmres<SC, MV, OP> {
this->input_.computeRitzValues = true;
}

virtual ~GmresSingleReduce ()
{}
virtual ~GmresSingleReduce () = default;

virtual void
setParameters (Teuchos::ParameterList& params) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ class GmresSstep : public Gmres<SC, MV, OP> {
this->input_.computeRitzValues = true;
}

virtual ~GmresSstep ()
{}
virtual ~GmresSstep () = default;

virtual void
getParameters (Teuchos::ParameterList& params,
Expand Down
8 changes: 3 additions & 5 deletions packages/belos/tpetra/src/solvers/Belos_Tpetra_Krylov.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,15 @@ class Krylov {
using device_type = typename MV::device_type;

public:
Krylov () :
verbosity_ (0)
{}
Krylov () = default;

Krylov (const Teuchos::RCP<const OP>& A) :
Krylov ()
{
A_ = A;
}

virtual ~Krylov () {}
virtual ~Krylov () = default;

//! Set the matrix A in the linear system to solve.
void setMatrix (const Teuchos::RCP<const OP>& A) {
Expand Down Expand Up @@ -385,7 +383,7 @@ class Krylov {
Teuchos::RCP<const OP> A_;
std::string precoType_;
Teuchos::RCP<const OP> M_;
int verbosity_;
int verbosity_ = 0;
};

} // namespace Impl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class SolverManager :
params)
{}

virtual ~SolverManager () {}
virtual ~SolverManager () = default;

virtual Teuchos::RCP<Belos::SolverManager<SC, MV, OP> >
clone () const override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class SolverManagerBase :
}
}

virtual ~SolverManagerBase () {}
virtual ~SolverManagerBase () = default;

const linear_problem_type& getProblem () const override {
const char prefix[] = "SolverManagerBase::getProblem: ";
Expand Down
218 changes: 218 additions & 0 deletions packages/tpetra/core/src/Tpetra_Details_allReduceView.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
// @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 ([email protected])
//
// ************************************************************************
// @HEADER

#ifndef TPETRA_DETAILS_ALLREDUCEVIEW_HPP
#define TPETRA_DETAILS_ALLREDUCEVIEW_HPP

#include "Tpetra_Details_Behavior.hpp"
#include "Tpetra_Details_isInterComm.hpp"
#include "Kokkos_Core.hpp"
#include "Teuchos_CommHelpers.hpp"
#include <limits>
#include <type_traits>

/// \file Tpetra_Details_allReduceView.hpp
/// \brief All-reduce a 1-D or 2-D Kokkos::View

namespace { // (anonymous)

// We can't assume C++14 yet, so we can't have templated constants.
template<class ViewType>
struct view_is_cuda_uvm {
static constexpr bool value =
#ifdef KOKKOS_ENABLE_CUDA
std::is_same<typename ViewType::memory_space,
Kokkos::CudaUVMSpace>::value;
#else
false;
#endif // KOKKOS_ENABLE_CUDA
};

template<class ViewType>
struct MakeContiguousBuffer {
static constexpr bool is_contiguous_layout =
std::is_same<
typename ViewType::array_layout,
Kokkos::LayoutLeft>::value ||
std::is_same<
typename ViewType::array_layout,
Kokkos::LayoutRight>::value;
using contiguous_array_layout =
typename std::conditional<is_contiguous_layout,
typename ViewType::array_layout,
Kokkos::LayoutLeft>::type;
using contiguous_device_type =
typename std::conditional<
std::is_same<
typename ViewType::memory_space,
Kokkos::HostSpace>::value,
typename ViewType::device_type,
Kokkos::HostSpace::device_type>::type;
using contiguous_buffer_type =
Kokkos::View<typename ViewType::non_const_data_type,
contiguous_array_layout,
contiguous_device_type>;

static contiguous_array_layout
makeLayout (const ViewType& view)
{
// NOTE (mfh 17 Mar 2019) This would be a good chance to use if
// constexpr, once we have C++17.
return contiguous_array_layout (view.extent (0), view.extent (1),
view.extent (2), view.extent (3),
view.extent (4), view.extent (5),
view.extent (6), view.extent (7));
}

static contiguous_buffer_type
make (const ViewType& view)
{
using Kokkos::view_alloc;
using Kokkos::WithoutInitializing;
return contiguous_buffer_type
(view_alloc (view.label (), WithoutInitializing),
makeLayout (view));
}
};

template<class ViewType>
typename MakeContiguousBuffer<ViewType>::contiguous_buffer_type
makeContiguousBuffer (const ViewType& view)
{
return MakeContiguousBuffer<ViewType>::make (view);
}

template<class ValueType>
static void
allReduceRawContiguous (ValueType output[],
const ValueType input[],
const size_t count,
const Teuchos::Comm<int>& comm)
{
using Teuchos::outArg;
using Teuchos::REDUCE_SUM;
using Teuchos::reduceAll;
constexpr size_t max_int = size_t (std::numeric_limits<int>::max ());
TEUCHOS_ASSERT( count <= size_t (max_int) );
reduceAll<int, ValueType> (comm, REDUCE_SUM, static_cast<int> (count),
input, output);
}

} // namespace (anonymous)

namespace Tpetra {
namespace Details {

/// \brief All-reduce from input Kokkos::View to output Kokkos::View.
///
/// The two Views may alias one another.
template<class InputViewType, class OutputViewType>
static void
allReduceView (const OutputViewType& output,
const InputViewType& input,
const Teuchos::Comm<int>& comm)
{
// If all the right conditions hold, we may all-reduce directly from
// the input to the output. Here are the relevant conditions:
//
// - assumeMpiCanAccessBuffers: May we safely assume that MPI may
// read from the input View and write to the output View? (Just
// because MPI _can_, doesn't mean that doing so will be faster.)
// - Do input and output Views alias each other, and is the
// communicator an intercommunicator? (Intercommunicators do not
// permit collectives to alias input and output buffers.)
// - Is either View noncontiguous?
//
// If either View is noncontiguous, we could use MPI_Type_Vector to
// create a noncontiguous MPI_Datatype, instead of packing and
// unpacking to resp. from a contiguous temporary buffer. Since
// MPI_Allreduce requires that the input and output buffers both
// have the same MPI_Datatype, this optimization might only work if
// the MPI communicator is an intercommunicator. Furthermore,
// creating an MPI_Datatype instance may require memory allocation
// anyway. Thus, it's probably better just to use a temporary
// contiguous buffer. We use a host buffer for that, since device
// buffers are slow to allocate.

const bool viewsAlias = output.data () == input.data ();
if (comm.getSize () == 1) {
if (! viewsAlias) {
// InputViewType and OutputViewType can't be AnonymousSpace
// Views, because deep_copy needs to know their memory spaces.
Kokkos::deep_copy (output, input);
}
return;
}

// We've had some experience that some MPI implementations do not
// perform well with UVM allocations.
const bool assumeMpiCanAccessBuffers =
! view_is_cuda_uvm<OutputViewType>::value &&
! view_is_cuda_uvm<InputViewType>::value &&
::Tpetra::Details::Behavior::assumeMpiIsCudaAware ();

const bool needContiguousTemporaryBuffers =
! assumeMpiCanAccessBuffers ||
::Tpetra::Details::isInterComm (comm) ||
output.span_is_contiguous () || input.span_is_contiguous ();
if (needContiguousTemporaryBuffers) {
auto output_tmp = makeContiguousBuffer (output);
auto input_tmp = makeContiguousBuffer (input);
Kokkos::deep_copy (input_tmp, input);
// It's OK if LayoutLeft allocations have padding at the end of
// each row. MPI might write to those padding bytes, but it's
// undefined behavior for users to use Kokkos to access whatever
// bytes are there, and the bytes there don't need to define valid
// ValueType instances.
allReduceRawContiguous (output_tmp.data (), input_tmp.data (),
output_tmp.span (), comm);
Kokkos::deep_copy (output, output_tmp);
}
else {
allReduceRawContiguous (output.data (), input.data (),
output.span (), comm);
}
}

} // namespace Details
} // namespace Tpetra

#endif // TPETRA_DETAILS_ALLREDUCEVIEW_HPP
2 changes: 0 additions & 2 deletions packages/tpetra/core/src/Tpetra_Import_def.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,6 @@ namespace Tpetra {
ArrayView<const GO> targetGIDs = target->getNodeElementList ();
const size_type numSrcGids = sourceGIDs.size ();
const size_type numTgtGids = targetGIDs.size ();
const size_type numGids = std::min (numSrcGids, numTgtGids);
const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();

Array<GO> tRemoteGIDs;
if (this->verbose ()) {
Expand Down
Loading

0 comments on commit b44c2b2

Please sign in to comment.