From fd550c1b3bfc68425d06dd172bea27c6b1128115 Mon Sep 17 00:00:00 2001 From: HongyuJia Date: Tue, 15 Nov 2022 20:41:24 +0800 Subject: [PATCH] [Opt Error Message] Opt error message when selecting kernels under phi (#47970) * opt error message when selecting kernels under phi * fix for loop * polish error message * polish error message, split into 3 error condition * polish error message --- paddle/phi/common/backend.h | 35 ++++++++++ paddle/phi/common/data_type.h | 41 +++++++++++ paddle/phi/core/kernel_factory.cc | 111 +++++++++++++++++++++++++++--- 3 files changed, 179 insertions(+), 8 deletions(-) diff --git a/paddle/phi/common/backend.h b/paddle/phi/common/backend.h index 50fbd8e0724..2ddafdac520 100644 --- a/paddle/phi/common/backend.h +++ b/paddle/phi/common/backend.h @@ -182,6 +182,41 @@ inline Backend StringToBackend(const char* backend_cstr) { } } +inline std::string BackendToString(const Backend& backend) { + switch (backend) { + case Backend::UNDEFINED: + return "Undefined(ALL_BACKEND)"; + case Backend::CPU: + return "CPU"; + case Backend::GPU: + return "GPU"; + case Backend::XPU: + return "XPU"; + case Backend::NPU: + return "NPU"; + case Backend::MLU: + return "MLU"; + case Backend::ONEDNN: + return "ONEDNN"; + case Backend::GPUDNN: + return "GPUDNN"; + case Backend::KPS: + return "KPS"; + case Backend::IPU: + return "IPU"; + default: + size_t device_type_id_ = static_cast(backend) - + static_cast(Backend::NUM_BACKENDS); + std::string device_type = phi::GetGlobalDeviceType(device_type_id_); + if (!device_type.empty()) { + return device_type; + } else { + PD_THROW( + "Invalid enum backend type `", static_cast(backend), "`."); + } + } +} + } // namespace experimental } // namespace paddle diff --git a/paddle/phi/common/data_type.h b/paddle/phi/common/data_type.h index d1cd0f69f2b..339f240dae2 100644 --- a/paddle/phi/common/data_type.h +++ b/paddle/phi/common/data_type.h @@ -212,6 +212,47 @@ inline std::ostream& operator<<(std::ostream& os, DataType dtype) { return os; } +inline std::string DataTypeToString(const DataType& dtype) { + switch (dtype) { + case DataType::UNDEFINED: + return "Undefined(ALL_DTYPE)"; + case DataType::BOOL: + return "bool"; + case DataType::INT8: + return "int8"; + case DataType::UINT8: + return "uint8"; + case DataType::INT16: + return "int16"; + case DataType::UINT16: + return "uint16"; + case DataType::INT32: + return "int32"; + case DataType::UINT32: + return "uint32"; + case DataType::INT64: + return "int64"; + case DataType::UINT64: + return "uint64"; + case DataType::BFLOAT16: + return "bfloat16"; + case DataType::FLOAT16: + return "float16"; + case DataType::FLOAT32: + return "float32"; + case DataType::FLOAT64: + return "float64"; + case DataType::COMPLEX64: + return "complex64"; + case DataType::COMPLEX128: + return "complex128"; + case DataType::PSTRING: + return "pstring"; + default: + PD_THROW("Invalid enum data type `", static_cast(dtype), "`."); + } +} + } // namespace experimental } // namespace paddle diff --git a/paddle/phi/core/kernel_factory.cc b/paddle/phi/core/kernel_factory.cc index bbfe10591f0..a2b9f597175 100644 --- a/paddle/phi/core/kernel_factory.cc +++ b/paddle/phi/core/kernel_factory.cc @@ -28,6 +28,9 @@ namespace phi { const static Kernel empty_kernel; // NOLINT +std::string kernel_selection_error_message(const std::string& kernel_name, + const KernelKey& target_key); + uint32_t KernelKey::Hash::operator()(const KernelKey& key) const { uint32_t hash_value = 0; // |----31-20------|---19-12---|---11-8----|---7-0---| @@ -141,9 +144,10 @@ KernelResult KernelFactory::SelectKernelOrThrowError( kernel_iter == iter->second.end() && kernel_key.backend() == Backend::CPU, true, phi::errors::NotFound( - "The kernel with key %s of kernel `%s` is not registered.", + "The kernel with key %s of kernel `%s` is not registered. %s", kernel_key, - kernel_name)); + kernel_name, + kernel_selection_error_message(kernel_name, kernel_key))); #if defined(PADDLE_WITH_XPU) && !defined(PADDLE_WITH_XPU_KP) VLOG(6) << "fluid_op_name: " << TransToFluidOpName(kernel_name); @@ -168,10 +172,11 @@ KernelResult KernelFactory::SelectKernelOrThrowError( kernel_iter, iter->second.end(), phi::errors::NotFound( - "The kernel with key %s of kernel `%s` is not registered and" - " fail to fallback to CPU one.", + "The kernel with key %s of kernel `%s` is not registered and " + "fail to fallback to CPU one. %s", kernel_key, - kernel_name)); + kernel_name, + kernel_selection_error_message(kernel_name, kernel_key))); VLOG(3) << "missing " << kernel_key.backend() << " kernel: " << kernel_name << ", expected_kernel_key:" << kernel_key @@ -184,12 +189,13 @@ KernelResult KernelFactory::SelectKernelOrThrowError( kernel_iter, iter->second.end(), phi::errors::NotFound( - "The kernel with key %s of kernel `%s` is not registered and" - " the current value of FLAGS_enable_api_kernel_fallback(bool," + "The kernel with key %s of kernel `%s` is not registered. %s " + "The current value of FLAGS_enable_api_kernel_fallback(bool," " default true) is false. If you want to fallback this kernel" " to CPU one, please set the flag true before run again.", kernel_key, - kernel_name)); + kernel_name, + kernel_selection_error_message(kernel_name, kernel_key))); return {kernel_iter->second, false}; } @@ -344,4 +350,93 @@ std::ostream& operator<<(std::ostream& os, KernelFactory& kernel_factory) { return os; } +// return all kernel selection error message of specific kernel_name: +// 1. If target_key not supports target backend, output "Selected wrong Backend +// ..." +// 2. If target_key not supports target datatype, output "Selected wrong +// DataType ..." +// 3. `target_key` is still not supported, output all kernel keys of +// corresponding kernel_name: +// { +// (CPU, NCHW, [int8, int16, ...]); +// (GPU, Undefined(AnyLayout), [float32, float64, ...]); +// ... +// } +std::string kernel_selection_error_message(const std::string& kernel_name, + const KernelKey& target_key) { + PADDLE_ENFORCE_NE( + KernelFactory::Instance().kernels().find(kernel_name), + KernelFactory::Instance().kernels().end(), + phi::errors::NotFound("The kernel `%s` is not registered.", kernel_name)); + + // Init data structure + bool support_backend = false; + bool support_dtype = false; + std::unordered_map> all_kernel_key; + std::unordered_set backend_set; + std::unordered_set dtype_set; + + // Record all kernel information of kernel_name + for (auto iter : KernelFactory::Instance().kernels()[kernel_name]) { + KernelKey kernel_key = iter.first; + if (kernel_key.backend() == target_key.backend()) { + support_backend = true; + if (kernel_key.dtype() == target_key.dtype()) { + support_dtype = true; + } + dtype_set.insert( + paddle::experimental::DataTypeToString(kernel_key.dtype())); + } + backend_set.insert( + paddle::experimental::BackendToString(kernel_key.backend())); + all_kernel_key[paddle::experimental::BackendToString(kernel_key.backend()) + + ", " + phi::DataLayoutToString(kernel_key.layout())] + .push_back(paddle::experimental::DataTypeToString(kernel_key.dtype())); + } + // 1. If target_key not supports target backend, output "Selected wrong + // Backend ..." + if (!support_backend) { + std::string error_message = ""; + for (auto iter = backend_set.begin(); iter != backend_set.end(); ++iter) { + error_message += *iter; + error_message += ", "; + } + error_message = error_message.substr(0, error_message.length() - 2); + return "Selected wrong Backend `" + + paddle::experimental::BackendToString(target_key.backend()) + + "`. Paddle support following Backends: " + error_message + "."; + } + // 2. If target_key not supports target datatype, output "Selected wrong + // DataType ..." + if (!support_dtype) { + std::string error_message = ""; + for (auto iter = dtype_set.begin(); iter != dtype_set.end(); ++iter) { + error_message += *iter; + error_message += ", "; + } + error_message = error_message.substr(0, error_message.length() - 2); + return "Selected wrong DataType `" + + paddle::experimental::DataTypeToString(target_key.dtype()) + + "`. Paddle support following DataTypes: " + error_message + "."; + } + // 3. `target_key` is still not supported, output all kernel keys of + // corresponding kernel_name + std::string message = "Currently, paddle support following kernel keys of `" + + kernel_name + "`: { "; + for (auto iter = all_kernel_key.begin(); iter != all_kernel_key.end(); + ++iter) { + message += "(" + iter->first + ", ["; + std::vector& dtype_vec = iter->second; + for (std::size_t i = 0; i < dtype_vec.size(); ++i) { + message += dtype_vec[i]; + if (i + 1 != dtype_vec.size()) { + message += ", "; + } + } + message += "]); "; + } + message += "}."; + return message; +} + } // namespace phi -- GitLab