Skip to content

Conversation

@cangtianhuang
Copy link
Contributor

@cangtianhuang cangtianhuang commented Mar 19, 2025

PR Category

Operator Mechanism

PR Types

Bug fixes

Description

该 pr 修复了 paddle.broadcast_tensors,为其增加了对 0-size tenosr、单个tensor、tensors 间不同 dtype 的支持。在此之前,使用 array_api_tests/test_data_type_functions.py::test_broadcast_arrays 将会引发形状不匹配、输入张量数量不足、数据类型不一致等问题。

具体修改如下:

  • 删除了 kernels/cpu/broadcast_tensors_kernel.cckernels/gpu/broadcast_tensors_kernel.cc ,增加了与硬件和数据无关的内核注册 kernels/broadcast_tensors_kernel.cc

  • 因为 broadcast_tensors 允许多数据类型广播至同一形状(参考pytorch、numpy),BroadcastTensorsKernel 应该是数据类型无关的,因此删除其模板 typename T,并增加数据分发函数 DispatchBroadcast ,以复用 ApplyBroadcast 函数

  • PADDLE_ENFORCE_GT 改为 PADDLE_ENFORCE_GE 以支持单个 Tensor

  • 删除 ops.yaml 关于 broadcast_tensorsdata_type ,增加了 data_transform skip_transform ,使其与数据类型无关,避免类型提升。

修改编译后,测试结果如下:

image

@paddle-bot
Copy link

paddle-bot bot commented Mar 19, 2025

你的PR提交成功,感谢你对开源项目的贡献!
请关注后续CI自动化测试结果,详情请参考Paddle-CI手册
Your PR has been submitted. Thanks for your contribution!
Please wait for the result of CI firstly. See Paddle CI Manual for details.

@paddle-bot paddle-bot bot added the contributor External developers label Mar 19, 2025
@luotao1 luotao1 added the HappyOpenSource 快乐开源活动issue与PR label Mar 20, 2025
Copy link
Contributor

@HydrogenSulfate HydrogenSulfate left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

添加单个输入和0-size情况下的单测

@HydrogenSulfate
Copy link
Contributor

@cangtianhuang 你的PR可能还加一些单测, 以及删除掉一些原有的单测,比如原来kernel没有支持int8类型,所以预期报错,但是你的PR里全部类型都支持了,所以你需要删除掉这类断言单测。

def test_dtype():
inputs = [
paddle.to_tensor(
np.ones(shape=[1, 1, 1, 1], dtype='int8', name="x6")
),
paddle.to_tensor(
np.ones(shape=[1, 4, 1, 1], dtype='int8', name="x7")
),
]
paddle.broadcast_tensors(inputs)
def test_bcast_semantics():
inputs = [
paddle.to_tensor(
np.ones(shape=[1, 3, 1, 1], dtype='float32', name="x9")
),
paddle.to_tensor(
np.ones(shape=[1, 8, 1, 1], dtype='float32', name="x10")
),
]
paddle.broadcast_tensors(inputs)
paddle.disable_static()
self.assertRaises(TypeError, test_type)
self.assertRaises(TypeError, test_dtype)

@cangtianhuang
Copy link
Contributor Author

@cangtianhuang 你的PR可能还加一些单测, 以及删除掉一些原有的单测,比如原来kernel没有支持int8类型,所以预期报错,但是你的PR里全部类型都支持了,所以你需要删除掉这类断言单测。

原来如此,非常感谢!😘我将修改它。

@cangtianhuang cangtianhuang reopened this Mar 31, 2025
@cangtianhuang
Copy link
Contributor Author

@HydrogenSulfate Check approval (pull_request) 不通过😭

@HydrogenSulfate
Copy link
Contributor

@HydrogenSulfate Check approval (pull_request) 不通过😭

Approval 系类的首次不通过是正常的,因为是需要团队研发手动approve然后rerun才能通过的,建议关注下其它单测相关的检查

@cangtianhuang
Copy link
Contributor Author

cangtianhuang commented Apr 1, 2025

