Browse Source

feat(mge/imperative): add graph profiler

GitOrigin-RevId: c73563f337
tags/v1.0.0-rc1
Megvii Engine Team 4 years ago
parent
commit
403a1e7b24
3 changed files with 62 additions and 0 deletions
  1. +17
    -0
      imperative/python/megengine/jit/tracing.py
  2. +26
    -0
      imperative/python/src/graph_rt.cpp
  3. +19
    -0
      imperative/python/test/unit/test_tracing.py

+ 17
- 0
imperative/python/megengine/jit/tracing.py View File

@@ -2,12 +2,14 @@ import collections
import contextlib import contextlib
import functools import functools
import itertools import itertools
import json
import typing import typing
import warnings import warnings
import weakref import weakref


import numpy as np import numpy as np


from ..core._imperative_rt import GraphProfiler
from ..core.ops.special import Const from ..core.ops.special import Const
from ..core.tensor import megbrain_graph as G from ..core.tensor import megbrain_graph as G
from ..core.tensor.core import OpBase, TensorBase, TensorWrapperBase, apply from ..core.tensor.core import OpBase, TensorBase, TensorWrapperBase, apply
@@ -85,11 +87,14 @@ class trace:
symbolic=False, symbolic=False,
capture_as_const=False, capture_as_const=False,
sublinear_memory_config: SublinearMemoryConfig = None, sublinear_memory_config: SublinearMemoryConfig = None,
profiling: bool = False,
): ):
self.__wrapped__ = function self.__wrapped__ = function
self._symbolic = symbolic self._symbolic = symbolic
self._capture_as_const = capture_as_const self._capture_as_const = capture_as_const
self._sublinear_memory_config = sublinear_memory_config self._sublinear_memory_config = sublinear_memory_config
self._profiling = profiling
self._profiler = None


self._untraced = True self._untraced = True
self._tinfo = [] # handle -> TensorInfo self._tinfo = [] # handle -> TensorInfo
@@ -308,6 +313,8 @@ class trace:
) )
sublinear_config.thresh_nr_try = self._sublinear_memory_config.thresh_nr_try sublinear_config.thresh_nr_try = self._sublinear_memory_config.thresh_nr_try
sublinear_config.num_worker = self._sublinear_memory_config.num_worker sublinear_config.num_worker = self._sublinear_memory_config.num_worker
if self._profiling:
self._profiler = GraphProfiler(graph)


def _compile(self): def _compile(self):
graph = self._graph = G.Graph() graph = self._graph = G.Graph()
@@ -581,6 +588,16 @@ class trace:
% (output_names and output_names[i] or i) % (output_names and output_names[i] or i)
) )


def get_profile(self):
"""
Get profiling result for compiled trace.

:return: a json compatible object.
"""
if not self._profiler:
raise RuntimeError("trace is not set with profiling=True")
return json.loads(self._profiler.get())



class CompiledTensorProxy(RawTensor): class CompiledTensorProxy(RawTensor):
""" """


+ 26
- 0
imperative/python/src/graph_rt.cpp View File

@@ -11,18 +11,38 @@


#include "./graph_rt.h" #include "./graph_rt.h"


#include "megbrain/graph/cg.h"
#include "megbrain/serialization/serializer.h" #include "megbrain/serialization/serializer.h"
#include "megbrain/imperative/opr_utility.h" #include "megbrain/imperative/opr_utility.h"
#include "megbrain/opr/io.h" #include "megbrain/opr/io.h"
#include "megbrain/opr/basic_arith.h" #include "megbrain/opr/basic_arith.h"
#include "megbrain/imperative.h" #include "megbrain/imperative.h"
#include "./helper.h" #include "./helper.h"
#include "megbrain/plugin/profiler.h"


namespace py = pybind11; namespace py = pybind11;


using namespace mgb; using namespace mgb;
using namespace imperative; using namespace imperative;


namespace {
class _CompGraphProfilerImpl {
std::shared_ptr<ComputingGraph> m_comp_graph;
GraphProfiler m_profiler;
public:
_CompGraphProfilerImpl(std::shared_ptr<ComputingGraph> cg):
m_comp_graph{cg},
m_profiler{m_comp_graph.get()}
{
}

std::string _get_result() {
auto json = m_profiler.to_json_full(
m_comp_graph->current_comp_seq());
return json->to_string();
}
};
}
#define DEF_READWRITE(name) .def_readwrite(#name, &CURRENT_CLASS::name) #define DEF_READWRITE(name) .def_readwrite(#name, &CURRENT_CLASS::name)


template<typename T> template<typename T>
@@ -102,6 +122,12 @@ void init_graph_rt(py::module m) {
}) })
.def_property_readonly("options", py::overload_cast<>(&cg::ComputingGraph::options)); .def_property_readonly("options", py::overload_cast<>(&cg::ComputingGraph::options));


py::class_<_CompGraphProfilerImpl, std::shared_ptr<_CompGraphProfilerImpl>>(m, "GraphProfiler")
.def(py::init([](std::shared_ptr<ComputingGraph> graph) {
return std::make_shared<_CompGraphProfilerImpl>(graph);
}))
.def("get", [](_CompGraphProfilerImpl& profiler) { return profiler._get_result(); });

m.def("dump_graph", [](const std::vector<VarNode*>& dest_vars) { m.def("dump_graph", [](const std::vector<VarNode*>& dest_vars) {
using namespace mgb::serialization; using namespace mgb::serialization;
std::vector<uint8_t> buf; std::vector<uint8_t> buf;


+ 19
- 0
imperative/python/test/unit/test_tracing.py View File

@@ -82,3 +82,22 @@ def test_dump():


file = io.BytesIO() file = io.BytesIO()
f.dump(file) f.dump(file)


def test_trace_profiler():
for symbolic in [False, True]:

@trace(symbolic=symbolic, profiling=True)
def f(x):
op = ops.Elemwise(mode="negate")
(y,) = apply(op, x)
return y

x = as_raw_tensor([1]).numpy()
y = f.__wrapped__(as_raw_tensor(x)).numpy()

f(as_raw_tensor(x))
f(as_raw_tensor(x)) # XXX: has to run twice

out = f.get_profile()
assert out.get("profiler")

Loading…
Cancel
Save