Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【PaddlePaddle Hackathon 2】15 新增 API Nanmedian #42385

Merged
merged 31 commits into from May 30, 2022

Conversation

thunder95
Copy link
Contributor

@thunder95 thunder95 commented Apr 28, 2022

PR types

New features

PR changes

APIs

Describe

完成第二期第15项目开发任务: #40318
paddle.nanmedian 扩展了 paddle.median API 的功能,如果输入Tensor中有nan值, paddle.median 会将nan值考虑在内然后取中位数(有可能为nan值),而 paddle.nanmedian 只考虑非nan值的中位数。

RFC设计文档: PaddlePaddle/community#89
中文文档: PaddlePaddle/docs#4820

@paddle-bot-old
Copy link

你的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-old paddle-bot-old bot added contributor External developers status: proposed labels Apr 28, 2022
@thunder95 thunder95 changed the title Nanmedian 【PaddlePaddle Hackathon 2】15 新增 API Nanmedian Apr 28, 2022
@TCChenlong
Copy link
Contributor

根据提示,应该是API的示例代码错误,可以检查一下
image

@thunder95
Copy link
Contributor Author

根据提示,应该是API的示例代码错误,可以检查一下 image

@TCChenlong 多谢龙哥,已经修改好, 现在只剩approved error了

@paddle-bot-old
Copy link

paddle-bot-old bot commented May 5, 2022

PR格式检查通过,你的PR将接受Paddle专家以及开源社区的review,请及时关注PR动态。
The format inspection passed. Your PR will be reviewed by experts of Paddle and developers from the open-source community. Stay tuned.

@@ -253,6 +253,140 @@ def numel(x, name=None):
return out


def nanmedian(x, axis=None, ignore_nan=True, keepdim=True, name=None):
Copy link
Contributor

@jeff41404 jeff41404 May 5, 2022

Choose a reason for hiding this comment

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

there is no parameter of ignore_nan in nanmedian RFC. if we want to add this parameter, should change RFC first.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This RFC doc was updated with a new PR: PaddlePaddle/community#124

Copy link
Contributor

@jeff41404 jeff41404 May 5, 2022

Choose a reason for hiding this comment

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

I discussed this case with some paddle experts today.
In Paddle v2 3(coming this month) C++ API will be officially introduced, a program (such as model Networking) can be composed by basic C++ APIs instead of Python APIs, which is very useful for some performance pursuit scenarios.
In order to reduce the threshold for users to use C++ API, it is necessary to ensure that the experience of using C++ API is the same with Python, that is, the parameters of the two should be the same (the different ones are being modified in plan), and the documents of Python API can be reused without writing another document about C++ API.
Therefore, in this case, the RFC doc does not need to be modified, and the parameter ignore_nan should be moved to a kernel function (e.g. BaseMedianLernel), and then both nanmediankernel and mediankernel call this function using different value of ignore_nan. So the parameters of Python API, C++ API and kernel are the same, and the paddle Median and padding Nanmedian is used in the same way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Your proposal is quite reasonable. I will move the logic into c++ implementation. I will adopt this structure, BaseMedianKernel(with parameters axis, keepdim), and then calculate the presence of nan values, and futher determine which kernel to pick (nanmediankernel and mediankernel). This param ignore_nan wont be used any more. If I understood incorrectly, pls let me know, thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

If ``axis`` is less than 0, it works the same way as :math:`axis + D`.
If ``axis`` is None, median is calculated over all elements of ``x``. Default is None.
ignore_nan (bool, optional): Whether to ignore nan values when median was calculated.
If `ignore_nan` is True, the calculation process is the same as `median` operator.
Copy link
Contributor

Choose a reason for hiding this comment

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

If ignore_nan is False, the calculation process is the same as median operator?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

modified.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

please add link of RFC(API design documents) in description

already added.

res_shape = [x for x in out_shape if x > 0]

if _in_legacy_dygraph():
medians, out = _C_ops.nanmedian(x, 'ignore_nan', ignore_nan)
Copy link
Contributor

Choose a reason for hiding this comment

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

According to the comments above, the parameters of Python API and C++ API should be the same, and the preprocessing logic in Python above should also be put into C++.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A question: can c++ api support the python data type like tuple and None?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done


