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

(this PR is just for my personal self-learning) [PaddlePaddle Hackathon 2 No.22] add paddle.index_add to Paddle #42475

Closed
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
94fb159
Add files via upload
OccupyMars2025 May 4, 2022
b4442be
Add files via upload
OccupyMars2025 May 4, 2022
f60ad37
Add files via upload
OccupyMars2025 May 4, 2022
9adf9cc
Add files via upload
OccupyMars2025 May 4, 2022
65cfb27
Add files via upload
OccupyMars2025 May 4, 2022
50e2cd1
Add files via upload
OccupyMars2025 May 4, 2022
9b8380b
Add files via upload
OccupyMars2025 May 4, 2022
65050b4
Add files via upload
OccupyMars2025 May 4, 2022
b3cf6be
Add files via upload
OccupyMars2025 May 4, 2022
04a3fce
Add files via upload
OccupyMars2025 May 4, 2022
5c3f5d1
Add files via upload
OccupyMars2025 May 4, 2022
f6cda0f
Add files via upload
OccupyMars2025 May 4, 2022
9415651
Add files via upload
OccupyMars2025 May 4, 2022
75c1869
Add files via upload
OccupyMars2025 May 4, 2022
35da3f7
Add files via upload
OccupyMars2025 May 4, 2022
88af7e7
Add files via upload
OccupyMars2025 May 4, 2022
2e2cf4c
Add files via upload
OccupyMars2025 May 4, 2022
98ab985
Add files via upload
OccupyMars2025 May 4, 2022
7b2dbef
Add files via upload
OccupyMars2025 May 4, 2022
d0a2631
Add files via upload
OccupyMars2025 May 4, 2022
b546b05
Add files via upload
OccupyMars2025 May 5, 2022
41d7be0
Add files via upload
OccupyMars2025 May 5, 2022
62a7f1c
Add files via upload
OccupyMars2025 May 5, 2022
959dbc2
Add files via upload
OccupyMars2025 May 5, 2022
00b25c2
Add files via upload
OccupyMars2025 May 5, 2022
04491ff
Add files via upload
OccupyMars2025 May 10, 2022
181665f
Add files via upload
OccupyMars2025 May 10, 2022
cfd71bb
Update __init__.py
OccupyMars2025 May 10, 2022
88d1295
Merge branch 'develop' into hackathon-2nd-task22-add-index_add
OccupyMars2025 May 10, 2022
0e62f69
Merge branch 'PaddlePaddle:develop' into hackathon-2nd-task22-add-ind…
OccupyMars2025 May 10, 2022
700dbee
Add files via upload
OccupyMars2025 May 12, 2022
75af4a1
Add files via upload
OccupyMars2025 May 12, 2022
3838749
Add files via upload
OccupyMars2025 May 12, 2022
dc8af85
Add files via upload
OccupyMars2025 May 12, 2022
aaaba0c
Add files via upload
OccupyMars2025 May 12, 2022
c017dac
Add files via upload
OccupyMars2025 May 12, 2022
2bcd776
Add files via upload
OccupyMars2025 May 12, 2022
78ce053
Add files via upload
OccupyMars2025 May 12, 2022
930e314
Add files via upload
OccupyMars2025 May 12, 2022
ae72a00
Add files via upload
OccupyMars2025 May 12, 2022
f66dc0c
Add files via upload
OccupyMars2025 May 12, 2022
33bb556
Add files via upload
OccupyMars2025 May 13, 2022
9de7ee3
Add files via upload
OccupyMars2025 May 13, 2022
43fc9f6
Add files via upload
OccupyMars2025 May 13, 2022
28839dd
Add files via upload
OccupyMars2025 May 14, 2022
b90a58c
Add files via upload
OccupyMars2025 May 14, 2022
a02247d
Add files via upload
OccupyMars2025 May 15, 2022
8fdae4a
Add files via upload
OccupyMars2025 May 15, 2022
c6cefc1
Add files via upload
OccupyMars2025 May 15, 2022
fbabcce
Add files via upload
OccupyMars2025 May 15, 2022
32ef9af
Add files via upload
OccupyMars2025 May 15, 2022
6a6f698
Add files via upload
OccupyMars2025 May 15, 2022
f68f280
Add files via upload
OccupyMars2025 May 15, 2022
354a3de
Add files via upload
OccupyMars2025 May 15, 2022
60454ed
Add files via upload
OccupyMars2025 May 15, 2022
418f613
Merge branch 'PaddlePaddle:develop' into hackathon-2nd-task22-add-ind…
OccupyMars2025 May 15, 2022
b714d86
Update unary.cc
OccupyMars2025 May 15, 2022
3b203b7
Update index_add_op.cc
OccupyMars2025 May 15, 2022
fbc056f
Add files via upload
OccupyMars2025 May 15, 2022
5ef0319
Add files via upload
OccupyMars2025 May 15, 2022
50037cb
Add files via upload
OccupyMars2025 May 15, 2022
66defb6
Add files via upload
OccupyMars2025 May 15, 2022
2e30e48
Add files via upload
OccupyMars2025 May 15, 2022
d59fe50
Add files via upload
OccupyMars2025 May 15, 2022
0362dae
Add files via upload
OccupyMars2025 May 15, 2022
c1b8a22
Add files via upload
OccupyMars2025 May 15, 2022
ddf255e
Add files via upload
OccupyMars2025 May 15, 2022
45c1e81
Add files via upload
OccupyMars2025 May 15, 2022
a0413f7
Add files via upload
OccupyMars2025 May 16, 2022
176d6bd
Add files via upload
OccupyMars2025 May 16, 2022
ceb519f
Add files via upload
OccupyMars2025 May 16, 2022
1b24d8b
Add files via upload
OccupyMars2025 May 16, 2022
a9c1617
Add files via upload
OccupyMars2025 May 16, 2022
01981d6
Add files via upload
OccupyMars2025 May 16, 2022
bfc0e35
Add files via upload
OccupyMars2025 May 16, 2022
d9cde21
Add files via upload
OccupyMars2025 May 16, 2022
33f0bcc
Add files via upload
OccupyMars2025 May 16, 2022
821eee6
Add files via upload
OccupyMars2025 May 16, 2022
d1aeda9
Add files via upload
OccupyMars2025 May 16, 2022
791c825
Add files via upload
OccupyMars2025 May 16, 2022
407673e
Add files via upload
OccupyMars2025 May 16, 2022
3b11f18
Add files via upload
OccupyMars2025 May 16, 2022
a113244
Merge branch 'PaddlePaddle:develop' into hackathon-2nd-task22-add-ind…
OccupyMars2025 May 16, 2022
df2ee5d
Merge branch 'PaddlePaddle:develop' into hackathon-2nd-task22-add-ind…
OccupyMars2025 May 16, 2022
b2d345b
just trigger CI again
OccupyMars2025 May 16, 2022
2483e07
add line 439 and line 440 EinsumInferMeta in paddle/phi/infermeta/un…
OccupyMars2025 May 17, 2022
9fbde57
restore code about heaviside API
OccupyMars2025 May 17, 2022
14786cf
restore code about heaviside API
OccupyMars2025 May 17, 2022
ff15e2d
uncomment other unit test cases
OccupyMars2025 May 17, 2022
24d3827
leave only one unit test case
OccupyMars2025 May 17, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions paddle/fluid/operators/index_add_op.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include <memory>
#include "paddle/fluid/framework/infershape_utils.h"
#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/framework/op_version_registry.h"
#include "paddle/phi/core/infermeta_utils.h"
#include "paddle/phi/infermeta/binary.h"

