logic.py 25.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#   Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# 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.

Z
Zhen Wang 已提交
15
from ..fluid.layer_helper import LayerHelper
16
from ..fluid.data_feeder import check_type, check_variable_and_dtype
Z
Zhen Wang 已提交
17
from ..fluid.layers.layer_function_generator import templatedoc
Z
zhiboniu 已提交
18
from ..static import Variable
J
Jiabin Yang 已提交
19
from ..fluid.framework import _in_legacy_dygraph, in_dygraph_mode
20 21 22 23 24 25
# TODO: define logic functions of a tensor
import paddle.fluid as fluid
if fluid.framework._in_eager_mode_:
    Tensor = fluid.framework.core.eager.Tensor
else:
    from ..framework import VarBase as Tensor
26 27 28 29 30
from ..fluid.layers import is_empty  # noqa: F401
from ..fluid.layers import logical_and  # noqa: F401
from ..fluid.layers import logical_not  # noqa: F401
from ..fluid.layers import logical_or  # noqa: F401
from ..fluid.layers import logical_xor  # noqa: F401
Z
zhiboniu 已提交
31
import paddle
W
wanghuancoder 已提交
32
from paddle import _C_ops
33
from paddle.tensor.creation import full
34

35 36
__all__ = []

37

W
wawltor 已提交
38
def equal_all(x, y, name=None):
39 40 41
    """
    This OP returns the truth value of :math:`x == y`. True if two inputs have the same elements, False otherwise.

W
wawltor 已提交
42
    **NOTICE**: The output of this OP has no gradient.
43 44

    Args:
45 46
        x(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
        y(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
W
wawltor 已提交
47 48
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.
49 50

    Returns:
W
wawltor 已提交
51
        Tensor: output Tensor, data type is bool, value is [False] or [True].
52 53 54 55 56

    Examples:
        .. code-block:: python

          import paddle
W
wawltor 已提交
57

58 59 60
          x = paddle.to_tensor([1, 2, 3])
          y = paddle.to_tensor([1, 2, 3])
          z = paddle.to_tensor([1, 4, 3])
W
wawltor 已提交
61
          result1 = paddle.equal_all(x, y)
N
Noel 已提交
62
          print(result1) # result1 = [True ]
W
wawltor 已提交
63
          result2 = paddle.equal_all(x, z)
N
Noel 已提交
64
          print(result2) # result2 = [False ]
65
    """
Z
zhiboniu 已提交
66
    if paddle.in_dynamic_mode():
W
wanghuancoder 已提交
67
        return _C_ops.equal_all(x, y)
W
wawltor 已提交
68 69

    helper = LayerHelper("equal_all", **locals())
70 71
    out = helper.create_variable_for_type_inference(dtype='bool')
    helper.append_op(
W
wawltor 已提交
72 73
        type='equal_all', inputs={'X': [x],
                                  'Y': [y]}, outputs={'Out': [out]})
74
    return out
Z
Zhen Wang 已提交
75 76 77


