-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Snippets: precision propagation #14996
Snippets: precision propagation #14996
Conversation
9f9b6f6
to
d86c1d0
Compare
2610461
to
ccba0c5
Compare
f017c43
to
cb23339
Compare
cb23339
to
9ba9431
Compare
6ccf2ba
to
165aff8
Compare
9aae89f
to
de622d9
Compare
@@ -0,0 +1,153 @@ | |||
// Copyright (C) 2022 Intel Corporation |
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.
Minor
// Copyright (C) 2022 Intel Corporation | |
// Copyright (C) 2023 Intel Corporation |
src/plugins/intel_cpu/src/snippets_transformations/remove_converts.hpp
Outdated
Show resolved
Hide resolved
src/plugins/intel_cpu/src/snippets_transformations/remove_converts.cpp
Outdated
Show resolved
Hide resolved
de622d9
to
a12dc7c
Compare
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.
Unfortunately the tests are still not fixed despite numerous offline discussions. Please align tests in this PR with the rest of the snippets tests infrastructure. It's Ok if you suggest to refactor the infrastructure, but ,as was discussed with @dmitry-gorokhov, it should be done out of the scope of this PR.
// returns supported precisions | ||
// precisions are ordered, the first bigger bitnes precision with the same type will be selected | ||
// empty collection means an emitter supports any input precisions | ||
static std::set<std::vector<element::Type>> get_supported_precisions(const std::shared_ptr<ngraph::Node>& node = nullptr); |
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.
Example of documented methods here
} | ||
default: { | ||
value = dnnl::impl::cpu::x64::float2int(ov::as_type_ptr<ov::op::v0::Constant>(n)->cast_vector<float>()[0]); | ||
break; |
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.
Sorry, I didn't get your point, please elaborate
namespace test { | ||
namespace snippets { | ||
|
||
class PrecisionPropagationFunction { |
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.
Please remove this class, since we don't need it anymore
|
||
class PrecisionPropagationFunction { | ||
public: | ||
template<typename T> |
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 template is instantiated only once, please convert it to an ordinary method.
const auto branch1 = make_branch(precision1, inputShape1, 1, convertion_before_op1.first); | ||
const auto branch2 = make_branch(precision2, inputShape2, 2, convertion_before_op1.second); | ||
|
||
std::shared_ptr<Node> parent = std::make_shared<T>(branch1.second, branch2.second); |
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.
Minor: If you want to create different nodes in the future, you can just pass them as an argument. This way we can avoid duplication of the whole function body. We don't need this code duplication, since the function will be called just a couple times.
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 you want to create different nodes in the future, you can just pass them as an argument.'
Custom operation type is a part of function parameterization approach which is defined outside of function. With template it's more flexible.
'This way we can avoid duplication of the whole function body. We don't need this code duplication, since the function will be called just a couple times.'
In this case we mix function parameterization and function implementation, add if
/else
in function implementation. Template instantiation is not 'code dublication'.
Note, please, SnippetsFunctionBase
and many of its useless empty inherited types with intermediate members increase binary size more then just static methods.
}; | ||
|
||
template<typename T> | ||
class EmpyInfrastructureSupportStubForPrecisionPropagationFunction : public SnippetsFunctionBase { |
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.
Please provide a name that describes the function's topology, for example PrecisionPropagationAddFunction
would do. You have a plenty good naming examples in the directory: ConvMulActivationFunction, TwoInputsAndOutputsFunction, BroadcastAddFunction
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.
It's still template function, there is no Add
operation in implementation. Will be renamed if template is removed.
actual.convertion_before_op2_2); | ||
} | ||
|
||
std::shared_ptr<ov::Model> initReference() const override { |
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.
Why would you override different methods to yield the same function. Please, take a look at other ngraph snippets functions implementations here, they all override only initOriginal()
since it's enough for functional tests
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.
Because it's not plugin test when we need to infer one function only. You are reviewing functional tests with two function instances: original and reference which are compared after original function transformation.
namespace test { | ||
namespace snippets { | ||
|
||
class PrecisionPropagationConvertionFunction { |
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.
Couldn't find the answer below. Please align PrecisionPropagationFunction
and PrecisionPropagationConvertionFunction
with the rest of the snippets ngraph functions
assert(std::all_of( | ||
supported_precisions.begin(), | ||
supported_precisions.end(), | ||
[&input_precisions](const std::vector<element::Type>& precisions) { | ||
return precisions.size() == input_precisions.size(); | ||
}) && "input precisions count is not equal for supported precisions"); |
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.
Ok, after an offline discussion I get your point regarding this particular assert and the one on L79. Let's leave them.
Didn't understand your argument regarding oneDNN or ONNX. It this a PR to a oneDNN repo?
{{element::f32, element::f32}}, | ||
{{element::f32, element::f32}} | ||
}, | ||
{} |
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.
Forgot to add the last comment:
You pass actual
and expected
to every test case, however expected
is uniquely defined by actual
, right?
It looks like it's enough to pass only actual
and then produce both initial and reference functions. This logic could be implemented inside get_reference()
method, for example. What do you think?
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.
'You pass actual and expected to every test case, however expected is uniquely defined by actual, right?' - off course.
Nothing is easier to get model instance during development, debugging, extending and feature understanding, then the single static method which is parameterized with actual
or expected
data directly from a test case. For a new test addition, you just need to declare a new test case in the test_cases
collection. No writing source code.
Let me explain:
-
To get model instance for the test we need specify some arguments for
PrecisionPropagationFunction::get
static method. To get two different model instances (original
&expected
) we should specify two sets of arguments (both are defined in the same test case) for the samePrecisionPropagationFunction::get
static method. It's the simplest way to create two model instances (original
&expected
) for the test. Isn't it? -
You suggested to keep the same
PrecisionPropagationFunction::get
method signature, the same function implementation but removeexpected
values from its test case and hardcode them for/inPrecisionPropagationFunction::get
call? I can not agree with that, I didn't see any advantages of that.
Can you sugest anything more simplier for test understanding, debugging and extension in the future? May be we still leave one PrecisionPropagationFunction::get
static method aproach ([template] customization will be removed) as is? : )))
cffba04
to
1685d1a
Compare
17b1678
to
6ca4c3c
Compare
6ca4c3c
to
1fdf05d
Compare
// general conditions: any new added precision will support | ||
return | ||
(actual.is_real() == required.is_real()) && | ||
(actual.bitwidth() >= required.bitwidth()); |
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.
Maybe I missed smt but this condition will return true for: actual=bf16 and/or required fp16. Seems like this is invalid case for fusing.
Details:
Tickets: