Skip to content

Commit

Permalink
Merge Pull Request #12303 from trilinos/Trilinos/csiefer-47d5db2
Browse files Browse the repository at this point in the history
Automatically Merged using Trilinos Pull Request AutoTester
PR Title: b'Tpetra: Updates to deep_copy / fence counting tools'
PR Author: csiefer2
  • Loading branch information
trilinos-autotester authored Sep 27, 2023
2 parents 8f2db99 + ff6158f commit 55108f7
Show file tree
Hide file tree
Showing 5 changed files with 358 additions and 118 deletions.
2 changes: 1 addition & 1 deletion packages/tpetra/core/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -937,5 +937,5 @@ SET_PROPERTY(
# / from this directory, or to / from the 'impl' subdirectory. That ensures
# that running "make" will also rerun CMake in order to regenerate Makefiles.
#
# Here's another change
# Here's another change. Again.

91 changes: 0 additions & 91 deletions packages/tpetra/core/src/Tpetra_Details_DeepCopyCounter.cpp

This file was deleted.

208 changes: 208 additions & 0 deletions packages/tpetra/core/src/Tpetra_Details_KokkosCounter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
/*
// @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.
//
// ************************************************************************
// @HEADER
*/
#include "Tpetra_Details_KokkosCounter.hpp"
#include "TpetraCore_config.h"
#include "Kokkos_Core.hpp"
#include "Teuchos_TestForException.hpp"
#include <cstring>

namespace Tpetra {
namespace Details {


/***************************** Deep Copy *****************************/
namespace DeepCopyCounterDetails {
// Static variables
bool is_initialized=true;
size_t count_same=0;
size_t count_different=0;
bool count_active=false;

void kokkosp_begin_deep_copy(Kokkos::Tools::SpaceHandle dst_handle, const char* dst_name, const void* dst_ptr,
Kokkos::Tools::SpaceHandle src_handle, const char* src_name, const void* src_ptr,
uint64_t size) {

if(count_active) {
if(strcmp(dst_handle.name,src_handle.name))
count_different++;
else
count_same++;
}
}

}// end DeepCopyCounterDetails


void DeepCopyCounter::start() {
DeepCopyCounterDetails::count_active=true;
Kokkos::Tools::Experimental::set_begin_deep_copy_callback(DeepCopyCounterDetails::kokkosp_begin_deep_copy);
}

void DeepCopyCounter::reset() {
DeepCopyCounterDetails::count_same=0;
DeepCopyCounterDetails::count_different=0;
}

void DeepCopyCounter::stop() {
DeepCopyCounterDetails::count_active=false;
}

size_t DeepCopyCounter::get_count_same_space() {
return DeepCopyCounterDetails::count_same;
}

size_t DeepCopyCounter::get_count_different_space() {
return DeepCopyCounterDetails::count_different;
}



/***************************** Fence *****************************/


namespace FenceCounterDetails {

// Static variables
bool is_initialized=false;
bool count_active=false;
std::vector<size_t> count_instance;
std::vector<size_t> count_global;
int num_devices=0;


void kokkosp_begin_fence(const char* name, const uint32_t deviceId,
uint64_t* handle) {

if(count_active) {
using namespace Kokkos::Tools::Experimental;
ExecutionSpaceIdentifier eid = identifier_from_devid(deviceId);

// Figure out what count bin to stick this in
int idx = (int) eid.type;
if(eid.instance_id == Impl::int_for_synchronization_reason(SpecialSynchronizationCases::GlobalDeviceSynchronization))
count_global[idx]++;
else
count_instance[idx]++;
}
}


std::string get_label(int i) {
using namespace Kokkos::Tools::Experimental;
DeviceType i_type = devicetype_from_uint32t(i);
std::string device_label;
if (i_type == DeviceType::Serial) device_label="Serial";
else if (i_type == DeviceType::OpenMP) device_label="OpenMP";
else if (i_type == DeviceType::Cuda) device_label="Cuda";
else if (i_type == DeviceType::HIP) device_label="HIP";
else if (i_type == DeviceType::OpenMPTarget) device_label="OpenMPTarget";
else if (i_type == DeviceType::HPX) device_label="HPX";
else if (i_type == DeviceType::Threads) device_label="Threats";
else if (i_type == DeviceType::SYCL) device_label="SYCL";
else if (i_type == DeviceType::OpenACC) device_label="OpenACC";
else if (i_type == DeviceType::Unknown) device_label="Unknown";

return device_label;
}

void initialize() {
using namespace Kokkos::Tools::Experimental;
num_devices = (int) DeviceType::Unknown;
count_instance.resize(num_devices);
count_instance.assign(num_devices,0);
count_global.resize(num_devices);
count_global.assign(num_devices,0);
is_initialized=true;
}

}// end FenceCounterDetails




void FenceCounter::start() {
if(!FenceCounterDetails::is_initialized)
FenceCounterDetails::initialize();
FenceCounterDetails::count_active=true;
Kokkos::Tools::Experimental::set_begin_fence_callback(FenceCounterDetails::kokkosp_begin_fence);
}

void FenceCounter::reset() {
FenceCounterDetails::count_instance.assign(FenceCounterDetails::num_devices,0);
FenceCounterDetails::count_global.assign(FenceCounterDetails::num_devices,0);
}

void FenceCounter::stop() {
FenceCounterDetails::count_active=false;
}

size_t FenceCounter::get_count_global(const std::string & device) {
using namespace Kokkos::Tools::Experimental;
for(int i=0;i<FenceCounterDetails::num_devices; i++) {
std::string device_label = FenceCounterDetails::get_label(i);

if(device == device_label)
return FenceCounterDetails::count_global[i];
}

// Haven't found a device by this name
TEUCHOS_TEST_FOR_EXCEPTION(1,std::runtime_error,std::string("Error: ") + device + std::string(" is not a device known to Tpetra"));
}


size_t FenceCounter::get_count_instance(const std::string & device) {
using namespace Kokkos::Tools::Experimental;
for(int i=0;i<FenceCounterDetails::num_devices; i++) {
std::string device_label = FenceCounterDetails::get_label(i);

if(device == device_label)
return FenceCounterDetails::count_instance[i];
}

// Haven't found a device by this name
TEUCHOS_TEST_FOR_EXCEPTION(1,std::runtime_error,std::string("Error: ") + device + std::string(" is not a device known to Tpetra"));
}



} // namespace Details
} // namespace Tpetra

Original file line number Diff line number Diff line change
Expand Up @@ -38,40 +38,57 @@
// ************************************************************************
// @HEADER
*/
#ifndef TPETRA_DETAILS_DEEP_COPY_COUNTER_HPP
#define TPETRA_DETAILS_DEEP_COPY_COUNTER_HPP
#ifndef TPETRA_DETAILS_KOKKOS_COUNTER_HPP
#define TPETRA_DETAILS_KOKKOS_COUNTER_HPP

/// \file Tpetra_Details_DeepCopyCounter.hpp
/// \brief Declaration of Tpetra::Details::DeepCopyCounter, a class that
/// uses Kokkos' profiling library to count deep copies between memory spaces
/// \file Tpetra_Details_KokkosCounter.hpp
/// \brief Declaration of various tools for counting Kokkos calls of various
/// types using the Kokkos Profiling Library

#include <cstddef>
#include <string>

namespace Tpetra {
namespace Details {

/// \brief Counter for Kokkos::deep_copy's between memory spaces.
class DeepCopyCounter {
public:
/// \brief Counter for Kokkos::deep_copy calls
namespace DeepCopyCounter {
/// \brief Start the deep_copy counter
static void start();
void start();

/// \brief Reset the deep_copy counter
static void reset();
void reset();

/// \brief Stop the deep_copy counter
static size_t stop();
void stop();

/// \brief Query the deep_copy counter
static size_t get_count();
/// \brief Query the deep_copy counter for copies in the same space
size_t get_count_same_space();

/// \brief Query the deep_copy counter for copies between different spaces
size_t get_count_different_space();

static size_t count;
static bool count_active;
}

/// \brief Counter for Kokkos::fence calls
namespace FenceCounter {
/// \brief Start the fence counter
void start();

/// \brief Reset the fence counter
void reset();

/// \brief Stop the fence counter
void stop();

/// \brief Query the fence counter for given device, for an exec_space_instance.fence()
size_t get_count_instance(const std::string & device);

/// \brief Query the fence counter for given device, for an Kokkos::fence()
size_t get_count_global(const std::string & device);
}

};

} // namespace Details
} // namespace Tpetra

#endif // TPETRA_DETAILS_DEEP_COPY_COUNTER_HPP
#endif // TPETRA_DETAILS_KOKKOS_COUNTER_HPP
Loading

0 comments on commit 55108f7

Please sign in to comment.