SIRIUS 7.5.0
Electronic structure library and applications
cuda_timer.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2017 Anton Kozhevnikov, Thomas Schulthess
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
5// the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8// following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
10// and the following disclaimer in the documentation and/or other materials provided with the distribution.
11//
12// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
13// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
15// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
17// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
18// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
20/** \file cuda_timer.hpp
21 *
22 * \brief Timer for CUDA kernels.
23 */
24
25#ifndef __CUDA_TIMER_HPP__
26#define __CUDA_TIMER_HPP__
27
28#include <map>
29#include <vector>
30#include <string>
31#include <stdio.h>
32
33namespace sirius {
34
36{
37 private:
38
39 std::map<std::string, std::vector<float> > cuda_timers_;
40
41 public:
42
43 void add_measurment(std::string const& label, float value)
44 {
45 cuda_timers_[label].push_back(value / 1000);
46 }
47
48 void print()
49 {
50 std::printf("\n");
51 std::printf("CUDA timers \n");
52 for (int i = 0; i < 115; i++) std::printf("-");
53 std::printf("\n");
54 std::printf("name count total min max average\n");
55 for (int i = 0; i < 115; i++) std::printf("-");
56 std::printf("\n");
57
58 std::map<std::string, std::vector<float> >::iterator it;
59 for (it = cuda_timers_.begin(); it != cuda_timers_.end(); it++) {
60 int count = (int)it->second.size();
61 double total = 0.0;
62 float minval = 1e10;
63 float maxval = 0.0;
64 for (int i = 0; i < count; i++) {
65 total += it->second[i];
66 minval = std::min(minval, it->second[i]);
67 maxval = std::max(maxval, it->second[i]);
68 }
69 double average = (count == 0) ? 0.0 : total / count;
70 if (count == 0) {
71 minval = 0.0;
72 }
73
74 std::printf("%-60s : %5i %10.4f %10.4f %10.4f %10.4f\n", it->first.c_str(), count, total, minval, maxval, average);
75 }
76 }
77};
78
80{
81 private:
82
83 cudaEvent_t e_start_;
84 cudaEvent_t e_stop_;
85 bool active_;
86 std::string label_;
87
88 void start()
89 {
90 cudaEventCreate(&e_start_);
91 cudaEventCreate(&e_stop_);
92 cudaEventRecord(e_start_, 0);
93 }
94
95 void stop()
96 {
97 float time;
98 cudaEventRecord(e_stop_, 0);
99 cudaEventSynchronize(e_stop_);
100 cudaEventElapsedTime(&time, e_start_, e_stop_);
101 cudaEventDestroy(e_start_);
102 cudaEventDestroy(e_stop_);
103 cuda_timers_wrapper().add_measurment(label_, time);
104 active_ = false;
105 }
106
107 public:
108
109 CUDA_timer(std::string const& label__) : label_(label__), active_(false)
110 {
111 start();
112 }
113
115 {
116 stop();
117 }
118
119 static CUDA_timers_wrapper& cuda_timers_wrapper()
120 {
121 static CUDA_timers_wrapper cuda_timers_wrapper_;
122 return cuda_timers_wrapper_;
123 }
124};
125
126} // namespace sirius
127
128#endif
Namespace of the SIRIUS library.
Definition: sirius.f90:5