-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Port build_module.py to C++ #667
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
Conversation
Thanks for starting this. Since the C++ api headers is quite serious change, there are a few things that we need to fix in this PR. Here are some guidelines
|
include/tvm/compilation.h
Outdated
* \file compilation.h | ||
* \brief Functions for compiling ops. | ||
*/ | ||
#ifndef TVM_COMPILATION_H_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use the same name tvm/build_module.h
include/tvm/compilation.h
Outdated
|
||
namespace tvm { | ||
|
||
namespace compilation { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leave user facing API and data structure under root namespace.
include/tvm/compilation.h
Outdated
std::unordered_set<std::string> options; | ||
|
||
|
||
Target(std::string targetName, DLDeviceType deviceType, int max_num_threads, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a static function to construct from target string
include/tvm/compilation.h
Outdated
*/ | ||
struct Target { | ||
/*! \brief The name of the target device */ | ||
std::string targetName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use stl_case for variable name
include/tvm/compilation.h
Outdated
/*! \brief The type of the target device */ | ||
DLDeviceType deviceType; | ||
/*! \brief The maximum threads that a schedule should use for this device */ | ||
int max_num_threads; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set default value of the optional argument here
include/tvm/compilation.h
Outdated
|
||
|
||
/*! \brief Convenience function for getting attributes */ | ||
TVMValue GetAttr(NodeRef node, std::string attrName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function do not belong to here. Instead of using GetAttr, use
node.as<Expr>->type()
for the type
include/tvm/compilation.h
Outdated
|
||
/*! \brief Convenience function for getting handle attributes */ | ||
template<typename T> | ||
T GetAttrHandle(NodeRef node, std::string attrName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use the node.as<> instead of C API mechanism to get the children
include/tvm/compilation.h
Outdated
* \param config The build configuration. | ||
* \return The built Stmt. | ||
*/ | ||
EXPORT Stmt BuildStmt(Schedule sch, Array<Tensor> args, std::unordered_map<Tensor, Buffer> binds, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a private function that should belong to cc file
include/tvm/compilation.h
Outdated
* \param config The build configuration. | ||
* \return The lowered function. | ||
*/ | ||
EXPORT LoweredFunc Lower(Schedule sch, Array<Tensor> args, std::string name, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lower->lower as it is user facing, make API function consistent with python API. Pass by const reference when possible if the function do not move the content
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
returns Array
include/tvm/compilation.h
Outdated
* \param config The build configuration. | ||
* \return The built module. | ||
*/ | ||
EXPORT runtime::Module BuildModule(Array<LoweredFunc> funcs, const Target& target, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BuildModule->build
Ok hopefully that commit resolves the style issues - naming conventions should now be observed and the API surface in the header should be significantly reduced. There's a couple of things I'm not sure about though:
|
|
lower now returns array
Ok lower() now returns array, and there is a function Target::create which should be consistent with create() in target.py |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for being patient with this, here is another set of review comments
include/tvm/build_module.h
Outdated
|
||
/*! | ||
* \brief Container for target device information. | ||
* Use target_llvm, target_cuda etc functions instead of constructing directly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update comment to target::llvm
include/tvm/build_module.h
Outdated
#define TVM_BUILD_MODULE_H_ | ||
|
||
#include <string> | ||
#include "./tvm/c_dsl_api.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is no longer needed
EXPORT static Target create(const std::string& target_str); | ||
}; | ||
|
||
namespace target { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
document the namespace
include/tvm/build_module.h
Outdated
|
||
Target(const std::string& target_name, DLDeviceType device_type, int max_num_threads, | ||
int thread_warp_size, const std::unordered_set<std::string>& keys, | ||
const std::unordered_set<std::string>& options) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use member initializers for class members.
|
||
namespace tvm { | ||
|
||
/*! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
general style issue: Google C style requires 2-space indentation.
src/compilation/build_module.cc
Outdated
@@ -0,0 +1,317 @@ | |||
/*! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put the file under src/codegen/build_module.cc for now, since for now it is only stich up things and do not need a new module
src/compilation/build_module.cc
Outdated
* Compile executable modules. | ||
* \file build_module.cc | ||
*/ | ||
#include "./tvm/build_module.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use <tvm/build_module.h> as it is in include path, same for all other includes
src/compilation/build_module.cc
Outdated
} else if (x->func_type == kDeviceFunc) { | ||
fdevice.push_back(x); | ||
} else { | ||
CHECK(false) << "unknown function type " << x->func_type; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LOG(FATAL)
src/compilation/build_module.cc
Outdated
stmt = ir::StorageRewrite(stmt); | ||
stmt = ir::UnrollLoop(stmt, config.auto_unroll_max_step, config.auto_unroll_max_depth, | ||
config.auto_unroll_max_extent, config.unroll_explicit); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one blank line
src/compilation/build_module.cc
Outdated
|
||
|
||
// Phase 2 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to insert blank line here
No problem, I've fixed up the requested changes |
please fix the lint error, and add an unittest-case to tests/cpp |
src/codegen/build_module.cc
Outdated
} | ||
|
||
void GetBinds(const Array<Tensor>& args, const std::unordered_map<Tensor, Buffer>& binds, | ||
Map<Tensor, Buffer>* out_binds, Array<NodeRef>* out_arg_list, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
normally function argument are aligned to last bracket, reference other code.
OK I've added a unit test, but I'm not sure how to get the c++ tests to build with CUDA support? I've tried changing the Jenkinsfile but that didn't seem to help - is it using the Jenkinsfile from the commit or from the current master? Or is this not the right way to enable CUDA for C++ tests? |
for now let us write the testcase with only LLVM (cpu) as target |
I just want to say good work @alex-weaver this is great. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few last things to work on, which hopefully will fix the test
tests/cpp/build_module_test.cc
Outdated
|
||
TEST(BuildModule, Basic) { | ||
using namespace tvm; | ||
auto n = Variable::make(Int(32), "n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use Var("n")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can only use Var("n") if the constructor of Halide::VarExpr is marked EXPORT - is this OK? I was originally using Variable::make so as not to require exposing the implementation detail from the Halide namespace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, I think we can create a function var, which constructs Var and export that function, so it is consistent with python
src/codegen/build_module.cc
Outdated
} // namespace target | ||
|
||
bool LLVMEnabled() { | ||
const runtime::PackedFunc* pf = runtime::Registry::Get("codegen.llvm_target_enabled"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is not correctly implemented, refer to https://github.com/dmlc/tvm/blob/master/src/codegen/codegen.cc#L24
please fix my other comment about LLVMEnabled not being correctly implemented |
Changed implementation of LLVMEnabled()
Ok requested fixes are implemented, but it seems the issue with running the test is that the C++ test environment is not built with LLVM support. Is there a simple way to get this enabled for the C++ tests? |
thanks for being patience on improving the pr, this is now merged. |
@tqchen great :) btw would it also be helpful to port some of the python schedules in TOPI to C++ too? I can look at that soon if it would be useful. |
* Port build_module.py to C++ * Fix lint errors * Fix more lint errors * Fix more lint errors * Fix more lint errors * Fix build error * Implemented style fixes * Fix lint errors * Added function to construct target from string lower now returns array * Fix lint error * Implemented review changes - style & Target options -> std::vector * Fixed lint, argument alignment and added unit test * Changed test to target LLVM, fixed sign compare warnings * Reverted unit test to CUDA, changed Jenkinsfile to enable GPU for C++ tests * Slight change to Jenkinsfile * Changed build_module test from CUDA to LLVM * Added function var() to construct a Var instance. Changed implementation of LLVMEnabled() * Reverted Jenkinsfile
* Port build_module.py to C++ * Fix lint errors * Fix more lint errors * Fix more lint errors * Fix more lint errors * Fix build error * Implemented style fixes * Fix lint errors * Added function to construct target from string lower now returns array * Fix lint error * Implemented review changes - style & Target options -> std::vector * Fixed lint, argument alignment and added unit test * Changed test to target LLVM, fixed sign compare warnings * Reverted unit test to CUDA, changed Jenkinsfile to enable GPU for C++ tests * Slight change to Jenkinsfile * Changed build_module test from CUDA to LLVM * Added function var() to construct a Var instance. Changed implementation of LLVMEnabled() * Reverted Jenkinsfile
I've ported the functions from build_module.py over to C++ to allow compiling from C++; this required also implementing equivalents of Target and BuildConfig in C++. I've also added EXPORT directives to a minimal set of functions in schedule.h to allow implementing the Getting Started example. I would imagine in future most of schedule.h will need EXPORT directives to allow specifying more elaborate schedules from C++.
This implementation can be verified with the following port of the Getting Started example: