未验证 提交 80285e85 编写于 作者: Y yongqiangma 提交者: GitHub

[arm]add op affine_grid. test=develop (#3799)

* add op affine_grid. test=develop
上级 4030e756
......@@ -66,7 +66,7 @@ class KernelBase {
virtual void SetProfileRuntimeKernelInfo(
paddle::lite::profile::OpCharacter* ch) {
ch->kernel_func_name = std::string("NotImpl");
#ifdef LITE_WITH_ARM
#ifdef LITE_WITH_OPENCL
ch->cl_event = event_;
#endif
}
......
......@@ -42,6 +42,7 @@ add_kernel(cast_compute_arm ARM basic SRCS cast_compute.cc DEPS ${lite_kernel_de
add_kernel(reduce_mean_compute_arm ARM basic SRCS reduce_mean_compute.cc DEPS ${lite_kernel_deps} math_arm)
add_kernel(stack_compute_arm ARM basic SRCS stack_compute.cc DEPS ${lite_kernel_deps} math_arm)
add_kernel(affine_channel_compute_arm ARM basic SRCS affine_channel_compute.cc DEPS ${lite_kernel_deps} math_arm)
add_kernel(affine_grid_compute_arm ARM basic SRCS affine_grid_compute.cc DEPS ${lite_kernel_deps} math_arm)
add_kernel(range_compute_arm ARM basic SRCS range_compute.cc DEPS ${lite_kernel_deps} math_arm)
add_kernel(dropout_compute_arm ARM basic SRCS dropout_compute.cc DEPS ${lite_kernel_deps} math_arm)
add_kernel(layout_compute_arm ARM basic SRCS layout_compute.cc DEPS ${lite_kernel_deps} math_arm)
......
// Copyright (c) 2019 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 "lite/kernels/arm/affine_grid_compute.h"
#include <string>
#include <vector>
#include "lite/backends/arm/math/funcs.h"
#include "lite/backends/arm/math/sgemm.h"
#include "lite/core/op_registry.h"
#include "lite/core/tensor.h"
#include "lite/core/type_system.h"
namespace paddle {
namespace lite {
namespace kernels {
namespace arm {
void AffineGridCompute::PrepareForRun() {
auto& param = Param<operators::AffineGridParam>();
auto& ctx = this->ctx_->template As<ARMContext>();
const lite::Tensor* x = param.X;
const float* din = x->data<float>();
lite::Tensor* out = param.Out;
float* dout = param.Out->mutable_data<float>();
int N = x->dims()[0];
int H = param.output_shape[2];
int W = param.output_shape[3];
vh = reinterpret_cast<float*>(malloc(sizeof(float) * H));
vw = reinterpret_cast<float*>(malloc(sizeof(float) * W));
int out_size = H * W * 3;
float scale = 2 / (static_cast<float>(H) - 1);
for (int i = 0; i < H; i++) {
vh[i] = -1 + scale * i;
}
scale = 2 / (static_cast<float>(W) - 1);
for (int i = 0; i < W; i++) {
vw[i] = -1 + i * scale;
}
return;
}
void AffineGridCompute::Run() {
auto& param = Param<operators::AffineGridParam>();
auto& ctx = this->ctx_->template As<ARMContext>();
const lite::Tensor* x = param.X;
int N = x->dims()[0];
int H = param.output_shape[2];
int W = param.output_shape[3];
int out_size = H * W * 3;
float* hw3 = ctx.workspace_data<float>() + ctx.llc_size() / sizeof(float);
for (int i = 0; i < out_size; i += 3) {
hw3[i] = 1;
hw3[i + 1] = 1;
hw3[i + 2] = 1;
}
for (int i = 0; i < H * W; i++) {
hw3[i * 3 + 1] = vh[i / W];
}
for (int i = 0; i < H * W; i++) {
hw3[i * 3] = vw[i % W];
}
const float* din = x->data<float>();
float* dout = param.Out->mutable_data<float>();
float* tmp = dout;
operators::ActivationParam act_param;
act_param.has_active = false;
for (int i = 0; i < N; i++) {
lite::arm::math::sgemm(false,
true,
H * W,
2,
3,
1.f,
hw3,
3,
din,
3,
0.f,
dout,
2,
nullptr,
false,
act_param,
&ctx);
din += 6;
dout += H * W * 2;
}
return;
}
} // namespace arm
} // namespace kernels
} // namespace lite
} // namespace paddle
REGISTER_LITE_KERNEL(affine_grid,
kARM,
kFloat,
kNCHW,
paddle::lite::kernels::arm::AffineGridCompute,
def)
.BindInput("Theta", {LiteType::GetTensorTy(TARGET(kARM))})
.BindOutput("Output", {LiteType::GetTensorTy(TARGET(kARM))})
.Finalize();
// Copyright (c) 2019 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 <algorithm>
#include "lite/core/kernel.h"
namespace paddle {
namespace lite {
namespace kernels {
namespace arm {
class AffineGridCompute : public KernelLite<TARGET(kARM), PRECISION(kFloat)> {
public:
using param_t = operators::AffineGridParam;
void PrepareForRun() override;
void Run() override;
virtual ~AffineGridCompute() = default;
float* vh;
float* vw;
};
} // namespace arm
} // namespace kernels
} // namespace lite
} // namespace paddle
......@@ -39,6 +39,7 @@ add_operator(unsqueeze_op_lite basic SRCS unsqueeze_op.cc DEPS ${op_DEPS})
add_operator(stack_op basic SRCS stack_op.cc DEPS ${op_DEPS})
add_operator(cast_op_lite basic SRCS cast_op.cc DEPS ${op_DEPS})
add_operator(affine_channel_op basic SRCS affine_channel_op.cc DEPS ${op_DEPS})
add_operator(affine_grid_op basic SRCS affine_grid_op.cc DEPS ${op_DEPS})
add_operator(range_op basic SRCS range_op.cc DEPS ${op_DEPS})
add_operator(reduce_mean_op basic SRCS reduce_mean_op.cc DEPS ${op_DEPS})
add_operator(relu_op basic SRCS relu_op.cc DEPS ${op_DEPS})
......
// Copyright (c) 2019 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 "lite/operators/affine_grid_op.h"
#include <vector>
#include "lite/core/op_lite.h"
#include "lite/core/op_registry.h"
namespace paddle {
namespace lite {
namespace operators {
bool AffineGridOpLite::CheckShape() const {
CHECK_OR_FALSE(param_.X);
CHECK_OR_FALSE(param_.Out);
const auto x_dims = param_.X->dims();
CHECK_OR_FALSE(x_dims.size() == 3);
CHECK_OR_FALSE(x_dims[1] == 2 && x_dims[2] == 3);
if (param_.output_shape.size() != 0) {
CHECK_OR_FALSE(param_.output_shape.size() == 4);
}
return true;
}
bool AffineGridOpLite::InferShapeImpl() const {
int N = param_.X->dims()[0];
int H, W;
if (param_.output_shape.size() == 0) {
const auto out_shape = param_.OutputShape->dims();
H = out_shape[2];
W = out_shape[3];
} else {
H = param_.output_shape[2];
W = param_.output_shape[3];
}
param_.Out->Resize(std::vector<int64_t>({N, H, W, 2}));
return true;
}
bool AffineGridOpLite::AttachImpl(const cpp::OpDesc &op_desc,
lite::Scope *scope) {
auto x = op_desc.Input("Theta").front();
auto output = op_desc.Output("Output").front();
param_.X = scope->FindVar(x)->GetMutable<lite::Tensor>();
param_.output_shape = op_desc.GetAttr<std::vector<int>>("output_shape");
param_.Out = scope->FindVar(output)->GetMutable<lite::Tensor>();
return true;
}
} // namespace operators
} // namespace lite
} // namespace paddle
REGISTER_LITE_OP(affine_grid, paddle::lite::operators::AffineGridOpLite);
// Copyright (c) 2019 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 <string>
#include "lite/core/op_lite.h"
#include "lite/core/scope.h"
#include "lite/operators/op_params.h"
#include "lite/utils/all.h"
namespace paddle {
namespace lite {
namespace operators {
class AffineGridOpLite : public OpLite {
public:
AffineGridOpLite() {}
explicit AffineGridOpLite(const std::string &op_type) : OpLite(op_type) {}
bool CheckShape() const override;
bool InferShapeImpl() const override;
bool AttachImpl(const cpp::OpDesc &opdesc, lite::Scope *scope) override;
void AttachKernel(KernelBase *kernel) override { kernel->SetParam(param_); }
std::string DebugString() const override { return "affine_grid"; }
private:
mutable AffineGridParam param_;
};
} // namespace operators
} // namespace lite
} // namespace paddle
......@@ -1166,6 +1166,13 @@ struct AffineChannelParam : ParamBase {
lite::Tensor* Out{};
};
struct AffineGridParam : ParamBase {
const lite::Tensor* X{}; // Theta:shape {?, 2, 3}
std::vector<int> output_shape;
const lite::Tensor* OutputShape;
lite::Tensor* Out{};
};
struct AnchorGeneratorParam : ParamBase {
const lite::Tensor* Input{};
std::vector<float> anchor_sizes{};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册