@HydrogenSulfate 您好!我发现 broadcast_tensors 是唯一需要允许不同 dtype 输入的 kernel (之前并不支持),这在 PrepareData 阶段产生了问题。目前的代码逻辑会自动提升数据类型,且无法通过设置 ops.yaml 中的 data_transform 标记解决,如下:

测试用例:

import paddle tensor1 = paddle.to_tensor([], dtype=paddle.complex64).reshape([0]) tensor2 = paddle.to_tensor(0.0, dtype=paddle.float32) tensor3 = paddle.to_tensor([], dtype=paddle.bool).reshape([0, 0]) paddle.broadcast_tensors([tensor1, tensor2, tensor3])

kernel_data_type 解析为最大的 complex64float32 将在 PrepareData 处被自动提升,判断逻辑为:

// paddle\phi\api\lib\data_transform.cc inline bool NeedTransformDataType(const DataType& input, const DataType& target, const TransformFlag& transform_flag) { return input != target && (transform_flag.need_trans_data_type() || ((target == DataType::COMPLEX64 || target == DataType::COMPLEX128) && (input != DataType::INT32 && input != DataType::INT64 && input != DataType::BOOL))); }

目前没有什么好的解决办法。能否为 TransformFlag 增加 disable_trans_dtype 标记,但是这需要修改 ops.yaml 的解析逻辑,可能更麻烦……

@HydrogenSulfate
Copy link
Contributor

@HydrogenSulfate 您好!我发现 broadcast_tensors 是唯一需要允许不同 dtype 输入的 kernel (之前并不支持),这在 PrepareData 阶段产生了问题。目前的代码逻辑会自动提升数据类型,且无法通过设置 ops.yaml 中的 data_transform 标记解决,如下:

测试用例:

import paddle tensor1 = paddle.to_tensor([], dtype=paddle.complex64).reshape([0]) tensor2 = paddle.to_tensor(0.0, dtype=paddle.float32) tensor3 = paddle.to_tensor([], dtype=paddle.bool).reshape([0, 0]) paddle.broadcast_tensors([tensor1, tensor2, tensor3])

kernel_data_type 解析为最大的 complex64float32 将在 PrepareData 处被自动提升,判断逻辑为:

// paddle\phi\api\lib\data_transform.cc inline bool NeedTransformDataType(const DataType& input, const DataType& target, const TransformFlag& transform_flag) { return input != target && (transform_flag.need_trans_data_type() || ((target == DataType::COMPLEX64 || target == DataType::COMPLEX128) && (input != DataType::INT32 && input != DataType::INT64 && input != DataType::BOOL))); }

目前没有什么好的解决办法。能否为 TransformFlag 增加 disable_trans_dtype 标记,但是这需要修改 ops.yaml 的解析逻辑,可能更麻烦……

这个是否暂时先认为不允许多种dtype作为输入?多种dtype的问题可能会在Q2进行讨论解决。

@cangtianhuang
Copy link
Contributor Author

这个是否暂时先认为不允许多种dtype作为输入?多种dtype的问题可能会在Q2进行讨论解决。

噢噢……是的,如果要改的话,改动的幅度会很大。在 #69908 中我认领的

python -m pytest -s -vvv array_api_tests/test_data_type_functions.py::test_broadcast_arrays 

的测试用例是多 dtype 的😖

我可以先关闭这个PR,并在另一个 PR 中提交仅对 0-size tensor 和 单输入 的支持。

@HydrogenSulfate
Copy link
Contributor

这个是否暂时先认为不允许多种dtype作为输入?多种dtype的问题可能会在Q2进行讨论解决。

噢噢……是的,如果要改的话,改动的幅度会很大。在 #69908 中我认领的

python -m pytest -s -vvv array_api_tests/test_data_type_functions.py::test_broadcast_arrays 

的测试用例是多 dtype 的😖

我可以先关闭这个PR,并在另一个 PR 中提交仅对 0-size tensor 和 单输入 的支持。

这个可以在https://github.com/HydrogenSulfate/array-api-compat/blob/support_paddle/array_api_compat/paddle/_aliases.py这里单独写一个同名函数,在函数内处理下多dtype的情况,然后paddle框架目前就暂时只支持单个dtype好了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor External developers HappyOpenSource 快乐开源活动issue与PR

3 participants