namespace paddle {
namespace operators {

class IndexAddOp : public framework::OperatorWithKernel {
public:
using framework::OperatorWithKernel::OperatorWithKernel;

framework::OpKernelType GetExpectedKernelType(
const framework::ExecutionContext& ctx) const override {
return framework::OpKernelType(
OperatorWithKernel::IndicateVarDataType(ctx, "X"), ctx.GetPlace());
}
};

class IndexAddOpMaker : public framework::OpProtoAndCheckerMaker {
public:
void Make() override {
AddInput("X",
"(Tensor, default input Tensor<float>), "
"the input feature data of IndexAddOp, dtype should be"
"int32, int64, float16, float32, float64.");
AddInput("Index",
Copy link

@iclementine iclementine May 11, 2022

Choose a reason for hiding this comment

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

Index 希望也能支持 python 的 list 或者 tuple of ints.
这样写是不能支持传入 list or tuple of ints, 这和设计中的描述也不一致。

"(Tensor, default 1-d Tensor<int>), "
"the 1-D tensor containing the indices to index, "
"dtype should be int32, int64");
AddAttr<int>("axis",
"(int, default 0), "
"the dimension in which we index.")
.SetDefault(0);

Choose a reason for hiding this comment

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

不建议添加默认值,因为没有合理的默认值

此外,axis 希望也能支持 Tensor 输入,亦即也作为一个 Input 而不只是 Attr. 具体实现方法可以参考 paddle/fluid/operators/scale_op.cc

AddAttr<float>("added_value",
"(float, default 0.0f) The value to add.")
.SetDefault(0.0f);

Choose a reason for hiding this comment

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

不建议添加默认值,因为没有合理的默认值

AddOutput("Out",
"(Tensor, default Tensor<float>),"
" the output of IndexAddOp, whose dtype and shape is the same as X.");
AddComment(R"DOC(
index_add operator.
Add the elements of the input tensor with value
by selecting the indices in the order given in 'index'
on the axis 'axis'.

This operator also supports inplace modification.
)DOC");
}
};

template <typename T>
class IndexAddGradOpMaker : public framework::SingleGradOpMaker<T> {
public:
using framework::SingleGradOpMaker<T>::SingleGradOpMaker;

void Apply(GradOpPtr<T> op) const override {
op->SetType("index_add_grad");
op->SetInput(framework::GradVarName("Out"), this->OutputGrad("Out"));
op->SetOutput(framework::GradVarName("X"), this->InputGrad("X"));
op->SetAttrMap(this->Attrs());
}
};

class IndexAddGradOp : public framework::OperatorWithKernel {
public:
using framework::OperatorWithKernel::OperatorWithKernel;

protected:
framework::OpKernelType GetExpectedKernelType(
const framework::ExecutionContext& ctx) const override {
return framework::OpKernelType(
OperatorWithKernel::IndicateVarDataType(
ctx, framework::GradVarName("Out")), ctx.GetPlace());
}
};

DECLARE_INPLACE_OP_INFERER(IndexAddInplaceInferer, {"X", "Out"});
DECLARE_INPLACE_OP_INFERER(IndexAddGradInplaceInferer,
{framework::GradVarName("Out"),
framework::GradVarName("X")});
// DECLARE_NO_NEED_BUFFER_VARS_INFERER(IndexAddGradNoNeedBufferVarsInferer, "X");

} // namespace operators
} // namespace paddle

namespace ops = paddle::operators;
DECLARE_INFER_SHAPE_FUNCTOR(index_add, IndexAddInferShapeFunctor,
PD_INFER_META(phi::IndexAddInferMeta));

REGISTER_OPERATOR(index_add, ops::IndexAddOp, ops::IndexAddOpMaker,
ops::IndexAddGradOpMaker<paddle::framework::OpDesc>,
ops::IndexAddGradOpMaker<paddle::imperative::OpBase>,
ops::IndexAddInplaceInferer, IndexAddInferShapeFunctor);

DECLARE_INFER_SHAPE_FUNCTOR(index_add_grad, IndexAddGradInferShapeFunctor,
PD_INFER_META(phi::IndexAddGradInferMeta));

REGISTER_OPERATOR(index_add_grad, ops::IndexAddGradOp,
ops::IndexAddGradInplaceInferer,
// ops::IndexAddGradNoNeedBufferVarsInferer,
IndexAddGradInferShapeFunctor);
45 changes: 45 additions & 0 deletions paddle/phi/infermeta/binary.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,51 @@ void HuberLossInferMeta(const MetaTensor& input,
out->share_lod(input);
}

void IndexAddInferMeta(const MetaTensor& x,
const MetaTensor& index,
int axis,
float added_value,
MetaTensor* output) {
auto input_dim = x.dims();
auto index_dim = index.dims();

PADDLE_ENFORCE_EQ(
axis < input_dim.size() && axis >= - input_dim.size(),
true,
phi::errors::OutOfRange(
"Attr(axis) is out of range, It's expected "
"to be in range of [-%d, %d). But received Attr(axis) = %d.",
input_dim.size(),
input_dim.size(),
axis));

PADDLE_ENFORCE_EQ(
// index_dim.size() == 1 || (index_dim.size() == 2 && index_dim[1] == 1),
index_dim.size() == 1 && index_dim[0] > 0,
true,
phi::errors::InvalidArgument(
"The 'shape' of Input(Index) must be 1-D tensor. "
"But received: the 'shape' of Input(Index) is [%s], "
"the dimension of Input(Index) is [%d].",
index_dim,
index_dim.size()));

output->set_dims(x.dims());
output->set_dtype(x.dtype());
output->set_layout(x.layout());
output->share_lod(x);
}

void IndexAddGradInferMeta(const MetaTensor& out_grad,
int axis,
float added_value,
MetaTensor* x_grad) {
x_grad->set_dims(out_grad.dims());
x_grad->set_dtype(out_grad.dtype());
x_grad->set_layout(out_grad.layout());
x_grad->share_lod(out_grad);
}

void IndexSampleInferMeta(const MetaTensor& x,
const MetaTensor& y,
MetaTensor* out,
Expand Down
11 changes: 11 additions & 0 deletions paddle/phi/infermeta/binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,17 @@ void HuberLossInferMeta(const MetaTensor& input_meta,
MetaTensor* residual,
MetaConfig config = MetaConfig());

void IndexAddInferMeta(const MetaTensor& x,
const MetaTensor& index,
int axis,
float added_value,

Choose a reason for hiding this comment

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

如前面所属,axis, index, add_value 都支持 Tensor 或者 非 Tensor 的话,这些也都需要相应修改。

MetaTensor* output);

void IndexAddGradInferMeta(const MetaTensor& out_grad,
int axis,
float added_value,
MetaTensor* x_grad);

void IndexSampleInferMeta(const MetaTensor& x,
const MetaTensor& y,
MetaTensor* out,
Expand Down
41 changes: 41 additions & 0 deletions paddle/phi/kernels/cpu/index_add_grad_kernel.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "paddle/phi/kernels/index_add_grad_kernel.h"
#include "paddle/phi/core/kernel_registry.h"
#include "paddle/phi/core/utils/data_type.h"
#include "paddle/phi/kernels/copy_kernel.h"

namespace phi {

template <typename T, typename Context>
void IndexAddGradKernel(const Context& dev_ctx,
const DenseTensor& out_grad,
int axis,
float added_value,
DenseTensor* x_grad) {
phi::Copy(dev_ctx, out_grad, dev_ctx.GetPlace(), false, x_grad);
}

} // namespace phi

PD_REGISTER_KERNEL(index_add_grad,
CPU,
ALL_LAYOUT,
phi::IndexAddGradKernel,
float,
phi::dtype::float16,
double,
int,
int64_t) {}
86 changes: 86 additions & 0 deletions paddle/phi/kernels/cpu/index_add_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "paddle/phi/core/dense_tensor.h"
#include "paddle/phi/kernels/copy_kernel.h"
#include "paddle/phi/kernels/funcs/blas/blas.h"
#include "paddle/phi/kernels/funcs/eigen/common.h"
#include "paddle/phi/kernels/funcs/math_function.h"

namespace phi {
template <typename Context, typename T, typename IndexT = int>
void IndexAddInner(const Context& ctx,
const DenseTensor& index,
DenseTensor* output,
int axis,
T added_val) {
auto output_dim = output->dims();
auto output_dim_size = output_dim.size();
auto index_size = index.dims()[0];

DenseTensor index_cpu_copy;
if (!paddle::platform::is_cpu_place(index.place())) {
phi::Copy(ctx, index, phi::CPUPlace(), true, &index_cpu_copy);
}
const IndexT* index_data = paddle::platform::is_cpu_place(index.place())
? index.data<IndexT>()
: index_cpu_copy.data<IndexT>();

auto slice_size = 1;
for (auto i = axis + 1; i < output_dim_size; i++) {
slice_size *= output_dim[i];
}

auto outer_nums = 1;
for (auto i = 0; i < axis; i++) {
outer_nums *= output_dim[i];
}

for (int i = 0; i < index_size; i++) {
PADDLE_ENFORCE_GE(
index_data[i],
0,
phi::errors::InvalidArgument(
"Variable value (index) of OP(index_add) "
"expected >= 0 and < %ld, but got %ld. Please check input "
"value.",
output_dim[axis],
index_data[i]));
PADDLE_ENFORCE_LT(
index_data[i],
output_dim[axis],
phi::errors::InvalidArgument(
"Variable value (index) of OP(index_add) "
"expected >= 0 and < %ld, but got %ld. Please check input "
"value.",
output_dim[axis],
index_data[i]));
}

output->Resize(phi::make_ddim({outer_nums, output_dim[axis], slice_size}));

auto output_tensor = EigenTensor<T, 3>::From(*output);
auto& place = *ctx.eigen_device();
for (auto j = 0; j < index_size; j++) {
IndexT index_value = index_data[j];
auto output_t = output_tensor.chip(index_value, 1);
// output_t.device(place) = output_t.constant(fill_val);
output_t.device(place) += output_t.constant(added_val);
}
output->Resize(output_dim);
}

} // namespace phi
66 changes: 66 additions & 0 deletions paddle/phi/kernels/cpu/index_add_kernel.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "paddle/phi/kernels/index_add_kernel.h"
#include "paddle/phi/core/kernel_registry.h"
#include "paddle/phi/core/utils/data_type.h"
#include "paddle/phi/kernels/copy_kernel.h"
#include "paddle/phi/kernels/cpu/index_add_impl.h"
#include "paddle/phi/kernels/funcs/eigen/common.h"

namespace phi {

template <typename T, typename Context>
void IndexAddKernel(const Context& dev_ctx,
const DenseTensor& x,
const DenseTensor& index,
int axis,
float added_value,
DenseTensor* output) {
phi::Copy(dev_ctx, x, dev_ctx.GetPlace(), false, output);
if (axis < 0) {
axis += x.dims().size();
}
const auto& index_type = index.dtype();

bool index_type_match =
index_type == phi::DataType::INT32 || index_type == phi::DataType::INT64;
PADDLE_ENFORCE_EQ(index_type_match,
true,
phi::errors::InvalidArgument(
"Input(Index) holds the wrong type, it holds %s, but "
"desires to be %s or %s",
index_type,
phi::DataType::INT32,
phi::DataType::INT64));

auto added_val = static_cast<T>(added_value);
if (index_type == phi::DataType::INT32) {
IndexAddInner<Context, T, int>(dev_ctx, index, output, axis, added_val);
} else if (index_type == phi::DataType::INT64) {
IndexAddInner<Context, T, int64_t>(dev_ctx, index, output, axis, added_val);
}
}

} // namespace phi

PD_REGISTER_KERNEL(index_add,
CPU,
ALL_LAYOUT,
phi::IndexAddKernel,
float,
phi::dtype::float16,
double,
int,
int64_t) {}
Copy link

@iclementine iclementine May 11, 2022

Choose a reason for hiding this comment

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

希望也支持 bool, bfloat16 和 complex 数据类型。
GPU 环境下也是,以及反向也是如此。

Loading