提交 c3db2db5 编写于 作者: E eclipsess

add transpose and regist op

上级 c3d3bd36
...@@ -25,6 +25,7 @@ limitations under the License. */ ...@@ -25,6 +25,7 @@ limitations under the License. */
#include "framework/attribute.h" #include "framework/attribute.h"
#include "framework/op_info.h" #include "framework/op_info.h"
#include "framework/op_kernel_type.h" #include "framework/op_kernel_type.h"
#include "framework/op_registry.h"
#include "framework/paddle_mobile_object.h" #include "framework/paddle_mobile_object.h"
#include "framework/program/block_desc.h" #include "framework/program/block_desc.h"
#include "framework/program/program-optimize/node.h" #include "framework/program/program-optimize/node.h"
......
...@@ -25,3 +25,7 @@ void BatchNormOp<Dtype, T>::InferShape() const { ...@@ -25,3 +25,7 @@ void BatchNormOp<Dtype, T>::InferShape() const {
template class BatchNormOp<CPU, float>; template class BatchNormOp<CPU, float>;
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
namespace ops = paddle_mobile::operators;
USE_OP(batchnorm);
REGISTER_OPERATOR(batchnorm, ops::BatchNormOp);
...@@ -48,3 +48,7 @@ void BoxCoderOp<Dtype, T>::InferShape() const { ...@@ -48,3 +48,7 @@ void BoxCoderOp<Dtype, T>::InferShape() const {
template class BoxCoderOp<CPU, float>; template class BoxCoderOp<CPU, float>;
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
namespace ops = paddle_mobile::operators;
USE_OP(box_coder);
REGISTER_OPERATOR(box_coder, ops::BoxCoderOp);
...@@ -58,3 +58,7 @@ template class ConcatOp<CPU, float>; ...@@ -58,3 +58,7 @@ template class ConcatOp<CPU, float>;
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
namespace ops = paddle_mobile::operators;
USE_OP(concat);
REGISTER_OPERATOR(concat, ops::ConcatOp);
...@@ -25,3 +25,7 @@ void ElementwiseAddOp<Dtype, T>::InferShape() const { ...@@ -25,3 +25,7 @@ void ElementwiseAddOp<Dtype, T>::InferShape() const {
template class ElementwiseAddOp<CPU, float>; template class ElementwiseAddOp<CPU, float>;
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
namespace ops = paddle_mobile::operators;
USE_OP(elementwise_add);
REGISTER_OPERATOR(elementwise_add, ops::ElementwiseAddOp);
/* Copyright (c) 2018 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 "operators/kernel/transpose_kernel.h"
namespace paddle_mobile {
namespace operators {
template <typename T>
void TransposeFunc(const int numel, const T* input, const vector<int> axis,
const vector<int> old_strides, const vector<int> new_strides,
T* output) {
for (int i = 0; i < numel; ++i) {
int old_idx = 0;
int idx = i;
for (int j = 0; j < axis.size(); ++j) {
int order = axis[j];
old_idx += (idx / new_strides[j]) * old_strides[order];
idx %= new_strides[j];
}
output[i] = input[old_idx];
}
}
template <>
void TransposeKernel<CPU, float>::Compute(const TransposeParam& param) const {
const auto* input_x = param.InputX();
const auto input_x_dims = input_x->dims();
auto* out = param.Out();
const auto axis = param.Axis();
const auto* input_x_data = input_x->data<float>();
auto* out_data = out->mutable_data<float>();
size_t axis_size = axis.size();
std::vector<int> new_dims;
new_dims.reserve(axis_size);
for (auto c : axis) {
new_dims.push_back(input_x_dims[c]);
}
std::vector<int> old_strides;
std::vector<int> new_strides;
for (int i = 0; i < axis.size(); i++) {
int temp_old = 1;
int temp_new = 1;
for (int j = i + 1; j < axis.size(); j++) {
temp_old *= input_x_dims[j];
temp_new *= new_dims[j];
}
old_strides.push_back(temp_old);
new_strides.push_back(temp_new);
}
TransposeFunc<float>(input_x->numel(), input_x_data, axis, old_strides,
new_strides, out_data);
}
} // namespace operators
} // namespace paddle_mobile
/* Copyright (c) 2018 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 <vector>
#include "framework/operator.h"
#include "operators/op_param.h"
#pragma once;
namespace paddle_mobile {
namespace operators {
template <typename DeviceType, typename T>
class TransposeKernel
: public framework::OpKernelBase<DeviceType, TransposeParam> {
public:
void Compute(const TransposeParam& param) const;
};
} // namespace operators
} // namespace paddle_mobile
...@@ -25,3 +25,7 @@ void LrnOp<Dtype, T>::InferShape() const { ...@@ -25,3 +25,7 @@ void LrnOp<Dtype, T>::InferShape() const {
template class LrnOp<CPU, float>; template class LrnOp<CPU, float>;
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
namespace ops = paddle_mobile::operators;
USE_OP(lrn);
REGISTER_OPERATOR(lrn, ops::LrnOp);
...@@ -51,3 +51,7 @@ void MulOp<Dtype, T>::InferShape() const { ...@@ -51,3 +51,7 @@ void MulOp<Dtype, T>::InferShape() const {
template class MulOp<CPU, float>; template class MulOp<CPU, float>;
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
namespace ops = paddle_mobile::operators;
USE_OP(mul);
REGISTER_OPERATOR(mul, ops::MulOp);
...@@ -35,3 +35,7 @@ void MultiClassNMSOp<Dtype, T>::InferShape() const { ...@@ -35,3 +35,7 @@ void MultiClassNMSOp<Dtype, T>::InferShape() const {
template class MultiClassNMSOp<CPU, float>; template class MultiClassNMSOp<CPU, float>;
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
namespace ops = paddle_mobile::operators;
USE_OP(multiclass_nms);
REGISTER_OPERATOR(multiclass_nms, ops::MultiClassNMSOp);
...@@ -583,5 +583,25 @@ class MultiClassNMSParam : public OpParam { ...@@ -583,5 +583,25 @@ class MultiClassNMSParam : public OpParam {
float score_threshold_; float score_threshold_;
}; };
class TransposeParam : public OpParam {
public:
TransposeParam(const VariableNameMap &inputs, const VariableNameMap &outputs,
const AttributeMap &attrs, const Scope &scope) {
input_x_ = InputXFrom<Tensor>(inputs, scope);
out_ = OutFrom<Tensor>(outputs, scope);
axis_ = GetAttr<vector<int>>("axis", attrs);
}
const Tensor *InputX() const { return input_x_; }
Tensor *Out() const { return out_; }
const vector<int> &Axis() const { return axis_; }
private:
Tensor *input_x_;
Tensor *out_;
vector<int> axis_;
};
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -54,3 +54,7 @@ void PoolOp<DeviceType, T>::InferShape() const { ...@@ -54,3 +54,7 @@ void PoolOp<DeviceType, T>::InferShape() const {
template class PoolOp<CPU, float>; template class PoolOp<CPU, float>;
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
namespace ops = paddle_mobile::operators;
USE_OP(pool2d);
REGISTER_OPERATOR(pool2d, ops::PoolOp);
...@@ -45,3 +45,7 @@ void PriorBoxOp<Dtype, T>::InferShape() const { ...@@ -45,3 +45,7 @@ void PriorBoxOp<Dtype, T>::InferShape() const {
template class PriorBoxOp<CPU, float>; template class PriorBoxOp<CPU, float>;
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
namespace ops = paddle_mobile::operators;
USE_OP(prior_box);
REGISTER_OPERATOR(prior_box, ops::PriorBoxOp);
...@@ -23,3 +23,7 @@ void SoftmaxOp<DeviceType, T>::InferShape() const { ...@@ -23,3 +23,7 @@ void SoftmaxOp<DeviceType, T>::InferShape() const {
template class SoftmaxOp<CPU, float>; template class SoftmaxOp<CPU, float>;
} // namespace operators } // namespace operators
} // namespace paddle_mobile } // namespace paddle_mobile
namespace ops = paddle_mobile::operators;
USE_OP(softmax);
REGISTER_OPERATOR(softmax, ops::SoftmaxOp);
/* Copyright (c) 2018 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 "operators/transpose_op.h"
#include <common/enforce.h>
#include <vector>
namespace paddle_mobile {
namespace operators {
template <typename Dtype, typename T>
void TransposeOp<Dtype, T>::InferShape() const {
auto input_x_dims = param_.InputX()->dims();
auto axis = param_.Axis();
size_t x_dims_size = input_x_dims.size();
size_t axis_size = axis.size();
PADDLE_MOBILE_ENFORCE((x_dims_size == axis_size),
"input_dims must "
"be equal to the axis_size. ")
std::vector<int> count(axis_size, 0);
for (size_t i = 0; i < axis_size; i++) {
PADDLE_MOBILE_ENFORCE(
axis[i] < static_cast<int>(axis_size) && ++count[axis[i]] == 1,
"Each element of Attribute axis should be a unique value "
"range from 0 to (dims - 1), "
"where the dims is the axis's size");
}
framework::DDim out_dims(input_x_dims);
for (size_t i = 0; i < axis_size; i++) {
out_dims[i] = input_x_dims[axis[i]];
}
param_.Out()->Resize(out_dims);
}
template class TransposeOp<CPU, float>;
} // namespace operators
} // namespace paddle_mobile
namespace ops = paddle_mobile::operators;
USE_OP(transpose);
REGISTER_OPERATOR(transpose, ops::TransposeOp);
/* Copyright (c) 2018 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 "framework/operator.h"
#include "operators/kernel/transpose_kernel.h"
#include "operators/op_param.h"
namespace paddle_mobile {
namespace operators {
using paddle_mobile::framework::Tensor;
template <typename DeviceType, typename T>
class TransposeOp : public framework::OperatorWithKernel<DeviceType> {
public:
TransposeOp(const std::string &type, const VariableNameMap &inputs,
const VariableNameMap &outputs,
const framework::AttributeMap attrs,
std::shared_ptr<framework::Scope> scope)
: framework::OperatorWithKernel<DeviceType>(type, inputs, outputs, attrs,
scope),
param_(inputs, outputs, attrs, *scope) {}
void Run() const {
operators::TransposeKernel<DeviceType, T> kernel;
kernel.Compute(param_);
}
using framework::OperatorWithKernel<DeviceType>::OperatorWithKernel;
void InferShape() const override;
protected:
TransposeParam param_;
};
} // namespace operators
} // namespace paddle_mobile
...@@ -34,6 +34,10 @@ target_link_libraries(test-priorbox-op paddle-mobile) ...@@ -34,6 +34,10 @@ target_link_libraries(test-priorbox-op paddle-mobile)
ADD_EXECUTABLE(test-boxcoder-op operators/test_box_coder_op.cpp test_helper.h test_include.h) ADD_EXECUTABLE(test-boxcoder-op operators/test_box_coder_op.cpp test_helper.h test_include.h)
target_link_libraries(test-boxcoder-op paddle-mobile) target_link_libraries(test-boxcoder-op paddle-mobile)
# gen test
ADD_EXECUTABLE(test-transpose-op operators/test_transpose_op.cpp test_helper.h test_include.h)
target_link_libraries(test-transpose-op paddle-mobile)
# gen test # gen test
ADD_EXECUTABLE(test-multiclassnms-op operators/test_multiclass_nms_op.cpp test_helper.h test_include.h) ADD_EXECUTABLE(test-multiclassnms-op operators/test_multiclass_nms_op.cpp test_helper.h test_include.h)
target_link_libraries(test-multiclassnms-op paddle-mobile) target_link_libraries(test-multiclassnms-op paddle-mobile)
......
...@@ -15,11 +15,13 @@ limitations under the License. */ ...@@ -15,11 +15,13 @@ limitations under the License. */
#pragma once #pragma once
#include <string> #include <string>
#include <vector>
#include "common/log.h" #include "common/log.h"
#include "framework/executor.h" #include "framework/executor.h"
#include "operators/conv_op.h" #include "operators/conv_op.h"
#include "operators/pool_op.h" #include "operators/pool_op.h"
#include "operators/softmax_op.h" #include "operators/softmax_op.h"
#include "operators/transpose_op.h"
using paddle_mobile::framework::BlockDesc; using paddle_mobile::framework::BlockDesc;
using paddle_mobile::framework::DDim; using paddle_mobile::framework::DDim;
......
/* Copyright (c) 2018 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 "../executor_for_test.h"
#include "../test_helper.h"
#include "./io.h"
int main() {
paddle_mobile::Loader<paddle_mobile::CPU> loader;
auto program = loader.Load(std::string("../../test/models/mobilenet+ssd"));
if (program.originProgram == nullptr) {
DLOG << "program read file";
}
Executor4Test<paddle_mobile::CPU, paddle_mobile::operators::TransposeOp<
paddle_mobile::CPU, float>>
executor(program, "transpose");
paddle_mobile::framework::Tensor input;
SetupTensor<float>(&input, {1, 2, 3, 4}, static_cast<float>(0),
static_cast<float>(1));
auto input_ptr = input.data<float>();
auto out_ddim = paddle_mobile::framework::make_ddim({1, 3, 4, 2});
auto output =
executor.predict(input, "conv2d_22.tmp_1", "transpose_0.tmp_0", out_ddim);
auto *output_ptr = output->data<float>();
DLOG << "input : ";
for (int j = 0; j < input.numel(); ++j) {
DLOG << " index " << j << " : " << input_ptr[j];
}
DLOG << "output : ";
for (int j = 0; j < output->numel(); ++j) {
DLOG << " index " << j << " : " << output_ptr[j];
}
DLOG << " for example : ";
DLOG << " you can check if input[16] == output[9] ";
DLOG << " you can check if input[12] == output[1] ";
return 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册