Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
7b58655
add buffer logging, allows printing before thrown errors
cderb Jan 5, 2026
714367a
limit buffered logs to I2, output on error log, add OutputBufferedLog…
cderb Jan 6, 2026
593859a
add throws to the error log
cderb Jan 6, 2026
921eff1
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 6, 2026
d00a31f
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 7, 2026
ab89678
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 8, 2026
f7d9f9f
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 12, 2026
41fc8f6
set log buffer to thread_local variable, add unit test
cderb Jan 14, 2026
18380ad
cleanup logging definition
cderb Jan 14, 2026
f60e7d6
add doc description of log env var
cderb Jan 14, 2026
edad330
update log buffer gtest
cderb Jan 14, 2026
a88cf62
add to change log, split gtest for log buffer
cderb Jan 14, 2026
28a7d5e
Update projects/miopen/docs/how-to/debug-log.rst
cderb Jan 15, 2026
9623a71
Apply suggestions from code review
cderb Jan 15, 2026
c054b41
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 15, 2026
9ca0d36
add hostname to log dump notification
cderb Jan 15, 2026
20a700b
Merge branch 'users/cderb/log_buffer' of https://github.com/ROCm/rocm…
cderb Jan 15, 2026
5972d14
Merge branch 'develop' into users/cderb/log_buffer
JonathanLichtnerAMD Jan 17, 2026
6350f04
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 19, 2026
7646a34
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 20, 2026
f020c71
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 21, 2026
f21816d
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 21, 2026
bcf774e
correction to log buffer index
cderb Jan 22, 2026
57c06fb
clean includes
cderb Jan 22, 2026
21b0cbb
tidy
cderb Jan 23, 2026
7979070
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 23, 2026
b368c32
clear dump file for buffer test
cderb Jan 23, 2026
b08d92d
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 26, 2026
6b2416c
Merge remote-tracking branch 'origin/develop' into users/cderb/log_bu…
cderb Jan 27, 2026
f1440fa
global namespace for getpid
cderb Jan 27, 2026
a7d465d
add getpid for win
cderb Jan 27, 2026
21709c3
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 28, 2026
8d30e92
update log buffering functions
cderb Jan 28, 2026
b144060
Merge branch 'users/cderb/log_buffer' of https://github.com/ROCm/rocm…
cderb Jan 28, 2026
2c62b97
error fix
cderb Jan 28, 2026
0c2b191
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 28, 2026
d56b20c
nolint
cderb Jan 28, 2026
bc49ce2
add function to clear buffer
cderb Jan 28, 2026
74d2135
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 29, 2026
bd1959e
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 29, 2026
9ebf13f
Merge branch 'develop' into users/cderb/log_buffer
cderb Jan 29, 2026
adec567
Merge branch 'develop' into users/cderb/log_buffer
cderb Feb 2, 2026
ebb0b06
add test corrections for windows
cderb Feb 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions projects/miopen/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Full documentation for MIOpen is available [here](https://rocm.docs.amd.com/proj
* [BatchNorm] Added V3 batch normalization API with separate running statistics buffers (prevResultRunningMean/Variance and nextResultRunningMean/Variance)
* [BatchNorm] New API entry-points `miopenBatchNormalizationForwardInferenceInvVariance` and
`miopenBatchNormForwardInferenceActivationInvVariance` to support hipDNN.
* Recent logs dumped to file (`/tmp/miopen_error_<pid>`) on error log or MIOpen throw.
* [Conv] Enabled CK wrw and bwd solvers with split-k disabled in deterministic mode.
* [Conv] Added initial Composable Kernel (CK) support for RDNA3.X and RDNA4

Expand Down
6 changes: 6 additions & 0 deletions projects/miopen/docs/how-to/debug-log.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ environmental variables to control logging. Both variables are disabled by defau

* ``MIOPEN_WARN_SEARCH``: Elevate log messages for Search to warnings.

* ``MIOPEN_LOG_BUFFER_SIZE``: Message length of the Info2 buffer.
If ``MIOPEN_LOG_LEVEL`` is less than 6, then log messages will be buffered.
The buffered logs will be dumped to a log file when MIOpen logs an error message,
or an error is thrown by MIOpen.
This log can be found in ``/tmp/miopen_error_<pid>``.

.. note::

If you require technical support, include the console log that is produced from these settings:
Expand Down
5 changes: 4 additions & 1 deletion projects/miopen/src/include/miopen/errors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <exception>
#include <iostream>
#include <miopen/logger.hpp>
#include <miopen/miopen.h>
#include <miopen/object.hpp>
#include <miopen/returns.hpp>
Expand Down Expand Up @@ -63,7 +64,9 @@ MIOPEN_EXPORT std::string HIPErrorMessage(int error, const std::string& msg = ""
template <class... Params>
[[noreturn]] void MIOpenThrow(const std::string& file, int line, Params&&... args)
{
throw miopen::Exception(std::forward<Params>(args)...).SetContext(file, line);
auto exe = miopen::Exception(std::forward<Params>(args)...);
MIOPEN_LOG_E_FROM(file + ":" + std::to_string(line), exe.message);
throw exe.SetContext(file, line);
}

#define MIOPEN_THROW(...) \
Expand Down
42 changes: 31 additions & 11 deletions projects/miopen/src/include/miopen/logger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,17 @@
#include <type_traits>
#include <chrono>

#include <miopen/each_args.hpp>
#include <miopen/object.hpp>
#include <miopen/config.hpp>

#if MIOPEN_USE_ROCTRACER
#include <roctracer/roctx.h>
#endif

#ifdef _WIN32
MIOPEN_INTERNALS_EXPORT size_t getpid();
#endif

// See https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms
#define MIOPEN_PP_CAT(x, y) MIOPEN_PP_PRIMITIVE_CAT(x, y)
#define MIOPEN_PP_PRIMITIVE_CAT(x, y) x##y
Expand Down Expand Up @@ -364,16 +367,33 @@ constexpr std::string_view LoggingParseFunction(const std::string_view func,
#define MIOPEN_GET_FN_NAME miopen::LoggingParseFunction(__func__, __PRETTY_FUNCTION__)
#endif

#define MIOPEN_LOG_XQ_CUSTOM(level, disableQuieting, category, fn_name, ...) \
do \
{ \
if(miopen::IsLogging(level, disableQuieting)) \
{ \
std::ostringstream miopen_log_ss; \
miopen_log_ss << miopen::LoggingPrefix() << category << " [" << fn_name << "] " \
<< __VA_ARGS__ << std::endl; \
std::cerr << miopen_log_ss.str(); \
} \
MIOPEN_INTERNALS_EXPORT void ClearBufferLog();

MIOPEN_INTERNALS_EXPORT void BufferLog(std::string line);

MIOPEN_INTERNALS_EXPORT void OutputBufferedLogs();

#define MIOPEN_LOG_XQ_CUSTOM(level, disableQuieting, category, fn_name, ...) \
do \
{ \
std::ostringstream miopen_log_ss; \
miopen_log_ss << miopen::LoggingPrefix() << category << " [" << fn_name << "] " \
<< __VA_ARGS__ << std::endl; \
if(miopen::IsLogging(level, disableQuieting)) \
{ \
std::cerr << miopen_log_ss.str(); \
} \
if(!miopen::IsLogging(miopen::LoggingLevel::Info2, disableQuieting)) \
{ \
if(level < miopen::LoggingLevel::Trace) \
{ \
miopen::BufferLog(miopen_log_ss.str()); \
} \
if(level == miopen::LoggingLevel::Error) \
{ \
miopen::OutputBufferedLogs(); \
} \
} \
} while(false)

#define MIOPEN_LOG_XQ_(level, disableQuieting, fn_name, ...) \
Expand Down
47 changes: 47 additions & 0 deletions projects/miopen/src/logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
*
*******************************************************************************/
#include <miopen/env.hpp>
#include <miopen/filesystem.hpp>
#include <miopen/logger.hpp>
#include <miopen/config.h>
#include <miopen/sysinfo_utils.hpp>

#include <cstdlib>
#include <chrono>
#include <fstream>
#include <ios>
#include <iomanip>
#include <sstream>
Expand All @@ -39,6 +41,11 @@
#include <sys/syscall.h> /* For SYS_xxx definitions */
#endif

#ifdef _WIN32
#include <windows.h>
size_t getpid() { return _getpid(); }
#endif

/// Enable logging of the most important function calls.
/// Name of envvar in a bit inadequate due to historical reasons.
MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_ENABLE_LOGGING)
Expand Down Expand Up @@ -68,8 +75,48 @@ MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_ENABLE_LOGGING_ROCTX)
/// Disable logging quieting.
MIOPEN_DECLARE_ENV_VAR_BOOL(MIOPEN_DEBUG_LOGGING_QUIETING_DISABLE)

MIOPEN_DECLARE_ENV_VAR_UINT64(MIOPEN_LOG_BUFFER_SIZE, 128);

namespace miopen {

// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables, cert-err58-cpp)
static thread_local size_t log_buffer_size = env::value(MIOPEN_LOG_BUFFER_SIZE);
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables, cert-err58-cpp)
static thread_local size_t log_buffer_i = 0;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables, cert-err58-cpp)
static thread_local std::vector<std::string> log_buffer(log_buffer_size, "");

void ClearBufferLog()
{
log_buffer_i = 0;
log_buffer = std::vector<std::string>(miopen::log_buffer_size, "");
}

void BufferLog(std::string line)
{
log_buffer[log_buffer_i] = line;
log_buffer_i = (log_buffer_i + 1) % log_buffer_size;
}

void OutputBufferedLogs()
{
auto buffer_size = (log_buffer[log_buffer_size - 1] == "") ? log_buffer_i : log_buffer_size;
auto filename =
fs::temp_directory_path() / ("miopen_error_" + std::to_string(::getpid()) + ".log");
std::cerr << "Buffered " << buffer_size << " messages to file: " << sysinfo::GetSystemHostname()
<< ":" << filename.string() << std::endl;
auto err_file = std::ofstream{filename};
size_t i = log_buffer_i;
do
{
if(log_buffer[i] != "")
{
err_file << log_buffer[i];
}
i = (i + 1) % log_buffer_size;
} while(i != log_buffer_i);
}

namespace debug {

// NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables)
Expand Down
89 changes: 89 additions & 0 deletions projects/miopen/test/gtest/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@
#include "get_handle.hpp"
#include "../lib_env_var.hpp"

#include <gtest/gtest_common.hpp>
#include <miopen/config.h>
#include <miopen/fusion_plan.hpp>
#include <miopen/logger.hpp>
#include "../random.hpp"

#if MIOPEN_BACKEND_OPENCL
Expand Down Expand Up @@ -330,3 +332,90 @@ void TestLogCmdBNormFusion(std::function<void(const miopenFusionPlanDescriptor_t
else
ASSERT_FALSE(isSubStr(str, sub_str)) << "str : " << str << "str_sub : " << sub_str;
}

void TestLogBufferOn()
{
auto filename =
fs::temp_directory_path() / ("miopen_error_" + std::to_string(getpid()) + ".log");
size_t line_i = 0;
std::string line;

fs::remove(filename);

ScopedEnvironment<std::string> log_level_env(MIOPEN_LOG_LEVEL,
"5"); // miopen::LoggingLevel::Info
// test log dump after error
miopen::ClearBufferLog();
MIOPEN_LOG_W("warn");
MIOPEN_LOG_I("info");
MIOPEN_LOG_I2("info2");
MIOPEN_LOG_T("trace");
MIOPEN_LOG_E("error");

ASSERT_TRUE(fs::exists(filename));
{
auto log_file = std::ifstream{filename};
while(std::getline(log_file, line))
{
switch(line_i)
{
case 0: ASSERT_TRUE(isSubStr(line, "warn")); break;
case 1: ASSERT_TRUE(isSubStr(line, "info")); break;
case 2: ASSERT_TRUE(isSubStr(line, "info2")); break;
case 3:
ASSERT_FALSE(isSubStr(line, "trace"));
ASSERT_TRUE(isSubStr(line, "error"));
break;
}
line_i++;
}
}
fs::remove(filename);

// test log dump after throw
miopen::ClearBufferLog();
MIOPEN_LOG_W("warn");
MIOPEN_LOG_I("info");
MIOPEN_LOG_I2("info2");
MIOPEN_LOG_T("trace");
EXPECT_ANY_THROW({ MIOPEN_THROW("throw"); });

EXPECT_TRUE(fs::exists(filename));
{
auto log_file = std::ifstream{filename};
line_i = 0;
while(std::getline(log_file, line))
{
switch(line_i)
{
case 0: ASSERT_TRUE(isSubStr(line, "warn")); break;
case 1: ASSERT_TRUE(isSubStr(line, "info")); break;
case 2: ASSERT_TRUE(isSubStr(line, "info2")); break;
case 3: ASSERT_TRUE(isSubStr(line, "throw")); break;
}
line_i++;
}
}
fs::remove(filename);
}

void TestLogBufferOff()
{
auto filename =
fs::temp_directory_path() / ("miopen_error_" + std::to_string(getpid()) + ".log");

fs::remove(filename);

ScopedEnvironment<std::string> log_level_env(MIOPEN_LOG_LEVEL,
"6"); // miopen::LoggingLevel::Info2

miopen::ClearBufferLog();
// log messages
MIOPEN_LOG_W("warn");
MIOPEN_LOG_I("info");
MIOPEN_LOG_I2("info2");
MIOPEN_LOG_T("trace");
// test log dump after error
MIOPEN_LOG_E("error");
ASSERT_FALSE(fs::exists(filename));
}
4 changes: 4 additions & 0 deletions projects/miopen/test/gtest/log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,7 @@ void TestLogCmdCBAFusion(std::function<void(const miopenFusionPlanDescriptor_t)>
void TestLogCmdBNormFusion(std::function<void(const miopenFusionPlanDescriptor_t)> const& func,
std::string sub_str,
bool set_env);

void TestLogBufferOn();

void TestLogBufferOff();
4 changes: 4 additions & 0 deletions projects/miopen/test/gtest/log_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ TEST(CPU_LOG_TEST_ASSERT_NONE, AssertLogFindCmdOutput)
TestLogFun(miopen::debug::LogCmdFindConvolution, logFindConv, true);
}

TEST(CPU_LOG_TEST_ASSERT_NONE, AssertLogBufferOn) { TestLogBufferOn(); }

TEST(CPU_LOG_TEST_ASSERT_NONE, AssertLogBufferOff) { TestLogBufferOff(); }

TEST(CPU_LOG_TEST_FUSION_NONE, AssertTestLogCmdCBAFusionOutput)
{
TestLogCmdCBAFusion(miopen::debug::LogCmdFusion, logFusionConvBiasActiv, true);
Expand Down
Loading