!106 support comparison ops for python

Merge pull request !106 from amongo/SupportPythonOperators
This commit is contained in:
mindspore-ci-bot 2020-04-03 15:52:08 +08:00 committed by Gitee
commit a5d95e472e
13 changed files with 462 additions and 15 deletions

View File

@ -92,16 +92,16 @@ convert_object_map = {
T.and_: multitype_ops.logical_and,
T.or_: multitype_ops.logical_or,
T.xor: NO_IMPLEMENT,
T.pos: F.scalar_uadd,
T.pos: multitype_ops.uadd,
T.neg: multitype_ops.negative,
T.invert: NO_IMPLEMENT,
T.not_: F.bool_not,
T.not_: multitype_ops.logical_not,
T.eq: multitype_ops.equal,
T.ne: F.scalar_ne,
T.ne: multitype_ops.not_equal,
T.lt: multitype_ops.less,
T.gt: F.scalar_gt,
T.gt: multitype_ops.greater,
T.le: multitype_ops.less_equal,
T.ge: F.scalar_ge,
T.ge: multitype_ops.greater_equal,
T.is_: F.is_,
T.is_not: F.is_not,
T.contains: NO_IMPLEMENT,

View File

@ -23,23 +23,33 @@ from .getitem_impl import getitem
from .zeros_like_impl import zeros_like
from .ones_like_impl import ones_like
from .equal_impl import equal
from .not_equal_impl import not_equal
from .less_impl import less
from .less_equal_impl import less_equal
from .greater_impl import greater
from .greater_equal_impl import greater_equal
from .negative_impl import negative
from .logical_and_impl import logical_and
from .logical_or_impl import logical_or
from .logic_not_impl import logical_not
from .uadd_impl import uadd
__all__ = [
'add',
'sub',
'mul',
'div',
'uadd',
'zeros_like',
'ones_like',
'equal',
'not_equal',
'less',
'less_equal',
'greater',
'greater_equal',
'negative',
'getitem',
'logical_and',
'logical_or'
'logical_or',
'logical_not'
]

View File

@ -190,7 +190,8 @@ def _none_equal_tuple(x, y):
"""
return False
@equal.register("Tensor", "Number")
@equal.register("Number", "Tensor")
@equal.register("Tensor", "Tensor")
def _tensor_equal_tensor(x, y):
"""

View File

@ -0,0 +1,53 @@
# 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.
# ============================================================================
"""greater_equal_impl"""
from mindspore.ops.composite import base
from mindspore.ops import functional as F
# greater_equal is a metagraph object which will determine if two objects are greater_equal according to input type
# using ".register" decorator
greater_equal = base.MultitypeFuncGraph("greater_equal")
@greater_equal.register("Number", "Number")
def _greater_equal_scala(x, y):
"""
Determine whether x is greater equal than y
Args:
x(Number): Number.
y(Number): Number.
Returns:
bool, if x >= y return true, x < y return false.
"""
return F.scalar_ge(x, y)
@greater_equal.register("Tensor", "Number")
@greater_equal.register("Number", "Tensor")
@greater_equal.register("Tensor", "Tensor")
def _greater_equal_tensor(x, y):
"""
Determine whether tensor x is greater equal than tensor y elementwise
Args:
x(Tensor): Tensor.
y(Tensor): Tensor.
Returns:
Tensor, return value by operator P.GreaterEqual.
"""
return F.tensor_ge(x, y)

View File

@ -0,0 +1,53 @@
# 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
#
# Ungreater 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.
# ============================================================================
"""equal_impl"""
from mindspore.ops.composite import base
from mindspore.ops import functional as F
# greater is a metafuncgraph object which will determine if two objects are greater according to input type
# using ".register" decorator
greater = base.MultitypeFuncGraph("greater")
@greater.register("Number", "Number")
def _greater_scala(x, y):
"""
Determine whether two numbers are greater.
Args:
x(Number): Number.
y(Number): Number.
Returns:
bool, if x > y return true, x <= y return false.
"""
return F.scalar_gt(x, y)
@greater.register("Tensor", "Number")
@greater.register("Number", "Tensor")
@greater.register("Tensor", "Tensor")
def _greater_tensor(x, y):
"""
Determine whether two tensor are greater by element.
Args:
x(Tensor): Tensor.
y(Tensor): Tensor.
Returns:
tensor, return operation of x and y by P.Greater
"""
return F.tensor_gt(x, y)

View File

@ -36,7 +36,8 @@ def _less_equal_scala(x, y):
"""
return F.scalar_le(x, y)
@less_equal.register("Tensor", "Number")
@less_equal.register("Number", "Tensor")
@less_equal.register("Tensor", "Tensor")
def _less_equal_tensor(x, y):
"""

View File

@ -36,7 +36,8 @@ def _less_scala(x, y):
"""
return F.scalar_lt(x, y)
@less.register("Tensor", "Number")
@less.register("Number", "Tensor")
@less.register("Tensor", "Tensor")
def _less_tensor(x, y):
"""
@ -47,6 +48,6 @@ def _less_tensor(x, y):
y(Tensor): Tensor.
Returns:
bool, if x and y are less elements by element return true, else return false.
Tensor, return value of x and y by operation P.Less()
"""
return F.tensor_lt(x, y)

View File

@ -0,0 +1,48 @@
# 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.
# ============================================================================
"""logical_not_impl"""
from mindspore.ops.composite import base
from mindspore.ops import functional as F
# logical_not is a metagraph object which will generate function according to input type
# using ".register" decorator
logical_not = base.MultitypeFuncGraph("logical_not")
@logical_not.register("Number")
def _logical_not_scala(x):
"""
Return logical not operation result of x
Args:
x(Number): Number.
Returns:
bool, Return logical not operation result of x
"""
return F.bool_not(x.__bool__())
@logical_not.register("Tensor")
def _logical_not_tensor(x):
"""
Return logical not operation result of x
Args:
x(Tensor): Tensor.
Returns:
Tensor, Return logical not operation result of x
"""
return F.logical_not(x)

View File

@ -0,0 +1,237 @@
# 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.
# ============================================================================
"""not_equal_impl"""
from ...composite import base
from ... import functional as F
not_equal = base.MultitypeFuncGraph("not_equal")
"""
not_equal is a metafuncgraph object which will determine if two objects are not_equal according to input type
using ".register" decorator
"""
@not_equal.register("Number", "Number")
def _not_equal_scalar(x, y):
"""
Determine if two numbers is not equal.
Args:
x (Number): x
y (NUmber): y
Returns:
bool, if x != y return true, x == y return false.
"""
return not F.scalar_eq(x, y)
@not_equal.register("String", "String")
def _not_equal_string(x, y):
"""
Determine if two strings are not equal.
Args:
x: str
y: str
Returns:
bool, if x != y return true, x == y return false.
"""
return not F.string_eq(x, y)
@not_equal.register("String", "None")
def _string_not_equal_none(x, y):
"""
Determine if string not equals none.
Args:
x: str.
y: None.
Returns:
bool, return True.
"""
return True
@not_equal.register("None", "String")
def _none_not_equal_string(x, y):
"""
Determine if string not equals none.
Args:
x: None.
y: str.
Returns:
bool, return True.
"""
return True
@not_equal.register("None", "None")
def _none_not_equal_none(x, y):
"""
Determine if none not equals none.
Args:
x: None.
y: None.
Returns:
bool, return False.
"""
return False
@not_equal.register("Number", "None")
def _scalar_not_equal_none(x, y):
"""
Determine if number not equals none.
Args:
x: Number.
y: None.
Returns:
bool, return True.
"""
return True
@not_equal.register("None", "Number")
def _none_not_equal_scalar(x, y):
"""
Determine if number not_equals none.
Args:
x: None.
y: NUmber.
Returns:
bool, return True.
"""
return True
@not_equal.register("Tuple", "Tuple")
def _euqal_tuple(x, y):
"""
Determine if two tuples are not equal by element.
Args:
x (tuple): x
y (tuple): y
Returns:
bool, if x and y are not equal by element return true, else return false.
"""
return not F.tuple_equal(x, y)
@not_equal.register("List", "List")
def _euqal_list(x, y):
"""
Determine if two lists are not equal by element.
Args:
x (list): x
y (list): y
Returns:
bool, if x and y are not equal by element return true, else return false.
"""
return not F.list_equal(x, y)
@not_equal.register("Tuple", "None")
def _tuple_euqal_none(x, y):
"""
Determine if tuple element not equals none element.
Args:
x: Tuple.
y: None.
Returns:
bool, return True.
"""
return True
@not_equal.register("None", "Tuple")
def _none_not_equal_tuple(x, y):
"""
Determine if tuple element not equals none element.
Args:
x: None.
y: Tuple.
Returns:
bool, return True.
"""
return True
@not_equal.register("Tensor", "Number")
@not_equal.register("Number", "Tensor")
@not_equal.register("Tensor", "Tensor")
def _tensor_not_equal_tensor(x, y):
"""
Determine if two tensors are not_equal.
Args:
x : Tensor.
y : Tensor.
Returns:
bool, if x == y return true, x != y return false.
"""
return F.not_equal(x, y)
@not_equal.register("Tensor", "None")
def _tensor_not_equal_none(x, y):
"""
Determine if tensor not_equal none.
Args:
x : Tensor.
y : None.
Returns:
bool, return True.
"""
return True
@not_equal.register("None", "Tensor")
def _none_not_equal_tensor(x, y):
"""
Determine if tensor not equal none.
Args:
x : None.
y : Tensor.
Returns:
bool, return True.
"""
return True

View File

@ -0,0 +1,26 @@
# 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.
# ============================================================================
"""uadd_impl"""
from mindspore.ops.composite import base
# uadd is a metagraph object which will return operation result regarding input
# using ".register" decorator
uadd = base.MultitypeFuncGraph("uadd")
@uadd.register("Tensor")
@uadd.register("Number")
def _uadd_scala(x):
return x

View File

@ -43,12 +43,15 @@ tensor_add = P.TensorAdd()
neg_tensor = P.Neg()
tensor_lt = P.Less()
tensor_le = P.LessEqual()
tensor_gt = P.Greater()
tensor_ge = P.GreaterEqual()
tensor_sub = P.Sub()
tensor_mul = P.Mul()
tensor_div = P.RealDiv()
strided_slice = P.StridedSlice()
same_type_shape = P.SameTypeShape()
equal = P.Equal()
not_equal = P.NotEqual()
assign_sub = P.AssignSub()
assign = P.Assign()
square = P.Square()
@ -97,6 +100,7 @@ bool_or = Primitive("bool_or")
bool_and = Primitive("bool_and")
logical_and = P.LogicalAnd()
logical_or = P.LogicalOr()
logical_not = P.LogicalNot()
array_to_scalar = Primitive('array_to_scalar')
is_ = Primitive("is_")
is_not = Primitive("is_not")

View File

@ -17,6 +17,7 @@ from mindspore.ops import Primitive
scala_add = Primitive('scalar_add')
scala_mul = Primitive('scalar_mul')
scalar_gt = Primitive('scalar_gt')
def scalar_add(x, y):
"""Implement `scalar_add`."""
return scala_add(x, y)
@ -26,6 +27,6 @@ def scalar_mul(x, y):
return scala_mul(x, y)
def test_if(x, y):
if x > y:
if scalar_gt(x, y):
return x
return y

View File

@ -31,8 +31,20 @@ class ComparisonOpsNet(nn.Cell):
def __init__(self):
super(ComparisonOpsNet, self).__init__()
def construct(self, x, y):
ret = x <= y
return ret
a = x <= y
b = x <= 1.0
c = y >= 1.0
d = y >= x
e = x < y
f = x < 1.0
g = 1.0 > y
h = y > x
i = y == 3.0
j = x != 4
k = + x
l = + 1.0
m = k != l
return a or b or c or d or e or f or g or h or i or j or m
class LogicalNumberOpsNet(nn.Cell):
def __init__(self):
@ -41,7 +53,7 @@ class LogicalNumberOpsNet(nn.Cell):
self.one = 0
self.zero = 0.0
def construct(self, x, y):
if self.cond and self.one or self.zero:
if self.cond and self.one or self.zero and not self.one:
return x + y
return x - y
@ -51,7 +63,7 @@ class LogicalTensorOpsNet(nn.Cell):
super(LogicalTensorOpsNet, self).__init__()
self.const_true = Tensor(True, dtype=mstype.bool_)
def construct(self, x, y):
ret = x and y and (y or self.const_true)
ret = x and y and (y or self.const_true) and (not self.const_true)
return ret