-
Notifications
You must be signed in to change notification settings - Fork 170
[onert] Dedicated exception for invalid data type #16229
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
base: master
Are you sure you want to change the base?
Conversation
| else | ||
| { | ||
| throw std::runtime_error{"Quantize: Unsupported data type"}; | ||
| throw UnsupportedDataTypeException{"Quantize", _input->data_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.
In general looks good to me but maybe we should consider some better way of handling cases where both input and output type can be unsupported. Probably UnsupportedDataTypeException can be easy extended for 1 input, 1 output and I'm thinking on more generic version.
Maybe UnsupportedDataTypeException(const std::string op_name, const std::vector<ITensor>& inputs, const std::vector<ITensor>& outpus) with message "Operation X with combination inputs data types: ... and output data types: ... is not supported" but it's also not perfect and maybe shouldn't use such details of backend.
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've been trying to make the exception less generic and hierarchical, but then there is a problem of which exception is the base one. Unsupported data type can be on behalf of an operation or in some other part of the code. Then we have other operation-originated exceptions... Data types are for input, input on the left side, input on the right side, output, and maybe some other cases. So, instead of created dedicated exception I chose more generic approach. However, there is a dedicated constructor for the operation originated exception, so the name of the operation is available in the error message (and potentially might be available in the exception itself).
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 the problems.
It's a bigger task but it will be nice that each operation has some print capabilities (maybe via visitor design pattern to avoid changes in many places?) with basic info like operation name, inputs/outputs shape, data type. It can be used in error messages. But as for now it's not must have.
| auto input = getGGMLTensor(_input); | ||
| auto indices = getGGMLTensor(_indices); | ||
| auto output = getGGMLTensor(_output); | ||
| auto input = getGGMLTensor("FullyConnected", _input); |
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.
Perhaps I'm missing something but why is this used with FullyConnected op name?
| { | ||
|
|
||
| struct ggml_tensor getGGMLTensor(const IPortableTensor *tensor); | ||
| struct ggml_tensor getGGMLTensor(std::string op, const IPortableTensor *tensor); |
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.
Since this is GGML (3rdparty) related, I'd suggest to catch the existing exception from getGGMLTensor and rethrow the specific UnsupportedDataTypeException at the call site. This will lower the amount of changes.
| { | ||
|
|
||
| class OnertException : public std::exception | ||
| class Exception : public std::exception |
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'm not sure that the change of the existing name is required here. What was the reason behind it?
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 wanted to remove redundancy in naming. Errors are in the onert namespace, so when using fully qualified name you have onert::OnertException, then I would have to follow the same pattern with other exceptions, i.e.: onert::OnertUnsupportedDataTypeException. So, in order to shorten exception names and remove redundancy I've removed the Onert prefix (there is no std::std_exception, but std::exception). If you prefer the old behavior I will restore that.
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 also like to remove the redundancy. However, it is beyond this PR. Could you please don't change this in this PR? We may get other's opinion in separate PR.
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.
Submitted as a separate PR: #16257
| throw std::runtime_error{"Unsupported type size"}; | ||
| case DataType::QUANT_GGML_Q4_0: | ||
| case DataType::QUANT_GGML_Q8_0: | ||
| // GGML block quantize type data size is not supported |
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.
If the GGML data types are not supported I think they should fall into the default case as before. This change just lists them explicitly but all the previous cases return the size for the supported data types, while this one breaks. Plus the default is now gone which is a potential problem in static analysis tools. I'm not sure that I agree with this approach.
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.
On contrary, using default in most cases is problematic because static analysis can not verify that some keys are missing. IMHO, the best practice when dealing with enums is to list all keys explicitly (if possible) and handle "default" case outside of the switch. Then, in case when new enum value is added, compiler will report that not all values are handled - you don't have to run the code to see that some functionality is not implemented.
This commit introduces dedicated exception for reporting unsupported or invalid data type. ONE-DCO-1.0-Signed-off-by: Arkadiusz Bokowy <[email protected]>
This commit introduces dedicated exception for reporting unsupported or invalid data type.
In case of invalid input data for the example
nnpackage/examples/v1.3.0/two_tflites/mv1.0.tflitemodel the output looks like:and the
nnfw_session::run()returnsNNFW_STATUS_UNSUPPORTED_DATA_TYPEstatus code.This PR is small part of issues diagnosed here: #16102 (comment)
ONE-DCO-1.0-Signed-off-by: Arkadiusz Bokowy [email protected]