Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Tpetra_Details_KokkosCounter.cpp
1 /*
2 // @HEADER
3 // ***********************************************************************
4 //
5 // Tpetra: Templated Linear Algebra Services Package
6 // Copyright (2008) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // ************************************************************************
39 // @HEADER
40 */
42 #include "TpetraCore_config.h"
43 #include "Kokkos_Core.hpp"
44 #include "Teuchos_TestForException.hpp"
45 #include <cstring>
46 
47 namespace Tpetra {
48 namespace Details {
49 
50 
51  /***************************** Deep Copy *****************************/
52  namespace DeepCopyCounterDetails {
53  // Static variables
54  bool is_initialized=true;
55  size_t count_same=0;
56  size_t count_different=0;
57  bool count_active=false;
58 
59  void kokkosp_begin_deep_copy(Kokkos::Tools::SpaceHandle dst_handle, const char* dst_name, const void* dst_ptr,
60  Kokkos::Tools::SpaceHandle src_handle, const char* src_name, const void* src_ptr,
61  uint64_t size) {
62 
63  if(count_active) {
64  if(strcmp(dst_handle.name,src_handle.name))
65  count_different++;
66  else
67  count_same++;
68  }
69  }
70 
71  }// end DeepCopyCounterDetails
72 
73 
75  DeepCopyCounterDetails::count_active=true;
76  Kokkos::Tools::Experimental::set_begin_deep_copy_callback(DeepCopyCounterDetails::kokkosp_begin_deep_copy);
77  }
78 
80  DeepCopyCounterDetails::count_same=0;
81  DeepCopyCounterDetails::count_different=0;
82  }
83 
85  DeepCopyCounterDetails::count_active=false;
86  }
87 
89  return DeepCopyCounterDetails::count_same;
90  }
91 
93  return DeepCopyCounterDetails::count_different;
94  }
95 
96 
97 
98  /***************************** Fence *****************************/
99 
100 
101  namespace FenceCounterDetails {
102 
103  // Static variables
104  bool is_initialized=false;
105  bool count_active=false;
106  std::vector<size_t> count_instance;
107  std::vector<size_t> count_global;
108  int num_devices=0;
109 
110 
111  void kokkosp_begin_fence(const char* name, const uint32_t deviceId,
112  uint64_t* handle) {
113 
114  if(count_active) {
115  using namespace Kokkos::Tools::Experimental;
116  ExecutionSpaceIdentifier eid = identifier_from_devid(deviceId);
117 
118  // Figure out what count bin to stick this in
119  int idx = (int) eid.type;
120  if(eid.instance_id == Impl::int_for_synchronization_reason(SpecialSynchronizationCases::GlobalDeviceSynchronization))
121  count_global[idx]++;
122  else
123  count_instance[idx]++;
124  }
125  }
126 
127 
128  std::string get_label(int i) {
129  using namespace Kokkos::Tools::Experimental;
130  DeviceType i_type = devicetype_from_uint32t(i);
131  std::string device_label;
132  if (i_type == DeviceType::Serial) device_label="Serial";
133  else if (i_type == DeviceType::OpenMP) device_label="OpenMP";
134  else if (i_type == DeviceType::Cuda) device_label="Cuda";
135  else if (i_type == DeviceType::HIP) device_label="HIP";
136  else if (i_type == DeviceType::OpenMPTarget) device_label="OpenMPTarget";
137  else if (i_type == DeviceType::HPX) device_label="HPX";
138  else if (i_type == DeviceType::Threads) device_label="Threats";
139  else if (i_type == DeviceType::SYCL) device_label="SYCL";
140  else if (i_type == DeviceType::OpenACC) device_label="OpenACC";
141  else if (i_type == DeviceType::Unknown) device_label="Unknown";
142 
143  return device_label;
144  }
145 
146  void initialize() {
147  using namespace Kokkos::Tools::Experimental;
148  num_devices = (int) DeviceType::Unknown;
149  count_instance.resize(num_devices);
150  count_instance.assign(num_devices,0);
151  count_global.resize(num_devices);
152  count_global.assign(num_devices,0);
153  is_initialized=true;
154  }
155 
156  }// end FenceCounterDetails
157 
158 
159 
160 
162  if(!FenceCounterDetails::is_initialized)
163  FenceCounterDetails::initialize();
164  FenceCounterDetails::count_active=true;
165  Kokkos::Tools::Experimental::set_begin_fence_callback(FenceCounterDetails::kokkosp_begin_fence);
166  }
167 
169  FenceCounterDetails::count_instance.assign(FenceCounterDetails::num_devices,0);
170  FenceCounterDetails::count_global.assign(FenceCounterDetails::num_devices,0);
171  }
172 
174  FenceCounterDetails::count_active=false;
175  }
176 
177  size_t FenceCounter::get_count_global(const std::string & device) {
178  using namespace Kokkos::Tools::Experimental;
179  for(int i=0;i<FenceCounterDetails::num_devices; i++) {
180  std::string device_label = FenceCounterDetails::get_label(i);
181 
182  if(device == device_label)
183  return FenceCounterDetails::count_global[i];
184  }
185 
186  // Haven't found a device by this name
187  TEUCHOS_TEST_FOR_EXCEPTION(1,std::runtime_error,std::string("Error: ") + device + std::string(" is not a device known to Tpetra"));
188  }
189 
190 
191  size_t FenceCounter::get_count_instance(const std::string & device) {
192  using namespace Kokkos::Tools::Experimental;
193  for(int i=0;i<FenceCounterDetails::num_devices; i++) {
194  std::string device_label = FenceCounterDetails::get_label(i);
195 
196  if(device == device_label)
197  return FenceCounterDetails::count_instance[i];
198  }
199 
200  // Haven't found a device by this name
201  TEUCHOS_TEST_FOR_EXCEPTION(1,std::runtime_error,std::string("Error: ") + device + std::string(" is not a device known to Tpetra"));
202  }
203 
204 
205 
206 } // namespace Details
207 } // namespace Tpetra
208 
void initialize(int *argc, char ***argv)
Initialize Tpetra.
void reset()
Reset the deep_copy counter.
Declaration of various tools for counting Kokkos calls of various types using the Kokkos Profiling Li...
size_t get_count_same_space()
Query the deep_copy counter for copies in the same space.
size_t get_count_global(const std::string &device)
Query the fence counter for given device, for an Kokkos::fence()
void start()
Start the fence counter.
size_t get_count_different_space()
Query the deep_copy counter for copies between different spaces.
void reset()
Reset the fence counter.
void start()
Start the deep_copy counter.
size_t get_count_instance(const std::string &device)
Query the fence counter for given device, for an exec_space_instance.fence()
void stop()
Stop the deep_copy counter.