Skip to content

Commit

Permalink
create on compile, check usage on execution
Browse files Browse the repository at this point in the history
  • Loading branch information
hseok-oh committed May 24, 2024
1 parent bc75ee2 commit f1a3b22
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 57 deletions.
47 changes: 45 additions & 2 deletions runtime/onert/core/src/compiler/ExecutorFactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,18 @@ ExecutorFactory::createLinearExecutor(std::unique_ptr<compiler::LoweredGraph> lo
order,
tracing_ctx};

// TODO use workspace
const auto trace_filepath = util::getConfigString(util::config::TRACE_FILEPATH);
std::unique_ptr<exec::IExecutionObserver> ctp =
std::make_unique<exec::TracingObserver>(trace_filepath, exec->graph(), tracing_ctx);
exec->addObserver(exec::ObserverType::TRACING, std::move(ctp));
#ifdef MINMAX_H5DUMPER
const auto minmax_filepath = util::getConfigString(util::config::MINMAX_FILEPATH);
exec->addObserver(exec::ObserverType::MINMAX_RECORD,
std::make_unique<exec::MinMaxRecorder>(minmax_filepath, exec->graph(),
exec->getBackendContexts()));
#endif

return exec;
}

Expand Down Expand Up @@ -567,10 +579,33 @@ ExecutorFactory::createDataflowExecutor(std::unique_ptr<compiler::LoweredGraph>
}
else
{
exec = new exec::DataflowExecutor{std::move(lowered_graph), std::move(backend_contexts),
tensor_regs, std::move(code_map), tracing_ctx};
auto dataflow_exec =
new exec::DataflowExecutor{std::move(lowered_graph), std::move(backend_contexts), tensor_regs,
std::move(code_map), tracing_ctx};

if (options->he_profiling_mode)
{
std::vector<const backend::Backend *> backends;
for (const auto &pair : dataflow_exec->getBackendContexts())
{
backends.push_back(pair.first);
}
auto et = std::make_shared<exec::ExecTime>(backends);
std::unique_ptr<exec::IExecutionObserver> obs =
std::make_unique<exec::ProfileObserver>(et, dataflow_exec->graph());
dataflow_exec->addObserver(exec::ObserverType::PROFILE, std::move(obs));
}
exec = dataflow_exec;
}

// TODO use workspace
const auto trace_filepath = util::getConfigString(util::config::TRACE_FILEPATH);
std::unique_ptr<exec::IExecutionObserver> ctp =
std::make_unique<exec::TracingObserver>(trace_filepath, exec->graph(), tracing_ctx);
exec->addObserver(exec::ObserverType::TRACING, std::move(ctp));

// TODO Support MINMAX_H5DUMPER

return exec;
}

Expand Down Expand Up @@ -856,6 +891,14 @@ exec::IExecutor *ExecutorFactory::createTrainableExecutor(
tracing_ctx,
training_info.lossInfo()};

// TODO use workspace
const auto trace_filepath = util::getConfigString(util::config::TRACE_FILEPATH);
std::unique_ptr<exec::IExecutionObserver> ctp =
std::make_unique<exec::TracingObserver>(trace_filepath, exec->graph(), tracing_ctx);
exec->addObserver(exec::ObserverType::TRACING, std::move(ctp));

// TODO Support MINMAX_H5DUMPER

return exec;
}

Expand Down
7 changes: 5 additions & 2 deletions runtime/onert/core/src/exec/ExecutionObservee.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ namespace onert
namespace exec
{

void ExecutionObservee::add(std::unique_ptr<IExecutionObserver> observer)
void ExecutionObservee::add(IExecutionObserver *observer)
{
_observers.emplace_back(std::move(observer));
if (observer == nullptr)
throw std::runtime_error{"Observer is nullptr"};

_observers.emplace_back(observer);
}

void ExecutionObservee::notifySubgraphBegin(ir::SubgraphIndex ind) const
Expand Down
4 changes: 2 additions & 2 deletions runtime/onert/core/src/exec/ExecutionObservee.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class ExecutionObservee
*
* @param observer Observer to be added
*/
void add(std::unique_ptr<IExecutionObserver> observer);
void add(IExecutionObserver *observer);
void notifySubgraphBegin(ir::SubgraphIndex ind) const;
void notifySubgraphEnd(ir::SubgraphIndex ind) const;
void notifyJobBegin(IExecutor *executor, ir::SubgraphIndex subg_ind, ir::OperationIndex op_ind,
Expand All @@ -50,7 +50,7 @@ class ExecutionObservee
bool isEmpty() const { return _observers.size() == 0; }

private:
std::list<std::unique_ptr<IExecutionObserver>> _observers;
std::list<IExecutionObserver *> _observers;
};

} // namespace exec
Expand Down
27 changes: 27 additions & 0 deletions runtime/onert/core/src/exec/ExecutionObservers.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,33 @@ class TracingObserver : public IExecutionObserver
const util::TracingCtx *_tracing_ctx;
};

