Skip to content

Commit 9df84bd

Browse files
authored
【NPU】add scale op for npu (#31499)
* add scale npu * fix * fix
1 parent e19195f commit 9df84bd

File tree

2 files changed

+158
-0
lines changed

2 files changed

+158
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/* Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License. */
14+
15+
#include <memory>
16+
#include <string>
17+
18+
#include "paddle/fluid/operators/npu_op_runner.h"
19+
#include "paddle/fluid/operators/scale_op.h"
20+
21+
namespace paddle {
22+
namespace operators {
23+
24+
template <typename DeviceContext, typename T>
25+
class ScaleNPUKernel : public framework::OpKernel<T> {
26+
public:
27+
void Compute(const framework::ExecutionContext& ctx) const override {
28+
auto* x = ctx.Input<framework::Tensor>("X");
29+
auto* out = ctx.Output<framework::Tensor>("Out");
30+
auto scale = static_cast<float>(ctx.Attr<float>("scale"));
31+
auto bias = static_cast<float>(ctx.Attr<float>("bias"));
32+
auto bias_after_scale = ctx.Attr<bool>("bias_after_scale");
33+
auto stream =
34+
ctx.template device_context<paddle::platform::NPUDeviceContext>()
35+
.stream();
36+
float _power = 1.0;
37+
if (bias_after_scale) {
38+
out->mutable_data<T>(ctx.GetPlace());
39+
auto runner =
40+
NpuOpRunner("Power", {*x}, {*out},
41+
{{"power", _power}, {"scale", scale}, {"shift", bias}});
42+
43+
runner.Run(stream);
44+
} else {
45+
Tensor tmp_x(x->type());
46+
tmp_x.Resize(x->dims());
47+
tmp_x.mutable_data<T>(ctx.GetPlace());
48+
auto runner_tmp = NpuOpRunner("Adds", {*x}, {tmp_x}, {{"value", bias}});
49+
runner_tmp.Run(stream);
50+
51+
out->mutable_data<T>(ctx.GetPlace());
52+
float _bias = 0.0;
53+
auto runner =
54+
NpuOpRunner("Power", {tmp_x}, {*out},
55+
{{"power", _power}, {"scale", scale}, {"shift", _bias}});
56+
runner.Run(stream);
57+
}
58+
}
59+
};
60+
61+
} // namespace operators
62+
} // namespace paddle
63+
64+
namespace ops = paddle::operators;
65+
66+
REGISTER_OP_NPU_KERNEL(
67+
scale, ops::ScaleNPUKernel<paddle::platform::NPUDeviceContext, float>,
68+
ops::ScaleNPUKernel<paddle::platform::NPUDeviceContext,
69+
paddle::platform::float16>);
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from __future__ import print_function
16+
17+
import numpy as np
18+
import unittest
19+
import sys
20+
sys.path.append("..")
21+
from op_test import OpTest
22+
import paddle
23+
import paddle.fluid as fluid
24+
25+
paddle.enable_static()
26+
SEED = 2021
27+
28+
29+
@unittest.skipIf(not paddle.is_compiled_with_npu(),
30+
"core is not compiled with NPU")
31+
class TestScale(OpTest):
32+
def setUp(self):
33+
self.set_npu()
34+
self.op_type = "scale"
35+
self.place = paddle.NPUPlace(0)
36+
self.init_dtype()
37+
38+
self.inputs = {
39+
'X': OpTest.np_dtype_to_fluid_dtype(
40+
np.random.random((10, 10)).astype(self.dtype))
41+
}
42+
self.attrs = {'scale': -2.3, 'bias': 0, 'bias_after_scale': True}
43+
self.outputs = {
44+
'Out': self.inputs['X'] * self.dtype(self.attrs['scale'])
45+
}
46+
47+
def set_npu(self):
48+
self.__class__.use_npu = True
49+
50+
def init_dtype(self):
51+
self.dtype = np.float32
52+
53+
def test_check_output(self):
54+
self.check_output_with_place(self.place, check_dygraph=False)
55+
56+
57+
class TestFP16Scale(TestScale):
58+
def init_dtype(self):
59+
self.dtype = np.float16
60+
61+
62+
class TestBiasAfterScale(OpTest):
63+
def setUp(self):
64+
self.set_npu()
65+
self.op_type = "scale"
66+
self.place = paddle.NPUPlace(0)
67+
self.init_dtype()
68+
69+
self.inputs = {
70+
'X': OpTest.np_dtype_to_fluid_dtype(
71+
np.random.random((10, 10)).astype(self.dtype))
72+
}
73+
self.attrs = {'scale': -2.3, 'bias': 0, 'bias_after_scale': False}
74+
self.outputs = {
75+
'Out': self.inputs['X'] * self.dtype(self.attrs['scale'])
76+
}
77+
78+
def set_npu(self):
79+
self.__class__.use_npu = True
80+
81+
def init_dtype(self):
82+
self.dtype = np.float32
83+
84+
def test_check_output(self):
85+
self.check_output_with_place(self.place, check_dygraph=False)
86+
87+
88+
if __name__ == '__main__':
89+
unittest.main()

0 commit comments

Comments
 (0)