Skip to content
Merged
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
8 changes: 7 additions & 1 deletion include/tvm/meta_schedule/apply_history_best.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ namespace meta_schedule {
*/
class ApplyHistoryBestNode : public runtime::Object {
public:
/*! \brief A callback function that filters TE compute */
using FTEFilterFunc =
runtime::TypedPackedFunc<Optional<tir::PrimFunc>(const Array<te::Tensor, void>&)>;
/*! \brief A callback function that takes a tuning record and does something with it */
using FTakeTuningRecord = runtime::TypedPackedFunc<void(const TuningRecord&)>;

/*! \brief The database to be queried from */
Database database{nullptr};
Expand All @@ -60,9 +63,12 @@ class ApplyHistoryBestNode : public runtime::Object {
* \param mod The module to be queried
* \param target The target to be queried
* \param dispatched The IRs after dispatch
* \param f_take_tuning_record A callback function that takes a tuning record and does something
* with it
*/
Optional<IRModule> Query(runtime::String task_name, IRModule mod, Target target,
Optional<Array<IRModule>> dispatched);
Optional<Array<IRModule>> dispatched,
FTakeTuningRecord f_take_tuning_record);

static constexpr const char* _type_key = "meta_schedule.ApplyHistoryBest";
TVM_DECLARE_FINAL_OBJECT_INFO(ApplyHistoryBestNode, runtime::Object);
Expand Down
10 changes: 7 additions & 3 deletions include/tvm/tir/stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1483,6 +1483,9 @@ constexpr const char* software_pipeline_stage = "software_pipeline_stage";
/*! \brief Mark the order of a statement in the software pipeline */
constexpr const char* software_pipeline_order = "software_pipeline_order";

/*! \brief Mark the buffers which is const access and can be transformed layout. */
constexpr const char* layout_free_buffers = "layout_free_buffers";

/*! \brief Mark the tiling structure of blocks that are applied by rule Multi-Level-Tiling */
constexpr const char* meta_schedule_tiling_structure = "meta_schedule.tiling_structure";

Expand Down Expand Up @@ -1516,11 +1519,12 @@ constexpr const char* meta_schedule_unroll_explicit = "meta_schedule.unroll_expl
/*! \brief Mark auto-unroll setting on the block. */
constexpr const char* meta_schedule_unroll_implicit = "meta_schedule.unroll_implicit";

/*!
* \brief Mark that a block should be further rewritten using tensorization.
*/
/*! \brief Mark that a block should be further rewritten using tensorization. */
constexpr const char* meta_schedule_auto_tensorize = "meta_schedule.auto_tensorize";

/*! \brief Mark that a block is a preprocessor block for layout rewrite. */
constexpr const char* meta_schedule_layout_rewrite_preproc = "meta_schedule.layout_rewrite_preproc";

/*!
* \brief Check if attr_key is a pragma key extension
* \param attr_key The attr key to be compared
Expand Down
6 changes: 6 additions & 0 deletions include/tvm/tir/transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,12 @@ TVM_DLL Pass Filter(runtime::TypedPackedFunc<bool(PrimFunc)> fcond);
*/
TVM_DLL Pass InjectPTXAsyncCopy();

/*!
* \brief Remove the weight layout rewrite block
* \return The pass.
*/
TVM_DLL Pass RemoveWeightLayoutRewriteBlock();

} // namespace transform
} // namespace tir
} // namespace tvm
Expand Down
6 changes: 5 additions & 1 deletion python/tvm/meta_schedule/apply_history_best.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from tvm.tir import PrimFunc

from . import _ffi_api
from .database import Database
from .database import Database, TuningRecord
from .utils import make_logging_func