int64_t pos = (stride - num_nan - 1) / 2;
std::nth_element(col_vec.begin(),
col_vec.begin() + pos,
Copy link
Contributor

Choose a reason for hiding this comment

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

use col_vec.begin() + pos + 1 is better? no need to use std::nth_element again in if statement below?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Learned from https://en.cppreference.com/w/cpp/algorithm/nth_element, the order of elements before the nth element seems to be somehow unreliable, so I fetched the n-1th element again. If the index of elements are needed, this std:nth_element would not be the good choice.

jeff41404
jeff41404 previously approved these changes May 16, 2022
Copy link
Contributor

@jeff41404 jeff41404 left a comment

Choose a reason for hiding this comment

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

LGTM

@TCChenlong
Copy link
Contributor

请补充中文文档,并将链接附在 Describe 中

@thunder95
Copy link
Contributor Author

请补充中文文档,并将链接附在 Describe 中

@TCChenlong 完成

@@ -241,6 +241,103 @@ def numel(x, name=None):
return out


def nanmedian(x, axis=None, keepdim=True, name=None):
"""
Compute the median along the specified axis, while ignoring NaNs.
Copy link
Contributor

Choose a reason for hiding this comment

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

在文档前加r ,现在无法正常解析英文文档

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Ligoml 已加

@@ -331,6 +331,7 @@
from .tensor.stat import var # noqa: F401
from .tensor.stat import numel # noqa: F401
from .tensor.stat import median # noqa: F401
from .tensor.stat import nanmedian # noqa: F401
Copy link
Contributor

@Ligoml Ligoml May 26, 2022

Choose a reason for hiding this comment

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

这个api需要加在 __all__ 中,否则不会被正常展示在api列表中

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Ligoml 已修改

Copy link
Contributor

@Ligoml Ligoml left a comment

Choose a reason for hiding this comment

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

LGTM for docs

@@ -0,0 +1,121 @@
/*Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
Copy link
Contributor

Choose a reason for hiding this comment

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

license换行缩进有点问题,建议参考别的改一下

Copy link
Contributor Author

Choose a reason for hiding this comment

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

老师 您好,已修改

out->set_dims(make_ddim(out_dim));
}

void NanmedianGradInferMeta(const MetaTensor& x,
Copy link
Contributor

Choose a reason for hiding this comment

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

反向的麻烦放到backward.h/cc中

Copy link
Contributor Author

Choose a reason for hiding this comment

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

老师 您好,已修改

bool should_ignore_nan = ignore_nan;
auto stream = dev_ctx.stream();
auto* ctx =
reinterpret_cast<const paddle::platform::CUDADeviceContext*>(&dev_ctx);
Copy link
Contributor

Choose a reason for hiding this comment

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

这里好像不需要转换?直接使用dev_ctx

Copy link
Contributor Author

Choose a reason for hiding this comment

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

老师 您好,已修改

for (int i = 0; i < ndims; i++) {
trans_dim[i] = input_dim[perm[i]];
}
x->mutable_data<T>(trans_dim, dev_ctx.GetPlace());
Copy link
Contributor

Choose a reason for hiding this comment

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

麻烦换成dev_ctx.template Alloc()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

老师 您好,已修改 @chenwhql

Copy link
Contributor

@chenwhql chenwhql left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@zhwesky2010 zhwesky2010 left a comment

Choose a reason for hiding this comment

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

LGTM for change parallel_UT_rule

Copy link
Contributor

@XiaoguangHu01 XiaoguangHu01 left a comment

Choose a reason for hiding this comment

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

LGTM

@jeff41404 jeff41404 merged commit f87fa3c into PaddlePaddle:develop May 30, 2022
fuyou765 pushed a commit to fuyou765/Paddle that referenced this pull request Jun 7, 2022
* nanmedian op

* 修改cuda kernel的bug

* 修复count_if在其他硬件平台不兼容

* 修复某些cpu硬件不兼容

* 修复某些cpu硬件不兼容

* 修复isnan判断

* 兼容numpy低版本不支持全部nan的情况

* 兼容numpy低版本不支持全部nan的情况

* fix code example

* fix api comment error

* 修改反向传播逻辑以及c++处理逻辑

* 完成修改建议

* typo pre_dim

* update en docs, test=document_fix

* remove numpy in en doc, test=document_fix

* add r,test=document_fix

* 添加api到all

* follow advice from chenwhql
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contributor External developers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants