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

add new api fill_diagonal_tensor_ #34515

Merged
merged 1 commit into from
Sep 10, 2021
Merged

add new api fill_diagonal_tensor_ #34515

merged 1 commit into from
Sep 10, 2021

Conversation

zhiboniu
Copy link
Contributor

@zhiboniu zhiboniu commented Jul 30, 2021

PR types

New features

PR changes

APIs

Describe

add new op/api fill_diagonal_tensor_

Examples:
    .. code-block:: python
        import paddle
        x = paddle.ones((4, 3)) * 2
        y = paddle.ones((3,))
        x.fill_diagonal_tensor_(y)
        print(x.tolist())   #[[1.0, 2.0, 2.0], [2.0, 1.0, 2.0], [2.0, 2.0, 1.0], [2.0, 2.0, 2.0]]

@paddle-bot-old
Copy link

Thanks for your contribution!
Please wait for the result of CI firstly. See Paddle CI Manual for details.

assert len(inshape) >= 2, ('Tensor dims should >= 2 in fill_diagmat_')
dim1 %= len(inshape)
dim2 %= len(inshape)
assert dim1 < dim2, ("dim1 should > dim2 in fill_diagmat_")
Copy link
Contributor

Choose a reason for hiding this comment

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

看这里的逻辑,报错中的 > 应该为 <

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,笔误,已修改

framework::TensorCopy(*xin, ctx.GetPlace(), out);

T *out_data = out->mutable_data<T>(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.

常规做法是先 out->mutable_data 分配内存后再使用 TensorCopy,这里反过来是否有特殊考虑

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, TensorCopy中也有out->mutable_data,所以其实都可以。不过也已经修改。

Comment on lines 77 to 73
framework::TensorCopy(*xin, ctx.GetPlace(), out);

T *out_data = out->mutable_data<T>(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.

常规做法是先 out->mutable_data 分配内存后再使用 TensorCopy,这里反过来是否有特殊考虑

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,同上

Copy link
Collaborator

@sneaxiy sneaxiy left a comment

Choose a reason for hiding this comment

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

Suggestion: you can use platform::ForRange to unify the CPU and GPU codes.

"Tensor, the output tensor, with the same shape and data type "
"as input(x)");
AddAttr<int>("dim1", "the first dim to figure out the diagonal")
.SetDefault(-2);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Default 0?

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

AddAttr<int>("dim1", "the first dim to figure out the diagonal")
.SetDefault(-2);
AddAttr<int>("dim2", "the second dim to figure out the diagonal")
.SetDefault(-1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Default 1?

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

"offset to up-right corner; negtive means offset to "
"bottom-left corner")
.SetDefault(0);
AddAttr<int>("matrows",
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems that this attribute is not necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

used for backward memory allocate

Copy link
Collaborator

@sneaxiy sneaxiy Aug 11, 2021

Choose a reason for hiding this comment

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

I know the purpose that you add this attribute. I mean, this attribute is not necessary, because it can be calculated by other informations (i.e., the dimensions of the input tensors and the values of other attributes). It is not orthogonal with other informations.

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

}
};

class FillDiagonalTensorOpVarTypeInference
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems that this class is not necessary because X and Out must be both Tensor. Please remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

算子开发注意事项中要求的注册这个函数:
框架没有提供默认的op_infer_var_type方法,用户需要根据实际情况添加op_infer_var_type。严格来说每个Op都应该注册一个InferVarType,op_infer_var_type根据输入的Var的type和dtype推断输出Var的type和dtype。

auto *xin = ctx.Input<framework::Tensor>("X");

T *out_data = out->mutable_data<T>(ctx.GetPlace());
T *fill_data = const_cast<T *>(srctensor->data<T>());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why const_cast? I do not think that you should change fill_data.

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