logger = logging.getLogger(__name__) # pylint: disable=invalid-name
Expand Down Expand Up @@ -71,6 +71,7 @@ def query(
mod: IRModule,
target: Target,
dispatched: Optional[List[IRModule]],
f_take_tuning_record: Callable[[TuningRecord], None] = None,
) -> Union[IRModule, None]:
"""The entry point of the integration

Expand All @@ -84,6 +85,8 @@ def query(
Target Info
dispatched : Optional[List[IRModule]]
A list of low-level IRs that the high-level IR could potentially dispatch to
f_take_tuning_record : Callable[[TuningRecord], None] = None
A callback function that takes a tuning record and does something with it

Returns
-------
Expand All @@ -97,6 +100,7 @@ def query(
mod,
target,
dispatched,
f_take_tuning_record,
)

@staticmethod
Expand Down
8 changes: 3 additions & 5 deletions python/tvm/meta_schedule/builder/local_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@
from tvm.target import Target

from ...contrib.popen_pool import MapResult, PopenPoolExecutor, StatusKind
from ..utils import (
cpu_count,
derived_object,
get_global_func_with_default_on_worker,
)
from ..utils import cpu_count, derived_object, get_global_func_with_default_on_worker
from .builder import BuilderInput, BuilderResult, PyBuilder

logger = logging.getLogger(__name__) # pylint: disable=invalid-name
Expand Down Expand Up @@ -258,8 +254,10 @@ def default_build(mod: IRModule, target: Target, _params: Optional[Dict[str, NDA
"""
# pylint: disable=import-outside-toplevel
from tvm.driver import build as tvm_build
from tvm.tir.transform import RemoveWeightLayoutRewriteBlock

# pylint: enable=import-outside-toplevel
mod = RemoveWeightLayoutRewriteBlock()(mod)
return tvm_build(mod, target=target)


Expand Down
15 changes: 11 additions & 4 deletions python/tvm/relay/backend/te_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@
from __future__ import absolute_import

import logging

import tvm
from tvm import te, autotvm
from tvm.ir.transform import PassContext
from tvm import autotvm, te
from tvm.runtime import Object
from tvm.support import libinfo
from tvm.target import Target
from ..backend.utils import mangle_module_name

from .. import function as _function
from .. import ty as _ty
from ..backend.utils import mangle_module_name
from . import _backend

logger = logging.getLogger("te_compiler")
Expand Down Expand Up @@ -170,14 +171,20 @@ def select_implementation(op, attrs, inputs, out_type, target, use_autotvm=True)
ret : tuple(relay.op.OpImplementation, List[tvm.te.Tensor])
The best op implementation and the corresponding output tensors.
"""
# pylint: disable=import-outside-toplevel
from tvm.auto_scheduler import is_auto_scheduler_enabled
from tvm.meta_schedule import is_meta_schedule_enabled

# pylint: enable=import-outside-toplevel

all_impls = get_valid_implementations(op, attrs, inputs, out_type, target)
if len(all_impls) == 0:
raise RuntimeError(f"No valid {op} implementations for {target}")
best_plevel_impl = max(all_impls, key=lambda x: x.plevel)

# Disable autotvm if auto_scheduler is enabled.
# (i.e., always return the implementation with the highest priority for auto-scheduler).
if PassContext.current().config.get("relay.backend.use_auto_scheduler", False):
if is_auto_scheduler_enabled() or is_meta_schedule_enabled():
use_autotvm = False

# If not use autotvm, always return the implementation with the highest priority
Expand Down
12 changes: 7 additions & 5 deletions python/tvm/relay/build_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

import numpy as np
from tvm.ir import IRModule
from tvm.ir.transform import PassContext
from tvm.target import Target

from .. import autotvm
Expand Down Expand Up @@ -139,20 +138,23 @@ def build(
params : dict
The parameters of the final graph.
"""
# pylint: disable=import-outside-toplevel
from tvm.auto_scheduler import is_auto_scheduler_enabled
from tvm.meta_schedule import is_meta_schedule_enabled

# pylint: enable=import-outside-toplevel
# Setup the params.
if params:
self._set_params(params)

# Build the IR module. If auto_scheduler is not enabled,
# then use the TOPI-defined schedule.
use_auto_scheduler = PassContext.current().config.get(
"relay.backend.use_auto_scheduler", False
)

# Turn off AutoTVM config not found warnings if auto_scheduler is enabled.
old_autotvm_silent = autotvm.GLOBAL_SCOPE.silent
autotvm.GLOBAL_SCOPE.silent = use_auto_scheduler or old_autotvm_silent
autotvm.GLOBAL_SCOPE.silent = (
is_auto_scheduler_enabled() or is_meta_schedule_enabled() or old_autotvm_silent
)