enum class ObserverType
{
PROFILE,
TRACING,
MINMAX_RECORD,
};

class ExecObserverMap
{
public:
void emplace(ObserverType type, std::unique_ptr<IExecutionObserver> &&observer)
{
_observers.emplace(type, std::move(observer));
}

IExecutionObserver *get(ObserverType type)
{
if (_observers.find(type) != _observers.end())
return _observers.at(type).get();

return nullptr;
}

private:
std::unordered_map<ObserverType, std::unique_ptr<IExecutionObserver>> _observers;
};

} // namespace exec
} // namespace onert

Expand Down
78 changes: 41 additions & 37 deletions runtime/onert/core/src/exec/ExecutorBase.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,36 +99,38 @@ void ExecutorBase::execute(const std::vector<backend::IPortableTensor *> &inputs

// Create observee
ExecutionObservee subject;
const auto minmax_filepath = util::getConfigString(util::config::MINMAX_FILEPATH);
const auto trace_filepath = util::getConfigString(util::config::TRACE_FILEPATH);
const auto he_profiling_mode = util::getConfigBool(util::config::PROFILING_MODE);

#ifdef MINMAX_H5DUMPER
const auto minmax_filepath = util::getConfigString(util::config::MINMAX_FILEPATH);
if (!minmax_filepath.empty())
{
LinearExecutor *executor = dynamic_cast<LinearExecutor *>(this);
if (!executor)
throw std::runtime_error{"MinMaxRecorder is only supported on LinearExecutor"};
auto observer = _observer_map.get(ObserverType::MINMAX_RECORD);
if (!observer)
throw std::runtime_error{"MinMaxRecorder is only supported on LinearExecutor, single model"};

subject.add(std::make_unique<MinMaxRecorder>(minmax_filepath, _graph, _backend_contexts));
subject.add(observer);
}
#endif

const auto trace_filepath = util::getConfigString(util::config::TRACE_FILEPATH);
if (!trace_filepath.empty())
subject.add(std::make_unique<TracingObserver>(trace_filepath, _graph, _tracing_ctx));
{
auto observer = _observer_map.get(ObserverType::TRACING);
if (!observer)
throw std::runtime_error{"Cannot find TracingObserver"};

subject.add(observer);
}

const auto he_profiling_mode = util::getConfigBool(util::config::PROFILING_MODE);
if (he_profiling_mode)
{
// Only support on dataflow executor
DataflowExecutor *executor = dynamic_cast<DataflowExecutor *>(this);
if (executor)
{
std::vector<const backend::Backend *> backends;
for (const auto &pair : _backend_contexts)
{
backends.push_back(pair.first);
}
auto et = std::make_shared<exec::ExecTime>(backends);
subject.add(std::make_unique<exec::ProfileObserver>(et, _graph));
}
auto observer = _observer_map.get(ObserverType::PROFILE);
if (!observer)
throw std::runtime_error{
"Profiling is only supported on DataflowExecutor with heterogenous scheduler"};

subject.add(observer);
}

executeImpl(subject);
Expand Down Expand Up @@ -203,29 +205,31 @@ void ExecutorBase::execute(const IODescription &desc)
#ifdef MINMAX_H5DUMPER
if (!minmax_filepath.empty())
{
LinearExecutor *executor = dynamic_cast<LinearExecutor *>(this);
if (!executor)
throw std::runtime_error{"MinMaxRecorder is only supported on LinearExecutor"};
auto observer = _observer_map.get(ObserverType::MINMAX_RECORD);
if (!observer)
throw std::runtime_error{"MinMaxRecorder is only supported on LinearExecutor, single model"};

subject.add(std::make_unique<MinMaxRecorder>(minmax_filepath, _graph, _backend_contexts));
subject.add(observer);
}
#endif

if (!trace_filepath.empty())
subject.add(std::make_unique<TracingObserver>(trace_filepath, _graph, _tracing_ctx));
{
auto observer = _observer_map.get(ObserverType::TRACING);
if (!observer)
throw std::runtime_error{"Cannot find TracingObserver"};

subject.add(observer);
}

if (he_profiling_mode)
{
// Only support on dataflow executor
DataflowExecutor *executor = dynamic_cast<DataflowExecutor *>(this);
if (executor)
{
std::vector<const backend::Backend *> backends;
for (const auto &pair : _backend_contexts)
{
backends.push_back(pair.first);
}
auto et = std::make_shared<exec::ExecTime>(backends);
subject.add(std::make_unique<exec::ProfileObserver>(et, _graph));
}
auto observer = _observer_map.get(ObserverType::PROFILE);
if (!observer)
throw std::runtime_error{
"Profiling is only supported on DataflowExecutor with heterogenous scheduler"};

subject.add(observer);
}

executeImpl(subject);
Expand Down
7 changes: 7 additions & 0 deletions runtime/onert/core/src/exec/ExecutorBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define __ONERT_EXEC_EXECUTOR_BASE_H__

#include "ExecutionObservee.h"
#include "ExecutionObservers.h"
#include "../backend/builtin/IOTensor.h"
#include "../compiler/TensorRegistries.h"

Expand Down Expand Up @@ -66,6 +67,11 @@ class ExecutorBase : public IExecutor

virtual void executeImpl(const ExecutionObservee &subject) = 0;

void addObserver(ObserverType type, std::unique_ptr<IExecutionObserver> ref)
{
_observer_map.emplace(type, std::move(ref));
};

const std::vector<backend::builtin::IOTensor *> &getInputTensors() const override
{
return _input_tensors;
Expand All @@ -84,6 +90,7 @@ class ExecutorBase : public IExecutor
bool hasDynamicInput();

protected:
ExecObserverMap _observer_map;
std::shared_ptr<ir::OperationIndexMap<int64_t>> _indexed_ranks;
std::unique_ptr<compiler::LoweredGraph> _lowered_graph;
backend::BackendContexts _backend_contexts;
Expand Down
29 changes: 15 additions & 14 deletions runtime/onert/core/src/exec/train/TrainableExecutor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,18 @@ void TrainableExecutor::forward(const IODescription &desc, bool training)

// Create observee
ExecutionObservee subject;
const auto minmax_filepath = util::getConfigString(util::config::MINMAX_FILEPATH);
const auto trace_filepath = util::getConfigString(util::config::TRACE_FILEPATH);
const auto he_profiling_mode = util::getConfigBool(util::config::PROFILING_MODE);

// TODO Support MINMAX_H5DUMPER
if (!minmax_filepath.empty())
throw std::runtime_error("Recording minmax is not supported for training models");
if (!trace_filepath.empty())
{
auto observer = _observer_map.get(ObserverType::TRACING);
if (!observer)
throw std::runtime_error{"Cannot find TracingObserver"};

// Trainable executor uses linear scheduling
if (he_profiling_mode)
throw std::runtime_error("Profiling mode is not supported for trainable executor");
subject.add(observer);
}

if (!trace_filepath.empty())
subject.add(
std::make_unique<TracingObserver>(trace_filepath, _trainable_graph.graph(), _tracing_ctx));
// TODO Support MINMAX_H5DUMPER

forwardImpl(subject, training);

Expand Down Expand Up @@ -173,9 +170,13 @@ void TrainableExecutor::backward(const IODescription &, uint32_t training_step)
const auto trace_filepath = util::getConfigString(util::config::TRACE_FILEPATH);

if (!trace_filepath.empty())
subject.add(
std::make_unique<TracingObserver>(trace_filepath, _trainable_graph.graph(), _tracing_ctx));
// TODO Support MINMAX_H5DUMPER
{
auto observer = _observer_map.get(ObserverType::TRACING);
if (!observer)
throw std::runtime_error{"Cannot find TracingObserver"};

subject.add(observer);
}

backwardImpl(subject, training_step);
}
Expand Down
7 changes: 7 additions & 0 deletions runtime/onert/core/src/exec/train/TrainableExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "exec/IExecutor.h"

#include "../ExecutionObservee.h"
#include "../ExecutionObservers.h"
#include "../../compiler/train/TensorRegistries.h"

#include "backend/train/TrainableBackendContext.h"
Expand Down Expand Up @@ -70,6 +71,11 @@ class TrainableExecutor : public IExecutor
_indexed_ranks = std::move(ranks);
};

void addObserver(ObserverType type, std::unique_ptr<IExecutionObserver> ref)
{
_observer_map.emplace(type, std::move(ref));
};

const std::vector<backend::builtin::IOTensor *> &getInputTensors() const override
{
return _input_tensors;
Expand All @@ -96,6 +102,7 @@ class TrainableExecutor : public IExecutor
compiler::train::TrainableCodeMap _code_map;
std::vector<ir::OperationIndex> _forward_order;
std::vector<ir::OperationIndex> _backward_order;
ExecObserverMap _observer_map;
std::shared_ptr<ir::OperationIndexMap<int64_t>> _indexed_ranks;
std::unique_ptr<compiler::train::LoweredTrainableGraph> _lowered_graph;
backend::train::TrainableBackendContexts _backend_contexts;
Expand Down

0 comments on commit f1a3b22

Please sign in to comment.