From e80f1a7d9de6650e7e4562784bdc406e127e3223 Mon Sep 17 00:00:00 2001 From: Masahiro Masuda Date: Fri, 20 Oct 2017 09:43:34 +0900 Subject: [PATCH 1/3] added math function support --- src/codegen/llvm/codegen_amdgpu.cc | 33 +++++++++++++++++++ src/codegen/llvm/intrin_rule_rocm.cc | 47 ++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/codegen/llvm/intrin_rule_rocm.cc diff --git a/src/codegen/llvm/codegen_amdgpu.cc b/src/codegen/llvm/codegen_amdgpu.cc index f3d9d811eec1..c6048c42787f 100644 --- a/src/codegen/llvm/codegen_amdgpu.cc +++ b/src/codegen/llvm/codegen_amdgpu.cc @@ -161,6 +161,39 @@ runtime::Module BuildAMDGPU(Array funcs, std::string target) { cg->AddFunction(f); } + //Hard coded. should move this over to python + const std::string rocdl_dir("/opt/rocm/lib/"); + const std::vector bitcode_files = { + "oclc_daz_opt_on.amdgcn.bc", + "ocml.amdgcn.bc", + "hc.amdgcn.bc", + "irif.amdgcn.bc", + "ockl.amdgcn.bc", + "oclc_correctly_rounded_sqrt_off.amdgcn.bc", + "oclc_correctly_rounded_sqrt_on.amdgcn.bc", + "oclc_daz_opt_off.amdgcn.bc", + "oclc_finite_only_off.amdgcn.bc", + "oclc_finite_only_on.amdgcn.bc", + "oclc_isa_version_803.amdgcn.bc", + "oclc_isa_version_900.amdgcn.bc", + "oclc_unsafe_math_off.amdgcn.bc", + "oclc_unsafe_math_on.amdgcn.bc", + }; + + for(auto& bitcode : bitcode_files){ + std::string path(rocdl_dir + bitcode); + llvm::SMDiagnostic err; + std::unique_ptr mlib = llvm::parseIRFile(path, err, *ctx); + if (mlib.get() == nullptr) { + std::string msg = err.getMessage(); + LOG(FATAL) << "Fail to load bitcode file " << path << "\n" + << "line " << err.getLineNo() << ":" << msg; + } + mlib->setTargetTriple(tm->getTargetTriple().str()); + mlib->setDataLayout(tm->createDataLayout()); + cg->AddLinkModule(std::move(mlib)); + } + std::unique_ptr module = cg->Finish(); llvm::SmallString<8> dataObj, data_ll, dataAsm; llvm::raw_svector_ostream destObj(dataObj), dest_ll(data_ll), destAsm(dataAsm); diff --git a/src/codegen/llvm/intrin_rule_rocm.cc b/src/codegen/llvm/intrin_rule_rocm.cc new file mode 100644 index 000000000000..2856705f6025 --- /dev/null +++ b/src/codegen/llvm/intrin_rule_rocm.cc @@ -0,0 +1,47 @@ +/*! + * Copyright (c) 2017 by Contributors + * \file intrin_rule_llvm.cc + */ +#ifdef TVM_LLVM_VERSION + +#include +#include +#include +#include "./intrin_rule_llvm.h" +#include + +namespace tvm { +namespace codegen { + +inline void DispatchExternOCML(const TVMArgs& args, TVMRetValue* rv) { + Expr e = args[0]; + using namespace ir; + const Call* call = e.as(); + CHECK(call != nullptr); + const std::string ocml_intrinsic_name = "__ocml_" + call->name + "_f" + std::to_string(call->type.bits()); + *rv = Call::make( + call->type, ocml_intrinsic_name, call->args, Call::PureExtern); +} + +namespace llvm { + +TVM_REGISTER_GLOBAL("tvm.intrin.rule.rocm.exp") +.set_body(DispatchExternOCML); + +TVM_REGISTER_GLOBAL("tvm.intrin.rule.rocm.fma") +.set_body(DispatchExternOCML); + +TVM_REGISTER_GLOBAL("tvm.intrin.rule.rocm.log") +.set_body(DispatchExternOCML); + +TVM_REGISTER_GLOBAL("tvm.intrin.rule.rocm.sqrt") +.set_body(DispatchExternOCML); + +TVM_REGISTER_GLOBAL("tvm.intrin.rule.rocm.pow") +.set_body(DispatchExternOCML); + +} // namespace llvm +} // namespace codegen +} // namespace tvm + +#endif // LLVM_VERSION From 7ab35b8d9132abde1e3fa3a3056057ce2c5e5c69 Mon Sep 17 00:00:00 2001 From: Masahiro Masuda Date: Fri, 20 Oct 2017 09:44:09 +0900 Subject: [PATCH 2/3] bug fix extern func call in llvm based codegen lint fix fix build bug fix extern func call in llvm based codegen --- src/codegen/llvm/codegen_amdgpu.cc | 8 ++++---- src/codegen/llvm/codegen_llvm.cc | 5 ++--- src/codegen/llvm/intrin_rule_rocm.cc | 9 +++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/codegen/llvm/codegen_amdgpu.cc b/src/codegen/llvm/codegen_amdgpu.cc index c6048c42787f..c866344726ef 100644 --- a/src/codegen/llvm/codegen_amdgpu.cc +++ b/src/codegen/llvm/codegen_amdgpu.cc @@ -161,7 +161,7 @@ runtime::Module BuildAMDGPU(Array funcs, std::string target) { cg->AddFunction(f); } - //Hard coded. should move this over to python + // Hard coded. should move this over to python const std::string rocdl_dir("/opt/rocm/lib/"); const std::vector bitcode_files = { "oclc_daz_opt_on.amdgcn.bc", @@ -175,12 +175,12 @@ runtime::Module BuildAMDGPU(Array funcs, std::string target) { "oclc_finite_only_off.amdgcn.bc", "oclc_finite_only_on.amdgcn.bc", "oclc_isa_version_803.amdgcn.bc", - "oclc_isa_version_900.amdgcn.bc", + "oclc_isa_version_900.amdgcn.bc", "oclc_unsafe_math_off.amdgcn.bc", "oclc_unsafe_math_on.amdgcn.bc", }; - for(auto& bitcode : bitcode_files){ + for (auto& bitcode : bitcode_files) { std::string path(rocdl_dir + bitcode); llvm::SMDiagnostic err; std::unique_ptr mlib = llvm::parseIRFile(path, err, *ctx); @@ -193,7 +193,7 @@ runtime::Module BuildAMDGPU(Array funcs, std::string target) { mlib->setDataLayout(tm->createDataLayout()); cg->AddLinkModule(std::move(mlib)); } - + std::unique_ptr module = cg->Finish(); llvm::SmallString<8> dataObj, data_ll, dataAsm; llvm::raw_svector_ostream destObj(dataObj), dest_ll(data_ll), destAsm(dataAsm); diff --git a/src/codegen/llvm/codegen_llvm.cc b/src/codegen/llvm/codegen_llvm.cc index cb2eae40eaeb..2654dee0f7e5 100644 --- a/src/codegen/llvm/codegen_llvm.cc +++ b/src/codegen/llvm/codegen_llvm.cc @@ -516,11 +516,10 @@ llvm::Value* CodeGenLLVM::GetVarValue(const Variable* v) const { } llvm::Value* CodeGenLLVM::CreateCallExtern(const Call* op) { - CHECK_GE(op->args.size(), 1U); std::vector arg_value; std::vector arg_type; - for (size_t i = 1; i < op->args.size(); ++i) { - arg_value.push_back(MakeValue(op->args[i + 1])); + for (size_t i = 0; i < op->args.size(); ++i) { + arg_value.push_back(MakeValue(op->args[i])); arg_type.push_back(arg_value.back()->getType()); } llvm::FunctionType* ftype = llvm::FunctionType::get( diff --git a/src/codegen/llvm/intrin_rule_rocm.cc b/src/codegen/llvm/intrin_rule_rocm.cc index 2856705f6025..5edd770fd6a4 100644 --- a/src/codegen/llvm/intrin_rule_rocm.cc +++ b/src/codegen/llvm/intrin_rule_rocm.cc @@ -4,10 +4,10 @@ */ #ifdef TVM_LLVM_VERSION +#include "./intrin_rule_llvm.h" #include #include #include -#include "./intrin_rule_llvm.h" #include namespace tvm { @@ -18,11 +18,12 @@ inline void DispatchExternOCML(const TVMArgs& args, TVMRetValue* rv) { using namespace ir; const Call* call = e.as(); CHECK(call != nullptr); - const std::string ocml_intrinsic_name = "__ocml_" + call->name + "_f" + std::to_string(call->type.bits()); + const std::string bit_width = std::to_string(call->type.bits()); + const std::string ocml_intrinsic_name = "__ocml_" + call->name + "_f" + bit_width; *rv = Call::make( call->type, ocml_intrinsic_name, call->args, Call::PureExtern); } - + namespace llvm { TVM_REGISTER_GLOBAL("tvm.intrin.rule.rocm.exp") @@ -33,7 +34,7 @@ TVM_REGISTER_GLOBAL("tvm.intrin.rule.rocm.fma") TVM_REGISTER_GLOBAL("tvm.intrin.rule.rocm.log") .set_body(DispatchExternOCML); - + TVM_REGISTER_GLOBAL("tvm.intrin.rule.rocm.sqrt") .set_body(DispatchExternOCML); From cdee602b7f547b29d31a72ae5fa6a22ad60edc98 Mon Sep 17 00:00:00 2001 From: Masahiro Masuda Date: Fri, 20 Oct 2017 11:32:14 +0900 Subject: [PATCH 3/3] moved rocm bitcodes detection to python --- python/tvm/contrib/rocm.py | 32 ++++++++++++++++++- src/codegen/llvm/codegen_amdgpu.cc | 47 ++++++++++------------------ src/codegen/llvm/intrin_rule_rocm.cc | 10 +++--- 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/python/tvm/contrib/rocm.py b/python/tvm/contrib/rocm.py index ee956c85e0ed..0f72a4694a82 100644 --- a/python/tvm/contrib/rocm.py +++ b/python/tvm/contrib/rocm.py @@ -1,7 +1,8 @@ """Utility for ROCm backend""" import subprocess +from os.path import join from . import util -from ..api import register_func +from ..api import register_func, convert def rocm_link(in_file, out_file): """Link relocatable ELF object to shared ELF object using lld @@ -49,3 +50,32 @@ def callback_rocm_link(obj_bin): rocm_link(tmp_obj, tmp_cobj) cobj_bin = bytearray(open(tmp_cobj, "rb").read()) return cobj_bin + +@register_func("tvm_callback_rocm_bitcode_path") +def callback_rocm_bitcode_path(rocdl_dir="/opt/rocm/lib/"): + """Utility function to find ROCm device library bitcodes + + Parameters + ---------- + rocdl_dir : str + The path to rocm library directory + The default value is the standard location + """ + # seems link order matters. + bitcode_files = [ + "oclc_daz_opt_on.amdgcn.bc", + "ocml.amdgcn.bc", + "hc.amdgcn.bc", + "irif.amdgcn.bc", + "ockl.amdgcn.bc", + "oclc_correctly_rounded_sqrt_off.amdgcn.bc", + "oclc_correctly_rounded_sqrt_on.amdgcn.bc", + "oclc_daz_opt_off.amdgcn.bc", + "oclc_finite_only_off.amdgcn.bc", + "oclc_finite_only_on.amdgcn.bc", + "oclc_isa_version_803.amdgcn.bc", + "oclc_isa_version_900.amdgcn.bc", + "oclc_unsafe_math_off.amdgcn.bc", + "oclc_unsafe_math_on.amdgcn.bc" + ] + return convert([join(rocdl_dir, bitcode) for bitcode in bitcode_files]) diff --git a/src/codegen/llvm/codegen_amdgpu.cc b/src/codegen/llvm/codegen_amdgpu.cc index c866344726ef..f49f2283210f 100644 --- a/src/codegen/llvm/codegen_amdgpu.cc +++ b/src/codegen/llvm/codegen_amdgpu.cc @@ -161,37 +161,22 @@ runtime::Module BuildAMDGPU(Array funcs, std::string target) { cg->AddFunction(f); } - // Hard coded. should move this over to python - const std::string rocdl_dir("/opt/rocm/lib/"); - const std::vector bitcode_files = { - "oclc_daz_opt_on.amdgcn.bc", - "ocml.amdgcn.bc", - "hc.amdgcn.bc", - "irif.amdgcn.bc", - "ockl.amdgcn.bc", - "oclc_correctly_rounded_sqrt_off.amdgcn.bc", - "oclc_correctly_rounded_sqrt_on.amdgcn.bc", - "oclc_daz_opt_off.amdgcn.bc", - "oclc_finite_only_off.amdgcn.bc", - "oclc_finite_only_on.amdgcn.bc", - "oclc_isa_version_803.amdgcn.bc", - "oclc_isa_version_900.amdgcn.bc", - "oclc_unsafe_math_off.amdgcn.bc", - "oclc_unsafe_math_on.amdgcn.bc", - }; - - for (auto& bitcode : bitcode_files) { - std::string path(rocdl_dir + bitcode); - llvm::SMDiagnostic err; - std::unique_ptr mlib = llvm::parseIRFile(path, err, *ctx); - if (mlib.get() == nullptr) { - std::string msg = err.getMessage(); - LOG(FATAL) << "Fail to load bitcode file " << path << "\n" - << "line " << err.getLineNo() << ":" << msg; - } - mlib->setTargetTriple(tm->getTargetTriple().str()); - mlib->setDataLayout(tm->createDataLayout()); - cg->AddLinkModule(std::move(mlib)); + const auto *find_rocm_bitcodes = + tvm::runtime::Registry::Get("tvm_callback_rocm_bitcode_path"); + Array bitcode_files = (*find_rocm_bitcodes)(); + + for (auto &bitcode : bitcode_files) { + std::string path = bitcode.as()->value; + llvm::SMDiagnostic err; + std::unique_ptr mlib = llvm::parseIRFile(path, err, *ctx); + if (mlib.get() == nullptr) { + std::string msg = err.getMessage(); + LOG(FATAL) << "Fail to load bitcode file " << path << "\n" + << "line " << err.getLineNo() << ":" << msg; + } + mlib->setTargetTriple(tm->getTargetTriple().str()); + mlib->setDataLayout(tm->createDataLayout()); + cg->AddLinkModule(std::move(mlib)); } std::unique_ptr module = cg->Finish(); diff --git a/src/codegen/llvm/intrin_rule_rocm.cc b/src/codegen/llvm/intrin_rule_rocm.cc index 5edd770fd6a4..e64a4fce4f27 100644 --- a/src/codegen/llvm/intrin_rule_rocm.cc +++ b/src/codegen/llvm/intrin_rule_rocm.cc @@ -8,7 +8,7 @@ #include #include #include -#include +#include namespace tvm { namespace codegen { @@ -18,10 +18,10 @@ inline void DispatchExternOCML(const TVMArgs& args, TVMRetValue* rv) { using namespace ir; const Call* call = e.as(); CHECK(call != nullptr); - const std::string bit_width = std::to_string(call->type.bits()); - const std::string ocml_intrinsic_name = "__ocml_" + call->name + "_f" + bit_width; - *rv = Call::make( - call->type, ocml_intrinsic_name, call->args, Call::PureExtern); + std::ostringstream intrinsic_name; + intrinsic_name << "__ocml_" << call->name << "_f" << call->type.bits(); + *rv = Call::make(call->type, intrinsic_name.str(), call->args, + Call::PureExtern); } namespace llvm {