mod_name = mangle_module_name(mod_name)

Expand Down
12 changes: 11 additions & 1 deletion python/tvm/tir/transform/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# under the License.
"""Wrapping existing transformations."""
# pylint: disable=invalid-name
from typing import Optional, Callable
from typing import Callable, Optional

from . import _ffi_api
from . import function_pass as _fpass
Expand Down Expand Up @@ -836,3 +836,13 @@ def InjectPTXAsyncCopy():
The result pass
"""
return _ffi_api.InjectPTXAsyncCopy() # type: ignore


def RemoveWeightLayoutRewriteBlock():
"""Remove weight layout rewrite block before benchmarking during tuning stage.
Returns
-------
fpass : tvm.transform.Pass
The result pass
"""
return _ffi_api.RemoveWeightLayoutRewriteBlock() # type: ignore
7 changes: 5 additions & 2 deletions src/meta_schedule/apply_history_best.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ ApplyHistoryBest::ApplyHistoryBest(Database database,
}

Optional<IRModule> ApplyHistoryBestNode::Query(runtime::String task_name, IRModule mod,
Target target,
Optional<Array<IRModule>> dispatched) {
Target target, Optional<Array<IRModule>> dispatched,
FTakeTuningRecord f_take_tuning_record) {
ICHECK(dispatched.defined());
ICHECK_EQ(dispatched.value().size(), 1);
ICHECK(HasOnlyOneFunction<relay::Function>(mod)) << mod;
Expand All @@ -122,6 +122,9 @@ Optional<IRModule> ApplyHistoryBestNode::Query(runtime::String task_name, IRModu
if (database->HasWorkload(prim_mod)) {
Array<TuningRecord> records = database->GetTopK(database->CommitWorkload(prim_mod), 1);
if (records.size() == 1) {
if (f_take_tuning_record != nullptr) {
f_take_tuning_record(records[0]);
}
tir::Schedule sch =
tir::Schedule::Traced(records[0]->workload->mod, /*seed=*/-1, /*debug_mask=*/0,
/*error_render_level=*/tir::ScheduleErrorRenderLevel::kNone);
Expand Down
9 changes: 4 additions & 5 deletions src/meta_schedule/arg_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,10 @@ Array<ArgInfo> ArgInfo::FromPrimFunc(const tir::PrimFunc& func) {
}

Array<ArgInfo> ArgInfo::FromEntryFunc(const IRModule& mod, bool remove_preproc) {
// TODO(@jinhongyii): add pass for layout rewrite
// if (remove_preproc) {
// IRModule new_mod = tir::transform::RemoveWeightLayoutRewriteBlock()(mod);
// return ArgInfo::FromPrimFunc(FindEntryFunc(new_mod));
// }
if (remove_preproc) {
IRModule new_mod = tir::transform::RemoveWeightLayoutRewriteBlock()(mod);
return ArgInfo::FromPrimFunc(FindEntryFunc(new_mod));
}
return ArgInfo::FromPrimFunc(FindEntryFunc(mod));
}

Expand Down
1 change: 1 addition & 0 deletions src/meta_schedule/feature_extractor/per_store_feature.cc
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ Pass SimplifyForFeatureExtraction() {
*/
Sequential PassListForPerStoreFeature() {
return Sequential({
tir::transform::RemoveWeightLayoutRewriteBlock(),
tir::transform::SimplifyForFeatureExtraction(),
tir::transform::LowerCrossThreadReduction(),
tir::transform::LowerInitBlock(),
Expand Down
1 change: 1 addition & 0 deletions src/meta_schedule/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <tvm/runtime/container/optional.h>
#include <tvm/support/parallel_for.h>
#include <tvm/tir/schedule/schedule.h>
#include <tvm/tir/transform.h>

#include <algorithm>
#include <string>
Expand Down
27 changes: 23 additions & 4 deletions src/relay/backend/te_compiler_cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#include <tvm/te/schedule.h>
#include <tvm/te/schedule_pass.h>
#include <tvm/tir/function.h>
#include <tvm/tir/index_map.h>
#include <tvm/tir/transform.h>
#include <tvm/topi/tags.h>

#include <functional>
Expand All @@ -47,6 +49,7 @@

#include "../../te/operation/create_primfunc.h"
#include "../op/memory/memory.h"
#include "../transforms/meta_schedule_layout_rewrite.h"
#include "../transforms/pass_utils.h"
#include "utils.h"

Expand All @@ -59,6 +62,16 @@ TVM_REGISTER_NODE_TYPE(CachedFuncNode);
TVM_REGISTER_NODE_TYPE(CCacheKeyNode);
TVM_REGISTER_NODE_TYPE(CCacheValueNode);

void ExtractTransformLayout(const meta_schedule::TuningRecord& record) {
static tir::InstructionKind kind_transform_layout = tir::InstructionKind::Get("TransformLayout");
for (const tir::Instruction& inst : record->trace->insts) {
if (inst->kind.same_as(kind_transform_layout)) {
ICHECK_EQ(inst->attrs.size(), 3);
relay::MetaScheduleLayoutRewriter::LayoutQueuePush(Downcast<tir::IndexMap>(inst->attrs[2]));
}
}
}

LoweredOutput::LoweredOutput(tvm::Array<te::Tensor> outputs, OpImplementation impl) {
auto n = make_object<LoweredOutputNode>();
n->outputs = std::move(outputs);
Expand Down Expand Up @@ -353,10 +366,16 @@ class ScheduleBuilder : public ExprVisitor {
meta_schedule_ctx_.value()->te_filter_func(te_args)) {
IRModule relay_mod({{prim_fn_var, relay_func}});
IRModule tir_mod({{prim_fn_var, tir_func.value()}});
if (Optional<IRModule> scheduled_mod = meta_schedule_ctx_.value()->Query(
prim_fn_var->name_hint, relay_mod, target_, Array<IRModule>{tir_mod})) {
ICHECK_EQ(scheduled_mod.value()->functions.count(prim_fn_var), 1);
prim_func = Downcast<tir::PrimFunc>(scheduled_mod.value()->functions[prim_fn_var]);
if (Optional<IRModule> opt_scheduled_mod = meta_schedule_ctx_.value()->Query(
/*task_name=*/prim_fn_var->name_hint, //
/*mod=*/relay_mod, //
/*target=*/target_, //
/*dispatched=*/Array<IRModule>{tir_mod}, //
/*f_take_tuning_record=*/ExtractTransformLayout)) {
IRModule scheduled_mod =
tir::transform::RemoveWeightLayoutRewriteBlock()(opt_scheduled_mod.value());
ICHECK_EQ(scheduled_mod->functions.count(prim_fn_var), 1);
prim_func = Downcast<tir::PrimFunc>(scheduled_mod->functions[prim_fn_var]);
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/te/operation/create_primfunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,27 +103,27 @@ class LayoutFreePlaceholdersNormalizer : public StmtMutator {
for (int i : this->layout_free_buffer_indices_) {
indices.push_back(Integer(i));
}
return WithAttr(std::move(func), attr, indices);
return WithAttr(std::move(func), tir::attr::layout_free_buffers, indices);
}

Stmt VisitStmt_(const BlockNode* _block) final {
Block block = Downcast<Block>(StmtMutator::VisitStmt_(_block));
if (Optional<ObjectRef> ann = block->annotations.Get(attr)) {
if (Optional<ObjectRef> ann = block->annotations.Get(topi_attr)) {
Array<Buffer> buffers = Downcast<Array<Buffer>>(ann);
for (Buffer buffer : buffers) {
auto it = buffer2index_.find(buffer);
if (it != buffer2index_.end()) {
layout_free_buffer_indices_.insert(it->second);
}
}
block.CopyOnWrite()->annotations.erase(attr);
block.CopyOnWrite()->annotations.erase(topi_attr);
}
return block;
}

std::unordered_map<tir::Buffer, int, ObjectPtrHash, ObjectPtrEqual> buffer2index_;
std::set<int> layout_free_buffer_indices_;
String attr = "layout_free_placeholders";
String topi_attr = "layout_free_placeholders";
};

BlockRealize GenerateBlockFromTensors(const te::ComputeOp& compute_op,
Expand Down
Loading