@templatedoc()
78
def allclose(x, y, rtol=1e-05, atol=1e-08, equal_nan=False, name=None):
Z
Zhen Wang 已提交
79 80 81 82
    """
    ${comment}

    Args:
83 84
        x(Tensor): ${input_comment}.
        y(Tensor): ${other_comment}.
H
huangxu96 已提交
85 86
        rtol(rtoltype, optional): The relative tolerance. Default: :math:`1e-5` .
        atol(atoltype, optional): The absolute tolerance. Default: :math:`1e-8` .
87 88 89
        equal_nan(equalnantype, optional): ${equal_nan_comment}.
        name (str, optional): Name for the operation. For more information, please
            refer to :ref:`api_guide_Name`. Default: None.
Z
Zhen Wang 已提交
90 91

    Returns:
92 93 94 95 96 97 98 99
        Tensor: ${out_comment}.

    Raises:
        TypeError: The data type of ``x`` must be one of float32, float64.
        TypeError: The data type of ``y`` must be one of float32, float64.
        TypeError: The type of ``rtol`` must be float.
        TypeError: The type of ``atol`` must be float.
        TypeError: The type of ``equal_nan`` must be bool.
Z
Zhen Wang 已提交
100 101 102 103 104 105

    Examples:
        .. code-block:: python

          import paddle

106 107
          x = paddle.to_tensor([10000., 1e-07])
          y = paddle.to_tensor([10000.1, 1e-08])
108
          result1 = paddle.allclose(x, y, rtol=1e-05, atol=1e-08,
Z
Zhen Wang 已提交
109
                                  equal_nan=False, name="ignore_nan")
110 111 112
          np_result1 = result1.numpy()
          # [False]
          result2 = paddle.allclose(x, y, rtol=1e-05, atol=1e-08,
Z
Zhen Wang 已提交
113
                                      equal_nan=True, name="equal_nan")
114 115 116
          np_result2 = result2.numpy()
          # [False]

117 118
          x = paddle.to_tensor([1.0, float('nan')])
          y = paddle.to_tensor([1.0, float('nan')])
119 120 121 122 123 124 125 126
          result1 = paddle.allclose(x, y, rtol=1e-05, atol=1e-08,
                                  equal_nan=False, name="ignore_nan")
          np_result1 = result1.numpy()
          # [False]
          result2 = paddle.allclose(x, y, rtol=1e-05, atol=1e-08,
                                      equal_nan=True, name="equal_nan")
          np_result2 = result2.numpy()
          # [True]
Z
Zhen Wang 已提交
127 128
    """

129
    if in_dygraph_mode():
130 131 132 133 134 135
        # NOTE(dev): Pass tol as Tensor to fix precision loss problem, because
        # C++ backend will cast it into float32 if passing float from python.
        as_tensor = lambda x: paddle.to_tensor([x], dtype='float64', place='cpu')
        return _C_ops.final_state_allclose(x, y,
                                           as_tensor(rtol),
                                           as_tensor(atol), equal_nan)
136
    if _in_legacy_dygraph():
W
wanghuancoder 已提交
137 138 139
        return _C_ops.allclose(x, y, 'rtol',
                               str(rtol), 'atol',
                               str(atol), 'equal_nan', equal_nan)
140 141
    check_variable_and_dtype(x, "input", ['float32', 'float64'], 'allclose')
    check_variable_and_dtype(y, "input", ['float32', 'float64'], 'allclose')
Z
Zhen Wang 已提交
142 143 144 145 146 147 148
    check_type(rtol, 'rtol', float, 'allclose')
    check_type(atol, 'atol', float, 'allclose')
    check_type(equal_nan, 'equal_nan', bool, 'allclose')

    helper = LayerHelper("allclose", **locals())
    out = helper.create_variable_for_type_inference(dtype='bool')

149
    inputs = {'Input': x, 'Other': y}
Z
Zhen Wang 已提交
150
    outputs = {'Out': out}
151
    attrs = {'rtol': str(rtol), 'atol': str(atol), 'equal_nan': equal_nan}
Z
Zhen Wang 已提交
152 153 154 155
    helper.append_op(
        type='allclose', inputs=inputs, outputs=outputs, attrs=attrs)

    return out
156 157


W
wawltor 已提交
158 159
@templatedoc()
def equal(x, y, name=None):
160
    """
S
swtkiwi 已提交
161

162
    This layer returns the truth value of :math:`x == y` elementwise.
N
Noel 已提交
163

W
wawltor 已提交
164
    **NOTICE**: The output of this OP has no gradient.
165 166

    Args:
167 168
        x(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
        y(Tensor): Tensor, data type is bool, float32, float64, int32, int64.
169 170 171 172
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.

    Returns:
W
wawltor 已提交
173
        Tensor: output Tensor, it's shape is the same as the input's Tensor,
174 175 176 177 178
        and the data type is bool. The result of this op is stop_gradient. 

    Examples:
        .. code-block:: python

W
wawltor 已提交
179 180
          import paddle

181 182
          x = paddle.to_tensor([1, 2, 3])
          y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
183
          result1 = paddle.equal(x, y)
N
Noel 已提交
184
          print(result1)  # result1 = [True False False]
185
    """
