Skip to content

Commit 3d11d01

Browse files
author
Qingsheng Li
authored
Fix scatter_op python API (#12742)
* Fix scatter_op python API and remove inconsistency between implementation and doc * API spec change * Change as review comment
1 parent 3ae97aa commit 3d11d01

File tree

6 files changed

+68
-8
lines changed

6 files changed

+68
-8
lines changed

paddle/fluid/API.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ paddle.fluid.layers.image_resize ArgSpec(args=['input', 'out_shape', 'scale', 'n
153153
paddle.fluid.layers.image_resize_short ArgSpec(args=['input', 'out_short_len', 'resample'], varargs=None, keywords=None, defaults=('BILINEAR',))
154154
paddle.fluid.layers.resize_bilinear ArgSpec(args=['input', 'out_shape', 'scale', 'name'], varargs=None, keywords=None, defaults=(None, None, None))
155155
paddle.fluid.layers.gather ArgSpec(args=['input', 'index'], varargs=None, keywords=None, defaults=None)
156+
paddle.fluid.layers.scatter ArgSpec(args=['input', 'index', 'updates', 'name'], varargs=None, keywords=None, defaults=(None,))
156157
paddle.fluid.layers.random_crop ArgSpec(args=['x', 'shape', 'seed'], varargs=None, keywords=None, defaults=(None,))
157158
paddle.fluid.layers.mean_iou ArgSpec(args=['input', 'label', 'num_classes'], varargs=None, keywords=None, defaults=None)
158159
paddle.fluid.layers.relu ArgSpec(args=['x', 'name'], varargs=None, keywords=None, defaults=(None,))
@@ -250,7 +251,6 @@ paddle.fluid.layers.logical_not ArgSpec(args=[], varargs='args', keywords='kwarg
250251
paddle.fluid.layers.uniform_random_batch_size_like ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None)
251252
paddle.fluid.layers.gaussian_random ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None)
252253
paddle.fluid.layers.gaussian_random_batch_size_like ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None)
253-
paddle.fluid.layers.scatter ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None)
254254
paddle.fluid.layers.sum ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None)
255255
paddle.fluid.layers.slice ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None)
256256
paddle.fluid.layers.shape ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None)

paddle/fluid/operators/scatter_op.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,16 @@ class ScatterOpMaker : public framework::OpProtoAndCheckerMaker {
8181
void Make() override {
8282
AddInput("X", "The source input of scatter op");
8383
AddInput("Ids", "The index input of scatter op where X will be updated");
84-
AddInput("Updates", "The updated value of updates op");
85-
AddOutput("Out", "The output of add op");
84+
AddInput("Updates", "The updated value of scatter op");
85+
AddOutput("Out", "The output of scatter op");
8686
AddComment(R"DOC(
8787
Scatter Operator.
8888
8989
This operator obtains output by updating the input on selected indices on the first axis:
9090
9191
$$
9292
Out = X \\
93-
Out[Ids] = X[Ids] + Updates
93+
Out[Ids] = Updates
9494
$$
9595
9696
)DOC");

paddle/fluid/operators/scatter_op.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ class ScatterOpKernel : public framework::OpKernel<T> {
3434
auto *Updates = ctx.Input<Tensor>("Updates");
3535
auto *Out = ctx.Output<Tensor>("Out");
3636

37-
// In place output: Out = X, Out[Ids] += Updates
37+
// In place output: Out = X, Out[Ids] = Updates
3838
framework::TensorCopySync(*X, ctx.GetPlace(), Out);
39-
// Apply ScatterUpdate: Out[index] += Updates[:]
39+
// Apply ScatterUpdate: Out[index] = Updates[:]
4040
ScatterAssign<T>(ctx.device_context(), *Updates, *Ids, Out);
4141
}
4242
};
@@ -55,7 +55,7 @@ class ScatterGradientOpKernel : public framework::OpKernel<T> {
5555
// In place gradient: dX = dO
5656
framework::TensorCopySync(*dOut, ctx.GetPlace(), dX);
5757
dUpdates->mutable_data<T>(ctx.GetPlace());
58-
// Gradient by Gather: dUpdates += dO[Ids]
58+
// Gradient by Gather: dUpdates = dO[Ids]
5959
CPUGather<T>(ctx.device_context(), *dOut, *Ids, dUpdates);
6060
}
6161
};

python/paddle/fluid/layers/nn.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
'image_resize_short',
9595
'resize_bilinear',
9696
'gather',
97+
'scatter',
9798
'random_crop',
9899
'mean_iou',
99100
'relu',
@@ -5036,6 +5037,47 @@ def gather(input, index):
50365037
return out
50375038

50385039

5040+
def scatter(input, index, updates, name=None):
5041+
"""
5042+
**Scatter Layer**
5043+
5044+
Output is obtained by updating the input on selected indices on the first
5045+
axis.
5046+
5047+
.. math::
5048+
5049+
Out = X
5050+
Out[Ids] = Updates
5051+
5052+
Args:
5053+
input (Variable): The source input with rank>=1.
5054+
index (Variable): The index input with rank=1. Its dtype should be
5055+
int32 or int64 as it is used as indexes.
5056+
updates (Variable): The updated value of scatter op.
5057+
name (str|None): The output variable name. Default None.
5058+
5059+
Returns:
5060+
output (Variable): The output is a tensor with the same shape as input.
5061+
5062+
Examples:
5063+
5064+
.. code-block:: python
5065+
5066+
output = fluid.layers.scatter(input, index, updates)
5067+
5068+
"""
5069+
helper = LayerHelper('scatter', **locals())
5070+
dtype = helper.input_dtype()
5071+
out = helper.create_tmp_variable(dtype)
5072+
helper.append_op(
5073+
type="scatter",
5074+
inputs={"X": input,
5075+
"Ids": index,
5076+
"Updates": updates},
5077+
outputs={"Out": out})
5078+
return out
5079+
5080+
50395081
@templatedoc()
50405082
def random_crop(x, shape, seed=None):
50415083
"""

python/paddle/fluid/layers/ops.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
'uniform_random_batch_size_like',
6666
'gaussian_random',
6767
'gaussian_random_batch_size_like',
68-
'scatter',
6968
'sum',
7069
'slice',
7170
'shape',

python/paddle/fluid/tests/unittests/test_layers.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,25 @@ def test_smooth_l1(self):
347347
self.assertIsNotNone(loss)
348348
print(str(program))
349349

350+
def test_scatter(self):
351+
program = Program()
352+
with program_guard(program):
353+
x = layers.data(
354+
name='x',
355+
shape=[3, 3],
356+
append_batch_size=False,
357+
dtype='float32')
358+
idx = layers.data(
359+
name='idx', shape=[2], append_batch_size=False, dtype='int32')
360+
updates = layers.data(
361+
name='updates',
362+
shape=[2, 3],
363+
append_batch_size=False,
364+
dtype='float32')
365+
out = layers.scatter(input=x, index=idx, updates=updates)
366+
self.assertIsNotNone(out)
367+
print(str(program))
368+
350369
def test_lod_reset(self):
351370
program = Program()
352371
with program_guard(program):

0 commit comments

Comments
 (0)