Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AOT] Support LLVM backend with C++ runtime #10753

Merged
merged 33 commits into from
Apr 19, 2022
Merged

Conversation

areusch
Copy link
Contributor

@areusch areusch commented Mar 24, 2022

This PR adds support for using the LLVM backend under the C++ runtime. Additional work is needed to support LLVM under the C runtime for microTVM uses.

#10280

@areusch areusch force-pushed the mbmr-aot-llvm branch 4 times, most recently from b98da99 to 111efec Compare March 24, 2022 20:03
@github-actions
Copy link
Contributor

It has been a while since this PR was updated, please leave a review or address the outstanding comments. @areusch if this PR is still a work in progress, please convert it to a draft until it is ready for review.

Copy link
Contributor

@manupak manupak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a pass @areusch .

Few comments for docs / cleanup.

* \param num the number to convert
* \return PrimExpr representing num
*/
inline PrimExpr ConstInt32(int32_t num) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not needed for this PR, but should we move this as tir::make_const_int32 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to use tir::make_const, which i think handles it

return tir::Evaluate(tir::Call(DataType::Int(32), tvm::tir::builtin::call_extern(),
{tvm::tir::StringImm(device_hook), context}));
}
} // namespace
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this empty namespace ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to make this a "static" function aka it cannot be linked against from elsewhere

tir::Stmt body = tir::SeqStmt::Flatten(prep_stmts_, call_stmts);

for (auto bind : let_binds_) {
body = tir::LetStmt(bind.first, bind.second, body);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need a Let binding here? Cant we just arg bind w/o introducing a let node here ?

void Bind(const PrimExpr& arg, const PrimExpr& value, const std::string& arg_name,
bool with_let = false);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah sorry, this part is cruft and should get deleted.

}
} // namespace

class AOTCallGenerator {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs : we need docs for this but I think this part is still WIP as I did not see who uses this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point--this is cruft from the old approach, before I started relying on LegalizePackedCalls/LowerTVMBuiltin, so can remove it now :)

PackedCall pc;
std::string func_name = args[0].as<StringImmNode>()->value;
llvm::Value* handle = GetPackedFuncHandle(func_name);
llvm::Value* handle = nullptr;
if (use_string_lookup) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we dont need to introduce handle just yet.

Shall we just merged to a single if/else down ? -- so its clear what happens when string-based function lookup is not used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

