Skip to content

Commit

Permalink
Tpetra CrsGraph: Add method "getLocalOffRankOffsets"
Browse files Browse the repository at this point in the history
  • Loading branch information
cgcgcg committed Jun 7, 2021
1 parent 5768b2c commit 4838d21
Show file tree
Hide file tree
Showing 7 changed files with 519 additions and 30 deletions.
18 changes: 18 additions & 0 deletions packages/tpetra/core/src/Tpetra_CrsGraph_decl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ namespace Tpetra {
using nonconst_global_inds_host_view_type =
typename row_graph_type::nonconst_global_inds_host_view_type;

using offset_device_view_type =
typename row_ptrs_device_view_type::non_const_type;


//KDDKDD INROW using local_inds_host_view_type =
//KDDKDD INROW typename local_inds_dualv_type::t_host::const_type;
Expand Down Expand Up @@ -1387,6 +1390,10 @@ namespace Tpetra {
void
getLocalDiagOffsets (const Kokkos::View<size_t*, device_type, Kokkos::MemoryUnmanaged>& offsets) const;

/// \brief Get offsets of the off-rank entries in the graph.
void
getLocalOffRankOffsets (offset_device_view_type& offsets) const;

/// \brief Backwards compatibility overload of the above method.
///
/// This method takes a Teuchos::ArrayRCP instead of a
Expand Down Expand Up @@ -2064,6 +2071,8 @@ namespace Tpetra {
/// </ul>
void computeGlobalConstants ();

bool haveLocalOffRankOffsets() const { return haveLocalOffRankOffsets_;}

protected:
/// \brief Compute local constants, if they have not yet been computed.
///
Expand Down Expand Up @@ -2410,6 +2419,13 @@ namespace Tpetra {
/// This may also exist with 1-D storage, if storage is unpacked.
num_row_entries_type k_numRowEntries_;

/// \brief The offsets for off-rank entries.
///
/// When off-rank entries are sorted last, this rowPtr-lile view
/// contains the offsets. It is compute on the first call to
/// getLocalOffRankOffsets().
mutable offset_device_view_type k_offRankOffsets_;

//@}

/// \brief Status of the graph's storage, when not in a
Expand Down Expand Up @@ -2438,6 +2454,8 @@ namespace Tpetra {
bool haveLocalConstants_ = false;
//! Whether all processes have computed global constants.
bool haveGlobalConstants_ = false;
//!
mutable bool haveLocalOffRankOffsets_ = false;

typedef typename std::map<global_ordinal_type, std::vector<global_ordinal_type> > nonlocals_type;

Expand Down
58 changes: 58 additions & 0 deletions packages/tpetra/core/src/Tpetra_CrsGraph_def.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "Tpetra_Details_copyOffsets.hpp"
#include "Tpetra_Details_gathervPrint.hpp"
#include "Tpetra_Details_getGraphDiagOffsets.hpp"
#include "Tpetra_Details_getGraphOffRankOffsets.hpp"
#include "Tpetra_Details_makeColMap.hpp"
#include "Tpetra_Details_Profiling.hpp"
#include "Tpetra_Details_getEntryOnHost.hpp"
Expand Down Expand Up @@ -6701,6 +6702,60 @@ namespace Tpetra {
} // debug_
}

template <class LocalOrdinal, class GlobalOrdinal, class Node>
void
CrsGraph<LocalOrdinal, GlobalOrdinal, Node>::
getLocalOffRankOffsets (offset_device_view_type& offsets) const
{
using std::endl;
const char tfecfFuncName[] = "getLocalOffRankOffsets: ";
const bool verbose = verbose_;

std::unique_ptr<std::string> prefix;
if (verbose) {
prefix = this->createPrefix("CrsGraph", "getLocalOffRankOffsets");
std::ostringstream os;
os << *prefix << "offsets.extent(0)=" << offsets.extent(0)
<< endl;
std::cerr << os.str();
}

TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC
(! hasColMap (), std::runtime_error, "The graph must have a column Map.");
// Instead of throwing, we could also copy the rowPtr to k_offRankOffsets_.

const size_t lclNumRows = this->getNodeNumRows ();

if (haveLocalOffRankOffsets_ && k_offRankOffsets_.extent(0) == lclNumRows) {
offsets = k_offRankOffsets_;
return;
}
haveLocalOffRankOffsets_ = false;
k_offRankOffsets_ = offset_device_view_type(Kokkos::ViewAllocateWithoutInitializing("offRankOffset"), lclNumRows);
offsets = k_offRankOffsets_;

const map_type& colMap = * (this->getColMap ());
const map_type& domMap = * (this->getDomainMap ());

// mfh 12 Mar 2016: LocalMap works on (CUDA) device. It has just
// the subset of Map functionality that we need below.
auto lclColMap = colMap.getLocalMap ();
auto lclDomMap = domMap.getLocalMap ();

// FIXME (mfh 16 Dec 2015) It's easy to thread-parallelize this
// setup, at least on the host. For CUDA, we have to use LocalMap
// (that comes from each of the two Maps).

TEUCHOS_ASSERT(this->isSorted ());
if (isFillComplete ()) {
auto lclGraph = this->getLocalGraph ();
::Tpetra::Details::getGraphOffRankOffsets (k_offRankOffsets_,
lclColMap, lclDomMap,
lclGraph);
haveLocalOffRankOffsets_ = true;
}
}

namespace { // (anonymous)

// mfh 21 Jan 2016: This is useful for getLocalDiagOffsets (see
Expand Down Expand Up @@ -7551,6 +7606,7 @@ namespace Tpetra {

std::swap(graph.rowPtrsUnpacked_dev_, this->rowPtrsUnpacked_dev_);
std::swap(graph.rowPtrsUnpacked_host_, this->rowPtrsUnpacked_host_);
std::swap(graph.k_offRankOffsets_, this->k_offRankOffsets_);

std::swap(graph.lclIndsUnpacked_wdv, this->lclIndsUnpacked_wdv);
std::swap(graph.gblInds_wdv, this->gblInds_wdv);
Expand All @@ -7566,6 +7622,7 @@ namespace Tpetra {
std::swap(graph.noRedundancies_, this->noRedundancies_);
std::swap(graph.haveLocalConstants_, this->haveLocalConstants_);
std::swap(graph.haveGlobalConstants_, this->haveGlobalConstants_);
std::swap(graph.haveLocalOffRankOffsets_, this->haveLocalOffRankOffsets_);

std::swap(graph.sortGhostsAssociatedWithEachProcessor_, this->sortGhostsAssociatedWithEachProcessor_);

Expand Down Expand Up @@ -7628,6 +7685,7 @@ namespace Tpetra {
output = this->noRedundancies_ == graph.noRedundancies_ ? output : false;
output = this->haveLocalConstants_ == graph.haveLocalConstants_ ? output : false;
output = this->haveGlobalConstants_ == graph.haveGlobalConstants_ ? output : false;
output = this->haveLocalOffRankOffsets_ == graph.haveLocalOffRankOffsets_ ? output : false;
output = this->sortGhostsAssociatedWithEachProcessor_ == this->sortGhostsAssociatedWithEachProcessor_ ? output : false;

// Compare nonlocals_ -- std::map<GlobalOrdinal, std::vector<GlobalOrdinal> >
Expand Down
67 changes: 67 additions & 0 deletions packages/tpetra/core/src/Tpetra_Details_getGraphOffRankOffsets.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
// @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
*/

#include "TpetraCore_config.h"

#if defined(HAVE_TPETRA_EXPLICIT_INSTANTIATION)

// We protect the contents of this file with macros, to assist
// applications that circumvent Trilinos' build system. (We do NOT
// recommend this.) That way, they can still build this file, but as
// long as the macros have correct definitions, they won't build
// anything that's not enabled.

#include "KokkosCompat_ClassicNodeAPI_Wrapper.hpp"
#include "Tpetra_Details_getGraphOffRankOffsets_decl.hpp"
#include "Tpetra_Details_getGraphOffRankOffsets_def.hpp"
#include "TpetraCore_ETIHelperMacros.h"

namespace Tpetra {

TPETRA_ETI_MANGLING_TYPEDEFS()

TPETRA_INSTANTIATE_LGN( TPETRA_DETAILS_IMPL_GETGRAPHOFFRANKOFFSETS_INSTANT )

} // namespace Tpetra

#endif // Whether we should build this specialization
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
// @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_GETGRAPHOFFRANKOFFSETS_DECL_HPP
#define TPETRA_DETAILS_GETGRAPHOFFRANKOFFSETS_DECL_HPP

/// \file Tpetra_Details_getGraphOffRankOffsets_decl.hpp
/// \brief Declare and define the function
/// Tpetra::Details::getGraphOffRankOffsets, an implementation detail
/// of Tpetra::CrsGraph.

#include "TpetraCore_config.h"
#include "Kokkos_Core.hpp"
#include "Kokkos_StaticCrsGraph.hpp"
#include "Tpetra_Details_LocalMap.hpp"
#include <type_traits>

namespace Tpetra {
namespace Details {
namespace Impl {

/// \brief Implementation detail of
/// Tpetra::Details::getGraphOffRankOffsets, which in turn is an
/// implementation detail of Tpetra::CrsGraph.
///
/// FIXME (mfh 12 Mar 2016) There's currently no way to make a
/// MemoryUnmanaged Kokkos::StaticCrsGraph. Thus, we have to do this
/// separately for its column indices. We want the column indices to
/// be unmanaged because we need to take subviews in this kernel.
/// Taking a subview of a managed View updates the reference count,
/// which is a thread scalability bottleneck.
///
/// mfh 12 Mar 2016: Tpetra::CrsGraph::getLocalOffRankOffsets returns
/// offsets as size_t. However, see Github Issue #213.
template<class LO,
class GO,
class DeviceType,
class OffsetType = size_t>
class GetGraphOffRankOffsets {
public:
typedef typename DeviceType::device_type device_type;
typedef OffsetType offset_type;
typedef ::Kokkos::View<offset_type*,
device_type,
::Kokkos::MemoryUnmanaged> offsets_type;
typedef ::Kokkos::StaticCrsGraph<LO,
::Kokkos::LayoutLeft,
device_type,
void, size_t> local_graph_type;
typedef ::Tpetra::Details::LocalMap<LO, GO, device_type> local_map_type;
typedef ::Kokkos::View<const typename local_graph_type::size_type*,
::Kokkos::LayoutLeft,
device_type,
::Kokkos::MemoryUnmanaged> row_offsets_type;
// This is unmanaged for performance, because we need to take
// subviews inside the functor.
typedef ::Kokkos::View<const LO*,
::Kokkos::LayoutLeft,
device_type,
::Kokkos::MemoryUnmanaged> lcl_col_inds_type;

//! Constructor; also runs the functor.
GetGraphOffRankOffsets (const offsets_type& OffRankOffsets,
const local_map_type& lclColMap,
const local_map_type& lclDomMap,
const row_offsets_type& ptr,
const lcl_col_inds_type& ind);

//! Kokkos::parallel_for loop body.
KOKKOS_FUNCTION void operator() (const LO& lclRowInd) const;

private:
offsets_type OffRankOffsets_;
local_map_type lclColMap_;
local_map_type lclDomMap_;
row_offsets_type ptr_;
lcl_col_inds_type ind_;
LO lclNumRows_;
};

} // namespace Impl

template<class OffsetsType,
class LclMapType,
class LclGraphType>
void
getGraphOffRankOffsets (const OffsetsType& OffRankOffsets,
const LclMapType& lclColMap,
const LclMapType& lclDomMap,
const LclGraphType& lclGraph)
{
typedef typename OffsetsType::non_const_value_type offset_type;
typedef typename LclMapType::local_ordinal_type LO;
typedef typename LclMapType::global_ordinal_type GO;
typedef typename LclMapType::device_type DT;

typedef Impl::GetGraphOffRankOffsets<LO, GO, DT, offset_type> impl_type;

// The functor's constructor runs the functor.
impl_type impl (OffRankOffsets, lclColMap, lclDomMap, lclGraph.row_map, lclGraph.entries);
}

} // namespace Details
} // namespace Tpetra

#endif // TPETRA_DETAILS_GETGRAPHOFFRANKOFFSETS_DECL_HPP
Loading

0 comments on commit 4838d21

Please sign in to comment.