Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
ed5ec09e
P
Paddle
项目概览
机器未来
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
ed5ec09e
编写于
6月 18, 2019
作者:
开心的小妮
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[LITE][ARM] Add transpose, transpose2 operator, kernel of arm cpu. test=develop
上级
af84d4ed
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
766 addition
and
1 deletion
+766
-1
paddle/fluid/lite/kernels/arm/CMakeLists.txt
paddle/fluid/lite/kernels/arm/CMakeLists.txt
+3
-0
paddle/fluid/lite/kernels/arm/transpose_compute.cc
paddle/fluid/lite/kernels/arm/transpose_compute.cc
+173
-0
paddle/fluid/lite/kernels/arm/transpose_compute.h
paddle/fluid/lite/kernels/arm/transpose_compute.h
+48
-0
paddle/fluid/lite/kernels/arm/transpose_compute_test.cc
paddle/fluid/lite/kernels/arm/transpose_compute_test.cc
+205
-0
paddle/fluid/lite/operators/CMakeLists.txt
paddle/fluid/lite/operators/CMakeLists.txt
+3
-0
paddle/fluid/lite/operators/op_params.h
paddle/fluid/lite/operators/op_params.h
+9
-0
paddle/fluid/lite/operators/transpose_op.cc
paddle/fluid/lite/operators/transpose_op.cc
+165
-0
paddle/fluid/lite/operators/transpose_op.h
paddle/fluid/lite/operators/transpose_op.h
+66
-0
paddle/fluid/lite/operators/transpose_op_test.cc
paddle/fluid/lite/operators/transpose_op_test.cc
+93
-0
paddle/fluid/lite/tools/build.sh
paddle/fluid/lite/tools/build.sh
+1
-1
未找到文件。
paddle/fluid/lite/kernels/arm/CMakeLists.txt
浏览文件 @
ed5ec09e
...
...
@@ -16,6 +16,7 @@ cc_library(pool_compute_arm SRCS pool_compute.cc DEPS ${lite_kernel_deps} math_a
cc_library
(
split_compute_arm SRCS split_compute.cc DEPS
${
lite_kernel_deps
}
math_arm
)
cc_library
(
concat_compute_arm SRCS concat_compute.cc DEPS
${
lite_kernel_deps
}
math_arm
)
cc_library
(
dropout_compute_arm SRCS dropout_compute.cc DEPS
${
lite_kernel_deps
}
math_arm
)
cc_library
(
transpose_compute_arm SRCS transpose_compute.cc DEPS
${
lite_kernel_deps
}
math_arm
)
lite_cc_test
(
test_fc_compute_arm SRCS fc_compute_test.cc DEPS fc_compute_arm math_arm
)
lite_cc_test
(
test_activation_compute_arm SRCS activation_compute_test.cc DEPS activation_compute_arm
)
...
...
@@ -29,6 +30,7 @@ lite_cc_test(test_mul_compute_arm SRCS mul_compute_test.cc DEPS mul_compute_arm)
lite_cc_test
(
test_split_compute_arm SRCS split_compute_test.cc DEPS split_compute_arm
)
lite_cc_test
(
test_concat_compute_arm SRCS concat_compute_test.cc DEPS concat_compute_arm
)
lite_cc_test
(
test_dropout_compute_arm SRCS dropout_compute_test.cc DEPS dropout_compute_arm
)
lite_cc_test
(
test_transpose_compute_arm SRCS transpose_compute_test.cc DEPS transpose_compute_arm
)
set
(
arm_kernels
fc_compute_arm
...
...
@@ -43,6 +45,7 @@ set(arm_kernels
split_compute_arm
concat_compute_arm
dropout_compute_arm
transpose_compute_arm
)
set
(
arm_kernels
"
${
arm_kernels
}
"
CACHE INTERNAL
"arm kernels"
)
...
...
paddle/fluid/lite/kernels/arm/transpose_compute.cc
0 → 100644
浏览文件 @
ed5ec09e
// 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 "paddle/fluid/lite/kernels/arm/transpose_compute.h"
#include <string>
#include <vector>
#include "paddle/fluid/lite/arm/math/funcs.h"
#include "paddle/fluid/lite/core/compatible_tensor.h"
#include "paddle/fluid/lite/core/op_registry.h"
#include "paddle/fluid/lite/core/type_system.h"
namespace
paddle
{
namespace
lite
{
namespace
kernels
{
namespace
arm
{
bool
IsShuffleChannel
(
const
std
::
vector
<
int
>
&
axis
)
{
bool
is_shuffle_channel
=
true
;
if
(
axis
.
size
()
>
2
&&
axis
[
0
]
==
0
&&
axis
[
1
]
==
2
&&
axis
[
2
]
==
1
)
{
for
(
int
i
=
3
;
i
<
axis
.
size
();
++
i
)
{
if
(
axis
[
i
]
!=
i
)
{
is_shuffle_channel
=
false
;
break
;
}
}
}
else
{
return
false
;
}
return
is_shuffle_channel
;
}
template
<
typename
Dtype
>
void
ShuffleChannelCompute
(
const
std
::
vector
<
int
>
&
axis
,
const
lite
::
Tensor
*
input
,
lite
::
Tensor
*
output
)
{
const
Dtype
*
input_ptr
=
input
->
data
<
Dtype
>
();
Dtype
*
output_ptr
=
output
->
mutable_data
<
Dtype
>
();
// input and output's shape dimension must >= 2 && <= 6.
const
DDim
&
in_dim
=
input
->
dims
();
const
DDim
&
out_dim
=
output
->
dims
();
size_t
offset
=
1
;
for
(
int
i
=
3
;
i
<
axis
.
size
();
++
i
)
{
offset
*=
in_dim
[
i
];
}
#pragma omp parallel for collapse(3)
for
(
int
batch
=
0
;
batch
<
out_dim
[
0
];
++
batch
)
{
for
(
int
c1
=
0
;
c1
<
out_dim
[
1
];
++
c1
)
{
for
(
int
c2
=
0
;
c2
<
out_dim
[
2
];
++
c2
)
{
size_t
out_offset
=
((
batch
*
out_dim
[
1
]
+
c1
)
*
out_dim
[
2
]
+
c2
)
*
offset
;
size_t
in_offset
=
((
batch
*
in_dim
[
1
]
+
c2
)
*
in_dim
[
2
]
+
c1
)
*
offset
;
memcpy
(
output_ptr
+
out_offset
,
input_ptr
+
in_offset
,
offset
*
sizeof
(
Dtype
));
}
}
}
}
template
<
typename
Dtype
>
void
TransposeCompute_
(
const
std
::
vector
<
int
>
&
axis
,
const
lite
::
Tensor
*
input
,
lite
::
Tensor
*
output
)
{
// const Dtype *input_ptr = input->data<Dtype>();
const
Dtype
*
input_ptr
=
input
->
data
<
float
>
();
Dtype
*
output_ptr
=
output
->
mutable_data
<
Dtype
>
();
// input and output's shape dimension must >= 2 && <= 6.
const
DDim
&
in_dim
=
input
->
dims
();
const
DDim
&
out_dim
=
output
->
dims
();
// precompute inverted output dim and strides
size_t
rout_dim
[
6
],
strides
[
6
];
int
permute
=
axis
.
size
();
// permute must >=2 && <= 6.
for
(
int
i
=
0
;
i
<
permute
;
++
i
)
{
int
k
=
permute
-
1
-
i
;
strides
[
k
]
=
1
;
for
(
int
j
=
axis
[
i
]
+
1
;
j
<
permute
;
++
j
)
{
strides
[
k
]
*=
in_dim
[
j
];
}
rout_dim
[
k
]
=
out_dim
[
i
];
}
// unroll the first 2 dimensions
int
reamin_dim
=
1
;
for
(
int
i
=
2
;
i
<
out_dim
.
size
();
++
i
)
{
reamin_dim
*=
out_dim
[
i
];
}
#pragma omp parallel for collapse(2)
for
(
int
batch
=
0
;
batch
<
out_dim
[
0
];
++
batch
)
{
for
(
int
j
=
0
;
j
<
out_dim
[
1
];
++
j
)
{
size_t
offset
=
batch
*
strides
[
permute
-
1
]
+
j
*
strides
[
permute
-
2
];
Dtype
*
out_ptr
=
output_ptr
+
(
batch
*
out_dim
[
1
]
+
j
)
*
reamin_dim
;
int
indics
[
4
]
=
{
0
,
0
,
0
,
0
};
for
(
int
k
=
0
;
k
<
reamin_dim
;
++
k
)
{
out_ptr
[
k
]
=
input_ptr
[
offset
];
indics
[
0
]
+=
1
;
offset
+=
strides
[
0
];
for
(
int
p
=
0
;
p
<
permute
-
3
;
++
p
)
{
if
(
indics
[
p
]
==
rout_dim
[
p
])
{
indics
[
p
+
1
]
+=
1
;
indics
[
p
]
=
0
;
offset
+=
strides
[
p
+
1
];
offset
-=
rout_dim
[
p
]
*
strides
[
p
];
}
else
{
break
;
}
}
}
}
}
}
// Transpose
void
TransposeCompute
::
Run
()
{
auto
&
param
=
Param
<
operators
::
TransposeParam
>
();
auto
*
input
=
param
.
x
;
auto
*
output
=
param
.
output
;
const
std
::
vector
<
int
>
axis
=
param
.
axis
;
bool
shuffle_channel
=
IsShuffleChannel
(
axis
);
if
(
shuffle_channel
)
{
ShuffleChannelCompute
<
float
>
(
axis
,
input
,
output
);
}
else
{
TransposeCompute_
<
float
>
(
axis
,
input
,
output
);
}
return
;
}
// Transpose2
void
Transpose2Compute
::
Run
()
{
auto
&
param
=
Param
<
operators
::
TransposeParam
>
();
auto
*
input
=
param
.
x
;
auto
*
output
=
param
.
output
;
const
std
::
vector
<
int
>
axis
=
param
.
axis
;
bool
shuffle_channel
=
IsShuffleChannel
(
axis
);
if
(
shuffle_channel
)
{
ShuffleChannelCompute
<
float
>
(
axis
,
input
,
output
);
}
else
{
TransposeCompute_
<
float
>
(
axis
,
input
,
output
);
}
return
;
}
}
// namespace arm
}
// namespace kernels
}
// namespace lite
}
// namespace paddle
// Transpose
REGISTER_LITE_KERNEL
(
transpose
,
kARM
,
kFloat
,
kNCHW
,
paddle
::
lite
::
kernels
::
arm
::
TransposeCompute
,
def
)
.
BindInput
(
"X"
,
{
LiteType
::
GetTensorTy
(
TARGET
(
kARM
))})
.
BindOutput
(
"Out"
,
{
LiteType
::
GetTensorTy
(
TARGET
(
kARM
))})
.
Finalize
();
// Transpose2
REGISTER_LITE_KERNEL
(
transpose2
,
kARM
,
kFloat
,
kNCHW
,
paddle
::
lite
::
kernels
::
arm
::
Transpose2Compute
,
def
)
.
BindInput
(
"X"
,
{
LiteType
::
GetTensorTy
(
TARGET
(
kARM
))})
.
BindOutput
(
"Out"
,
{
LiteType
::
GetTensorTy
(
TARGET
(
kARM
))})
.
Finalize
();
paddle/fluid/lite/kernels/arm/transpose_compute.h
0 → 100644
浏览文件 @
ed5ec09e
// 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 "paddle/fluid/lite/core/kernel.h"
#include "paddle/fluid/lite/operators/transpose_op.h"
namespace
paddle
{
namespace
lite
{
namespace
kernels
{
namespace
arm
{
// Transpose
class
TransposeCompute
:
public
KernelLite
<
TARGET
(
kARM
),
PRECISION
(
kFloat
)
>
{
public:
using
param_t
=
operators
::
TransposeParam
;
void
Run
()
override
;
virtual
~
TransposeCompute
()
=
default
;
};
// Transpose2
class
Transpose2Compute
:
public
KernelLite
<
TARGET
(
kARM
),
PRECISION
(
kFloat
)
>
{
public:
using
param_t
=
operators
::
TransposeParam
;
void
Run
()
override
;
virtual
~
Transpose2Compute
()
=
default
;
};
}
// namespace arm
}
// namespace kernels
}
// namespace lite
}
// namespace paddle
paddle/fluid/lite/kernels/arm/transpose_compute_test.cc
0 → 100644
浏览文件 @
ed5ec09e
// 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 "paddle/fluid/lite/kernels/arm/transpose_compute.h"
#include <gtest/gtest.h>
#include <limits>
#include <string>
#include <vector>
#include "paddle/fluid/lite/arm/math/funcs.h"
#include "paddle/fluid/lite/core/lite_tensor.h"
#include "paddle/fluid/lite/core/op_registry.h"
namespace
paddle
{
namespace
lite
{
namespace
kernels
{
namespace
arm
{
#define IN(n, c, h, w) \
input_data[w + h * input_w + c * input_h * input_w + \
n * input_c * input_h * input_w]
#define OUT(n, c, h, w) \
output_data[w + h * output_w + c * output_h * output_w + \
n * output_c * output_h * output_w]
void
transpose_compute_ref
(
const
operators
::
TransposeParam
&
param
)
{
const
lite
::
Tensor
*
input
=
param
.
x
;
lite
::
Tensor
*
output
=
param
.
output
;
std
::
vector
<
int
>
axis
=
param
.
axis
;
auto
*
input_data
=
input
->
data
<
float
>
();
auto
*
output_data
=
output
->
mutable_data
<
float
>
();
int
input_n
=
input
->
dims
()[
0
];
int
input_c
=
input
->
dims
()[
1
];
int
input_h
=
input
->
dims
()[
2
];
int
input_w
=
input
->
dims
()[
3
];
int
output_n
=
output
->
dims
()[
0
];
int
output_c
=
output
->
dims
()[
1
];
int
output_h
=
output
->
dims
()[
2
];
int
output_w
=
output
->
dims
()[
3
];
for
(
int
n
=
0
;
n
<
input_n
;
++
n
)
{
for
(
int
c
=
0
;
c
<
input_c
;
++
c
)
{
for
(
int
h
=
0
;
h
<
input_h
;
++
h
)
{
for
(
int
w
=
0
;
w
<
input_w
;
++
w
)
{
OUT
(
n
,
h
,
w
,
c
)
=
IN
(
n
,
c
,
h
,
w
);
}
}
}
}
}
// Transpose
TEST
(
transpose_arm
,
init
)
{
TransposeCompute
transpose
;
ASSERT_EQ
(
transpose
.
precision
(),
PRECISION
(
kFloat
));
ASSERT_EQ
(
transpose
.
target
(),
TARGET
(
kARM
));
}
TEST
(
transpose_arm
,
compute_shape_nchw
)
{
TransposeCompute
transpose
;
operators
::
TransposeParam
param
;
std
::
vector
<
int
>
axis
{
0
,
2
,
3
,
1
};
param
.
axis
=
axis
;
lite
::
Tensor
input
;
lite
::
Tensor
output
;
lite
::
Tensor
output_ref
;
const
std
::
vector
<
int64_t
>
input_shape
{
1
,
24
,
2
,
2
};
const
std
::
vector
<
int64_t
>
output_shape
{
1
,
2
,
2
,
24
};
DDimLite
ddimInput
(
input_shape
);
DDimLite
ddimOutput
(
output_shape
);
input
.
Resize
(
ddimInput
);
output
.
Resize
(
ddimOutput
);
output_ref
.
Resize
(
ddimOutput
);
for
(
int
i
=
0
;
i
<
input_shape
[
0
]
*
input_shape
[
1
]
*
input_shape
[
2
]
*
input_shape
[
3
];
i
+=
4
)
{
input
.
mutable_data
<
float
>
()[
i
]
=
i
;
input
.
mutable_data
<
float
>
()[
i
+
1
]
=
i
+
1
;
input
.
mutable_data
<
float
>
()[
i
+
2
]
=
i
+
2
;
input
.
mutable_data
<
float
>
()[
i
+
3
]
=
i
+
3
;
}
for
(
int
i
=
0
;
i
<
input_shape
[
0
]
*
input_shape
[
1
]
*
input_shape
[
2
]
*
input_shape
[
3
];
i
+=
4
)
{
}
param
.
x
=
&
input
;
param
.
output
=
&
output
;
// run transpose_compute
transpose
.
SetParam
(
param
);
transpose
.
Run
();
// run transpose_compute_ref
param
.
output
=
&
output_ref
;
transpose_compute_ref
(
param
);
auto
*
output_data
=
output
.
data
<
float
>
();
auto
*
output_ref_data
=
output_ref
.
data
<
float
>
();
for
(
int
i
=
0
;
i
<
input_shape
[
0
]
*
input_shape
[
1
]
*
input_shape
[
2
]
*
input_shape
[
3
];
i
+=
4
)
{
EXPECT_NEAR
(
output_data
[
i
],
output_ref_data
[
i
],
1e-5
);
}
}
TEST
(
transpose
,
retrive_op
)
{
auto
transpose
=
KernelRegistry
::
Global
().
Create
<
TARGET
(
kARM
),
PRECISION
(
kFloat
)
>
(
"transpose"
);
ASSERT_FALSE
(
transpose
.
empty
());
ASSERT_TRUE
(
transpose
.
front
());
}
// Transpose2
TEST
(
transpose2_arm
,
init
)
{
Transpose2Compute
transpose2
;
ASSERT_EQ
(
transpose2
.
precision
(),
PRECISION
(
kFloat
));
ASSERT_EQ
(
transpose2
.
target
(),
TARGET
(
kARM
));
}
TEST
(
transpose2_arm
,
compute_shape_nchw
)
{
Transpose2Compute
transpose2
;
operators
::
TransposeParam
param
;
std
::
vector
<
int
>
axis
{
0
,
2
,
3
,
1
};
param
.
axis
=
axis
;
lite
::
Tensor
input
;
lite
::
Tensor
output
;
lite
::
Tensor
output_ref
;
const
std
::
vector
<
int64_t
>
input_shape
{
1
,
24
,
2
,
2
};
const
std
::
vector
<
int64_t
>
output_shape
{
1
,
2
,
2
,
24
};
DDimLite
ddimInput
(
input_shape
);
DDimLite
ddimOutput
(
output_shape
);
input
.
Resize
(
ddimInput
);
output
.
Resize
(
ddimOutput
);
output_ref
.
Resize
(
ddimOutput
);
for
(
int
i
=
0
;
i
<
input_shape
[
0
]
*
input_shape
[
1
]
*
input_shape
[
2
]
*
input_shape
[
3
];
i
+=
4
)
{
input
.
mutable_data
<
float
>
()[
i
]
=
i
;
input
.
mutable_data
<
float
>
()[
i
+
1
]
=
i
+
1
;
input
.
mutable_data
<
float
>
()[
i
+
2
]
=
i
+
2
;
input
.
mutable_data
<
float
>
()[
i
+
3
]
=
i
+
3
;
}
for
(
int
i
=
0
;
i
<
input_shape
[
0
]
*
input_shape
[
1
]
*
input_shape
[
2
]
*
input_shape
[
3
];
i
+=
4
)
{
}
param
.
x
=
&
input
;
param
.
output
=
&
output
;
// run transpose_compute
transpose2
.
SetParam
(
param
);
transpose2
.
Run
();
// run transpose_compute_ref
param
.
output
=
&
output_ref
;
transpose_compute_ref
(
param
);
auto
*
output_data
=
output
.
data
<
float
>
();
auto
*
output_ref_data
=
output_ref
.
data
<
float
>
();
for
(
int
i
=
0
;
i
<
input_shape
[
0
]
*
input_shape
[
1
]
*
input_shape
[
2
]
*
input_shape
[
3
];
i
+=
4
)
{
EXPECT_NEAR
(
output_data
[
i
],
output_ref_data
[
i
],
1e-5
);
}
}
TEST
(
transpose2
,
retrive_op
)
{
auto
transpose2
=
KernelRegistry
::
Global
().
Create
<
TARGET
(
kARM
),
PRECISION
(
kFloat
)
>
(
"transpose2"
);
ASSERT_FALSE
(
transpose2
.
empty
());
ASSERT_TRUE
(
transpose2
.
front
());
}
}
// namespace arm
}
// namespace kernels
}
// namespace lite
}
// namespace paddle
USE_LITE_KERNEL
(
transpose
,
kARM
,
kFloat
,
kNCHW
,
def
);
USE_LITE_KERNEL
(
transpose2
,
kARM
,
kFloat
,
kNCHW
,
def
);
paddle/fluid/lite/operators/CMakeLists.txt
浏览文件 @
ed5ec09e
...
...
@@ -22,6 +22,7 @@ cc_library(op_params_lite SRCS op_params.cc DEPS ${tensor_lite} any_lite framewo
cc_library
(
dropout_op_lite SRCS dropout_op.cc DEPS
${
op_DEPS
}
)
cc_library
(
concat_op_lite SRCS concat_op.cc DEPS
${
op_DEPS
}
)
cc_library
(
split_op_lite SRCS split_op.cc DEPS
${
op_DEPS
}
)
cc_library
(
transpose_op_lite SRCS transpose_op.cc DEPS
${
op_DEPS
}
)
set
(
ops_lite
conv_op_lite
...
...
@@ -44,6 +45,7 @@ set(ops_lite
dropout_op_lite
concat_op_lite
split_op_lite
transpose_op_lite
PARENT_SCOPE
)
lite_cc_test
(
test_fc_op_lite SRCS fc_op_test.cc
...
...
@@ -61,3 +63,4 @@ lite_cc_test(test_concat_op_lite SRCS concat_op_test.cc DEPS concat_op_lite memo
lite_cc_test
(
test_fusion_elementwise_activation_ops_lite
SRCS fusion_elementwise_activation_ops_test.cc
DEPS fusion_elementwise_activation_ops_lite memory_lite
)
lite_cc_test
(
test_transpose_op_lite SRCS transpose_op_test.cc DEPS transpose_op_lite memory_lite
)
paddle/fluid/lite/operators/op_params.h
浏览文件 @
ed5ec09e
...
...
@@ -203,6 +203,15 @@ struct SplitParam {
std
::
vector
<
int
>
sections
;
};
// For Transpose op
struct
TransposeParam
{
const
lite
::
Tensor
*
x
{};
lite
::
Tensor
*
output
{};
std
::
vector
<
int
>
axis
;
bool
use_mkldnn
{
false
};
std
::
string
data_format
{
"AnyLayout"
};
};
/// ----------------------- element wise operators ----------------------
struct
ElementwiseParam
{
const
lite
::
Tensor
*
X
{};
...
...
paddle/fluid/lite/operators/transpose_op.cc
0 → 100644
浏览文件 @
ed5ec09e
// 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 "paddle/fluid/lite/operators/transpose_op.h"
#include "paddle/fluid/lite/core/op_registry.h"
namespace
paddle
{
namespace
lite
{
namespace
operators
{
// Transpose
bool
TransposeOp
::
CheckShape
()
const
{
CHECK_OR_FALSE
(
param_
.
x
);
CHECK_OR_FALSE
(
param_
.
output
);
auto
x_dims
=
param_
.
x
->
dims
();
auto
x_rank
=
x_dims
.
size
();
std
::
vector
<
int
>
axis
=
param_
.
axis
;
size_t
axis_size
=
axis
.
size
();
// "The input tensor's rank(%d) should be equal to the axis's size(%d)",
// x_rank, axis_size
CHECK_OR_FALSE
(
x_rank
==
axis_size
);
std
::
vector
<
int
>
count
(
axis_size
,
0
);
for
(
size_t
i
=
0
;
i
<
axis_size
;
i
++
)
{
// Each element of Attribute axis should be a unique value
// range from 0 to (dims - 1),
// where the dims is the axis's size
CHECK_OR_FALSE
(
axis
[
i
]
<
static_cast
<
int
>
(
axis_size
)
&&
++
count
[
axis
[
i
]]
==
1
);
}
return
true
;
}
bool
TransposeOp
::
InferShape
()
const
{
CHECK_OR_FALSE
(
param_
.
x
);
CHECK_OR_FALSE
(
param_
.
output
);
auto
x_dims
=
param_
.
x
->
dims
();
auto
x_rank
=
x_dims
.
size
();
std
::
vector
<
int
>
axis
=
param_
.
axis
;
size_t
axis_size
=
axis
.
size
();
// "The input tensor's rank(%d) should be equal to the axis's size(%d)",
// x_rank, axis_size
CHECK_OR_FALSE
(
x_rank
==
axis_size
);
std
::
vector
<
int
>
count
(
axis_size
,
0
);
for
(
size_t
i
=
0
;
i
<
axis_size
;
i
++
)
{
// Each element of Attribute axis should be a unique value
// range from 0 to (dims - 1),
// where the dims is the axis's size
CHECK_OR_FALSE
(
axis
[
i
]
<
static_cast
<
int
>
(
axis_size
)
&&
++
count
[
axis
[
i
]]
==
1
);
}
lite
::
DDim
out_dims
(
x_dims
);
for
(
size_t
i
=
0
;
i
<
axis_size
;
i
++
)
{
out_dims
[
i
]
=
x_dims
[
axis
[
i
]];
}
param_
.
output
->
Resize
(
out_dims
);
return
true
;
}
bool
TransposeOp
::
AttachImpl
(
const
cpp
::
OpDesc
&
op_desc
,
lite
::
Scope
*
scope
)
{
auto
x
=
op_desc
.
Input
(
"X"
).
front
();
auto
out
=
op_desc
.
Output
(
"Out"
).
front
();
CHECK
(
scope
->
FindVar
(
x
));
CHECK
(
scope
->
FindVar
(
out
));
param_
.
x
=
GetVar
<
lite
::
Tensor
>
(
scope
,
x
);
param_
.
output
=
GetMutableVar
<
lite
::
Tensor
>
(
scope
,
out
);
param_
.
axis
=
op_desc
.
GetAttr
<
std
::
vector
<
int
>>
(
"axis"
);
if
(
op_desc
.
HasAttr
(
"use_mkldnn"
))
{
param_
.
use_mkldnn
=
op_desc
.
GetAttr
<
bool
>
(
"use_mkldnn"
);
}
if
(
op_desc
.
HasAttr
(
"data_format"
))
{
param_
.
data_format
=
op_desc
.
GetAttr
<
std
::
string
>
(
"data_format"
);
}
return
true
;
}
// Transpose2
bool
Transpose2Op
::
CheckShape
()
const
{
CHECK_OR_FALSE
(
param_
.
x
);
CHECK_OR_FALSE
(
param_
.
output
);
auto
x_dims
=
param_
.
x
->
dims
();
auto
x_rank
=
x_dims
.
size
();
std
::
vector
<
int
>
axis
=
param_
.
axis
;
size_t
axis_size
=
axis
.
size
();
// "The input tensor's rank(%d) should be equal to the axis's size(%d)",
// x_rank, axis_size
CHECK_OR_FALSE
(
x_rank
==
axis_size
);
std
::
vector
<
int
>
count
(
axis_size
,
0
);
for
(
size_t
i
=
0
;
i
<
axis_size
;
i
++
)
{
// Each element of Attribute axis should be a unique value
// range from 0 to (dims - 1),
// where the dims is the axis's size
CHECK_OR_FALSE
(
axis
[
i
]
<
static_cast
<
int
>
(
axis_size
)
&&
++
count
[
axis
[
i
]]
==
1
);
}
return
true
;
}
bool
Transpose2Op
::
InferShape
()
const
{
CHECK_OR_FALSE
(
param_
.
x
);
CHECK_OR_FALSE
(
param_
.
output
);
auto
x_dims
=
param_
.
x
->
dims
();
auto
x_rank
=
x_dims
.
size
();
std
::
vector
<
int
>
axis
=
param_
.
axis
;
size_t
axis_size
=
axis
.
size
();
// "The input tensor's rank(%d) should be equal to the axis's size(%d)",
// x_rank, axis_size
CHECK_OR_FALSE
(
x_rank
==
axis_size
);
std
::
vector
<
int
>
count
(
axis_size
,
0
);
for
(
size_t
i
=
0
;
i
<
axis_size
;
i
++
)
{
// Each element of Attribute axis should be a unique value
// range from 0 to (dims - 1),
// where the dims is the axis's size
CHECK_OR_FALSE
(
axis
[
i
]
<
static_cast
<
int
>
(
axis_size
)
&&
++
count
[
axis
[
i
]]
==
1
);
}
lite
::
DDim
out_dims
(
x_dims
);
for
(
size_t
i
=
0
;
i
<
axis_size
;
i
++
)
{
out_dims
[
i
]
=
x_dims
[
axis
[
i
]];
}
param_
.
output
->
Resize
(
out_dims
);
return
true
;
}
bool
Transpose2Op
::
AttachImpl
(
const
cpp
::
OpDesc
&
op_desc
,
lite
::
Scope
*
scope
)
{
auto
x
=
op_desc
.
Input
(
"X"
).
front
();
auto
out
=
op_desc
.
Output
(
"Out"
).
front
();
CHECK
(
scope
->
FindVar
(
x
));
CHECK
(
scope
->
FindVar
(
out
));
param_
.
x
=
GetVar
<
lite
::
Tensor
>
(
scope
,
x
);
param_
.
output
=
GetMutableVar
<
lite
::
Tensor
>
(
scope
,
out
);
param_
.
axis
=
op_desc
.
GetAttr
<
std
::
vector
<
int
>>
(
"axis"
);
if
(
op_desc
.
HasAttr
(
"use_mkldnn"
))
{
param_
.
use_mkldnn
=
op_desc
.
GetAttr
<
bool
>
(
"use_mkldnn"
);
}
if
(
op_desc
.
HasAttr
(
"data_format"
))
{
param_
.
data_format
=
op_desc
.
GetAttr
<
std
::
string
>
(
"data_format"
);
}
return
true
;
}
}
// namespace operators
}
// namespace lite
}
// namespace paddle
REGISTER_LITE_OP
(
transpose
,
paddle
::
lite
::
operators
::
TransposeOp
);
REGISTER_LITE_OP
(
transpose2
,
paddle
::
lite
::
operators
::
Transpose2Op
);
paddle/fluid/lite/operators/transpose_op.h
0 → 100644
浏览文件 @
ed5ec09e
// 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 <vector>
#include "paddle/fluid/lite/core/op_lite.h"
#include "paddle/fluid/lite/core/scope.h"
#include "paddle/fluid/lite/utils/all.h"
namespace
paddle
{
namespace
lite
{
namespace
operators
{
// Transpose
class
TransposeOp
:
public
OpLite
{
public:
TransposeOp
()
{}
explicit
TransposeOp
(
const
std
::
string
&
op_type
)
:
OpLite
(
op_type
)
{}
bool
CheckShape
()
const
override
;
bool
InferShape
()
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
"transpose"
;
}
private:
mutable
TransposeParam
param_
;
};
// Transpose2
class
Transpose2Op
:
public
OpLite
{
public:
Transpose2Op
()
{}
explicit
Transpose2Op
(
const
std
::
string
&
op_type
)
:
OpLite
(
op_type
)
{}
bool
CheckShape
()
const
override
;
bool
InferShape
()
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
"transpose2"
;
}
private:
mutable
TransposeParam
param_
;
};
}
// namespace operators
}
// namespace lite
}
// namespace paddle
paddle/fluid/lite/operators/transpose_op_test.cc
0 → 100644
浏览文件 @
ed5ec09e
// 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 "paddle/fluid/lite/operators/transpose_op.h"
#include <gtest/gtest.h>
#include "paddle/fluid/lite/core/op_registry.h"
namespace
paddle
{
namespace
lite
{
namespace
operators
{
// Transpose
TEST
(
transpose_op_lite
,
test
)
{
// prepare variables
Scope
scope
;
auto
*
x
=
scope
.
Var
(
"x"
)
->
GetMutable
<
Tensor
>
();
auto
*
output
=
scope
.
Var
(
"output"
)
->
GetMutable
<
Tensor
>
();
const
int
h
=
10
;
const
int
w
=
20
;
x
->
Resize
(
DDim
(
std
::
vector
<
int64_t
>
({
h
,
w
})));
output
->
Resize
(
DDim
(
std
::
vector
<
int64_t
>
{
w
,
h
}));
// set data
for
(
int
i
=
0
;
i
<
h
*
w
;
i
++
)
{
x
->
mutable_data
<
float
>
()[
i
]
=
i
;
}
for
(
int
i
=
0
;
i
<
w
*
h
;
i
++
)
{
output
->
mutable_data
<
float
>
()[
i
]
=
0.
;
}
// prepare op desc
cpp
::
OpDesc
desc
;
desc
.
SetType
(
"transpose"
);
desc
.
SetInput
(
"X"
,
{
"x"
});
desc
.
SetOutput
(
"Out"
,
{
"output"
});
// axis change for shape in mobilenetssd: [1, 24, 2, 2] => [1, 2, 2, 24]
std
::
vector
<
int
>
axis
{
0
,
2
,
3
,
1
};
desc
.
SetAttr
(
"axis"
,
axis
);
TransposeOp
transpose
(
"transpose"
);
transpose
.
SetValidPlaces
({
Place
{
TARGET
(
kARM
),
PRECISION
(
kFloat
)}});
transpose
.
Attach
(
desc
,
&
scope
);
}
// Transpose2
TEST
(
transpose2_op_lite
,
test
)
{
// prepare variables
Scope
scope
;
auto
*
x
=
scope
.
Var
(
"x"
)
->
GetMutable
<
Tensor
>
();
auto
*
output
=
scope
.
Var
(
"output"
)
->
GetMutable
<
Tensor
>
();
const
int
h
=
10
;
const
int
w
=
20
;
x
->
Resize
(
DDim
(
std
::
vector
<
int64_t
>
({
h
,
w
})));
output
->
Resize
(
DDim
(
std
::
vector
<
int64_t
>
{
w
,
h
}));
// set data
for
(
int
i
=
0
;
i
<
h
*
w
;
i
++
)
{
x
->
mutable_data
<
float
>
()[
i
]
=
i
;
}
for
(
int
i
=
0
;
i
<
w
*
h
;
i
++
)
{
output
->
mutable_data
<
float
>
()[
i
]
=
0.
;
}
// prepare op desc
cpp
::
OpDesc
desc
;
desc
.
SetType
(
"transpose2"
);
desc
.
SetInput
(
"X"
,
{
"x"
});
desc
.
SetOutput
(
"Out"
,
{
"output"
});
// axis change for shape in mobilenetssd: [1, 24, 2, 2] => [1, 2, 2, 24]
std
::
vector
<
int
>
axis
{
0
,
2
,
3
,
1
};
desc
.
SetAttr
(
"axis"
,
axis
);
Transpose2Op
transpose2
(
"transpose2"
);
transpose2
.
SetValidPlaces
({
Place
{
TARGET
(
kARM
),
PRECISION
(
kFloat
)}});
transpose2
.
Attach
(
desc
,
&
scope
);
}
}
// namespace operators
}
// namespace lite
}
// namespace paddle
paddle/fluid/lite/tools/build.sh
浏览文件 @
ed5ec09e
...
...
@@ -75,7 +75,7 @@ function build_single {
}
function
build
{
make lite_compile_deps
-j
$NUM_CORES_FOR_COMPILE
make lite_compile_deps
-j
$NUM_CORES_FOR_COMPILE
}
# It will eagerly test all lite related unittests.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录