if (auto* ptr_op = op->op.as<OpNode>()) {
auto call_op = GetRef<Op>(ptr_op);
if (op->op.same_as(builtin_call_extern_) || op->op.same_as(builtin_call_pure_extern_)) {
if (op->op.same_as(builtin_lookup_param_)) {
// return llvm::ConstantInt::get(t_void_p_, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -389,6 +406,16 @@ class CodeGenLLVM : public ExprFunctor<llvm::Value*(const PrimExpr&)>,
unsigned int shared_address_space, int alignment,
llvm::GlobalValue::LinkageTypes linkage);

llvm::Argument* GetArg(const llvm::Function* function, int i) const {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add docs for this ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

// std::string tmp;
// llvm::raw_string_ostream stream(tmp);
// mod->print(stream, nullptr);
// LOG(INFO) << "LLVM metadata IR: " << stream.str();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -144,6 +144,12 @@ static runtime::Module CreateCppMetadataModule(
auto metadata_module = CreateCSourceCppMetadataModule(runtime_metadata);
metadata_module->Import(target_module);
target_module = metadata_module;
#ifdef TVM_LLVM_VERSION
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this Ifdef ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indicates USE_LLVM is ON. added a comment.

* \file tvm/target/metadata_utils.cc
* \brief Defines utility functions and classes for emitting metadata.
*/
#include "metadata_utils.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add docs for all the functions introduced here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done (let me know if more are needed)

masahi and others added 20 commits April 5, 2022 16:41
 * this is necessary to allow CodeGenCPU to emit calls that include resource_handle.
 * previously I believe we required interface_api == "c", but
   this really means to generate C API bindings, and we are generating
   "packed" bindings.
 * I think "c" was chosen here because the distinction between
   interface-api and use-unpacked-api is confusing. "c" interface-api
   means to generate an entrypoint API for microcontrollers that
   accepts bare data buffers. "packed" interface-api means to generate
   a TVMBackendPackedCFunc entrypoint. use-unpacked-api forms the same
   determination for the operator functions.
 * A further confusion here is that there are two ways to call
   "packed" operator functions: tir.tvm_builtin_call_packed and
   tir.tvm_builtin_call_cpacked. This distinction describes whether or
   not to late-bind calls via TVMBackendGetFuncFromEnv. Right now, AOT
   only ever requires call_cpacked because target_host == target, and
   for all suitable target_host, we expect a single DSO-exportable
   runtime.Module. When we move away from this by introducing
   heterogeneous target support to AOT, we can use this as a condition
   to help us choose between call_cpacked and call_packed (and
   possibly add a compile-time option to assert it is call_cpacked,
   for situations where we really don't want call_packed).
Copy link
Contributor Author

@areusch areusch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manupa-arm thanks for the review! i'm still working on fixing up the unit tests (the test_tir_usmp_transform_convert_pool_allocations_to_offsets needs updating but I don't quite understand how to do this with preflattened_buffer_map--will confer with @Lunderberg tomorrow).

would appreciate a second round of comments when you get a minute!

* \param num the number to convert
* \return PrimExpr representing num
*/
inline PrimExpr ConstInt32(int32_t num) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to use tir::make_const, which i think handles it

return tir::Evaluate(tir::Call(DataType::Int(32), tvm::tir::builtin::call_extern(),
{tvm::tir::StringImm(device_hook), context}));
}
} // namespace
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to make this a "static" function aka it cannot be linked against from elsewhere

}
} // namespace

class AOTCallGenerator {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point--this is cruft from the old approach, before I started relying on LegalizePackedCalls/LowerTVMBuiltin, so can remove it now :)

tir::Stmt body = tir::SeqStmt::Flatten(prep_stmts_, call_stmts);

