Skip to content

Commit 9615bb4

Browse files
authored
Merge pull request #38184 from mantidproject/ornlAlgoTimeRegister
Enable Profiling on Linux
2 parents 6165add + 3827721 commit 9615bb4

File tree

10 files changed

+340
-62
lines changed

10 files changed

+340
-62
lines changed

CMakePresets.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@
5959
"inherits": [
6060
"ci-default",
6161
"conda"
62-
]
62+
],
63+
"cacheVariables": {
64+
"PROFILE_ALGORITHM_LINUX": "ON"
65+
}
6366
},
6467
{
6568
"name": "win-64-ci",
@@ -120,7 +123,10 @@
120123
"inherits": [
121124
"unix-debug",
122125
"conda"
123-
]
126+
],
127+
"cacheVariables": {
128+
"PROFILE_ALGORITHM_LINUX": "ON"
129+
}
124130
},
125131
{
126132
"name": "win-vs-2019",

Framework/API/CMakeLists.txt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -363,14 +363,6 @@ set(INC_FILES
363363
inc/MantidAPI/Workspace_fwd.h
364364
)
365365

366-
option(PROFILE_ALGORITHM_LINUX "Profile algorithm execution on Linux" OFF)
367-
if(PROFILE_ALGORITHM_LINUX)
368-
set(SRC_FILES "${SRC_FILES}" "src/AlgorithmExecuteProfile.cpp" "src/AlgoTimeRegister.cpp")
369-
set(INC_FILES "${INC_FILES}" "inc/MantidAPI/AlgoTimeRegister.h")
370-
else()
371-
set(SRC_FILES "${SRC_FILES}" "src/AlgorithmExecute.cpp")
372-
endif()
373-
374366
set(TEST_FILES
375367
ADSValidatorTest.h
376368
AlgorithmFactoryObserverTest.h
@@ -490,6 +482,15 @@ set(TEST_FILES
490482
WorkspaceUnitValidatorTest.h
491483
)
492484

485+
option(PROFILE_ALGORITHM_LINUX "Profile algorithm execution on Linux" OFF)
486+
if(PROFILE_ALGORITHM_LINUX)
487+
set(SRC_FILES "${SRC_FILES}" "src/AlgorithmExecuteProfile.cpp" "src/AlgoTimeRegister.cpp")
488+
set(INC_FILES "${INC_FILES}" "inc/MantidAPI/AlgoTimeRegister.h")
489+
set(TEST_FILES "${TEST_FILES}" "AlgoTimeRegisterTest.h")
490+
else()
491+
set(SRC_FILES "${SRC_FILES}" "src/AlgorithmExecute.cpp")
492+
endif()
493+
493494
set(GMOCK_TEST_FILES ImplicitFunctionFactoryTest.h ImplicitFunctionParameterParserFactoryTest.h MatrixWorkspaceTest.h)
494495

495496
if(COVERAGE)

Framework/API/inc/MantidAPI/AlgoTimeRegister.h

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
// SPDX - License - Identifier: GPL - 3.0 +
77
#pragma once
88

9+
#include "MantidKernel/Logger.h"
10+
#include "MantidKernel/SingletonHolder.h"
911
#include "MantidKernel/Timer.h"
1012
#include <mutex>
1113
#include <thread>
@@ -19,42 +21,47 @@ namespace Instrumentation {
1921
/** AlgoTimeRegister : simple class to dump information about executed
2022
* algorithms
2123
*/
22-
class AlgoTimeRegister {
24+
class MANTID_API_DLL AlgoTimeRegisterImpl {
2325
public:
24-
static AlgoTimeRegister globalAlgoTimeRegister;
25-
struct Info {
26-
std::string m_name;
27-
std::thread::id m_threadId;
28-
Kernel::time_point_ns m_begin;
29-
Kernel::time_point_ns m_end;
30-
31-
Info(const std::string &nm, const std::thread::id &id, const Kernel::time_point_ns &be,
32-
const Kernel::time_point_ns &en)
33-
: m_name(nm), m_threadId(id), m_begin(be), m_end(en) {}
34-
};
26+
AlgoTimeRegisterImpl(const AlgoTimeRegisterImpl &) = delete;
27+
AlgoTimeRegisterImpl &operator=(const AlgoTimeRegisterImpl &) = delete;
3528

3629
class Dump {
37-
AlgoTimeRegister &m_algoTimeRegister;
3830
Kernel::time_point_ns m_regStart_chrono;
39-
4031
const std::string m_name;
4132

4233
public:
43-
Dump(AlgoTimeRegister &atr, const std::string &nm);
34+
Dump(const std::string &nm);
4435
~Dump();
4536
};
4637

4738
void addTime(const std::string &name, const std::thread::id thread_id, const Kernel::time_point_ns &begin,
4839
const Kernel::time_point_ns &end);
4940
void addTime(const std::string &name, const Kernel::time_point_ns &begin, const Kernel::time_point_ns &end);
50-
AlgoTimeRegister();
51-
~AlgoTimeRegister();
5241

53-
private:
5442
std::mutex m_mutex;
55-
std::vector<Info> m_info;
43+
44+
private:
45+
friend struct Mantid::Kernel::CreateUsingNew<AlgoTimeRegisterImpl>;
46+
47+
AlgoTimeRegisterImpl();
48+
~AlgoTimeRegisterImpl();
49+
50+
bool writeToFile();
51+
5652
Kernel::time_point_ns m_start;
53+
std::string m_filename;
54+
bool m_hasWrittenToFile;
5755
};
5856

57+
using AlgoTimeRegister = Mantid::Kernel::SingletonHolder<AlgoTimeRegisterImpl>;
58+
5959
} // namespace Instrumentation
6060
} // namespace Mantid
61+
62+
namespace Mantid {
63+
namespace Kernel {
64+
EXTERN_MANTID_API template class MANTID_API_DLL
65+
Mantid::Kernel::SingletonHolder<Mantid::Instrumentation::AlgoTimeRegisterImpl>;
66+
} // namespace Kernel
67+
} // namespace Mantid

Framework/API/src/AlgoTimeRegister.cpp

Lines changed: 65 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,44 +12,84 @@
1212
namespace Mantid {
1313
namespace Instrumentation {
1414

15+
namespace {
16+
Kernel::Logger &LOGGER() {
17+
static Kernel::Logger logger("AlgoTimeRegister");
18+
return logger;
19+
}
20+
} // namespace
21+
22+
using Kernel::ConfigService;
1523
using Kernel::time_point_ns;
1624

17-
AlgoTimeRegister::Dump::Dump(AlgoTimeRegister &atr, const std::string &nm)
18-
: m_algoTimeRegister(atr), m_regStart_chrono(std::chrono::high_resolution_clock::now()), m_name(nm) {}
25+
AlgoTimeRegisterImpl::Dump::Dump(const std::string &nm)
26+
: m_regStart_chrono(std::chrono::high_resolution_clock::now()), m_name(nm) {}
1927

20-
AlgoTimeRegister::Dump::~Dump() {
28+
AlgoTimeRegisterImpl::Dump::~Dump() {
2129
const time_point_ns regFinish = std::chrono::high_resolution_clock::now();
22-
{
23-
std::lock_guard<std::mutex> lock(m_algoTimeRegister.m_mutex);
24-
m_algoTimeRegister.addTime(m_name, std::this_thread::get_id(), m_regStart_chrono, regFinish);
25-
}
30+
{ AlgoTimeRegister::Instance().addTime(m_name, std::this_thread::get_id(), m_regStart_chrono, regFinish); }
2631
}
2732

28-
void AlgoTimeRegister::addTime(const std::string &name, const std::thread::id thread_id,
29-
const Kernel::time_point_ns &begin, const Kernel::time_point_ns &end) {
30-
m_info.emplace_back(name, thread_id, begin, end);
33+
void AlgoTimeRegisterImpl::addTime(const std::string &name, const Kernel::time_point_ns &begin,
34+
const Kernel::time_point_ns &end) {
35+
AlgoTimeRegister::Instance().addTime(name, std::this_thread::get_id(), begin, end);
3136
}
3237

33-
void AlgoTimeRegister::addTime(const std::string &name, const Kernel::time_point_ns &begin,
34-
const Kernel::time_point_ns &end) {
35-
this->addTime(name, std::this_thread::get_id(), begin, end);
36-
}
38+
bool AlgoTimeRegisterImpl::writeToFile() {
39+
auto writeEnable = Kernel::ConfigService::Instance().getValue<bool>("performancelog.write").value();
40+
if (!writeEnable) {
41+
LOGGER().debug() << "performancelog.write is disabled (off/0/false)\n";
42+
return false;
43+
}
44+
auto filename = Kernel::ConfigService::Instance().getString("performancelog.filename");
45+
if (filename.empty()) {
46+
LOGGER().debug() << "performancelog.filename is empty, please provide valid filename\n";
47+
return false;
48+
}
49+
if (m_filename == filename && m_hasWrittenToFile) {
50+
return true;
51+
}
52+
53+
m_filename = filename;
3754

38-
AlgoTimeRegister::AlgoTimeRegister() : m_start(std::chrono::high_resolution_clock::now()) {}
55+
LOGGER().debug() << "Performance log file: " << m_filename << '\n';
3956

40-
AlgoTimeRegister::~AlgoTimeRegister() {
4157
std::fstream fs;
42-
fs.open("./algotimeregister.out", std::ios::out);
43-
// c++20 has an implementation of operator<<
44-
fs << "START_POINT: " << std::chrono::duration_cast<std::chrono::nanoseconds>(m_start.time_since_epoch()).count()
45-
<< " MAX_THREAD: " << PARALLEL_GET_MAX_THREADS << "\n";
46-
for (auto &elem : m_info) {
47-
const std::chrono::nanoseconds st = elem.m_begin - m_start;
48-
const std::chrono::nanoseconds fi = elem.m_end - m_start;
49-
fs << "ThreadID=" << elem.m_threadId << ", AlgorithmName=" << elem.m_name << ", StartTime=" << st.count()
50-
<< ", EndTime=" << fi.count() << "\n";
58+
59+
fs.open(m_filename, std::ios::out);
60+
if (fs.is_open()) {
61+
fs << "START_POINT: " << std::chrono::duration_cast<std::chrono::nanoseconds>(m_start.time_since_epoch()).count()
62+
<< " MAX_THREAD: " << PARALLEL_GET_MAX_THREADS << "\n";
63+
fs.close();
64+
m_hasWrittenToFile = true;
65+
} else {
66+
LOGGER().notice() << "Failed to open the file, timing will not write to file.\n";
67+
return false;
5168
}
69+
return true;
5270
}
5371

72+
void AlgoTimeRegisterImpl::addTime(const std::string &name, const std::thread::id thread_id,
73+
const Kernel::time_point_ns &begin, const Kernel::time_point_ns &end) {
74+
std::lock_guard<std::mutex> lock(AlgoTimeRegister::Instance().m_mutex);
75+
if (writeToFile()) {
76+
std::fstream fs;
77+
fs.open(m_filename, std::ios::out | std::ios::app);
78+
if (fs.is_open()) {
79+
const std::chrono::nanoseconds st = begin - m_start;
80+
const std::chrono::nanoseconds fi = end - m_start;
81+
fs << "ThreadID=" << thread_id << ", AlgorithmName=" << name << ", StartTime=" << st.count()
82+
<< ", EndTime=" << fi.count() << "\n";
83+
84+
fs.close();
85+
}
86+
}
87+
}
88+
89+
AlgoTimeRegisterImpl::AlgoTimeRegisterImpl()
90+
: m_start(std::chrono::high_resolution_clock::now()), m_hasWrittenToFile(false) {}
91+
92+
AlgoTimeRegisterImpl::~AlgoTimeRegisterImpl() {}
93+
5494
} // namespace Instrumentation
5595
} // namespace Mantid

Framework/API/src/AlgorithmExecuteProfile.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include "MantidAPI/Algorithm.h"
99

1010
namespace Mantid {
11-
Instrumentation::AlgoTimeRegister Instrumentation::AlgoTimeRegister::globalAlgoTimeRegister;
1211
namespace API {
1312

1413
//---------------------------------------------------------------------------------------------
@@ -23,13 +22,13 @@ namespace API {
2322
* @return true if executed successfully.
2423
*/
2524
bool Algorithm::execute() {
26-
Instrumentation::AlgoTimeRegister::AlgoTimeRegister::Dump dmp(
27-
Instrumentation::AlgoTimeRegister::globalAlgoTimeRegister, name());
25+
Instrumentation::AlgoTimeRegister::Instance();
26+
Instrumentation::AlgoTimeRegisterImpl::Dump dmp(name());
2827
return executeInternal();
2928
}
3029
void Algorithm::addTimer(const std::string &name, const Kernel::time_point_ns &begin,
3130
const Kernel::time_point_ns &end) {
32-
Instrumentation::AlgoTimeRegister::globalAlgoTimeRegister.addTime(name, begin, end);
31+
Instrumentation::AlgoTimeRegister::Instance().addTime(name, begin, end);
3332
}
3433
} // namespace API
3534
} // namespace Mantid

0 commit comments

Comments
 (0)