This is an automated email from the ASF dual-hosted git repository. tqchen pushed a commit to branch refactor-s2 in repository https://gitbox.apache.org/repos/asf/tvm.git
commit aa7b897f2929a40196c3b1aaf91e475a308e310c Author: tqchen <[email protected]> AuthorDate: Sun Apr 20 20:49:10 2025 -0400 Upgrade error reporting mechanism ABI to new FFI. --- src/runtime/library_module.cc | 2 +- src/runtime/thread_pool.cc | 16 ++++++---- src/target/llvm/codegen_cpu.cc | 38 ++++++++++++------------ src/target/llvm/codegen_cpu.h | 12 ++++---- tests/python/codegen/test_target_codegen_llvm.py | 19 ++++++++++++ 5 files changed, 55 insertions(+), 32 deletions(-) diff --git a/src/runtime/library_module.cc b/src/runtime/library_module.cc index a8a66b21cb..4d1520f7a2 100644 --- a/src/runtime/library_module.cc +++ b/src/runtime/library_module.cc @@ -83,7 +83,7 @@ void InitContextFunctions(std::function<void*(const char*)> fgetsymbol) { } // Initialize the functions TVM_INIT_CONTEXT_FUNC(TVMFFIFuncCall); - TVM_INIT_CONTEXT_FUNC(TVMAPISetLastError); + TVM_INIT_CONTEXT_FUNC(TVMFFISetLastErrorCStr); TVM_INIT_CONTEXT_FUNC(TVMBackendGetFuncFromEnv); TVM_INIT_CONTEXT_FUNC(TVMBackendAllocWorkspace); TVM_INIT_CONTEXT_FUNC(TVMBackendFreeWorkspace); diff --git a/src/runtime/thread_pool.cc b/src/runtime/thread_pool.cc index 74f87934e7..40bfdc9d11 100644 --- a/src/runtime/thread_pool.cc +++ b/src/runtime/thread_pool.cc @@ -103,18 +103,22 @@ class ParallelLauncher { if (!has_error_.load()) return 0; std::ostringstream os; for (size_t i = 0; i < par_errors_.size(); ++i) { - if (par_errors_[i].length() != 0) { - os << "Task " << i << " error: " << par_errors_[i] << '\n'; - par_errors_[i].clear(); + if (par_errors_[i] != nullptr) { + if (std::optional<tvm::ffi::Error> error = par_errors_[i].as<tvm::ffi::Error>()) { + os << "Task " << i << " error: " << (*error).what(); + } else { + os << "Task " << i << " RuntimeError"; + } + par_errors_[i] = nullptr; } } - TVMAPISetLastError(os.str().c_str()); + TVMFFISetLastErrorCStr("RuntimeError", os.str().c_str()); return -1; } // Signal that one job has finished. void SignalJobError(int task_id) { num_pending_.fetch_sub(1); - par_errors_[task_id] = TVMGetLastError(); + TVMFFIMoveFromLastError(reinterpret_cast<TVMFFIAny*>(&par_errors_[task_id])); has_error_.store(true); } // Signal that one job has finished. @@ -139,7 +143,7 @@ class ParallelLauncher { // The counter page. std::atomic<int32_t>* sync_counter_{nullptr}; // The error message - std::vector<std::string> par_errors_; + std::vector<Any> par_errors_; }; /*! \brief Lock-free single-producer-single-consumer queue for each thread */ diff --git a/src/target/llvm/codegen_cpu.cc b/src/target/llvm/codegen_cpu.cc index 83b07b14e9..b9941ff904 100644 --- a/src/target/llvm/codegen_cpu.cc +++ b/src/target/llvm/codegen_cpu.cc @@ -120,15 +120,15 @@ void CodeGenCPU::Init(const std::string& module_name, LLVMTarget* llvm_target, // int TVMFFIFuncCall(TVMFunctionHandle func, TVMFFIAny* args, int32_t num_args, // TVMFFIAny* result); ftype_tvm_ffi_func_call_ = ftype_tvm_ffi_c_func_; + // Defined in include/tvm/ffi/c_api.h: + // void TVMFFISetLastErrorCStr(const char *kind, const char* msg); + ftype_tvm_ffi_set_last_error_c_str_ = llvm::FunctionType::get( + t_void_, {llvmGetPointerTo(t_char_, 0), llvmGetPointerTo(t_char_, 0)}, false); // Defined in include/tvm/runtime/c_backend_api.h: // int TVMBackendGetFuncFromEnv(void* mod_node, const char* func_name, TVMFunctionHandle* out); ftype_tvm_get_func_from_env_ = llvm::FunctionType::get( t_int_, {t_void_p_, llvmGetPointerTo(t_char_, 0), llvmGetPointerTo(t_tvm_func_handle_, 0)}, false); - // Defined in include/tvm/runtime/c_runtime_api.h: - // void TVMAPISetLastError(const char* msg); - ftype_tvm_api_set_last_error_ = - llvm::FunctionType::get(t_void_, {llvmGetPointerTo(t_char_, 0)}, false); // Defined in include/tvm/runtime/c_backend_api.h: // int TVMBackendParallelLaunch(FTVMParallelLambda flambda, void* cdata, int num_task); ftype_tvm_parallel_launch_ = llvm::FunctionType::get( @@ -157,9 +157,9 @@ void CodeGenCPU::Init(const std::string& module_name, LLVMTarget* llvm_target, if (dynamic_lookup || system_lib_prefix_.defined()) { f_tvm_ffi_func_call_ = llvm::Function::Create( ftype_tvm_ffi_func_call_, llvm::Function::ExternalLinkage, "TVMFFIFuncCall", module_.get()); - f_tvm_api_set_last_error_ = - llvm::Function::Create(ftype_tvm_api_set_last_error_, llvm::Function::ExternalLinkage, - "TVMAPISetLastError", module_.get()); + f_tvm_ffi_set_last_error_c_str_ = + llvm::Function::Create(ftype_tvm_ffi_set_last_error_c_str_, llvm::Function::ExternalLinkage, + "TVMFFISetLastErrorCStr", module_.get()); f_tvm_get_func_from_env_ = llvm::Function::Create(ftype_tvm_get_func_from_env_, llvm::Function::ExternalLinkage, "TVMBackendGetFuncFromEnv", module_.get()); @@ -443,12 +443,12 @@ void CodeGenCPU::InitGlobalContext(bool dynamic_lookup) { export_system_symbols_.emplace_back(std::make_pair(ctx_symbol, gv_mod_ctx_)); } else { if (!dynamic_lookup) { - gv_tvm_func_call_ = + gv_tvm_ffi_func_call_ = InitContextPtr(llvmGetPointerTo(ftype_tvm_ffi_func_call_, 0), "__TVMFFIFuncCall"); gv_tvm_get_func_from_env_ = InitContextPtr(llvmGetPointerTo(ftype_tvm_get_func_from_env_, 0), "__TVMBackendGetFuncFromEnv"); - gv_tvm_api_set_last_error_ = InitContextPtr( - llvmGetPointerTo(ftype_tvm_api_set_last_error_, 0), "__TVMAPISetLastError"); + gv_tvm_ffi_set_last_error_c_str_ = InitContextPtr( + llvmGetPointerTo(ftype_tvm_ffi_set_last_error_c_str_, 0), "__TVMFFISetLastErrorCStr"); gv_tvm_parallel_launch_ = InitContextPtr(llvmGetPointerTo(ftype_tvm_parallel_launch_, 0), "__TVMBackendParallelLaunch"); gv_tvm_parallel_barrier_ = InitContextPtr(llvmGetPointerTo(ftype_tvm_parallel_barrier_, 0), @@ -833,7 +833,7 @@ CodeGenCPU::PackedCall CodeGenCPU::MakeCallPackedLowered(const Array<PrimExpr>& if (use_env_lookup) { callee_ftype = ftype_tvm_ffi_func_call_; - callee_value = RuntimeTVMFuncCall(); + callee_value = RuntimeTVMFFIFuncCall(); call_args.push_back(GetPackedFuncHandle(func_name)); call_args.insert(call_args.end(), {packed_args, ConstInt32(nargs), result}); } else { @@ -927,18 +927,18 @@ llvm::Value* CodeGenCPU::CreateCallTracePacked(const CallNode* op) { return phi_rvalue; } -llvm::Value* CodeGenCPU::RuntimeTVMFuncCall() { +llvm::Value* CodeGenCPU::RuntimeTVMFFIFuncCall() { if (f_tvm_ffi_func_call_ != nullptr) return f_tvm_ffi_func_call_; - return GetContextPtr(gv_tvm_func_call_); + return GetContextPtr(gv_tvm_ffi_func_call_); } llvm::Value* CodeGenCPU::RuntimeTVMGetFuncFromEnv() { if (f_tvm_get_func_from_env_ != nullptr) return f_tvm_get_func_from_env_; return GetContextPtr(gv_tvm_get_func_from_env_); } -llvm::Value* CodeGenCPU::RuntimeTVMAPISetLastError() { - if (f_tvm_api_set_last_error_ != nullptr) return f_tvm_api_set_last_error_; - return GetContextPtr(gv_tvm_api_set_last_error_); +llvm::Value* CodeGenCPU::RuntimeTVMFFISetLastErrorCStr() { + if (f_tvm_ffi_set_last_error_c_str_ != nullptr) return f_tvm_ffi_set_last_error_c_str_; + return GetContextPtr(gv_tvm_ffi_set_last_error_c_str_); } llvm::Value* CodeGenCPU::RuntimeTVMParallelLaunch() { if (f_tvm_parallel_launch_ != nullptr) return f_tvm_parallel_launch_; @@ -1063,11 +1063,11 @@ void CodeGenCPU::VisitStmt_(const AssertStmtNode* op) { #if TVM_LLVM_VERSION >= 90 auto err_callee = - llvm::FunctionCallee(ftype_tvm_api_set_last_error_, RuntimeTVMAPISetLastError()); + llvm::FunctionCallee(ftype_tvm_ffi_set_last_error_c_str_, RuntimeTVMFFISetLastErrorCStr()); #else - auto err_callee = RuntimeTVMAPISetLastError(); + auto err_callee = RuntimeTVMFFISetLastErrorCStr(); #endif - builder_->CreateCall(err_callee, {msg}); + builder_->CreateCall(err_callee, {GetConstString("RuntimeError"), msg}); builder_->CreateRet(ConstInt32(-1)); // otherwise set it to be new end. builder_->SetInsertPoint(end_block); diff --git a/src/target/llvm/codegen_cpu.h b/src/target/llvm/codegen_cpu.h index 03a0ad966e..760ce65b4b 100644 --- a/src/target/llvm/codegen_cpu.h +++ b/src/target/llvm/codegen_cpu.h @@ -93,7 +93,7 @@ class CodeGenCPU : public CodeGenLLVM { llvm::FunctionType* ftype_tvm_parallel_lambda_{nullptr}; llvm::FunctionType* ftype_tvm_ffi_func_call_{nullptr}; llvm::FunctionType* ftype_tvm_get_func_from_env_{nullptr}; - llvm::FunctionType* ftype_tvm_api_set_last_error_{nullptr}; + llvm::FunctionType* ftype_tvm_ffi_set_last_error_c_str_{nullptr}; llvm::FunctionType* ftype_tvm_parallel_launch_{nullptr}; llvm::FunctionType* ftype_tvm_parallel_barrier_{nullptr}; llvm::FunctionType* ftype_tvm_register_system_symbol_{nullptr}; @@ -115,9 +115,9 @@ class CodeGenCPU : public CodeGenLLVM { void InitGlobalContext(bool dynamic_lookup); llvm::GlobalVariable* InitContextPtr(llvm::Type* type, std::string name); llvm::Value* GetContextPtr(llvm::GlobalVariable* gv); - llvm::Value* RuntimeTVMFuncCall(); + llvm::Value* RuntimeTVMFFIFuncCall(); llvm::Value* RuntimeTVMGetFuncFromEnv(); - llvm::Value* RuntimeTVMAPISetLastError(); + llvm::Value* RuntimeTVMFFISetLastErrorCStr(); llvm::Value* RuntimeTVMParallelLaunch(); llvm::Value* RuntimeTVMParallelBarrier(); llvm::Value* CreateStaticHandle(); @@ -156,16 +156,16 @@ class CodeGenCPU : public CodeGenLLVM { // Context for injection lookup llvm::GlobalVariable* gv_mod_ctx_{nullptr}; - llvm::GlobalVariable* gv_tvm_func_call_{nullptr}; + llvm::GlobalVariable* gv_tvm_ffi_func_call_{nullptr}; llvm::GlobalVariable* gv_tvm_get_func_from_env_{nullptr}; - llvm::GlobalVariable* gv_tvm_api_set_last_error_{nullptr}; + llvm::GlobalVariable* gv_tvm_ffi_set_last_error_c_str_{nullptr}; llvm::GlobalVariable* gv_tvm_parallel_launch_{nullptr}; llvm::GlobalVariable* gv_tvm_parallel_barrier_{nullptr}; std::unordered_map<String, llvm::GlobalVariable*> gv_func_map_; // context for direct dynamic lookup llvm::Function* f_tvm_ffi_func_call_{nullptr}; llvm::Function* f_tvm_get_func_from_env_{nullptr}; - llvm::Function* f_tvm_api_set_last_error_{nullptr}; + llvm::Function* f_tvm_ffi_set_last_error_c_str_{nullptr}; llvm::Function* f_tvm_parallel_launch_{nullptr}; llvm::Function* f_tvm_parallel_barrier_{nullptr}; llvm::Function* f_tvm_register_system_symbol_{nullptr}; diff --git a/tests/python/codegen/test_target_codegen_llvm.py b/tests/python/codegen/test_target_codegen_llvm.py index 090bced6cc..b6d501b86b 100644 --- a/tests/python/codegen/test_target_codegen_llvm.py +++ b/tests/python/codegen/test_target_codegen_llvm.py @@ -1176,5 +1176,24 @@ def test_bool_return_value(): assert not built(15) +def test_invalid_arguments(): + """Integers may be passed to functions accepting bool""" + + @T.prim_func + def func(a0: T.bool, a1: T.Buffer([10], "float32")) -> T.int32: + T.func_attr({"target": T.target("llvm")}) + return 0 + + built = tvm.compile(func) + with pytest.raises(RuntimeError): + built(1, 1) + + with pytest.raises(RuntimeError): + built(1, tvm.nd.empty([10], "int32")) + + with pytest.raises(RuntimeError): + built(False, tvm.nd.empty([11], "float32")) + + if __name__ == "__main__": tvm.testing.main()