186 187 188 189 190 191 192
    if not isinstance(y, (int, bool, float, Variable)):
        raise TypeError(
            "Type of input args must be float, bool, int or Tensor, but received type {}".
            format(type(y)))
    if not isinstance(y, Variable):
        y = full(shape=[1], dtype=x.dtype, fill_value=y)

J
Jiabin Yang 已提交
193
    if in_dygraph_mode():
194 195
        default_axis = -1
        return _C_ops.final_state_equal(x, y, default_axis)
J
Jiabin Yang 已提交
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
    else:
        if _in_legacy_dygraph():
            return _C_ops.equal(x, y)
        else:
            check_variable_and_dtype(
                x, "x", ["bool", "float32", "float64", "int32", "int64"],
                "equal")
            check_variable_and_dtype(
                y, "y", ["bool", "float32", "float64", "int32", "int64"],
                "equal")
            helper = LayerHelper("equal", **locals())
            out = helper.create_variable_for_type_inference(dtype='bool')
            out.stop_gradient = True

            helper.append_op(
                type='equal',
                inputs={'X': [x],
                        'Y': [y]},
                outputs={'Out': [out]})
            return out
216

W
wawltor 已提交
217 218 219 220 221

@templatedoc()
def greater_equal(x, y, name=None):
    """
    This OP returns the truth value of :math:`x >= y` elementwise, which is equivalent function to the overloaded operator `>=`.
N
Noel 已提交
222

W
wawltor 已提交
223 224 225
    **NOTICE**: The output of this OP has no gradient.

    Args:
226 227
        x(Tensor): First input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
        y(Tensor): Second input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
W
wawltor 已提交
228 229 230 231 232 233 234
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.
    Returns:
        Tensor, the output data type is bool: The tensor storing the output, the output shape is same as input :attr:`x`.

    Examples:
        .. code-block:: python
N
Noel 已提交
235

W
wawltor 已提交
236 237
            import paddle

238 239
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
240
            result1 = paddle.greater_equal(x, y)
N
Noel 已提交
241
            print(result1)  # result1 = [True False True]
W
wawltor 已提交
242
    """
J
Jiabin Yang 已提交
243
    if in_dygraph_mode():
244 245
        default_axis = -1
        return _C_ops.final_state_greater_equal(x, y, default_axis)
J
Jiabin Yang 已提交
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
    else:
        if _in_legacy_dygraph():
            return _C_ops.greater_equal(x, y)
        else:
            check_variable_and_dtype(
                x, "x", ["bool", "float32", "float64", "int32", "int64"],
                "greater_equal")
            check_variable_and_dtype(
                y, "y", ["bool", "float32", "float64", "int32", "int64"],
                "greater_equal")
            helper = LayerHelper("greater_equal", **locals())
            out = helper.create_variable_for_type_inference(dtype='bool')
            out.stop_gradient = True

            helper.append_op(
                type='greater_equal',
                inputs={'X': [x],
                        'Y': [y]},
                outputs={'Out': [out]})
            return out
W
wawltor 已提交
266 267 268 269 270 271


@templatedoc()
def greater_than(x, y, name=None):
    """
    This OP returns the truth value of :math:`x > y` elementwise, which is equivalent function to the overloaded operator `>`.
N
Noel 已提交
272

W
wawltor 已提交
273 274 275
    **NOTICE**: The output of this OP has no gradient.

    Args:
276 277
        x(Tensor): First input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
        y(Tensor): Second input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
W
wawltor 已提交
278 279 280 281 282 283 284
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.
    Returns:
        Tensor, the output data type is bool: The tensor storing the output, the output shape is same as input :attr:`x` .

    Examples:
        .. code-block:: python
N
Noel 已提交
285

W
wawltor 已提交
286 287
            import paddle

288 289
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
290
            result1 = paddle.greater_than(x, y)
N
Noel 已提交
291
            print(result1)  # result1 = [False False True]
W
wawltor 已提交
292
    """
