tkonolige commented on a change in pull request #7952:
URL: https://github.com/apache/tvm/pull/7952#discussion_r634627982



##########
File path: include/tvm/ir/instrument.h
##########
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*!
+ * \file tvm/ir/instrument.h
+ *
+ * This file introduces a pass instrument infrastructure, inspired from LLVM 
and MLIR.
+ * It inserts instrumentation points between passes run.
+ *
+ * Within a pass context (tvm::transfom::PassContext), the instrumentation 
call sequence will like:
+ *
+ *   Instrument SetUp
+ *
+ *     if (Instrument Before Pass)
+ *       Pass Run

Review comment:
       Can you differentiate the two blocks here so it doesn't look like the 
same pass is being run twice.

##########
File path: include/tvm/ir/instrument.h
##########
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*!
+ * \file tvm/ir/instrument.h
+ *
+ * This file introduces a pass instrument infrastructure, inspired from LLVM 
and MLIR.
+ * It inserts instrumentation points between passes run.
+ *
+ * Within a pass context (tvm::transfom::PassContext), the instrumentation 
call sequence will like:
+ *
+ *   Instrument SetUp
+ *
+ *     if (Instrument Before Pass)
+ *       Pass Run
+ *       Instrument After Pass
+ *
+ *     if (Instrument Before Pass)
+ *       Pass Run
+ *       Instrument After Pass
+ *
+ *   Instrument TearDown
+ *
+ *
+ * Instrument point before pass can determine particular pass is disable or 
not depends on the
+ * callback registered.

Review comment:
       ```suggestion
    * The `Before Pass` instrumentation point can selectively disable passes by 
returning true (to enable) or false (to disable).
   ```

##########
File path: include/tvm/ir/instrument.h
##########
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*!
+ * \file tvm/ir/instrument.h
+ *
+ * This file introduces a pass instrument infrastructure, inspired from LLVM 
and MLIR.

Review comment:
       ```suggestion
    * This file introduces a pass instrument infrastructure, inspired by LLVM 
and MLIR.
   ```

