Skip to content

Commit e0a49bb

Browse files
committed
[Code] Add lib logger and expose this feature into python api
1 parent f4d06cb commit e0a49bb

File tree

17 files changed

+462
-24
lines changed

17 files changed

+462
-24
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ This project is licensed under MIT License. License text can be found in the
268268
## Acknowledgments
269269
270270
This is a research project of the Programming Languages and Tools Laboratory
271-
at JetBrains Research company. Laboratory website [link](https://research.jetbrains.org/groups/plt_lab/).
271+
at JetBrains-Research. Laboratory website [link](https://research.jetbrains.org/groups/plt_lab/).
272272
273273
## Also
274274

cubool/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ set(CUBOOL_SOURCES
2121
sources/core/library.cpp
2222
sources/core/library.hpp
2323
sources/core/matrix.cpp
24-
sources/core/matrix.hpp)
24+
sources/core/matrix.hpp
25+
sources/io/logger.cpp
26+
sources/io/logger.hpp)
2527

2628
set(CUBOOL_C_API_SOURCES
2729
include/cubool/cubool.h
@@ -30,6 +32,7 @@ set(CUBOOL_C_API_SOURCES
3032
sources/cuBool_LicenseInfo_Get.cpp
3133
sources/cuBool_Initialize.cpp
3234
sources/cuBool_Finalize.cpp
35+
sources/cuBool_SetupLogger.cpp
3336
sources/cuBool_Matrix_New.cpp
3437
sources/cuBool_Matrix_Build.cpp
3538
sources/cuBool_Matrix_ExtractPairs.cpp

cubool/include/cubool/cubool.h

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,13 @@ typedef enum cuBool_Hint {
8383
/** Accumulate result of the operation in the result matrix */
8484
CUBOOL_HINT_ACCUMULATE = 0x8,
8585
/** Finalize library state, even if not all resources were explicitly released */
86-
CUBOOL_HINT_RELAXED_FINALIZE = 0x16
86+
CUBOOL_HINT_RELAXED_FINALIZE = 0x16,
87+
/** Logging hint: log error message */
88+
CUBOOL_HINT_LOG_ERROR = 0x32,
89+
/** Logging hint: log warning message */
90+
CUBOOL_HINT_LOG_WARNING = 0x64,
91+
/** Logging hint: log all messages */
92+
CUBOOL_HINT_LOG_ALL = 0x128,
8793
} cuBool_Hint;
8894

8995
/** Hit mask */
@@ -141,6 +147,26 @@ CUBOOL_EXPORT CUBOOL_API cuBool_Status cuBool_Version_Get(
141147
int* sub
142148
);
143149

150+
/**
151+
* Allows to setup logging file for all operations, invoked after this function call.
152+
* Empty hints field is interpreted as `CUBOOL_HINT_LOG_ALL` by default.
153+
*
154+
* @note It is safe to call this function before the library is initialized.
155+
*
156+
* @note Pass `CUBOOL_HINT_LOG_ERROR` to include error messages into log
157+
* @note Pass `CUBOOL_HINT_LOG_WARNING` to include warning messages into log
158+
* @note Pass `CUBOOL_HINT_LOG_ALL` to include all messages into log
159+
*
160+
* @param logFileName File name in the encoding of the target platform.
161+
* @param hints Logging hints to filter messages.
162+
*
163+
* @return Error code on this operation
164+
*/
165+
CUBOOL_EXPORT CUBOOL_API cuBool_Status cuBool_SetupLogging(
166+
const char* logFileName,
167+
cuBool_Hints hints
168+
);
169+
144170
/**
145171
* Initialize library instance object, which provides context to all library operations and primitives.
146172
* This function must be called before any other library function is called,
@@ -171,13 +197,13 @@ CUBOOL_EXPORT CUBOOL_API cuBool_Status cuBool_Finalize(
171197
/**
172198
* Query device capabilities/properties if cuda compatible device is present.
173199
*
174-
* @note This function must be called only for cuda backend.
200+
* @note This function returns no actual info if cuda backend is not presented.
175201
* @param deviceCaps Pointer to device caps structure to store result
176202
*
177203
* @return Error if cuda device not present or if failed to query capabilities
178204
*/
179205
CUBOOL_EXPORT CUBOOL_API cuBool_Status cuBool_DeviceCaps_Get(
180-
CuBool_DeviceCaps* deviceCaps
206+
CuBool_DeviceCaps* deviceCaps
181207
);
182208

183209
/**

cubool/sources/core/library.cpp

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@
2727
#include <core/matrix.hpp>
2828
#include <backend/backend_base.hpp>
2929
#include <backend/matrix_base.hpp>
30+
#include <io/logger.hpp>
31+
32+
#include <fstream>
3033
#include <iostream>
34+
#include <memory>
35+
#include <iomanip>
3136

3237
#ifdef CUBOOL_WITH_CUDA
3338
#include <cuda/cuda_backend.hpp>
@@ -41,6 +46,7 @@ namespace cubool {
4146

4247
std::unordered_set<class MatrixBase*> Library::mAllocated;
4348
BackendBase* Library::mBackend = nullptr;
49+
std::shared_ptr<class Logger> Library::mLogger = std::make_shared<DummyLogger>();
4450
bool Library::mRelaxedRelease = false;
4551

4652
void Library::initialize(hints initHints) {
@@ -58,6 +64,8 @@ namespace cubool {
5864
if (!mBackend->isInitialized()) {
5965
delete mBackend;
6066
mBackend = nullptr;
67+
68+
mLogger->logWarning("Failed to initialize Cuda backend");
6169
}
6270
#endif
6371
}
@@ -71,6 +79,8 @@ namespace cubool {
7179
if (!mBackend->isInitialized()) {
7280
delete mBackend;
7381
mBackend = nullptr;
82+
83+
mLogger->logWarning("Failed to initialize Cpu fallback backend");
7484
}
7585
}
7686
#endif
@@ -101,6 +111,62 @@ namespace cubool {
101111
CHECK_RAISE_CRITICAL_ERROR(mBackend != nullptr || mRelaxedRelease, InvalidState, "Library is not initialized");
102112
}
103113

114+
void Library::setupLogging(const char *logFileName, cuBool_Hints hints) {
115+
CHECK_RAISE_ERROR(logFileName != nullptr, InvalidArgument, "Null file name is not allowed");
116+
117+
auto lofFile = std::make_shared<std::ofstream>();
118+
119+
lofFile->open(logFileName, std::ios::out);
120+
121+
if (!lofFile->is_open()) {
122+
RAISE_ERROR(InvalidArgument, "Failed to create logging file");
123+
}
124+
125+
// Create logger and setup filters && post-actions
126+
auto textLogger = std::make_shared<TextLogger>();
127+
128+
textLogger->addFilter([=](Logger::Level level, const std::string& message) -> bool {
129+
bool all = hints == 0x0 || (hints & CUBOOL_HINT_LOG_ALL);
130+
bool error = hints & CUBOOL_HINT_LOG_ERROR;
131+
bool warning = hints & CUBOOL_HINT_LOG_WARNING;
132+
133+
return all ||
134+
(error && level == Logger::Level::Error) ||
135+
(warning && level == Logger::Level::Warning);
136+
});
137+
138+
textLogger->addOnLoggerAction([=](size_t id, Logger::Level level, const std::string& message) {
139+
auto& file = *lofFile;
140+
141+
const auto idSize = 10;
142+
const auto levelSize = 20;
143+
144+
file << "[" << std::setw(idSize) << id << std::setw(-1) << "]";
145+
file << "[" << std::setw(levelSize);
146+
switch (level) {
147+
case Logger::Level::Info:
148+
file << "Level::Info";
149+
break;
150+
case Logger::Level::Warning:
151+
file << "Level::Warning";
152+
break;
153+
case Logger::Level::Error:
154+
file << "Level::Error";
155+
break;
156+
default:
157+
file << "Level::Always";
158+
}
159+
file << std::setw(-1) << "] ";
160+
file << message << std::endl << std::endl;
161+
});
162+
163+
// Assign new text logger
164+
mLogger = textLogger;
165+
166+
// Initial message
167+
mLogger->logInfo("*** cuBool::Logger file ***");
168+
}
169+
104170
MatrixBase *Library::createMatrix(size_t nrows, size_t ncols) {
105171
CHECK_RAISE_ERROR(nrows > 0, InvalidArgument, "Cannot create matrix with zero dimension");
106172
CHECK_RAISE_ERROR(ncols > 0, InvalidArgument, "Cannot create matrix with zero dimension");
@@ -118,7 +184,11 @@ namespace cubool {
118184
}
119185

120186
void Library::handleError(const std::exception& error) {
121-
std::cerr << "cuBool:Error: " << error.what() << std::endl;
187+
mLogger->log(Logger::Level::Error, error.what());
188+
}
189+
190+
class Logger * Library::getLogger() {
191+
return mLogger.get();
122192
}
123193

124194
}

cubool/sources/core/library.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,16 @@ namespace cubool {
3737
static void initialize(hints initHints);
3838
static void finalize();
3939
static void validate();
40+
static void setupLogging(const char* logFileName, cuBool_Hints hints);
4041
static class MatrixBase *createMatrix(size_t nrows, size_t ncols);
4142
static void releaseMatrix(class MatrixBase *matrixBase);
4243
static void handleError(const std::exception& error);
44+
static class Logger* getLogger();
4345

4446
private:
4547
static std::unordered_set<class MatrixBase*> mAllocated;
4648
static class BackendBase* mBackend;
49+
static std::shared_ptr<class Logger> mLogger;
4750
static bool mRelaxedRelease;
4851
};
4952

cubool/sources/cuBool_SetupLogger.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**********************************************************************************/
2+
/* MIT License */
3+
/* */
4+
/* Copyright (c) 2020, 2021 JetBrains-Research */
5+
/* */
6+
/* Permission is hereby granted, free of charge, to any person obtaining a copy */
7+
/* of this software and associated documentation files (the "Software"), to deal */
8+
/* in the Software without restriction, including without limitation the rights */
9+
/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
10+
/* copies of the Software, and to permit persons to whom the Software is */
11+
/* furnished to do so, subject to the following conditions: */
12+
/* */
13+
/* The above copyright notice and this permission notice shall be included in all */
14+
/* copies or substantial portions of the Software. */
15+
/* */
16+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
17+
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
18+
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
19+
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
20+
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
21+
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
22+
/* SOFTWARE. */
23+
/**********************************************************************************/
24+
25+
#include <cuBool_Common.hpp>
26+
27+
cuBool_Status cuBool_SetupLogging(
28+
const char* logFileName,
29+
cuBool_Hints hints
30+
) {
31+
CUBOOL_BEGIN_BODY
32+
cubool::Library::setupLogging(logFileName, hints);
33+
CUBOOL_END_BODY
34+
}

cubool/sources/io/logger.cpp

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/**********************************************************************************/
2+
/* MIT License */
3+
/* */
4+
/* Copyright (c) 2020, 2021 JetBrains-Research */
5+
/* */
6+
/* Permission is hereby granted, free of charge, to any person obtaining a copy */
7+
/* of this software and associated documentation files (the "Software"), to deal */
8+
/* in the Software without restriction, including without limitation the rights */
9+
/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
10+
/* copies of the Software, and to permit persons to whom the Software is */
11+
/* furnished to do so, subject to the following conditions: */
12+
/* */
13+
/* The above copyright notice and this permission notice shall be included in all */
14+
/* copies or substantial portions of the Software. */
15+
/* */
16+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
17+
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
18+
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
19+
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
20+
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
21+
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
22+
/* SOFTWARE. */
23+
/**********************************************************************************/
24+
25+
#include <io/logger.hpp>
26+
27+
namespace cubool {
28+
29+
void Logger::logInfo(const std::string &message) {
30+
this->log(Level::Info, message);
31+
}
32+
33+
void Logger::logWarning(const std::string &message) {
34+
this->log(Level::Warning, message);
35+
}
36+
37+
void Logger::logError(const std::string &message) {
38+
this->log(Level::Error, message);
39+
}
40+
41+
void TextLogger::log(Logger::Level level, const std::string &message) {
42+
bool pass = true;
43+
44+
// If pass all filters
45+
for (const auto& filter: mFilters) {
46+
pass = pass && filter(level, message);
47+
}
48+
49+
if (pass || level == Level::Always) {
50+
auto id = mNextMessageId++;
51+
52+
Entry entry;
53+
entry.message = message;
54+
entry.level = level;
55+
entry.id = id;
56+
57+
mEntries.emplace_back(std::move(entry));
58+
59+
// Notify listeners
60+
for (const auto& action: mOnLogged) {
61+
action(id, level, message);
62+
}
63+
}
64+
}
65+
66+
size_t TextLogger::getMessagesCount() const {
67+
return mEntries.size();
68+
}
69+
70+
void TextLogger::addFilter(Filter filter) {
71+
mFilters.emplace_back(std::move(filter));
72+
}
73+
74+
void TextLogger::removeAllFilters() {
75+
mFilters.clear();
76+
}
77+
78+
void TextLogger::addOnLoggerAction(OnLogged onLogged) {
79+
mOnLogged.emplace_back(std::move(onLogged));
80+
}
81+
82+
void TextLogger::removeAllOnLoggedActions() {
83+
mOnLogged.clear();
84+
}
85+
86+
void DummyLogger::log(Logger::Level level, const std::string &message) {
87+
// no op.
88+
}
89+
90+
size_t DummyLogger::getMessagesCount() const {
91+
return 0;
92+
}
93+
}

0 commit comments

Comments
 (0)