|
- # Copyright 2021 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 numpy as np
- import pytest
- from mindspore.common import dtype as mstype
- from mindspore import nn
- from mindspore import Tensor
- from mindspore.ops import composite as C
- from mindspore.ops import operations as P
- from mindspore import context
- from mindspore.common.parameter import Parameter
-
- context.set_context(mode=context.GRAPH_MODE, save_graphs=False)
- grad_all = C.GradOperation(get_all=True)
-
-
- class Grad(nn.Cell):
- def __init__(self, net):
- super(Grad, self).__init__(auto_prefix=False)
- self.forward_net = net
- self.grad = C.GradOperation(get_all=True)
-
- def construct(self, *inputs):
- grads = self.grad(self.forward_net)(*inputs)
- return grads
-
-
- class ForBreakForwardNet(nn.Cell):
- def __init__(self, max_cycles=10):
- super(ForBreakForwardNet, self).__init__()
- self.max_cycles = max_cycles
- self.zero = Tensor(np.array(0), mstype.int32)
-
- def construct(self, x, y):
- out = self.zero
- for i in range(self.max_cycles):
- if i % 2 == 0:
- continue
- out = x * y + out
- if out == 20:
- return out
- if out > 20:
- break
-
- return out
-
-
- @pytest.mark.level1
- @pytest.mark.platform_x86_gpu_training
- @pytest.mark.platform_arm_ascend_training
- @pytest.mark.platform_x86_ascend_training
- @pytest.mark.env_onecard
- def test_for_break_forward():
- x = Tensor(np.array(1), mstype.int32)
- y = Tensor(np.array(3), mstype.int32)
- forward_net = ForBreakForwardNet(max_cycles=3)
- graph_out = forward_net(x, y)
- assert graph_out == Tensor(np.array(3), mstype.int32)
-
-
- @pytest.mark.level0
- @pytest.mark.platform_x86_gpu_training
- @pytest.mark.platform_arm_ascend_training
- @pytest.mark.platform_x86_ascend_training
- @pytest.mark.env_onecard
- def test_for_break_backward():
- x = Tensor(np.array(1), mstype.int32)
- y = Tensor(np.array(3), mstype.int32)
- forward_net = ForBreakForwardNet(max_cycles=3)
- backward_net = Grad(forward_net)
- graph_grads = backward_net(x, y)
- assert graph_grads == (Tensor(np.array(3), mstype.int32), Tensor(np.array(1), mstype.int32))
-
-
- class WhileBreakForwardNet(nn.Cell):
- def __init__(self, max_cycles=10):
- super(WhileBreakForwardNet, self).__init__()
- self.max_cycles = max_cycles
- self.i = Tensor(np.array(0), mstype.int32)
- self.zero = Tensor(np.array(0), mstype.int32)
-
- def construct(self, x, y):
- i = self.i
- out = self.zero
- while i < self.max_cycles:
- if i % 2 == 0:
- i = i + 1
- continue
- out = x * y + out
- if out > 20:
- break
- if out == 20:
- return out
- i = i + 1
- return out
-
-
- @pytest.mark.level1
- @pytest.mark.platform_x86_gpu_training
- @pytest.mark.platform_arm_ascend_training
- @pytest.mark.platform_x86_ascend_training
- @pytest.mark.env_onecard
- def test_while_break_forward():
- x = Tensor(np.array(1), mstype.int32)
- y = Tensor(np.array(3), mstype.int32)
- forward_net = WhileBreakForwardNet(max_cycles=10)
- graph_mode_out = forward_net(x, y)
- assert graph_mode_out == Tensor(np.array(15))
-
-
- @pytest.mark.level0
- @pytest.mark.platform_arm_ascend_training
- @pytest.mark.platform_x86_ascend_training
- @pytest.mark.env_onecard
- def test_while_break_backward():
- context.set_context(mode=context.GRAPH_MODE, save_graphs=True)
- x = Tensor(np.array(1), mstype.int32)
- y = Tensor(np.array(3), mstype.int32)
- forward_net = WhileBreakForwardNet(max_cycles=10)
- backward_net = Grad(forward_net)
- graph_grads = backward_net(x, y)
- assert graph_grads == (Tensor(np.array(15), mstype.int32), Tensor(np.array(5), mstype.int32))
-
-
- class IfAfterIfInWhileBreakForwardNet(nn.Cell):
- def __init__(self, max_cycles=10):
- super(IfAfterIfInWhileBreakForwardNet, self).__init__()
- self.max_cycles = max_cycles
- self.i = Tensor(np.array(0), mstype.int32)
- self.zero = Tensor(np.array(0), mstype.int32)
- self.weight = Parameter(Tensor(np.array(0), mstype.int32))
-
- def construct(self, x, y):
- i = self.i
- out = self.zero
- while i < self.max_cycles:
- self.weight = i
- if self.weight % 2 == 0:
- i = i + 1
- continue
- if out <= 20:
- self.weight = i
- out = x * y + out
- else:
- break
- i = i + 1
- if out >= 30:
- self.weight = out
- out = out - 30
- return out
- out = out + 1
- return out
-
-
- @pytest.mark.level1
- @pytest.mark.platform_x86_gpu_training
- @pytest.mark.platform_arm_ascend_training
- @pytest.mark.platform_x86_ascend_training
- @pytest.mark.env_onecard
- def test_if_after_if_in_while_break_forward():
- x = Tensor(np.array(1), mstype.int32)
- y = Tensor(np.array(3), mstype.int32)
- # Graph Mode
- context.set_context(mode=context.GRAPH_MODE, save_graphs=False)
- graph_forward_net = IfAfterIfInWhileBreakForwardNet(max_cycles=10)
- graph_mode_out = graph_forward_net(x, y)
- assert graph_mode_out == Tensor(np.array(16), mstype.int32)
-
-
- @pytest.mark.level1
- @pytest.mark.platform_x86_gpu_training
- @pytest.mark.platform_arm_ascend_training
- @pytest.mark.platform_x86_ascend_training
- @pytest.mark.env_onecard
- def test_if_after_if_in_while_break_backward():
- x = Tensor(np.array(1), mstype.int32)
- y = Tensor(np.array(3), mstype.int32)
- # Graph Mode
- context.set_context(mode=context.GRAPH_MODE)
- graph_forward_net = IfAfterIfInWhileBreakForwardNet(max_cycles=10)
- graph_backward_net = Grad(graph_forward_net)
- graph_mode_grads = graph_backward_net(x, y)
-
- assert graph_mode_grads == (Tensor(np.array(15), mstype.int32), Tensor(np.array(5), mstype.int32))
-
-
- @pytest.mark.level1
- @pytest.mark.platform_x86_gpu_training
- @pytest.mark.platform_arm_ascend_training
- @pytest.mark.platform_x86_ascend_training
- @pytest.mark.env_onecard
- def test_if_after_for_in_if_break():
- class IfAfterForInIfNet(nn.Cell):
- def __init__(self):
- super().__init__()
- self.param_a = Parameter(Tensor(5, mstype.int32), name='a')
- self.param_b = Parameter(Tensor(4, mstype.int32), name='b')
-
- def construct(self, x):
- out = x + self.param_a
- if self.param_a > self.param_b:
- for _ in range(4):
- self.param_a += 1
- if self.param_b < 0:
- continue
- self.param_b -= 3
- if self.param_a > 6:
- break
-
- self.param_b += 15
- if x < self.param_b:
- out -= self.param_b
- return out
- out = self.param_b + out
- return out
-
- x = Tensor(2, mstype.int32)
-
- # graph mode
-
- forward_net = IfAfterForInIfNet()
- graph_forward_res = forward_net(x)
-
- context.set_context(mode=context.GRAPH_MODE)
- if_after_for_in_if_net = IfAfterForInIfNet()
- net = Grad(if_after_for_in_if_net)
- graph_backward_res = net(x)
-
- assert graph_forward_res == Tensor(-6, mstype.int32)
- assert graph_backward_res == (Tensor(1, mstype.int32),)
-
-
- @pytest.mark.skip(reason="ME EvalCNode error.")
- @pytest.mark.level0
- @pytest.mark.platform_x86_gpu_training
- @pytest.mark.platform_arm_ascend_training
- @pytest.mark.platform_x86_ascend_training
- @pytest.mark.env_onecard
- def test_if_after_for_in_for_break():
- class IfAfterForInForNet(nn.Cell):
- def __init__(self):
- super().__init__()
- self.param_a = Parameter(Tensor(5, mstype.int32), name='a')
- self.param_b = Parameter(Tensor(2, mstype.int32), name='b')
-
- def construct(self, x):
- out = x + self.param_a
- for _ in range(0, 10):
- x *= 2
- if self.param_a % 2 == 0:
- self.param_a += 1
- continue
- for _ in range(0, 5):
- self.param_a += 1
- x += self.param_b
- if x > 10:
- break
- if x > 100:
- return x
- if self.param_a > self.param_b:
- out += x
- return out
-
- x = Tensor(2, mstype.int32)
-
- # graph mode
- forward_net = IfAfterForInForNet()
- graph_forward_res = forward_net(x)
-
- if_after_for_in_for_net = IfAfterForInForNet()
- net = Grad(if_after_for_in_for_net)
- graph_backward_res = net(x)
-
- print("test_if_after_for_in_for_break graph_forward_res:", graph_forward_res)
- print("test_if_after_for_in_for_break graph_backward_res:", graph_backward_res)
- # assert graph_forward_res == Tensor(12285, mstype.int32)
- # assert graph_backward_res == (Tensor(1025, mstype.int32),)
-
-
- class WhileAfterWhileInWhileBreakForwardNet(nn.Cell):
- def __init__(self, max_cycles=10):
- super(WhileAfterWhileInWhileBreakForwardNet, self).__init__()
- self.max_cycles = max_cycles
- self.zero = Tensor(np.array(0), mstype.int32)
- self.i = Tensor(np.array(0), mstype.int32)
-
- def construct(self, x, y):
- out = self.zero
- i = self.i
- while i < self.max_cycles:
- j = self.i
- while j < self.max_cycles + 3:
- out = x * y + out
- j = j + 1
- if j > 4:
- break
- i = i + 1
- if i > 2:
- break
- i = self.i
- while i < self.max_cycles:
- out = x * y + out
- i = i + 1
- return out
-
-
- @pytest.mark.level1
- @pytest.mark.platform_x86_gpu_training
- @pytest.mark.platform_arm_ascend_training
- @pytest.mark.platform_x86_ascend_training
- @pytest.mark.env_onecard
- def test_while_after_while_in_while_break_forward():
- context.set_context(mode=context.GRAPH_MODE)
- x = Tensor(np.array(1), mstype.int32)
- y = Tensor(np.array(3), mstype.int32)
- forward_net = WhileAfterWhileInWhileBreakForwardNet(max_cycles=3)
- graph_out = forward_net(x, y)
-
- assert graph_out == Tensor(np.array(54), mstype.int32)
-
-
- @pytest.mark.level1
- @pytest.mark.platform_x86_gpu_training
- @pytest.mark.platform_arm_ascend_training
- @pytest.mark.platform_x86_ascend_training
- @pytest.mark.env_onecard
- def test_while_after_while_in_while_break_backward():
- context.set_context(mode=context.GRAPH_MODE)
- x = Tensor(np.array(1), mstype.int32)
- y = Tensor(np.array(3), mstype.int32)
- forward_net = WhileAfterWhileInWhileBreakForwardNet(max_cycles=3)
- backward_net = Grad(forward_net)
- graph_grads = backward_net(x, y)
-
- assert graph_grads == (Tensor(np.array(54), mstype.int32), Tensor(np.array(18), mstype.int32))
-
-
- class TwoBreakDeadForwardNet(nn.Cell):
- def __init__(self):
- super(TwoBreakDeadForwardNet, self).__init__()
- self.zero = Tensor(np.array(0), mstype.int32)
-
- def construct(self, x):
- while x < 5:
- if x > 3:
- x -= 2
- elif x == 3:
- break
- else:
- break
- x = x + 1
- return x
-
-
- @pytest.mark.level1
- @pytest.mark.platform_x86_gpu_training
- @pytest.mark.platform_arm_ascend_training
- @pytest.mark.platform_x86_ascend_training
- @pytest.mark.env_onecard
- def test_2break_dead_block():
- x = Tensor(np.array(1), mstype.int32)
- forward_net = TwoBreakDeadForwardNet()
- graph_out = forward_net(x)
-
- assert graph_out == Tensor(np.array(1), mstype.int32)
-
-
- class ForInFor2BreakForwardNet(nn.Cell):
- def __init__(self):
- super(ForInFor2BreakForwardNet, self).__init__()
- self.relu = P.ReLU()
- self.add = P.TensorAdd()
-
- def construct(self, x, y, z):
- out = z
- for _ in range(2):
- for _ in range(3):
- if 2 * x < y:
- out = self.add(out, out)
- x = x + 1
- if x + 6 == y:
- break
- out = self.relu(out)
- return out
-
-
- @pytest.mark.skip(reason="Get wrong parent graph")
- def test_for_in_for_break():
- x = Tensor(np.array(7), mstype.float32)
- y = Tensor(np.array(20), mstype.float32)
- z = Tensor(np.array(2), mstype.float32)
- forward_net = ForInFor2BreakForwardNet()
- graph_out = forward_net(x, y, z)
- print("test_for_in_for_break graph out:", graph_out)
-
-
- # raise a endless loop exception.
- @pytest.mark.skip(reason="Infer raise a endless loop exception")
- def test_while_true_break():
- context.set_context(save_graphs=True)
-
- class WhileTrueBreakNet(nn.Cell):
- def __init__(self, t):
- super(WhileTrueBreakNet, self).__init__()
- self.add = P.Add()
- self.mul = P.Mul()
- self.para = Parameter(Tensor(t, mstype.int32), name="a")
-
- def construct(self, x, y):
- out = self.mul(y, self.para)
- while True:
- if x == 5:
- x = x - 3
- continue
- if x == 2:
- break
- out = self.add(out, out)
- return out
-
- t = np.array([1]).astype(np.int32)
- y = Tensor([1], mstype.int32)
- x = Tensor([5], mstype.int32)
- net = WhileTrueBreakNet(t)
- grad_net = Grad(net)
- grad_out = grad_net(x, y)
- print(grad_out)
-
-
- # stuck in vm backend
- @pytest.mark.skip(reason="Stuck in vm backend")
- def test_continue_stuck_in_vm():
- context.set_context(save_graphs=True)
-
- class NetWork(nn.Cell):
- def __init__(self, t):
- super().__init__()
- self.add = P.Add()
- self.mul = P.Mul()
- self.para = Parameter(Tensor(t, mstype.int32), name="a")
-
- def construct(self, x, y):
- out = self.mul(y, y)
- while x != 3:
- while self.para > 5:
- # self.param -= 1 if set after if_switch, which is wrong
- self.para -= 1
- x += 1
- if x > 3:
- self.para -= x
- return out
- out = self.add(out, y)
- continue
- out = self.mul(out, y)
- return out
-
- x = Tensor(2, mstype.int32)
- t = 8
- y = Tensor(1, mstype.int32)
- net = NetWork(t)
- grad_net = Grad(net)
- grad = grad_net(x, y)
- print(grad)
|