Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update and Fix Profiler #12940

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
91 changes: 46 additions & 45 deletions kratos/sources/profiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,50 @@
#include <algorithm>
#include <thread>
#include <vector>
#include <tuple>
#include <fstream>
#include <sstream>
#include <atomic>
#include <limits> // std::numeric_limits


namespace Kratos::Internals {


namespace {
template <class TTimeUnit>
std::string GetTimeUnit()
{
KRATOS_ERROR << "Unsupported time unit";
}

template <>
std::string GetTimeUnit<std::chrono::milliseconds>()
{
return "ms";
}

template <>
std::string GetTimeUnit<std::chrono::microseconds>()
{
return "us";
}

template <>

std::string GetTimeUnit<std::chrono::nanoseconds>()
{
return "ns";
}
} // unnamed namespace


template <class T>
Profiler<T>::Item::Item(CodeLocation&& rLocation)
: Item(0,
Duration(0),
Duration(0),
Duration(0),
std::move(rLocation))
: Item(0, // <== .mCallCount
Duration(0), // <== .mCumulative
Duration(std::numeric_limits<typename Duration::rep>::max()), // <== .mMin
Duration(0), // <== .mMax
std::move(rLocation)) // <== .mLocation
{
}

Expand Down Expand Up @@ -70,7 +98,7 @@ typename Profiler<T>::Item& Profiler<T>::Item::operator+=(const Item& rOther)

template <class T>
Profiler<T>::Profiler()
: Profiler("kratos_profiler_output.json")
: Profiler("kratos_profiler_output_" + GetTimeUnit<T>() + ".json")
{
}

Expand Down Expand Up @@ -112,34 +140,6 @@ typename Profiler<T>::Item& Profiler<T>::Create(CodeLocation&& r_item)
}


namespace {
template <class TTimeUnit>
std::string GetTimeUnit()
{
KRATOS_ERROR << "Unknown time unit";
}

template <>
std::string GetTimeUnit<std::chrono::milliseconds>()
{
return "ms";
}

template <>
std::string GetTimeUnit<std::chrono::microseconds>()
{
return "us";
}

template <>

std::string GetTimeUnit<std::chrono::nanoseconds>()
{
return "ns";
}
} // unnamed namespace


