Skip to content

Commit ad4c0ef

Browse files
authored
Merge pull request #2 from solvcon/feature/profile
Add a simple profiler
2 parents 9b94eda + c264915 commit ad4c0ef

File tree

8 files changed

+224
-1
lines changed

8 files changed

+224
-1
lines changed

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,18 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "Export compile commands")
1414
option(HIDE_SYMBOL "hide the symbols of python wrapper" OFF)
1515
message(STATUS "HIDE_SYMBOL: ${HIDE_SYMBOL}")
1616

17+
option(DEBUG_SYMBOL "add debug information" ON)
18+
message(STATUS "DEBUG_SYMBOL: ${DEBUG_SYMBOL}")
1719
if(DEBUG_SYMBOL)
1820
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
1921
endif()
2022

23+
option(MODMESH_PROFILE "enable profiler" OFF)
24+
message(STATUS "MODMESH_PROFILE: ${MODMESH_PROFILE}")
25+
if(MODMESH_PROFILE)
26+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMODMESH_PROFILE")
27+
endif()
28+
2129
option(pybind11_path "pybind11 path")
2230
find_package(pybind11 REQUIRED PATHS ${pybind11_path})
2331
message(STATUS "pybind11_INCLUDE_DIRS: ${pybind11_INCLUDE_DIRS}")
@@ -32,6 +40,7 @@ include_directories("include")
3240
set(MODMESH_HEADERS
3341
include/modmesh/modmesh.hpp
3442
include/modmesh/base.hpp
43+
include/modmesh/profile.hpp
3544
include/modmesh/grid.hpp
3645
)
3746
string(REPLACE "include/" "${CMAKE_CURRENT_SOURCE_DIR}/include/"

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
HIDE_SYMBOL ?= OFF
1212
DEBUG_SYMBOL ?= ON
13+
MODMESH_PROFILE ?= OFF
1314
USE_CLANG_TIDY ?= OFF
1415
CMAKE_BUILD_TYPE ?= Release
1516
MODMESH_ROOT ?= $(shell pwd)
@@ -70,6 +71,7 @@ $(BUILD_PATH)/Makefile: CMakelists.txt Makefile
7071
-DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) \
7172
-DHIDE_SYMBOL=$(HIDE_SYMBOL) \
7273
-DDEBUG_SYMBOL=$(DEBUG_SYMBOL) \
74+
-DMODMESH_PROFILE=$(MODMESH_PROFILE) \
7375
-DUSE_CLANG_TIDY=$(USE_CLANG_TIDY) \
7476
-DLINT_AS_ERRORS=ON \
7577
$(CMAKE_ARGS)

include/modmesh/base.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
// Shared by all code.
1212
#include <algorithm>
1313
#include <memory>
14+
#include <iostream>
15+
#include <map>
1416

1517
#define MODMESH_EXCEPT(CLS, EXC, MSG) throw EXC(#CLS ": " MSG);
1618

include/modmesh/grid.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*/
1111

1212
#include "modmesh/base.hpp"
13+
#include "modmesh/profile.hpp"
1314