#ifdef __HIPCC__
hipMalloc(reinterpret_cast<void **>(&memory_block_cu),
sizeof(int) * (2 + fill_dims[0]));
hipMemcpy(memory_block_cu, memory_block, sizeof(int) * (2 + fill_dims[0]),
Copy link
Collaborator

@sneaxiy sneaxiy Aug 6, 2021

Choose a reason for hiding this comment

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

Use memory::Copy instead of hipMemcpy/cudaMemcpy.

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


dim3 kBlockDim(std::min(int64_t(new_dims[0]), kMaxBlockDim),
std::min(int64_t(new_dims[1]), kMaxBlockDim), 1);
fill_diagonal_tensor_kernel<T><<<1, kBlockDim, 0>>>(
Copy link
Collaborator

@sneaxiy sneaxiy Aug 6, 2021

Choose a reason for hiding this comment

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

I do not know why you use this dimension setting. I prefer to use both gridDim and blockDim. The gridDim can be up to 2^27 usually.

Also, add testings of large dimensions.

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


class TensorFillDiagTensor_Test(unittest.TestCase):
def test_dim2(self):
expected_np = np.array(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add testing with larger dimensions.

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

@@ -37,6 +37,43 @@
__all__ = []


@dygraph_only
def fill_diagonal_tensor_(x, src_tensor, dim1=0, dim2=1, offset=0):
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems that we can have another API named fill_diagonal_tensor (non-inplace version). This API can be used in both static and dygraph mode.

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

src_tensor = src_tensor.reshape([1, -1])

matrows = 1
for dim in src_tensor.shape[:-1]:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not need this attribute.

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

public:
void Make() override {
AddComment(R"DOC(Fill replace operator
Fill the diagonal matrix of an tensor with `y` Tensor.
Copy link
Collaborator

Choose a reason for hiding this comment

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

As discussed offline, not matrix.

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

Fill the diagonal matrix of an tensor with `y` Tensor.
)DOC");
AddInput("X", "(Tensor) The input tensor.");
AddInput("y", "(Tensor) The input tensor to filled in.");
Copy link
Collaborator

Choose a reason for hiding this comment

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

to filled -> to fill.

y -> SrcTensor.

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, As discussed, "y" is accepted

@@ -37,6 +37,128 @@
__all__ = []


@dygraph_only
def fill_diagonal_tensor_(x, y, dim1=0, dim2=1, offset=0, name=None):
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why not unify most of the codes of fill_diagonal_tensor_ and fill_diagonal_tensor. Too many duplicate codes....

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

import paddle


class TensorFillDiagTensor_Test(unittest.TestCase):
Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. No tests with the case dim1 > dim2.
  2. Why not use OpTest?

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, add both

@zhiboniu zhiboniu changed the title add api fill_diagmat_inplace add new api fill_diagonal_tensor_ Aug 17, 2021
sneaxiy
sneaxiy previously approved these changes Aug 25, 2021
Copy link
Collaborator

@sneaxiy sneaxiy left a comment

Choose a reason for hiding this comment

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

LGTM.

@@ -86,6 +86,112 @@ def fill_diagonal_(x, value, offset=0, wrap=False, name=None):
setattr(core.VarBase, 'fill_diagonal_', fill_diagonal_)


def fill_diagonal_tensor_kernel(x, y, offset=0, dim1=0, dim2=1, inplace=False):
Copy link
Contributor

Choose a reason for hiding this comment

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

kernel是c++底层的概念,python层的API需要避免用这个名字,避免概念混淆。
建议用其他名字,比如_fill_diagonal_tensor_impl之类,表示具体的实现implement

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

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.

LG API

Returns:
Tensor: Tensor with diagonal filled with y.

Returns type:
Copy link
Contributor

Choose a reason for hiding this comment

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

returns type这个在文档说明中不需要吧?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

嗯,下个pr里改了

Returns:
Tensor: Tensor with diagonal filled with y.

Returns type:
Copy link
Contributor

Choose a reason for hiding this comment

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

returns type这个在文档说明中不需要吧?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

嗯,下个pr里改了

Copy link
Contributor

@jzhang533 jzhang533 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

@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

@jeff41404 jeff41404 merged commit 98d047d into PaddlePaddle:develop Sep 10, 2021
AnnaTrainingG pushed a commit to AnnaTrainingG/Paddle that referenced this pull request Sep 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants