!18938 infer optimize:codex + testcases

Merge pull request !18938 from lanzhineng/infer_optv5
This commit is contained in:
i-robot 2021-07-06 01:19:13 +00:00 committed by Gitee
commit b26dc0f162
5 changed files with 136 additions and 19 deletions

View File

@ -26,11 +26,14 @@ namespace mindspore {
namespace abstract {
HealthPointMgr HealthPointMgr::instance_;
void HealthPointMgr::Clear() { point_ = 1; }
void HealthPointMgr::HandleException() {
std::lock_guard<std::recursive_mutex> lock(lock_);
for (auto &item : asyncAbstractList_) {
item->SetRunable();
}
asyncAbstractList_.clear();
}
void HealthPointMgr::SetNextRunable() {
std::lock_guard<std::recursive_mutex> lock(lock_);
@ -43,8 +46,7 @@ void HealthPointMgr::SetNextRunable() {
[](const auto &item) { return item->HasResult(); });
if (it == asyncAbstractList_.end()) {
// Enter endless loop if there is not ready result.
MS_LOG(EXCEPTION) << "Enter endless loop. Please check the code. point = "
<< " point:" << HealthPointMgr::GetInstance().point()
MS_LOG(EXCEPTION) << "Enter endless loop. Please check the code. point = " << HealthPointMgr::GetInstance().point()
<< " Called times : " << asyncAbstractList_.front()->count();
}
asyncAbstractList_.insert(asyncAbstractList_.end(), asyncAbstractList_.begin(), it);
@ -110,13 +112,14 @@ AbstractBasePtr AnalysisResultCacheMgr::GetSwitchValue(const AnfNodeConfigPtr &c
// Conf has been visited and set value.
if (async_eval_result != nullptr) {
// Add to schedule
HealthPointMgr::GetInstance().PushBack(async_eval_result);
HealthPointMgr::GetInstance().Add2Schedule(async_eval_result);
// Maybe blocked for waiting. AsyncAbstract maybe null, if time out.
auto result = async_eval_result->GetResult();
if (result == nullptr) {
result = std::make_shared<AbstractTimeOut>();
MS_LOG(ERROR) << "AsyncAbstract for NodeConfig " << conf->node()->ToString() << " is nullptr, maybe timeout.";
MS_LOG(ERROR) << "detail:" << conf->ToString();
MS_LOG(ERROR) << "AsyncAbstract of NodeConfig " << conf->node()->ToString()
<< " is nullptr. There is something wrong.";
StaticAnalysisException::Instance().CheckException();
}
return result;
}

View File

@ -42,7 +42,9 @@ class HealthPointMgr {
HealthPointMgr(const HealthPointMgr &) = delete;
HealthPointMgr &operator=(const HealthPointMgr &) = delete;
static HealthPointMgr &GetInstance() { return instance_; }
void Clear();
void SetNextRunable();
void HandleException();
void CheckPoint() {
MS_LOG(DEBUG) << "The Health Point is " << point_;
@ -59,8 +61,6 @@ class HealthPointMgr {
CheckPoint();
}
void HandleException();
void AddPoint() {
std::lock_guard<std::recursive_mutex> lock(lock_);
++point_;
@ -68,9 +68,9 @@ class HealthPointMgr {
int point() { return point_; }
void PushBack(const AsyncAbstractPtr &base) {
void Add2Schedule(const AsyncAbstractPtr &asyncAbastract) {
std::lock_guard<std::recursive_mutex> lock(lock_);
asyncAbstractList_.push_back(base);
asyncAbstractList_.push_back(asyncAbastract);
}
private:
@ -198,9 +198,9 @@ class AsyncAbstract : public std::enable_shared_from_this<AsyncAbstract> {
hasDropPoint = true;
}
MS_LOG(DEBUG) << this << " ranable: " << runable_ << " result: " << (result_ ? result_.get() : 0);
MS_LOG(DEBUG) << this << " runable: " << runable_ << " result: " << (result_ ? result_.get() : 0);
condition_var_.wait(lock, [this] { return runable_; });
MS_LOG(DEBUG) << this << " continue ranable: " << runable_ << " result: " << (result_ ? result_.get() : 0);
MS_LOG(DEBUG) << this << " continue runable: " << runable_ << " result: " << (result_ ? result_.get() : 0);
StaticAnalysisException::Instance().CheckException();
runable_ = false;
if (result_ != nullptr) {
@ -211,14 +211,14 @@ class AsyncAbstract : public std::enable_shared_from_this<AsyncAbstract> {
return result_;
}
// Push to list
HealthPointMgr::GetInstance().PushBack(shared_from_this());
HealthPointMgr::GetInstance().Add2Schedule(shared_from_this());
if (hasDropPoint) {
HealthPointMgr::GetInstance().AddPoint();
}
// Notify the next asyncAbastract to run.
HealthPointMgr::GetInstance().SetNextRunable();
MS_LOG(DEBUG) << this << " SetNextRunable "
<< " ranable: " << runable_ << " result: " << (result_ ? result_.get() : 0)
<< " runable: " << runable_ << " result: " << (result_ ? result_.get() : 0)
<< " point:" << HealthPointMgr::GetInstance().point();
}
return nullptr;

View File

@ -119,6 +119,7 @@ bool AnfNodeConfigEqual::operator()(const AnfNodeConfigPtr lhs, const AnfNodeCon
AnalysisResult AnalysisEngine::Run(const FuncGraphPtr &func_graph, const AbstractBasePtrList &args_spec_list) {
StaticAnalysisException::Instance().ClearException();
HealthPointMgr::GetInstance().Clear();
ConfigPtrList args_conf_list;
(void)std::transform(args_spec_list.begin(), args_spec_list.end(), std::back_inserter(args_conf_list),
[](const AbstractBasePtr &arg) -> ConfigPtr { return std::make_shared<VirtualConfig>(arg); });
@ -889,12 +890,12 @@ EvalResultPtr AnalysisEngine::ExecuteMultipleEvaluatorsMultiThread(const std::ve
asyncRun0->JoinResult(std::make_shared<AbstractScalar>(0));
asyncRun1->JoinResult(std::make_shared<AbstractScalar>(0));
// Run order
HealthPointMgr::GetInstance().PushBack(asyncRun0); // First order
HealthPointMgr::GetInstance().PushBack(asyncRun1); // Second order
HealthPointMgr::GetInstance().Add2Schedule(asyncRun0); // First order
HealthPointMgr::GetInstance().Add2Schedule(asyncRun1); // Second order
MS_LOG(DEBUG) << GetInferThread() << "async : wait for one of async to finish. " << evaluators[0]->ToString()
<< " or " << evaluators[1]->ToString();
HealthPointMgr::GetInstance().PushBack(asyncResult_main); // Third order
HealthPointMgr::GetInstance().Add2Schedule(asyncResult_main); // Third order
auto branchResult = asyncResult_main->GetResult();
if (branchResult == nullptr || branchResult->isa<AbstractTimeOut>()) {
MS_LOG(EXCEPTION) << "Can't finish " << evaluators[0]->ToString() << " or " << evaluators[1]->ToString()
@ -911,7 +912,7 @@ EvalResultPtr AnalysisEngine::ExecuteMultipleEvaluatorsMultiThread(const std::ve
if (NeedWaitForTwoBranches(branchResult)) {
MS_LOG(DEBUG) << GetInferThread() << "async waiting for " << evaluators[0]->ToString();
// The asyncRun0 will eval asyncResult0
HealthPointMgr::GetInstance().PushBack(asyncResult0);
HealthPointMgr::GetInstance().Add2Schedule(asyncResult0);
auto result0 = asyncResult0->GetResult();
if (result0 == nullptr || result0->isa<AbstractTimeOut>()) {
MS_LOG(EXCEPTION) << "Eval " << evaluators[0]->ToString() << " is time out."
@ -921,7 +922,7 @@ EvalResultPtr AnalysisEngine::ExecuteMultipleEvaluatorsMultiThread(const std::ve
MS_LOG(DEBUG) << GetInferThread() << "async waiting for " << evaluators[1]->ToString();
// The asyncRun1 will eval asyncResult1
HealthPointMgr::GetInstance().PushBack(asyncResult1);
HealthPointMgr::GetInstance().Add2Schedule(asyncResult1);
auto result1 = asyncResult1->GetResult();
if (result1 == nullptr || result1->isa<AbstractTimeOut>()) {
MS_LOG(EXCEPTION) << "Eval " << evaluators[1]->ToString() << " is time out."
@ -930,7 +931,7 @@ EvalResultPtr AnalysisEngine::ExecuteMultipleEvaluatorsMultiThread(const std::ve
out_specs.push_back(result1);
} else {
// Next time to get the result of branches.
HealthPointMgr::GetInstance().PushBack(asyncResult_main);
HealthPointMgr::GetInstance().Add2Schedule(asyncResult_main);
(void)asyncResult_main->GetResult();
// Don't use GetResult

View File

@ -0,0 +1,46 @@
# Copyright 2020 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
import mindspore.context as context
from mindspore import Tensor, ms_function
from mindspore.common import dtype as mstype
@ms_function
def hof(x):
def f(x):
return x + 3
def k(x):
return x - 1
def g(x):
if x < 5:
return f
return k
ret = g(x)(x)
return ret
def test_fun_fun():
context.set_context(mode=context.GRAPH_MODE)
x = Tensor([10], mstype.int32)
ret = hof(x)
expect = Tensor([9], mstype.int32)
assert ret == expect
if __name__ == "__main__":
test_fun_fun()

View File

@ -0,0 +1,67 @@
# Copyright 2020 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
import mindspore.context as context
from mindspore import Tensor, ms_function
from mindspore.common import dtype as mstype
import pytest
ZERO = Tensor([0], mstype.int32)
ONE = Tensor([1], mstype.int32)
@ms_function
def f(x):
y = f(x - 4)
if x < 0:
y = f(x - 3)
elif x < 3:
y = x * f(x - 1)
elif x >= 3:
y = x * f(x - 2)
z = y + 1
return z
@ms_function
def fr(x):
y = ZERO
if x < 0:
y = ONE
elif x < 3:
y = x * fr(x - 1)
elif x >= 3:
y = x * fr(x - 2)
z = y + 1
return z
def test_endless():
context.set_context(mode=context.GRAPH_MODE)
x = Tensor([5], mstype.int32)
f(x)
with pytest.raises(ValueError):
print("endless.")
def test_recrusive_fun():
context.set_context(mode=context.GRAPH_MODE)
x = Tensor([5], mstype.int32)
ret = fr(x)
expect = Tensor([36], mstype.int32)
assert ret == expect
if __name__ == "__main__":
test_recrusive_fun()