1415
namespace modmesh
1516
{
@@ -87,6 +88,12 @@ class StaticGrid1d
8788
real_type at (size_t it) const { ensure_range(it); return (*this)[it]; }
8889
real_type & at (size_t it) { ensure_range(it); return (*this)[it]; }
8990

91+
void fill(real_type val)
92+
{
93+
MODMESH_TIME("StaticGrid1d::fill");
94+
std::fill(m_coord.get(), m_coord.get()+m_nx, val);
95+
}
96+
9097
private:
9198

9299
std::unique_ptr<real_type[]> allocate(serial_type nx)

include/modmesh/modmesh.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include "modmesh/base.hpp"
9+
#include "modmesh/profile.hpp"
910
#include "modmesh/grid.hpp"
1011

1112
// vim: set ff=unix fenc=utf8 et sw=4 ts=4 sts=4:

include/modmesh/profile.hpp

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
#pragma once
2+
3+
/*
4+
* Copyright (c) 2019, Yung-Yu Chen <[email protected]>
5+
* BSD-style license; see COPYING
6+
*/
7+
8+
#include "modmesh/base.hpp"
9+
10+
/*
11+
* MODMESH_PROFILE defined: Enable profiling API.
12+
*/
13+
#ifdef MODMESH_PROFILE
14+
15+
#define MODMESH_TIME(NAME) \
16+
ScopedTimer local_scoped_timer_ ## __LINE__(NAME);
17+
18+
/*
19+
* No MODMESH_PROFILE defined: Disable profiling API.
20+
*/
21+
#else // MODMESH_PROFILE
22+
23+
#define MODMESH_TIME(NAME)
24+
25+
#endif // MODMESH_PROFILE
26+
/*
27+
* End MODMESH_PROFILE.
28+
*/
29+
30+
namespace modmesh
31+
{
32+
33+
#if __APPLE__
34+
35+
#include <assert.h>
36+
#include <CoreServices/CoreServices.h>
37+
#include <mach/mach.h>
38+
#include <mach/mach_time.h>
39+
40+
struct StopWatch
41+
{
42+
43+
StopWatch()
44+
{
45+
mach_timebase_info(&m_tbinfo);
46+
lap();
47+
}
48+
49+
double lap()
50+
{
51+
m_start = m_end;
52+
m_end = mach_absolute_time();
53+
uint64_t elapsed = m_end - m_start;
54+
return elapsed * m_tbinfo.numer / m_tbinfo.denom * 1.e-9;
55+
}
56+
57+
/// A global singleton.
58+
static StopWatch & me()
59+
{
60+
static StopWatch instance;
61+
return instance;
62+
}
63+
64+
mach_timebase_info_data_t m_tbinfo;
65+
uint64_t m_start = 0;
66+
uint64_t m_end = 0;
67+
68+
}; /* end struct StopWatch */
69+
70+
#elif __linux__
71+
72+
#include <time.h>
73+
74+
struct StopWatch
75+
{
76+
StopWatch()
77+
{
78+
clock_getres(CLOCK_PROCESS_CPUTIME_ID, &m_res);
79+
lap();
80+
}
81+
82+
double lap()
83+
{
84+
m_start = m_end;
85+
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &m_end);
86+
return diff(m_start, m_end) * 1.e-9;
87+
}
88+
89+
int64_t diff(timespec const & t1, timespec const & t2)
90+
{
91+
timespec temp;
92+
int64_t nsec;
93+
if ((t2.tv_nsec - t1.tv_nsec)<0)
94+
{
95+
nsec = 1000000000 + t2.tv_nsec - t1.tv_nsec;
96+
nsec += 1000000000 * (t2.tv_sec - t1.tv_sec - 1);
97+
}
98+
else
99+
{
100+
nsec = t2.tv_nsec - t1.tv_nsec;
101+
nsec += 1000000000 * (t2.tv_sec - t1.tv_sec);
102+
}
103+
return nsec;
104+
}
105+
106+
/// A global singleton.
107+
static StopWatch & me()
108+
{
109+
static StopWatch instance;
110+
return instance;
111+
}
112+
113+
timespec m_res;
114+
timespec m_start;
115+
timespec m_end;
116+
117+
}; /* end struct StopWatch */
118+
119+
#endif
120+
121+
struct TimedEntry
122+
{
123+
size_t m_count = 0;
124+
double m_time = 0.0;
125+
}; /* end struct TimedEntry */
126+
127+
class TimeRegistry
128+
{
129+
130+
public:
131+
132+
static TimeRegistry & me()
133+
{
134+
static TimeRegistry inst;
135+
return inst;
136+
}
137+
138+
void add(const char * name, double time)
139+
{
140+
auto it = m_time.find(name);
141+
if (it == m_time.end())
142+
{
143+
it = std::get<0>(m_time.insert({name, {0, 0.0}}));
144+
}
145+
++(it->second.m_count);
146+
it->second.m_time += time;
147+
}
148+
149+
~TimeRegistry()
150+
{
151+
for (auto it = m_time.begin() ; it != m_time.end() ; ++it)
152+
{
153+
std::cout
154+
<< it->first << " : "
155+
<< "count = " << it->second.m_count << " , "
156+
<< "time = " << it->second.m_time << " (second)"
157+
<< std::endl;
158+
}
159+
}
160+
161+
private:
162+
163+
TimeRegistry()
164+
{
165+
}
166+
167+
std::map<const char *, TimedEntry> m_time;
168+
169+
}; /* end struct TimeRegistry */
170+
171+
struct ScopedTimer
172+
{
173+
174+
ScopedTimer() = delete;
175+
176+
ScopedTimer(const char * name) : m_name(name) {}
177+
178+
~ScopedTimer()
179+
{
180+
TimeRegistry::me().add(m_name, m_sw.lap());
181+
}
182+
183+
StopWatch m_sw;
184+
char const * m_name;
185+
186+
}; /* end struct ScopedTimer */
187+
188+
} /* end namespace modmesh */
189+
190+
// vim: set ff=unix fenc=utf8 et sw=4 ts=4 sts=4:

include/modmesh/python/python.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ WrapBase
7878
#define DECL_MM_PYBIND_CLASS_METHOD(METHOD) \
7979
template< class... Args > \
8080
/* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \
81-
wrapper_type & METHOD(Args&&... args) { \
81+
wrapper_type & METHOD(Args&&... args) \
82+
{ \
8283
m_cls.METHOD(std::forward<Args>(args)...); \
8384
return *static_cast<wrapper_type*>(this); \
8485
}
@@ -230,6 +231,12 @@ class WrapStaticGrid1d
230231
}
231232
}
232233
)
234+
.def
235+
(
236+
"fill"
237+
, &wrapped_type::fill
238+
, py::arg("value")
239+
)
233240
;
234241

235242
}

tests/test_grid1d.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,9 @@ def check_life_cycle():
3939
coord = check_life_cycle()
4040
self.assertEqual([0, 1, 2, 3, 4], coord.tolist())
4141

42+
def test_fill(self):
43+
44+
gd = modmesh.StaticGrid1d(11)
45+
gd.fill(102)
46+
4247
# vim: set ff=unix fenc=utf8 et sw=4 ts=4 sts=4:

0 commit comments

Comments
 (0)