Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
7 changes: 7 additions & 0 deletions src/esp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ set(
core/Check.h
core/Configuration.cpp
core/Configuration.h
core/diagnostics/DiagnosticsRecord.h
core/diagnostics/DiagnosticsTool.h
core/Esp.cpp
core/Esp.h
core/Logging.cpp
Expand Down Expand Up @@ -311,6 +313,11 @@ set(
metadata/attributes/SemanticAttributes.cpp
metadata/attributes/StageAttributes.h
metadata/attributes/StageAttributes.cpp
metadata/diagnostics/DatasetDiagnosticsTool.h
metadata/diagnostics/DatasetDiagnosticsTool.cpp
metadata/diagnostics/DatasetDiagnosticsRecord.h
metadata/diagnostics/DatasetDiagnostics.h
metadata/diagnostics/DatasetDiagnostics.cpp
metadata/managers/AbstractAttributesManager.h
metadata/managers/AbstractObjectAttributesManager.h
metadata/managers/AOAttributesManager.h
Expand Down
121 changes: 121 additions & 0 deletions src/esp/core/diagnostics/DiagnosticsRecord.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Copyright (c) Meta Platforms, Inc. and its affiliates.
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.

#ifndef ESP_CORE_DIAGNOSTICS_DIAGNOSTICSRECORD_H_
#define ESP_CORE_DIAGNOSTICS_DIAGNOSTICSRECORD_H_

#include <type_traits>
#include <unordered_map>
#include "esp/core/Esp.h"

namespace esp {
namespace core {
namespace diagnostics {

/**
* @brief Construct to provide a foundation for building a record of the results
* of a series of diagnostics.
*/
class DiagnosticsRecord {
public:
explicit DiagnosticsRecord(uint32_t diagnosticsFlags)
: diagnosticsFlags_(diagnosticsFlags) {}

protected:
/**
* @brief Set the diagnostic flag representing the type of diagnostics
* recorded by this record
*/
template <class T>
inline void setFlag(T flag, bool val) {
//_flag must be an enum value
static_assert(std::is_enum<T>::value,
"The Diagnostics Record flag must be an enum");
//_flag must be backed by a uint32_t
static_assert(
std::is_same<typename std::underlying_type<T>::type, uint32_t>::value,
"The Diagnostics Record flag enum must be backed by a uint32_t");
if (val) {
diagnosticsFlags_ |= static_cast<uint32_t>(flag);
} else {
diagnosticsFlags_ &= ~static_cast<uint32_t>(flag);
}
}

/**
* @brief Get the diagnostic flag representing the type of diagnostics
* recorded by this record
*/
template <class T>
inline bool getFlag(T flag) const {
//_flag must be an enum value
static_assert(std::is_enum<T>::value,
"The Diagnostics Record flag must be an enum");
//_flag must be backed by a uint32_t
static_assert(
std::is_same<typename std::underlying_type<T>::type, uint32_t>::value,
"The Diagnostics Record flag enum must be backed by a uint32_t");
return (diagnosticsFlags_ & static_cast<uint32_t>(flag)) ==
static_cast<uint32_t>(flag);
}

/**
* @brief Record diagnostic information for specified test.
* @param diagFlag The diagnostic test enum representing the type of the test.
* @param report String report to be appended to the @p _resultsLog
*/
template <class T>
void recordDiagResult(T diagFlag, const std::string& report) {
//_flag must be an enum value
static_assert(std::is_enum<T>::value,
"The Diagnostics Record flag must be an enum");
//_flag must be backed by a uint32_t
static_assert(
std::is_same<typename std::underlying_type<T>::type, uint32_t>::value,
"The Diagnostics Record flag enum must be backed by a uint32_t");
// either add a new or retrieve existing
auto emplaceRes = resultsLog_.emplace(static_cast<uint32_t>(diagFlag),
std::vector<std::string>());
emplaceRes.first->second.push_back(report);
}

/**
* @brief Retrieve results log for specific diagnostic test type
*/
template <class T>
const std::vector<std::string> getDiagResult(T diagFlag) const {
//_flag must be an enum value
static_assert(std::is_enum<T>::value,
"The Diagnostics Record flag must be an enum");
//_flag must be backed by a uint32_t
static_assert(
std::is_same<typename std::underlying_type<T>::type, uint32_t>::value,
"The Diagnostics Record flag enum must be backed by a uint32_t");
auto reportIter = resultsLog_.find(static_cast<uint32_t>(diagFlag));
if (reportIter == resultsLog_.end()) {
// Caller should check for empty and respond accordingly
return {};
}
return reportIter->second;
} // getDiagResult

private:
/**
* @brief Holds collections of strings recording the results of each enabled
* diagnostic.
*/
std::unordered_map<uint32_t, std::vector<std::string>> resultsLog_;
/**
* @brief Flags to record the diagnostics performed
*/
uint32_t diagnosticsFlags_ = 0u;

public:
ESP_SMART_POINTERS(DiagnosticsRecord)
}; // class DiagnosticsRecord

} // namespace diagnostics
} // namespace core
} // namespace esp
#endif // ESP_CORE_DIAGNOSTICS_DIAGNOSTICSRECORD_H_
152 changes: 152 additions & 0 deletions src/esp/core/diagnostics/DiagnosticsTool.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// Copyright (c) Meta Platforms, Inc. and its affiliates.
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.

#ifndef ESP_CORE_DIAGNOSTICS_DIAGNOSTICSTOOL_H_
#define ESP_CORE_DIAGNOSTICS_DIAGNOSTICSTOOL_H_

#include <type_traits>
#include "esp/core/Check.h"
#include "esp/core/Esp.h"

namespace esp {
namespace core {
namespace diagnostics {

/**
* @brief This class will track requested diagnostics for specific config
* files/attributes. It is intended that each @ref AbstractAttributesManager
* would instantiate one of these objects and use it to determine various
* diagnostic behavior.
*/
class DiagnosticsTool {
public:
DiagnosticsTool() = default;

/**
* @brief Reset the current state of the Diagnostics tool.
*/
void reset() {
clearDiagnosticFlags();
resetIndiv();
}

/**
* @brief Implementation class-specific reset code
*/
virtual void resetIndiv() = 0;

/**
* @brief Clear all existing diagnostic flag settings.
*/
void clearDiagnosticFlags() { diagnosticsFlags_ = 0u; }

protected:
/**
* @brief Merge the passed @ref DiagnosticsTool's @p _diagnosticsFlag
* settings into this one's, preserving this one's diagnostic requests as
* well. Only referenced internally to ensure tool type consistency.
*/
void mergeDiagnosticsToolInternal(const DiagnosticsTool& tool) {
diagnosticsFlags_ |= tool.diagnosticsFlags_;
}

/**
* @brief Enable/disable the diagnostic given by @p diagnostic string based on
* @p val.
*
* @param diagnostic The string name of the diagnostic. This must be mappable
* to an appropriate enum type via @p diagMap .
* @param diagMap Map holding the string to enum mapping for the implementing
* diagnostic tool.
* @param val Whether to enable or disable the given diagnostic
* @param abortOnFail Whether or not to abort the program if the
* @p diagnostic requeseted is not found in @p diagMap. If false,
* will print an error message and skip the unknown request.
* @return Whether the passed string successfully mapped to a known diagnostic
*/
template <class T>
bool setNamedDiagnosticInternal(const std::string& diagnostic,
const std::map<std::string, T>& diagMap,
bool val,
bool abortOnFail = false);

template <class T>
inline void setFlag(T _flag, bool _val) {
//_flag must be an enum value
static_assert(std::is_enum<T>::value,
"The Diagnostics Tool's flag must be an enum");
//_flag must be backed by a uint32_t
static_assert(
std::is_same<typename std::underlying_type<T>::type, uint32_t>::value,
"The Diagnostics Tool's flag enum must be backed by a uint32_t");
if (_val) {
diagnosticsFlags_ |= static_cast<uint32_t>(_flag);
} else {
diagnosticsFlags_ &= ~static_cast<uint32_t>(_flag);
}
}

template <class T>
inline bool getFlag(T _flag) const {
//_flag must be an enum value
static_assert(std::is_enum<T>::value,
"The Diagnostics Tool's flag must be an enum");
//_flag must be backed by a uint32_t
static_assert(
std::is_same<typename std::underlying_type<T>::type, uint32_t>::value,
"The Diagnostics Tool's flag enum must be backed by a uint32_t");
return (diagnosticsFlags_ & static_cast<uint32_t>(_flag)) ==
static_cast<uint32_t>(_flag);
}

private:
uint32_t diagnosticsFlags_ = 0u;

public:
ESP_SMART_POINTERS(DiagnosticsTool)

}; // class DiagnosticsTool

/////////////////////////////
// Class Template Method Definitions
template <class T>
bool DiagnosticsTool::setNamedDiagnosticInternal(
const std::string& diagnostic,
const std::map<std::string, T>& diagMap,
bool val,
bool abortOnFail) {
//_flag must be an enum value
static_assert(std::is_enum<T>::value,
"The Diagnostics Tool's flag must be an enum");
//_flag must be backed by a uint32_t
static_assert(
std::is_same<typename std::underlying_type<T>::type, uint32_t>::value,
"The Diagnostics Tool's flag enum must be backed by a uint32_t");
const std::string diagnosticLC =
Corrade::Utility::String::lowercase(diagnostic);

auto mapIter = diagMap.find(diagnosticLC);
if (abortOnFail) {
// If not found then abort.
ESP_CHECK(mapIter != diagMap.end(),
"Unknown Diagnostic Test requested to be "
<< (val ? "Enabled :" : "Disabled :") << diagnostic
<< ". Aborting.");
} else {
if (mapIter == diagMap.end()) {
ESP_ERROR() << "Unknown Diagnostic Test requested to be "
<< (val ? "Enabled" : "Disabled") << " :" << diagnostic
<< " so ignoring request.";
return false;
}
}
setFlag(mapIter->second, val);
return true;
} // DiagnosticsTool::setNamedDiagnostic

} // namespace diagnostics
} // namespace core
} // namespace esp

#endif // ESP_CORE_DIAGNOSTICS_DIAGNOSTICSTOOL_H_
40 changes: 40 additions & 0 deletions src/esp/metadata/diagnostics/DatasetDiagnostics.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

// Copyright (c) Meta Platforms, Inc. and its affiliates.
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.

#include "DatasetDiagnostics.h"

namespace esp {
namespace metadata {
namespace diagnostics {

const std::map<std::string, DSDiagnosticType> DSDiagnosticTypeMap = {
{"savecorrected", DSDiagnosticType::SaveCorrected},
{"sceneinstanceduplicates", DSDiagnosticType::TestForDuplicateInstances},
{"semanticregionduplicates", DSDiagnosticType::TestForDuplicateRegions},
// Future diagnostics should be listed here, before "all"
{"all", DSDiagnosticType::AllDiagnostics},
{"allsavecorrected", DSDiagnosticType::AllDiagnosticsSaveCorrected},
};

std::string getDSDiagnosticsTypeName(DSDiagnosticType dsDiagTypeName) {
// this verifies that enum value being checked is supported by string-keyed
// map. The values below should be the minimum and maximum enums supported by
// DSDiagnosticTypeMap
if (dsDiagTypeName <= DSDiagnosticType::Unknown) {
return "unknown";
}
// Must always be valid value
for (const auto& it : DSDiagnosticTypeMap) {
if (it.second == dsDiagTypeName) {
return it.first;
}
}
return "unknown";
} // getDSDiagnosticsTypeName

} // namespace diagnostics

} // namespace metadata
} // namespace esp
Loading
Loading