template <class T>
typename Profiler<T>::ItemMap Profiler<T>::Aggregate() const
{
Expand Down Expand Up @@ -208,7 +208,8 @@ void Profiler<T>::Write(std::ostream& rStream) const
const auto& r_location = p_item->mLocation;
result.AddString("file", std::string(r_location.GetFileName()));
result.AddInt("line", int(r_location.GetLineNumber()));
result.AddString("function", std::string(r_location.GetFunctionName()));
result.AddString("signature", std::string(r_location.GetFunctionName()));
result.AddString("function", std::string(r_location.CleanFunctionName()));
result.AddInt("callCount", p_item->mCallCount);

std::stringstream stream;
Expand Down Expand Up @@ -267,19 +268,19 @@ template <class T>
std::mutex ProfilerSingleton<T>::mMutex;


template class Profiler<std::chrono::milliseconds>;
template class ProfilerSingleton<std::chrono::milliseconds>;
template std::ostream& operator<<(std::ostream&, const Profiler<std::chrono::milliseconds>&);
template class KRATOS_API(KRATOS_CORE) Profiler<std::chrono::milliseconds>;
template class KRATOS_API(KRATOS_CORE) ProfilerSingleton<std::chrono::milliseconds>;
template KRATOS_API(KRATOS_CORE) std::ostream& operator<<(std::ostream&, const Profiler<std::chrono::milliseconds>&);


template class Profiler<std::chrono::microseconds>;
template class ProfilerSingleton<std::chrono::microseconds>;
template std::ostream& operator<<(std::ostream&, const Profiler<std::chrono::microseconds>&);
template class KRATOS_API(KRATOS_CORE) Profiler<std::chrono::microseconds>;
template class KRATOS_API(KRATOS_CORE) ProfilerSingleton<std::chrono::microseconds>;
template KRATOS_API(KRATOS_CORE) std::ostream& operator<<(std::ostream&, const Profiler<std::chrono::microseconds>&);


template class Profiler<std::chrono::nanoseconds>;
template class ProfilerSingleton<std::chrono::nanoseconds>;
template std::ostream& operator<<(std::ostream&, const Profiler<std::chrono::nanoseconds>&);
template class KRATOS_API(KRATOS_CORE) Profiler<std::chrono::nanoseconds>;
template class KRATOS_API(KRATOS_CORE) ProfilerSingleton<std::chrono::nanoseconds>;
template KRATOS_API(KRATOS_CORE) std::ostream& operator<<(std::ostream&, const Profiler<std::chrono::nanoseconds>&);


} // namespace cie::utils
34 changes: 23 additions & 11 deletions kratos/utilities/profiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,23 @@ namespace Kratos::Internals {


template <class TTimeUnit>
class Profiler
class KRATOS_API(KRATOS_CORE) Profiler
{
private:
/// @brief Absolute time type.
using TimeUnit = TTimeUnit;

/// @brief Relative time type.
using Duration = TimeUnit;

/// @brief Clock type used for measuring durations.
using Clock = std::chrono::high_resolution_clock;

/// @brief Class for identifying a profiled scope and aggregating its stats.
class Item
{
public:
Item(CodeLocation&& rLocation);
explicit Item(CodeLocation&& rLocation);

private:
Item(std::size_t CallCount,
Expand All @@ -51,40 +54,49 @@ class Profiler
Duration MaxDuration,
CodeLocation&& rLocation);

/// @brief Aggregate profiled data from another @ref Item in the same scope.
Item& operator+=(const Item& rOther);

private:
friend class Profiler;

/// @brief Counter for keeping track of recursive calls.
/// @details Recursive function calls are aggregated onto the top
/// level call. To do that, the @ref Item must keep track
/// of its recursion depth.
unsigned mRecursionLevel;

/// @brief Counter tracking total number of calls to a function during the program's entire execution time.
std::size_t mCallCount;

/// @brief Counter summing the duration of each call to the profiled scope.
Duration mCumulative;

/// @brief Minimum time spent in the profiled scope.
Duration mMin;

/// @brief Maximum time spent in the profiled scope.
Duration mMax;

/// @brief Source information about the profiled scope.
CodeLocation mLocation;
}; // class Item

struct SourceLocationHash
{
std::size_t operator()(const CodeLocation& r_argument) const
std::size_t operator()(const CodeLocation& rArgument) const
{
std::string string(r_argument.GetFileName());
string.append(std::to_string(r_argument.GetLineNumber()));
return std::hash<std::string>()(string);
return std::hash<std::string>()(rArgument.GetFileName() + rArgument.GetFunctionName());
}
};

struct SourceLocationEquality
{
bool operator()(const CodeLocation& r_lhs,
const CodeLocation& r_rhs) const
bool operator()(const CodeLocation& rLhs,
const CodeLocation& rRhs) const
{
return (std::string(r_lhs.GetFileName()) == std::string(r_rhs.GetFileName())) && (r_lhs.GetLineNumber() == r_rhs.GetLineNumber());
return (rLhs.GetFileName() == rRhs.GetFileName())
&& (rLhs.GetFunctionName() == rRhs.GetFunctionName());
}
};

Expand Down Expand Up @@ -180,11 +192,11 @@ class Profiler


template <class T>
std::ostream& operator<<(std::ostream& rStream, const Profiler<T>& rProfiler);
KRATOS_API(KRATOS_CORE) std::ostream& operator<<(std::ostream& rStream, const Profiler<T>& rProfiler);


template <class TTimeUnit>
class ProfilerSingleton
class KRATOS_API(KRATOS_CORE) ProfilerSingleton
{
public:
static Profiler<TTimeUnit>& Get() noexcept;
Expand Down
1 change: 0 additions & 1 deletion kratos/utilities/profiler_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "utilities/profiler.h" // <== help the language server

// System includes
#include <string>
#include <chrono>


Expand Down
Loading