##########
File path: python/tvm/ir/transform.py
##########
@@ -80,9 +88,13 @@ def __init__(
         if not isinstance(disabled, (list, tuple)):
             raise TypeError("disabled_pass is expected to be the type of " + 
"list/tuple/set.")
 
+        instruments = list(instruments) if instruments else []
+        if not isinstance(instruments, (list, tuple)):
+            raise TypeError("disabled_pass is expected to be the type of " + 
"list/tuple/set.")

Review comment:
       Add which type it actually is to the error message.

##########
File path: src/ir/transform.cc
##########
@@ -162,170 +164,64 @@ void PassContext::RegisterConfigOption(const char* key, 
uint32_t value_type_inde
 
 PassContext PassContext::Create() { return 
PassContext(make_object<PassContextNode>()); }
 
-void PassContext::Trace(const IRModule& module, const PassInfo& info, bool 
is_before) const {
+void PassContext::InstrumentSetUp() const {
   auto pass_ctx_node = this->operator->();
-  if (pass_ctx_node->trace_func != nullptr) {
-    pass_ctx_node->trace_func(module, info, is_before);
+  if (pass_ctx_node->instruments.defined()) {
+    for (instrument::PassInstrument pi : pass_ctx_node->instruments) {
+      pi->SetUp();
+    }
   }
 }
 
-class ModulePass;
-
-/*! \brief PassProfile stores profiling information for a given pass and its 
sub-passes. */
-struct PassProfile {
-  // TODO(@altanh): expose PassProfile through TVM Object API
-  using Clock = std::chrono::steady_clock;
-  using Duration = std::chrono::duration<double, std::micro>;
-  using Time = std::chrono::time_point<Clock>;
-
-  /*! \brief The name of the pass being profiled. */
-  String name;
-  /*! \brief The time when the pass was entered. */
-  Time start;
-  /*! \brief The time when the pass completed. */
-  Time end;
-  /*! \brief The total duration of the pass, i.e. end - start. */
-  Duration duration;
-  /*! \brief PassProfiles for all sub-passes invoked during the execution of 
the pass. */
-  std::vector<PassProfile> children;
-
-  explicit PassProfile(String name)
-      : name(name), start(Clock::now()), end(Clock::now()), children() {}
-
-  /*! \brief Gets the PassProfile of the currently executing pass. */
-  static PassProfile* Current();
-  /*! \brief Pushes a new PassProfile with the given pass name. */
-  static void EnterPass(String name);
-  /*! \brief Pops the current PassProfile. */
-  static void ExitPass();
-};
-
-struct PassProfileThreadLocalEntry {
-  /*! \brief The placeholder top-level PassProfile. */
-  PassProfile root;
-  /*! \brief The stack of PassProfiles for nested passes currently running. */
-  std::stack<PassProfile*> profile_stack;
-  /*! \brief Whether or not pass profiling is active. */
-  bool active;
-
-  PassProfileThreadLocalEntry() : root("root"), active(false) {}
-};
-
-/*! \brief Thread local store to hold the pass profiling data. */
-typedef dmlc::ThreadLocalStore<PassProfileThreadLocalEntry> 
PassProfileThreadLocalStore;
-
-void PassProfile::EnterPass(String name) {
-  if (!PassProfileThreadLocalStore::Get()->active) return;
-  PassProfile* cur = PassProfile::Current();
-  cur->children.emplace_back(name);
-  
PassProfileThreadLocalStore::Get()->profile_stack.push(&cur->children.back());
+void PassContext::InstrumentTearDown() const {
+  auto pass_ctx_node = this->operator->();
+  if (pass_ctx_node->instruments.defined()) {
+    for (instrument::PassInstrument pi : pass_ctx_node->instruments) {
+      pi->TearDown();
+    }
+  }
 }
 
-void PassProfile::ExitPass() {
-  if (!PassProfileThreadLocalStore::Get()->active) return;
-  PassProfile* cur = PassProfile::Current();
-  ICHECK_NE(cur->name, "root") << "mismatched enter/exit for pass profiling";
-  cur->end = std::move(PassProfile::Clock::now());
-  cur->duration = std::chrono::duration_cast<PassProfile::Duration>(cur->end - 
cur->start);
-  PassProfileThreadLocalStore::Get()->profile_stack.pop();
+bool PassContext::InstrumentBeforePass(const IRModule& ir_module, const 
PassInfo& pass_info) const {
+  auto pass_ctx_node = this->operator->();
+  if (pass_ctx_node->instruments.defined()) {
+    for (instrument::PassInstrument pi : pass_ctx_node->instruments) {
+      if (!pi->RunBeforePass(ir_module, pass_info)) {
+        return false;
+      }
+    }
+    return true;
+  }
+  return true;
 }
 
-PassProfile* PassProfile::Current() {
-  PassProfileThreadLocalEntry* entry = PassProfileThreadLocalStore::Get();
-  if (!entry->profile_stack.empty()) {
-    return entry->profile_stack.top();
-  } else {
-    return &entry->root;
+void PassContext::InstrumentAfterPass(const IRModule& ir_module, const 
PassInfo& pass_info) const {
+  auto pass_ctx_node = this->operator->();
+  if (pass_ctx_node->instruments.defined()) {
+    for (instrument::PassInstrument pi : pass_ctx_node->instruments) {
+      pi->RunAfterPass(ir_module, pass_info);
+    }
   }
 }
 
 IRModule Pass::operator()(IRModule mod) const {
   const PassNode* node = operator->();
   ICHECK(node != nullptr);
-  PassProfile::EnterPass(node->Info()->name);
+  // PassProfile::EnterPass(node->Info()->name);
   auto ret = node->operator()(std::move(mod));
-  PassProfile::ExitPass();
+  // PassProfile::ExitPass();

Review comment:
       uncomment or delete

##########
File path: include/tvm/ir/instrument.h
##########
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*!
+ * \file tvm/ir/instrument.h
+ *
+ * This file introduces a pass instrument infrastructure, inspired from LLVM 
and MLIR.
+ * It inserts instrumentation points between passes run.

Review comment:
       ```suggestion
    * It inserts instrumentation points around passes.
   ```

##########
File path: include/tvm/ir/instrument.h
##########
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*!
+ * \file tvm/ir/instrument.h
+ *
+ * This file introduces a pass instrument infrastructure, inspired from LLVM 
and MLIR.
+ * It inserts instrumentation points between passes run.
+ *
+ * Within a pass context (tvm::transfom::PassContext), the instrumentation 
call sequence will like:
+ *
+ *   Instrument SetUp
+ *
+ *     if (Instrument Before Pass)
+ *       Pass Run
+ *       Instrument After Pass
+ *
+ *     if (Instrument Before Pass)
+ *       Pass Run
+ *       Instrument After Pass
+ *
+ *   Instrument TearDown
+ *
+ *
+ * Instrument point before pass can determine particular pass is disable or 
not depends on the
+ * callback registered.
+ */
+#ifndef TVM_IR_INSTRUMENT_H_
+#define TVM_IR_INSTRUMENT_H_
+
+#include <tvm/node/reflection.h>
+#include <tvm/runtime/container.h>
+
+#include <utility>
+#include <vector>
+
+namespace tvm {
+
+class IRModule;
+
+// Forward class for PassInstrumentNode methods
+namespace transform {
+class PassInfo;
+}  // namespace transform
+
+namespace instrument {
+
+/*!
+ * \brief PassInstrumentNode forms an instrument implementation.
+ * It provides API for users to register callbacks at different instrument 
point.
+ * \sa PassInstrument
+ */
+class PassInstrumentNode : public Object {
+ public:
+  virtual ~PassInstrumentNode() {}
+
+  /*! \brief Set up environment for instrumentation. */
+  virtual void SetUp() const = 0;
+
+  /*! \brief Clean up instrumentation environment. */
+  virtual void TearDown() const = 0;
+
+  /*!
+   * \brief Instrument before pass run, determine whether to run the pass or 
not.
+   * \param mod The module that an optimization pass runs on.
+   * \param info The pass information.
+   *
+   * \return true to run the pass; false to skip the pass.
+   */
+  virtual bool RunBeforePass(const IRModule& mod, const transform::PassInfo& 
info) const = 0;

Review comment:
       Can calls to `RunBeforePass` be nested?

##########
File path: include/tvm/ir/instrument.h
##########
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*!
+ * \file tvm/ir/instrument.h
+ *
+ * This file introduces a pass instrument infrastructure, inspired from LLVM 
and MLIR.
+ * It inserts instrumentation points between passes run.
+ *
+ * Within a pass context (tvm::transfom::PassContext), the instrumentation 
call sequence will like:
+ *
+ *   Instrument SetUp
+ *
+ *     if (Instrument Before Pass)

Review comment:
       ```suggestion
    *     if (Instrument Before Pass())
   ```
   
   To make it clear that you are running the before pass

##########
File path: include/tvm/ir/instrument.h
##########
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*!
+ * \file tvm/ir/instrument.h
+ *
+ * This file introduces a pass instrument infrastructure, inspired from LLVM 
and MLIR.
+ * It inserts instrumentation points between passes run.
+ *
+ * Within a pass context (tvm::transfom::PassContext), the instrumentation 
call sequence will like:
+ *
+ *   Instrument SetUp
+ *
+ *     if (Instrument Before Pass)
+ *       Pass Run
+ *       Instrument After Pass
+ *
+ *     if (Instrument Before Pass)

Review comment:
       How does disabling passes work if there are multiple instruments?

##########
File path: include/tvm/ir/instrument.h
##########
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*!
+ * \file tvm/ir/instrument.h
+ *
+ * This file introduces a pass instrument infrastructure, inspired from LLVM 
and MLIR.
+ * It inserts instrumentation points between passes run.
+ *
+ * Within a pass context (tvm::transfom::PassContext), the instrumentation 
call sequence will like:
+ *
+ *   Instrument SetUp

Review comment:
       I would move this description into the `PassInstrumentNode` class

##########
File path: include/tvm/ir/instrument.h
##########
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*!
+ * \file tvm/ir/instrument.h
+ *
+ * This file introduces a pass instrument infrastructure, inspired from LLVM 
and MLIR.
+ * It inserts instrumentation points between passes run.
+ *
+ * Within a pass context (tvm::transfom::PassContext), the instrumentation 
call sequence will like:
+ *
+ *   Instrument SetUp
+ *
+ *     if (Instrument Before Pass)
+ *       Pass Run
+ *       Instrument After Pass
+ *
+ *     if (Instrument Before Pass)
+ *       Pass Run
+ *       Instrument After Pass
+ *
+ *   Instrument TearDown
+ *
+ *
+ * Instrument point before pass can determine particular pass is disable or 
not depends on the
+ * callback registered.
+ */
+#ifndef TVM_IR_INSTRUMENT_H_
+#define TVM_IR_INSTRUMENT_H_
+
+#include <tvm/node/reflection.h>
+#include <tvm/runtime/container.h>
+
+#include <utility>
+#include <vector>
+
+namespace tvm {
+
+class IRModule;
+
+// Forward class for PassInstrumentNode methods
+namespace transform {
+class PassInfo;
+}  // namespace transform
+
+namespace instrument {
+
+/*!
+ * \brief PassInstrumentNode forms an instrument implementation.
+ * It provides API for users to register callbacks at different instrument 
point.

Review comment:
       ```suggestion
    * It provides API for users to register callbacks at different 
instrumentation points.
   ```

##########
File path: python/tvm/ir/transform.py
##########
@@ -65,12 +65,20 @@ class PassContext(tvm.runtime.Object):
     disabled_pass : Optional[Union[List[str], Set[str], Tuple[str]]]
         The list of passes that are disabled.
 
+    instruments : Optional[Union[List[PassInstrument], Set[PassInstrument], 
Tuple[PassInstrument]]]

Review comment:
       ```suggestion
       instruments : Optional[Sequence[PassInstrument]]
   ```

##########
File path: src/ir/transform.cc
##########
@@ -162,170 +164,64 @@ void PassContext::RegisterConfigOption(const char* key, 
uint32_t value_type_inde
 
 PassContext PassContext::Create() { return 
PassContext(make_object<PassContextNode>()); }
 
-void PassContext::Trace(const IRModule& module, const PassInfo& info, bool 
is_before) const {
+void PassContext::InstrumentSetUp() const {
   auto pass_ctx_node = this->operator->();
-  if (pass_ctx_node->trace_func != nullptr) {
-    pass_ctx_node->trace_func(module, info, is_before);
+  if (pass_ctx_node->instruments.defined()) {
+    for (instrument::PassInstrument pi : pass_ctx_node->instruments) {
+      pi->SetUp();
+    }
   }
 }
 
-class ModulePass;
-
-/*! \brief PassProfile stores profiling information for a given pass and its 
sub-passes. */
-struct PassProfile {
-  // TODO(@altanh): expose PassProfile through TVM Object API
-  using Clock = std::chrono::steady_clock;
-  using Duration = std::chrono::duration<double, std::micro>;
-  using Time = std::chrono::time_point<Clock>;
-
-  /*! \brief The name of the pass being profiled. */
-  String name;
-  /*! \brief The time when the pass was entered. */
-  Time start;
-  /*! \brief The time when the pass completed. */
-  Time end;
-  /*! \brief The total duration of the pass, i.e. end - start. */
-  Duration duration;
-  /*! \brief PassProfiles for all sub-passes invoked during the execution of 
the pass. */
-  std::vector<PassProfile> children;
-
-  explicit PassProfile(String name)
-      : name(name), start(Clock::now()), end(Clock::now()), children() {}
-
-  /*! \brief Gets the PassProfile of the currently executing pass. */
-  static PassProfile* Current();
-  /*! \brief Pushes a new PassProfile with the given pass name. */
-  static void EnterPass(String name);
-  /*! \brief Pops the current PassProfile. */
-  static void ExitPass();
-};
-
-struct PassProfileThreadLocalEntry {
-  /*! \brief The placeholder top-level PassProfile. */
-  PassProfile root;
-  /*! \brief The stack of PassProfiles for nested passes currently running. */
-  std::stack<PassProfile*> profile_stack;
-  /*! \brief Whether or not pass profiling is active. */
-  bool active;
-
-  PassProfileThreadLocalEntry() : root("root"), active(false) {}
-};
-
-/*! \brief Thread local store to hold the pass profiling data. */
-typedef dmlc::ThreadLocalStore<PassProfileThreadLocalEntry> 
PassProfileThreadLocalStore;
-
-void PassProfile::EnterPass(String name) {
-  if (!PassProfileThreadLocalStore::Get()->active) return;
-  PassProfile* cur = PassProfile::Current();
-  cur->children.emplace_back(name);
-  
PassProfileThreadLocalStore::Get()->profile_stack.push(&cur->children.back());
+void PassContext::InstrumentTearDown() const {
+  auto pass_ctx_node = this->operator->();
+  if (pass_ctx_node->instruments.defined()) {
+    for (instrument::PassInstrument pi : pass_ctx_node->instruments) {
+      pi->TearDown();
+    }
+  }
 }
 
-void PassProfile::ExitPass() {
-  if (!PassProfileThreadLocalStore::Get()->active) return;
-  PassProfile* cur = PassProfile::Current();
-  ICHECK_NE(cur->name, "root") << "mismatched enter/exit for pass profiling";
-  cur->end = std::move(PassProfile::Clock::now());
-  cur->duration = std::chrono::duration_cast<PassProfile::Duration>(cur->end - 
cur->start);
-  PassProfileThreadLocalStore::Get()->profile_stack.pop();
+bool PassContext::InstrumentBeforePass(const IRModule& ir_module, const 
PassInfo& pass_info) const {
+  auto pass_ctx_node = this->operator->();
+  if (pass_ctx_node->instruments.defined()) {
+    for (instrument::PassInstrument pi : pass_ctx_node->instruments) {
+      if (!pi->RunBeforePass(ir_module, pass_info)) {
+        return false;
+      }
+    }
+    return true;
+  }
+  return true;
 }
 
-PassProfile* PassProfile::Current() {
-  PassProfileThreadLocalEntry* entry = PassProfileThreadLocalStore::Get();
-  if (!entry->profile_stack.empty()) {
-    return entry->profile_stack.top();
-  } else {
-    return &entry->root;
+void PassContext::InstrumentAfterPass(const IRModule& ir_module, const 
PassInfo& pass_info) const {
+  auto pass_ctx_node = this->operator->();
+  if (pass_ctx_node->instruments.defined()) {
+    for (instrument::PassInstrument pi : pass_ctx_node->instruments) {
+      pi->RunAfterPass(ir_module, pass_info);
+    }
   }
 }
 
 IRModule Pass::operator()(IRModule mod) const {
   const PassNode* node = operator->();
   ICHECK(node != nullptr);
-  PassProfile::EnterPass(node->Info()->name);
+  // PassProfile::EnterPass(node->Info()->name);

Review comment:
       uncomment or delete

##########
File path: tests/python/relay/test_pass_manager.py
##########
@@ -536,10 +537,12 @@ def test_print_ir(capfd):
 __TRACE_COUNTER__ = 0
 
 
-def _tracer(module, info, is_before):
-    global __TRACE_COUNTER__
-    if bool(is_before):
[email protected]_instrument
+class MyInstrument:
+    def run_before_pass(self, module, info):
+        global __TRACE_COUNTER__

Review comment:
       Can you switch this test to not use a global.

##########
File path: src/ir/instrument.cc
##########
@@ -0,0 +1,310 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*!
+ * \file src/ir/instrument.cc
+ * \brief Infrastructure for instrumentation.
+ */
+#include <dmlc/thread_local.h>
+#include <tvm/ir/instrument.h>
+#include <tvm/ir/transform.h>
+#include <tvm/node/repr_printer.h>
+#include <tvm/runtime/registry.h>
+
+#include <stack>
+
+namespace tvm {
+namespace instrument {
+
+/*!
+ * \brief A named PassInstrument implementation
+ * \sa NamedPassInstrument
+ */
+class NamedPassInstrumentNode : public PassInstrumentNode {
+ public:
+  /*! \brief Name of this pass instrument object. */
+  String name;
+
+  /*! \brief Callback for instrumentation environment set up. */
+  runtime::TypedPackedFunc<void()> set_up_callback;
+  /*! \brief Callback for instrumentation environment clean up. */
+  runtime::TypedPackedFunc<void()> tear_down_callback;
+
+  /*! \brief Callback to run before a pass. */
+  runtime::TypedPackedFunc<bool(const IRModule&, const transform::PassInfo&)>
+      run_before_pass_callback;
+  /*! \brief Callback to run after a pass. */
+  runtime::TypedPackedFunc<void(const IRModule&, const transform::PassInfo&)>
+      run_after_pass_callback;
+
+  void VisitAttrs(AttrVisitor* v) { v->Visit("name", &name); }
+
+  /*! \brief Set up environment for instrumentation. */
+  void SetUp() const final;
+
+  /*! \brief Clean up instrumentation environment. */
+  void TearDown() const final;
+
+  /*!
+   * \brief Instrument before pass run, determine whether to run the pass or 
not.
+   * \param mod The module that an optimization pass runs on.
+   * \param info The pass information.
+   *
+   * \return true to run the pass; false to skip the pass.
+   */
+  bool RunBeforePass(const IRModule& mod, const transform::PassInfo& info) 
const final;
+
+  /*!
+   * \brief Instrument after pass run.
+   *
+   * \param mod The module that an optimization pass runs on.
+   * \param info The pass information.
+   */
+  void RunAfterPass(const IRModule& mod, const transform::PassInfo& info) 
const final;
+
+  static constexpr const char* _type_key = "instrument.NamedPassInstrument";
+  TVM_DECLARE_FINAL_OBJECT_INFO(NamedPassInstrumentNode, PassInstrumentNode);
+};
+
+/*!
+ * \brief Managed reference class for NamedPassInstrumentNode
+ * \sa NamedPassInstrumentNode
+ */
+class NamedPassInstrument : public PassInstrument {
+ public:
+  /*!
+   * \brief Constructor
+   * \param name Name for this instrumentation.
+   */
+  TVM_DLL NamedPassInstrument(String name);

Review comment:
       Why not have the constructor take all the `TypedPackedFunc`s as 
arguments? Then you can avoid the mutable accessor




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to