J
Jiabin Yang 已提交
293
    if in_dygraph_mode():
W
wanghuancoder 已提交
294
        return _C_ops.final_state_greater_than(x, y, -1)
J
Jiabin Yang 已提交
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
    else:
        if _in_legacy_dygraph():
            return _C_ops.greater_than(x, y)
        else:
            check_variable_and_dtype(
                x, "x", ["bool", "float32", "float64", "int32", "int64"],
                "greater_than")
            check_variable_and_dtype(
                y, "y", ["bool", "float32", "float64", "int32", "int64"],
                "greater_than")
            helper = LayerHelper("greater_than", **locals())
            out = helper.create_variable_for_type_inference(dtype='bool')
            out.stop_gradient = True

            helper.append_op(
                type='greater_than',
                inputs={'X': [x],
                        'Y': [y]},
                outputs={'Out': [out]})
            return out
W
wawltor 已提交
315 316 317 318 319 320


@templatedoc()
def less_equal(x, y, name=None):
    """
    This OP returns the truth value of :math:`x <= y` elementwise, which is equivalent function to the overloaded operator `<=`.
N
Noel 已提交
321

W
wawltor 已提交
322 323 324
    **NOTICE**: The output of this OP has no gradient.

    Args:
325 326
        x(Tensor): First input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
        y(Tensor): Second input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
W
wawltor 已提交
327 328 329 330 331 332 333 334
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        Tensor, the output data type is bool: The tensor storing the output, the output shape is same as input :attr:`x`.

    Examples:
        .. code-block:: python
N
Noel 已提交
335

W
wawltor 已提交
336 337
            import paddle

338 339
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
340
            result1 = paddle.less_equal(x, y)
N
Noel 已提交
341
            print(result1)  # result1 = [True True False]
W
wawltor 已提交
342
    """
J
Jiabin Yang 已提交
343
    if in_dygraph_mode():
0
0x45f 已提交
344 345
        axis = -1
        return _C_ops.final_state_less_equal(x, y, axis)
J
Jiabin Yang 已提交
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
    else:
        if _in_legacy_dygraph():
            return _C_ops.less_equal(x, y)
        else:
            check_variable_and_dtype(
                x, "x", ["bool", "float32", "float64", "int32", "int64"],
                "less_equal")
            check_variable_and_dtype(
                y, "y", ["bool", "float32", "float64", "int32", "int64"],
                "less_equal")
            helper = LayerHelper("less_equal", **locals())
            out = helper.create_variable_for_type_inference(dtype='bool')
            out.stop_gradient = True

            helper.append_op(
                type='less_equal',
                inputs={'X': [x],
                        'Y': [y]},
                outputs={'Out': [out]})
            return out
W
wawltor 已提交
366 367 368 369 370 371


@templatedoc()
def less_than(x, y, name=None):
    """
    This OP returns the truth value of :math:`x < y` elementwise, which is equivalent function to the overloaded operator `<`.
N
Noel 已提交
372

W
wawltor 已提交
373 374 375
    **NOTICE**: The output of this OP has no gradient.

    Args:
376 377
        x(Tensor): First input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
        y(Tensor): Second input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
W
wawltor 已提交
378 379 380 381 382 383 384 385
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        Tensor, the output data type is bool: The tensor storing the output, the output shape is same as input :attr:`x`.

    Examples:
        .. code-block:: python
N
Noel 已提交
386

W
wawltor 已提交
387 388
            import paddle

389 390
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
391
            result1 = paddle.less_than(x, y)
N
Noel 已提交
392
            print(result1)  # result1 = [False True False]
W
wawltor 已提交
393
    """
J
Jiabin Yang 已提交
394
    if in_dygraph_mode():
395 396
        default_axis = -1
        return _C_ops.final_state_less_than(x, y, default_axis)
J
Jiabin Yang 已提交
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
    else:
        if _in_legacy_dygraph():
            return _C_ops.less_than(x, y)
        else:
            check_variable_and_dtype(
                x, "x", ["bool", "float32", "float64", "int32", "int64"],
                "less_than")
            check_variable_and_dtype(
                y, "y", ["bool", "float32", "float64", "int32", "int64"],
                "less_than")
            helper = LayerHelper("less_than", **locals())
            out = helper.create_variable_for_type_inference(dtype='bool')
            out.stop_gradient = True

            helper.append_op(
                type='less_than',
                inputs={'X': [x],
                        'Y': [y]},
                outputs={'Out': [out]})
            return out
W
wawltor 已提交
417 418 419 420 421 422


@templatedoc()
def not_equal(x, y, name=None):
    """
    This OP returns the truth value of :math:`x != y` elementwise, which is equivalent function to the overloaded operator `!=`.
N
Noel 已提交
423
    
W
wawltor 已提交
424 425 426
    **NOTICE**: The output of this OP has no gradient.

    Args:
427 428
        x(Tensor): First input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
        y(Tensor): Second input to compare which is N-D tensor. The input data type should be bool, float32, float64, int32, int64.
W
wawltor 已提交
429 430 431 432 433 434 435 436
        name(str, optional): The default value is None.  Normally there is no need for
            user to set this property.  For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        Tensor, the output data type is bool: The tensor storing the output, the output shape is same as input :attr:`x`.

    Examples:
        .. code-block:: python
437

W
wawltor 已提交
438 439
            import paddle

440 441
            x = paddle.to_tensor([1, 2, 3])
            y = paddle.to_tensor([1, 3, 2])
W
wawltor 已提交
442
            result1 = paddle.not_equal(x, y)
N
Noel 已提交
443
            print(result1)  # result1 = [False True True]
W
wawltor 已提交
444
    """
J
Jiabin Yang 已提交
445
    if in_dygraph_mode():
0
0x45f 已提交
446 447
        axis = -1
        return _C_ops.final_state_not_equal(x, y, axis)
J
Jiabin Yang 已提交
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
    else:
        if _in_legacy_dygraph():
            return _C_ops.not_equal(x, y)
        else:
            check_variable_and_dtype(
                x, "x", ["bool", "float32", "float64", "int32", "int64"],
                "not_equal")
            check_variable_and_dtype(
                y, "y", ["bool", "float32", "float64", "int32", "int64"],
                "not_equal")
            helper = LayerHelper("not_equal", **locals())
            out = helper.create_variable_for_type_inference(dtype='bool')
            out.stop_gradient = True

            helper.append_op(
                type='not_equal',
                inputs={'X': [x],
                        'Y': [y]},
                outputs={'Out': [out]})
            return out
Z
zhulei 已提交
468 469 470 471 472


def is_tensor(x):
    """

C
chentianyu03 已提交
473
    This function tests whether input object is a paddle.Tensor.
Z
zhulei 已提交
474 475 476 477 478

    Args:
        x (object): Object to test.

    Returns:
C
chentianyu03 已提交
479
        A boolean value. True if 'x' is a paddle.Tensor, otherwise False.
Z
zhulei 已提交
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494

    Examples:
        .. code-block:: python

            import paddle

            input1 = paddle.rand(shape=[2, 3, 5], dtype='float32')
            check = paddle.is_tensor(input1)
            print(check)  #True

            input3 = [1, 4]
            check = paddle.is_tensor(input3)
            print(check)  #False
            
    """
H
hong 已提交
495
    return isinstance(x, (Tensor, paddle.fluid.core.eager.Tensor))
496 497 498


def _bitwise_op(op_name, x, y, out=None, name=None, binary_op=True):
Z
zhiboniu 已提交
499
    if paddle.in_dynamic_mode():
W
wanghuancoder 已提交
500
        op = getattr(_C_ops, op_name)
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
        if binary_op:
            return op(x, y)
        else:
            return op(x)

    check_variable_and_dtype(
        x, "x", ["bool", "uint8", "int8", "int16", "int32", "int64"], op_name)
    if y is not None:
        check_variable_and_dtype(
            y, "y", ["bool", "uint8", "int8", "int16", "int32", "int64"],
            op_name)
    if out is not None:
        check_type(out, "out", Variable, op_name)

    helper = LayerHelper(op_name, **locals())
    if binary_op:
        assert x.dtype == y.dtype

    if out is None:
        out = helper.create_variable_for_type_inference(dtype=x.dtype)

    if binary_op:
        helper.append_op(
            type=op_name, inputs={"X": x,
                                  "Y": y}, outputs={"Out": out})
    else:
        helper.append_op(type=op_name, inputs={"X": x}, outputs={"Out": out})

    return out


@templatedoc()
def bitwise_and(x, y, out=None, name=None):
    """
    ${comment}
    
    Args:
        x (Tensor): ${x_comment}
        y (Tensor): ${y_comment}
        out(Tensor): ${out_comment}

    Returns:
        Tensor: ${out_comment}
        
    Examples:
        .. code-block:: python

            import paddle
            x = paddle.to_tensor([-5, -1, 1])
            y = paddle.to_tensor([4,  2, -3])
            res = paddle.bitwise_and(x, y)
            print(res)  # [0, 2, 1]
    """
0
0x45f 已提交
554
    if in_dygraph_mode() and out is None:
H
hong 已提交
555
        return _C_ops.final_state_bitwise_and(x, y)
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
    return _bitwise_op(
        op_name="bitwise_and", x=x, y=y, name=name, out=out, binary_op=True)


@templatedoc()
def bitwise_or(x, y, out=None, name=None):
    """
    ${comment}
    
    Args:
        x (Tensor): ${x_comment}
        y (Tensor): ${y_comment}
        out(Tensor): ${out_comment}

    Returns:
        Tensor: ${out_comment}

    Examples:
        .. code-block:: python

            import paddle
            x = paddle.to_tensor([-5, -1, 1])
            y = paddle.to_tensor([4,  2, -3])
            res = paddle.bitwise_or(x, y)
            print(res)  # [-1, -1, -3]
    """
0
0x45f 已提交
582
    if in_dygraph_mode() and out is None:
H
hong 已提交
583 584
        return _C_ops.final_state_bitwise_or(x, y)

585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610
    return _bitwise_op(
        op_name="bitwise_or", x=x, y=y, name=name, out=out, binary_op=True)


@templatedoc()
def bitwise_xor(x, y, out=None, name=None):
    """
    ${comment}

    Args:
        x (Tensor): ${x_comment}
        y (Tensor): ${y_comment}
        out(Tensor): ${out_comment}

    Returns:
        Tensor: ${out_comment}

    Examples:
        .. code-block:: python

            import paddle
            x = paddle.to_tensor([-5, -1, 1])
            y = paddle.to_tensor([4,  2, -3])
            res = paddle.bitwise_xor(x, y)
            print(res) # [-1, -3, -4]
    """
0
0x45f 已提交
611
    if in_dygraph_mode() and out is None:
H
hong 已提交
612
        return _C_ops.final_state_bitwise_xor(x, y)
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
    return _bitwise_op(
        op_name="bitwise_xor", x=x, y=y, name=name, out=out, binary_op=True)


@templatedoc()
def bitwise_not(x, out=None, name=None):
    """
    ${comment}

    Args:
        x(Tensor):  ${x_comment}
        out(Tensor): ${out_comment}
    
    Returns:
        Tensor: ${out_comment}

    Examples:
        .. code-block:: python

            import paddle
            x = paddle.to_tensor([-5, -1, 1])
            res = paddle.bitwise_not(x)
            print(res) # [4, 0, -2]
    """