for (auto bind : let_binds_) {
body = tir::LetStmt(bind.first, bind.second, body);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah sorry, this part is cruft and should get deleted.

PackedCall pc;
std::string func_name = args[0].as<StringImmNode>()->value;
llvm::Value* handle = GetPackedFuncHandle(func_name);
llvm::Value* handle = nullptr;
if (use_string_lookup) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

if (auto* ptr_op = op->op.as<OpNode>()) {
auto call_op = GetRef<Op>(ptr_op);
if (op->op.same_as(builtin_call_extern_) || op->op.same_as(builtin_call_pure_extern_)) {
if (op->op.same_as(builtin_lookup_param_)) {
// return llvm::ConstantInt::get(t_void_p_, 0);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -389,6 +406,16 @@ class CodeGenLLVM : public ExprFunctor<llvm::Value*(const PrimExpr&)>,
unsigned int shared_address_space, int alignment,
llvm::GlobalValue::LinkageTypes linkage);

llvm::Argument* GetArg(const llvm::Function* function, int i) const {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

// std::string tmp;
// llvm::raw_string_ostream stream(tmp);
// mod->print(stream, nullptr);
// LOG(INFO) << "LLVM metadata IR: " << stream.str();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -144,6 +144,12 @@ static runtime::Module CreateCppMetadataModule(
auto metadata_module = CreateCSourceCppMetadataModule(runtime_metadata);
metadata_module->Import(target_module);
target_module = metadata_module;
#ifdef TVM_LLVM_VERSION
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indicates USE_LLVM is ON. added a comment.

* \file tvm/target/metadata_utils.cc
* \brief Defines utility functions and classes for emitting metadata.
*/
#include "metadata_utils.h"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done (let me know if more are needed)

Copy link
Member

@Mousius Mousius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @areusch,

I had a quick look over this, I've mostly identified areas where it'd be good to add some additional tests (especially the TIR script bit) - though I've avoided areas which aren't as well setup for testing. Other than that, it looks fine move forwards given the other reviews caught everything else 😸

const char* get_c_struct_name() const final;

std::string get_element_c_struct_name() const {
CHECK(kind == MetadataKind::kMetadata)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add an ASSERT_THROWS test for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 146 to 147
auto a = VisitExpr(e);
return a;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either be explicit with the type or directly return the value from VisitExpr

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, leftover from logging. fixed!

Comment on lines +903 to +920
if data is None:
data = self.context.func_buffer_map[param].data

buffer_name: str = f"{postflattened.name}_preflatten"
if align != -1:
if isinstance(align, IntImm):
align = align.value
else:
assert isinstance(align, int), f"align: want int or IntImm, got {align!r}"

if offset_factor != 0:
if isinstance(offset_factor, IntImm):
offset_factor = offset_factor.value
else:
assert isinstance(
offset_factor, int
), f"offset_factor: want int or IntImm, got {offset_factor!r}"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add some unit tests for these cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


DiscoverArraysVisitor::DiscoverArraysVisitor(std::vector<DiscoveredArray>* queue) : queue_{queue} {}

std::string address_from_parts(const std::vector<std::string>& parts) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be AddressFromParts to match the coding conventions?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, should this be in the middle of the DiscoverArraysVisitor definitions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, fixed both

Comment on lines 53 to 79
void DiscoverArraysVisitor::Visit(const char* key, ObjectRef* value) {
address_parts_.push_back(key);
if (value->as<runtime::metadata::MetadataBaseNode>() != nullptr) {
auto metadata = Downcast<runtime::metadata::MetadataBase>(*value);
const runtime::metadata::MetadataArrayNode* arr =
value->as<runtime::metadata::MetadataArrayNode>();
if (arr != nullptr) {
for (unsigned int i = 0; i < arr->array.size(); i++) {
ObjectRef o = arr->array[i];
if (o.as<runtime::metadata::MetadataBaseNode>() != nullptr) {
std::stringstream ss;
ss << i;
address_parts_.push_back(ss.str());
runtime::metadata::MetadataBase metadata = Downcast<runtime::metadata::MetadataBase>(o);
ReflectionVTable::Global()->VisitAttrs(metadata.operator->(), this);
address_parts_.pop_back();
}
}

queue_->push_back(std::make_tuple(address_from_parts(address_parts_),
Downcast<runtime::metadata::MetadataArray>(metadata)));
} else {
ReflectionVTable::Global()->VisitAttrs(metadata.operator->(), this);
}
}
address_parts_.pop_back();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to add some testing for these visitors (DiscoverComplexTypesVisitor and DiscoverArraysVisitor) whilst we're creating this file afresh?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor Author

@areusch areusch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the round of comments @Mousius! would appreciate another look here

const char* get_c_struct_name() const final;

std::string get_element_c_struct_name() const {
CHECK(kind == MetadataKind::kMetadata)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 53 to 79
void DiscoverArraysVisitor::Visit(const char* key, ObjectRef* value) {
address_parts_.push_back(key);
if (value->as<runtime::metadata::MetadataBaseNode>() != nullptr) {
auto metadata = Downcast<runtime::metadata::MetadataBase>(*value);
const runtime::metadata::MetadataArrayNode* arr =
value->as<runtime::metadata::MetadataArrayNode>();
if (arr != nullptr) {
for (unsigned int i = 0; i < arr->array.size(); i++) {
ObjectRef o = arr->array[i];
if (o.as<runtime::metadata::MetadataBaseNode>() != nullptr) {
std::stringstream ss;
ss << i;
address_parts_.push_back(ss.str());
runtime::metadata::MetadataBase metadata = Downcast<runtime::metadata::MetadataBase>(o);
ReflectionVTable::Global()->VisitAttrs(metadata.operator->(), this);
address_parts_.pop_back();
}
}

queue_->push_back(std::make_tuple(address_from_parts(address_parts_),
Downcast<runtime::metadata::MetadataArray>(metadata)));
} else {
ReflectionVTable::Global()->VisitAttrs(metadata.operator->(), this);
}
}
address_parts_.pop_back();
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +903 to +920
if data is None:
data = self.context.func_buffer_map[param].data

buffer_name: str = f"{postflattened.name}_preflatten"
if align != -1:
if isinstance(align, IntImm):
align = align.value
else:
assert isinstance(align, int), f"align: want int or IntImm, got {align!r}"

if offset_factor != 0:
if isinstance(offset_factor, IntImm):
offset_factor = offset_factor.value
else:
assert isinstance(
offset_factor, int
), f"offset_factor: want int or IntImm, got {offset_factor!r}"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 146 to 147
auto a = VisitExpr(e);
return a;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, leftover from logging. fixed!


DiscoverArraysVisitor::DiscoverArraysVisitor(std::vector<DiscoveredArray>* queue) : queue_{queue} {}

std::string address_from_parts(const std::vector<std::string>& parts) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, fixed both

@areusch
Copy link
Contributor Author

areusch commented Apr 14, 2022

oops, it seems we ran into some kind of CI bug :(

i don't think PR will start testing til it's merged, unfortunately will need a review on #11007 before we can retest this one. Nevertheless, it's ready for another look.

@areusch
Copy link
Contributor Author

areusch commented Apr 14, 2022

also, did push this #11007 on top of this PR to exercise the fix, you can see it here: https://ci.tlcpack.ai/blue/organizations/jenkins/tvm/detail/areusch-test-jenkinsfile-merge-fix/3/pipeline/

Copy link
Member

@Mousius Mousius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM once CI passes 😸

@@ -481,6 +518,8 @@ void CodeGenLLVM::AddFunctionsOrdered(IterType begin, IterType end, ConvType pfu
return name_a < name_b;
});
for (auto& f : funcs) {
auto global_symbol = f->GetAttr<String>(tvm::attr::kGlobalSymbol);
LOG(INFO) << "Adding " << static_cast<std::string>(global_symbol.value());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this diff, I see codegen_llvm.h:522: Adding ... all over the place in the log https://ci.tlcpack.ai/blue/organizations/jenkins/tvm/detail/PR-10753/19/pipeline

Sorry I remember I added this one

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry can you also remove auto global_symbol = f->GetAttr<String>(tvm::attr::kGlobalSymbol); change since global_symbol is not used

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can address this in a follow-up

@areusch areusch merged commit 4178617 into apache:main Apr 19, 2022
Lucien0 pushed a commit to Lucien0/tvm that referenced this pull request Apr 19, 2022
* add get_c_struct_name() method to Metadata to distinguish struct type name in llvm

* add metadata serialization support to llvm codegen

* Organize MetadataQueuer into a separate file.

* Add DiscoverArraysVisitor to metadata_utils

* Fill DLTensor metadata in LegalizePackedCalls.

* Improve error message from Call asserts

* Pass non-String device_context down to codegen.

 * this is necessary to allow CodeGenCPU to emit calls that include resource_handle.

* Scope usage of lvalue refs in LowerTVMBuiltin to avoid corrupt memory.

* test fixes

* Also fill preflattened_buffer_map (TODO, maybe don't do this)

* Fix C codegen.

* Set USMP elem_offset to 0.

* Clarify calculation of byte_offset from elem_offset.

* fix tests

* Fix arm compile warning

* Fix hexagon test.

 * previously I believe we required interface_api == "c", but
   this really means to generate C API bindings, and we are generating
   "packed" bindings.
 * I think "c" was chosen here because the distinction between
   interface-api and use-unpacked-api is confusing. "c" interface-api
   means to generate an entrypoint API for microcontrollers that
   accepts bare data buffers. "packed" interface-api means to generate
   a TVMBackendPackedCFunc entrypoint. use-unpacked-api forms the same
   determination for the operator functions.
 * A further confusion here is that there are two ways to call
   "packed" operator functions: tir.tvm_builtin_call_packed and
   tir.tvm_builtin_call_cpacked. This distinction describes whether or
   not to late-bind calls via TVMBackendGetFuncFromEnv. Right now, AOT
   only ever requires call_cpacked because target_host == target, and
   for all suitable target_host, we expect a single DSO-exportable
   runtime.Module. When we move away from this by introducing
   heterogeneous target support to AOT, we can use this as a condition
   to help us choose between call_cpacked and call_packed (and
   possibly add a compile-time option to assert it is call_cpacked,
   for situations where we really don't want call_packed).

* Document T.preflattened_buffer

* Fix test_aot_legalize_packed_calls

* Address manupa comments

* Fix convert_pool_allocations_to_offsets test.

* lint

* Fix T.preflattened_buffer

* Add preflattened_buffer_map to TIRTextPrinter

* Fix tests

* Fix BYOC

* Fix invoking C device API.

* remove comments

* Address Mousius comments

* lint

* lint

* Fix GMock linking on new CMake

* address masahi comment

Co-authored-by: Masahiro Masuda <masahi129@gmail.com>
altanh pushed a commit to altanh/tvm that referenced this pull request Apr 28, 2022
* add get_c_struct_name() method to Metadata to distinguish struct type name in llvm

* add metadata serialization support to llvm codegen

* Organize MetadataQueuer into a separate file.

* Add DiscoverArraysVisitor to metadata_utils

* Fill DLTensor metadata in LegalizePackedCalls.

* Improve error message from Call asserts

* Pass non-String device_context down to codegen.

 * this is necessary to allow CodeGenCPU to emit calls that include resource_handle.

* Scope usage of lvalue refs in LowerTVMBuiltin to avoid corrupt memory.

* test fixes

* Also fill preflattened_buffer_map (TODO, maybe don't do this)

* Fix C codegen.

* Set USMP elem_offset to 0.

* Clarify calculation of byte_offset from elem_offset.

* fix tests

* Fix arm compile warning

* Fix hexagon test.

 * previously I believe we required interface_api == "c", but
   this really means to generate C API bindings, and we are generating
   "packed" bindings.
 * I think "c" was chosen here because the distinction between
   interface-api and use-unpacked-api is confusing. "c" interface-api
   means to generate an entrypoint API for microcontrollers that
   accepts bare data buffers. "packed" interface-api means to generate
   a TVMBackendPackedCFunc entrypoint. use-unpacked-api forms the same
   determination for the operator functions.
 * A further confusion here is that there are two ways to call
   "packed" operator functions: tir.tvm_builtin_call_packed and
   tir.tvm_builtin_call_cpacked. This distinction describes whether or
   not to late-bind calls via TVMBackendGetFuncFromEnv. Right now, AOT
   only ever requires call_cpacked because target_host == target, and
   for all suitable target_host, we expect a single DSO-exportable
   runtime.Module. When we move away from this by introducing
   heterogeneous target support to AOT, we can use this as a condition
   to help us choose between call_cpacked and call_packed (and
   possibly add a compile-time option to assert it is call_cpacked,
   for situations where we really don't want call_packed).

* Document T.preflattened_buffer

* Fix test_aot_legalize_packed_calls

* Address manupa comments

* Fix convert_pool_allocations_to_offsets test.

* lint

* Fix T.preflattened_buffer

* Add preflattened_buffer_map to TIRTextPrinter

* Fix tests

* Fix BYOC

* Fix invoking C device API.

* remove comments

* Address Mousius comments

* lint

* lint

* Fix GMock linking on new CMake

* address masahi comment

Co-authored-by: Masahiro Masuda <masahi129@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants