From e71d2a33c8b7a002c7a3ddba8c5b83fb958d9439 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Thu, 25 Jan 2024 06:48:09 +0000 Subject: [PATCH 01/34] add type promotion for complex and real number. --- .../generator/eager_gen.py | 10 + paddle/fluid/pybind/eager_math_op_patch.cc | 360 +----------------- paddle/phi/common/type_promotion.h | 48 ++- python/paddle/base/framework.py | 13 + 4 files changed, 80 insertions(+), 351 deletions(-) diff --git a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py index 8555519778e3f..a694538dbc70f 100644 --- a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py +++ b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py @@ -80,7 +80,17 @@ type_promote_white_list = { "add": ["x", "y"], "subtract": ["x", "y"], + "divide": ["x", "y"], + "floor_divide": ["x", "y"], + "elementwise_pow": ["x", "y"], "where": ["x", "y"], + "equal": ["x", "y"], + "not_equal": ["x", "y"], + "less_than": ["x", "y"], + "less_equal": ["x", "y"], + "greater_than": ["x", "y"], + "greater_equal": ["x", "y"], + "matmul": ["x", "y"], } # dict of special api that forward api's output will affect bacward api's output diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index 8598e8841b371..99aaf29e4812f 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -263,37 +263,7 @@ static PyObject* tensor__add__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to add_ad_func - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype && !phi::NeedTypePromotion(lhs_dtype, rhs_dtype)) { - // note: only op_type in _supported_promote_complex_types_ should promote - // dtype - if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - phi::DataType promote_dtype = - framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - framework::TransToProtoVarType(lhs_dtype), - framework::TransToProtoVarType(rhs_dtype))); - if (lhs_dtype != promote_dtype) { - // cast - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, promote_dtype); - } - if (rhs_dtype != promote_dtype) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, promote_dtype); - } - } else { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling add_ad_func in tensor__add__method"; @@ -381,35 +351,7 @@ static PyObject* tensor__sub__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to subtract_ad_func - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype && !phi::NeedTypePromotion(lhs_dtype, rhs_dtype)) { - if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - phi::DataType promote_dtype = - framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - framework::TransToProtoVarType(lhs_dtype), - framework::TransToProtoVarType(rhs_dtype))); - if (lhs_dtype != promote_dtype) { - // cast - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, promote_dtype); - } - if (rhs_dtype != promote_dtype) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, promote_dtype); - } - } else { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling subtract_ad_func in tensor__sub__method"; @@ -495,35 +437,7 @@ static PyObject* tensor__rsub__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to subtract_ad_func - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype && !phi::NeedTypePromotion(lhs_dtype, rhs_dtype)) { - if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - phi::DataType promote_dtype = - framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - framework::TransToProtoVarType(lhs_dtype), - framework::TransToProtoVarType(rhs_dtype))); - if (lhs_dtype != promote_dtype) { - // cast - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, promote_dtype); - } - if (rhs_dtype != promote_dtype) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, promote_dtype); - } - } else { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling subtract_ad_func in tensor__rsub__method"; @@ -618,37 +532,7 @@ static PyObject* tensor__mul__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to multiply_ad_func - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype && !phi::NeedTypePromotion(lhs_dtype, rhs_dtype)) { - // note: only op_type in _supported_promote_complex_types_ should promote - // dtype - if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - phi::DataType promote_dtype = - framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - framework::TransToProtoVarType(lhs_dtype), - framework::TransToProtoVarType(rhs_dtype))); - if (lhs_dtype != promote_dtype) { - // cast - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, promote_dtype); - } - if (rhs_dtype != promote_dtype) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, promote_dtype); - } - } else { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling multiply_ad_func in tensor__mul__method"; @@ -740,46 +624,7 @@ static PyObject* tensor__div__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - // note: only op_type in _supported_promote_complex_types_ should promote - // dtype - if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - phi::DataType promote_dtype = - framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - framework::TransToProtoVarType(lhs_dtype), - framework::TransToProtoVarType(rhs_dtype))); - if (lhs_dtype != promote_dtype) { - // cast - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, promote_dtype); - } - if (rhs_dtype != promote_dtype) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, promote_dtype); - } - } else { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } - } - if (_supported_int_dtype_.find(self_tensor.dtype()) != - _supported_int_dtype_.end()) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - } - if (_supported_int_dtype_.find(other_tensor.dtype()) != - _supported_int_dtype_.end()) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, DataType::FLOAT32); - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling divide_ad_func in tensor__div__method"; @@ -879,46 +724,7 @@ static PyObject* tensor__rdiv__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - // note: only op_type in _supported_promote_complex_types_ should promote - // dtype - if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - phi::DataType promote_dtype = - framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - framework::TransToProtoVarType(lhs_dtype), - framework::TransToProtoVarType(rhs_dtype))); - if (lhs_dtype != promote_dtype) { - // cast - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, promote_dtype); - } - if (rhs_dtype != promote_dtype) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, promote_dtype); - } - } else { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } - } - if (_supported_int_dtype_.find(self_tensor.dtype()) != - _supported_int_dtype_.end()) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - } - if (_supported_int_dtype_.find(other_tensor.dtype()) != - _supported_int_dtype_.end()) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, DataType::FLOAT32); - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling divide_ad_func in tensor__rdiv__method"; @@ -1016,17 +822,7 @@ static PyObject* tensor__gt__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling greater_than_ad_func in tensor__gt__method"; @@ -1125,17 +921,7 @@ static PyObject* tensor__ge__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling greater_equal_ad_func in tensor__ge__method"; @@ -1235,17 +1021,7 @@ static PyObject* tensor__mod__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling remainder_ad_func in tensor__mod__method"; @@ -1342,36 +1118,7 @@ static PyObject* tensor__matmul__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - // note: only op_type in _supported_promote_complex_types_ should promote - // dtype - if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - phi::DataType promote_dtype = - framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - framework::TransToProtoVarType(lhs_dtype), - framework::TransToProtoVarType(rhs_dtype))); - if (lhs_dtype != promote_dtype) { - // cast - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, promote_dtype); - } - if (rhs_dtype != promote_dtype) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, promote_dtype); - } - } else { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling matmul_ad_func in tensor__matmul__method"; @@ -1469,17 +1216,7 @@ static PyObject* tensor__lt__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling less_than_ad_func in tensor__lt__method"; @@ -1578,17 +1315,7 @@ static PyObject* tensor__le__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling less_equal_ad_func in tensor__le__method"; @@ -1686,20 +1413,7 @@ static PyObject* tensor__floordiv__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - // note: only op_type in _supported_promote_complex_types_ should promote - // dtype, floordiv is not in _supported_promote_complex_types_, will not do - // promote dtype - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling floor_divide_ad_func in tensor__floordiv__method"; @@ -1788,17 +1502,7 @@ static PyObject* tensor__pow__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling elementwise_pow_ad_func in tensor__pow__method"; @@ -1899,17 +1603,7 @@ static PyObject* tensor__rpow__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling elementwise_pow_ad_func in tensor__rpow__method"; @@ -2006,17 +1700,7 @@ static PyObject* tensor__ne__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling not_equal_ad_func in tensor__ne__method"; @@ -2113,17 +1797,7 @@ static PyObject* tensor__eq__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // 3. type promotion will be automatically performed in add_ad_func // 4. calculation VLOG(6) << "Calling equal_ad_func in tensor__eq__method"; diff --git a/paddle/phi/common/type_promotion.h b/paddle/phi/common/type_promotion.h index fdb3f1e717faf..9dffca520cbe1 100644 --- a/paddle/phi/common/type_promotion.h +++ b/paddle/phi/common/type_promotion.h @@ -82,7 +82,7 @@ inline static DataType promoteTypes(DataType x, DataType y) { return _promoteTypesLookup[DataTypeToNum(x)][DataTypeToNum(y)]; } -static inline bool is_support_float(DataType dtype) { +inline bool is_support_float(DataType dtype) { if (dtype == DataType::FLOAT16 || dtype == DataType::FLOAT32 || dtype == DataType::FLOAT64 || dtype == DataType::BFLOAT16) { return true; @@ -91,22 +91,54 @@ static inline bool is_support_float(DataType dtype) { } } +inline bool is_support_complex(DataType dtype) { + if (dtype == DataType::COMPLEX64 || dtype == DataType::COMPLEX128) { + return true; + } else { + return false; + } +} + +inline DataType ComplexToFloat(DataType dtype) { + if (dtype == DataType::COMPLEX64) { + return DataType::FLOAT32; + } else if (dtype == DataType::COMPLEX128) { + return DataType::FLOAT64; + } else { + return dtype; + } +} + inline phi::DataType GetPromoteDtype(const std::string& op_name, const DataType x, const DataType y) { - // future will deal this by different rule - if (op_name == "greater_than") { - // bool logic - return DataType::BOOL; + // complex will be cast to float + if (op_name == "l1_loss" || op_name == "smooth_l1_loss" || + op_name == "mse_loss") { + return phi::promoteTypes(ComplexToFloat(x), ComplexToFloat(y)); } else { + // use default rule return phi::promoteTypes(x, y); } } inline bool NeedTypePromotion(const DataType x, const DataType y) { - // Tensor + Tensor only support type promotion for float type - if ((x != y) && is_support_float(x) && is_support_float(y)) { - return true; + // Tensor + Tensor type promotion only support calculations between + // floating-point numbers and between complex and real numbers. + if (x != y) { + if ((is_support_float(x) && is_support_float(y)) || + (is_support_complex(x) || is_support_complex(y))) { + return true; + } else { + PD_THROW( + "Type promotion only support calculations between floating-point " + "numbers and between complex and real numbers. But got different " + "data type x: `", + x, + "` y: `", + y, + "`."); + } } else { return false; } diff --git a/python/paddle/base/framework.py b/python/paddle/base/framework.py index cc5c231158d03..0dbbc15005d6b 100644 --- a/python/paddle/base/framework.py +++ b/python/paddle/base/framework.py @@ -63,8 +63,21 @@ "elementwise_sub_grad": ['X', 'Y'], "elementwise_mul": ['X', 'Y'], "elementwise_mul_grad": ['X', 'Y'], + "elementwise_div": ['X', 'Y'], + "elementwise_div_grad": ['X', 'Y'], + "elementwise_floordiv": ['X', 'Y'], + "elementwise_floordiv_grad": ['X', 'Y'], + "elementwise_pow": ['X', 'Y'], + "elementwise_pow_grad": ['X', 'Y'], "where": ['X', 'Y'], "where_grad": ['X', 'Y'], + "equal": ['X', 'Y'], + "not_equal": ['X', 'Y'], + "less_than": ['X', 'Y'], + "less_equal": ['X', 'Y'], + "greater_than": ['X', 'Y'], + "greater_equal": ['X', 'Y'], + "matmul_v2": ['X', 'Y'], } From b5b54d686c291fbcb1661386b5760700b4185649 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Thu, 25 Jan 2024 09:37:10 +0000 Subject: [PATCH 02/34] fix --- paddle/fluid/eager/auto_code_generator/generator/eager_gen.py | 1 + python/paddle/base/framework.py | 1 + 2 files changed, 2 insertions(+) diff --git a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py index a694538dbc70f..654f7ff370d0c 100644 --- a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py +++ b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py @@ -1604,6 +1604,7 @@ def GenerateForwardDefinitionAndDeclaration(self, is_inplaced): for name, atype, default_val, pos in forward_attrs_list: inputs_call_list[pos] = name amp_inputs_call_list[pos] = name + type_promote_inputs_call_list[pos] = name if default_val is not None: inputs_args_declaration_list[ pos diff --git a/python/paddle/base/framework.py b/python/paddle/base/framework.py index 0dbbc15005d6b..f2a3a007ac306 100644 --- a/python/paddle/base/framework.py +++ b/python/paddle/base/framework.py @@ -78,6 +78,7 @@ "greater_than": ['X', 'Y'], "greater_equal": ['X', 'Y'], "matmul_v2": ['X', 'Y'], + "matmul_v2_grad": ['X', 'Y'], } From 828b92bd2127e74bd21ed86c7b2e96bbfcc6f31b Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Fri, 26 Jan 2024 02:52:24 +0000 Subject: [PATCH 03/34] reduce api support --- .../generator/eager_gen.py | 10 - paddle/fluid/pybind/eager_math_op_patch.cc | 364 +++++++++++++++++- python/paddle/base/framework.py | 14 - 3 files changed, 347 insertions(+), 41 deletions(-) diff --git a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py index 654f7ff370d0c..4d61d5e06a891 100644 --- a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py +++ b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py @@ -80,17 +80,7 @@ type_promote_white_list = { "add": ["x", "y"], "subtract": ["x", "y"], - "divide": ["x", "y"], - "floor_divide": ["x", "y"], - "elementwise_pow": ["x", "y"], "where": ["x", "y"], - "equal": ["x", "y"], - "not_equal": ["x", "y"], - "less_than": ["x", "y"], - "less_equal": ["x", "y"], - "greater_than": ["x", "y"], - "greater_equal": ["x", "y"], - "matmul": ["x", "y"], } # dict of special api that forward api's output will affect bacward api's output diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index 99aaf29e4812f..1a481b5427952 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -263,7 +263,38 @@ static PyObject* tensor__add__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var, float type promotion + // mv to add_ad_func + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype && !phi::NeedTypePromotion(lhs_dtype, + // rhs_dtype)) { + // // note: only op_type in _supported_promote_complex_types_ should promote + // // dtype + // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || + // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { + // phi::DataType promote_dtype = + // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( + // framework::TransToProtoVarType(lhs_dtype), + // framework::TransToProtoVarType(rhs_dtype))); + // if (lhs_dtype != promote_dtype) { + // // cast + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, promote_dtype); + // } + // if (rhs_dtype != promote_dtype) { + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, promote_dtype); + // } + // } else { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } + // } // 4. calculation VLOG(6) << "Calling add_ad_func in tensor__add__method"; @@ -351,7 +382,36 @@ static PyObject* tensor__sub__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var, float type promotion + // mv to subtract_ad_func + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype && !phi::NeedTypePromotion(lhs_dtype, + // rhs_dtype)) { + // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || + // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { + // phi::DataType promote_dtype = + // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( + // framework::TransToProtoVarType(lhs_dtype), + // framework::TransToProtoVarType(rhs_dtype))); + // if (lhs_dtype != promote_dtype) { + // // cast + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, promote_dtype); + // } + // if (rhs_dtype != promote_dtype) { + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, promote_dtype); + // } + // } else { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } + // } // 4. calculation VLOG(6) << "Calling subtract_ad_func in tensor__sub__method"; @@ -437,7 +497,36 @@ static PyObject* tensor__rsub__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var, float type promotion + // mv to subtract_ad_func + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype && !phi::NeedTypePromotion(lhs_dtype, + // rhs_dtype)) { + // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || + // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { + // phi::DataType promote_dtype = + // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( + // framework::TransToProtoVarType(lhs_dtype), + // framework::TransToProtoVarType(rhs_dtype))); + // if (lhs_dtype != promote_dtype) { + // // cast + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, promote_dtype); + // } + // if (rhs_dtype != promote_dtype) { + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, promote_dtype); + // } + // } else { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } + // } // 4. calculation VLOG(6) << "Calling subtract_ad_func in tensor__rsub__method"; @@ -532,7 +621,38 @@ static PyObject* tensor__mul__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var, float type promotion + // mv to multiply_ad_func + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype && !phi::NeedTypePromotion(lhs_dtype, + // rhs_dtype)) { + // // note: only op_type in _supported_promote_complex_types_ should promote + // // dtype + // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || + // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { + // phi::DataType promote_dtype = + // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( + // framework::TransToProtoVarType(lhs_dtype), + // framework::TransToProtoVarType(rhs_dtype))); + // if (lhs_dtype != promote_dtype) { + // // cast + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, promote_dtype); + // } + // if (rhs_dtype != promote_dtype) { + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, promote_dtype); + // } + // } else { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } + // } // 4. calculation VLOG(6) << "Calling multiply_ad_func in tensor__mul__method"; @@ -624,7 +744,46 @@ static PyObject* tensor__div__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + // note: only op_type in _supported_promote_complex_types_ should promote + // dtype + if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || + _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { + phi::DataType promote_dtype = + framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( + framework::TransToProtoVarType(lhs_dtype), + framework::TransToProtoVarType(rhs_dtype))); + if (lhs_dtype != promote_dtype) { + // cast + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, promote_dtype); + } + if (rhs_dtype != promote_dtype) { + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, promote_dtype); + } + } else { + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } + } + if (_supported_int_dtype_.find(self_tensor.dtype()) != + _supported_int_dtype_.end()) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + } + if (_supported_int_dtype_.find(other_tensor.dtype()) != + _supported_int_dtype_.end()) { + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, DataType::FLOAT32); + } // 4. calculation VLOG(6) << "Calling divide_ad_func in tensor__div__method"; @@ -724,7 +883,46 @@ static PyObject* tensor__rdiv__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + // note: only op_type in _supported_promote_complex_types_ should promote + // dtype + if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || + _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { + phi::DataType promote_dtype = + framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( + framework::TransToProtoVarType(lhs_dtype), + framework::TransToProtoVarType(rhs_dtype))); + if (lhs_dtype != promote_dtype) { + // cast + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, promote_dtype); + } + if (rhs_dtype != promote_dtype) { + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, promote_dtype); + } + } else { + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } + } + if (_supported_int_dtype_.find(self_tensor.dtype()) != + _supported_int_dtype_.end()) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + } + if (_supported_int_dtype_.find(other_tensor.dtype()) != + _supported_int_dtype_.end()) { + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, DataType::FLOAT32); + } // 4. calculation VLOG(6) << "Calling divide_ad_func in tensor__rdiv__method"; @@ -822,7 +1020,17 @@ static PyObject* tensor__gt__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } // 4. calculation VLOG(6) << "Calling greater_than_ad_func in tensor__gt__method"; @@ -921,7 +1129,17 @@ static PyObject* tensor__ge__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } // 4. calculation VLOG(6) << "Calling greater_equal_ad_func in tensor__ge__method"; @@ -1021,7 +1239,17 @@ static PyObject* tensor__mod__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } // 4. calculation VLOG(6) << "Calling remainder_ad_func in tensor__mod__method"; @@ -1118,7 +1346,36 @@ static PyObject* tensor__matmul__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + // note: only op_type in _supported_promote_complex_types_ should promote + // dtype + if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || + _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { + phi::DataType promote_dtype = + framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( + framework::TransToProtoVarType(lhs_dtype), + framework::TransToProtoVarType(rhs_dtype))); + if (lhs_dtype != promote_dtype) { + // cast + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, promote_dtype); + } + if (rhs_dtype != promote_dtype) { + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, promote_dtype); + } + } else { + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } + } // 4. calculation VLOG(6) << "Calling matmul_ad_func in tensor__matmul__method"; @@ -1216,7 +1473,17 @@ static PyObject* tensor__lt__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } // 4. calculation VLOG(6) << "Calling less_than_ad_func in tensor__lt__method"; @@ -1315,7 +1582,17 @@ static PyObject* tensor__le__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } // 4. calculation VLOG(6) << "Calling less_equal_ad_func in tensor__le__method"; @@ -1413,7 +1690,20 @@ static PyObject* tensor__floordiv__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + // note: only op_type in _supported_promote_complex_types_ should promote + // dtype, floordiv is not in _supported_promote_complex_types_, will not do + // promote dtype + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } // 4. calculation VLOG(6) << "Calling floor_divide_ad_func in tensor__floordiv__method"; @@ -1502,7 +1792,17 @@ static PyObject* tensor__pow__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } // 4. calculation VLOG(6) << "Calling elementwise_pow_ad_func in tensor__pow__method"; @@ -1603,7 +1903,17 @@ static PyObject* tensor__rpow__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } // 4. calculation VLOG(6) << "Calling elementwise_pow_ad_func in tensor__rpow__method"; @@ -1700,7 +2010,17 @@ static PyObject* tensor__ne__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } // 4. calculation VLOG(6) << "Calling not_equal_ad_func in tensor__ne__method"; @@ -1797,7 +2117,17 @@ static PyObject* tensor__eq__method(TensorObject* self, } } - // 3. type promotion will be automatically performed in add_ad_func + // 3. promote types or unify right var type to left var + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } // 4. calculation VLOG(6) << "Calling equal_ad_func in tensor__eq__method"; diff --git a/python/paddle/base/framework.py b/python/paddle/base/framework.py index f2a3a007ac306..cc5c231158d03 100644 --- a/python/paddle/base/framework.py +++ b/python/paddle/base/framework.py @@ -63,22 +63,8 @@ "elementwise_sub_grad": ['X', 'Y'], "elementwise_mul": ['X', 'Y'], "elementwise_mul_grad": ['X', 'Y'], - "elementwise_div": ['X', 'Y'], - "elementwise_div_grad": ['X', 'Y'], - "elementwise_floordiv": ['X', 'Y'], - "elementwise_floordiv_grad": ['X', 'Y'], - "elementwise_pow": ['X', 'Y'], - "elementwise_pow_grad": ['X', 'Y'], "where": ['X', 'Y'], "where_grad": ['X', 'Y'], - "equal": ['X', 'Y'], - "not_equal": ['X', 'Y'], - "less_than": ['X', 'Y'], - "less_equal": ['X', 'Y'], - "greater_than": ['X', 'Y'], - "greater_equal": ['X', 'Y'], - "matmul_v2": ['X', 'Y'], - "matmul_v2_grad": ['X', 'Y'], } From 5b91d51716238ce0dd101a4cb2a2ed79b60c8a4b Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Tue, 30 Jan 2024 12:30:51 +0000 Subject: [PATCH 04/34] add more api support --- .../generator/eager_gen.py | 30 ++ paddle/fluid/pybind/eager_math_op_patch.cc | 433 +++++++++--------- python/paddle/base/framework.py | 59 ++- 3 files changed, 297 insertions(+), 225 deletions(-) diff --git a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py index 4d61d5e06a891..9abb41281ece8 100644 --- a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py +++ b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py @@ -77,12 +77,42 @@ # white ops list whose kernel can automaically do type promotion. # future will get this list from same place with static graph. +# type_promote_white_list = { +# "add": ["x", "y"], +# "subtract": ["x", "y"], +# "where": ["x", "y"], +# } type_promote_white_list = { "add": ["x", "y"], "subtract": ["x", "y"], + "divide": ["x", "y"], + "floor_divide": ["x", "y"], + "elementwise_pow": ["x", "y"], "where": ["x", "y"], + "equal": ["x", "y"], + "not_equal": ["x", "y"], + "less_than": ["x", "y"], + "less_equal": ["x", "y"], + "greater_than": ["x", "y"], + "greater_equal": ["x", "y"], + "matmul": ["x", "y"], + "logical_and": ["x", "y"], + "logical_or": ["x", "y"], + "logical_xor": ["x", "y"], + "bitwise_and": ["x", "y"], + "bitwise_or": ["x", "y"], + "bitwise_xor": ["x", "y"], + "fmax": ["x", "y"], + "fmin": ["x", "y"], + "maximum": ["x", "y"], + "minimum": ["x", "y"], + "remainder": ["x", "y"], + "huber_loss": ["input", "label"], + "nextafter": ["x", "y"], + "atan2": ["x", "y"], } + # dict of special api that forward api's output will affect bacward api's output # bacward api's output usually affected by backward api's input special_prune_dict = { diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index 1a481b5427952..ae4d93029b49a 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -745,45 +745,45 @@ static PyObject* tensor__div__method(TensorObject* self, } // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - // note: only op_type in _supported_promote_complex_types_ should promote - // dtype - if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - phi::DataType promote_dtype = - framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - framework::TransToProtoVarType(lhs_dtype), - framework::TransToProtoVarType(rhs_dtype))); - if (lhs_dtype != promote_dtype) { - // cast - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, promote_dtype); - } - if (rhs_dtype != promote_dtype) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, promote_dtype); - } - } else { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } - } - if (_supported_int_dtype_.find(self_tensor.dtype()) != - _supported_int_dtype_.end()) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - } - if (_supported_int_dtype_.find(other_tensor.dtype()) != - _supported_int_dtype_.end()) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, DataType::FLOAT32); - } + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype) { + // // note: only op_type in _supported_promote_complex_types_ should promote + // // dtype + // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || + // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { + // phi::DataType promote_dtype = + // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( + // framework::TransToProtoVarType(lhs_dtype), + // framework::TransToProtoVarType(rhs_dtype))); + // if (lhs_dtype != promote_dtype) { + // // cast + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, promote_dtype); + // } + // if (rhs_dtype != promote_dtype) { + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, promote_dtype); + // } + // } else { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } + // } + // if (_supported_int_dtype_.find(self_tensor.dtype()) != + // _supported_int_dtype_.end()) { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + // } + // if (_supported_int_dtype_.find(other_tensor.dtype()) != + // _supported_int_dtype_.end()) { + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, DataType::FLOAT32); + // } // 4. calculation VLOG(6) << "Calling divide_ad_func in tensor__div__method"; @@ -884,45 +884,45 @@ static PyObject* tensor__rdiv__method(TensorObject* self, } // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - // note: only op_type in _supported_promote_complex_types_ should promote - // dtype - if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - phi::DataType promote_dtype = - framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - framework::TransToProtoVarType(lhs_dtype), - framework::TransToProtoVarType(rhs_dtype))); - if (lhs_dtype != promote_dtype) { - // cast - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, promote_dtype); - } - if (rhs_dtype != promote_dtype) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, promote_dtype); - } - } else { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } - } - if (_supported_int_dtype_.find(self_tensor.dtype()) != - _supported_int_dtype_.end()) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - } - if (_supported_int_dtype_.find(other_tensor.dtype()) != - _supported_int_dtype_.end()) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, DataType::FLOAT32); - } + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype) { + // // note: only op_type in _supported_promote_complex_types_ should promote + // // dtype + // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || + // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { + // phi::DataType promote_dtype = + // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( + // framework::TransToProtoVarType(lhs_dtype), + // framework::TransToProtoVarType(rhs_dtype))); + // if (lhs_dtype != promote_dtype) { + // // cast + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, promote_dtype); + // } + // if (rhs_dtype != promote_dtype) { + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, promote_dtype); + // } + // } else { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } + // } + // if (_supported_int_dtype_.find(self_tensor.dtype()) != + // _supported_int_dtype_.end()) { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + // } + // if (_supported_int_dtype_.find(other_tensor.dtype()) != + // _supported_int_dtype_.end()) { + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, DataType::FLOAT32); + // } // 4. calculation VLOG(6) << "Calling divide_ad_func in tensor__rdiv__method"; @@ -1021,16 +1021,16 @@ static PyObject* tensor__gt__method(TensorObject* self, } // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype) { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } // 4. calculation VLOG(6) << "Calling greater_than_ad_func in tensor__gt__method"; @@ -1130,16 +1130,16 @@ static PyObject* tensor__ge__method(TensorObject* self, } // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype) { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } // 4. calculation VLOG(6) << "Calling greater_equal_ad_func in tensor__ge__method"; @@ -1240,16 +1240,16 @@ static PyObject* tensor__mod__method(TensorObject* self, } // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype) { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } // 4. calculation VLOG(6) << "Calling remainder_ad_func in tensor__mod__method"; @@ -1347,35 +1347,35 @@ static PyObject* tensor__matmul__method(TensorObject* self, } // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - // note: only op_type in _supported_promote_complex_types_ should promote - // dtype - if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - phi::DataType promote_dtype = - framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - framework::TransToProtoVarType(lhs_dtype), - framework::TransToProtoVarType(rhs_dtype))); - if (lhs_dtype != promote_dtype) { - // cast - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, promote_dtype); - } - if (rhs_dtype != promote_dtype) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, promote_dtype); - } - } else { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } - } + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype) { + // // note: only op_type in _supported_promote_complex_types_ should promote + // // dtype + // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || + // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { + // phi::DataType promote_dtype = + // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( + // framework::TransToProtoVarType(lhs_dtype), + // framework::TransToProtoVarType(rhs_dtype))); + // if (lhs_dtype != promote_dtype) { + // // cast + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, promote_dtype); + // } + // if (rhs_dtype != promote_dtype) { + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, promote_dtype); + // } + // } else { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } + // } // 4. calculation VLOG(6) << "Calling matmul_ad_func in tensor__matmul__method"; @@ -1474,23 +1474,23 @@ static PyObject* tensor__lt__method(TensorObject* self, } // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype) { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } - // 4. calculation - VLOG(6) << "Calling less_than_ad_func in tensor__lt__method"; - { - eager_gil_scoped_release guard; - ret = less_than_ad_func(self_tensor, other_tensor); - } + // // 4. calculation + // VLOG(6) << "Calling less_than_ad_func in tensor__lt__method"; + // { + // eager_gil_scoped_release guard; + // ret = less_than_ad_func(self_tensor, other_tensor); + // } return ToPyObject(ret); EAGER_CATCH_AND_THROW_RETURN_NULL @@ -1583,16 +1583,16 @@ static PyObject* tensor__le__method(TensorObject* self, } // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype) { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } // 4. calculation VLOG(6) << "Calling less_equal_ad_func in tensor__le__method"; @@ -1691,19 +1691,20 @@ static PyObject* tensor__floordiv__method(TensorObject* self, } // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - // note: only op_type in _supported_promote_complex_types_ should promote - // dtype, floordiv is not in _supported_promote_complex_types_, will not do - // promote dtype - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype) { + // // note: only op_type in _supported_promote_complex_types_ should promote + // // dtype, floordiv is not in _supported_promote_complex_types_, will not + // do + // // promote dtype + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } // 4. calculation VLOG(6) << "Calling floor_divide_ad_func in tensor__floordiv__method"; @@ -1793,16 +1794,16 @@ static PyObject* tensor__pow__method(TensorObject* self, } // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype) { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } // 4. calculation VLOG(6) << "Calling elementwise_pow_ad_func in tensor__pow__method"; @@ -1904,16 +1905,16 @@ static PyObject* tensor__rpow__method(TensorObject* self, } // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype) { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } // 4. calculation VLOG(6) << "Calling elementwise_pow_ad_func in tensor__rpow__method"; @@ -2011,16 +2012,16 @@ static PyObject* tensor__ne__method(TensorObject* self, } // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype) { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } // 4. calculation VLOG(6) << "Calling not_equal_ad_func in tensor__ne__method"; @@ -2118,16 +2119,16 @@ static PyObject* tensor__eq__method(TensorObject* self, } // 3. promote types or unify right var type to left var - phi::DataType lhs_dtype = self_tensor.dtype(); - phi::DataType rhs_dtype = other_tensor.dtype(); - if (lhs_dtype != rhs_dtype) { - VLOG(6) << "The dtype of left and right Tensor are not the same, left " - "dtype is " - << lhs_dtype << ", but right dtype is " << rhs_dtype - << ", the right dtype will convert to " << lhs_dtype; - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, lhs_dtype); - } + // phi::DataType lhs_dtype = self_tensor.dtype(); + // phi::DataType rhs_dtype = other_tensor.dtype(); + // if (lhs_dtype != rhs_dtype) { + // VLOG(6) << "The dtype of left and right Tensor are not the same, left " + // "dtype is " + // << lhs_dtype << ", but right dtype is " << rhs_dtype + // << ", the right dtype will convert to " << lhs_dtype; + // eager_gil_scoped_release guard; + // other_tensor = cast_ad_func(other_tensor, lhs_dtype); + // } // 4. calculation VLOG(6) << "Calling equal_ad_func in tensor__eq__method"; diff --git a/python/paddle/base/framework.py b/python/paddle/base/framework.py index cc5c231158d03..9f97a076e732e 100644 --- a/python/paddle/base/framework.py +++ b/python/paddle/base/framework.py @@ -36,6 +36,7 @@ from .. import pir from . import core, unique_name +from .data_feeder import _PADDLE_DTYPE_2_NUMPY_DTYPE from .libpaddle import DataType from .proto import ( data_feed_pb2, # noqa: F401 @@ -56,6 +57,17 @@ CONTROL_DEP_VAR_PREFIX = core.kControlDepVarName() _global_flags_ = core.globals() +# SUPPORT_PROMOTION_OPS_AND_INPUTNAME = { +# "elementwise_add": ['X', 'Y'], +# "elementwise_add_grad": ['X', 'Y'], +# "elementwise_sub": ['X', 'Y'], +# "elementwise_sub_grad": ['X', 'Y'], +# "elementwise_mul": ['X', 'Y'], +# "elementwise_mul_grad": ['X', 'Y'], +# "where": ['X', 'Y'], +# "where_grad": ['X', 'Y'], +# } + SUPPORT_PROMOTION_OPS_AND_INPUTNAME = { "elementwise_add": ['X', 'Y'], "elementwise_add_grad": ['X', 'Y'], @@ -63,8 +75,42 @@ "elementwise_sub_grad": ['X', 'Y'], "elementwise_mul": ['X', 'Y'], "elementwise_mul_grad": ['X', 'Y'], + "elementwise_div": ['X', 'Y'], + "elementwise_div_grad": ['X', 'Y'], + "elementwise_floordiv": ['X', 'Y'], + "elementwise_floordiv_grad": ['X', 'Y'], + "elementwise_pow": ['X', 'Y'], + "elementwise_pow_grad": ['X', 'Y'], "where": ['X', 'Y'], "where_grad": ['X', 'Y'], + "equal": ['X', 'Y'], + "not_equal": ['X', 'Y'], + "less_than": ['X', 'Y'], + "less_equal": ['X', 'Y'], + "greater_than": ['X', 'Y'], + "greater_equal": ['X', 'Y'], + "matmul_v2": ['X', 'Y'], + "matmul_v2_grad": ['X', 'Y'], + "logical_and": ['X', 'Y'], + "logical_or": ['X', 'Y'], + "logical_xor": ['X', 'Y'], + "bitwise_and": ['X', 'Y'], + "bitwise_or": ['X', 'Y'], + "bitwise_xor": ['X', 'Y'], + "elementwise_fmax": ['X', 'Y'], + "elementwise_fmax_grad": ['X', 'Y'], + "elementwise_fmin": ['X', 'Y'], + "elementwise_fmin_grad": ['X', 'Y'], + "elementwise_max": ['X', 'Y'], + "elementwise_max_grad": ['X', 'Y'], + "elementwise_min": ['X', 'Y'], + "elementwise_min_grad": ['X', 'Y'], + "elementwise_mod": ['X', 'Y'], + "huber_loss": ['input', 'label'], + "huber_loss_grad": ['input', 'label'], + "nextafter": ['x', 'y'], + "atan2": ['X1', 'X2'], + "atan2_grad": ['X1', 'X2'], } @@ -8155,16 +8201,11 @@ def _get_paddle_place_list(places): def dtype_to_str(in_dtype): - if in_dtype == core.VarDesc.VarType.FP16: - return "fp16" - elif in_dtype == core.VarDesc.VarType.BF16: - return "bf16" - elif in_dtype == core.VarDesc.VarType.FP32: - return "fp32" - elif in_dtype == core.VarDesc.VarType.FP64: - return "fp64" + if in_dtype == core.VarDesc.VarType.BF16: + # _PADDLE_DTYPE_2_NUMPY_DTYPE will trans bfloat16 to uint16. Can delete this if after same. + return "bfloat16" else: - return None + return _PADDLE_DTYPE_2_NUMPY_DTYPE[in_dtype] def add_cast_for_type_promotion(op, block, idx, var_name, out_dtype): From 5dd3ce1596105b68e163391df1573f03b54b2c62 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Tue, 30 Jan 2024 14:28:31 +0000 Subject: [PATCH 05/34] fix --- python/paddle/base/framework.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/python/paddle/base/framework.py b/python/paddle/base/framework.py index 9f97a076e732e..41955b3fd054c 100644 --- a/python/paddle/base/framework.py +++ b/python/paddle/base/framework.py @@ -36,7 +36,6 @@ from .. import pir from . import core, unique_name -from .data_feeder import _PADDLE_DTYPE_2_NUMPY_DTYPE from .libpaddle import DataType from .proto import ( data_feed_pb2, # noqa: F401 @@ -8201,11 +8200,20 @@ def _get_paddle_place_list(places): def dtype_to_str(in_dtype): - if in_dtype == core.VarDesc.VarType.BF16: - # _PADDLE_DTYPE_2_NUMPY_DTYPE will trans bfloat16 to uint16. Can delete this if after same. - return "bfloat16" + if in_dtype == core.VarDesc.VarType.FP16: + return "fp16" + elif in_dtype == core.VarDesc.VarType.BF16: + return "bf16" + elif in_dtype == core.VarDesc.VarType.FP32: + return "fp32" + elif in_dtype == core.VarDesc.VarType.FP64: + return "fp64" + elif in_dtype == core.VarDesc.VarType.COMPLEX64: + return "complex64" + elif in_dtype == core.VarDesc.VarType.COMPLEX128: + return "complex128" else: - return _PADDLE_DTYPE_2_NUMPY_DTYPE[in_dtype] + raise TypeError(f"got unspport data type for promotion: {in_dtype}.") def add_cast_for_type_promotion(op, block, idx, var_name, out_dtype): From bca1b67a2941e8ed43b80de8a74639556ebdd538 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Thu, 1 Feb 2024 08:11:34 +0000 Subject: [PATCH 06/34] fix --- paddle/fluid/pybind/eager_math_op_patch.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index ae4d93029b49a..6e257d8730b38 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -1486,11 +1486,11 @@ static PyObject* tensor__lt__method(TensorObject* self, // } // // 4. calculation - // VLOG(6) << "Calling less_than_ad_func in tensor__lt__method"; - // { - // eager_gil_scoped_release guard; - // ret = less_than_ad_func(self_tensor, other_tensor); - // } + VLOG(6) << "Calling less_than_ad_func in tensor__lt__method"; + { + eager_gil_scoped_release guard; + ret = less_than_ad_func(self_tensor, other_tensor); + } return ToPyObject(ret); EAGER_CATCH_AND_THROW_RETURN_NULL From e6f09f42cbd992bc498941f3a39fb5e4c2898c5e Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Mon, 5 Feb 2024 06:37:49 +0000 Subject: [PATCH 07/34] remove matmul --- paddle/fluid/eager/auto_code_generator/generator/eager_gen.py | 1 - python/paddle/base/framework.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py index 9abb41281ece8..891fc1c23f657 100644 --- a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py +++ b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py @@ -95,7 +95,6 @@ "less_equal": ["x", "y"], "greater_than": ["x", "y"], "greater_equal": ["x", "y"], - "matmul": ["x", "y"], "logical_and": ["x", "y"], "logical_or": ["x", "y"], "logical_xor": ["x", "y"], diff --git a/python/paddle/base/framework.py b/python/paddle/base/framework.py index 41955b3fd054c..3333c34bceaa5 100644 --- a/python/paddle/base/framework.py +++ b/python/paddle/base/framework.py @@ -88,8 +88,6 @@ "less_equal": ['X', 'Y'], "greater_than": ['X', 'Y'], "greater_equal": ['X', 'Y'], - "matmul_v2": ['X', 'Y'], - "matmul_v2_grad": ['X', 'Y'], "logical_and": ['X', 'Y'], "logical_or": ['X', 'Y'], "logical_xor": ['X', 'Y'], From 5f9c3f1e3cce82c90e4250255d92cf5f130effb9 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Wed, 28 Feb 2024 07:37:48 +0000 Subject: [PATCH 08/34] add T+S logic. --- paddle/fluid/pybind/eager_math_op_patch.cc | 900 +++++++++++------- paddle/fluid/pybind/pybind.cc | 8 +- paddle/phi/common/type_promotion.h | 36 +- python/paddle/base/framework.py | 11 - python/paddle/base/layers/math_op_patch.py | 57 +- python/paddle/nn/functional/loss.py | 12 +- test/dygraph_to_static/test_break_continue.py | 10 +- test/dygraph_to_static/test_tensor_methods.py | 1 + test/legacy_test/test_trapezoid.py | 2 +- 9 files changed, 654 insertions(+), 383 deletions(-) diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index 6e257d8730b38..e8ab047814974 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -228,10 +228,17 @@ static PyObject* tensor__add__method(TensorObject* self, ret = CallScalarFuction(self_tensor, other, "add"); } return ToPyObject(ret); + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj paddle::Tensor other_tensor; + if (PyCheckTensor(other_obj)) { auto& self_tensor_ref = self->tensor; auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); @@ -239,6 +246,31 @@ static PyObject* tensor__add__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "add", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -265,36 +297,6 @@ static PyObject* tensor__add__method(TensorObject* self, // 3. promote types or unify right var type to left var, float type promotion // mv to add_ad_func - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype && !phi::NeedTypePromotion(lhs_dtype, - // rhs_dtype)) { - // // note: only op_type in _supported_promote_complex_types_ should promote - // // dtype - // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - // phi::DataType promote_dtype = - // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - // framework::TransToProtoVarType(lhs_dtype), - // framework::TransToProtoVarType(rhs_dtype))); - // if (lhs_dtype != promote_dtype) { - // // cast - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, promote_dtype); - // } - // if (rhs_dtype != promote_dtype) { - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, promote_dtype); - // } - // } else { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } - // } // 4. calculation VLOG(6) << "Calling add_ad_func in tensor__add__method"; @@ -347,6 +349,12 @@ static PyObject* tensor__sub__method(TensorObject* self, } return ToPyObject(ret); + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -358,6 +366,31 @@ static PyObject* tensor__sub__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "subtract", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -384,34 +417,6 @@ static PyObject* tensor__sub__method(TensorObject* self, // 3. promote types or unify right var type to left var, float type promotion // mv to subtract_ad_func - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype && !phi::NeedTypePromotion(lhs_dtype, - // rhs_dtype)) { - // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - // phi::DataType promote_dtype = - // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - // framework::TransToProtoVarType(lhs_dtype), - // framework::TransToProtoVarType(rhs_dtype))); - // if (lhs_dtype != promote_dtype) { - // // cast - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, promote_dtype); - // } - // if (rhs_dtype != promote_dtype) { - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, promote_dtype); - // } - // } else { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } - // } // 4. calculation VLOG(6) << "Calling subtract_ad_func in tensor__sub__method"; @@ -462,6 +467,12 @@ static PyObject* tensor__rsub__method(TensorObject* self, ret = CallScalarFuction(self_tensor, other, "rsub"); } return ToPyObject(ret); + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -473,6 +484,31 @@ static PyObject* tensor__rsub__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "subtract", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -499,34 +535,6 @@ static PyObject* tensor__rsub__method(TensorObject* self, // 3. promote types or unify right var type to left var, float type promotion // mv to subtract_ad_func - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype && !phi::NeedTypePromotion(lhs_dtype, - // rhs_dtype)) { - // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - // phi::DataType promote_dtype = - // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - // framework::TransToProtoVarType(lhs_dtype), - // framework::TransToProtoVarType(rhs_dtype))); - // if (lhs_dtype != promote_dtype) { - // // cast - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, promote_dtype); - // } - // if (rhs_dtype != promote_dtype) { - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, promote_dtype); - // } - // } else { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } - // } // 4. calculation VLOG(6) << "Calling subtract_ad_func in tensor__rsub__method"; @@ -578,6 +586,12 @@ static PyObject* tensor__mul__method(TensorObject* self, ret = CallScalarFuction(self_tensor, other, "mul"); } return ToPyObject(ret); + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -591,6 +605,31 @@ static PyObject* tensor__mul__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "multiply", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -623,36 +662,6 @@ static PyObject* tensor__mul__method(TensorObject* self, // 3. promote types or unify right var type to left var, float type promotion // mv to multiply_ad_func - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype && !phi::NeedTypePromotion(lhs_dtype, - // rhs_dtype)) { - // // note: only op_type in _supported_promote_complex_types_ should promote - // // dtype - // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - // phi::DataType promote_dtype = - // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - // framework::TransToProtoVarType(lhs_dtype), - // framework::TransToProtoVarType(rhs_dtype))); - // if (lhs_dtype != promote_dtype) { - // // cast - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, promote_dtype); - // } - // if (rhs_dtype != promote_dtype) { - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, promote_dtype); - // } - // } else { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } - // } // 4. calculation VLOG(6) << "Calling multiply_ad_func in tensor__mul__method"; @@ -705,6 +714,12 @@ static PyObject* tensor__div__method(TensorObject* self, ret = CallScalarFuction(self_tensor, other, "div"); } return ToPyObject(ret); + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -716,6 +731,35 @@ static PyObject* tensor__div__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "divide", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } else if (is_support_int(self_tensor_ref.dtype()) && + self_tensor_ref.dtype() == other_tensor_ref.dtype()) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, DataType::FLOAT32); + other_tensor_ref = cast_ad_func(other_tensor_ref, DataType::FLOAT32); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -744,46 +788,8 @@ static PyObject* tensor__div__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype) { - // // note: only op_type in _supported_promote_complex_types_ should promote - // // dtype - // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - // phi::DataType promote_dtype = - // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - // framework::TransToProtoVarType(lhs_dtype), - // framework::TransToProtoVarType(rhs_dtype))); - // if (lhs_dtype != promote_dtype) { - // // cast - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, promote_dtype); - // } - // if (rhs_dtype != promote_dtype) { - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, promote_dtype); - // } - // } else { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } - // } - // if (_supported_int_dtype_.find(self_tensor.dtype()) != - // _supported_int_dtype_.end()) { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - // } - // if (_supported_int_dtype_.find(other_tensor.dtype()) != - // _supported_int_dtype_.end()) { - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, DataType::FLOAT32); - // } + // 3. promote types or unify right var type to left var, float type promotion + // mv to divide_ad_func // 4. calculation VLOG(6) << "Calling divide_ad_func in tensor__div__method"; @@ -834,6 +840,12 @@ static PyObject* tensor__rdiv__method(TensorObject* self, eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -855,6 +867,36 @@ static PyObject* tensor__rdiv__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "divide", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } + if (is_support_int(self_tensor_ref.dtype()) && + self_tensor_ref.dtype() == other_tensor_ref.dtype()) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, DataType::FLOAT32); + other_tensor_ref = cast_ad_func(other_tensor_ref, DataType::FLOAT32); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -883,46 +925,8 @@ static PyObject* tensor__rdiv__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype) { - // // note: only op_type in _supported_promote_complex_types_ should promote - // // dtype - // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - // phi::DataType promote_dtype = - // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - // framework::TransToProtoVarType(lhs_dtype), - // framework::TransToProtoVarType(rhs_dtype))); - // if (lhs_dtype != promote_dtype) { - // // cast - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, promote_dtype); - // } - // if (rhs_dtype != promote_dtype) { - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, promote_dtype); - // } - // } else { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } - // } - // if (_supported_int_dtype_.find(self_tensor.dtype()) != - // _supported_int_dtype_.end()) { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - // } - // if (_supported_int_dtype_.find(other_tensor.dtype()) != - // _supported_int_dtype_.end()) { - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, DataType::FLOAT32); - // } + // 3. promote types or unify right var type to left var, float type promotion + // mv to divide_ad_func // 4. calculation VLOG(6) << "Calling divide_ad_func in tensor__rdiv__method"; @@ -971,6 +975,12 @@ static PyObject* tensor__gt__method(TensorObject* self, other_double = CastPyArg2Double(other_obj, "__gt__", 0); has_other_double = true; } + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -992,6 +1002,31 @@ static PyObject* tensor__gt__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "greater_than", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1020,17 +1055,8 @@ static PyObject* tensor__gt__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype) { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } + // 3. promote types or unify right var type to left var, float type promotion + // mv to greater_than_ad_func // 4. calculation VLOG(6) << "Calling greater_than_ad_func in tensor__gt__method"; @@ -1080,6 +1106,12 @@ static PyObject* tensor__ge__method(TensorObject* self, other_double = CastPyArg2Double(other_obj, "__ge__", 0); has_other_double = true; } + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -1101,6 +1133,31 @@ static PyObject* tensor__ge__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "greater_equal", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1129,17 +1186,8 @@ static PyObject* tensor__ge__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype) { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } + // 3. promote types or unify right var type to left var, float type promotion + // mv to greater_equal_ad_func // 4. calculation VLOG(6) << "Calling greater_equal_ad_func in tensor__ge__method"; @@ -1190,6 +1238,12 @@ static PyObject* tensor__mod__method(TensorObject* self, other_double = CastPyArg2Double(other_obj, "__mod__", 0); // NOLINT has_other_double = true; } + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -1211,6 +1265,31 @@ static PyObject* tensor__mod__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "remainder", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1239,17 +1318,8 @@ static PyObject* tensor__mod__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype) { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } + // 3. promote types or unify right var type to left var, float type promotion + // mv to remainder_ad_func // 4. calculation VLOG(6) << "Calling remainder_ad_func in tensor__mod__method"; @@ -1347,35 +1417,35 @@ static PyObject* tensor__matmul__method(TensorObject* self, } // 3. promote types or unify right var type to left var - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype) { - // // note: only op_type in _supported_promote_complex_types_ should promote - // // dtype - // if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || - // _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { - // phi::DataType promote_dtype = - // framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( - // framework::TransToProtoVarType(lhs_dtype), - // framework::TransToProtoVarType(rhs_dtype))); - // if (lhs_dtype != promote_dtype) { - // // cast - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, promote_dtype); - // } - // if (rhs_dtype != promote_dtype) { - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, promote_dtype); - // } - // } else { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } - // } + phi::DataType lhs_dtype = self_tensor.dtype(); + phi::DataType rhs_dtype = other_tensor.dtype(); + if (lhs_dtype != rhs_dtype) { + // note: only op_type in _supported_promote_complex_types_ should promote + // dtype + if (_complex_dtypes.find(lhs_dtype) != _complex_dtypes.end() || + _complex_dtypes.find(rhs_dtype) != _complex_dtypes.end()) { + phi::DataType promote_dtype = + framework::TransToPhiDataType(framework::PromoteTypesIfComplexExists( + framework::TransToProtoVarType(lhs_dtype), + framework::TransToProtoVarType(rhs_dtype))); + if (lhs_dtype != promote_dtype) { + // cast + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, promote_dtype); + } + if (rhs_dtype != promote_dtype) { + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, promote_dtype); + } + } else { + VLOG(6) << "The dtype of left and right Tensor are not the same, left " + "dtype is " + << lhs_dtype << ", but right dtype is " << rhs_dtype + << ", the right dtype will convert to " << lhs_dtype; + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, lhs_dtype); + } + } // 4. calculation VLOG(6) << "Calling matmul_ad_func in tensor__matmul__method"; @@ -1424,6 +1494,12 @@ static PyObject* tensor__lt__method(TensorObject* self, other_double = CastPyArg2Double(other_obj, "__lt__", 0); // NOLINT has_other_double = true; } + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -1445,6 +1521,31 @@ static PyObject* tensor__lt__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "less_than", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1473,17 +1574,8 @@ static PyObject* tensor__lt__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype) { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } + // 3. promote types or unify right var type to left var, float type promotion + // mv to less_than_ad_func // // 4. calculation VLOG(6) << "Calling less_than_ad_func in tensor__lt__method"; @@ -1533,6 +1625,12 @@ static PyObject* tensor__le__method(TensorObject* self, other_double = CastPyArg2Double(other_obj, "__le__", 0); // NOLINT has_other_double = true; } + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -1554,6 +1652,31 @@ static PyObject* tensor__le__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "less_equal", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1582,17 +1705,8 @@ static PyObject* tensor__le__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype) { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } + // 3. promote types or unify right var type to left var, float type promotion + // mv to less_equal_ad_func // 4. calculation VLOG(6) << "Calling less_equal_ad_func in tensor__le__method"; @@ -1643,6 +1757,12 @@ static PyObject* tensor__floordiv__method(TensorObject* self, other_double = CastPyArg2Double(other_obj, "__floordiv__", 0); has_other_double = true; } + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -1664,6 +1784,31 @@ static PyObject* tensor__floordiv__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "floor_divide", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1690,21 +1835,8 @@ static PyObject* tensor__floordiv__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype) { - // // note: only op_type in _supported_promote_complex_types_ should promote - // // dtype, floordiv is not in _supported_promote_complex_types_, will not - // do - // // promote dtype - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } + // 3. promote types or unify right var type to left var, float type promotion + // mv to floor_divide_ad_func // 4. calculation VLOG(6) << "Calling floor_divide_ad_func in tensor__floordiv__method"; @@ -1756,6 +1888,12 @@ static PyObject* tensor__pow__method(TensorObject* self, ret = CallScalarFuction(self_tensor, other, "pow"); } return ToPyObject(ret); + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -1767,6 +1905,32 @@ static PyObject* tensor__pow__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype("elementwise_pow", + self_tensor_ref.dtype(), + other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1793,17 +1957,8 @@ static PyObject* tensor__pow__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype) { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } + // 3. promote types or unify right var type to left var, float type promotion + // mv to elementwise_pow_ad_func // 4. calculation VLOG(6) << "Calling elementwise_pow_ad_func in tensor__pow__method"; @@ -1855,6 +2010,12 @@ static PyObject* tensor__rpow__method(TensorObject* self, other_double = CastPyArg2Double(other_obj, "__rpow__", 0); has_other_double = true; } + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -1876,6 +2037,32 @@ static PyObject* tensor__rpow__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype("elementwise_pow", + self_tensor_ref.dtype(), + other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1904,17 +2091,8 @@ static PyObject* tensor__rpow__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype) { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } + // 3. promote types or unify right var type to left var, float type promotion + // mv to elementwise_pow_ad_func // 4. calculation VLOG(6) << "Calling elementwise_pow_ad_func in tensor__rpow__method"; @@ -1964,6 +2142,12 @@ static PyObject* tensor__ne__method(TensorObject* self, other_double = CastPyArg2Double(other_obj, "__ne__", 0); has_other_double = true; } + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -1985,6 +2169,31 @@ static PyObject* tensor__ne__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "not_equal", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -2011,17 +2220,8 @@ static PyObject* tensor__ne__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype) { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } + // 3. promote types or unify right var type to left var, float type promotion + // mv to not_equal_ad_func // 4. calculation VLOG(6) << "Calling not_equal_ad_func in tensor__ne__method"; @@ -2071,6 +2271,12 @@ static PyObject* tensor__eq__method(TensorObject* self, other_double = CastPyArg2Double(other_obj, "__eq__", 0); has_other_double = true; } + } else if (PyComplex_Check(other_obj)) { + if (is_support_complex(self_tensor.dtype()) == false) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func( + self_tensor, promoteTypes(self_tensor.dtype(), DataType::COMPLEX64)); + } } // 2. create or get tensor for other_obj @@ -2092,6 +2298,31 @@ static PyObject* tensor__eq__method(TensorObject* self, if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); } + // got 0-d tensor, and need type promotion. The rules same with Tensor + + // Scalar. + if (other_tensor_ref.shape().size() == 0 && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + // common major types follow with tensor: int32(tensor) + int64(scalar) = + // int32 + if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype())) { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } else { + // different major types follow with rule. + phi::DataType promote_type = GetPromoteDtype( + "equal", self_tensor_ref.dtype(), other_tensor_ref.dtype()); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); + } + } + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -2118,17 +2349,8 @@ static PyObject* tensor__eq__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var - // phi::DataType lhs_dtype = self_tensor.dtype(); - // phi::DataType rhs_dtype = other_tensor.dtype(); - // if (lhs_dtype != rhs_dtype) { - // VLOG(6) << "The dtype of left and right Tensor are not the same, left " - // "dtype is " - // << lhs_dtype << ", but right dtype is " << rhs_dtype - // << ", the right dtype will convert to " << lhs_dtype; - // eager_gil_scoped_release guard; - // other_tensor = cast_ad_func(other_tensor, lhs_dtype); - // } + // 3. promote types or unify right var type to left var, float type promotion + // mv to equal_ad_func // 4. calculation VLOG(6) << "Calling equal_ad_func in tensor__eq__method"; diff --git a/paddle/fluid/pybind/pybind.cc b/paddle/fluid/pybind/pybind.cc index ffc2549d5e73f..4ca11c2135972 100644 --- a/paddle/fluid/pybind/pybind.cc +++ b/paddle/fluid/pybind/pybind.cc @@ -925,7 +925,13 @@ PYBIND11_MODULE(libpaddle, m) { framework::TransToPhiDataType(type_x), framework::TransToPhiDataType(type_y))); }); - + m.def("is_common_dtype_for_scalar", + [](framework::proto::VarType::Type type_x, + framework::proto::VarType::Type type_y) { + return phi::is_common_dtype_for_scalar( + framework::TransToPhiDataType(type_x), + framework::TransToPhiDataType(type_y)); + }); m.def("disable_signal_handler", &DisableSignalHandler); m.def("clear_gradients", diff --git a/paddle/phi/common/type_promotion.h b/paddle/phi/common/type_promotion.h index 9dffca520cbe1..44de17184fdb1 100644 --- a/paddle/phi/common/type_promotion.h +++ b/paddle/phi/common/type_promotion.h @@ -99,27 +99,37 @@ inline bool is_support_complex(DataType dtype) { } } -inline DataType ComplexToFloat(DataType dtype) { - if (dtype == DataType::COMPLEX64) { - return DataType::FLOAT32; - } else if (dtype == DataType::COMPLEX128) { - return DataType::FLOAT64; +// only T+S support int type promotion +inline bool is_support_int(DataType dtype) { + if (dtype == DataType::UINT8 || dtype == DataType::INT8 || + dtype == DataType::INT16 || dtype == DataType::INT32 || + dtype == DataType::INT64 || dtype == DataType::BOOL) { + return true; + } else { + return false; + } +} + +inline bool is_common_dtype_for_scalar(DataType x, DataType y) { + if ((is_support_int(x) && is_support_int(y)) || + (is_support_float(x) && is_support_float(y)) || + (is_support_complex(x) && is_support_complex(y))) { + return true; } else { - return dtype; + return false; } } inline phi::DataType GetPromoteDtype(const std::string& op_name, const DataType x, const DataType y) { - // complex will be cast to float - if (op_name == "l1_loss" || op_name == "smooth_l1_loss" || - op_name == "mse_loss") { - return phi::promoteTypes(ComplexToFloat(x), ComplexToFloat(y)); - } else { - // use default rule - return phi::promoteTypes(x, y); + if (op_name == "divide") { + // only T+S can run into this branch + if (is_support_int(x) && is_support_int(y)) { + return DataType::FLOAT32; + } } + return phi::promoteTypes(x, y); } inline bool NeedTypePromotion(const DataType x, const DataType y) { diff --git a/python/paddle/base/framework.py b/python/paddle/base/framework.py index 3333c34bceaa5..89233830efb32 100644 --- a/python/paddle/base/framework.py +++ b/python/paddle/base/framework.py @@ -56,17 +56,6 @@ CONTROL_DEP_VAR_PREFIX = core.kControlDepVarName() _global_flags_ = core.globals() -# SUPPORT_PROMOTION_OPS_AND_INPUTNAME = { -# "elementwise_add": ['X', 'Y'], -# "elementwise_add_grad": ['X', 'Y'], -# "elementwise_sub": ['X', 'Y'], -# "elementwise_sub_grad": ['X', 'Y'], -# "elementwise_mul": ['X', 'Y'], -# "elementwise_mul_grad": ['X', 'Y'], -# "where": ['X', 'Y'], -# "where_grad": ['X', 'Y'], -# } - SUPPORT_PROMOTION_OPS_AND_INPUTNAME = { "elementwise_add": ['X', 'Y'], "elementwise_add_grad": ['X', 'Y'], diff --git a/python/paddle/base/layers/math_op_patch.py b/python/paddle/base/layers/math_op_patch.py index 758f0410285a4..42283447e5b90 100644 --- a/python/paddle/base/layers/math_op_patch.py +++ b/python/paddle/base/layers/math_op_patch.py @@ -28,6 +28,11 @@ core.VarDesc.VarType.INT32, core.VarDesc.VarType.INT64, ] +_supported_complex_dtype_ = [ + core.VarDesc.VarType.COMPLEX64, + core.VarDesc.VarType.COMPLEX128, +] + compare_ops = ['__eq__', '__ne__', '__lt__', '__le__', '__gt__', '__ge__'] @@ -38,6 +43,20 @@ "__rsub__", "__mul__", "__rmul__", + "__mod__", + "__div__", + "__rdiv__", + "__truediv__", + "__rtruediv__", + "__floordiv__", + "__pow__", + "__rpow__", + "__eq__", + "__ne__", + "__lt__", + "__le__", + "__gt__", + "__ge__", ] EXPRESSION_MAP = { @@ -500,6 +519,12 @@ def __impl__(self, other_var): # but only +, -, *, / can use this method if scalar_method is not None: return scalar_method(self, other_var) + elif isinstance(other_var, complex): + if self.dtype not in _supported_complex_dtype_: + self = astype(self, 'complex64') + other_var = create_new_tmp_var( + current_block(self), dtype='complex64' + ) else: # do nothing pass @@ -533,7 +558,21 @@ def __impl__(self, other_var): if lhs_dtype != rhs_dtype: if method_name in SUPPORT_PROMOTION_OPS: - if core.need_type_promotion(lhs_dtype, rhs_dtype): + # for 0-d tensor, the logic same with Tensor + Scalar + if len(other_var.shape) == 0: + if core.is_common_dtype_for_scalar( + lhs_dtype, rhs_dtype + ): + other_var = astype(other_var, lhs_dtype) + else: + promote_type = core.get_promote_dtype( + op_type, lhs_dtype, rhs_dtype + ) + if lhs_dtype != promote_type: + self = astype(self, promote_type) + if rhs_dtype != promote_type: + other_var = astype(other_var, promote_type) + elif core.need_type_promotion(lhs_dtype, rhs_dtype): # only report warning here, real promotion deal in Executor warnings.warn( f"The input dtypes of OP {op_type} are {lhs_dtype} and {rhs_dtype}, the output will be auto-promoted" @@ -541,13 +580,10 @@ def __impl__(self, other_var): warnings.filterwarnings( "ignore", message="The input dtypes of OP" ) - else: - # NOTE(zoooo0820): Currently, we still keep the old illogical \ - # logic for compatibility reasons - other_var = astype(other_var, lhs_dtype) - else: - other_var = astype(other_var, lhs_dtype) + raise TypeError( + f"got different data type in {op_type} between {lhs_dtype} and {rhs_dtype}." + ) if reverse: tmp = self @@ -555,11 +591,12 @@ def __impl__(self, other_var): other_var = tmp if ( - op_type == "divide" or op_type == "elementwise_div" - ) and self.dtype in _supported_int_dtype_: + (op_type == "divide" or op_type == "elementwise_div") + and self.dtype in _supported_int_dtype_ + and self.dtype == other_var.dtype + ): self = astype(self, 'float32') other_var = astype(other_var, 'float32') - # NOTE(zhiqiu): the output of compare operator should be bool. if method_name in compare_ops: out = create_new_tmp_var(current_block(self), dtype="bool") diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index 98605b04415dc..d4be55e1542a1 100644 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -2918,21 +2918,27 @@ def cross_entropy( if weight is None: mask = paddle.cast(mask, dtype=out_sum.dtype) count = _C_ops.sum(mask, [], None, False) - ret = out_sum / (count + (count == 0.0)) + ret = out_sum / (count + (count == 0.0).astype(count.dtype)) else: mask = paddle.cast(mask, weight_gather_reshape.dtype) weight_ignored = _C_ops.multiply( mask, weight_gather_reshape ) weight_sum = _C_ops.sum(weight_ignored, [], None, False) - ret = out_sum / (weight_sum + (weight_sum == 0.0)) + ret = out_sum / ( + weight_sum + + (weight_sum == 0.0).astype(weight_sum.dtype) + ) return ret elif weight is not None: out_sum = _C_ops.sum(out, [], None, False) total_weight = _C_ops.sum( weight_gather_reshape, [], None, False ) - return out_sum / (total_weight + (total_weight == 0.0)) + return out_sum / ( + total_weight + + (total_weight == 0.0).astype(total_weight.dtype) + ) else: return _C_ops.mean_all(out) diff --git a/test/dygraph_to_static/test_break_continue.py b/test/dygraph_to_static/test_break_continue.py index fdb909cb4c45a..a0e04516fe69a 100644 --- a/test/dygraph_to_static/test_break_continue.py +++ b/test/dygraph_to_static/test_break_continue.py @@ -66,7 +66,7 @@ def test_continue_in_for_at_end(x): def test_continue_in_while(x): x = paddle.to_tensor(x) - i = paddle.tensor.fill_constant(shape=[1], dtype='int32', value=0) + i = paddle.tensor.fill_constant(shape=[1], dtype='int64', value=0) while i < 10: i += 1 if i > 5: @@ -98,7 +98,7 @@ def test_break_in_for_at_end(x): def test_break_in_while(x): x = paddle.to_tensor(x) - i = paddle.tensor.fill_constant(shape=[1], dtype='int32', value=0) + i = paddle.tensor.fill_constant(shape=[1], dtype='int64', value=0) while i < 10: i += 1 if i > 5: @@ -120,8 +120,8 @@ def test_break_continue_in_for(x): break x += 10086 - a = paddle.tensor.fill_constant(shape=[1], dtype='int32', value=0) - b = paddle.tensor.fill_constant(shape=[1], dtype='int32', value=3) + a = paddle.tensor.fill_constant(shape=[1], dtype='int64', value=0) + b = paddle.tensor.fill_constant(shape=[1], dtype='int64', value=3) # b = 10 # TODO: add Raise Error and suggestion for usage: # Py for contains break/continue depends on control-flow. @@ -196,7 +196,7 @@ def test_optim_break_in_for(x): def test_optim_break_in_while(x): x = paddle.to_tensor(x) - i = paddle.tensor.fill_constant(shape=[1], dtype='int32', value=0) + i = paddle.tensor.fill_constant(shape=[1], dtype='int64', value=0) while i < 10: if i > 5: break diff --git a/test/dygraph_to_static/test_tensor_methods.py b/test/dygraph_to_static/test_tensor_methods.py index 467b0f8c269de..a362fe73331f2 100644 --- a/test/dygraph_to_static/test_tensor_methods.py +++ b/test/dygraph_to_static/test_tensor_methods.py @@ -134,6 +134,7 @@ def test_true_div(self): with enable_to_static_guard(False): dygraph_res = self._run() static_res = self._run() + print(dygraph_res, static_res) np.testing.assert_allclose(dygraph_res, static_res, rtol=1e-5) diff --git a/test/legacy_test/test_trapezoid.py b/test/legacy_test/test_trapezoid.py index e1b8697ccff15..2a27e401b828d 100644 --- a/test/legacy_test/test_trapezoid.py +++ b/test/legacy_test/test_trapezoid.py @@ -155,7 +155,7 @@ class TestTrapezoidAxis1(TestTrapezoidAPI): def set_args(self): self.y = np.random.random((3, 3, 4)).astype('float32') self.x = None - self.dx = 1 + self.dx = 1.0 self.axis = 1 From 2ba876422e40e36c0d27119f8b03b28c40ff0116 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Thu, 29 Feb 2024 03:42:29 +0000 Subject: [PATCH 09/34] fix bug --- paddle/fluid/pybind/eager_math_op_patch.cc | 15 +++++++++++---- python/paddle/base/layers/math_op_patch.py | 7 +++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index e8ab047814974..c4921647345fe 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -248,15 +248,22 @@ static PyObject* tensor__add__method(TensorObject* self, } // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + if ((other_tensor_ref.shape().size() == 0 || + self_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { // common major types follow with tensor: int32(tensor) + int64(scalar) = // int32 if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } else { // different major types follow with rule. phi::DataType promote_type = GetPromoteDtype( diff --git a/python/paddle/base/layers/math_op_patch.py b/python/paddle/base/layers/math_op_patch.py index 42283447e5b90..5eff880055ed3 100644 --- a/python/paddle/base/layers/math_op_patch.py +++ b/python/paddle/base/layers/math_op_patch.py @@ -559,11 +559,14 @@ def __impl__(self, other_var): if lhs_dtype != rhs_dtype: if method_name in SUPPORT_PROMOTION_OPS: # for 0-d tensor, the logic same with Tensor + Scalar - if len(other_var.shape) == 0: + if len(other_var.shape) == 0 or len(self.shape) == 0: if core.is_common_dtype_for_scalar( lhs_dtype, rhs_dtype ): - other_var = astype(other_var, lhs_dtype) + if len(self.shape) == 0: + self = astype(self, rhs_dtype) + else: + other_var = astype(other_var, lhs_dtype) else: promote_type = core.get_promote_dtype( op_type, lhs_dtype, rhs_dtype From 7df3fa1e3be851101985c753e3acb7857e86295a Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Fri, 1 Mar 2024 03:32:21 +0000 Subject: [PATCH 10/34] fix unittest --- paddle/fluid/pybind/eager_math_op_patch.cc | 28 ++++++++++------- paddle/phi/common/type_promotion.h | 11 ++++--- python/paddle/base/framework.py | 2 +- python/paddle/distribution/gumbel.py | 11 +++++-- python/paddle/metric/metrics.py | 2 +- python/paddle/tensor/linalg.py | 7 +++-- python/paddle/tensor/math.py | 4 +-- python/paddle/tensor/stat.py | 4 ++- test/dygraph_to_static/test_for_enumerate.py | 6 ++-- test/indexing/test_setitem.py | 2 +- .../test_math_op_patch_var_base.py | 4 +-- test/legacy_test/test_modelaverage.py | 11 +++++-- test/legacy_test/test_multiply.py | 2 +- ...est_save_inference_model_conditional_op.py | 2 +- .../legacy_test/test_sparse_elementwise_op.py | 30 +++++++++++-------- test/legacy_test/test_sparse_sum_op.py | 10 +++++-- .../legacy_test/test_tensor_type_promotion.py | 2 +- test/sot/test_18_tensor_method.py | 7 ++++- 18 files changed, 90 insertions(+), 55 deletions(-) diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index c4921647345fe..89200a975caa9 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -761,11 +761,6 @@ static PyObject* tensor__div__method(TensorObject* self, other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } - } else if (is_support_int(self_tensor_ref.dtype()) && - self_tensor_ref.dtype() == other_tensor_ref.dtype()) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, DataType::FLOAT32); - other_tensor_ref = cast_ad_func(other_tensor_ref, DataType::FLOAT32); } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -797,6 +792,15 @@ static PyObject* tensor__div__method(TensorObject* self, // 3. promote types or unify right var type to left var, float type promotion // mv to divide_ad_func + if (self_tensor.dtype() == other_tensor.dtype()) { + if (_supported_int_dtype_.find(self_tensor.dtype()) != + _supported_int_dtype_.end()) { + std::cout << "cast self" << std::endl; + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + other_tensor = cast_ad_func(other_tensor, DataType::FLOAT32); + } + } // 4. calculation VLOG(6) << "Calling divide_ad_func in tensor__div__method"; @@ -898,12 +902,6 @@ static PyObject* tensor__rdiv__method(TensorObject* self, } } } - if (is_support_int(self_tensor_ref.dtype()) && - self_tensor_ref.dtype() == other_tensor_ref.dtype()) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, DataType::FLOAT32); - other_tensor_ref = cast_ad_func(other_tensor_ref, DataType::FLOAT32); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -934,6 +932,14 @@ static PyObject* tensor__rdiv__method(TensorObject* self, // 3. promote types or unify right var type to left var, float type promotion // mv to divide_ad_func + if (self_tensor.dtype() == other_tensor.dtype()) { + if (_supported_int_dtype_.find(self_tensor.dtype()) != + _supported_int_dtype_.end()) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + other_tensor = cast_ad_func(other_tensor, DataType::FLOAT32); + } + } // 4. calculation VLOG(6) << "Calling divide_ad_func in tensor__rdiv__method"; diff --git a/paddle/phi/common/type_promotion.h b/paddle/phi/common/type_promotion.h index 44de17184fdb1..bca3880bd52aa 100644 --- a/paddle/phi/common/type_promotion.h +++ b/paddle/phi/common/type_promotion.h @@ -43,7 +43,8 @@ inline int DataTypeToNum(const DataType& dtype) { case DataType::BFLOAT16: return 11; default: - PD_THROW("Invalid enum data type for type promote `", dtype, "`."); + PADDLE_THROW(phi::errors::InvalidType( + "Invalid enum data type for type promote %s.", dtype)); } } @@ -140,14 +141,12 @@ inline bool NeedTypePromotion(const DataType x, const DataType y) { (is_support_complex(x) || is_support_complex(y))) { return true; } else { - PD_THROW( + PADDLE_THROW(phi::errors::InvalidType( "Type promotion only support calculations between floating-point " "numbers and between complex and real numbers. But got different " - "data type x: `", + "data type x: %s, y: %s.", x, - "` y: `", - y, - "`."); + y)); } } else { return false; diff --git a/python/paddle/base/framework.py b/python/paddle/base/framework.py index 89233830efb32..140f67f35e29d 100644 --- a/python/paddle/base/framework.py +++ b/python/paddle/base/framework.py @@ -8268,7 +8268,7 @@ def process_type_promotion(program): all_input_name_need_cast.append(input_arg_name) # only support promote between float - if core.need_type_promotion(*all_dtypes): + if len(all_dtypes) == 2 and core.need_type_promotion(*all_dtypes): common_dtype = core.get_promote_dtype(op.type, *all_dtypes) for input_name_need_cast in all_input_name_need_cast: var_name = op.block._var_recursive(input_name_need_cast) diff --git a/python/paddle/distribution/gumbel.py b/python/paddle/distribution/gumbel.py index 005801ae6b7cc..31dd7c5e6818e 100644 --- a/python/paddle/distribution/gumbel.py +++ b/python/paddle/distribution/gumbel.py @@ -189,7 +189,9 @@ def prob(self, value): Tensor: probability.The data type is same with value. """ - y = (self.loc - value) / self.scale + y = (self.loc.astype(value.dtype) - value) / self.scale.astype( + value.dtype + ) return paddle.exp(y - paddle.exp(y)) / self.scale @@ -214,7 +216,12 @@ def cdf(self, value): Tensor: cumulative probability of value. """ - return paddle.exp(-paddle.exp(-(value - self.loc) / self.scale)) + return paddle.exp( + -paddle.exp( + -(value - self.loc.astype(value.dtype)) + / self.scale.astype(value.dtype) + ) + ) def entropy(self): """Entropy of Gumbel distribution. diff --git a/python/paddle/metric/metrics.py b/python/paddle/metric/metrics.py index e87ab0068ff2c..206b79cb20f88 100644 --- a/python/paddle/metric/metrics.py +++ b/python/paddle/metric/metrics.py @@ -271,7 +271,7 @@ def compute(self, pred, label, *args): elif label.shape[-1] != 1: # one-hot label label = paddle.argmax(label, axis=-1, keepdim=True) - correct = pred == label + correct = pred == label.astype(pred.dtype) return paddle.cast(correct, dtype='float32') def update(self, correct, *args): diff --git a/python/paddle/tensor/linalg.py b/python/paddle/tensor/linalg.py index 321366276c611..6e1dc4a547eea 100644 --- a/python/paddle/tensor/linalg.py +++ b/python/paddle/tensor/linalg.py @@ -1397,7 +1397,10 @@ def cov(x, rowvar=True, ddof=True, fweights=None, aweights=None, name=None): "The value of Input(fweights) cannot be negative, but received " f"min of Input(fweights) is {fweights.min()}." ) - if not paddle.all(fweights == paddle.round(fweights.astype('float64'))): + if not paddle.all( + fweights + == paddle.round(fweights.astype('float64').astype(fweights.dtype)) + ): raise ValueError("Input(fweights) must be integer ") if aweights is not None: @@ -1441,7 +1444,7 @@ def cov(x, rowvar=True, ddof=True, fweights=None, aweights=None, name=None): nx_w = nx if w is not None and aweights is not None and ddof: - norm_factor = w_sum - (w * aweights).sum() / w_sum + norm_factor = w_sum - (w * aweights.astype(w.dtype)).sum() / w_sum else: norm_factor = w_sum - ddof if norm_factor <= 0: diff --git a/python/paddle/tensor/math.py b/python/paddle/tensor/math.py index 1a88acd43d0a2..8c75b9c4791e5 100644 --- a/python/paddle/tensor/math.py +++ b/python/paddle/tensor/math.py @@ -773,8 +773,8 @@ def logaddexp(x, y, name=None): Tensor(shape=[3], dtype=float64, place=Place(cpu), stop_gradient=True, [-0.30685282, -0.68673831, -0.87307199]) """ - - return paddle.log1p(paddle.exp(-paddle.abs(x - y))) + paddle.maximum(x, y) + log_1p = paddle.log1p(paddle.exp(-paddle.abs(x - y))) + return log_1p + paddle.maximum(x, y).astype(log_1p.dtype) def subtract(x, y, name=None): diff --git a/python/paddle/tensor/stat.py b/python/paddle/tensor/stat.py index 643ef08d74320..d29184bc4c766 100644 --- a/python/paddle/tensor/stat.py +++ b/python/paddle/tensor/stat.py @@ -458,7 +458,9 @@ def median(x, axis=None, keepdim=False, name=None): dtype=dtype, ) out_tensor = out_tensor + paddle.sum( - paddle.cast(paddle.isnan(x), dtype=dtype) * x, axis=axis, keepdim=True + paddle.cast(paddle.isnan(x), dtype=dtype) * x.astype(dtype), + axis=axis, + keepdim=True, ) if is_flatten: if keepdim: diff --git a/test/dygraph_to_static/test_for_enumerate.py b/test/dygraph_to_static/test_for_enumerate.py index 7b754fb1343ea..881a5c8301bac 100644 --- a/test/dygraph_to_static/test_for_enumerate.py +++ b/test/dygraph_to_static/test_for_enumerate.py @@ -179,7 +179,7 @@ def for_iter_var_list(x): # 2. iter list[var] y = paddle.tensor.fill_constant([1], 'int32', 0) for x in a: - y = y + x + y = y + x.astype('int32') return y @@ -196,7 +196,7 @@ def for_enumerate_var_list(x): z = paddle.tensor.fill_constant([1], 'int32', 0) for i, x in enumerate(a): y = y + i - z = z + x + z = z + x.astype('int32') return y, z @@ -245,7 +245,7 @@ def for_tuple_as_enumerate_iter(x_array): a_result = paddle.zeros([5]) for t in enumerate(x_list): - a_result += t[1] + a_result += t[1].astype('float32') return a_result diff --git a/test/indexing/test_setitem.py b/test/indexing/test_setitem.py index 818672dfd8d15..d9d7e8c9264c4 100644 --- a/test/indexing/test_setitem.py +++ b/test/indexing/test_setitem.py @@ -700,7 +700,7 @@ def test_combined_indexing_and_value_is_tensor_1(self): paddle.static.Program(), paddle.static.Program() ): x = paddle.ones((3, 3), dtype='int32') - v = paddle.to_tensor([-1, -1, -1]) + v = paddle.to_tensor([-1, -1, -1], dtype='int32') y = _setitem_static( x, (slice(None), [0, 2]), diff --git a/test/legacy_test/test_math_op_patch_var_base.py b/test/legacy_test/test_math_op_patch_var_base.py index 7b6c865eb6c45..4a75c6ebcd8eb 100644 --- a/test/legacy_test/test_math_op_patch_var_base.py +++ b/test/legacy_test/test_math_op_patch_var_base.py @@ -542,8 +542,8 @@ def test_add_different_dtype(self): np.testing.assert_array_equal(res.numpy(), a_np + b_np) def test_floordiv_different_dtype(self): - a_np = np.full(self.shape, 10, np.int64) - b_np = np.full(self.shape, 2, np.int32) + a_np = np.full(self.shape, 10, np.float32) + b_np = np.full(self.shape, 2, np.float16) with base.dygraph.guard(): a = paddle.to_tensor(a_np) b = paddle.to_tensor(b_np) diff --git a/test/legacy_test/test_modelaverage.py b/test/legacy_test/test_modelaverage.py index 29d192eeebad9..40572ae21dce2 100644 --- a/test/legacy_test/test_modelaverage.py +++ b/test/legacy_test/test_modelaverage.py @@ -166,10 +166,15 @@ def train(layer, loader, loss_fn, opt, model_average): 'num_updates', layer.bias ) + print(num_accumulates, old_num_accumulates) return ( - (sum_1 + sum_2 + sum_3) - / (num_accumulates + old_num_accumulates) - ).numpy() + ( + (sum_1 + sum_2 + sum_3) + / (num_accumulates + old_num_accumulates) + ) + .astype(sum_1.dtype) + .numpy() + ) def evaluate(layer, loader, loss_fn, check_param): for batch_id, (image, label) in enumerate(loader()): diff --git a/test/legacy_test/test_multiply.py b/test/legacy_test/test_multiply.py index ee297bdcd2789..ba7decc5c58a2 100755 --- a/test/legacy_test/test_multiply.py +++ b/test/legacy_test/test_multiply.py @@ -149,7 +149,7 @@ def test_errors(self): y_data = np.random.randn(200).astype(np.float64) x = paddle.to_tensor(x_data) y = paddle.to_tensor(y_data) - self.assertRaises(ValueError, paddle.multiply, x, y) + self.assertRaises(TypeError, paddle.multiply, x, y) # test dynamic computation graph: dtype must be Tensor type x_data = np.random.randn(200).astype(np.int64) diff --git a/test/legacy_test/test_save_inference_model_conditional_op.py b/test/legacy_test/test_save_inference_model_conditional_op.py index 19466e3cdc9f4..f59354bb34d2b 100644 --- a/test/legacy_test/test_save_inference_model_conditional_op.py +++ b/test/legacy_test/test_save_inference_model_conditional_op.py @@ -69,7 +69,7 @@ def __init__(self): super().__init__() def forward(self, x): - y = paddle.to_tensor([5]) + y = paddle.to_tensor([5], dtype='int32') if x > y: x = x + 1 else: diff --git a/test/legacy_test/test_sparse_elementwise_op.py b/test/legacy_test/test_sparse_elementwise_op.py index 3583d861e49de..53f568256654e 100644 --- a/test/legacy_test/test_sparse_elementwise_op.py +++ b/test/legacy_test/test_sparse_elementwise_op.py @@ -79,12 +79,12 @@ def func_test_csr(self, op): expect_res = op(dense_x, dense_y) expect_res.backward() - np.testing.assert_allclose( - expect_res.numpy(), - actual_res.to_dense().numpy(), - rtol=1e-05, - equal_nan=True, - ) + # np.testing.assert_allclose( + # expect_res.numpy(), + # actual_res.to_dense().numpy(), + # rtol=1e-05, + # equal_nan=True, + # ) if not (op == __truediv__ and dtype in ['int32', 'int64']): np.testing.assert_allclose( mask_to_zero(dense_x.grad.numpy(), mask_x), @@ -124,17 +124,20 @@ def func_test_coo(self, op): coo_y.retain_grads() actual_res = get_actual_res(coo_x, coo_y, op) + print(coo_x.dtype, coo_y.dtype, op) actual_res.backward(actual_res) expect_res = op(dense_x, dense_y) expect_res.backward(expect_res) - - np.testing.assert_allclose( - expect_res.numpy(), - actual_res.to_dense().numpy(), - rtol=1e-05, - equal_nan=True, - ) + print(coo_x.grad.dtype, actual_res.dtype, expect_res.dtype) + print(dense_x.grad.dtype, dense_y.grad.dtype, expect_res.dtype) + + # np.testing.assert_allclose( + # expect_res.numpy(), + # actual_res.to_dense().numpy(), + # rtol=1e-05, + # equal_nan=True, + # ) np.testing.assert_allclose(coo_x.shape, coo_x.grad.shape) np.testing.assert_allclose( dense_x.grad.numpy(), @@ -160,6 +163,7 @@ def test_support_dtypes_coo(self): paddle.device.set_device('cpu') if paddle.device.get_device() == "cpu": for op in op_list: + print(op) self.func_test_coo(op) def test_add_same_indices(self): diff --git a/test/legacy_test/test_sparse_sum_op.py b/test/legacy_test/test_sparse_sum_op.py index 3690341c51dc0..4b165ecc8e21b 100644 --- a/test/legacy_test/test_sparse_sum_op.py +++ b/test/legacy_test/test_sparse_sum_op.py @@ -61,7 +61,9 @@ def check_result( mask = paddle.randint(0, 2, x_shape) # "+ 1" to make sure that all zero elements in "origin_x" is caused by multiplying by "mask", # or the backward checks may fail. - origin_x = (paddle.rand(x_shape, dtype='float64') + 1) * mask + origin_x = ( + paddle.rand(x_shape, dtype='float64') + 1 + ) * mask.astype('float64') dense_x = origin_x.detach() dense_x.stop_gradient = False dense_out = paddle.sum(dense_x, dims, keepdim=keepdim, dtype=dtype) @@ -75,7 +77,7 @@ def check_result( sp_out.backward() np.testing.assert_allclose( sp_x.grad.to_dense().numpy(), - (dense_x.grad * mask).numpy(), + (dense_x.grad * mask.astype(dense_x.grad.dtype)).numpy(), rtol=1e-05, ) @@ -122,7 +124,9 @@ def check_result_coo(self, x_shape, dims, keepdim, dtype=None): mask = paddle.randint(0, 2, x_shape) while paddle.sum(mask) == 0: mask = paddle.randint(0, 2, x_shape) - origin_data = (paddle.rand(x_shape, dtype='float32') + 1) * mask + origin_data = ( + paddle.rand(x_shape, dtype='float32') + 1 + ) * mask.astype('float32') sparse_data = origin_data.detach().to_sparse_coo( sparse_dim=len(x_shape) ) diff --git a/test/legacy_test/test_tensor_type_promotion.py b/test/legacy_test/test_tensor_type_promotion.py index 19d26048f6997..d830c08c94063 100644 --- a/test/legacy_test/test_tensor_type_promotion.py +++ b/test/legacy_test/test_tensor_type_promotion.py @@ -20,7 +20,7 @@ class TestTensorTypePromotion(unittest.TestCase): def setUp(self): - self.x = paddle.to_tensor([2, 3]) + self.x = paddle.to_tensor([2, 3], dtype='float16') self.y = paddle.to_tensor([1.0, 2.0]) def add_operator(self): diff --git a/test/sot/test_18_tensor_method.py b/test/sot/test_18_tensor_method.py index 2591db1f748d9..d243ee1f7611e 100644 --- a/test/sot/test_18_tensor_method.py +++ b/test/sot/test_18_tensor_method.py @@ -48,7 +48,12 @@ def tensor_method_property(a: paddle.Tensor, b: paddle.Tensor): a.type, a.is_tensor(), a.clear_gradient(), - a @ b.T + len(a.shape) + b.size + a.ndim + a.dim() + a.rank(), + a @ b.T.astype(a.dtype) + + len(a.shape) + + b.size + + a.ndim + + a.dim() + + a.rank(), ) From 05d93c1067e835e709ee91b8f3ed009f41ad61dc Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Fri, 1 Mar 2024 03:41:57 +0000 Subject: [PATCH 11/34] fix --- .../fluid/eager/auto_code_generator/generator/eager_gen.py | 5 ----- python/paddle/base/framework.py | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py index 891fc1c23f657..3cf4daa556538 100644 --- a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py +++ b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py @@ -77,11 +77,6 @@ # white ops list whose kernel can automaically do type promotion. # future will get this list from same place with static graph. -# type_promote_white_list = { -# "add": ["x", "y"], -# "subtract": ["x", "y"], -# "where": ["x", "y"], -# } type_promote_white_list = { "add": ["x", "y"], "subtract": ["x", "y"], diff --git a/python/paddle/base/framework.py b/python/paddle/base/framework.py index 140f67f35e29d..18a8867a65ce0 100644 --- a/python/paddle/base/framework.py +++ b/python/paddle/base/framework.py @@ -92,6 +92,7 @@ "elementwise_min": ['X', 'Y'], "elementwise_min_grad": ['X', 'Y'], "elementwise_mod": ['X', 'Y'], + "elementwise_mod_grad": ['X', 'Y'], "huber_loss": ['input', 'label'], "huber_loss_grad": ['input', 'label'], "nextafter": ['x', 'y'], From f3af9191bf4ed857f2d49ce84085a8d81761e000 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Fri, 1 Mar 2024 03:43:56 +0000 Subject: [PATCH 12/34] fix --- python/paddle/base/framework.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/paddle/base/framework.py b/python/paddle/base/framework.py index 18a8867a65ce0..ffce684b581b7 100644 --- a/python/paddle/base/framework.py +++ b/python/paddle/base/framework.py @@ -93,8 +93,8 @@ "elementwise_min_grad": ['X', 'Y'], "elementwise_mod": ['X', 'Y'], "elementwise_mod_grad": ['X', 'Y'], - "huber_loss": ['input', 'label'], - "huber_loss_grad": ['input', 'label'], + "huber_loss": ['X', 'Y'], + "huber_loss_grad": ['X', 'Y'], "nextafter": ['x', 'y'], "atan2": ['X1', 'X2'], "atan2_grad": ['X1', 'X2'], From d0eef9be750894eb22cee12a517ef46956690e39 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Fri, 1 Mar 2024 06:40:50 +0000 Subject: [PATCH 13/34] fix unittest --- python/paddle/distribution/gumbel.py | 2 +- python/paddle/tensor/linalg.py | 2 +- test/legacy_test/test_modelaverage.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/python/paddle/distribution/gumbel.py b/python/paddle/distribution/gumbel.py index 31dd7c5e6818e..37c10c29bfbc9 100644 --- a/python/paddle/distribution/gumbel.py +++ b/python/paddle/distribution/gumbel.py @@ -193,7 +193,7 @@ def prob(self, value): value.dtype ) - return paddle.exp(y - paddle.exp(y)) / self.scale + return paddle.exp(y - paddle.exp(y)) / self.scale.astype(y.dtype) def log_prob(self, value): """Log probability density/mass function. diff --git a/python/paddle/tensor/linalg.py b/python/paddle/tensor/linalg.py index 6e1dc4a547eea..53f61ee271e09 100644 --- a/python/paddle/tensor/linalg.py +++ b/python/paddle/tensor/linalg.py @@ -1399,7 +1399,7 @@ def cov(x, rowvar=True, ddof=True, fweights=None, aweights=None, name=None): ) if not paddle.all( fweights - == paddle.round(fweights.astype('float64').astype(fweights.dtype)) + == paddle.round(fweights.astype('float64')).astype(fweights.dtype) ): raise ValueError("Input(fweights) must be integer ") diff --git a/test/legacy_test/test_modelaverage.py b/test/legacy_test/test_modelaverage.py index 40572ae21dce2..40a0821a45a22 100644 --- a/test/legacy_test/test_modelaverage.py +++ b/test/legacy_test/test_modelaverage.py @@ -89,7 +89,7 @@ def test_model_average_static(self): average_b = (sum_1 + sum_2 + sum_3) / ( num_accumulates + old_num_accumulates - ) + ).astype('float32') # apply ModelAverage with model_average.apply(exe): x = np.random.random(size=(10, 1)).astype('float32') @@ -170,7 +170,7 @@ def train(layer, loader, loss_fn, opt, model_average): return ( ( (sum_1 + sum_2 + sum_3) - / (num_accumulates + old_num_accumulates) + / (num_accumulates + old_num_accumulates).astype('float32') ) .astype(sum_1.dtype) .numpy() From 1da794bb3be82d390f6308357777ce4c3053d99c Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Fri, 1 Mar 2024 09:11:56 +0000 Subject: [PATCH 14/34] fix gumbel --- paddle/fluid/pybind/eager_math_op_patch.cc | 1 - python/paddle/distribution/gumbel.py | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index 89200a975caa9..e57656a92b37d 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -795,7 +795,6 @@ static PyObject* tensor__div__method(TensorObject* self, if (self_tensor.dtype() == other_tensor.dtype()) { if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { - std::cout << "cast self" << std::endl; eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); other_tensor = cast_ad_func(other_tensor, DataType::FLOAT32); diff --git a/python/paddle/distribution/gumbel.py b/python/paddle/distribution/gumbel.py index 37c10c29bfbc9..a388f62c512b6 100644 --- a/python/paddle/distribution/gumbel.py +++ b/python/paddle/distribution/gumbel.py @@ -189,8 +189,8 @@ def prob(self, value): Tensor: probability.The data type is same with value. """ - y = (self.loc.astype(value.dtype) - value) / self.scale.astype( - value.dtype + y = (self.loc - value.astype(self.loc.dtype)) / self.scale.astype( + self.loc.dtype ) return paddle.exp(y - paddle.exp(y)) / self.scale.astype(y.dtype) From 290fe25003f492eefc749d757d32daed1a0f95cd Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Fri, 1 Mar 2024 09:18:08 +0000 Subject: [PATCH 15/34] rm print --- test/legacy_test/test_modelaverage.py | 1 - .../legacy_test/test_sparse_elementwise_op.py | 30 ++++++++----------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/test/legacy_test/test_modelaverage.py b/test/legacy_test/test_modelaverage.py index f8909e151abcc..61ff09ea30461 100644 --- a/test/legacy_test/test_modelaverage.py +++ b/test/legacy_test/test_modelaverage.py @@ -196,7 +196,6 @@ def train(layer, loader, loss_fn, opt, model_average): 'num_updates', layer.bias ) - print(num_accumulates, old_num_accumulates) return ( ( (sum_1 + sum_2 + sum_3) diff --git a/test/legacy_test/test_sparse_elementwise_op.py b/test/legacy_test/test_sparse_elementwise_op.py index 53f568256654e..3583d861e49de 100644 --- a/test/legacy_test/test_sparse_elementwise_op.py +++ b/test/legacy_test/test_sparse_elementwise_op.py @@ -79,12 +79,12 @@ def func_test_csr(self, op): expect_res = op(dense_x, dense_y) expect_res.backward() - # np.testing.assert_allclose( - # expect_res.numpy(), - # actual_res.to_dense().numpy(), - # rtol=1e-05, - # equal_nan=True, - # ) + np.testing.assert_allclose( + expect_res.numpy(), + actual_res.to_dense().numpy(), + rtol=1e-05, + equal_nan=True, + ) if not (op == __truediv__ and dtype in ['int32', 'int64']): np.testing.assert_allclose( mask_to_zero(dense_x.grad.numpy(), mask_x), @@ -124,20 +124,17 @@ def func_test_coo(self, op): coo_y.retain_grads() actual_res = get_actual_res(coo_x, coo_y, op) - print(coo_x.dtype, coo_y.dtype, op) actual_res.backward(actual_res) expect_res = op(dense_x, dense_y) expect_res.backward(expect_res) - print(coo_x.grad.dtype, actual_res.dtype, expect_res.dtype) - print(dense_x.grad.dtype, dense_y.grad.dtype, expect_res.dtype) - - # np.testing.assert_allclose( - # expect_res.numpy(), - # actual_res.to_dense().numpy(), - # rtol=1e-05, - # equal_nan=True, - # ) + + np.testing.assert_allclose( + expect_res.numpy(), + actual_res.to_dense().numpy(), + rtol=1e-05, + equal_nan=True, + ) np.testing.assert_allclose(coo_x.shape, coo_x.grad.shape) np.testing.assert_allclose( dense_x.grad.numpy(), @@ -163,7 +160,6 @@ def test_support_dtypes_coo(self): paddle.device.set_device('cpu') if paddle.device.get_device() == "cpu": for op in op_list: - print(op) self.func_test_coo(op) def test_add_same_indices(self): From 9cd34a9130030a5a3d384789819ec3dc0b4b6d60 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Tue, 5 Mar 2024 08:45:31 +0000 Subject: [PATCH 16/34] fix more unittests. --- python/paddle/nn/functional/loss.py | 2 +- test/auto_parallel/test_to_static.py | 2 +- test/legacy_test/test_elementwise_add_op.py | 2 +- test/legacy_test/test_elementwise_sub_op.py | 4 ++-- test/legacy_test/test_sparse_addmm_op.py | 8 ++++++-- test/legacy_test/test_sparse_matmul_op.py | 8 +++++--- test/legacy_test/test_sparse_mv_op.py | 8 ++++---- 7 files changed, 20 insertions(+), 14 deletions(-) diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index d9380b5c7c62f..9a10922ebc204 100644 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -1959,7 +1959,7 @@ def warpctc( loss_out = paddle.squeeze(loss_out, [-1]) assert reduction in ['mean', 'sum', 'none'] if reduction == 'mean': - loss_out = paddle.mean(loss_out / label_lengths) + loss_out = paddle.mean(loss_out / label_lengths.astype(loss_out.dtype)) elif reduction == 'sum': loss_out = paddle.sum(loss_out) return loss_out diff --git a/test/auto_parallel/test_to_static.py b/test/auto_parallel/test_to_static.py index 7a3f9f204f61b..66797b98caa37 100644 --- a/test/auto_parallel/test_to_static.py +++ b/test/auto_parallel/test_to_static.py @@ -112,7 +112,7 @@ def test_apply_optimizer(self): program_helper.to('train') forward_ops = program_helper.main_program.block(0).ops - self.assertEqual(len(forward_ops), 17) + self.assertEqual(len(forward_ops), 18) # step 2: apply optimizer to generate whole program optimize_ops, _ = program_helper.apply_optimizer(optimizer) diff --git a/test/legacy_test/test_elementwise_add_op.py b/test/legacy_test/test_elementwise_add_op.py index 81fc27044e04d..7f23170524611 100644 --- a/test/legacy_test/test_elementwise_add_op.py +++ b/test/legacy_test/test_elementwise_add_op.py @@ -725,7 +725,7 @@ class TestComplexElementwiseAddOp(OpTest): def setUp(self): self.op_type = "elementwise_add" self.python_api = paddle.add - self.dtype = np.float64 + self.dtype = np.complex128 self.shape = (2, 3, 4, 5) self.init_input_output() diff --git a/test/legacy_test/test_elementwise_sub_op.py b/test/legacy_test/test_elementwise_sub_op.py index 2ee7c8090d989..1053002c41cf5 100644 --- a/test/legacy_test/test_elementwise_sub_op.py +++ b/test/legacy_test/test_elementwise_sub_op.py @@ -819,7 +819,7 @@ def setUp(self): self.python_api = paddle.subtract self.public_python_api = paddle.subtract self.prim_op_type = "prim" - self.dtype = np.float64 + self.dtype = np.complex128 self.shape = (2, 3, 4, 5) self.init_input_output() @@ -833,7 +833,7 @@ def setUp(self): self.if_enable_cinn() def init_base_dtype(self): - self.dtype = np.float64 + self.dtype = np.complex128 def init_input_output(self): self.x = np.random.random(self.shape).astype( diff --git a/test/legacy_test/test_sparse_addmm_op.py b/test/legacy_test/test_sparse_addmm_op.py index 43be65aba3d1a..5ee8cca78b4ce 100644 --- a/test/legacy_test/test_sparse_addmm_op.py +++ b/test/legacy_test/test_sparse_addmm_op.py @@ -44,7 +44,9 @@ def check_result(self, input_shape, x_shape, y_shape, format): mask = paddle.randint(0, 2, x_shape) origin_input = paddle.rand(input_shape) - origin_x = paddle.rand(x_shape) * mask + origin_x = paddle.rand(x_shape) * mask.astype( + paddle.get_default_dtype() + ) origin_y = paddle.rand(y_shape) dense_input = origin_input.detach() @@ -77,7 +79,9 @@ def check_result(self, input_shape, x_shape, y_shape, format): ) np.testing.assert_allclose( sp_x.grad.to_dense().numpy(), - (dense_x.grad * mask).numpy(), + ( + dense_x.grad * mask.astype(paddle.get_default_dtype()) + ).numpy(), rtol=1e-05, ) np.testing.assert_allclose( diff --git a/test/legacy_test/test_sparse_matmul_op.py b/test/legacy_test/test_sparse_matmul_op.py index ae08b7df48c53..067d75de94b90 100644 --- a/test/legacy_test/test_sparse_matmul_op.py +++ b/test/legacy_test/test_sparse_matmul_op.py @@ -43,7 +43,9 @@ def check_result(self, x_shape, y_shape, format): mask = paddle.randint(0, 2, [x_shape[-2], x_shape[-1]]) else: mask = paddle.randint(0, 2, x_shape) - origin_x = paddle.rand(x_shape) * mask + origin_x = paddle.rand(x_shape) * mask.astype( + paddle.get_default_dtype() + ) origin_y = paddle.rand(y_shape) dense_x = origin_x.detach() @@ -275,7 +277,7 @@ def test_masked_matmul_3d(self): paddle.set_default_dtype('float32') origin_x = paddle.rand([16, 16, 12]) mask = paddle.randint(0, 2, [16, 12]) - origin_x = origin_x * mask + origin_x = origin_x * mask.astype('float32') origin_y = paddle.rand([16, 12, 10]) dense_x = origin_x.detach() @@ -297,7 +299,7 @@ def test_masked_matmul_3d(self): ) np.testing.assert_allclose( sp_x.grad.to_dense().numpy(), - (dense_x.grad * mask).numpy(), + (dense_x.grad * mask.astype('float32')).numpy(), rtol=1e-05, ) np.testing.assert_allclose( diff --git a/test/legacy_test/test_sparse_mv_op.py b/test/legacy_test/test_sparse_mv_op.py index 2ecf4fc45dd5c..c1e3182b42729 100644 --- a/test/legacy_test/test_sparse_mv_op.py +++ b/test/legacy_test/test_sparse_mv_op.py @@ -45,7 +45,7 @@ def test_mv(self): paddle.set_default_dtype('float64') origin_x = paddle.rand([64, 32]) mask = paddle.randint(0, 2, [64, 32]) - origin_x = origin_x * mask + origin_x = origin_x * mask.astype('float64') origin_vec = paddle.rand([32]) dense_x = origin_x.detach() @@ -67,7 +67,7 @@ def test_mv(self): ) np.testing.assert_allclose( sp_x.grad.to_dense().numpy(), - (dense_x.grad * mask).numpy(), + (dense_x.grad * mask.astype('float64')).numpy(), rtol=1e-05, ) np.testing.assert_allclose( @@ -85,7 +85,7 @@ def test_mv(self): paddle.set_default_dtype('float64') origin_x = paddle.rand([64, 32]) mask = paddle.randint(0, 2, [64, 32]) - origin_x = origin_x * mask + origin_x = origin_x * mask.astype('float64') origin_vec = paddle.rand([32]) dense_x = origin_x.detach() @@ -107,7 +107,7 @@ def test_mv(self): ) np.testing.assert_allclose( sp_x.grad.to_dense().numpy(), - (dense_x.grad * mask).numpy(), + (dense_x.grad * mask.astype('float64')).numpy(), rtol=1e-05, ) np.testing.assert_allclose( From 7912dc47c5d5cb1a78dbf17c21a208a16780fd86 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Tue, 12 Mar 2024 07:01:47 +0000 Subject: [PATCH 17/34] fix test_llama_group_log_softmax.py --- test/ir/pir/cinn/symbolic/test_llama_group_log_softmax.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/ir/pir/cinn/symbolic/test_llama_group_log_softmax.py b/test/ir/pir/cinn/symbolic/test_llama_group_log_softmax.py index 602367573cf3b..ea6952a196099 100644 --- a/test/ir/pir/cinn/symbolic/test_llama_group_log_softmax.py +++ b/test/ir/pir/cinn/symbolic/test_llama_group_log_softmax.py @@ -34,7 +34,9 @@ def update_scores_for_generation( ): # update scores - unfinished_scores = (scores * length + next_scores) / (length + 1) + unfinished_scores = (scores * length.astype(scores.dtype) + next_scores) / ( + length + 1 + ).astype(scores.dtype) return unfinished_scores From 38adb7b0dfe88bc8611313f84c0484f33aca485f Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Mon, 18 Mar 2024 11:30:45 +0000 Subject: [PATCH 18/34] fix bug, and add 0-d + 0-d logic. --- paddle/fluid/pybind/eager_math_op_patch.cc | 711 +++++++++++++-------- python/paddle/base/layers/math_op_patch.py | 17 +- test/auto_parallel/test_to_static.py | 2 +- 3 files changed, 459 insertions(+), 271 deletions(-) diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index c91e99811e8a9..3a4be07dd0d93 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -240,32 +240,20 @@ static PyObject* tensor__add__method(TensorObject* self, paddle::Tensor other_tensor; if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((other_tensor_ref.shape().size() == 0 || - self_tensor_ref.shape().size() == 0) && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "add", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -276,8 +264,25 @@ static PyObject* tensor__add__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -367,25 +372,20 @@ static PyObject* tensor__sub__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "subtract", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -396,8 +396,23 @@ static PyObject* tensor__sub__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -485,25 +500,20 @@ static PyObject* tensor__rsub__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; if (PyCheckTensor(other_obj)) { - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - auto& self_tensor_ref = self->tensor; - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); + auto self_tensor_ref = self->tensor; // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "subtract", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -514,8 +524,25 @@ static PyObject* tensor__rsub__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -606,25 +633,20 @@ static PyObject* tensor__mul__method(TensorObject* self, // if one of the input is numpy or scalar, no need to do inplace cast. paddle::Tensor other_tensor; if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "multiply", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -635,8 +657,25 @@ static PyObject* tensor__mul__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -732,24 +771,20 @@ static PyObject* tensor__div__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "divide", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -760,8 +795,25 @@ static PyObject* tensor__div__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -871,24 +923,20 @@ static PyObject* tensor__rdiv__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && + self_tensor_ref.dtype() != other_tensor_ref.dtype()) { + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "divide", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -899,8 +947,25 @@ static PyObject* tensor__rdiv__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1008,25 +1073,20 @@ static PyObject* tensor__gt__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "greater_than", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -1037,8 +1097,25 @@ static PyObject* tensor__gt__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1139,25 +1216,20 @@ static PyObject* tensor__ge__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "greater_equal", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -1168,8 +1240,25 @@ static PyObject* tensor__ge__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1271,25 +1360,20 @@ static PyObject* tensor__mod__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "remainder", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -1300,8 +1384,25 @@ static PyObject* tensor__mod__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1527,25 +1628,20 @@ static PyObject* tensor__lt__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "less_than", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -1556,8 +1652,25 @@ static PyObject* tensor__lt__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1658,25 +1771,20 @@ static PyObject* tensor__le__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "less_equal", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -1687,8 +1795,25 @@ static PyObject* tensor__le__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1790,25 +1915,20 @@ static PyObject* tensor__floordiv__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "floor_divide", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -1819,8 +1939,25 @@ static PyObject* tensor__floordiv__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1911,25 +2048,20 @@ static PyObject* tensor__pow__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype("elementwise_pow", self_tensor_ref.dtype(), other_tensor_ref.dtype()); @@ -1941,8 +2073,25 @@ static PyObject* tensor__pow__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -2043,25 +2192,20 @@ static PyObject* tensor__rpow__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype("elementwise_pow", self_tensor_ref.dtype(), other_tensor_ref.dtype()); @@ -2073,8 +2217,25 @@ static PyObject* tensor__rpow__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -2175,25 +2336,20 @@ static PyObject* tensor__ne__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "not_equal", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -2204,8 +2360,25 @@ static PyObject* tensor__ne__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -2304,25 +2477,20 @@ static PyObject* tensor__eq__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { - auto& self_tensor_ref = self->tensor; - auto& other_tensor_ref = CastPyArg2Tensor(other_obj, 0); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } + auto self_tensor_ref = self->tensor; + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if (other_tensor_ref.shape().size() == 0 && + auto self_tensor_size = self_tensor_ref.shape().size(); + auto other_tensor_size = other_tensor_ref.shape().size(); + if ((self_tensor_size == 0 || other_tensor_size == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - // common major types follow with tensor: int32(tensor) + int64(scalar) = - // int32 - if (is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype())) { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } else { - // different major types follow with rule. + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), + other_tensor_ref.dtype()) || + (self_tensor_size == 0 && other_tensor_size == 0)) { phi::DataType promote_type = GetPromoteDtype( "equal", self_tensor_ref.dtype(), other_tensor_ref.dtype()); if (self_tensor_ref.dtype() != promote_type) { @@ -2333,8 +2501,25 @@ static PyObject* tensor__eq__method(TensorObject* self, eager_gil_scoped_release guard; other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor_ref.shape().size() == 0) { + eager_gil_scoped_release guard; + self_tensor_ref = + cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); + } else { + eager_gil_scoped_release guard; + other_tensor_ref = + cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); + } } } + + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { + ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); + } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { diff --git a/python/paddle/base/layers/math_op_patch.py b/python/paddle/base/layers/math_op_patch.py index 1ad5f999298ed..bd80b85d87fcd 100644 --- a/python/paddle/base/layers/math_op_patch.py +++ b/python/paddle/base/layers/math_op_patch.py @@ -637,16 +637,13 @@ def __impl__(self, other_var): if lhs_dtype != rhs_dtype: if method_name in SUPPORT_PROMOTION_OPS: - # for 0-d tensor, the logic same with Tensor + Scalar + # different major types or both 0-d tensor follow with T+T rule. if len(other_var.shape) == 0 or len(self.shape) == 0: - if core.is_common_dtype_for_scalar( + if not core.is_common_dtype_for_scalar( lhs_dtype, rhs_dtype + ) or ( + len(other_var.shape) == 0 and len(self.shape) == 0 ): - if len(self.shape) == 0: - self = astype(self, rhs_dtype) - else: - other_var = astype(other_var, lhs_dtype) - else: promote_type = core.get_promote_dtype( op_type, lhs_dtype, rhs_dtype ) @@ -654,6 +651,12 @@ def __impl__(self, other_var): self = astype(self, promote_type) if rhs_dtype != promote_type: other_var = astype(other_var, promote_type) + # common major types follow with tensor: int32(tensor) + int64(scalar) = int32 + else: + if len(self.shape) == 0: + self = astype(self, rhs_dtype) + else: + other_var = astype(other_var, lhs_dtype) elif core.need_type_promotion(lhs_dtype, rhs_dtype): # only report warning here, real promotion deal in Executor warnings.warn( diff --git a/test/auto_parallel/test_to_static.py b/test/auto_parallel/test_to_static.py index 66797b98caa37..a173745a50845 100644 --- a/test/auto_parallel/test_to_static.py +++ b/test/auto_parallel/test_to_static.py @@ -122,7 +122,7 @@ def test_apply_optimizer(self): for op in program_helper.main_program.block(0).ops if op.type == 'sgd' ] - self.assertEqual(len(all_ops), 37) + self.assertEqual(len(all_ops), 38) self.assertEqual(len(optimize_ops), len(sgd_ops)) program_helper.reset() From 437ca5b250eb16617315adde39ccef97315420d4 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Tue, 19 Mar 2024 02:52:53 +0000 Subject: [PATCH 19/34] rm print --- test/dygraph_to_static/test_tensor_methods.py | 1 - test/legacy_test/test_sparse_matmul_op.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/dygraph_to_static/test_tensor_methods.py b/test/dygraph_to_static/test_tensor_methods.py index a362fe73331f2..467b0f8c269de 100644 --- a/test/dygraph_to_static/test_tensor_methods.py +++ b/test/dygraph_to_static/test_tensor_methods.py @@ -134,7 +134,6 @@ def test_true_div(self): with enable_to_static_guard(False): dygraph_res = self._run() static_res = self._run() - print(dygraph_res, static_res) np.testing.assert_allclose(dygraph_res, static_res, rtol=1e-5) diff --git a/test/legacy_test/test_sparse_matmul_op.py b/test/legacy_test/test_sparse_matmul_op.py index 067d75de94b90..db942dead1b75 100644 --- a/test/legacy_test/test_sparse_matmul_op.py +++ b/test/legacy_test/test_sparse_matmul_op.py @@ -71,7 +71,7 @@ def check_result(self, x_shape, y_shape, format): sp_out.backward() np.testing.assert_allclose( sp_x.grad.to_dense().numpy(), - (dense_x.grad * mask).numpy(), + (dense_x.grad * mask.astype(dense_x.dtype)).numpy(), rtol=1e-05, ) np.testing.assert_allclose( From 80f21320f5680b04a7d69cc894b873dcf6ab7da6 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Wed, 20 Mar 2024 09:54:09 +0000 Subject: [PATCH 20/34] fix behavior of bool and int --- paddle/fluid/pybind/eager_math_op_patch.cc | 40 ++++++++++++++++++++++ paddle/phi/common/type_promotion.h | 2 +- python/paddle/base/layers/math_op_patch.py | 3 ++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index 3a4be07dd0d93..d83624d7ca5e3 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -220,6 +220,10 @@ static PyObject* tensor__add__method(TensorObject* self, self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); + } other = CastPyArg2Double(other_obj, "__add__", 0); } @@ -353,6 +357,10 @@ static PyObject* tensor__sub__method(TensorObject* self, self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); + } other = CastPyArg2Double(other_obj, "__sub__", 0); } { @@ -482,6 +490,10 @@ static PyObject* tensor__rsub__method(TensorObject* self, self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); + } other = CastPyArg2Double(other_obj, "__rsub__", 0); } { @@ -613,6 +625,10 @@ static PyObject* tensor__mul__method(TensorObject* self, self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); + } other = CastPyArg2Double(other_obj, "__mul__", 0); } { @@ -748,6 +764,10 @@ static PyObject* tensor__div__method(TensorObject* self, if (PyFloat_Check(other_obj)) { other = CastPyArg2Double(other_obj, "__div__", 0); } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); + } other = CastPyArg2Double(other_obj, "__div__", 0); } if (_supported_int_dtype_.find(self_tensor.dtype()) != @@ -894,6 +914,10 @@ static PyObject* tensor__rdiv__method(TensorObject* self, other_double = CastPyArg2Double(other_obj, "__rdiv__", 0); has_other_double = true; } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { // NOLINT + if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); + } other_double = CastPyArg2Double(other_obj, "__rdiv__", 0); has_other_double = true; } @@ -1336,6 +1360,10 @@ static PyObject* tensor__mod__method(TensorObject* self, self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); + } other_double = CastPyArg2Double(other_obj, "__mod__", 0); // NOLINT has_other_double = true; } @@ -1891,6 +1919,10 @@ static PyObject* tensor__floordiv__method(TensorObject* self, self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); + } other_double = CastPyArg2Double(other_obj, "__floordiv__", 0); has_other_double = true; } @@ -2030,6 +2062,10 @@ static PyObject* tensor__pow__method(TensorObject* self, self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); + } other = CastPyArg2Double(other_obj, "__pow__", 0); } { @@ -2168,6 +2204,10 @@ static PyObject* tensor__rpow__method(TensorObject* self, self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); + } other_double = CastPyArg2Double(other_obj, "__rpow__", 0); has_other_double = true; } diff --git a/paddle/phi/common/type_promotion.h b/paddle/phi/common/type_promotion.h index bca3880bd52aa..7bc50e90e7a4d 100644 --- a/paddle/phi/common/type_promotion.h +++ b/paddle/phi/common/type_promotion.h @@ -104,7 +104,7 @@ inline bool is_support_complex(DataType dtype) { inline bool is_support_int(DataType dtype) { if (dtype == DataType::UINT8 || dtype == DataType::INT8 || dtype == DataType::INT16 || dtype == DataType::INT32 || - dtype == DataType::INT64 || dtype == DataType::BOOL) { + dtype == DataType::INT64) { return true; } else { return false; diff --git a/python/paddle/base/layers/math_op_patch.py b/python/paddle/base/layers/math_op_patch.py index bd80b85d87fcd..3dbc058ce2486 100644 --- a/python/paddle/base/layers/math_op_patch.py +++ b/python/paddle/base/layers/math_op_patch.py @@ -594,6 +594,9 @@ def __impl__(self, other_var): and self.dtype in _supported_int_dtype_ ): self = astype(self, 'float32') + # bool(tensor) + int(scalar) will do type promotion to int64 + if self.dtype == core.VarDesc.VarType.BOOL: + self = astype(self, 'int64') # here use `scale` replace `elementwise` to get better performance # but only +, -, *, / can use this method if scalar_method is not None: From 8b086875a0e434b24268f1097bd873c77e9bb621 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Thu, 21 Mar 2024 12:35:52 +0000 Subject: [PATCH 21/34] add unittest for all type promotion. --- .../generator/eager_gen.py | 3 - python/paddle/base/framework.py | 3 - python/paddle/nn/functional/loss.py | 1 - python/paddle/tensor/logic.py | 5 - python/paddle/tensor/math.py | 5 +- ...st_tensor_scalar_type_promotion_dynamic.py | 427 ++- ...est_tensor_scalar_type_promotion_static.py | 435 ++- .../legacy_test/test_tensor_type_promotion.py | 2710 ++++++++++++++++- 8 files changed, 3490 insertions(+), 99 deletions(-) diff --git a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py index 6f803aed27a50..ef32fbcf2b0c6 100644 --- a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py +++ b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py @@ -93,9 +93,6 @@ "logical_and": ["x", "y"], "logical_or": ["x", "y"], "logical_xor": ["x", "y"], - "bitwise_and": ["x", "y"], - "bitwise_or": ["x", "y"], - "bitwise_xor": ["x", "y"], "fmax": ["x", "y"], "fmin": ["x", "y"], "maximum": ["x", "y"], diff --git a/python/paddle/base/framework.py b/python/paddle/base/framework.py index fd6ecc3cbaa88..6bf54b56a625a 100644 --- a/python/paddle/base/framework.py +++ b/python/paddle/base/framework.py @@ -81,9 +81,6 @@ "logical_and": ['X', 'Y'], "logical_or": ['X', 'Y'], "logical_xor": ['X', 'Y'], - "bitwise_and": ['X', 'Y'], - "bitwise_or": ['X', 'Y'], - "bitwise_xor": ['X', 'Y'], "elementwise_fmax": ['X', 'Y'], "elementwise_fmax_grad": ['X', 'Y'], "elementwise_fmin": ['X', 'Y'], diff --git a/python/paddle/nn/functional/loss.py b/python/paddle/nn/functional/loss.py index a7327f7703d6f..eb8137cfab195 100644 --- a/python/paddle/nn/functional/loss.py +++ b/python/paddle/nn/functional/loss.py @@ -1594,7 +1594,6 @@ def poisson_nll_loss( if not (input.shape == label.shape): raise ValueError("input's shape must equal to label's shape") - label = paddle.cast(label, input.dtype) loss_out = 0 if log_input: loss_out = paddle.exp(input) - label * input diff --git a/python/paddle/tensor/logic.py b/python/paddle/tensor/logic.py index 64fb7c0aadd97..dc8afb2a737c5 100755 --- a/python/paddle/tensor/logic.py +++ b/python/paddle/tensor/logic.py @@ -87,11 +87,6 @@ def _logical_op(op_name, x, y, out=None, name=None, binary_op=True): helper = LayerHelper(op_name, **locals()) - if binary_op and x.dtype != y.dtype: - raise ValueError( - f"(InvalidArgument) The DataType of {op_name} Op's Variable must be consistent, but received {x.dtype} and {y.dtype}." - ) - if out is None: out = helper.create_variable_for_type_inference(dtype=x.dtype) diff --git a/python/paddle/tensor/math.py b/python/paddle/tensor/math.py index 36793878b7d12..5a85a5768bd34 100644 --- a/python/paddle/tensor/math.py +++ b/python/paddle/tensor/math.py @@ -775,7 +775,10 @@ def logaddexp(x, y, name=None): [-0.30685282, -0.68673831, -0.87307199]) """ log_1p = paddle.log1p(paddle.exp(-paddle.abs(x - y))) - return log_1p + paddle.maximum(x, y).astype(log_1p.dtype) + maximum = paddle.maximum(x, y) + if maximum.dtype == paddle.int32 or maximum.dtype == paddle.int64: + maximum = maximum.astype(log_1p.dtype) + return log_1p + maximum def subtract(x, y, name=None): diff --git a/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py b/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py index 2f6541f67968e..a7f8f813eae2a 100644 --- a/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py +++ b/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# Copyright (c) 2024 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. @@ -20,11 +20,13 @@ # Support types are ref from `paddle.tensor.math` # - Related paddle dtypes: -# - int type: int64, (no test here: uint8, int8, int16, int32) -# - float type: float32, (no test here: float64) +# - int type: int64, uint8, int8, int16, int32 +# - float type: float16, bfloat16, float32, float64 +# - complex type: complex64, complex128 # - Python scalar dtypes: # - int(64) -# - float(64) +# - float(32) +# - complex(64) class TestTensorScalarTypePromotionDynamic(unittest.TestCase): @@ -313,5 +315,422 @@ def test_tensor_mod_scalar(self): self.check_operation(a, b, c, '%') +def create_test_case( + baseclass, + dtype, + expected_out_dtype_with_int=None, + expected_out_dtype_with_float=None, + expected_out_dtype_with_complex=None, +): + class TestPromotion(baseclass): + def set_dtype(self): + self.dtype = dtype + self.expected_out_dtype_with_int = expected_out_dtype_with_int + self.expected_out_dtype_with_float = expected_out_dtype_with_float + self.expected_out_dtype_with_complex = ( + expected_out_dtype_with_complex + ) + + cls_name = f"{baseclass.__name__}{dtype}" + TestPromotion.__name__ = cls_name + globals()[cls_name] = TestPromotion + + +class TestTensorAddScalar(unittest.TestCase): + def setUp(self): + self.set_dtype() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + self.generate_test_value() + out_int = self.value + 1 + out_float = self.value + 1.0 + out_complex = self.value + 2j + return out_int, out_float, out_complex + + def test_dtype_is_expected(self): + res_int, res_float, res_complex = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_int, + ) + self.assertEqual( + res_float.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_float, + ) + self.assertEqual( + res_complex.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_complex, + ) + + +create_test_case(TestTensorAddScalar, 'bool', 'int64', 'float32', 'complex64') +create_test_case(TestTensorAddScalar, 'uint8', 'uint8', 'float32', 'complex64') +create_test_case(TestTensorAddScalar, 'int8', 'int8', 'float32', 'complex64') +create_test_case(TestTensorAddScalar, 'int32', 'int32', 'float32', 'complex64') +create_test_case(TestTensorAddScalar, 'int64', 'int64', 'float32', 'complex64') +create_test_case( + TestTensorAddScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorAddScalar, 'bfloat16', 'bfloat16', 'bfloat16', 'complex64' +) +create_test_case( + TestTensorAddScalar, 'float64', 'float64', 'float64', 'complex128' +) +create_test_case( + TestTensorAddScalar, 'complex64', 'complex64', 'complex64', 'complex64' +) +create_test_case( + TestTensorAddScalar, 'complex128', 'complex128', 'complex128', 'complex128' +) + + +class TestTensorSubScalar(unittest.TestCase): + def setUp(self): + self.set_dtype() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + self.generate_test_value() + out_int = self.value - 1 + out_float = self.value - 1.0 + out_complex = self.value - 2j + return out_int, out_float, out_complex + + def test_dtype_is_expected(self): + res_int, res_float, res_complex = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_int, + ) + self.assertEqual( + res_float.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_float, + ) + self.assertEqual( + res_complex.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_complex, + ) + + +create_test_case(TestTensorSubScalar, 'bool', 'int64', 'float32', 'complex64') +create_test_case(TestTensorSubScalar, 'uint8', 'uint8', 'float32', 'complex64') +create_test_case(TestTensorSubScalar, 'int8', 'int8', 'float32', 'complex64') +create_test_case(TestTensorSubScalar, 'int32', 'int32', 'float32', 'complex64') +create_test_case(TestTensorSubScalar, 'int64', 'int64', 'float32', 'complex64') +create_test_case( + TestTensorSubScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorSubScalar, 'bfloat16', 'bfloat16', 'bfloat16', 'complex64' +) +create_test_case( + TestTensorSubScalar, 'float64', 'float64', 'float64', 'complex128' +) +create_test_case( + TestTensorSubScalar, 'complex64', 'complex64', 'complex64', 'complex64' +) +create_test_case( + TestTensorSubScalar, 'complex128', 'complex128', 'complex128', 'complex128' +) + + +class TestTensorDivScalar(unittest.TestCase): + def setUp(self): + self.set_dtype() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + self.generate_test_value() + out_int = self.value / 1 + out_float = self.value / 1.0 + out_complex = self.value / 2j + return out_int, out_float, out_complex + + def test_dtype_is_expected(self): + res_int, res_float, res_complex = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_int, + ) + self.assertEqual( + res_float.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_float, + ) + self.assertEqual( + res_complex.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_complex, + ) + + +create_test_case(TestTensorDivScalar, 'bool', 'float32', 'float32', 'complex64') +create_test_case( + TestTensorDivScalar, 'uint8', 'float32', 'float32', 'complex64' +) +create_test_case(TestTensorDivScalar, 'int8', 'float32', 'float32', 'complex64') +create_test_case( + TestTensorDivScalar, 'int32', 'float32', 'float32', 'complex64' +) +create_test_case( + TestTensorDivScalar, 'int64', 'float32', 'float32', 'complex64' +) +create_test_case( + TestTensorDivScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorDivScalar, 'bfloat16', 'bfloat16', 'bfloat16', 'complex64' +) +create_test_case( + TestTensorDivScalar, 'float64', 'float64', 'float64', 'complex128' +) +create_test_case( + TestTensorDivScalar, 'complex64', 'complex64', 'complex64', 'complex64' +) +create_test_case( + TestTensorDivScalar, 'complex128', 'complex128', 'complex128', 'complex128' +) + + +class TestTensorMulScalar(unittest.TestCase): + def setUp(self): + self.set_dtype() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + self.generate_test_value() + out_int = self.value * 1 + out_float = self.value * 1.0 + out_complex = self.value * 2j + return out_int, out_float, out_complex + + def test_dtype_is_expected(self): + res_int, res_float, res_complex = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_int, + ) + self.assertEqual( + res_float.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_float, + ) + self.assertEqual( + res_complex.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_complex, + ) + + +create_test_case(TestTensorMulScalar, 'bool', 'int64', 'float32', 'complex64') +create_test_case(TestTensorMulScalar, 'uint8', 'uint8', 'float32', 'complex64') +create_test_case(TestTensorMulScalar, 'int8', 'int8', 'float32', 'complex64') +create_test_case(TestTensorMulScalar, 'int32', 'int32', 'float32', 'complex64') +create_test_case(TestTensorMulScalar, 'int64', 'int64', 'float32', 'complex64') +create_test_case( + TestTensorMulScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorMulScalar, 'bfloat16', 'bfloat16', 'bfloat16', 'complex64' +) +create_test_case( + TestTensorMulScalar, 'float64', 'float64', 'float64', 'complex128' +) +create_test_case( + TestTensorMulScalar, 'complex64', 'complex64', 'complex64', 'complex64' +) +create_test_case( + TestTensorMulScalar, 'complex128', 'complex128', 'complex128', 'complex128' +) + + +class TestTensorPowScalar(unittest.TestCase): + def setUp(self): + self.set_dtype() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + self.generate_test_value() + out_int = self.value**1 + out_float = self.value**1.0 + # pow API not support complex + out_complex = None + return out_int, out_float, out_complex + + def test_dtype_is_expected(self): + res_int, res_float, res_complex = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_int, + ) + self.assertEqual( + res_float.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_float, + ) + # self.assertEqual(res_complex.dtype.__str__(), "paddle." + self.expected_out_dtype_with_complex) + + +# pow API not support uint8, int8, complex64, complex128 +create_test_case(TestTensorPowScalar, 'bool', 'int64', 'float32', 'complex64') +create_test_case(TestTensorPowScalar, 'int32', 'int32', 'float32', 'complex64') +create_test_case(TestTensorPowScalar, 'int64', 'int64', 'float32', 'complex64') +create_test_case( + TestTensorPowScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorPowScalar, 'bfloat16', 'bfloat16', 'bfloat16', 'complex64' +) +create_test_case( + TestTensorPowScalar, 'float64', 'float64', 'float64', 'complex128' +) + + +class TestTensorFloorDivScalar(unittest.TestCase): + def setUp(self): + self.set_dtype() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + self.generate_test_value() + out_int = self.value // 1 + out_float = self.value // 1.0 + # floor_div API not support complex + out_complex = None + return out_int, out_float, out_complex + + def test_dtype_is_expected(self): + res_int, res_float, res_complex = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_int, + ) + self.assertEqual( + res_float.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_float, + ) + # self.assertEqual(res_complex.dtype.__str__(), "paddle." + self.expected_out_dtype_with_complex) + + +# floor_div API not support complex64, complex128 +create_test_case( + TestTensorFloorDivScalar, 'bool', 'int64', 'float32', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'uint8', 'uint8', 'float32', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'int8', 'int8', 'float32', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'int32', 'int32', 'float32', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'int64', 'int64', 'float32', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'bfloat16', 'bfloat16', 'bfloat16', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'float64', 'float64', 'float64', 'complex128' +) + + +class TestTensorModScalar(unittest.TestCase): + def setUp(self): + self.set_dtype() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + self.generate_test_value() + out_int = self.value % 1 + out_float = self.value % 1.0 + # mod API not support complex + out_complex = None + return out_int, out_float, out_complex + + def test_dtype_is_expected(self): + res_int, res_float, res_complex = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_int, + ) + self.assertEqual( + res_float.dtype.__str__(), + "paddle." + self.expected_out_dtype_with_float, + ) + # self.assertEqual(res_complex.dtype.__str__(), "paddle." + self.expected_out_dtype_with_complex) + + +# mod API not support uint8, int8, complex64, complex128 +create_test_case(TestTensorModScalar, 'bool', 'int64', 'float32', 'complex64') +create_test_case(TestTensorModScalar, 'int32', 'int32', 'float32', 'complex64') +create_test_case(TestTensorModScalar, 'int64', 'int64', 'float32', 'complex64') +create_test_case( + TestTensorModScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorModScalar, 'bfloat16', 'bfloat16', 'bfloat16', 'complex64' +) +create_test_case( + TestTensorModScalar, 'float64', 'float64', 'float64', 'complex128' +) + if __name__ == '__main__': unittest.main() diff --git a/test/legacy_test/test_tensor_scalar_type_promotion_static.py b/test/legacy_test/test_tensor_scalar_type_promotion_static.py index 8ec524e579e7d..06e7192f1d485 100644 --- a/test/legacy_test/test_tensor_scalar_type_promotion_static.py +++ b/test/legacy_test/test_tensor_scalar_type_promotion_static.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# Copyright (c) 2024 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. @@ -21,11 +21,13 @@ # Support types are ref from `paddle.tensor.math` # - Related paddle dtypes: -# - int type: int64, (no test here: uint8, int8, int16, int32) -# - float type: float32, (no test here: float64) +# - int type: int64, uint8, int8, int16, int32 +# - float type: float16, bfloat16, float32, float64 +# - complex type: complex64, complex128 # - Python scalar dtypes: # - int(64) -# - float(64) +# - float(32) +# - complex(64) class TestTensorScalarTypePromotionStatic(unittest.TestCase): @@ -363,5 +365,430 @@ def test_tensor_mod_scalar(self): self.check_operation(a, b, c, '%') +def create_test_case( + baseclass, + dtype, + expected_out_dtype_with_int=None, + expected_out_dtype_with_float=None, + expected_out_dtype_with_complex=None, +): + class TestPromotion(baseclass): + def set_dtype(self): + self.dtype = dtype + self.expected_out_dtype_with_int = expected_out_dtype_with_int + self.expected_out_dtype_with_float = expected_out_dtype_with_float + # static not support compute with scalar complex + self.expected_out_dtype_with_complex = ( + expected_out_dtype_with_complex + ) + + cls_name = f"{baseclass.__name__}{dtype}" + TestPromotion.__name__ = cls_name + globals()[cls_name] = TestPromotion + + +class TestTensorAddScalar(unittest.TestCase): + def setUp(self): + paddle.enable_static() + self.set_dtype() + self.exe = paddle.static.Executor() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + out_int = self.value + 1 + out_float = self.value + 1.0 + # out_complex = self.value + 2j + res = self.exe.run(prog, fetch_list=[out_int, out_float]) + return res + + def test_dtype_is_expected(self): + res_int, res_float = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), self.expected_out_dtype_with_int + ) + self.assertEqual( + res_float.dtype.__str__(), self.expected_out_dtype_with_float + ) + # self.assertEqual(res_complex.dtype.__str__(), self.expected_out_dtype_with_complex) + + +create_test_case(TestTensorAddScalar, 'bool', 'int64', 'float32', 'complex64') +create_test_case(TestTensorAddScalar, 'uint8', 'uint8', 'float32', 'complex64') +create_test_case(TestTensorAddScalar, 'int8', 'int8', 'float32', 'complex64') +create_test_case(TestTensorAddScalar, 'int32', 'int32', 'float32', 'complex64') +create_test_case(TestTensorAddScalar, 'int64', 'int64', 'float32', 'complex64') +create_test_case( + TestTensorAddScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorAddScalar, 'bfloat16', 'uint16', 'uint16', 'complex64' +) +create_test_case( + TestTensorAddScalar, 'float64', 'float64', 'float64', 'complex128' +) +create_test_case( + TestTensorAddScalar, 'complex64', 'complex64', 'complex64', 'complex64' +) +create_test_case( + TestTensorAddScalar, 'complex128', 'complex128', 'complex128', 'complex128' +) + + +class TestTensorSubScalar(unittest.TestCase): + def setUp(self): + paddle.enable_static() + self.set_dtype() + self.exe = paddle.static.Executor() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + out_int = self.value - 1 + out_float = self.value - 1.0 + # out_complex = self.value - 2j + res = self.exe.run(prog, fetch_list=[out_int, out_float]) + return res + + def test_dtype_is_expected(self): + res_int, res_float = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), self.expected_out_dtype_with_int + ) + self.assertEqual( + res_float.dtype.__str__(), self.expected_out_dtype_with_float + ) + # self.assertEqual(res_complex.dtype.__str__(), self.expected_out_dtype_with_complex) + + +create_test_case(TestTensorSubScalar, 'bool', 'int64', 'float32', 'complex64') +create_test_case(TestTensorSubScalar, 'uint8', 'uint8', 'float32', 'complex64') +create_test_case(TestTensorSubScalar, 'int8', 'int8', 'float32', 'complex64') +create_test_case(TestTensorSubScalar, 'int32', 'int32', 'float32', 'complex64') +create_test_case(TestTensorSubScalar, 'int64', 'int64', 'float32', 'complex64') +create_test_case( + TestTensorSubScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorSubScalar, 'bfloat16', 'uint16', 'uint16', 'complex64' +) +create_test_case( + TestTensorSubScalar, 'float64', 'float64', 'float64', 'complex128' +) +create_test_case( + TestTensorSubScalar, 'complex64', 'complex64', 'complex64', 'complex64' +) +create_test_case( + TestTensorSubScalar, 'complex128', 'complex128', 'complex128', 'complex128' +) + + +class TestTensorDivScalar(unittest.TestCase): + def setUp(self): + paddle.enable_static() + self.set_dtype() + self.exe = paddle.static.Executor() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + out_int = self.value / 1 + out_float = self.value / 1.0 + # out_complex = self.value / 2j + res = self.exe.run(prog, fetch_list=[out_int, out_float]) + return res + + def test_dtype_is_expected(self): + res_int, res_float = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), self.expected_out_dtype_with_int + ) + self.assertEqual( + res_float.dtype.__str__(), self.expected_out_dtype_with_float + ) + # self.assertEqual(res_complex.dtype.__str__(), self.expected_out_dtype_with_complex) + + +create_test_case(TestTensorDivScalar, 'bool', 'float32', 'float32', 'complex64') +create_test_case( + TestTensorDivScalar, 'uint8', 'float32', 'float32', 'complex64' +) +create_test_case(TestTensorDivScalar, 'int8', 'float32', 'float32', 'complex64') +create_test_case( + TestTensorDivScalar, 'int32', 'float32', 'float32', 'complex64' +) +create_test_case( + TestTensorDivScalar, 'int64', 'float32', 'float32', 'complex64' +) +create_test_case( + TestTensorDivScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorDivScalar, 'bfloat16', 'uint16', 'uint16', 'complex64' +) +create_test_case( + TestTensorDivScalar, 'float64', 'float64', 'float64', 'complex128' +) +create_test_case( + TestTensorDivScalar, 'complex64', 'complex64', 'complex64', 'complex64' +) +create_test_case( + TestTensorDivScalar, 'complex128', 'complex128', 'complex128', 'complex128' +) + + +class TestTensorMulScalar(unittest.TestCase): + def setUp(self): + paddle.enable_static() + self.set_dtype() + self.exe = paddle.static.Executor() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + out_int = self.value * 1 + out_float = self.value * 1.0 + # out_complex = self.value * 2j + res = self.exe.run(prog, fetch_list=[out_int, out_float]) + return res + + def test_dtype_is_expected(self): + res_int, res_float = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), self.expected_out_dtype_with_int + ) + self.assertEqual( + res_float.dtype.__str__(), self.expected_out_dtype_with_float + ) + # self.assertEqual(res_complex.dtype.__str__(), self.expected_out_dtype_with_complex) + + +create_test_case(TestTensorMulScalar, 'bool', 'int64', 'float32', 'complex64') +create_test_case(TestTensorMulScalar, 'uint8', 'uint8', 'float32', 'complex64') +create_test_case(TestTensorMulScalar, 'int8', 'int8', 'float32', 'complex64') +create_test_case(TestTensorMulScalar, 'int32', 'int32', 'float32', 'complex64') +create_test_case(TestTensorMulScalar, 'int64', 'int64', 'float32', 'complex64') +create_test_case( + TestTensorMulScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorMulScalar, 'bfloat16', 'uint16', 'uint16', 'complex64' +) +create_test_case( + TestTensorMulScalar, 'float64', 'float64', 'float64', 'complex128' +) +create_test_case( + TestTensorMulScalar, 'complex64', 'complex64', 'complex64', 'complex64' +) +create_test_case( + TestTensorMulScalar, 'complex128', 'complex128', 'complex128', 'complex128' +) + + +class TestTensorPowScalar(unittest.TestCase): + def setUp(self): + paddle.enable_static() + self.set_dtype() + self.exe = paddle.static.Executor() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + out_int = self.value**1 + out_float = self.value**1.0 + # pow API not support complex + res = self.exe.run(prog, fetch_list=[out_int, out_float]) + return res + + def test_dtype_is_expected(self): + res_int, res_float = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), self.expected_out_dtype_with_int + ) + self.assertEqual( + res_float.dtype.__str__(), self.expected_out_dtype_with_float + ) + # self.assertEqual(res_complex.dtype.__str__(), self.expected_out_dtype_with_complex) + + +# pow API not support uint8, int8, complex64, complex128 +create_test_case(TestTensorPowScalar, 'bool', 'int64', 'float32', 'complex64') +create_test_case(TestTensorPowScalar, 'int32', 'int32', 'float32', 'complex64') +create_test_case(TestTensorPowScalar, 'int64', 'int64', 'float32', 'complex64') +create_test_case( + TestTensorPowScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorPowScalar, 'bfloat16', 'uint16', 'uint16', 'complex64' +) +create_test_case( + TestTensorPowScalar, 'float64', 'float64', 'float64', 'complex128' +) + + +class TestTensorFloorDivScalar(unittest.TestCase): + def setUp(self): + paddle.enable_static() + self.set_dtype() + self.exe = paddle.static.Executor() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + out_int = self.value // 1 + out_float = self.value // 1.0 + # floor_div API not support complex + res = self.exe.run(prog, fetch_list=[out_int, out_float]) + return res + + def test_dtype_is_expected(self): + res_int, res_float = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), self.expected_out_dtype_with_int + ) + self.assertEqual( + res_float.dtype.__str__(), self.expected_out_dtype_with_float + ) + # self.assertEqual(res_complex.dtype.__str__(), self.expected_out_dtype_with_complex) + + +# floor_div API not support complex64, complex128 +create_test_case( + TestTensorFloorDivScalar, 'bool', 'int64', 'float32', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'uint8', 'uint8', 'float32', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'int8', 'int8', 'float32', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'int32', 'int32', 'float32', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'int64', 'int64', 'float32', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'bfloat16', 'uint16', 'uint16', 'complex64' +) +create_test_case( + TestTensorFloorDivScalar, 'float64', 'float64', 'float64', 'complex128' +) + + +class TestTensorModScalar(unittest.TestCase): + def setUp(self): + paddle.enable_static() + self.set_dtype() + self.exe = paddle.static.Executor() + + def set_dtype(self): + self.dtype = 'float32' + self.expected_out_dtype_with_int = 'float32' + self.expected_out_dtype_with_float = 'float32' + self.expected_out_dtype_with_complex = 'complex64' + + def generate_test_value(self): + self.value = paddle.rand([2, 3, 4]).astype(self.dtype) + + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + out_int = self.value % 1 + out_float = self.value % 1.0 + # mod API not support complex + res = self.exe.run(prog, fetch_list=[out_int, out_float]) + return res + + def test_dtype_is_expected(self): + res_int, res_float = self.run_api() + self.assertEqual( + res_int.dtype.__str__(), self.expected_out_dtype_with_int + ) + self.assertEqual( + res_float.dtype.__str__(), self.expected_out_dtype_with_float + ) + # self.assertEqual(res_complex.dtype.__str__(), self.expected_out_dtype_with_complex) + + +# mod API not support uint8, int8, complex64, complex128 +create_test_case(TestTensorModScalar, 'bool', 'int64', 'float32', 'complex64') +create_test_case(TestTensorModScalar, 'int32', 'int32', 'float32', 'complex64') +create_test_case(TestTensorModScalar, 'int64', 'int64', 'float32', 'complex64') +create_test_case( + TestTensorModScalar, 'float16', 'float16', 'float16', 'complex64' +) +create_test_case( + TestTensorModScalar, 'bfloat16', 'uint16', 'uint16', 'complex64' +) +create_test_case( + TestTensorModScalar, 'float64', 'float64', 'float64', 'complex128' +) + + if __name__ == '__main__': unittest.main() diff --git a/test/legacy_test/test_tensor_type_promotion.py b/test/legacy_test/test_tensor_type_promotion.py index d830c08c94063..d9524529941a3 100644 --- a/test/legacy_test/test_tensor_type_promotion.py +++ b/test/legacy_test/test_tensor_type_promotion.py @@ -63,11 +63,10 @@ def set_dtype(self): globals()[cls_name] = TestPromotion -class TestOperatorOverloadAddInStatic(unittest.TestCase): +class TestOperatorOverloadAddInDygraph(unittest.TestCase): def setUp(self): - paddle.enable_static() + paddle.disable_static() self.set_dtype() - self.exe = paddle.static.Executor() def set_dtype(self): self.ldtype = 'float32' @@ -79,168 +78,2723 @@ def generate_test_value(self): self.r_value = (paddle.randn((4, 3, 2)) * 10).astype(self.rdtype) def run_api(self): - prog = paddle.static.Program() - with paddle.static.program_guard(prog): - self.generate_test_value() + self.generate_test_value() - out = self.l_value + self.r_value - out_reverse = self.r_value + self.l_value + out = self.l_value + self.r_value + out_reverse = self.r_value + self.l_value - res = self.exe.run(prog, fetch_list=[out, out_reverse]) - return res + return out, out_reverse def test_dtype_is_expected(self): - res = self.run_api() - self.assertEqual(res[0].dtype.__str__(), self.expected_out_dtype) - self.assertEqual(res[1].dtype.__str__(), self.expected_out_dtype) + out, out_reverse = self.run_api() + self.assertEqual( + out.dtype.__str__(), "paddle." + self.expected_out_dtype + ) + self.assertEqual( + out_reverse.dtype.__str__(), "paddle." + self.expected_out_dtype + ) create_test_case( - TestOperatorOverloadAddInStatic, 'float16', 'float32', 'float32' + TestOperatorOverloadAddInDygraph, 'float16', 'float32', 'float32' ) create_test_case( - TestOperatorOverloadAddInStatic, 'float16', 'float64', 'float64' + TestOperatorOverloadAddInDygraph, 'float16', 'float64', 'float64' ) create_test_case( - TestOperatorOverloadAddInStatic, 'float32', 'float64', 'float64' + TestOperatorOverloadAddInDygraph, 'float32', 'float64', 'float64' ) - if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): create_test_case( - TestOperatorOverloadAddInStatic, 'bfloat16', 'float16', 'float32' + TestOperatorOverloadAddInDygraph, 'bfloat16', 'float16', 'float32' ) create_test_case( - TestOperatorOverloadAddInStatic, 'bfloat16', 'float32', 'float32' + TestOperatorOverloadAddInDygraph, 'bfloat16', 'float32', 'float32' ) create_test_case( - TestOperatorOverloadAddInStatic, 'bfloat16', 'float64', 'float64' + TestOperatorOverloadAddInDygraph, 'bfloat16', 'float64', 'float64' + ) + create_test_case( + TestOperatorOverloadAddInDygraph, 'bfloat16', 'complex64', 'complex64' + ) + create_test_case( + TestOperatorOverloadAddInDygraph, 'bfloat16', 'complex128', 'complex128' ) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex64', 'bool', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex64', 'int8', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex64', 'uint8', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex64', 'int16', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex64', 'int32', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex64', 'int64', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex64', 'float16', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex64', 'float32', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex64', 'float64', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex64', 'complex128', 'complex128' +) -class TestAPIAddInStatic(TestOperatorOverloadAddInStatic): - def run_api(self): - prog = paddle.static.Program() - with paddle.static.program_guard(prog): - self.generate_test_value() +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex128', 'bool', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex128', 'int8', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex128', 'uint8', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex128', 'int16', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex128', 'int32', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex128', 'int64', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex128', 'float16', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex128', 'float32', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInDygraph, 'complex128', 'float64', 'complex128' +) - out = paddle.add(self.l_value, self.r_value) - out_reverse = paddle.add(self.r_value, self.l_value) - res = self.exe.run(prog, fetch_list=[out, out_reverse]) - return res +class TestAPIAddInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + out = paddle.add(self.l_value, self.r_value) + out_reverse = paddle.add(self.r_value, self.l_value) -create_test_case(TestAPIAddInStatic, 'float16', 'float32', 'float32') -create_test_case(TestAPIAddInStatic, 'float16', 'float64', 'float64') + return out, out_reverse -create_test_case(TestAPIAddInStatic, 'float32', 'float64', 'float64') +create_test_case(TestAPIAddInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIAddInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIAddInDygraph, 'float32', 'float64', 'float64') if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): - create_test_case(TestAPIAddInStatic, 'bfloat16', 'float16', 'float32') - create_test_case(TestAPIAddInStatic, 'bfloat16', 'float32', 'float32') - create_test_case(TestAPIAddInStatic, 'bfloat16', 'float64', 'float64') + create_test_case(TestAPIAddInDygraph, 'bfloat16', 'float16', 'float32') + create_test_case(TestAPIAddInDygraph, 'bfloat16', 'float32', 'float32') + create_test_case(TestAPIAddInDygraph, 'bfloat16', 'float64', 'float64') + create_test_case(TestAPIAddInDygraph, 'bfloat16', 'complex64', 'complex64') + create_test_case( + TestAPIAddInDygraph, 'bfloat16', 'complex128', 'complex128' + ) +create_test_case(TestAPIAddInDygraph, 'complex64', 'bool', 'complex64') +create_test_case(TestAPIAddInDygraph, 'complex64', 'int8', 'complex64') +create_test_case(TestAPIAddInDygraph, 'complex64', 'uint8', 'complex64') +create_test_case(TestAPIAddInDygraph, 'complex64', 'int16', 'complex64') +create_test_case(TestAPIAddInDygraph, 'complex64', 'int32', 'complex64') +create_test_case(TestAPIAddInDygraph, 'complex64', 'int64', 'complex64') +create_test_case(TestAPIAddInDygraph, 'complex64', 'float16', 'complex64') +create_test_case(TestAPIAddInDygraph, 'complex64', 'float32', 'complex64') +create_test_case(TestAPIAddInDygraph, 'complex64', 'float64', 'complex128') +create_test_case(TestAPIAddInDygraph, 'complex64', 'complex128', 'complex128') -class TestOperatorOverloadSubInStatic(TestOperatorOverloadAddInStatic): +create_test_case(TestAPIAddInDygraph, 'complex128', 'bool', 'complex128') +create_test_case(TestAPIAddInDygraph, 'complex128', 'int8', 'complex128') +create_test_case(TestAPIAddInDygraph, 'complex128', 'uint8', 'complex128') +create_test_case(TestAPIAddInDygraph, 'complex128', 'int16', 'complex128') +create_test_case(TestAPIAddInDygraph, 'complex128', 'int32', 'complex128') +create_test_case(TestAPIAddInDygraph, 'complex128', 'int64', 'complex128') +create_test_case(TestAPIAddInDygraph, 'complex128', 'float16', 'complex128') +create_test_case(TestAPIAddInDygraph, 'complex128', 'float32', 'complex128') +create_test_case(TestAPIAddInDygraph, 'complex128', 'float64', 'complex128') + + +class TestOperatorOverloadSubInDygraph(TestOperatorOverloadAddInDygraph): def run_api(self): - prog = paddle.static.Program() - with paddle.static.program_guard(prog): - self.generate_test_value() + self.generate_test_value() - out = self.l_value - self.r_value - out_reverse = self.r_value - self.l_value + out = self.l_value - self.r_value + out_reverse = self.r_value - self.l_value - res = self.exe.run(prog, fetch_list=[out, out_reverse]) - return res + return out, out_reverse create_test_case( - TestOperatorOverloadSubInStatic, 'float16', 'float32', 'float32' + TestOperatorOverloadSubInDygraph, 'float16', 'float32', 'float32' ) create_test_case( - TestOperatorOverloadSubInStatic, 'float16', 'float64', 'float64' + TestOperatorOverloadSubInDygraph, 'float16', 'float64', 'float64' ) create_test_case( - TestOperatorOverloadSubInStatic, 'float32', 'float64', 'float64' + TestOperatorOverloadSubInDygraph, 'float32', 'float64', 'float64' ) - if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): create_test_case( - TestOperatorOverloadSubInStatic, 'bfloat16', 'float16', 'float32' + TestOperatorOverloadSubInDygraph, 'bfloat16', 'float16', 'float32' ) create_test_case( - TestOperatorOverloadSubInStatic, 'bfloat16', 'float32', 'float32' + TestOperatorOverloadSubInDygraph, 'bfloat16', 'float32', 'float32' ) create_test_case( - TestOperatorOverloadSubInStatic, 'bfloat16', 'float64', 'float64' + TestOperatorOverloadSubInDygraph, 'bfloat16', 'float64', 'float64' + ) + create_test_case( + TestOperatorOverloadSubInDygraph, 'bfloat16', 'complex64', 'complex64' + ) + create_test_case( + TestOperatorOverloadSubInDygraph, 'bfloat16', 'complex128', 'complex128' ) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex64', 'bool', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex64', 'int8', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex64', 'uint8', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex64', 'int16', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex64', 'int32', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex64', 'int64', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex64', 'float16', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex64', 'float32', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex64', 'float64', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex64', 'complex128', 'complex128' +) -class TestAPISubInStatic(TestOperatorOverloadAddInStatic): +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex128', 'bool', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex128', 'int8', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex128', 'uint8', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex128', 'int16', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex128', 'int32', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex128', 'int64', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex128', 'float16', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex128', 'float32', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInDygraph, 'complex128', 'float64', 'complex128' +) + + +class TestAPISubInDygraph(TestOperatorOverloadAddInDygraph): def run_api(self): - prog = paddle.static.Program() - with paddle.static.program_guard(prog): - self.generate_test_value() + self.generate_test_value() - out = paddle.subtract(self.l_value, self.r_value) - out_reverse = paddle.subtract(self.r_value, self.l_value) + out = paddle.subtract(self.l_value, self.r_value) + out_reverse = paddle.subtract(self.r_value, self.l_value) - res = self.exe.run(prog, fetch_list=[out, out_reverse]) - return res + return out, out_reverse -create_test_case(TestAPISubInStatic, 'float16', 'float32', 'float32') -create_test_case(TestAPISubInStatic, 'float16', 'float64', 'float64') +create_test_case(TestAPISubInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPISubInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPISubInDygraph, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case(TestAPISubInDygraph, 'bfloat16', 'float16', 'float32') + create_test_case(TestAPISubInDygraph, 'bfloat16', 'float32', 'float32') + create_test_case(TestAPISubInDygraph, 'bfloat16', 'float64', 'float64') + create_test_case(TestAPISubInDygraph, 'bfloat16', 'complex64', 'complex64') + create_test_case( + TestAPISubInDygraph, 'bfloat16', 'complex128', 'complex128' + ) + +create_test_case(TestAPISubInDygraph, 'complex64', 'bool', 'complex64') +create_test_case(TestAPISubInDygraph, 'complex64', 'int8', 'complex64') +create_test_case(TestAPISubInDygraph, 'complex64', 'uint8', 'complex64') +create_test_case(TestAPISubInDygraph, 'complex64', 'int16', 'complex64') +create_test_case(TestAPISubInDygraph, 'complex64', 'int32', 'complex64') +create_test_case(TestAPISubInDygraph, 'complex64', 'int64', 'complex64') +create_test_case(TestAPISubInDygraph, 'complex64', 'float16', 'complex64') +create_test_case(TestAPISubInDygraph, 'complex64', 'float32', 'complex64') +create_test_case(TestAPISubInDygraph, 'complex64', 'float64', 'complex128') +create_test_case(TestAPISubInDygraph, 'complex64', 'complex128', 'complex128') + +create_test_case(TestAPISubInDygraph, 'complex128', 'bool', 'complex128') +create_test_case(TestAPISubInDygraph, 'complex128', 'int8', 'complex128') +create_test_case(TestAPISubInDygraph, 'complex128', 'uint8', 'complex128') +create_test_case(TestAPISubInDygraph, 'complex128', 'int16', 'complex128') +create_test_case(TestAPISubInDygraph, 'complex128', 'int32', 'complex128') +create_test_case(TestAPISubInDygraph, 'complex128', 'int64', 'complex128') +create_test_case(TestAPISubInDygraph, 'complex128', 'float16', 'complex128') +create_test_case(TestAPISubInDygraph, 'complex128', 'float32', 'complex128') +create_test_case(TestAPISubInDygraph, 'complex128', 'float64', 'complex128') -create_test_case(TestAPIAddInStatic, 'float32', 'float64', 'float64') +class TestOperatorOverloadMulInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = self.l_value * self.r_value + out_reverse = self.r_value * self.l_value + + return out, out_reverse + + +create_test_case( + TestOperatorOverloadMulInDygraph, 'float16', 'float32', 'float32' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'float16', 'float64', 'float64' +) + +create_test_case( + TestOperatorOverloadMulInDygraph, 'float32', 'float64', 'float64' +) if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): - create_test_case(TestAPISubInStatic, 'bfloat16', 'float16', 'float32') - create_test_case(TestAPISubInStatic, 'bfloat16', 'float32', 'float32') - create_test_case(TestAPISubInStatic, 'bfloat16', 'float64', 'float64') + create_test_case( + TestOperatorOverloadMulInDygraph, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestOperatorOverloadMulInDygraph, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestOperatorOverloadMulInDygraph, 'bfloat16', 'float64', 'float64' + ) + create_test_case( + TestOperatorOverloadMulInDygraph, 'bfloat16', 'complex64', 'complex64' + ) + create_test_case( + TestOperatorOverloadMulInDygraph, 'bfloat16', 'complex128', 'complex128' + ) + +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex64', 'bool', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex64', 'int8', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex64', 'uint8', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex64', 'int16', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex64', 'int32', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex64', 'int64', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex64', 'float16', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex64', 'float32', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex64', 'float64', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex64', 'complex128', 'complex128' +) + +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex128', 'bool', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex128', 'int8', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex128', 'uint8', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex128', 'int16', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex128', 'int32', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex128', 'int64', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex128', 'float16', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex128', 'float32', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInDygraph, 'complex128', 'float64', 'complex128' +) -class TestOperatorOverloadMulInStatic(TestOperatorOverloadAddInStatic): +class TestAPIMulInDygraph(TestOperatorOverloadAddInDygraph): def run_api(self): - prog = paddle.static.Program() - with paddle.static.program_guard(prog): - self.generate_test_value() + self.generate_test_value() - out = self.l_value * self.r_value - out_reverse = self.r_value * self.l_value + out = paddle.multiply(self.l_value, self.r_value) + out_reverse = paddle.multiply(self.r_value, self.l_value) - res = self.exe.run(prog, fetch_list=[out, out_reverse]) - return res + return out, out_reverse + + +create_test_case(TestAPIMulInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIMulInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIMulInDygraph, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case(TestAPIMulInDygraph, 'bfloat16', 'float16', 'float32') + create_test_case(TestAPIMulInDygraph, 'bfloat16', 'float32', 'float32') + create_test_case(TestAPIMulInDygraph, 'bfloat16', 'float64', 'float64') + create_test_case(TestAPIMulInDygraph, 'bfloat16', 'complex64', 'complex64') + create_test_case( + TestAPIMulInDygraph, 'bfloat16', 'complex128', 'complex128' + ) + +create_test_case(TestAPIMulInDygraph, 'complex64', 'bool', 'complex64') +create_test_case(TestAPIMulInDygraph, 'complex64', 'int8', 'complex64') +create_test_case(TestAPIMulInDygraph, 'complex64', 'uint8', 'complex64') +create_test_case(TestAPIMulInDygraph, 'complex64', 'int16', 'complex64') +create_test_case(TestAPIMulInDygraph, 'complex64', 'int32', 'complex64') +create_test_case(TestAPIMulInDygraph, 'complex64', 'int64', 'complex64') +create_test_case(TestAPIMulInDygraph, 'complex64', 'float16', 'complex64') +create_test_case(TestAPIMulInDygraph, 'complex64', 'float32', 'complex64') +create_test_case(TestAPIMulInDygraph, 'complex64', 'float64', 'complex128') +create_test_case(TestAPIMulInDygraph, 'complex64', 'complex128', 'complex128') + +create_test_case(TestAPIMulInDygraph, 'complex128', 'bool', 'complex128') +create_test_case(TestAPIMulInDygraph, 'complex128', 'int8', 'complex128') +create_test_case(TestAPIMulInDygraph, 'complex128', 'uint8', 'complex128') +create_test_case(TestAPIMulInDygraph, 'complex128', 'int16', 'complex128') +create_test_case(TestAPIMulInDygraph, 'complex128', 'int32', 'complex128') +create_test_case(TestAPIMulInDygraph, 'complex128', 'int64', 'complex128') +create_test_case(TestAPIMulInDygraph, 'complex128', 'float16', 'complex128') +create_test_case(TestAPIMulInDygraph, 'complex128', 'float32', 'complex128') +create_test_case(TestAPIMulInDygraph, 'complex128', 'float64', 'complex128') + + +class TestOperatorOverloadDivInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = self.l_value / self.r_value + out_reverse = self.r_value / self.l_value + + return out, out_reverse create_test_case( - TestOperatorOverloadMulInStatic, 'float16', 'float32', 'float32' + TestOperatorOverloadDivInDygraph, 'float16', 'float32', 'float32' ) create_test_case( - TestOperatorOverloadMulInStatic, 'float16', 'float64', 'float64' + TestOperatorOverloadDivInDygraph, 'float16', 'float64', 'float64' ) create_test_case( - TestOperatorOverloadMulInStatic, 'float32', 'float64', 'float64' + TestOperatorOverloadDivInDygraph, 'float32', 'float64', 'float64' ) if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): create_test_case( - TestOperatorOverloadMulInStatic, 'bfloat16', 'float16', 'float32' + TestOperatorOverloadDivInDygraph, 'bfloat16', 'float16', 'float32' ) create_test_case( - TestOperatorOverloadMulInStatic, 'bfloat16', 'float32', 'float32' + TestOperatorOverloadDivInDygraph, 'bfloat16', 'float32', 'float32' ) create_test_case( - TestOperatorOverloadMulInStatic, 'bfloat16', 'float64', 'float64' + TestOperatorOverloadDivInDygraph, 'bfloat16', 'float64', 'float64' + ) + create_test_case( + TestOperatorOverloadDivInDygraph, 'bfloat16', 'complex64', 'complex64' ) + create_test_case( + TestOperatorOverloadDivInDygraph, 'bfloat16', 'complex128', 'complex128' + ) + +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex64', 'bool', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex64', 'int8', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex64', 'uint8', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex64', 'int16', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex64', 'int32', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex64', 'int64', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex64', 'float16', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex64', 'float32', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex64', 'float64', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex64', 'complex128', 'complex128' +) + +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex128', 'bool', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex128', 'int8', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex128', 'uint8', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex128', 'int16', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex128', 'int32', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex128', 'int64', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex128', 'float16', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex128', 'float32', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInDygraph, 'complex128', 'float64', 'complex128' +) + + +class TestAPIDivInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.divide(self.l_value, self.r_value) + out_reverse = paddle.divide(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIDivInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIDivInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIDivInDygraph, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case(TestAPIDivInDygraph, 'bfloat16', 'float16', 'float32') + create_test_case(TestAPIDivInDygraph, 'bfloat16', 'float32', 'float32') + create_test_case(TestAPIDivInDygraph, 'bfloat16', 'float64', 'float64') + create_test_case(TestAPIDivInDygraph, 'bfloat16', 'complex64', 'complex64') + create_test_case( + TestAPIDivInDygraph, 'bfloat16', 'complex128', 'complex128' + ) + +create_test_case(TestAPIDivInDygraph, 'complex64', 'bool', 'complex64') +create_test_case(TestAPIDivInDygraph, 'complex64', 'int8', 'complex64') +create_test_case(TestAPIDivInDygraph, 'complex64', 'uint8', 'complex64') +create_test_case(TestAPIDivInDygraph, 'complex64', 'int16', 'complex64') +create_test_case(TestAPIDivInDygraph, 'complex64', 'int32', 'complex64') +create_test_case(TestAPIDivInDygraph, 'complex64', 'int64', 'complex64') +create_test_case(TestAPIDivInDygraph, 'complex64', 'float16', 'complex64') +create_test_case(TestAPIDivInDygraph, 'complex64', 'float32', 'complex64') +create_test_case(TestAPIDivInDygraph, 'complex64', 'float64', 'complex128') +create_test_case(TestAPIDivInDygraph, 'complex64', 'complex128', 'complex128') + +create_test_case(TestAPIDivInDygraph, 'complex128', 'bool', 'complex128') +create_test_case(TestAPIDivInDygraph, 'complex128', 'int8', 'complex128') +create_test_case(TestAPIDivInDygraph, 'complex128', 'uint8', 'complex128') +create_test_case(TestAPIDivInDygraph, 'complex128', 'int16', 'complex128') +create_test_case(TestAPIDivInDygraph, 'complex128', 'int32', 'complex128') +create_test_case(TestAPIDivInDygraph, 'complex128', 'int64', 'complex128') +create_test_case(TestAPIDivInDygraph, 'complex128', 'float16', 'complex128') +create_test_case(TestAPIDivInDygraph, 'complex128', 'float32', 'complex128') +create_test_case(TestAPIDivInDygraph, 'complex128', 'float64', 'complex128') + + +class TestOperatorOverloadPowInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = self.l_value**self.r_value + out_reverse = self.r_value**self.l_value + + return out, out_reverse + + +create_test_case( + TestOperatorOverloadPowInDygraph, 'float16', 'float32', 'float32' +) +create_test_case( + TestOperatorOverloadPowInDygraph, 'float16', 'float64', 'float64' +) + +create_test_case( + TestOperatorOverloadPowInDygraph, 'float32', 'float64', 'float64' +) + + +class TestAPIPowInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.pow(self.l_value, self.r_value) + out_reverse = paddle.pow(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIPowInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIPowInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIPowInDygraph, 'float32', 'float64', 'float64') + + +class TestOperatorOverloadFloorDivInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = self.l_value // self.r_value + out_reverse = self.r_value // self.l_value + + return out, out_reverse + + +create_test_case( + TestOperatorOverloadFloorDivInDygraph, 'float16', 'float32', 'float32' +) +create_test_case( + TestOperatorOverloadFloorDivInDygraph, 'float16', 'float64', 'float64' +) + +create_test_case( + TestOperatorOverloadFloorDivInDygraph, 'float32', 'float64', 'float64' +) + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestOperatorOverloadFloorDivInDygraph, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestOperatorOverloadFloorDivInDygraph, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestOperatorOverloadFloorDivInDygraph, 'bfloat16', 'float64', 'float64' + ) + + +class TestAPIFloorDivInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.floor_divide(self.l_value, self.r_value) + out_reverse = paddle.floor_divide(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case( + TestOperatorOverloadFloorDivInDygraph, 'float16', 'float32', 'float32' +) +create_test_case( + TestOperatorOverloadFloorDivInDygraph, 'float16', 'float64', 'float64' +) + +create_test_case( + TestOperatorOverloadFloorDivInDygraph, 'float32', 'float64', 'float64' +) + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestOperatorOverloadFloorDivInDygraph, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestOperatorOverloadFloorDivInDygraph, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestOperatorOverloadFloorDivInDygraph, 'bfloat16', 'float64', 'float64' + ) + + +class TestOperatorOverloadModInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = self.l_value % self.r_value + out_reverse = self.r_value % self.l_value + + return out, out_reverse + + +create_test_case( + TestOperatorOverloadModInDygraph, 'float16', 'float32', 'float32' +) +create_test_case( + TestOperatorOverloadModInDygraph, 'float16', 'float64', 'float64' +) + +create_test_case( + TestOperatorOverloadModInDygraph, 'float32', 'float64', 'float64' +) + + +class TestAPIModInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.mod(self.l_value, self.r_value) + out_reverse = paddle.mod(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIModInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIModInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIModInDygraph, 'float32', 'float64', 'float64') + + +class TestOperatorOverloadEqualInDygraph(unittest.TestCase): + def setUp(self): + paddle.disable_static() + self.set_dtype() + + def set_dtype(self): + self.ldtype = 'float32' + self.rdtype = 'float64' + self.expected_out_dtype = 'bool' + + def generate_test_value(self): + self.l_value = (paddle.randn((4, 3, 2)) * 10).astype(self.ldtype) + self.r_value = (paddle.randn((4, 3, 2)) * 10).astype(self.rdtype) + + def run_api(self): + self.generate_test_value() + + out = self.l_value == self.r_value + out_reverse = self.r_value == self.l_value + + return out, out_reverse + + def test_dtype_is_expected(self): + out, out_reverse = self.run_api() + self.assertEqual( + out.dtype.__str__(), "paddle." + self.expected_out_dtype + ) + self.assertEqual( + out_reverse.dtype.__str__(), "paddle." + self.expected_out_dtype + ) + + +create_test_case( + TestOperatorOverloadEqualInDygraph, 'float16', 'float32', 'bool' +) +create_test_case( + TestOperatorOverloadEqualInDygraph, 'float16', 'float64', 'bool' +) + +create_test_case( + TestOperatorOverloadEqualInDygraph, 'float32', 'float64', 'bool' +) + + +class TestAPIEqualInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.equal(self.l_value, self.r_value) + out_reverse = paddle.equal(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIEqualInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPIEqualInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPIEqualInDygraph, 'float32', 'float64', 'bool') + + +class TestOperatorOverloadNotEqualInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + + out = self.l_value != self.r_value + out_reverse = self.r_value != self.l_value + + return out, out_reverse + + +create_test_case( + TestOperatorOverloadNotEqualInDygraph, 'float16', 'float32', 'bool' +) +create_test_case( + TestOperatorOverloadNotEqualInDygraph, 'float16', 'float64', 'bool' +) + +create_test_case( + TestOperatorOverloadNotEqualInDygraph, 'float32', 'float64', 'bool' +) + + +class TestAPINotEqualInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.not_equal(self.l_value, self.r_value) + out_reverse = paddle.not_equal(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPINotEqualInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPINotEqualInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPINotEqualInDygraph, 'float32', 'float64', 'bool') + + +class TestOperatorOverloadLessThanInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + + out = self.l_value < self.r_value + out_reverse = self.r_value < self.l_value + + return out, out_reverse + + +create_test_case( + TestOperatorOverloadLessThanInDygraph, 'float16', 'float32', 'bool' +) +create_test_case( + TestOperatorOverloadLessThanInDygraph, 'float16', 'float64', 'bool' +) + +create_test_case( + TestOperatorOverloadLessThanInDygraph, 'float32', 'float64', 'bool' +) + + +class TestAPILessThanInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.less_than(self.l_value, self.r_value) + out_reverse = paddle.less_than(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPILessThanInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPILessThanInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPILessThanInDygraph, 'float32', 'float64', 'bool') + + +class TestOperatorOverloadLessEqualInDygraph( + TestOperatorOverloadEqualInDygraph +): + def run_api(self): + self.generate_test_value() + + out = self.l_value <= self.r_value + out_reverse = self.r_value <= self.l_value + + return out, out_reverse + + +create_test_case( + TestOperatorOverloadLessEqualInDygraph, 'float16', 'float32', 'bool' +) +create_test_case( + TestOperatorOverloadLessEqualInDygraph, 'float16', 'float64', 'bool' +) + +create_test_case( + TestOperatorOverloadLessEqualInDygraph, 'float32', 'float64', 'bool' +) + + +class TestAPILessEqualInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.less_equal(self.l_value, self.r_value) + out_reverse = paddle.less_equal(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPILessEqualInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPILessEqualInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPILessEqualInDygraph, 'float32', 'float64', 'bool') + + +class TestOperatorOverloadGreaterThanInDygraph( + TestOperatorOverloadEqualInDygraph +): + def run_api(self): + self.generate_test_value() + + out = self.l_value > self.r_value + out_reverse = self.r_value > self.l_value + + return out, out_reverse + + +create_test_case( + TestOperatorOverloadGreaterThanInDygraph, 'float16', 'float32', 'bool' +) +create_test_case( + TestOperatorOverloadGreaterThanInDygraph, 'float16', 'float64', 'bool' +) + +create_test_case( + TestOperatorOverloadGreaterThanInDygraph, 'float32', 'float64', 'bool' +) + + +class TestAPIGreaterThanInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.greater_than(self.l_value, self.r_value) + out_reverse = paddle.greater_than(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIGreaterThanInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPIGreaterThanInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPIGreaterThanInDygraph, 'float32', 'float64', 'bool') + + +class TestOperatorOverloadGreaterEqualInDygraph( + TestOperatorOverloadEqualInDygraph +): + def run_api(self): + self.generate_test_value() + + out = self.l_value >= self.r_value + out_reverse = self.r_value >= self.l_value + + return out, out_reverse + + +create_test_case( + TestOperatorOverloadGreaterEqualInDygraph, 'float16', 'float32', 'bool' +) +create_test_case( + TestOperatorOverloadGreaterEqualInDygraph, 'float16', 'float64', 'bool' +) + +create_test_case( + TestOperatorOverloadGreaterEqualInDygraph, 'float32', 'float64', 'bool' +) + + +class TestAPIGreaterEqualInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.greater_equal(self.l_value, self.r_value) + out_reverse = paddle.greater_equal(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIGreaterEqualInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPIGreaterEqualInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPIGreaterEqualInDygraph, 'float32', 'float64', 'bool') + + +class TestAPILogicalAndInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.logical_and(self.l_value, self.r_value) + out_reverse = paddle.logical_and(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPILogicalAndInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPILogicalAndInDygraph, 'float32', 'float64', 'bool') + +create_test_case(TestAPILogicalAndInDygraph, 'complex64', 'bool', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex64', 'int8', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex64', 'int16', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex64', 'int32', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex64', 'int64', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex64', 'float16', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex64', 'float32', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex64', 'float64', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex64', 'complex128', 'bool') + +create_test_case(TestAPILogicalAndInDygraph, 'complex128', 'bool', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex128', 'int8', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex128', 'int16', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex128', 'int32', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex128', 'int64', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex128', 'float16', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex128', 'float32', 'bool') +create_test_case(TestAPILogicalAndInDygraph, 'complex128', 'float64', 'bool') + + +class TestAPILogicalOrInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.logical_or(self.l_value, self.r_value) + out_reverse = paddle.logical_or(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPILogicalOrInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPILogicalOrInDygraph, 'float32', 'float64', 'bool') + +create_test_case(TestAPILogicalOrInDygraph, 'complex64', 'bool', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex64', 'int8', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex64', 'int16', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex64', 'int32', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex64', 'int64', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex64', 'float16', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex64', 'float32', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex64', 'float64', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex64', 'complex128', 'bool') + +create_test_case(TestAPILogicalOrInDygraph, 'complex128', 'bool', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex128', 'int8', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex128', 'int16', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex128', 'int32', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex128', 'int64', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex128', 'float16', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex128', 'float32', 'bool') +create_test_case(TestAPILogicalOrInDygraph, 'complex128', 'float64', 'bool') + + +class TestAPILogicalXorInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.logical_xor(self.l_value, self.r_value) + out_reverse = paddle.logical_xor(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPILogicalXorInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPILogicalXorInDygraph, 'float32', 'float64', 'bool') + +create_test_case(TestAPILogicalXorInDygraph, 'complex64', 'bool', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex64', 'int8', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex64', 'int16', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex64', 'int32', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex64', 'int64', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex64', 'float16', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex64', 'float32', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex64', 'float64', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex64', 'complex128', 'bool') + +create_test_case(TestAPILogicalXorInDygraph, 'complex128', 'bool', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex128', 'int8', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex128', 'int16', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex128', 'int32', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex128', 'int64', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex128', 'float16', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex128', 'float32', 'bool') +create_test_case(TestAPILogicalXorInDygraph, 'complex128', 'float64', 'bool') + + +class TestAPIFmaxInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.fmax(self.l_value, self.r_value) + out_reverse = paddle.fmax(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIFmaxInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIFmaxInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIFmaxInDygraph, 'float32', 'float64', 'float64') + + +class TestAPIFminInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.fmin(self.l_value, self.r_value) + out_reverse = paddle.fmin(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIFminInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIFminInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIFminInDygraph, 'float32', 'float64', 'float64') + + +class TestAPILogAddExpInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.logaddexp(self.l_value, self.r_value) + out_reverse = paddle.logaddexp(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPILogAddExpInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPILogAddExpInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPILogAddExpInDygraph, 'float32', 'float64', 'float64') + + +class TestAPIMaximumInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.maximum(self.l_value, self.r_value) + out_reverse = paddle.maximum(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIMaximumInDygraph, 'float32', 'float64', 'float64') + + +class TestAPIMinimumInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.minimum(self.l_value, self.r_value) + out_reverse = paddle.minimum(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIMinimumInDygraph, 'float32', 'float64', 'float64') + + +class TestAPINextAfterInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.nextafter(self.l_value, self.r_value) + out_reverse = paddle.nextafter(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPINextAfterInDygraph, 'float32', 'float64', 'float64') + + +class TestAPIAtan2InDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.atan2(self.l_value, self.r_value) + out_reverse = paddle.atan2(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIAtan2InDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIAtan2InDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIAtan2InDygraph, 'float32', 'float64', 'float64') + + +class TestAPIPoissonNllLossInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.nn.functional.poisson_nll_loss(self.l_value, self.r_value) + out_reverse = paddle.nn.functional.poisson_nll_loss( + self.r_value, self.l_value + ) + + return out, out_reverse + + +create_test_case( + TestAPIPoissonNllLossInDygraph, 'float16', 'float32', 'float32' +) +create_test_case( + TestAPIPoissonNllLossInDygraph, 'float16', 'float64', 'float64' +) + +create_test_case( + TestAPIPoissonNllLossInDygraph, 'float32', 'float64', 'float64' +) + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestAPIPoissonNllLossInDygraph, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestAPIPoissonNllLossInDygraph, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestAPIPoissonNllLossInDygraph, 'bfloat16', 'float64', 'float64' + ) + + +class TestAPIL1LossInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.nn.functional.l1_loss(self.l_value, self.r_value) + out_reverse = paddle.nn.functional.l1_loss(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIL1LossInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIL1LossInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIL1LossInDygraph, 'float32', 'float64', 'float64') + + +class TestAPISmoothL1LossInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.nn.functional.smooth_l1_loss(self.l_value, self.r_value) + out_reverse = paddle.nn.functional.smooth_l1_loss( + self.r_value, self.l_value + ) + + return out, out_reverse + + +create_test_case(TestAPISmoothL1LossInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPISmoothL1LossInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPISmoothL1LossInDygraph, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestAPISmoothL1LossInDygraph, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestAPISmoothL1LossInDygraph, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestAPISmoothL1LossInDygraph, 'bfloat16', 'float64', 'float64' + ) + + +class TestAPIHuberLossInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle._C_ops.huber_loss(self.l_value, self.r_value, 1.0) + out_reverse = paddle._C_ops.huber_loss(self.r_value, self.l_value, 1.0) + + return out, out_reverse + + +create_test_case(TestAPIHuberLossInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIHuberLossInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIHuberLossInDygraph, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestAPIHuberLossInDygraph, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestAPIHuberLossInDygraph, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestAPIHuberLossInDygraph, 'bfloat16', 'float64', 'float64' + ) + + +class TestAPIMSELossInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + + out = paddle.nn.functional.mse_loss(self.l_value, self.r_value) + out_reverse = paddle.nn.functional.mse_loss(self.r_value, self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIMSELossInDygraph, 'float32', 'float64', 'float64') + + +class TestOperatorOverloadAddInStatic(unittest.TestCase): + def setUp(self): + paddle.enable_static() + self.set_dtype() + self.exe = paddle.static.Executor() + + def set_dtype(self): + self.ldtype = 'float32' + self.rdtype = 'float64' + self.expected_out_dtype = 'float64' + + def generate_test_value(self): + self.l_value = (paddle.randn((4, 3, 2)) * 10).astype(self.ldtype) + self.r_value = (paddle.randn((4, 3, 2)) * 10).astype(self.rdtype) + + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = self.l_value + self.r_value + out_reverse = self.r_value + self.l_value + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + def test_dtype_is_expected(self): + res = self.run_api() + self.assertEqual(res[0].dtype.__str__(), self.expected_out_dtype) + self.assertEqual(res[1].dtype.__str__(), self.expected_out_dtype) + + +create_test_case( + TestOperatorOverloadAddInStatic, 'float16', 'float32', 'float32' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'float16', 'float64', 'float64' +) + +create_test_case( + TestOperatorOverloadAddInStatic, 'float32', 'float64', 'float64' +) + + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestOperatorOverloadAddInStatic, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestOperatorOverloadAddInStatic, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestOperatorOverloadAddInStatic, 'bfloat16', 'float64', 'float64' + ) + create_test_case( + TestOperatorOverloadAddInStatic, 'bfloat16', 'complex64', 'complex64' + ) + create_test_case( + TestOperatorOverloadAddInStatic, 'bfloat16', 'complex128', 'complex128' + ) + +create_test_case( + TestOperatorOverloadAddInStatic, 'complex64', 'bool', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex64', 'int8', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex64', 'uint8', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex64', 'int16', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex64', 'int32', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex64', 'int64', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex64', 'float16', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex64', 'float32', 'complex64' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex64', 'float64', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex64', 'complex128', 'complex128' +) + +create_test_case( + TestOperatorOverloadAddInStatic, 'complex128', 'bool', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex128', 'int8', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex128', 'uint8', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex128', 'int16', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex128', 'int32', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex128', 'int64', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex128', 'float16', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex128', 'float32', 'complex128' +) +create_test_case( + TestOperatorOverloadAddInStatic, 'complex128', 'float64', 'complex128' +) + + +class TestAPIAddInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.add(self.l_value, self.r_value) + out_reverse = paddle.add(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIAddInStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPIAddInStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPIAddInStatic, 'float32', 'float64', 'float64') + + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case(TestAPIAddInStatic, 'bfloat16', 'float16', 'float32') + create_test_case(TestAPIAddInStatic, 'bfloat16', 'float32', 'float32') + create_test_case(TestAPIAddInStatic, 'bfloat16', 'float64', 'float64') + create_test_case(TestAPIAddInStatic, 'bfloat16', 'complex64', 'complex64') + create_test_case(TestAPIAddInStatic, 'bfloat16', 'complex128', 'complex128') + +create_test_case(TestAPIAddInStatic, 'complex64', 'bool', 'complex64') +create_test_case(TestAPIAddInStatic, 'complex64', 'int32', 'complex64') +create_test_case(TestAPIAddInStatic, 'complex64', 'int64', 'complex64') +create_test_case(TestAPIAddInStatic, 'complex64', 'float16', 'complex64') +create_test_case(TestAPIAddInStatic, 'complex64', 'float32', 'complex64') +create_test_case(TestAPIAddInStatic, 'complex64', 'float64', 'complex128') +create_test_case(TestAPIAddInStatic, 'complex64', 'complex128', 'complex128') + +create_test_case(TestAPIAddInStatic, 'complex128', 'bool', 'complex128') +create_test_case(TestAPIAddInStatic, 'complex128', 'int32', 'complex128') +create_test_case(TestAPIAddInStatic, 'complex128', 'int64', 'complex128') +create_test_case(TestAPIAddInStatic, 'complex128', 'float16', 'complex128') +create_test_case(TestAPIAddInStatic, 'complex128', 'float32', 'complex128') +create_test_case(TestAPIAddInStatic, 'complex128', 'float64', 'complex128') + + +class TestOperatorOverloadSubInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = self.l_value - self.r_value + out_reverse = self.r_value - self.l_value + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case( + TestOperatorOverloadSubInStatic, 'float16', 'float32', 'float32' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'float16', 'float64', 'float64' +) + +create_test_case( + TestOperatorOverloadSubInStatic, 'float32', 'float64', 'float64' +) + + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestOperatorOverloadSubInStatic, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestOperatorOverloadSubInStatic, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestOperatorOverloadSubInStatic, 'bfloat16', 'float64', 'float64' + ) + create_test_case( + TestOperatorOverloadSubInStatic, 'bfloat16', 'complex64', 'complex64' + ) + create_test_case( + TestOperatorOverloadSubInStatic, 'bfloat16', 'complex128', 'complex128' + ) + +create_test_case( + TestOperatorOverloadSubInStatic, 'complex64', 'bool', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex64', 'int8', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex64', 'uint8', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex64', 'int16', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex64', 'int32', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex64', 'int64', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex64', 'float16', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex64', 'float32', 'complex64' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex64', 'float64', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex64', 'complex128', 'complex128' +) + +create_test_case( + TestOperatorOverloadSubInStatic, 'complex128', 'bool', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex128', 'int8', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex128', 'uint8', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex128', 'int16', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex128', 'int32', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex128', 'int64', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex128', 'float16', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex128', 'float32', 'complex128' +) +create_test_case( + TestOperatorOverloadSubInStatic, 'complex128', 'float64', 'complex128' +) + + +class TestAPISubInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.subtract(self.l_value, self.r_value) + out_reverse = paddle.subtract(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPISubInStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPISubInStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPISubInStatic, 'float32', 'float64', 'float64') + + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case(TestAPISubInStatic, 'bfloat16', 'float16', 'float32') + create_test_case(TestAPISubInStatic, 'bfloat16', 'float32', 'float32') + create_test_case(TestAPISubInStatic, 'bfloat16', 'float64', 'float64') + create_test_case(TestAPISubInStatic, 'bfloat16', 'complex64', 'complex64') + create_test_case(TestAPISubInStatic, 'bfloat16', 'complex128', 'complex128') + +create_test_case(TestAPISubInStatic, 'complex64', 'bool', 'complex64') +create_test_case(TestAPISubInStatic, 'complex64', 'int32', 'complex64') +create_test_case(TestAPISubInStatic, 'complex64', 'int64', 'complex64') +create_test_case(TestAPISubInStatic, 'complex64', 'float16', 'complex64') +create_test_case(TestAPISubInStatic, 'complex64', 'float32', 'complex64') +create_test_case(TestAPISubInStatic, 'complex64', 'float64', 'complex128') +create_test_case(TestAPISubInStatic, 'complex64', 'complex128', 'complex128') + +create_test_case(TestAPISubInStatic, 'complex128', 'bool', 'complex128') +create_test_case(TestAPISubInStatic, 'complex128', 'int32', 'complex128') +create_test_case(TestAPISubInStatic, 'complex128', 'int64', 'complex128') +create_test_case(TestAPISubInStatic, 'complex128', 'float16', 'complex128') +create_test_case(TestAPISubInStatic, 'complex128', 'float32', 'complex128') +create_test_case(TestAPISubInStatic, 'complex128', 'float64', 'complex128') + + +class TestOperatorOverloadMulInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = self.l_value * self.r_value + out_reverse = self.r_value * self.l_value + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case( + TestOperatorOverloadMulInStatic, 'float16', 'float32', 'float32' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'float16', 'float64', 'float64' +) + +create_test_case( + TestOperatorOverloadMulInStatic, 'float32', 'float64', 'float64' +) + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestOperatorOverloadMulInStatic, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestOperatorOverloadMulInStatic, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestOperatorOverloadMulInStatic, 'bfloat16', 'float64', 'float64' + ) + create_test_case( + TestOperatorOverloadMulInStatic, 'bfloat16', 'complex64', 'complex64' + ) + create_test_case( + TestOperatorOverloadMulInStatic, 'bfloat16', 'complex128', 'complex128' + ) + +create_test_case( + TestOperatorOverloadMulInStatic, 'complex64', 'bool', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex64', 'int8', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex64', 'uint8', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex64', 'int16', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex64', 'int32', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex64', 'int64', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex64', 'float16', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex64', 'float32', 'complex64' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex64', 'float64', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex64', 'complex128', 'complex128' +) + +create_test_case( + TestOperatorOverloadMulInStatic, 'complex128', 'bool', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex128', 'int8', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex128', 'uint8', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex128', 'int16', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex128', 'int32', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex128', 'int64', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex128', 'float16', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex128', 'float32', 'complex128' +) +create_test_case( + TestOperatorOverloadMulInStatic, 'complex128', 'float64', 'complex128' +) + + +class TestAPIMulInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.multiply(self.l_value, self.r_value) + out_reverse = paddle.multiply(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIMulInStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPIMulInStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPIMulInStatic, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case(TestAPIMulInStatic, 'bfloat16', 'float16', 'float32') + create_test_case(TestAPIMulInStatic, 'bfloat16', 'float32', 'float32') + create_test_case(TestAPIMulInStatic, 'bfloat16', 'float64', 'float64') + create_test_case(TestAPIMulInStatic, 'bfloat16', 'complex64', 'complex64') + create_test_case(TestAPIMulInStatic, 'bfloat16', 'complex128', 'complex128') + +create_test_case(TestAPIMulInStatic, 'complex64', 'bool', 'complex64') +create_test_case(TestAPIMulInStatic, 'complex64', 'int32', 'complex64') +create_test_case(TestAPIMulInStatic, 'complex64', 'int64', 'complex64') +create_test_case(TestAPIMulInStatic, 'complex64', 'float16', 'complex64') +create_test_case(TestAPIMulInStatic, 'complex64', 'float32', 'complex64') +create_test_case(TestAPIMulInStatic, 'complex64', 'float64', 'complex128') +create_test_case(TestAPIMulInStatic, 'complex64', 'complex128', 'complex128') + +create_test_case(TestAPIMulInStatic, 'complex128', 'bool', 'complex128') +create_test_case(TestAPIMulInStatic, 'complex128', 'int32', 'complex128') +create_test_case(TestAPIMulInStatic, 'complex128', 'int64', 'complex128') +create_test_case(TestAPIMulInStatic, 'complex128', 'float16', 'complex128') +create_test_case(TestAPIMulInStatic, 'complex128', 'float32', 'complex128') +create_test_case(TestAPIMulInStatic, 'complex128', 'float64', 'complex128') + + +class TestAPIDivInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.divide(self.l_value, self.r_value) + out_reverse = paddle.divide(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIDivInStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPIDivInStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPIDivInStatic, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case(TestAPIDivInStatic, 'bfloat16', 'float16', 'float32') + create_test_case(TestAPIDivInStatic, 'bfloat16', 'float32', 'float32') + create_test_case(TestAPIDivInStatic, 'bfloat16', 'float64', 'float64') + create_test_case(TestAPIDivInStatic, 'bfloat16', 'complex64', 'complex64') + create_test_case(TestAPIDivInStatic, 'bfloat16', 'complex128', 'complex128') + +create_test_case(TestAPIDivInStatic, 'complex64', 'bool', 'complex64') +create_test_case(TestAPIDivInStatic, 'complex64', 'int32', 'complex64') +create_test_case(TestAPIDivInStatic, 'complex64', 'int64', 'complex64') +create_test_case(TestAPIDivInStatic, 'complex64', 'float16', 'complex64') +create_test_case(TestAPIDivInStatic, 'complex64', 'float32', 'complex64') +create_test_case(TestAPIDivInStatic, 'complex64', 'float64', 'complex128') +create_test_case(TestAPIDivInStatic, 'complex64', 'complex128', 'complex128') + +create_test_case(TestAPIDivInStatic, 'complex128', 'bool', 'complex128') +create_test_case(TestAPIDivInStatic, 'complex128', 'int32', 'complex128') +create_test_case(TestAPIDivInStatic, 'complex128', 'int64', 'complex128') +create_test_case(TestAPIDivInStatic, 'complex128', 'float16', 'complex128') +create_test_case(TestAPIDivInStatic, 'complex128', 'float32', 'complex128') +create_test_case(TestAPIDivInStatic, 'complex128', 'float64', 'complex128') + + +class TestOperatorOverloadDivInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = self.l_value / self.r_value + out_reverse = self.r_value / self.l_value + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case( + TestOperatorOverloadDivInStatic, 'float16', 'float32', 'float32' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'float16', 'float64', 'float64' +) + +create_test_case( + TestOperatorOverloadDivInStatic, 'float32', 'float64', 'float64' +) + + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestOperatorOverloadDivInStatic, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestOperatorOverloadDivInStatic, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestOperatorOverloadDivInStatic, 'bfloat16', 'float64', 'float64' + ) + create_test_case( + TestOperatorOverloadDivInStatic, 'bfloat16', 'complex64', 'complex64' + ) + create_test_case( + TestOperatorOverloadDivInStatic, 'bfloat16', 'complex128', 'complex128' + ) + +create_test_case( + TestOperatorOverloadDivInStatic, 'complex64', 'bool', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex64', 'int8', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex64', 'uint8', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex64', 'int16', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex64', 'int32', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex64', 'int64', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex64', 'float16', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex64', 'float32', 'complex64' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex64', 'float64', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex64', 'complex128', 'complex128' +) + +create_test_case( + TestOperatorOverloadDivInStatic, 'complex128', 'bool', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex128', 'int8', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex128', 'uint8', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex128', 'int16', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex128', 'int32', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex128', 'int64', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex128', 'float16', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex128', 'float32', 'complex128' +) +create_test_case( + TestOperatorOverloadDivInStatic, 'complex128', 'float64', 'complex128' +) + + +class TestAPIFloorDivInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.floor_divide(self.l_value, self.r_value) + out_reverse = paddle.floor_divide(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIFloorDivInStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPIFloorDivInStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPIFloorDivInStatic, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case(TestAPIFloorDivInStatic, 'bfloat16', 'float16', 'float32') + create_test_case(TestAPIFloorDivInStatic, 'bfloat16', 'float32', 'float32') + create_test_case(TestAPIFloorDivInStatic, 'bfloat16', 'float64', 'float64') + + +class TestOperatorOverloadFloorDivInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = self.l_value // self.r_value + out_reverse = self.r_value // self.l_value + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case( + TestOperatorOverloadFloorDivInStatic, 'float16', 'float32', 'float32' +) +create_test_case( + TestOperatorOverloadFloorDivInStatic, 'float16', 'float64', 'float64' +) + +create_test_case( + TestOperatorOverloadFloorDivInStatic, 'float32', 'float64', 'float64' +) + + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestOperatorOverloadFloorDivInStatic, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestOperatorOverloadFloorDivInStatic, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestOperatorOverloadFloorDivInStatic, 'bfloat16', 'float64', 'float64' + ) + + +class TestAPIPowInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.pow(self.l_value, self.r_value) + out_reverse = paddle.pow(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIPowInStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPIPowInStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPIPowInStatic, 'float32', 'float64', 'float64') + + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case(TestAPIPowInStatic, 'bfloat16', 'float16', 'float32') + create_test_case(TestAPIPowInStatic, 'bfloat16', 'float32', 'float32') + create_test_case(TestAPIPowInStatic, 'bfloat16', 'float64', 'float64') + + +class TestOperatorOverloadPowInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = self.l_value**self.r_value + out_reverse = self.r_value**self.l_value + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case( + TestOperatorOverloadPowInStatic, 'float16', 'float32', 'float32' +) +create_test_case( + TestOperatorOverloadPowInStatic, 'float16', 'float64', 'float64' +) + +create_test_case( + TestOperatorOverloadPowInStatic, 'float32', 'float64', 'float64' +) + + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestOperatorOverloadPowInStatic, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestOperatorOverloadPowInStatic, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestOperatorOverloadPowInStatic, 'bfloat16', 'float64', 'float64' + ) + + +class TestAPIModInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.mod(self.l_value, self.r_value) + out_reverse = paddle.mod(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIModInStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPIModInStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPIModInStatic, 'float32', 'float64', 'float64') + + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case(TestAPIModInStatic, 'bfloat16', 'float16', 'float32') + create_test_case(TestAPIModInStatic, 'bfloat16', 'float32', 'float32') + create_test_case(TestAPIModInStatic, 'bfloat16', 'float64', 'float64') + + +class TestOperatorOverloadModInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = self.l_value % self.r_value + out_reverse = self.r_value % self.l_value + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case( + TestOperatorOverloadModInStatic, 'float16', 'float32', 'float32' +) +create_test_case( + TestOperatorOverloadModInStatic, 'float16', 'float64', 'float64' +) + +create_test_case( + TestOperatorOverloadModInStatic, 'float32', 'float64', 'float64' +) + + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestOperatorOverloadModInStatic, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestOperatorOverloadModInStatic, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestOperatorOverloadModInStatic, 'bfloat16', 'float64', 'float64' + ) + + +class TestOperatorOverloadEqualInStatic(unittest.TestCase): + def setUp(self): + paddle.enable_static() + self.set_dtype() + self.exe = paddle.static.Executor() + + def set_dtype(self): + self.ldtype = 'float32' + self.rdtype = 'float64' + self.expected_out_dtype = 'bool' + + def generate_test_value(self): + self.l_value = (paddle.randn((4, 3, 2)) * 10).astype(self.ldtype) + self.r_value = (paddle.randn((4, 3, 2)) * 10).astype(self.rdtype) + + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = self.l_value == self.r_value + out_reverse = self.r_value == self.l_value + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + def test_dtype_is_expected(self): + res = self.run_api() + self.assertEqual(res[0].dtype.__str__(), self.expected_out_dtype) + self.assertEqual(res[1].dtype.__str__(), self.expected_out_dtype) + + +create_test_case( + TestOperatorOverloadEqualInStatic, 'float16', 'float32', 'bool' +) +create_test_case( + TestOperatorOverloadEqualInStatic, 'float16', 'float64', 'bool' +) + +create_test_case( + TestOperatorOverloadEqualInStatic, 'float32', 'float64', 'bool' +) + + +class TestAPIEqualInStatic(TestOperatorOverloadEqualInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.equal(self.l_value, self.r_value) + out_reverse = paddle.equal(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIEqualInStatic, 'float16', 'float32', 'bool') +create_test_case(TestAPIEqualInStatic, 'float16', 'float64', 'bool') + +create_test_case(TestAPIEqualInStatic, 'float32', 'float64', 'bool') + + +class TestAPINotEqualInStatic(TestOperatorOverloadEqualInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.not_equal(self.l_value, self.r_value) + out_reverse = paddle.not_equal(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPINotEqualInStatic, 'float16', 'float32', 'bool') +create_test_case(TestAPINotEqualInStatic, 'float16', 'float64', 'bool') + +create_test_case(TestAPINotEqualInStatic, 'float32', 'float64', 'bool') + + +class TestOperatorOverloadNotEqualInStatic(TestOperatorOverloadEqualInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = self.l_value != self.r_value + out_reverse = self.r_value != self.l_value + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case( + TestOperatorOverloadNotEqualInStatic, 'float16', 'float32', 'bool' +) +create_test_case( + TestOperatorOverloadNotEqualInStatic, 'float16', 'float64', 'bool' +) + +create_test_case( + TestOperatorOverloadNotEqualInStatic, 'float32', 'float64', 'bool' +) + + +class TestAPILessThanInStatic(TestOperatorOverloadEqualInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.less_than(self.l_value, self.r_value) + out_reverse = paddle.less_than(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPILessThanInStatic, 'float16', 'float32', 'bool') +create_test_case(TestAPILessThanInStatic, 'float16', 'float64', 'bool') + +create_test_case(TestAPILessThanInStatic, 'float32', 'float64', 'bool') + + +class TestOperatorOverloadLessThanInStatic(TestOperatorOverloadEqualInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = self.l_value < self.r_value + out_reverse = self.r_value < self.l_value + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case( + TestOperatorOverloadLessThanInStatic, 'float16', 'float32', 'bool' +) +create_test_case( + TestOperatorOverloadLessThanInStatic, 'float16', 'float64', 'bool' +) + +create_test_case( + TestOperatorOverloadLessThanInStatic, 'float32', 'float64', 'bool' +) + + +class TestAPILessEqualInStatic(TestOperatorOverloadEqualInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.less_equal(self.l_value, self.r_value) + out_reverse = paddle.less_equal(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPILessEqualInStatic, 'float16', 'float32', 'bool') +create_test_case(TestAPILessEqualInStatic, 'float16', 'float64', 'bool') + +create_test_case(TestAPILessEqualInStatic, 'float32', 'float64', 'bool') + + +class TestOperatorOverloadLessEqualInStatic(TestOperatorOverloadEqualInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = self.l_value <= self.r_value + out_reverse = self.r_value <= self.l_value + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case( + TestOperatorOverloadLessEqualInStatic, 'float16', 'float32', 'bool' +) +create_test_case( + TestOperatorOverloadLessEqualInStatic, 'float16', 'float64', 'bool' +) + +create_test_case( + TestOperatorOverloadLessEqualInStatic, 'float32', 'float64', 'bool' +) + + +class TestAPIGreaterThanInStatic(TestOperatorOverloadEqualInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.greater_than(self.l_value, self.r_value) + out_reverse = paddle.greater_than(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIGreaterThanInStatic, 'float16', 'float32', 'bool') +create_test_case(TestAPIGreaterThanInStatic, 'float16', 'float64', 'bool') + +create_test_case(TestAPIGreaterThanInStatic, 'float32', 'float64', 'bool') + + +class TestOperatorOverloadGreaterThanInStatic( + TestOperatorOverloadEqualInStatic +): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = self.l_value > self.r_value + out_reverse = self.r_value > self.l_value + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case( + TestOperatorOverloadGreaterThanInStatic, 'float16', 'float32', 'bool' +) +create_test_case( + TestOperatorOverloadGreaterThanInStatic, 'float16', 'float64', 'bool' +) + +create_test_case( + TestOperatorOverloadGreaterThanInStatic, 'float32', 'float64', 'bool' +) + + +class TestAPIGreaterEqualInStatic(TestOperatorOverloadEqualInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.greater_equal(self.l_value, self.r_value) + out_reverse = paddle.greater_equal(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIGreaterEqualInStatic, 'float16', 'float32', 'bool') +create_test_case(TestAPIGreaterEqualInStatic, 'float16', 'float64', 'bool') + +create_test_case(TestAPIGreaterEqualInStatic, 'float32', 'float64', 'bool') + + +class TestOperatorOverloadGreaterEqualInStatic( + TestOperatorOverloadEqualInStatic +): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = self.l_value >= self.r_value + out_reverse = self.r_value >= self.l_value + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case( + TestOperatorOverloadGreaterEqualInStatic, 'float16', 'float32', 'bool' +) +create_test_case( + TestOperatorOverloadGreaterEqualInStatic, 'float16', 'float64', 'bool' +) + +create_test_case( + TestOperatorOverloadGreaterEqualInStatic, 'float32', 'float64', 'bool' +) + + +class TestAPILogicalAndInStatic(TestOperatorOverloadEqualInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.logical_and(self.l_value, self.r_value) + out_reverse = paddle.logical_and(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPILogicalAndInStatic, 'float16', 'float32', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'float16', 'float64', 'bool') + +create_test_case(TestAPILogicalAndInStatic, 'float32', 'float64', 'bool') + +create_test_case(TestAPILogicalAndInStatic, 'complex64', 'bool', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex64', 'int8', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex64', 'int16', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex64', 'int32', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex64', 'int64', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex64', 'float16', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex64', 'float32', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex64', 'float64', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex64', 'complex128', 'bool') + +create_test_case(TestAPILogicalAndInStatic, 'complex128', 'bool', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex128', 'int8', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex128', 'int16', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex128', 'int32', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex128', 'int64', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex128', 'float16', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex128', 'float32', 'bool') +create_test_case(TestAPILogicalAndInStatic, 'complex128', 'float64', 'bool') + + +class TestAPILogicalOrInStatic(TestOperatorOverloadEqualInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.logical_or(self.l_value, self.r_value) + out_reverse = paddle.logical_or(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPILogicalOrInStatic, 'float16', 'float32', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'float16', 'float64', 'bool') + +create_test_case(TestAPILogicalOrInStatic, 'float32', 'float64', 'bool') + +create_test_case(TestAPILogicalOrInStatic, 'complex64', 'bool', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex64', 'int8', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex64', 'int16', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex64', 'int32', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex64', 'int64', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex64', 'float16', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex64', 'float32', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex64', 'float64', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex64', 'complex128', 'bool') + +create_test_case(TestAPILogicalOrInStatic, 'complex128', 'bool', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex128', 'int8', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex128', 'int16', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex128', 'int32', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex128', 'int64', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex128', 'float16', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex128', 'float32', 'bool') +create_test_case(TestAPILogicalOrInStatic, 'complex128', 'float64', 'bool') + + +class TestAPILogicalXorInStatic(TestOperatorOverloadEqualInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.logical_xor(self.l_value, self.r_value) + out_reverse = paddle.logical_xor(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPILogicalXorInStatic, 'float16', 'float32', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'float16', 'float64', 'bool') + +create_test_case(TestAPILogicalXorInStatic, 'float32', 'float64', 'bool') + +create_test_case(TestAPILogicalXorInStatic, 'complex64', 'bool', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex64', 'int8', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex64', 'int16', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex64', 'int32', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex64', 'int64', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex64', 'float16', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex64', 'float32', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex64', 'float64', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex64', 'complex128', 'bool') + +create_test_case(TestAPILogicalXorInStatic, 'complex128', 'bool', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex128', 'int8', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex128', 'int16', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex128', 'int32', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex128', 'int64', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex128', 'float16', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex128', 'float32', 'bool') +create_test_case(TestAPILogicalXorInStatic, 'complex128', 'float64', 'bool') + + +class TestAPIFmaxInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.fmax(self.l_value, self.r_value) + out_reverse = paddle.fmax(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIFmaxInStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPIFmaxInStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPIFmaxInStatic, 'float32', 'float64', 'float64') + + +class TestAPIFminInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.fmin(self.l_value, self.r_value) + out_reverse = paddle.fmin(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIFminInStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPIFminInStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPIFminInStatic, 'float32', 'float64', 'float64') + + +class TestAPILogAddExpInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.logaddexp(self.l_value, self.r_value) + out_reverse = paddle.logaddexp(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPILogAddExpInStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPILogAddExpInStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPILogAddExpInStatic, 'float32', 'float64', 'float64') + + +class TestAPIMaximumInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.maximum(self.l_value, self.r_value) + out_reverse = paddle.maximum(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIMaximumInStatic, 'float32', 'float64', 'float64') + + +class TestAPIMiniumInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.minimum(self.l_value, self.r_value) + out_reverse = paddle.maximum(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIMiniumInStatic, 'float32', 'float64', 'float64') + + +class TestAPINextAfterInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.nextafter(self.l_value, self.r_value) + out_reverse = paddle.nextafter(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPINextAfterInStatic, 'float32', 'float64', 'float64') + + +class TestAPIAtan2InStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.atan2(self.l_value, self.r_value) + out_reverse = paddle.atan2(self.r_value, self.l_value) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIAtan2InStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPIAtan2InStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPIAtan2InStatic, 'float32', 'float64', 'float64') + + +class TestAPIPoissonNllLossInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.nn.functional.poisson_nll_loss( + self.l_value, self.r_value + ) + out_reverse = paddle.nn.functional.poisson_nll_loss( + self.r_value, self.l_value + ) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIPoissonNllLossInStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPIPoissonNllLossInStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPIPoissonNllLossInStatic, 'float32', 'float64', 'float64') + + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestAPIPoissonNllLossInStatic, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestAPIPoissonNllLossInStatic, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestAPIPoissonNllLossInStatic, 'bfloat16', 'float64', 'float64' + ) + + +class TestAPIL1LossInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.nn.functional.l1_loss(self.l_value, self.r_value) + out_reverse = paddle.nn.functional.l1_loss( + self.r_value, self.l_value + ) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPIL1LossInStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPIL1LossInStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPIL1LossInStatic, 'float32', 'float64', 'float64') + + +class TestAPISmoothL1LossInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.nn.functional.smooth_l1_loss( + self.l_value, self.r_value + ) + out_reverse = paddle.nn.functional.smooth_l1_loss( + self.r_value, self.l_value + ) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + + +create_test_case(TestAPISmoothL1LossInStatic, 'float16', 'float32', 'float32') +create_test_case(TestAPISmoothL1LossInStatic, 'float16', 'float64', 'float64') + +create_test_case(TestAPISmoothL1LossInStatic, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestAPISmoothL1LossInStatic, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestAPISmoothL1LossInStatic, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestAPISmoothL1LossInStatic, 'bfloat16', 'float64', 'float64' + ) + + +class TestAPIMSELossInStatic(TestOperatorOverloadAddInStatic): + def run_api(self): + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + self.generate_test_value() + + out = paddle.nn.functional.mse_loss(self.l_value, self.r_value) + out_reverse = paddle.nn.functional.mse_loss( + self.r_value, self.l_value + ) + + res = self.exe.run(prog, fetch_list=[out, out_reverse]) + return res + +create_test_case(TestAPIMSELossInStatic, 'float32', 'float64', 'float64') if __name__ == '__main__': unittest.main() From f44e92657a567dd7b9bf5e14cf73a4b7513a465e Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Fri, 22 Mar 2024 06:39:19 +0000 Subject: [PATCH 22/34] rm unintest which is unsupport dtype --- .../test_tensor_scalar_type_promotion_dynamic.py | 16 +++------------- .../test_tensor_scalar_type_promotion_static.py | 15 ++------------- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py b/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py index a7f8f813eae2a..7f13d70dabeef 100644 --- a/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py +++ b/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py @@ -608,16 +608,10 @@ def test_dtype_is_expected(self): # self.assertEqual(res_complex.dtype.__str__(), "paddle." + self.expected_out_dtype_with_complex) -# pow API not support uint8, int8, complex64, complex128 -create_test_case(TestTensorPowScalar, 'bool', 'int64', 'float32', 'complex64') +# pow API support int32, int64, float64, float32. create_test_case(TestTensorPowScalar, 'int32', 'int32', 'float32', 'complex64') create_test_case(TestTensorPowScalar, 'int64', 'int64', 'float32', 'complex64') -create_test_case( - TestTensorPowScalar, 'float16', 'float16', 'float16', 'complex64' -) -create_test_case( - TestTensorPowScalar, 'bfloat16', 'bfloat16', 'bfloat16', 'complex64' -) + create_test_case( TestTensorPowScalar, 'float64', 'float64', 'float64', 'complex128' ) @@ -718,16 +712,12 @@ def test_dtype_is_expected(self): # self.assertEqual(res_complex.dtype.__str__(), "paddle." + self.expected_out_dtype_with_complex) -# mod API not support uint8, int8, complex64, complex128 -create_test_case(TestTensorModScalar, 'bool', 'int64', 'float32', 'complex64') +# mod API support float16, float32, float64, int32, int64 create_test_case(TestTensorModScalar, 'int32', 'int32', 'float32', 'complex64') create_test_case(TestTensorModScalar, 'int64', 'int64', 'float32', 'complex64') create_test_case( TestTensorModScalar, 'float16', 'float16', 'float16', 'complex64' ) -create_test_case( - TestTensorModScalar, 'bfloat16', 'bfloat16', 'bfloat16', 'complex64' -) create_test_case( TestTensorModScalar, 'float64', 'float64', 'float64', 'complex128' ) diff --git a/test/legacy_test/test_tensor_scalar_type_promotion_static.py b/test/legacy_test/test_tensor_scalar_type_promotion_static.py index 06e7192f1d485..87b3a4d089d34 100644 --- a/test/legacy_test/test_tensor_scalar_type_promotion_static.py +++ b/test/legacy_test/test_tensor_scalar_type_promotion_static.py @@ -661,16 +661,9 @@ def test_dtype_is_expected(self): # self.assertEqual(res_complex.dtype.__str__(), self.expected_out_dtype_with_complex) -# pow API not support uint8, int8, complex64, complex128 -create_test_case(TestTensorPowScalar, 'bool', 'int64', 'float32', 'complex64') +# pow API support int32, int64, float64, float32. create_test_case(TestTensorPowScalar, 'int32', 'int32', 'float32', 'complex64') create_test_case(TestTensorPowScalar, 'int64', 'int64', 'float32', 'complex64') -create_test_case( - TestTensorPowScalar, 'float16', 'float16', 'float16', 'complex64' -) -create_test_case( - TestTensorPowScalar, 'bfloat16', 'uint16', 'uint16', 'complex64' -) create_test_case( TestTensorPowScalar, 'float64', 'float64', 'float64', 'complex128' ) @@ -775,16 +768,12 @@ def test_dtype_is_expected(self): # self.assertEqual(res_complex.dtype.__str__(), self.expected_out_dtype_with_complex) -# mod API not support uint8, int8, complex64, complex128 -create_test_case(TestTensorModScalar, 'bool', 'int64', 'float32', 'complex64') +# # mod API support float16, float32, float64, int32, int64 create_test_case(TestTensorModScalar, 'int32', 'int32', 'float32', 'complex64') create_test_case(TestTensorModScalar, 'int64', 'int64', 'float32', 'complex64') create_test_case( TestTensorModScalar, 'float16', 'float16', 'float16', 'complex64' ) -create_test_case( - TestTensorModScalar, 'bfloat16', 'uint16', 'uint16', 'complex64' -) create_test_case( TestTensorModScalar, 'float64', 'float64', 'float64', 'complex128' ) From 55980104c3f977fa141f81fde1a413f66eebc9f0 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Fri, 22 Mar 2024 08:39:13 +0000 Subject: [PATCH 23/34] fix --- python/paddle/tensor/math.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/python/paddle/tensor/math.py b/python/paddle/tensor/math.py index 5a85a5768bd34..e9f1b6d903379 100644 --- a/python/paddle/tensor/math.py +++ b/python/paddle/tensor/math.py @@ -1109,11 +1109,6 @@ def multiply(x, y, name=None): if in_dynamic_or_pir_mode(): return _C_ops.multiply(x, y) else: - if x.dtype != y.dtype: - raise TypeError( - f'Input tensors must be same type, but received type of x: {x.dtype}, type of y: {y.dtype} ' - ) - return _elementwise_op(LayerHelper('elementwise_mul', **locals())) From aa0bf9c655aac1aae41a5adf3b78f081166dead2 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Fri, 22 Mar 2024 09:59:40 +0000 Subject: [PATCH 24/34] fix --- .../legacy_test/test_tensor_scalar_type_promotion_dynamic.py | 5 +---- test/legacy_test/test_tensor_scalar_type_promotion_static.py | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py b/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py index 7f13d70dabeef..8bdb7261404cb 100644 --- a/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py +++ b/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py @@ -712,12 +712,9 @@ def test_dtype_is_expected(self): # self.assertEqual(res_complex.dtype.__str__(), "paddle." + self.expected_out_dtype_with_complex) -# mod API support float16, float32, float64, int32, int64 +# mod API support float32, float64, int32, int64 create_test_case(TestTensorModScalar, 'int32', 'int32', 'float32', 'complex64') create_test_case(TestTensorModScalar, 'int64', 'int64', 'float32', 'complex64') -create_test_case( - TestTensorModScalar, 'float16', 'float16', 'float16', 'complex64' -) create_test_case( TestTensorModScalar, 'float64', 'float64', 'float64', 'complex128' ) diff --git a/test/legacy_test/test_tensor_scalar_type_promotion_static.py b/test/legacy_test/test_tensor_scalar_type_promotion_static.py index 87b3a4d089d34..2f005ee144a08 100644 --- a/test/legacy_test/test_tensor_scalar_type_promotion_static.py +++ b/test/legacy_test/test_tensor_scalar_type_promotion_static.py @@ -768,12 +768,9 @@ def test_dtype_is_expected(self): # self.assertEqual(res_complex.dtype.__str__(), self.expected_out_dtype_with_complex) -# # mod API support float16, float32, float64, int32, int64 +# # mod API support float32, float64, int32, int64 create_test_case(TestTensorModScalar, 'int32', 'int32', 'float32', 'complex64') create_test_case(TestTensorModScalar, 'int64', 'int64', 'float32', 'complex64') -create_test_case( - TestTensorModScalar, 'float16', 'float16', 'float16', 'complex64' -) create_test_case( TestTensorModScalar, 'float64', 'float64', 'float64', 'complex128' ) From 59d02a2c2218b47292ac3451cc0817478b3b8bd9 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Mon, 25 Mar 2024 12:50:02 +0000 Subject: [PATCH 25/34] add error unittest --- ...st_tensor_scalar_type_promotion_dynamic.py | 9 ++++++++ ...est_tensor_scalar_type_promotion_static.py | 13 ++++++++++++ .../legacy_test/test_tensor_type_promotion.py | 21 +++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py b/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py index 8bdb7261404cb..222955108c9dc 100644 --- a/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py +++ b/test/legacy_test/test_tensor_scalar_type_promotion_dynamic.py @@ -719,5 +719,14 @@ def test_dtype_is_expected(self): TestTensorModScalar, 'float64', 'float64', 'float64', 'complex128' ) + +class Test0DTensor(unittest.TestCase): + def test_0d_add_0d(self): + a = paddle.ones([], dtype='int32') + b = paddle.ones([], dtype='int64') + res = a / b + return res + + if __name__ == '__main__': unittest.main() diff --git a/test/legacy_test/test_tensor_scalar_type_promotion_static.py b/test/legacy_test/test_tensor_scalar_type_promotion_static.py index 2f005ee144a08..ecac148c839e0 100644 --- a/test/legacy_test/test_tensor_scalar_type_promotion_static.py +++ b/test/legacy_test/test_tensor_scalar_type_promotion_static.py @@ -776,5 +776,18 @@ def test_dtype_is_expected(self): ) +class Test0DTensor(unittest.TestCase): + def test_0d_add_0d(self): + paddle.enable_static() + prog = paddle.static.Program() + with paddle.static.program_guard(prog): + a = paddle.ones([], dtype='complex128') + b = paddle.ones([], dtype='complex64') + out = a + b + # mod API not support complex + res = self.exe.run(prog, fetch_list=[out]) + return res + + if __name__ == '__main__': unittest.main() diff --git a/test/legacy_test/test_tensor_type_promotion.py b/test/legacy_test/test_tensor_type_promotion.py index d9524529941a3..155f78c78bdf8 100644 --- a/test/legacy_test/test_tensor_type_promotion.py +++ b/test/legacy_test/test_tensor_type_promotion.py @@ -2796,5 +2796,26 @@ def run_api(self): create_test_case(TestAPIMSELossInStatic, 'float32', 'float64', 'float64') + +class TestTypePromotionRaiseError(unittest.TestCase): + def test_static_type_error(self): + paddle.enable_static() + with self.assertRaises(TypeError): + prog = paddle.static.Program() + exe = paddle.static.Executor() + with paddle.static.program_guard(prog): + a = paddle.ones([3, 3], dtype='float32') + b = paddle.ones([3, 3], dtype='float64') + out = a.__matmul__(b) + res = exe.run(prog, fetch_list=[out]) + return res + + def test_dygraph_type_error(self): + with self.assertRaises(TypeError): + a = paddle.ones([3, 3], dtype='float32') + b = paddle.ones([3, 3], dtype='int32') + return a + b + + if __name__ == '__main__': unittest.main() From ed5ed3df03c5bb94817ea35ed8fa8d936e06b909 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Tue, 26 Mar 2024 02:50:14 +0000 Subject: [PATCH 26/34] fix increase unittest --- python/paddle/tensor/stat.py | 2 +- test/legacy_test/test_tensor_scalar_type_promotion_static.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/paddle/tensor/stat.py b/python/paddle/tensor/stat.py index c18f987a98586..74b492ab32eb5 100644 --- a/python/paddle/tensor/stat.py +++ b/python/paddle/tensor/stat.py @@ -712,7 +712,7 @@ def _compute_index(index): if interpolation == "midpoint": return (tensor_upper + tensor_below) / 2 - weights = (index - indices_below).astype(x.dtype) + weights = (index - indices_below.astype(index.dtype)).astype(x.dtype) # "linear" return paddle.lerp( tensor_below.astype(x.dtype), diff --git a/test/legacy_test/test_tensor_scalar_type_promotion_static.py b/test/legacy_test/test_tensor_scalar_type_promotion_static.py index ecac148c839e0..ed17cc32bea97 100644 --- a/test/legacy_test/test_tensor_scalar_type_promotion_static.py +++ b/test/legacy_test/test_tensor_scalar_type_promotion_static.py @@ -780,12 +780,12 @@ class Test0DTensor(unittest.TestCase): def test_0d_add_0d(self): paddle.enable_static() prog = paddle.static.Program() + exe = paddle.static.Executor() with paddle.static.program_guard(prog): a = paddle.ones([], dtype='complex128') b = paddle.ones([], dtype='complex64') out = a + b - # mod API not support complex - res = self.exe.run(prog, fetch_list=[out]) + res = exe.run(prog, fetch_list=[out]) return res From 9b1caf1756c791d4dacc70184781310950682c58 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Fri, 29 Mar 2024 07:31:27 +0000 Subject: [PATCH 27/34] bug fix --- paddle/fluid/pybind/eager_math_op_patch.cc | 211 ++++++++++++++------- 1 file changed, 147 insertions(+), 64 deletions(-) diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index d83624d7ca5e3..960b45428445b 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -244,6 +244,15 @@ static PyObject* tensor__add__method(TensorObject* self, paddle::Tensor other_tensor; if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -283,10 +292,6 @@ static PyObject* tensor__add__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -380,6 +385,15 @@ static PyObject* tensor__sub__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -417,10 +431,6 @@ static PyObject* tensor__sub__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -512,6 +522,15 @@ static PyObject* tensor__rsub__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); auto self_tensor_ref = self->tensor; // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -551,10 +570,6 @@ static PyObject* tensor__rsub__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -649,8 +664,18 @@ static PyObject* tensor__mul__method(TensorObject* self, // if one of the input is numpy or scalar, no need to do inplace cast. paddle::Tensor other_tensor; if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); + // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. auto self_tensor_size = self_tensor_ref.shape().size(); @@ -659,6 +684,8 @@ static PyObject* tensor__mul__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); + auto self_tensor_ref_0d = self_tensor_ref; + auto other_tensor_ref_0d = other_tensor_ref; // different major types or both 0-d tensor follow with T+T rule. if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), other_tensor_ref.dtype()) || @@ -688,10 +715,6 @@ static PyObject* tensor__mul__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -791,6 +814,15 @@ static PyObject* tensor__div__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -830,10 +862,6 @@ static PyObject* tensor__div__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -947,6 +975,15 @@ static PyObject* tensor__rdiv__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -986,10 +1023,6 @@ static PyObject* tensor__rdiv__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1097,6 +1130,15 @@ static PyObject* tensor__gt__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -1136,10 +1178,6 @@ static PyObject* tensor__gt__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1240,6 +1278,15 @@ static PyObject* tensor__ge__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -1279,10 +1326,6 @@ static PyObject* tensor__ge__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1388,6 +1431,15 @@ static PyObject* tensor__mod__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -1427,10 +1479,6 @@ static PyObject* tensor__mod__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1656,6 +1704,15 @@ static PyObject* tensor__lt__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -1695,10 +1752,6 @@ static PyObject* tensor__lt__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1799,6 +1852,15 @@ static PyObject* tensor__le__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -1838,10 +1900,6 @@ static PyObject* tensor__le__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -1947,6 +2005,15 @@ static PyObject* tensor__floordiv__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -1986,10 +2053,6 @@ static PyObject* tensor__floordiv__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -2084,6 +2147,15 @@ static PyObject* tensor__pow__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -2124,10 +2196,6 @@ static PyObject* tensor__pow__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -2232,6 +2300,15 @@ static PyObject* tensor__rpow__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -2272,10 +2349,6 @@ static PyObject* tensor__rpow__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -2376,6 +2449,15 @@ static PyObject* tensor__ne__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -2415,10 +2497,6 @@ static PyObject* tensor__ne__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { @@ -2517,6 +2595,15 @@ static PyObject* tensor__eq__method(TensorObject* self, ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); } } else if (PyCheckTensor(other_obj)) { + auto& self_tensor_ref_addr = self->tensor; + auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); + const phi::distributed::ProcessMesh* mesh = nullptr; + if (InputsContainDistTensor( + &mesh, self_tensor_ref_addr, other_tensor_ref_addr)) { + ConvertAllInputsToDistTensor( + mesh, self_tensor_ref_addr, other_tensor_ref_addr); + } + auto self_tensor_ref = self->tensor; auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + @@ -2556,10 +2643,6 @@ static PyObject* tensor__eq__method(TensorObject* self, } } - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor_ref, other_tensor_ref)) { - ConvertAllInputsToDistTensor(mesh, self_tensor_ref, other_tensor_ref); - } self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; } else { From e2a76863b1e4e729dc9c2961639e2716eecbc3a3 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Fri, 12 Apr 2024 08:31:39 +0000 Subject: [PATCH 28/34] fixed by comment --- paddle/fluid/pybind/eager_math_op_patch.cc | 1266 +++++++++----------- 1 file changed, 534 insertions(+), 732 deletions(-) diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index 960b45428445b..d1ccb53c74859 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -166,23 +166,20 @@ void SetDevice(paddle::platform::Place place) { // scalar func only support add, radd, sub, rsub, mul, rmul, div, truediv. // this function will update gradually. paddle::Tensor CallScalarFuction(const paddle::Tensor& self_tensor, - double other, + float other, std::string op_type) { paddle::Tensor ret; + // scale_ad_func need sclar and bias with float type. if (op_type == "add" || op_type == "radd") { - ret = scale_ad_func( - self_tensor, phi::Scalar(1.0), static_cast(other), true); + ret = scale_ad_func(self_tensor, phi::Scalar(1.0), other, true); } else if (op_type == "sub") { - ret = scale_ad_func( - self_tensor, phi::Scalar(1.0), static_cast(-other), true); - + ret = scale_ad_func(self_tensor, phi::Scalar(1.0), -other, true); } else if (op_type == "rsub") { - ret = scale_ad_func( - self_tensor, phi::Scalar(-1.0), static_cast(other), true); + ret = scale_ad_func(self_tensor, phi::Scalar(-1.0), other, true); } else if (op_type == "mul") { - ret = scale_ad_func(self_tensor, phi::Scalar(other), 0.0, true); + ret = scale_ad_func(self_tensor, other, 0.0, true); } else if (op_type == "div") { - ret = scale_ad_func(self_tensor, phi::Scalar(1.0 / other), 0.0, true); + ret = scale_ad_func(self_tensor, 1.0 / other, 0.0, true); } else if (op_type == "pow") { ret = pow_ad_func(self_tensor, other); } @@ -190,6 +187,26 @@ paddle::Tensor CallScalarFuction(const paddle::Tensor& self_tensor, return ret; } +phi::DataType TypePromotionForZeroDimTensor(std::string func, + paddle::Tensor self_tensor, + paddle::Tensor other_tensor) { + if (!is_common_dtype_for_scalar(self_tensor.dtype(), other_tensor.dtype()) || + (self_tensor.shape().size() == 0 && other_tensor.shape().size() == 0)) { + phi::DataType promote_type = + GetPromoteDtype(func, self_tensor.dtype(), other_tensor.dtype()); + return promote_type; + } else { + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + std::cout << "got common dtype" << std::endl; + if (self_tensor.shape().size() == 0) { + return other_tensor.dtype(); + } else { + return self_tensor.dtype(); + } + } +} + static PyObject* tensor__add__method(TensorObject* self, PyObject* args, PyObject* kwargs) { @@ -211,22 +228,19 @@ static PyObject* tensor__add__method(TensorObject* self, // 1. scalar exists cases if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - double other = 0.0; if (PyFloat_Check(other_obj)) { - other = CastPyArg2Double(other_obj, "__add__", 0); if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::INT64); - } - other = CastPyArg2Double(other_obj, "__add__", 0); + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } + float other = CastPyArg2Float(other_obj, "__add__", 0); { eager_gil_scoped_release guard; ret = CallScalarFuction(self_tensor, other, "add"); @@ -264,31 +278,15 @@ static PyObject* tensor__add__method(TensorObject* self, VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "add", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "add", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -316,10 +314,7 @@ static PyObject* tensor__add__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to add_ad_func - - // 4. calculation + // 3. calculation VLOG(6) << "Calling add_ad_func in tensor__add__method"; { @@ -353,21 +348,19 @@ static PyObject* tensor__sub__method(TensorObject* self, // 1. scalar exists cases if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - double other = 0.0; if (PyFloat_Check(other_obj)) { - other = CastPyArg2Double(other_obj, "__sub__", 0); if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::INT64); - } - other = CastPyArg2Double(other_obj, "__sub__", 0); + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } + + float other = CastPyArg2Float(other_obj, "__sub__", 0); { eager_gil_scoped_release guard; ret = CallScalarFuction(self_tensor, other, "sub"); @@ -404,30 +397,15 @@ static PyObject* tensor__sub__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "subtract", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "subtract", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -455,10 +433,7 @@ static PyObject* tensor__sub__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to subtract_ad_func - - // 4. calculation + // 3. calculation VLOG(6) << "Calling subtract_ad_func in tensor__sub__method"; { eager_gil_scoped_release guard; @@ -491,21 +466,19 @@ static PyObject* tensor__rsub__method(TensorObject* self, // 1. scalar exists cases if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - double other = 0.0; if (PyFloat_Check(other_obj)) { - other = CastPyArg2Double(other_obj, "__rsub__", 0); if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::INT64); - } - other = CastPyArg2Double(other_obj, "__rsub__", 0); + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } + + float other = CastPyArg2Float(other_obj, "__rsub__", 0); { eager_gil_scoped_release guard; ret = CallScalarFuction(self_tensor, other, "rsub"); @@ -541,32 +514,15 @@ static PyObject* tensor__rsub__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "subtract", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "subtract", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -594,10 +550,7 @@ static PyObject* tensor__rsub__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to subtract_ad_func - - // 4. calculation + // 3. calculation VLOG(6) << "Calling subtract_ad_func in tensor__rsub__method"; { eager_gil_scoped_release guard; @@ -631,21 +584,19 @@ static PyObject* tensor__mul__method(TensorObject* self, // 1. scalar exists cases if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - double other = 0.0; if (PyFloat_Check(other_obj)) { - other = CastPyArg2Double(other_obj, "__mul__", 0); if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::INT64); - } - other = CastPyArg2Double(other_obj, "__mul__", 0); + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } + + float other = CastPyArg2Float(other_obj, "__mul__", 0); { eager_gil_scoped_release guard; ret = CallScalarFuction(self_tensor, other, "mul"); @@ -684,34 +635,15 @@ static PyObject* tensor__mul__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - auto self_tensor_ref_0d = self_tensor_ref; - auto other_tensor_ref_0d = other_tensor_ref; - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "multiply", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "multiply", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -745,10 +677,7 @@ static PyObject* tensor__mul__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to multiply_ad_func - - // 4. calculation + // 3. calculation VLOG(6) << "Calling multiply_ad_func in tensor__mul__method"; { eager_gil_scoped_release guard; @@ -783,21 +712,13 @@ static PyObject* tensor__div__method(TensorObject* self, // 1. scalar exists cases if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - double other = 0.0; - if (PyFloat_Check(other_obj)) { - other = CastPyArg2Double(other_obj, "__div__", 0); - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::INT64); - } - other = CastPyArg2Double(other_obj, "__div__", 0); - } if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } + + float other = CastPyArg2Float(other_obj, "__div__", 0); { eager_gil_scoped_release guard; ret = CallScalarFuction(self_tensor, other, "div"); @@ -833,32 +754,15 @@ static PyObject* tensor__div__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "divide", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "divide", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -934,21 +838,10 @@ static PyObject* tensor__rdiv__method(TensorObject* self, // 1. scalar exists cases // there is no scalar_div function for __rdiv__ and __rtruediv__ - double other_double = 0.0; - bool has_other_double = false; + // double other_double = 0.0; + // bool has_other_double = false; if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - if (PyFloat_Check(other_obj)) { // NOLINT - other_double = CastPyArg2Double(other_obj, "__rdiv__", 0); - has_other_double = true; - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { // NOLINT - if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::INT64); - } - other_double = CastPyArg2Double(other_obj, "__rdiv__", 0); - has_other_double = true; - } if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; @@ -963,18 +856,20 @@ static PyObject* tensor__rdiv__method(TensorObject* self, } // 2. create or get tensor for other_obj + paddle::Tensor other_tensor; - if (has_other_double) { - eager_gil_scoped_release guard; - other_tensor = full_ad_func(self_tensor.shape(), - phi::Scalar(other_double), - self_tensor.dtype(), - place); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - } - } else if (PyCheckTensor(other_obj)) { + // if (has_other_double) { + // eager_gil_scoped_release guard; + // other_tensor = full_ad_func(self_tensor.shape(), + // phi::Scalar(other_double), + // self_tensor.dtype(), + // place); + // const phi::distributed::ProcessMesh* mesh = nullptr; + // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { + // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); + // } + // } else + if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); const phi::distributed::ProcessMesh* mesh = nullptr; @@ -994,32 +889,15 @@ static PyObject* tensor__rdiv__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "divide", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "divide", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -1090,24 +968,37 @@ static PyObject* tensor__gt__method(TensorObject* self, paddle::Tensor ret; paddle::Tensor self_tensor = self->tensor; PyObject* other_obj = PyTuple_GET_ITEM(args, 0); + // bool has_other_double = false; + // double other_double =0.0; // 1. scalar exists cases // there is no scalar function for __gt__ now - double other_double = 0.0; - bool has_other_double = false; + // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || + // IsNumpyType(other_obj)) { + // if (PyFloat_Check(other_obj)) { + // // other_double = CastPyArg2Double(other_obj, "__gt__", 0); + // // has_other_double = true; + // if (_supported_int_dtype_.find(self_tensor.dtype()) != + // _supported_int_dtype_.end()) { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + // } + // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + // // other_double = CastPyArg2Double(other_obj, "__gt__", 0); + // // has_other_double = true; + // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__gt__", 0); - has_other_double = true; if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__gt__", 0); - has_other_double = true; + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } } else if (PyComplex_Check(other_obj)) { if (is_support_complex(self_tensor.dtype()) == false) { @@ -1119,17 +1010,18 @@ static PyObject* tensor__gt__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - if (has_other_double) { - eager_gil_scoped_release guard; - other_tensor = full_ad_func(self_tensor.shape(), - phi::Scalar(other_double), - self_tensor.dtype(), - place); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - } - } else if (PyCheckTensor(other_obj)) { + // if (has_other_double) { + // eager_gil_scoped_release guard; + // other_tensor = full_ad_func(self_tensor.shape(), + // phi::Scalar(other_double), + // self_tensor.dtype(), + // place); + // const phi::distributed::ProcessMesh* mesh = nullptr; + // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { + // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); + // } + // } else + if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); const phi::distributed::ProcessMesh* mesh = nullptr; @@ -1149,32 +1041,15 @@ static PyObject* tensor__gt__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "greater_than", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "greater_than", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -1206,10 +1081,7 @@ static PyObject* tensor__gt__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to greater_than_ad_func - - // 4. calculation + // 3. calculation VLOG(6) << "Calling greater_than_ad_func in tensor__gt__method"; { eager_gil_scoped_release guard; @@ -1241,21 +1113,34 @@ static PyObject* tensor__ge__method(TensorObject* self, // 1. scalar exists cases // there is no scalar function for __ge__ now - double other_double = 0.0; - bool has_other_double = false; + // double other_double = 0.0; + // bool has_other_double = false; + // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || + // IsNumpyType(other_obj)) { + // if (PyFloat_Check(other_obj)) { + // // other_double = CastPyArg2Double(other_obj, "__ge__", 0); + // // has_other_double = true; + // if (_supported_int_dtype_.find(self_tensor.dtype()) != + // _supported_int_dtype_.end()) { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + // } + // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + // other_double = CastPyArg2Double(other_obj, "__ge__", 0); + // has_other_double = true; + // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__ge__", 0); - has_other_double = true; if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__ge__", 0); - has_other_double = true; + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } } else if (PyComplex_Check(other_obj)) { if (is_support_complex(self_tensor.dtype()) == false) { @@ -1267,17 +1152,18 @@ static PyObject* tensor__ge__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - if (has_other_double) { - eager_gil_scoped_release guard; - other_tensor = full_ad_func(self_tensor.shape(), - phi::Scalar(other_double), - self_tensor.dtype(), - place); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - } - } else if (PyCheckTensor(other_obj)) { + // if (has_other_double) { + // eager_gil_scoped_release guard; + // other_tensor = full_ad_func(self_tensor.shape(), + // phi::Scalar(other_double), + // self_tensor.dtype(), + // place); + // const phi::distributed::ProcessMesh* mesh = nullptr; + // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { + // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); + // } + // } else + if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); const phi::distributed::ProcessMesh* mesh = nullptr; @@ -1297,32 +1183,15 @@ static PyObject* tensor__ge__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "greater_equal", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "greater_equal", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -1354,10 +1223,7 @@ static PyObject* tensor__ge__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to greater_equal_ad_func - - // 4. calculation + // 3. calculation VLOG(6) << "Calling greater_equal_ad_func in tensor__ge__method"; { eager_gil_scoped_release guard; @@ -1390,25 +1256,39 @@ static PyObject* tensor__mod__method(TensorObject* self, // 1. scalar exists cases // there is no scalar_mod function for __mod__ now - float other_double = 0.0f; - bool has_other_double = false; + // float other_double = 0.0f; + // bool has_other_double = false; + // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || + // IsNumpyType(other_obj)) { + // if (PyFloat_Check(other_obj)) { + // other_double = CastPyArg2Double(other_obj, "__mod__", 0); // NOLINT + // has_other_double = true; + // if (_supported_int_dtype_.find(self_tensor.dtype()) != + // _supported_int_dtype_.end()) { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + // } + // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + // if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) + // { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::INT64); + // } + // other_double = CastPyArg2Double(other_obj, "__mod__", 0); // NOLINT + // has_other_double = true; + // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__mod__", 0); // NOLINT - has_other_double = true; if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::INT64); - } - other_double = CastPyArg2Double(other_obj, "__mod__", 0); // NOLINT - has_other_double = true; + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } } else if (PyComplex_Check(other_obj)) { if (is_support_complex(self_tensor.dtype()) == false) { @@ -1420,17 +1300,18 @@ static PyObject* tensor__mod__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - if (has_other_double) { - eager_gil_scoped_release guard; - other_tensor = full_ad_func(self_tensor.shape(), - phi::Scalar(other_double), - self_tensor.dtype(), - self_tensor.place()); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - } - } else if (PyCheckTensor(other_obj)) { + // if (has_other_double) { + // eager_gil_scoped_release guard; + // other_tensor = full_ad_func(self_tensor.shape(), + // phi::Scalar(other_double), + // self_tensor.dtype(), + // self_tensor.place()); + // const phi::distributed::ProcessMesh* mesh = nullptr; + // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { + // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); + // } + // } else + if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); const phi::distributed::ProcessMesh* mesh = nullptr; @@ -1450,32 +1331,15 @@ static PyObject* tensor__mod__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "remainder", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "remainder", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -1507,10 +1371,7 @@ static PyObject* tensor__mod__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to remainder_ad_func - - // 4. calculation + // 3. calculation VLOG(6) << "Calling remainder_ad_func in tensor__mod__method"; { eager_gil_scoped_release guard; @@ -1667,21 +1528,34 @@ static PyObject* tensor__lt__method(TensorObject* self, // 1. scalar exists cases // there is no scalar function for __lt__ now - float other_double = 0.0f; - bool has_other_double = false; + // float other_double = 0.0f; + // bool has_other_double = false; + // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || + // IsNumpyType(other_obj)) { + // if (PyFloat_Check(other_obj)) { + // other_double = CastPyArg2Double(other_obj, "__lt__", 0); // NOLINT + // has_other_double = true; + // if (_supported_int_dtype_.find(self_tensor.dtype()) != + // _supported_int_dtype_.end()) { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + // } + // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + // other_double = CastPyArg2Double(other_obj, "__lt__", 0); // NOLINT + // has_other_double = true; + // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__lt__", 0); // NOLINT - has_other_double = true; if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__lt__", 0); // NOLINT - has_other_double = true; + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } } else if (PyComplex_Check(other_obj)) { if (is_support_complex(self_tensor.dtype()) == false) { @@ -1693,17 +1567,18 @@ static PyObject* tensor__lt__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - if (has_other_double) { - eager_gil_scoped_release guard; - other_tensor = full_ad_func(self_tensor.shape(), - phi::Scalar(other_double), - self_tensor.dtype(), - self_tensor.place()); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - } - } else if (PyCheckTensor(other_obj)) { + // if (has_other_double) { + // eager_gil_scoped_release guard; + // other_tensor = full_ad_func(self_tensor.shape(), + // phi::Scalar(other_double), + // self_tensor.dtype(), + // self_tensor.place()); + // const phi::distributed::ProcessMesh* mesh = nullptr; + // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { + // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); + // } + // } else + if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); const phi::distributed::ProcessMesh* mesh = nullptr; @@ -1723,32 +1598,15 @@ static PyObject* tensor__lt__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "less_than", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "less_than", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -1780,10 +1638,7 @@ static PyObject* tensor__lt__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to less_than_ad_func - - // // 4. calculation + // // 3. calculation VLOG(6) << "Calling less_than_ad_func in tensor__lt__method"; { eager_gil_scoped_release guard; @@ -1815,21 +1670,34 @@ static PyObject* tensor__le__method(TensorObject* self, // 1. scalar exists cases // there is no scalar function for __le__ now - float other_double = 0.0f; - bool has_other_double = false; + // float other_double = 0.0f; + // bool has_other_double = false; + // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || + // IsNumpyType(other_obj)) { + // if (PyFloat_Check(other_obj)) { + // other_double = CastPyArg2Double(other_obj, "__le__", 0); // NOLINT + // has_other_double = true; + // if (_supported_int_dtype_.find(self_tensor.dtype()) != + // _supported_int_dtype_.end()) { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + // } + // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + // other_double = CastPyArg2Double(other_obj, "__le__", 0); // NOLINT + // has_other_double = true; + // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__le__", 0); // NOLINT - has_other_double = true; if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__le__", 0); // NOLINT - has_other_double = true; + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } } else if (PyComplex_Check(other_obj)) { if (is_support_complex(self_tensor.dtype()) == false) { @@ -1841,17 +1709,18 @@ static PyObject* tensor__le__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - if (has_other_double) { - eager_gil_scoped_release guard; - other_tensor = full_ad_func(self_tensor.shape(), - phi::Scalar(other_double), - self_tensor.dtype(), - self_tensor.place()); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - } - } else if (PyCheckTensor(other_obj)) { + // if (has_other_double) { + // eager_gil_scoped_release guard; + // other_tensor = full_ad_func(self_tensor.shape(), + // phi::Scalar(other_double), + // self_tensor.dtype(), + // self_tensor.place()); + // const phi::distributed::ProcessMesh* mesh = nullptr; + // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { + // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); + // } + // } else + if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); const phi::distributed::ProcessMesh* mesh = nullptr; @@ -1871,32 +1740,15 @@ static PyObject* tensor__le__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "less_equal", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "less_equal", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -1928,10 +1780,7 @@ static PyObject* tensor__le__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to less_equal_ad_func - - // 4. calculation + // 3. calculation VLOG(6) << "Calling less_equal_ad_func in tensor__le__method"; { eager_gil_scoped_release guard; @@ -1964,25 +1813,39 @@ static PyObject* tensor__floordiv__method(TensorObject* self, // 1. scalar exists cases or not // there is no scalar case for floordiv, but alse need to cast self_tensor // in need. - double other_double = 0.0; - bool has_other_double = false; + // double other_double = 0.0; + // bool has_other_double = false; + // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || + // IsNumpyType(other_obj)) { + // if (PyFloat_Check(other_obj)) { + // other_double = CastPyArg2Double(other_obj, "__floordiv__", 0); + // has_other_double = true; + // if (_supported_int_dtype_.find(self_tensor.dtype()) != + // _supported_int_dtype_.end()) { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + // } + // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + // if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) + // { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::INT64); + // } + // other_double = CastPyArg2Double(other_obj, "__floordiv__", 0); + // has_other_double = true; + // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__floordiv__", 0); - has_other_double = true; if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::INT64); - } - other_double = CastPyArg2Double(other_obj, "__floordiv__", 0); - has_other_double = true; + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } } else if (PyComplex_Check(other_obj)) { if (is_support_complex(self_tensor.dtype()) == false) { @@ -1994,17 +1857,18 @@ static PyObject* tensor__floordiv__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - if (has_other_double) { - eager_gil_scoped_release guard; - other_tensor = full_ad_func(self_tensor.shape(), - phi::Scalar(other_double), - self_tensor.dtype(), - self_tensor.place()); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - } - } else if (PyCheckTensor(other_obj)) { + // if (has_other_double) { + // eager_gil_scoped_release guard; + // other_tensor = full_ad_func(self_tensor.shape(), + // phi::Scalar(other_double), + // self_tensor.dtype(), + // self_tensor.place()); + // const phi::distributed::ProcessMesh* mesh = nullptr; + // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { + // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); + // } + // } else + if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); const phi::distributed::ProcessMesh* mesh = nullptr; @@ -2024,32 +1888,15 @@ static PyObject* tensor__floordiv__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "floor_divide", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "floor_divide", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -2079,10 +1926,7 @@ static PyObject* tensor__floordiv__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to floor_divide_ad_func - - // 4. calculation + // 3. calculation VLOG(6) << "Calling floor_divide_ad_func in tensor__floordiv__method"; { eager_gil_scoped_release guard; @@ -2116,21 +1960,18 @@ static PyObject* tensor__pow__method(TensorObject* self, // 1. scalar exists cases if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - double other = 0.0; if (PyFloat_Check(other_obj)) { - other = CastPyArg2Double(other_obj, "__pow__", 0); if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::INT64); - } - other = CastPyArg2Double(other_obj, "__pow__", 0); + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } + float other = CastPyArg2Float(other_obj, "__pow__", 0); { eager_gil_scoped_release guard; ret = CallScalarFuction(self_tensor, other, "pow"); @@ -2166,33 +2007,15 @@ static PyObject* tensor__pow__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype("elementwise_pow", - self_tensor_ref.dtype(), - other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "elementwise_pow", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -2222,10 +2045,7 @@ static PyObject* tensor__pow__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to elementwise_pow_ad_func - - // 4. calculation + // 3. calculation VLOG(6) << "Calling elementwise_pow_ad_func in tensor__pow__method"; { eager_gil_scoped_release guard; @@ -2257,27 +2077,41 @@ static PyObject* tensor__rpow__method(TensorObject* self, PyObject* other_obj = PyTuple_GET_ITEM(args, 0); // 1. scalar exists cases or not - // there is no scalar case for rpow, but alse need to cast self_tensor in + // there is no scalar case for rpow, but also need to cast self_tensor in // need. - double other_double = 0.0; - bool has_other_double = false; + // double other_double = 0.0; + // bool has_other_double = false; + // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || + // IsNumpyType(other_obj)) { + // if (PyFloat_Check(other_obj)) { + // other_double = CastPyArg2Double(other_obj, "__rpow__", 0); + // has_other_double = true; + // if (_supported_int_dtype_.find(self_tensor.dtype()) != + // _supported_int_dtype_.end()) { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + // } + // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + // if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) + // { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::INT64); + // } + // other_double = CastPyArg2Double(other_obj, "__rpow__", 0); + // has_other_double = true; + // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__rpow__", 0); - has_other_double = true; if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, DataType::INT64); - } - other_double = CastPyArg2Double(other_obj, "__rpow__", 0); - has_other_double = true; + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } } else if (PyComplex_Check(other_obj)) { if (is_support_complex(self_tensor.dtype()) == false) { @@ -2289,17 +2123,18 @@ static PyObject* tensor__rpow__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - if (has_other_double) { - eager_gil_scoped_release guard; - other_tensor = full_ad_func(self_tensor.shape(), - phi::Scalar(other_double), - self_tensor.dtype(), - self_tensor.place()); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - } - } else if (PyCheckTensor(other_obj)) { + // if (has_other_double) { + // eager_gil_scoped_release guard; + // other_tensor = full_ad_func(self_tensor.shape(), + // phi::Scalar(other_double), + // self_tensor.dtype(), + // self_tensor.place()); + // const phi::distributed::ProcessMesh* mesh = nullptr; + // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { + // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); + // } + // } else + if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); const phi::distributed::ProcessMesh* mesh = nullptr; @@ -2319,33 +2154,15 @@ static PyObject* tensor__rpow__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype("elementwise_pow", - self_tensor_ref.dtype(), - other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "elementwise_pow", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -2377,10 +2194,7 @@ static PyObject* tensor__rpow__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to elementwise_pow_ad_func - - // 4. calculation + // 3. calculation VLOG(6) << "Calling elementwise_pow_ad_func in tensor__rpow__method"; { eager_gil_scoped_release guard; @@ -2412,21 +2226,34 @@ static PyObject* tensor__ne__method(TensorObject* self, // 1. scalar exists cases // there is no scalar function for __ne__ now - double other_double = 0.0; - bool has_other_double = false; + // double other_double = 0.0; + // bool has_other_double = false; + // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || + // IsNumpyType(other_obj)) { + // if (PyFloat_Check(other_obj)) { + // other_double = CastPyArg2Double(other_obj, "__ne__", 0); + // has_other_double = true; + // if (_supported_int_dtype_.find(self_tensor.dtype()) != + // _supported_int_dtype_.end()) { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + // } + // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + // other_double = CastPyArg2Double(other_obj, "__ne__", 0); + // has_other_double = true; + // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__ne__", 0); - has_other_double = true; if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__ne__", 0); - has_other_double = true; + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } } else if (PyComplex_Check(other_obj)) { if (is_support_complex(self_tensor.dtype()) == false) { @@ -2438,17 +2265,18 @@ static PyObject* tensor__ne__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - if (has_other_double) { - eager_gil_scoped_release guard; - other_tensor = full_ad_func(self_tensor.shape(), - phi::Scalar(other_double), - self_tensor.dtype(), - self_tensor.place()); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - } - } else if (PyCheckTensor(other_obj)) { + // if (has_other_double) { + // eager_gil_scoped_release guard; + // other_tensor = full_ad_func(self_tensor.shape(), + // phi::Scalar(other_double), + // self_tensor.dtype(), + // self_tensor.place()); + // const phi::distributed::ProcessMesh* mesh = nullptr; + // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { + // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); + // } + // } else + if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); const phi::distributed::ProcessMesh* mesh = nullptr; @@ -2468,32 +2296,15 @@ static PyObject* tensor__ne__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "not_equal", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "not_equal", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -2523,10 +2334,7 @@ static PyObject* tensor__ne__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to not_equal_ad_func - - // 4. calculation + // 3. calculation VLOG(6) << "Calling not_equal_ad_func in tensor__ne__method"; { eager_gil_scoped_release guard; @@ -2558,21 +2366,34 @@ static PyObject* tensor__eq__method(TensorObject* self, // 1. scalar exists cases // there is no scalar function for __eq__ now - double other_double = 0.0; - bool has_other_double = false; + // double other_double = 0.0; + // bool has_other_double = false; + // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || + // IsNumpyType(other_obj)) { + // if (PyFloat_Check(other_obj)) { + // other_double = CastPyArg2Double(other_obj, "__eq__", 0); + // has_other_double = true; + // if (_supported_int_dtype_.find(self_tensor.dtype()) != + // _supported_int_dtype_.end()) { + // eager_gil_scoped_release guard; + // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); + // } + // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { + // other_double = CastPyArg2Double(other_obj, "__eq__", 0); + // has_other_double = true; + // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__eq__", 0); - has_other_double = true; if (_supported_int_dtype_.find(self_tensor.dtype()) != _supported_int_dtype_.end()) { eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - other_double = CastPyArg2Double(other_obj, "__eq__", 0); - has_other_double = true; + } else if (PyCheckInteger(other_obj) && + self_tensor.dtype() == DataType::BOOL) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, DataType::INT64); } } else if (PyComplex_Check(other_obj)) { if (is_support_complex(self_tensor.dtype()) == false) { @@ -2584,17 +2405,18 @@ static PyObject* tensor__eq__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - if (has_other_double) { - eager_gil_scoped_release guard; - other_tensor = full_ad_func(self_tensor.shape(), - phi::Scalar(other_double), - self_tensor.dtype(), - self_tensor.place()); - const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - } - } else if (PyCheckTensor(other_obj)) { + // if (has_other_double) { + // eager_gil_scoped_release guard; + // other_tensor = full_ad_func(self_tensor.shape(), + // phi::Scalar(other_double), + // self_tensor.dtype(), + // self_tensor.place()); + // const phi::distributed::ProcessMesh* mesh = nullptr; + // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { + // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); + // } + // } else + if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); const phi::distributed::ProcessMesh* mesh = nullptr; @@ -2614,32 +2436,15 @@ static PyObject* tensor__eq__method(TensorObject* self, self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - if (!is_common_dtype_for_scalar(self_tensor_ref.dtype(), - other_tensor_ref.dtype()) || - (self_tensor_size == 0 && other_tensor_size == 0)) { - phi::DataType promote_type = GetPromoteDtype( - "equal", self_tensor_ref.dtype(), other_tensor_ref.dtype()); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor_ref.shape().size() == 0) { - eager_gil_scoped_release guard; - self_tensor_ref = - cast_ad_func(self_tensor_ref, other_tensor_ref.dtype()); - } else { - eager_gil_scoped_release guard; - other_tensor_ref = - cast_ad_func(other_tensor_ref, self_tensor_ref.dtype()); - } + phi::DataType promote_type = TypePromotionForZeroDimTensor( + "equal", self_tensor_ref, other_tensor_ref); + if (self_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); + } + if (other_tensor_ref.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); } } @@ -2669,10 +2474,7 @@ static PyObject* tensor__eq__method(TensorObject* self, } } - // 3. promote types or unify right var type to left var, float type promotion - // mv to equal_ad_func - - // 4. calculation + // 3. calculation VLOG(6) << "Calling equal_ad_func in tensor__eq__method"; { eager_gil_scoped_release guard; From 4a54c321d53eb8a3c4ddd5175405a8c49983f40f Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Fri, 12 Apr 2024 08:41:46 +0000 Subject: [PATCH 29/34] remove useless code. --- paddle/fluid/pybind/eager_math_op_patch.cc | 271 --------------------- 1 file changed, 271 deletions(-) diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index d1ccb53c74859..4582f1be1d730 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -838,8 +838,6 @@ static PyObject* tensor__rdiv__method(TensorObject* self, // 1. scalar exists cases // there is no scalar_div function for __rdiv__ and __rtruediv__ - // double other_double = 0.0; - // bool has_other_double = false; if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (_supported_int_dtype_.find(self_tensor.dtype()) != @@ -858,17 +856,6 @@ static PyObject* tensor__rdiv__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - // if (has_other_double) { - // eager_gil_scoped_release guard; - // other_tensor = full_ad_func(self_tensor.shape(), - // phi::Scalar(other_double), - // self_tensor.dtype(), - // place); - // const phi::distributed::ProcessMesh* mesh = nullptr; - // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - // } - // } else if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); @@ -968,25 +955,9 @@ static PyObject* tensor__gt__method(TensorObject* self, paddle::Tensor ret; paddle::Tensor self_tensor = self->tensor; PyObject* other_obj = PyTuple_GET_ITEM(args, 0); - // bool has_other_double = false; - // double other_double =0.0; // 1. scalar exists cases // there is no scalar function for __gt__ now - // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || - // IsNumpyType(other_obj)) { - // if (PyFloat_Check(other_obj)) { - // // other_double = CastPyArg2Double(other_obj, "__gt__", 0); - // // has_other_double = true; - // if (_supported_int_dtype_.find(self_tensor.dtype()) != - // _supported_int_dtype_.end()) { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - // } - // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - // // other_double = CastPyArg2Double(other_obj, "__gt__", 0); - // // has_other_double = true; - // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { @@ -1010,17 +981,6 @@ static PyObject* tensor__gt__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - // if (has_other_double) { - // eager_gil_scoped_release guard; - // other_tensor = full_ad_func(self_tensor.shape(), - // phi::Scalar(other_double), - // self_tensor.dtype(), - // place); - // const phi::distributed::ProcessMesh* mesh = nullptr; - // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - // } - // } else if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); @@ -1113,22 +1073,6 @@ static PyObject* tensor__ge__method(TensorObject* self, // 1. scalar exists cases // there is no scalar function for __ge__ now - // double other_double = 0.0; - // bool has_other_double = false; - // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || - // IsNumpyType(other_obj)) { - // if (PyFloat_Check(other_obj)) { - // // other_double = CastPyArg2Double(other_obj, "__ge__", 0); - // // has_other_double = true; - // if (_supported_int_dtype_.find(self_tensor.dtype()) != - // _supported_int_dtype_.end()) { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - // } - // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - // other_double = CastPyArg2Double(other_obj, "__ge__", 0); - // has_other_double = true; - // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { @@ -1152,17 +1096,6 @@ static PyObject* tensor__ge__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - // if (has_other_double) { - // eager_gil_scoped_release guard; - // other_tensor = full_ad_func(self_tensor.shape(), - // phi::Scalar(other_double), - // self_tensor.dtype(), - // place); - // const phi::distributed::ProcessMesh* mesh = nullptr; - // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - // } - // } else if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); @@ -1256,27 +1189,6 @@ static PyObject* tensor__mod__method(TensorObject* self, // 1. scalar exists cases // there is no scalar_mod function for __mod__ now - // float other_double = 0.0f; - // bool has_other_double = false; - // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || - // IsNumpyType(other_obj)) { - // if (PyFloat_Check(other_obj)) { - // other_double = CastPyArg2Double(other_obj, "__mod__", 0); // NOLINT - // has_other_double = true; - // if (_supported_int_dtype_.find(self_tensor.dtype()) != - // _supported_int_dtype_.end()) { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - // } - // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - // if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) - // { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::INT64); - // } - // other_double = CastPyArg2Double(other_obj, "__mod__", 0); // NOLINT - // has_other_double = true; - // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { @@ -1300,17 +1212,6 @@ static PyObject* tensor__mod__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - // if (has_other_double) { - // eager_gil_scoped_release guard; - // other_tensor = full_ad_func(self_tensor.shape(), - // phi::Scalar(other_double), - // self_tensor.dtype(), - // self_tensor.place()); - // const phi::distributed::ProcessMesh* mesh = nullptr; - // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - // } - // } else if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); @@ -1528,22 +1429,6 @@ static PyObject* tensor__lt__method(TensorObject* self, // 1. scalar exists cases // there is no scalar function for __lt__ now - // float other_double = 0.0f; - // bool has_other_double = false; - // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || - // IsNumpyType(other_obj)) { - // if (PyFloat_Check(other_obj)) { - // other_double = CastPyArg2Double(other_obj, "__lt__", 0); // NOLINT - // has_other_double = true; - // if (_supported_int_dtype_.find(self_tensor.dtype()) != - // _supported_int_dtype_.end()) { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - // } - // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - // other_double = CastPyArg2Double(other_obj, "__lt__", 0); // NOLINT - // has_other_double = true; - // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { @@ -1567,17 +1452,6 @@ static PyObject* tensor__lt__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - // if (has_other_double) { - // eager_gil_scoped_release guard; - // other_tensor = full_ad_func(self_tensor.shape(), - // phi::Scalar(other_double), - // self_tensor.dtype(), - // self_tensor.place()); - // const phi::distributed::ProcessMesh* mesh = nullptr; - // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - // } - // } else if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); @@ -1670,22 +1544,6 @@ static PyObject* tensor__le__method(TensorObject* self, // 1. scalar exists cases // there is no scalar function for __le__ now - // float other_double = 0.0f; - // bool has_other_double = false; - // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || - // IsNumpyType(other_obj)) { - // if (PyFloat_Check(other_obj)) { - // other_double = CastPyArg2Double(other_obj, "__le__", 0); // NOLINT - // has_other_double = true; - // if (_supported_int_dtype_.find(self_tensor.dtype()) != - // _supported_int_dtype_.end()) { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - // } - // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - // other_double = CastPyArg2Double(other_obj, "__le__", 0); // NOLINT - // has_other_double = true; - // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { @@ -1709,17 +1567,6 @@ static PyObject* tensor__le__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - // if (has_other_double) { - // eager_gil_scoped_release guard; - // other_tensor = full_ad_func(self_tensor.shape(), - // phi::Scalar(other_double), - // self_tensor.dtype(), - // self_tensor.place()); - // const phi::distributed::ProcessMesh* mesh = nullptr; - // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - // } - // } else if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); @@ -1813,27 +1660,6 @@ static PyObject* tensor__floordiv__method(TensorObject* self, // 1. scalar exists cases or not // there is no scalar case for floordiv, but alse need to cast self_tensor // in need. - // double other_double = 0.0; - // bool has_other_double = false; - // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || - // IsNumpyType(other_obj)) { - // if (PyFloat_Check(other_obj)) { - // other_double = CastPyArg2Double(other_obj, "__floordiv__", 0); - // has_other_double = true; - // if (_supported_int_dtype_.find(self_tensor.dtype()) != - // _supported_int_dtype_.end()) { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - // } - // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - // if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) - // { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::INT64); - // } - // other_double = CastPyArg2Double(other_obj, "__floordiv__", 0); - // has_other_double = true; - // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { @@ -1857,17 +1683,6 @@ static PyObject* tensor__floordiv__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - // if (has_other_double) { - // eager_gil_scoped_release guard; - // other_tensor = full_ad_func(self_tensor.shape(), - // phi::Scalar(other_double), - // self_tensor.dtype(), - // self_tensor.place()); - // const phi::distributed::ProcessMesh* mesh = nullptr; - // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - // } - // } else if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); @@ -2079,27 +1894,6 @@ static PyObject* tensor__rpow__method(TensorObject* self, // 1. scalar exists cases or not // there is no scalar case for rpow, but also need to cast self_tensor in // need. - // double other_double = 0.0; - // bool has_other_double = false; - // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || - // IsNumpyType(other_obj)) { - // if (PyFloat_Check(other_obj)) { - // other_double = CastPyArg2Double(other_obj, "__rpow__", 0); - // has_other_double = true; - // if (_supported_int_dtype_.find(self_tensor.dtype()) != - // _supported_int_dtype_.end()) { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - // } - // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - // if (PyCheckInteger(other_obj) && self_tensor.dtype() == DataType::BOOL) - // { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::INT64); - // } - // other_double = CastPyArg2Double(other_obj, "__rpow__", 0); - // has_other_double = true; - // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { @@ -2123,17 +1917,6 @@ static PyObject* tensor__rpow__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - // if (has_other_double) { - // eager_gil_scoped_release guard; - // other_tensor = full_ad_func(self_tensor.shape(), - // phi::Scalar(other_double), - // self_tensor.dtype(), - // self_tensor.place()); - // const phi::distributed::ProcessMesh* mesh = nullptr; - // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - // } - // } else if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); @@ -2226,22 +2009,6 @@ static PyObject* tensor__ne__method(TensorObject* self, // 1. scalar exists cases // there is no scalar function for __ne__ now - // double other_double = 0.0; - // bool has_other_double = false; - // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || - // IsNumpyType(other_obj)) { - // if (PyFloat_Check(other_obj)) { - // other_double = CastPyArg2Double(other_obj, "__ne__", 0); - // has_other_double = true; - // if (_supported_int_dtype_.find(self_tensor.dtype()) != - // _supported_int_dtype_.end()) { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - // } - // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - // other_double = CastPyArg2Double(other_obj, "__ne__", 0); - // has_other_double = true; - // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { @@ -2265,17 +2032,6 @@ static PyObject* tensor__ne__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - // if (has_other_double) { - // eager_gil_scoped_release guard; - // other_tensor = full_ad_func(self_tensor.shape(), - // phi::Scalar(other_double), - // self_tensor.dtype(), - // self_tensor.place()); - // const phi::distributed::ProcessMesh* mesh = nullptr; - // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - // } - // } else if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); @@ -2366,22 +2122,6 @@ static PyObject* tensor__eq__method(TensorObject* self, // 1. scalar exists cases // there is no scalar function for __eq__ now - // double other_double = 0.0; - // bool has_other_double = false; - // if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || - // IsNumpyType(other_obj)) { - // if (PyFloat_Check(other_obj)) { - // other_double = CastPyArg2Double(other_obj, "__eq__", 0); - // has_other_double = true; - // if (_supported_int_dtype_.find(self_tensor.dtype()) != - // _supported_int_dtype_.end()) { - // eager_gil_scoped_release guard; - // self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); - // } - // } else if (PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { - // other_double = CastPyArg2Double(other_obj, "__eq__", 0); - // has_other_double = true; - // } if (PyFloat_Check(other_obj) || PyCheckInteger(other_obj) || IsNumpyType(other_obj)) { if (PyFloat_Check(other_obj)) { @@ -2405,17 +2145,6 @@ static PyObject* tensor__eq__method(TensorObject* self, // 2. create or get tensor for other_obj paddle::Tensor other_tensor; - // if (has_other_double) { - // eager_gil_scoped_release guard; - // other_tensor = full_ad_func(self_tensor.shape(), - // phi::Scalar(other_double), - // self_tensor.dtype(), - // self_tensor.place()); - // const phi::distributed::ProcessMesh* mesh = nullptr; - // if (InputsContainDistTensor(&mesh, self_tensor, other_tensor)) { - // ConvertAllInputsToDistTensor(mesh, self_tensor, other_tensor); - // } - // } else if (PyCheckTensor(other_obj)) { auto& self_tensor_ref_addr = self->tensor; auto& other_tensor_ref_addr = CastPyArg2Tensor(other_obj, 0); From 0e62c85b4df75568c96924e0bf08791fb510a3a3 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Tue, 16 Apr 2024 03:52:08 +0000 Subject: [PATCH 30/34] fix --- paddle/fluid/pybind/eager_math_op_patch.cc | 31 ++++++++++++---------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index 4582f1be1d730..3f2375ebcc99f 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -166,7 +166,7 @@ void SetDevice(paddle::platform::Place place) { // scalar func only support add, radd, sub, rsub, mul, rmul, div, truediv. // this function will update gradually. paddle::Tensor CallScalarFuction(const paddle::Tensor& self_tensor, - float other, + double other, std::string op_type) { paddle::Tensor ret; // scale_ad_func need sclar and bias with float type. @@ -177,9 +177,9 @@ paddle::Tensor CallScalarFuction(const paddle::Tensor& self_tensor, } else if (op_type == "rsub") { ret = scale_ad_func(self_tensor, phi::Scalar(-1.0), other, true); } else if (op_type == "mul") { - ret = scale_ad_func(self_tensor, other, 0.0, true); + ret = scale_ad_func(self_tensor, phi::Scalar(other), 0.0, true); } else if (op_type == "div") { - ret = scale_ad_func(self_tensor, 1.0 / other, 0.0, true); + ret = scale_ad_func(self_tensor, phi::Scalar(1.0 / other), 0.0, true); } else if (op_type == "pow") { ret = pow_ad_func(self_tensor, other); } @@ -198,7 +198,6 @@ phi::DataType TypePromotionForZeroDimTensor(std::string func, } else { // common major types follow with tensor: int32(tensor) + int64(scalar) // = int32 - std::cout << "got common dtype" << std::endl; if (self_tensor.shape().size() == 0) { return other_tensor.dtype(); } else { @@ -240,7 +239,7 @@ static PyObject* tensor__add__method(TensorObject* self, self_tensor = cast_ad_func(self_tensor, DataType::INT64); } - float other = CastPyArg2Float(other_obj, "__add__", 0); + double other = CastPyArg2Double(other_obj, "__add__", 0); { eager_gil_scoped_release guard; ret = CallScalarFuction(self_tensor, other, "add"); @@ -360,7 +359,7 @@ static PyObject* tensor__sub__method(TensorObject* self, self_tensor = cast_ad_func(self_tensor, DataType::INT64); } - float other = CastPyArg2Float(other_obj, "__sub__", 0); + double other = CastPyArg2Double(other_obj, "__sub__", 0); { eager_gil_scoped_release guard; ret = CallScalarFuction(self_tensor, other, "sub"); @@ -478,7 +477,7 @@ static PyObject* tensor__rsub__method(TensorObject* self, self_tensor = cast_ad_func(self_tensor, DataType::INT64); } - float other = CastPyArg2Float(other_obj, "__rsub__", 0); + double other = CastPyArg2Double(other_obj, "__rsub__", 0); { eager_gil_scoped_release guard; ret = CallScalarFuction(self_tensor, other, "rsub"); @@ -596,7 +595,7 @@ static PyObject* tensor__mul__method(TensorObject* self, self_tensor = cast_ad_func(self_tensor, DataType::INT64); } - float other = CastPyArg2Float(other_obj, "__mul__", 0); + double other = CastPyArg2Double(other_obj, "__mul__", 0); { eager_gil_scoped_release guard; ret = CallScalarFuction(self_tensor, other, "mul"); @@ -718,7 +717,7 @@ static PyObject* tensor__div__method(TensorObject* self, self_tensor = cast_ad_func(self_tensor, DataType::FLOAT32); } - float other = CastPyArg2Float(other_obj, "__div__", 0); + double other = CastPyArg2Double(other_obj, "__div__", 0); { eager_gil_scoped_release guard; ret = CallScalarFuction(self_tensor, other, "div"); @@ -1786,7 +1785,7 @@ static PyObject* tensor__pow__method(TensorObject* self, eager_gil_scoped_release guard; self_tensor = cast_ad_func(self_tensor, DataType::INT64); } - float other = CastPyArg2Float(other_obj, "__pow__", 0); + double other = CastPyArg2Double(other_obj, "__pow__", 0); { eager_gil_scoped_release guard; ret = CallScalarFuction(self_tensor, other, "pow"); @@ -2080,8 +2079,10 @@ static PyObject* tensor__ne__method(TensorObject* self, full_ad_func({1}, value, DataType::COMPLEX64, self_tensor.place()); } else { eager_gil_scoped_release guard; - other_tensor = - full_ad_func({1}, value, self_tensor.dtype(), self_tensor.place()); + other_tensor = full_ad_func(self_tensor.shape(), + value, + self_tensor.dtype(), + self_tensor.place()); } } const phi::distributed::ProcessMesh* mesh = nullptr; @@ -2193,8 +2194,10 @@ static PyObject* tensor__eq__method(TensorObject* self, full_ad_func({1}, value, DataType::COMPLEX64, self_tensor.place()); } else { eager_gil_scoped_release guard; - other_tensor = - full_ad_func({1}, value, self_tensor.dtype(), self_tensor.place()); + other_tensor = full_ad_func(self_tensor.shape(), + value, + self_tensor.dtype(), + self_tensor.place()); } } const phi::distributed::ProcessMesh* mesh = nullptr; From c34aa6b2072876799563472c00aa2598c1171b0e Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Wed, 17 Apr 2024 09:06:23 +0000 Subject: [PATCH 31/34] fix --- paddle/fluid/pybind/eager_math_op_patch.cc | 280 ++++++--------------- 1 file changed, 79 insertions(+), 201 deletions(-) diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index 3f2375ebcc99f..784582982cfaa 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -187,23 +187,32 @@ paddle::Tensor CallScalarFuction(const paddle::Tensor& self_tensor, return ret; } -phi::DataType TypePromotionForZeroDimTensor(std::string func, - paddle::Tensor self_tensor, - paddle::Tensor other_tensor) { +void TypePromotionForZeroDimTensor(std::string func, + paddle::Tensor& self_tensor, // NOLINT + paddle::Tensor& other_tensor // NOLINT +) { + phi::DataType promote_type; if (!is_common_dtype_for_scalar(self_tensor.dtype(), other_tensor.dtype()) || (self_tensor.shape().size() == 0 && other_tensor.shape().size() == 0)) { - phi::DataType promote_type = + promote_type = GetPromoteDtype(func, self_tensor.dtype(), other_tensor.dtype()); - return promote_type; } else { // common major types follow with tensor: int32(tensor) + int64(scalar) // = int32 if (self_tensor.shape().size() == 0) { - return other_tensor.dtype(); + promote_type = other_tensor.dtype(); } else { - return self_tensor.dtype(); + promote_type = self_tensor.dtype(); } } + if (self_tensor.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, promote_type); + } + if (other_tensor.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, promote_type); + } } static PyObject* tensor__add__method(TensorObject* self, @@ -270,23 +279,13 @@ static PyObject* tensor__add__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); // different major types or both 0-d tensor follow with T+T rule. - phi::DataType promote_type = TypePromotionForZeroDimTensor( - "add", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } + TypePromotionForZeroDimTensor("add", self_tensor_ref, other_tensor_ref); } self_tensor = self_tensor_ref; @@ -390,22 +389,14 @@ static PyObject* tensor__sub__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "subtract", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -507,22 +498,14 @@ static PyObject* tensor__rsub__method(TensorObject* self, auto self_tensor_ref = self->tensor; // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "subtract", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -628,22 +611,14 @@ static PyObject* tensor__mul__method(TensorObject* self, // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "multiply", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -747,22 +722,14 @@ static PyObject* tensor__div__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "divide", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -869,22 +836,14 @@ static PyObject* tensor__rdiv__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "divide", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -994,22 +953,14 @@ static PyObject* tensor__gt__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "greater_than", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -1109,22 +1060,14 @@ static PyObject* tensor__ge__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "greater_equal", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -1225,22 +1168,14 @@ static PyObject* tensor__mod__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "remainder", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -1465,22 +1400,14 @@ static PyObject* tensor__lt__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "less_than", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -1580,22 +1507,14 @@ static PyObject* tensor__le__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "less_equal", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -1696,22 +1615,14 @@ static PyObject* tensor__floordiv__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "floor_divide", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -1815,22 +1726,14 @@ static PyObject* tensor__pow__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "elementwise_pow", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -1930,22 +1833,14 @@ static PyObject* tensor__rpow__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "elementwise_pow", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -2045,22 +1940,14 @@ static PyObject* tensor__ne__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor( "not_equal", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } } self_tensor = self_tensor_ref; @@ -2160,22 +2047,13 @@ static PyObject* tensor__eq__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - auto self_tensor_size = self_tensor_ref.shape().size(); - auto other_tensor_size = other_tensor_ref.shape().size(); - if ((self_tensor_size == 0 || other_tensor_size == 0) && + if ((self_tensor_ref.shape().size() == 0 || + other_tensor_ref.shape().size() == 0) && self_tensor_ref.dtype() != other_tensor_ref.dtype()) { VLOG(5) << "got 0-d tensor and need to do type promotion, x: " << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - phi::DataType promote_type = TypePromotionForZeroDimTensor( - "equal", self_tensor_ref, other_tensor_ref); - if (self_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor_ref = cast_ad_func(self_tensor_ref, promote_type); - } - if (other_tensor_ref.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor_ref = cast_ad_func(other_tensor_ref, promote_type); - } + // different major types or both 0-d tensor follow with T+T rule. + TypePromotionForZeroDimTensor("equal", self_tensor_ref, other_tensor_ref); } self_tensor = self_tensor_ref; From dc624f8568ba5bc4546a413c46ba0844d2dc2037 Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Thu, 18 Apr 2024 03:27:50 +0000 Subject: [PATCH 32/34] fix TypePromotionForZeroDimTensor --- paddle/fluid/pybind/eager_math_op_patch.cc | 216 ++++++--------------- 1 file changed, 55 insertions(+), 161 deletions(-) diff --git a/paddle/fluid/pybind/eager_math_op_patch.cc b/paddle/fluid/pybind/eager_math_op_patch.cc index 784582982cfaa..90cfe1db9f4bb 100644 --- a/paddle/fluid/pybind/eager_math_op_patch.cc +++ b/paddle/fluid/pybind/eager_math_op_patch.cc @@ -191,27 +191,35 @@ void TypePromotionForZeroDimTensor(std::string func, paddle::Tensor& self_tensor, // NOLINT paddle::Tensor& other_tensor // NOLINT ) { - phi::DataType promote_type; - if (!is_common_dtype_for_scalar(self_tensor.dtype(), other_tensor.dtype()) || - (self_tensor.shape().size() == 0 && other_tensor.shape().size() == 0)) { - promote_type = - GetPromoteDtype(func, self_tensor.dtype(), other_tensor.dtype()); - } else { - // common major types follow with tensor: int32(tensor) + int64(scalar) - // = int32 - if (self_tensor.shape().size() == 0) { - promote_type = other_tensor.dtype(); + if ((self_tensor.shape().size() == 0 || other_tensor.shape().size() == 0) && + self_tensor.dtype() != other_tensor.dtype()) { + VLOG(5) << "got 0-d tensor and need to do type promotion, x: " + << self_tensor.dtype() << " y: " << other_tensor.dtype(); + + phi::DataType promote_type; + // different major types or both 0-d tensor follow with T+T rule. + if (!is_common_dtype_for_scalar(self_tensor.dtype(), + other_tensor.dtype()) || + (self_tensor.shape().size() == 0 && other_tensor.shape().size() == 0)) { + promote_type = + GetPromoteDtype(func, self_tensor.dtype(), other_tensor.dtype()); } else { - promote_type = self_tensor.dtype(); + // common major types follow with tensor: int32(tensor) + int64(scalar) + // = int32 + if (self_tensor.shape().size() == 0) { + promote_type = other_tensor.dtype(); + } else { + promote_type = self_tensor.dtype(); + } + } + if (self_tensor.dtype() != promote_type) { + eager_gil_scoped_release guard; + self_tensor = cast_ad_func(self_tensor, promote_type); + } + if (other_tensor.dtype() != promote_type) { + eager_gil_scoped_release guard; + other_tensor = cast_ad_func(other_tensor, promote_type); } - } - if (self_tensor.dtype() != promote_type) { - eager_gil_scoped_release guard; - self_tensor = cast_ad_func(self_tensor, promote_type); - } - if (other_tensor.dtype() != promote_type) { - eager_gil_scoped_release guard; - other_tensor = cast_ad_func(other_tensor, promote_type); } } @@ -279,14 +287,7 @@ static PyObject* tensor__add__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor("add", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor("add", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -389,15 +390,8 @@ static PyObject* tensor__sub__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "subtract", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor( + "subtract", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -498,15 +492,8 @@ static PyObject* tensor__rsub__method(TensorObject* self, auto self_tensor_ref = self->tensor; // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "subtract", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor( + "subtract", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -611,15 +598,8 @@ static PyObject* tensor__mul__method(TensorObject* self, // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "multiply", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor( + "multiply", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -722,15 +702,7 @@ static PyObject* tensor__div__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "divide", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor("divide", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -836,15 +808,7 @@ static PyObject* tensor__rdiv__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "divide", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor("divide", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -953,15 +917,8 @@ static PyObject* tensor__gt__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "greater_than", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor( + "greater_than", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -1060,15 +1017,8 @@ static PyObject* tensor__ge__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "greater_equal", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor( + "greater_equal", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -1168,15 +1118,8 @@ static PyObject* tensor__mod__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "remainder", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor( + "remainder", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -1400,15 +1343,8 @@ static PyObject* tensor__lt__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "less_than", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor( + "less_than", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -1507,15 +1443,8 @@ static PyObject* tensor__le__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "less_equal", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor( + "less_equal", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -1615,15 +1544,8 @@ static PyObject* tensor__floordiv__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "floor_divide", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor( + "floor_divide", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -1726,15 +1648,8 @@ static PyObject* tensor__pow__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "elementwise_pow", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor( + "elementwise_pow", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -1833,15 +1748,8 @@ static PyObject* tensor__rpow__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "elementwise_pow", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor( + "elementwise_pow", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -1940,15 +1848,8 @@ static PyObject* tensor__ne__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor( - "not_equal", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor( + "not_equal", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; @@ -2047,14 +1948,7 @@ static PyObject* tensor__eq__method(TensorObject* self, auto other_tensor_ref = CastPyArg2Tensor(other_obj, 0); // got 0-d tensor, and need type promotion. The rules same with Tensor + // Scalar. - if ((self_tensor_ref.shape().size() == 0 || - other_tensor_ref.shape().size() == 0) && - self_tensor_ref.dtype() != other_tensor_ref.dtype()) { - VLOG(5) << "got 0-d tensor and need to do type promotion, x: " - << self_tensor_ref.dtype() << " y: " << other_tensor_ref.dtype(); - // different major types or both 0-d tensor follow with T+T rule. - TypePromotionForZeroDimTensor("equal", self_tensor_ref, other_tensor_ref); - } + TypePromotionForZeroDimTensor("equal", self_tensor_ref, other_tensor_ref); self_tensor = self_tensor_ref; other_tensor = other_tensor_ref; From de8ac06d106d84acb51cbe99c2973a3fc4c1cbcb Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Wed, 24 Apr 2024 12:07:07 +0000 Subject: [PATCH 33/34] add inplace API support, add special case can skip type promotion (add x=float32,y=float16/bfloat16). --- .../forwards/multiply_fwd_func.cc | 20 +- .../generator/eager_gen.py | 61 +- paddle/fluid/eager/type_promotion_utils.h | 11 + paddle/fluid/pybind/pybind.cc | 6 +- paddle/phi/common/type_promotion.h | 12 +- python/paddle/base/framework.py | 4 +- python/paddle/base/layers/math_op_patch.py | 4 +- .../legacy_test/test_tensor_type_promotion.py | 673 +++++++++++++++++- 8 files changed, 776 insertions(+), 15 deletions(-) diff --git a/paddle/fluid/eager/api/manual/eager_manual/forwards/multiply_fwd_func.cc b/paddle/fluid/eager/api/manual/eager_manual/forwards/multiply_fwd_func.cc index aa18f8cd4acb8..cfea756cf02d5 100644 --- a/paddle/fluid/eager/api/manual/eager_manual/forwards/multiply_fwd_func.cc +++ b/paddle/fluid/eager/api/manual/eager_manual/forwards/multiply_fwd_func.cc @@ -70,7 +70,7 @@ paddle::Tensor multiply_ad_func(const paddle::Tensor& x, } // Type promotion Logic - if (phi::NeedTypePromotion(x.dtype(), y.dtype())) { + if (phi::NeedTypePromotion("multiply", x.dtype(), y.dtype())) { VLOG(5) << "got different data type, run type promotion automatically."; LOG_FIRST_N(WARNING, 1) << "got different data type, run type promotion " @@ -247,6 +247,22 @@ paddle::Tensor& multiply__ad_func(paddle::Tensor& x, // NOLINT VLOG(5) << " No AMP for multiply__ad_func because it is a inplace or cast api. "; + + // Type promotion Logic + if (phi::NeedTypePromotion("multiply_", x.dtype(), y.dtype())) { + VLOG(5) << "got different data type, run type promotion automatically."; + LOG_FIRST_N(WARNING, 1) + << "got different data type, run type promotion " + "automatically, this may cause data type been changed."; + auto op_name = phi::TransToFluidOpName("multiply_"); + auto promotion_type = phi::GetPromoteDtype(op_name, x.dtype(), y.dtype()); + + x = egr::PromoteCastInplace("x", x, promotion_type); + auto new_y = egr::PromoteCast("y", y, promotion_type); + + return multiply__ad_func(x, new_y); + } + // Layout autotune if (egr::Controller::Instance().UseLayoutAutoTune()) { @@ -424,7 +440,7 @@ paddle::Tensor multiply_ad_func(const paddle::Tensor& x, } // Type promotion Logic - if (phi::NeedTypePromotion(x.dtype(), y.dtype())) { + if (phi::NeedTypePromotion("multiply", x.dtype(), y.dtype())) { VLOG(5) << "got different data type, run type promotion automatically."; LOG_FIRST_N(WARNING, 1) << "got different data type, run type promotion " diff --git a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py index 50a9ffc29e39c..d7379ffb4e444 100644 --- a/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py +++ b/paddle/fluid/eager/auto_code_generator/generator/eager_gen.py @@ -108,6 +108,24 @@ "atan2": ["x", "y"], } +type_promote_inplace_white_list = { + "add_": ["x", "y"], + "subtract_": ["x", "y"], + "divide_": ["x", "y"], + "floor_divide_": ["x", "y"], + "where_": ["x", "y"], + "equal_": ["x", "y"], + "not_equal_": ["x", "y"], + "less_than_": ["x", "y"], + "less_equal_": ["x", "y"], + "greater_than_": ["x", "y"], + "greater_equal_": ["x", "y"], + "logical_and_": ["x", "y"], + "logical_or_": ["x", "y"], + "logical_xor_": ["x", "y"], + "remainder_": ["x", "y"], +} + # dict of special api that forward api's output will affect backward api's output # backward api's output usually affected by backward api's input @@ -558,13 +576,13 @@ class {} : public egr::GradNodeBase {{ }} """ -TYPE_PROMOTION_LOGIC_TEMPLATE = """ if (phi::NeedTypePromotion({x}.dtype(), {y}.dtype())) {{ +TYPE_PROMOTION_LOGIC_TEMPLATE = """ if (phi::NeedTypePromotion({op_func_name}, {x}.dtype(), {y}.dtype())) {{ VLOG(5) << "got different data type, run type promotion automatically."; LOG_FIRST_N(WARNING, 1) << "got different data type, run type promotion automatically, this may cause data type been changed."; {op_name} auto promotion_type = phi::GetPromoteDtype(op_name, {x}.dtype(), {y}.dtype()); - auto new_{x} = egr::PromoteCast("{x}", {x}, promotion_type); + {x_cast} auto new_{y} = egr::PromoteCast("{y}", {y}, promotion_type); {return_value} @@ -1532,6 +1550,18 @@ def GenerateForwardDefinitionAndDeclaration(self, is_inplaced): type_promote_inputs_call_list[pos] = f"new_{name}" else: type_promote_inputs_call_list[pos] = f"{name}" + elif forward_api_name in type_promote_inplace_white_list: + if name in type_promote_inplace_white_list[forward_api_name]: + if ( + is_inplaced + and forward_inplace_map + and name in forward_inplace_map + ): + type_promote_inputs_call_list[pos] = f"{name}" + else: + type_promote_inputs_call_list[pos] = f"new_{name}" + else: + type_promote_inputs_call_list[pos] = f"{name}" if IsPlainTensorType(ttype): if is_optional: if ( @@ -1868,6 +1898,7 @@ def GenerateForwardDefinitionAndDeclaration(self, is_inplaced): # Forward type promotion logic if forward_api_name in type_promote_white_list: # only support two inputs + op_func_name = f"\"{forward_api_name}\"" x = type_promote_white_list[forward_api_name][0] y = type_promote_white_list[forward_api_name][1] type_promote_inputs_call_args_str = ", ".join( @@ -1875,9 +1906,35 @@ def GenerateForwardDefinitionAndDeclaration(self, is_inplaced): ) type_promote_call_list = f"return {forward_ad_function_name}({type_promote_inputs_call_args_str});" + x_cast = f"auto new_{x} = egr::PromoteCast(\"{x}\", {x}, promotion_type);" + + type_promotion_logic_str = TYPE_PROMOTION_LOGIC_TEMPLATE.format( + op_func_name=op_func_name, + x=x, + y=y, + x_cast=x_cast, + op_name=kernel_trans2_op_name_str, + return_value=type_promote_call_list, + ) + elif forward_api_name in type_promote_inplace_white_list: + # only support two inputs + op_func_name = f"\"{forward_api_name}\"" + x = type_promote_inplace_white_list[forward_api_name][0] + y = type_promote_inplace_white_list[forward_api_name][1] + type_promote_inputs_call_args_str = ", ".join( + type_promote_inputs_call_list + ) + type_promote_call_list = f"return {forward_ad_function_name}({type_promote_inputs_call_args_str});" + + x_cast = ( + f"{x} = egr::PromoteCastInplace(\"{x}\", {x}, promotion_type);" + ) + type_promotion_logic_str = TYPE_PROMOTION_LOGIC_TEMPLATE.format( + op_func_name=op_func_name, x=x, y=y, + x_cast=x_cast, op_name=kernel_trans2_op_name_str, return_value=type_promote_call_list, ) diff --git a/paddle/fluid/eager/type_promotion_utils.h b/paddle/fluid/eager/type_promotion_utils.h index 3ef732bac78bf..7ab9965cd15c4 100644 --- a/paddle/fluid/eager/type_promotion_utils.h +++ b/paddle/fluid/eager/type_promotion_utils.h @@ -30,4 +30,15 @@ inline paddle::Tensor PromoteCast(const std::string& input_name, } } +inline paddle::Tensor PromoteCastInplace(const std::string& input_name, + paddle::Tensor& input, // NOLINT + const phi::DataType& dst_dtype, + bool trace_backward = true) { + if (input.dtype() != dst_dtype) { + return paddle::experimental::cast_(input, dst_dtype); + } else { + return input; + } +} + } // namespace egr diff --git a/paddle/fluid/pybind/pybind.cc b/paddle/fluid/pybind/pybind.cc index 02d87fe02e00d..271aebaae7e49 100644 --- a/paddle/fluid/pybind/pybind.cc +++ b/paddle/fluid/pybind/pybind.cc @@ -924,9 +924,11 @@ PYBIND11_MODULE(libpaddle, m) { m.def("set_num_threads", &platform::SetNumThreads); m.def("need_type_promotion", - [](framework::proto::VarType::Type type_x, + [](const std::string &op_name, + framework::proto::VarType::Type type_x, framework::proto::VarType::Type type_y) { - return phi::NeedTypePromotion(framework::TransToPhiDataType(type_x), + return phi::NeedTypePromotion(op_name, + framework::TransToPhiDataType(type_x), framework::TransToPhiDataType(type_y)); }); m.def("get_promote_dtype", diff --git a/paddle/phi/common/type_promotion.h b/paddle/phi/common/type_promotion.h index 7bc50e90e7a4d..e8d8af1221c0b 100644 --- a/paddle/phi/common/type_promotion.h +++ b/paddle/phi/common/type_promotion.h @@ -133,10 +133,20 @@ inline phi::DataType GetPromoteDtype(const std::string& op_name, return phi::promoteTypes(x, y); } -inline bool NeedTypePromotion(const DataType x, const DataType y) { +inline bool NeedTypePromotion(const std::string& op_name, + const DataType x, + const DataType y) { // Tensor + Tensor type promotion only support calculations between // floating-point numbers and between complex and real numbers. if (x != y) { +// TODO(Xi Zhao): we got special case for add now, should remove it in furture. +#ifdef PADDLE_WITH_CUDA + if (op_name == "add" && x == DataType::FLOAT32 && + (y == phi::DataType::BFLOAT16 || y == phi::DataType::FLOAT16)) { + return false; + } +#endif + if ((is_support_float(x) && is_support_float(y)) || (is_support_complex(x) || is_support_complex(y))) { return true; diff --git a/python/paddle/base/framework.py b/python/paddle/base/framework.py index 823e4c760f3ea..aa4738d194ff9 100644 --- a/python/paddle/base/framework.py +++ b/python/paddle/base/framework.py @@ -8304,7 +8304,9 @@ def process_type_promotion(program): all_input_name_need_cast.append(input_arg_name) # only support promote between float - if len(all_dtypes) == 2 and core.need_type_promotion(*all_dtypes): + if len(all_dtypes) == 2 and core.need_type_promotion( + op.type, *all_dtypes + ): common_dtype = core.get_promote_dtype(op.type, *all_dtypes) for input_name_need_cast in all_input_name_need_cast: var_name = op.block._var_recursive(input_name_need_cast) diff --git a/python/paddle/base/layers/math_op_patch.py b/python/paddle/base/layers/math_op_patch.py index 40b5659b067d3..241f395e8a518 100644 --- a/python/paddle/base/layers/math_op_patch.py +++ b/python/paddle/base/layers/math_op_patch.py @@ -656,7 +656,9 @@ def __impl__(self, other_var): self = astype(self, rhs_dtype) else: other_var = astype(other_var, lhs_dtype) - elif core.need_type_promotion(lhs_dtype, rhs_dtype): + elif core.need_type_promotion( + op_type, lhs_dtype, rhs_dtype + ): # only report warning here, real promotion deal in Executor warnings.warn( f"The input dtypes of OP {op_type} are {lhs_dtype} and {rhs_dtype}, the output will be auto-promoted" diff --git a/test/legacy_test/test_tensor_type_promotion.py b/test/legacy_test/test_tensor_type_promotion.py index 155f78c78bdf8..8e4e425babb1e 100644 --- a/test/legacy_test/test_tensor_type_promotion.py +++ b/test/legacy_test/test_tensor_type_promotion.py @@ -229,6 +229,83 @@ def run_api(self): create_test_case(TestAPIAddInDygraph, 'complex128', 'float64', 'complex128') +class TestAPIAddInplaceInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.add_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.add_(self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIAddInplaceInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIAddInplaceInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIAddInplaceInDygraph, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestAPIAddInplaceInDygraph, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestAPIAddInplaceInDygraph, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestAPIAddInplaceInDygraph, 'bfloat16', 'float64', 'float64' + ) + create_test_case( + TestAPIAddInplaceInDygraph, 'bfloat16', 'complex64', 'complex64' + ) + create_test_case( + TestAPIAddInplaceInDygraph, 'bfloat16', 'complex128', 'complex128' + ) + +create_test_case(TestAPIAddInplaceInDygraph, 'complex64', 'bool', 'complex64') +create_test_case(TestAPIAddInplaceInDygraph, 'complex64', 'int8', 'complex64') +create_test_case(TestAPIAddInplaceInDygraph, 'complex64', 'uint8', 'complex64') +create_test_case(TestAPIAddInplaceInDygraph, 'complex64', 'int16', 'complex64') +create_test_case(TestAPIAddInplaceInDygraph, 'complex64', 'int32', 'complex64') +create_test_case(TestAPIAddInplaceInDygraph, 'complex64', 'int64', 'complex64') +create_test_case( + TestAPIAddInplaceInDygraph, 'complex64', 'float16', 'complex64' +) +create_test_case( + TestAPIAddInplaceInDygraph, 'complex64', 'float32', 'complex64' +) +create_test_case( + TestAPIAddInplaceInDygraph, 'complex64', 'float64', 'complex128' +) +create_test_case( + TestAPIAddInplaceInDygraph, 'complex64', 'complex128', 'complex128' +) + +create_test_case(TestAPIAddInplaceInDygraph, 'complex128', 'bool', 'complex128') +create_test_case(TestAPIAddInplaceInDygraph, 'complex128', 'int8', 'complex128') +create_test_case( + TestAPIAddInplaceInDygraph, 'complex128', 'uint8', 'complex128' +) +create_test_case( + TestAPIAddInplaceInDygraph, 'complex128', 'int16', 'complex128' +) +create_test_case( + TestAPIAddInplaceInDygraph, 'complex128', 'int32', 'complex128' +) +create_test_case( + TestAPIAddInplaceInDygraph, 'complex128', 'int64', 'complex128' +) +create_test_case( + TestAPIAddInplaceInDygraph, 'complex128', 'float16', 'complex128' +) +create_test_case( + TestAPIAddInplaceInDygraph, 'complex128', 'float32', 'complex128' +) +create_test_case( + TestAPIAddInplaceInDygraph, 'complex128', 'float64', 'complex128' +) + + class TestOperatorOverloadSubInDygraph(TestOperatorOverloadAddInDygraph): def run_api(self): self.generate_test_value() @@ -373,6 +450,83 @@ def run_api(self): create_test_case(TestAPISubInDygraph, 'complex128', 'float64', 'complex128') +class TestAPISubInplaceInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.subtract_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.subtract_(self.l_value) + + return out, out_reverse + + +create_test_case(TestAPISubInplaceInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPISubInplaceInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPISubInplaceInDygraph, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestAPISubInplaceInDygraph, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestAPISubInplaceInDygraph, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestAPISubInplaceInDygraph, 'bfloat16', 'float64', 'float64' + ) + create_test_case( + TestAPISubInplaceInDygraph, 'bfloat16', 'complex64', 'complex64' + ) + create_test_case( + TestAPISubInplaceInDygraph, 'bfloat16', 'complex128', 'complex128' + ) + +create_test_case(TestAPISubInplaceInDygraph, 'complex64', 'bool', 'complex64') +create_test_case(TestAPISubInplaceInDygraph, 'complex64', 'int8', 'complex64') +create_test_case(TestAPISubInplaceInDygraph, 'complex64', 'uint8', 'complex64') +create_test_case(TestAPISubInplaceInDygraph, 'complex64', 'int16', 'complex64') +create_test_case(TestAPISubInplaceInDygraph, 'complex64', 'int32', 'complex64') +create_test_case(TestAPISubInplaceInDygraph, 'complex64', 'int64', 'complex64') +create_test_case( + TestAPISubInplaceInDygraph, 'complex64', 'float16', 'complex64' +) +create_test_case( + TestAPISubInplaceInDygraph, 'complex64', 'float32', 'complex64' +) +create_test_case( + TestAPISubInplaceInDygraph, 'complex64', 'float64', 'complex128' +) +create_test_case( + TestAPISubInplaceInDygraph, 'complex64', 'complex128', 'complex128' +) + +create_test_case(TestAPISubInplaceInDygraph, 'complex128', 'bool', 'complex128') +create_test_case(TestAPISubInplaceInDygraph, 'complex128', 'int8', 'complex128') +create_test_case( + TestAPISubInplaceInDygraph, 'complex128', 'uint8', 'complex128' +) +create_test_case( + TestAPISubInplaceInDygraph, 'complex128', 'int16', 'complex128' +) +create_test_case( + TestAPISubInplaceInDygraph, 'complex128', 'int32', 'complex128' +) +create_test_case( + TestAPISubInplaceInDygraph, 'complex128', 'int64', 'complex128' +) +create_test_case( + TestAPISubInplaceInDygraph, 'complex128', 'float16', 'complex128' +) +create_test_case( + TestAPISubInplaceInDygraph, 'complex128', 'float32', 'complex128' +) +create_test_case( + TestAPISubInplaceInDygraph, 'complex128', 'float64', 'complex128' +) + + class TestOperatorOverloadMulInDygraph(TestOperatorOverloadAddInDygraph): def run_api(self): self.generate_test_value() @@ -517,6 +671,83 @@ def run_api(self): create_test_case(TestAPIMulInDygraph, 'complex128', 'float64', 'complex128') +class TestAPIMulInplaceInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.multiply_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.multiply_(self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIMulInplaceInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIMulInplaceInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIMulInplaceInDygraph, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestAPIMulInplaceInDygraph, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestAPIMulInplaceInDygraph, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestAPIMulInplaceInDygraph, 'bfloat16', 'float64', 'float64' + ) + create_test_case( + TestAPIMulInplaceInDygraph, 'bfloat16', 'complex64', 'complex64' + ) + create_test_case( + TestAPIMulInplaceInDygraph, 'bfloat16', 'complex128', 'complex128' + ) + +create_test_case(TestAPIMulInplaceInDygraph, 'complex64', 'bool', 'complex64') +create_test_case(TestAPIMulInplaceInDygraph, 'complex64', 'int8', 'complex64') +create_test_case(TestAPIMulInplaceInDygraph, 'complex64', 'uint8', 'complex64') +create_test_case(TestAPIMulInplaceInDygraph, 'complex64', 'int16', 'complex64') +create_test_case(TestAPIMulInplaceInDygraph, 'complex64', 'int32', 'complex64') +create_test_case(TestAPIMulInplaceInDygraph, 'complex64', 'int64', 'complex64') +create_test_case( + TestAPIMulInplaceInDygraph, 'complex64', 'float16', 'complex64' +) +create_test_case( + TestAPIMulInplaceInDygraph, 'complex64', 'float32', 'complex64' +) +create_test_case( + TestAPIMulInplaceInDygraph, 'complex64', 'float64', 'complex128' +) +create_test_case( + TestAPIMulInplaceInDygraph, 'complex64', 'complex128', 'complex128' +) + +create_test_case(TestAPIMulInplaceInDygraph, 'complex128', 'bool', 'complex128') +create_test_case(TestAPIMulInplaceInDygraph, 'complex128', 'int8', 'complex128') +create_test_case( + TestAPIMulInplaceInDygraph, 'complex128', 'uint8', 'complex128' +) +create_test_case( + TestAPIMulInplaceInDygraph, 'complex128', 'int16', 'complex128' +) +create_test_case( + TestAPIMulInplaceInDygraph, 'complex128', 'int32', 'complex128' +) +create_test_case( + TestAPIMulInplaceInDygraph, 'complex128', 'int64', 'complex128' +) +create_test_case( + TestAPIMulInplaceInDygraph, 'complex128', 'float16', 'complex128' +) +create_test_case( + TestAPIMulInplaceInDygraph, 'complex128', 'float32', 'complex128' +) +create_test_case( + TestAPIMulInplaceInDygraph, 'complex128', 'float64', 'complex128' +) + + class TestOperatorOverloadDivInDygraph(TestOperatorOverloadAddInDygraph): def run_api(self): self.generate_test_value() @@ -661,6 +892,83 @@ def run_api(self): create_test_case(TestAPIDivInDygraph, 'complex128', 'float64', 'complex128') +class TestAPIDivInplaceInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.divide_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.divide_(self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIDivInplaceInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIDivInplaceInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIDivInplaceInDygraph, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case( + TestAPIDivInplaceInDygraph, 'bfloat16', 'float16', 'float32' + ) + create_test_case( + TestAPIDivInplaceInDygraph, 'bfloat16', 'float32', 'float32' + ) + create_test_case( + TestAPIDivInplaceInDygraph, 'bfloat16', 'float64', 'float64' + ) + create_test_case( + TestAPIDivInplaceInDygraph, 'bfloat16', 'complex64', 'complex64' + ) + create_test_case( + TestAPIDivInplaceInDygraph, 'bfloat16', 'complex128', 'complex128' + ) + +create_test_case(TestAPIDivInplaceInDygraph, 'complex64', 'bool', 'complex64') +create_test_case(TestAPIDivInplaceInDygraph, 'complex64', 'int8', 'complex64') +create_test_case(TestAPIDivInplaceInDygraph, 'complex64', 'uint8', 'complex64') +create_test_case(TestAPIDivInplaceInDygraph, 'complex64', 'int16', 'complex64') +create_test_case(TestAPIDivInplaceInDygraph, 'complex64', 'int32', 'complex64') +create_test_case(TestAPIDivInplaceInDygraph, 'complex64', 'int64', 'complex64') +create_test_case( + TestAPIDivInplaceInDygraph, 'complex64', 'float16', 'complex64' +) +create_test_case( + TestAPIDivInplaceInDygraph, 'complex64', 'float32', 'complex64' +) +create_test_case( + TestAPIDivInplaceInDygraph, 'complex64', 'float64', 'complex128' +) +create_test_case( + TestAPIDivInplaceInDygraph, 'complex64', 'complex128', 'complex128' +) + +create_test_case(TestAPIDivInplaceInDygraph, 'complex128', 'bool', 'complex128') +create_test_case(TestAPIDivInplaceInDygraph, 'complex128', 'int8', 'complex128') +create_test_case( + TestAPIDivInplaceInDygraph, 'complex128', 'uint8', 'complex128' +) +create_test_case( + TestAPIDivInplaceInDygraph, 'complex128', 'int16', 'complex128' +) +create_test_case( + TestAPIDivInplaceInDygraph, 'complex128', 'int32', 'complex128' +) +create_test_case( + TestAPIDivInplaceInDygraph, 'complex128', 'int64', 'complex128' +) +create_test_case( + TestAPIDivInplaceInDygraph, 'complex128', 'float16', 'complex128' +) +create_test_case( + TestAPIDivInplaceInDygraph, 'complex128', 'float32', 'complex128' +) +create_test_case( + TestAPIDivInplaceInDygraph, 'complex128', 'float64', 'complex128' +) + + class TestOperatorOverloadPowInDygraph(TestOperatorOverloadAddInDygraph): def run_api(self): self.generate_test_value() @@ -742,26 +1050,48 @@ def run_api(self): return out, out_reverse +create_test_case(TestAPIFloorDivInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIFloorDivInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIFloorDivInDygraph, 'float32', 'float64', 'float64') + +if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): + create_test_case(TestAPIFloorDivInDygraph, 'bfloat16', 'float16', 'float32') + create_test_case(TestAPIFloorDivInDygraph, 'bfloat16', 'float32', 'float32') + create_test_case(TestAPIFloorDivInDygraph, 'bfloat16', 'float64', 'float64') + + +class TestAPIFloorDivInplaceInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.floor_divide_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.floor_divide_(self.l_value) + + return out, out_reverse + + create_test_case( - TestOperatorOverloadFloorDivInDygraph, 'float16', 'float32', 'float32' + TestAPIFloorDivInplaceInDygraph, 'float16', 'float32', 'float32' ) create_test_case( - TestOperatorOverloadFloorDivInDygraph, 'float16', 'float64', 'float64' + TestAPIFloorDivInplaceInDygraph, 'float16', 'float64', 'float64' ) create_test_case( - TestOperatorOverloadFloorDivInDygraph, 'float32', 'float64', 'float64' + TestAPIFloorDivInplaceInDygraph, 'float32', 'float64', 'float64' ) if paddle.is_compiled_with_cuda() and paddle.base.core.supports_bfloat16(): create_test_case( - TestOperatorOverloadFloorDivInDygraph, 'bfloat16', 'float16', 'float32' + TestAPIFloorDivInplaceInDygraph, 'bfloat16', 'float16', 'float32' ) create_test_case( - TestOperatorOverloadFloorDivInDygraph, 'bfloat16', 'float32', 'float32' + TestAPIFloorDivInplaceInDygraph, 'bfloat16', 'float32', 'float32' ) create_test_case( - TestOperatorOverloadFloorDivInDygraph, 'bfloat16', 'float64', 'float64' + TestAPIFloorDivInplaceInDygraph, 'bfloat16', 'float64', 'float64' ) @@ -803,6 +1133,23 @@ def run_api(self): create_test_case(TestAPIModInDygraph, 'float32', 'float64', 'float64') +class TestAPIModInplaceInDygraph(TestOperatorOverloadAddInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.mod_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.mod_(self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIModInplaceInDygraph, 'float16', 'float32', 'float32') +create_test_case(TestAPIModInplaceInDygraph, 'float16', 'float64', 'float64') + +create_test_case(TestAPIModInplaceInDygraph, 'float32', 'float64', 'float64') + + class TestOperatorOverloadEqualInDygraph(unittest.TestCase): def setUp(self): paddle.disable_static() @@ -863,6 +1210,23 @@ def run_api(self): create_test_case(TestAPIEqualInDygraph, 'float32', 'float64', 'bool') +class TestAPIEqualInplaceInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.equal_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.equal_(self.l_value) + + return out, out_reverse + + +create_test_case(TestAPIEqualInplaceInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPIEqualInplaceInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPIEqualInplaceInDygraph, 'float32', 'float64', 'bool') + + class TestOperatorOverloadNotEqualInDygraph(TestOperatorOverloadEqualInDygraph): def run_api(self): self.generate_test_value() @@ -901,6 +1265,23 @@ def run_api(self): create_test_case(TestAPINotEqualInDygraph, 'float32', 'float64', 'bool') +class TestAPINotEqualInplaceInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.not_equal_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.not_equal_(self.l_value) + + return out, out_reverse + + +create_test_case(TestAPINotEqualInplaceInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPINotEqualInplaceInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPINotEqualInplaceInDygraph, 'float32', 'float64', 'bool') + + class TestOperatorOverloadLessThanInDygraph(TestOperatorOverloadEqualInDygraph): def run_api(self): self.generate_test_value() @@ -939,6 +1320,23 @@ def run_api(self): create_test_case(TestAPILessThanInDygraph, 'float32', 'float64', 'bool') +class TestAPILessThanInplaceInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.less_than_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.less_than_(self.l_value) + + return out, out_reverse + + +create_test_case(TestAPILessThanInplaceInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPILessThanInplaceInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPILessThanInplaceInDygraph, 'float32', 'float64', 'bool') + + class TestOperatorOverloadLessEqualInDygraph( TestOperatorOverloadEqualInDygraph ): @@ -979,6 +1377,23 @@ def run_api(self): create_test_case(TestAPILessEqualInDygraph, 'float32', 'float64', 'bool') +class TestAPILessEqualInplaceInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.less_equal_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.less_equal_(self.l_value) + + return out, out_reverse + + +create_test_case(TestAPILessEqualInplaceInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPILessEqualInplaceInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPILessEqualInplaceInDygraph, 'float32', 'float64', 'bool') + + class TestOperatorOverloadGreaterThanInDygraph( TestOperatorOverloadEqualInDygraph ): @@ -1019,6 +1434,29 @@ def run_api(self): create_test_case(TestAPIGreaterThanInDygraph, 'float32', 'float64', 'bool') +class TestAPIGreaterThanInplaceInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.greater_than_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.greater_than_(self.l_value) + + return out, out_reverse + + +create_test_case( + TestAPIGreaterThanInplaceInDygraph, 'float16', 'float32', 'bool' +) +create_test_case( + TestAPIGreaterThanInplaceInDygraph, 'float16', 'float64', 'bool' +) + +create_test_case( + TestAPIGreaterThanInplaceInDygraph, 'float32', 'float64', 'bool' +) + + class TestOperatorOverloadGreaterEqualInDygraph( TestOperatorOverloadEqualInDygraph ): @@ -1059,6 +1497,29 @@ def run_api(self): create_test_case(TestAPIGreaterEqualInDygraph, 'float32', 'float64', 'bool') +class TestAPIGreaterEqualInplaceInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.greater_equal_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.greater_equal_(self.l_value) + + return out, out_reverse + + +create_test_case( + TestAPIGreaterEqualInplaceInDygraph, 'float16', 'float32', 'bool' +) +create_test_case( + TestAPIGreaterEqualInplaceInDygraph, 'float16', 'float64', 'bool' +) + +create_test_case( + TestAPIGreaterEqualInplaceInDygraph, 'float32', 'float64', 'bool' +) + + class TestAPILogicalAndInDygraph(TestOperatorOverloadEqualInDygraph): def run_api(self): self.generate_test_value() @@ -1094,6 +1555,78 @@ def run_api(self): create_test_case(TestAPILogicalAndInDygraph, 'complex128', 'float64', 'bool') +class TestAPILogicalAndInplaceInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.logical_and_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.logical_and_(self.l_value) + + return out, out_reverse + + +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'float16', 'float32', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'float16', 'float64', 'bool' +) + +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'float32', 'float64', 'bool' +) + +create_test_case(TestAPILogicalAndInplaceInDygraph, 'complex64', 'bool', 'bool') +create_test_case(TestAPILogicalAndInplaceInDygraph, 'complex64', 'int8', 'bool') +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex64', 'int16', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex64', 'int32', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex64', 'int64', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex64', 'float16', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex64', 'float32', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex64', 'float64', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex64', 'complex128', 'bool' +) + +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex128', 'bool', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex128', 'int8', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex128', 'int16', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex128', 'int32', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex128', 'int64', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex128', 'float16', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex128', 'float32', 'bool' +) +create_test_case( + TestAPILogicalAndInplaceInDygraph, 'complex128', 'float64', 'bool' +) + + class TestAPILogicalOrInDygraph(TestOperatorOverloadEqualInDygraph): def run_api(self): self.generate_test_value() @@ -1129,6 +1662,62 @@ def run_api(self): create_test_case(TestAPILogicalOrInDygraph, 'complex128', 'float64', 'bool') +class TestAPILogicalOrInplaceInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.logical_or_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.logical_or_(self.l_value) + + return out, out_reverse + + +create_test_case(TestAPILogicalOrInplaceInDygraph, 'float16', 'float32', 'bool') +create_test_case(TestAPILogicalOrInplaceInDygraph, 'float16', 'float64', 'bool') + +create_test_case(TestAPILogicalOrInplaceInDygraph, 'float32', 'float64', 'bool') + +create_test_case(TestAPILogicalOrInplaceInDygraph, 'complex64', 'bool', 'bool') +create_test_case(TestAPILogicalOrInplaceInDygraph, 'complex64', 'int8', 'bool') +create_test_case(TestAPILogicalOrInplaceInDygraph, 'complex64', 'int16', 'bool') +create_test_case(TestAPILogicalOrInplaceInDygraph, 'complex64', 'int32', 'bool') +create_test_case(TestAPILogicalOrInplaceInDygraph, 'complex64', 'int64', 'bool') +create_test_case( + TestAPILogicalOrInplaceInDygraph, 'complex64', 'float16', 'bool' +) +create_test_case( + TestAPILogicalOrInplaceInDygraph, 'complex64', 'float32', 'bool' +) +create_test_case( + TestAPILogicalOrInplaceInDygraph, 'complex64', 'float64', 'bool' +) +create_test_case( + TestAPILogicalOrInplaceInDygraph, 'complex64', 'complex128', 'bool' +) + +create_test_case(TestAPILogicalOrInplaceInDygraph, 'complex128', 'bool', 'bool') +create_test_case(TestAPILogicalOrInplaceInDygraph, 'complex128', 'int8', 'bool') +create_test_case( + TestAPILogicalOrInplaceInDygraph, 'complex128', 'int16', 'bool' +) +create_test_case( + TestAPILogicalOrInplaceInDygraph, 'complex128', 'int32', 'bool' +) +create_test_case( + TestAPILogicalOrInplaceInDygraph, 'complex128', 'int64', 'bool' +) +create_test_case( + TestAPILogicalOrInplaceInDygraph, 'complex128', 'float16', 'bool' +) +create_test_case( + TestAPILogicalOrInplaceInDygraph, 'complex128', 'float32', 'bool' +) +create_test_case( + TestAPILogicalOrInplaceInDygraph, 'complex128', 'float64', 'bool' +) + + class TestAPILogicalXorInDygraph(TestOperatorOverloadEqualInDygraph): def run_api(self): self.generate_test_value() @@ -1164,6 +1753,78 @@ def run_api(self): create_test_case(TestAPILogicalXorInDygraph, 'complex128', 'float64', 'bool') +class TestAPILogicalXorInplaceInDygraph(TestOperatorOverloadEqualInDygraph): + def run_api(self): + self.generate_test_value() + out = self.l_value.logical_xor_(self.r_value) + + self.generate_test_value() + out_reverse = self.r_value.logical_xor_(self.l_value) + + return out, out_reverse + + +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'float16', 'float32', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'float16', 'float64', 'bool' +) + +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'float32', 'float64', 'bool' +) + +create_test_case(TestAPILogicalXorInplaceInDygraph, 'complex64', 'bool', 'bool') +create_test_case(TestAPILogicalXorInplaceInDygraph, 'complex64', 'int8', 'bool') +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex64', 'int16', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex64', 'int32', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex64', 'int64', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex64', 'float16', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex64', 'float32', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex64', 'float64', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex64', 'complex128', 'bool' +) + +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex128', 'bool', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex128', 'int8', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex128', 'int16', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex128', 'int32', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex128', 'int64', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex128', 'float16', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex128', 'float32', 'bool' +) +create_test_case( + TestAPILogicalXorInplaceInDygraph, 'complex128', 'float64', 'bool' +) + + class TestAPIFmaxInDygraph(TestOperatorOverloadAddInDygraph): def run_api(self): self.generate_test_value() From 46238aa7f8db26b70b971c0d3e10ccee8cc768ab Mon Sep 17 00:00:00 2001 From: zxcd <228587199@qq.com> Date: Tue, 30 Apr 2024 09:31:58 +0000 Subject: [PATCH 34/34] add broatcast support for MultiPrecisionAddKernelImpl. --- paddle/phi/kernels/kps/elementwise_kernel.cu | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/paddle/phi/kernels/kps/elementwise_kernel.cu b/paddle/phi/kernels/kps/elementwise_kernel.cu index a6caa95b766e1..ca0ad275bcd1c 100644 --- a/paddle/phi/kernels/kps/elementwise_kernel.cu +++ b/paddle/phi/kernels/kps/elementwise_kernel.cu @@ -59,17 +59,19 @@ void MultiPrecisionAddKernelImpl(const Context& dev_ctx, std::vector inputs = {&x, &y}; std::vector outputs = {out}; if (y.dtype() == phi::DataType::BFLOAT16) { - funcs::ElementwiseKernel( + funcs::BroadcastKernel( dev_ctx, inputs, &outputs, - funcs::MultiPrecisionAddFunctor()); + funcs::MultiPrecisionAddFunctor(), + -1); } else if (y.dtype() == phi::DataType::FLOAT16) { - funcs::ElementwiseKernel( + funcs::BroadcastKernel( dev_ctx, inputs, &outputs, - funcs::MultiPrecisionAddFunctor()); + funcs::MultiPrecisionAddFunctor(), + -1); } else { PADDLE_THROW(phi::errors::InvalidArgument( "Unsupport x dtype:%s, y dtype:%s for add(x, y) operation",