0
0x45f 已提交
637
    if in_dygraph_mode() and out is None:
H
hong 已提交
638
        return _C_ops.final_state_bitwise_not(x)
639 640 641

    return _bitwise_op(
        op_name="bitwise_not", x=x, y=None, name=name, out=out, binary_op=False)
A
andyjpaddle 已提交
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695


@templatedoc()
def isclose(x, y, rtol=1e-05, atol=1e-08, equal_nan=False, name=None):
    """
    ${comment}

    Args:
        x(Tensor): ${input_comment}.
        y(Tensor): ${other_comment}.
        rtol(rtoltype, optional): The relative tolerance. Default: :math:`1e-5` .
        atol(atoltype, optional): The absolute tolerance. Default: :math:`1e-8` .
        equal_nan(equalnantype, optional): ${equal_nan_comment}.
        name (str, optional): Name for the operation. For more information, please
            refer to :ref:`api_guide_Name`. Default: None.

    Returns:
        Tensor: ${out_comment}.

    Raises:
        TypeError: The data type of ``x`` must be one of float32, float64.
        TypeError: The data type of ``y`` must be one of float32, float64.
        TypeError: The type of ``rtol`` must be float.
        TypeError: The type of ``atol`` must be float.
        TypeError: The type of ``equal_nan`` must be bool.

    Examples:
        .. code-block:: python

          import paddle

          x = paddle.to_tensor([10000., 1e-07])
          y = paddle.to_tensor([10000.1, 1e-08])
          result1 = paddle.isclose(x, y, rtol=1e-05, atol=1e-08,
                                  equal_nan=False, name="ignore_nan")
          np_result1 = result1.numpy()
          # [True, False]
          result2 = paddle.isclose(x, y, rtol=1e-05, atol=1e-08,
                                      equal_nan=True, name="equal_nan")
          np_result2 = result2.numpy()
          # [True, False]

          x = paddle.to_tensor([1.0, float('nan')])
          y = paddle.to_tensor([1.0, float('nan')])
          result1 = paddle.isclose(x, y, rtol=1e-05, atol=1e-08,
                                  equal_nan=False, name="ignore_nan")
          np_result1 = result1.numpy()
          # [True, False]
          result2 = paddle.isclose(x, y, rtol=1e-05, atol=1e-08,
                                      equal_nan=True, name="equal_nan")
          np_result2 = result2.numpy()
          # [True, True]
    """

696
    if in_dygraph_mode():
697 698 699 700 701 702
        # NOTE(dev): Pass tol as Tensor to fix precision loss problem, because
        # C++ backend will cast it into float32 if passing float from python.
        as_tensor = lambda x: paddle.to_tensor([x], dtype='float64', place='cpu')
        return _C_ops.final_state_isclose(x, y,
                                          as_tensor(rtol),
                                          as_tensor(atol), equal_nan)
703
    if _in_legacy_dygraph():
A
andyjpaddle 已提交
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
        return _C_ops.isclose(x, y, 'rtol',
                              str(rtol), 'atol',
                              str(atol), 'equal_nan', equal_nan)

    check_variable_and_dtype(x, "input", ['float32', 'float64'], 'isclose')
    check_variable_and_dtype(y, "input", ['float32', 'float64'], 'isclose')
    check_type(rtol, 'rtol', float, 'isclose')
    check_type(atol, 'atol', float, 'isclose')
    check_type(equal_nan, 'equal_nan', bool, 'isclose')

    helper = LayerHelper("isclose", **locals())
    out = helper.create_variable_for_type_inference(dtype='bool')

    inputs = {'Input': x, 'Other': y}
    outputs = {'Out': out}
    attrs = {'rtol': str(rtol), 'atol': str(atol), 'equal_nan': equal_nan}
    helper.append_op(
        type='isclose', inputs=inputs, outputs=outputs, attrs=attrs)
    return out