Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle-Lite
提交
aef98218
P
Paddle-Lite
项目概览
PaddlePaddle
/
Paddle-Lite
通知
338
Star
4
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
271
列表
看板
标记
里程碑
合并请求
78
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle-Lite
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
271
Issue
271
列表
看板
标记
里程碑
合并请求
78
合并请求
78
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
aef98218
编写于
5月 17, 2018
作者:
朔-望
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update clang-format & update code stylee
上级
333ff13f
变更
70
隐藏空白更改
内联
并排
Showing
70 changed file
with
18839 addition
and
16728 deletion
+18839
-16728
.clang-format
.clang-format
+7
-0
.pre-commit-config.yaml
.pre-commit-config.yaml
+12
-1
src/common/type_define.h
src/common/type_define.h
+27
-26
src/common/types.h
src/common/types.h
+37
-37
src/common/variant.h
src/common/variant.h
+63
-63
src/framework/attribute.cpp
src/framework/attribute.cpp
+1
-1
src/framework/attribute.h
src/framework/attribute.h
+96
-93
src/framework/block_desc.cpp
src/framework/block_desc.cpp
+24
-24
src/framework/block_desc.h
src/framework/block_desc.h
+33
-29
src/framework/data_layout.h
src/framework/data_layout.h
+40
-39
src/framework/data_transform.cpp
src/framework/data_transform.cpp
+63
-58
src/framework/data_transform.h
src/framework/data_transform.h
+7
-7
src/framework/data_type.h
src/framework/data_type.h
+18
-18
src/framework/ddim.cc
src/framework/ddim.cc
+316
-307
src/framework/ddim.h
src/framework/ddim.h
+135
-130
src/framework/dim.h
src/framework/dim.h
+368
-346
src/framework/executor.cpp
src/framework/executor.cpp
+77
-68
src/framework/executor.h
src/framework/executor.h
+15
-15
src/framework/framework.pb.cpp
src/framework/framework.pb.cpp
+8484
-7699
src/framework/framework.pb.h
src/framework/framework.pb.h
+5426
-4802
src/framework/lod_tensor.cc
src/framework/lod_tensor.cc
+298
-274
src/framework/lod_tensor.h
src/framework/lod_tensor.h
+186
-174
src/framework/op_desc.cpp
src/framework/op_desc.cpp
+54
-51
src/framework/op_desc.h
src/framework/op_desc.h
+20
-18
src/framework/op_info.h
src/framework/op_info.h
+70
-66
src/framework/op_kernel_type.h
src/framework/op_kernel_type.h
+38
-30
src/framework/op_proto_maker.h
src/framework/op_proto_maker.h
+4
-4
src/framework/operator.cpp
src/framework/operator.cpp
+17
-17
src/framework/operator.h
src/framework/operator.h
+44
-40
src/framework/paddle_mobile_object.h
src/framework/paddle_mobile_object.h
+9
-9
src/framework/program.cpp
src/framework/program.cpp
+1
-1
src/framework/program.h
src/framework/program.h
+10
-10
src/framework/program_desc.cpp
src/framework/program_desc.cpp
+11
-11
src/framework/program_desc.h
src/framework/program_desc.h
+13
-11
src/framework/scope.cc
src/framework/scope.cc
+100
-97
src/framework/scope.h
src/framework/scope.h
+38
-37
src/framework/selected_rows.h
src/framework/selected_rows.h
+42
-40
src/framework/tensor.h
src/framework/tensor.h
+312
-283
src/framework/tensor_util.cc
src/framework/tensor_util.cc
+185
-179
src/framework/tensor_util.h
src/framework/tensor_util.h
+31
-31
src/framework/var_desc.cpp
src/framework/var_desc.cpp
+3
-3
src/framework/var_desc.h
src/framework/var_desc.h
+53
-52
src/framework/var_type.h
src/framework/var_type.h
+12
-11
src/framework/variable.h
src/framework/variable.h
+70
-68
src/io.cpp
src/io.cpp
+350
-304
src/io.h
src/io.h
+8
-7
src/memory/t_malloc.cc
src/memory/t_malloc.cc
+22
-22
src/memory/t_malloc.h
src/memory/t_malloc.h
+32
-32
src/operators/conv_op.cpp
src/operators/conv_op.cpp
+33
-33
src/operators/conv_op.h
src/operators/conv_op.h
+28
-27
src/operators/kernel/arm/conv_kernel.cpp
src/operators/kernel/arm/conv_kernel.cpp
+146
-131
src/operators/kernel/conv_kernel.h
src/operators/kernel/conv_kernel.h
+9
-8
src/operators/kernel/fpga/conv_kernel.cpp
src/operators/kernel/fpga/conv_kernel.cpp
+7
-6
src/operators/math/im2col.cc
src/operators/math/im2col.cc
+319
-245
src/operators/math/im2col.h
src/operators/math/im2col.h
+88
-75
src/operators/math/math_function.cc
src/operators/math/math_function.cc
+121
-102
src/operators/math/math_function.h
src/operators/math/math_function.h
+22
-20
src/operators/math/vol2col.cc
src/operators/math/vol2col.cc
+208
-175
src/operators/math/vol2col.h
src/operators/math/vol2col.h
+71
-59
src/operators/op_param.cpp
src/operators/op_param.cpp
+20
-19
src/operators/op_param.h
src/operators/op_param.h
+88
-82
src/platform/data_type.h
src/platform/data_type.h
+97
-96
src/platform/macros.h
src/platform/macros.h
+5
-5
tools/android-cmake/android.toolchain.cmake
tools/android-cmake/android.toolchain.cmake
+0
-0
tools/ios-cmake/ios.toolchain.cmake
tools/ios-cmake/ios.toolchain.cmake
+0
-0
tools/pre-commit.hooks/.clang_format.hook
tools/pre-commit.hooks/.clang_format.hook
+0
-0
tools/pre-commit.hooks/.copyright.hook
tools/pre-commit.hooks/.copyright.hook
+124
-0
tools/pre-commit.hooks/clang-format.bash
tools/pre-commit.hooks/clang-format.bash
+15
-0
tools/pre-commit.hooks/copyright.py
tools/pre-commit.hooks/copyright.py
+143
-0
tools/pre-commit.hooks/cpplint.bash
tools/pre-commit.hooks/cpplint.bash
+13
-0
未找到文件。
.clang-format
0 → 100644
浏览文件 @
aef98218
---
Language: Cpp
BasedOnStyle: LLVM
Standard: Cpp11
IndentWidth: 4
NamespaceIndentation: All
...
.pre-commit-config.yaml
浏览文件 @
aef98218
...
@@ -6,6 +6,7 @@ repos:
...
@@ -6,6 +6,7 @@ repos:
files
:
(src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$
files
:
(src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$
-
id
:
remove-tabs
-
id
:
remove-tabs
files
:
(src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$
files
:
(src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$
-
repo
:
https://github.com/pre-commit/pre-commit-hooks
-
repo
:
https://github.com/pre-commit/pre-commit-hooks
sha
:
5bf6c09bfa1297d3692cadd621ef95f1284e33c0
sha
:
5bf6c09bfa1297d3692cadd621ef95f1284e33c0
hooks
:
hooks
:
...
@@ -18,11 +19,21 @@ repos:
...
@@ -18,11 +19,21 @@ repos:
files
:
(src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$
files
:
(src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$
-
id
:
trailing-whitespace
-
id
:
trailing-whitespace
files
:
(src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$
files
:
(src).*\.(md|py|mm|swift|java|c|cc|cxx|cpp|cu|h|hpp|hxx)$
-
repo
:
local
-
repo
:
local
hooks
:
hooks
:
-
id
:
clang-format-with-version-check
-
id
:
clang-format-with-version-check
name
:
clang-format
name
:
clang-format
description
:
Format files with ClangFormat.
description
:
Format files with ClangFormat.
entry
:
bash .clang_format.hook -i
entry
:
bash .
/tools/pre-commit.hooks/.
clang_format.hook -i
language
:
system
language
:
system
files
:
(src).*\.(c|cc|cxx|cpp|h|hpp|hxx)$
files
:
(src).*\.(c|cc|cxx|cpp|h|hpp|hxx)$
#- repo: local
# hooks:
# - id: copyright_checker
# name: copyright_checker
# entry: python ./tools/pre-commit.hooks/.copyright.hook
# language: system
# files: (src).*\.(c|cc|cxx|cpp|cu|h|hpp|hxx|proto|py)$
# exclude: (?!.*third_party)^.*$ | (?!.*book)^.*$
src/common/type_define.h
浏览文件 @
aef98218
...
@@ -23,30 +23,31 @@ SOFTWARE.
...
@@ -23,30 +23,31 @@ SOFTWARE.
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
template
<
typename
Dtype
>
class
OperatorBase
;
template
<
typename
Dtype
>
class
OperatorBase
;
class
OpDesc
;
class
OpDesc
;
class
BlockDesc
;
class
BlockDesc
;
class
InferShapeContext
;
class
InferShapeContext
;
}
}
using
VariableNameMap
=
std
::
map
<
std
::
string
,
std
::
vector
<
std
::
string
>>
;
using
VariableNameMap
=
std
::
map
<
std
::
string
,
std
::
vector
<
std
::
string
>>
;
template
<
typename
Dtype
>
template
<
typename
Dtype
>
using
OpCreator
=
std
::
function
<
framework
::
OperatorBase
<
Dtype
>
*
(
using
OpCreator
=
std
::
function
<
framework
::
OperatorBase
<
Dtype
>
*
(
const
std
::
string
&
/*type*/
,
const
VariableNameMap
&
/*inputs*/
,
const
std
::
string
&
/*type*/
,
const
VariableNameMap
&
/*inputs*/
,
const
VariableNameMap
&
/*outputs*/
,
const
VariableNameMap
&
/*outputs*/
,
const
framework
::
AttributeMap
&
/*attrs*/
)
>
;
const
framework
::
AttributeMap
&
/*attrs*/
)
>
;
using
GradOpMakerFN
=
using
GradOpMakerFN
=
std
::
function
<
std
::
vector
<
std
::
unique_ptr
<
framework
::
OpDesc
>>
(
std
::
function
<
std
::
vector
<
std
::
unique_ptr
<
framework
::
OpDesc
>>
(
const
framework
::
OpDesc
&
,
const
framework
::
OpDesc
&
,
const
std
::
unordered_set
<
std
::
string
>
&
/*no_grad_set*/
,
const
std
::
unordered_set
<
std
::
string
>
&
/*no_grad_set*/
,
std
::
unordered_map
<
std
::
string
,
std
::
string
>
*
/*grad_to_var*/
,
std
::
unordered_map
<
std
::
string
,
std
::
string
>
*
/*grad_to_var*/
,
const
std
::
vector
<
framework
::
BlockDesc
*>
&
grad_block
)
>
;
const
std
::
vector
<
framework
::
BlockDesc
*>
&
grad_block
)
>
;
using
InferVarTypeFN
=
std
::
function
<
void
(
const
framework
::
OpDesc
&
/*op_desc*/
,
using
InferVarTypeFN
=
framework
::
BlockDesc
*
/*block*/
)
>
;
std
::
function
<
void
(
const
framework
::
OpDesc
&
/*op_desc*/
,
framework
::
BlockDesc
*
/*block*/
)
>
;
using
InferShapeFN
=
std
::
function
<
void
(
framework
::
InferShapeContext
*
)
>
;
using
InferShapeFN
=
std
::
function
<
void
(
framework
::
InferShapeContext
*
)
>
;
};
};
src/common/types.h
浏览文件 @
aef98218
...
@@ -19,45 +19,45 @@ SOFTWARE.
...
@@ -19,45 +19,45 @@ SOFTWARE.
#pragma once;
#pragma once;
namespace
paddle_mobile
{
namespace
paddle_mobile
{
enum
class
Precision
:
int
{
FP32
=
0
};
enum
class
Precision
:
int
{
FP32
=
0
};
//! device type
//! device type
enum
DeviceTypeEnum
{
kINVALID
=
-
1
,
kCPU
=
0
,
kFPGA
=
1
,
kGPU_MALI
=
2
};
enum
DeviceTypeEnum
{
kINVALID
=
-
1
,
kCPU
=
0
,
kFPGA
=
1
,
kGPU_MALI
=
2
};
template
<
DeviceTypeEnum
T
>
struct
DeviceType
{};
template
<
DeviceTypeEnum
T
>
struct
DeviceType
{};
typedef
DeviceType
<
kCPU
>
CPU
;
typedef
DeviceType
<
kCPU
>
CPU
;
typedef
DeviceType
<
kFPGA
>
FPGA
;
typedef
DeviceType
<
kFPGA
>
FPGA
;
typedef
DeviceType
<
kGPU_MALI
>
GPU_MALI
;
typedef
DeviceType
<
kGPU_MALI
>
GPU_MALI
;
//! data type
//! data type
enum
DataType
{
enum
DataType
{
PM_INVALID
=
-
1
,
PM_INVALID
=
-
1
,
PM_HALF
=
0
,
PM_HALF
=
0
,
PM_FLOAT
=
1
,
PM_FLOAT
=
1
,
PM_DOUBLE
=
2
,
PM_DOUBLE
=
2
,
PM_INT8
=
3
,
PM_INT8
=
3
,
PM_INT16
=
4
,
PM_INT16
=
4
,
PM_INT32
=
5
,
PM_INT32
=
5
,
PM_INT64
=
6
,
PM_INT64
=
6
,
PM_UINT8
=
7
,
PM_UINT8
=
7
,
PM_UINT16
=
8
,
PM_UINT16
=
8
,
PM_UINT32
=
9
,
PM_UINT32
=
9
,
PM_STRING
=
10
,
PM_STRING
=
10
,
PM_BOOL
=
11
,
PM_BOOL
=
11
,
PM_SHAPE
=
12
,
PM_SHAPE
=
12
,
PM_TENSOR
=
13
PM_TENSOR
=
13
};
};
//!
//!
enum
PMStatus
{
enum
PMStatus
{
PMSuccess
=
0xFF
,
/*!< No errors */
PMSuccess
=
0xFF
,
/*!< No errors */
PMNotInitialized
=
0x01
,
/*!< Data not initialized. */
PMNotInitialized
=
0x01
,
/*!< Data not initialized. */
PMInvalidValue
=
0x02
,
/*!< Incorrect variable value. */
PMInvalidValue
=
0x02
,
/*!< Incorrect variable value. */
PMMemAllocFailed
=
0x03
,
/*!< Memory allocation error. */
PMMemAllocFailed
=
0x03
,
/*!< Memory allocation error. */
PMUnKownError
=
0x04
,
/*!< Unknown error. */
PMUnKownError
=
0x04
,
/*!< Unknown error. */
PMOutOfAuthority
=
0x05
,
/*!< Try to modified data not your own*/
PMOutOfAuthority
=
0x05
,
/*!< Try to modified data not your own*/
PMOutOfMem
=
0x06
,
/*!< OOM error*/
PMOutOfMem
=
0x06
,
/*!< OOM error*/
PMUnImplError
=
0x07
,
/*!< Unimplement error. */
PMUnImplError
=
0x07
,
/*!< Unimplement error. */
PMWrongDevice
=
0x08
/*!< un-correct device. */
PMWrongDevice
=
0x08
/*!< un-correct device. */
};
};
}
}
src/common/variant.h
浏览文件 @
aef98218
...
@@ -21,79 +21,79 @@ SOFTWARE.
...
@@ -21,79 +21,79 @@ SOFTWARE.
#pragma once
#pragma once
namespace
paddle_mobile
{
namespace
paddle_mobile
{
template
<
int
ID
,
typename
Type
>
struct
IDToType
{
typedef
Type
type_t
;
};
template
<
int
ID
,
typename
Type
>
struct
IDToType
{
typedef
Type
type_t
;
};
template
<
typename
F
,
typename
...
Ts
>
struct
VariantHelper
{
template
<
typename
F
,
typename
...
Ts
>
struct
VariantHelper
{
static
const
size_t
size
=
sizeof
(
F
)
>
VariantHelper
<
Ts
...
>::
size
static
const
size_t
size
=
sizeof
(
F
)
>
VariantHelper
<
Ts
...
>::
size
?
sizeof
(
F
)
?
sizeof
(
F
)
:
VariantHelper
<
Ts
...
>::
size
;
:
VariantHelper
<
Ts
...
>::
size
;
inline
static
void
Destroy
(
size_t
id
,
void
*
data
)
{
inline
static
void
Destroy
(
size_t
id
,
void
*
data
)
{
if
(
id
==
typeid
(
F
).
hash_code
())
{
if
(
id
==
typeid
(
F
).
hash_code
())
{
reinterpret_cast
<
F
*>
(
data
)
->~
F
();
reinterpret_cast
<
F
*>
(
data
)
->~
F
();
}
else
{
}
else
{
VariantHelper
<
Ts
...
>::
Destroy
(
id
,
data
);
VariantHelper
<
Ts
...
>::
Destroy
(
id
,
data
);
}
}
}
}
};
};
template
<
typename
F
>
struct
VariantHelper
<
F
>
{
template
<
typename
F
>
struct
VariantHelper
<
F
>
{
static
const
size_t
size
=
sizeof
(
F
);
static
const
size_t
size
=
sizeof
(
F
);
inline
static
void
Destroy
(
size_t
id
,
void
*
data
)
{
inline
static
void
Destroy
(
size_t
id
,
void
*
data
)
{
if
(
id
==
typeid
(
F
).
hash_code
())
{
if
(
id
==
typeid
(
F
).
hash_code
())
{
// reinterpret_cast<F*>(data)->~F();
// reinterpret_cast<F*>(data)->~F();
}
else
{
}
else
{
// std::cout << "未匹配到 " << std::endl;
// std::cout << "未匹配到 " << std::endl;
}
}
}
}
};
};
template
<
size_t
size
>
class
RawData
{
template
<
size_t
size
>
class
RawData
{
public:
public:
char
data
[
size
];
char
data
[
size
];
RawData
()
{}
RawData
()
{}
RawData
(
const
RawData
&
raw_data
)
{
strcpy
(
data
,
raw_data
.
data
);
}
RawData
(
const
RawData
&
raw_data
)
{
strcpy
(
data
,
raw_data
.
data
);
}
// void operator=(const RawData &raw_data){
// void operator=(const RawData &raw_data){
// strcpy(data, raw_data.data);
// strcpy(data, raw_data.data);
// }
// }
};
};
template
<
typename
...
Ts
>
struct
Variant
{
template
<
typename
...
Ts
>
struct
Variant
{
Variant
(
const
Variant
&
variant
)
{
Variant
(
const
Variant
&
variant
)
{
// std::cout << " 赋值构造函数 " << std::endl;
// std::cout << " 赋值构造函数 " << std::endl;
type_id
=
variant
.
type_id
;
type_id
=
variant
.
type_id
;
data
=
variant
.
data
;
data
=
variant
.
data
;
}
}
Variant
()
:
type_id
(
invalid_type
())
{}
Variant
()
:
type_id
(
invalid_type
())
{}
~
Variant
()
{
~
Variant
()
{
// helper::Destroy(type_id, &data);
// helper::Destroy(type_id, &data);
}
}
template
<
typename
T
,
typename
...
Args
>
void
Set
(
Args
&&
...
args
)
{
template
<
typename
T
,
typename
...
Args
>
void
Set
(
Args
&&
...
args
)
{
helper
::
Destroy
(
type_id
,
&
data
);
helper
::
Destroy
(
type_id
,
&
data
);
new
(
&
data
)
T
(
std
::
forward
<
Args
>
(
args
)...);
new
(
&
data
)
T
(
std
::
forward
<
Args
>
(
args
)...);
type_id
=
typeid
(
T
).
hash_code
();
type_id
=
typeid
(
T
).
hash_code
();
}
}
template
<
typename
T
>
T
&
Get
()
const
{
template
<
typename
T
>
T
&
Get
()
const
{
if
(
type_id
==
typeid
(
T
).
hash_code
())
{
if
(
type_id
==
typeid
(
T
).
hash_code
())
{
return
*
const_cast
<
T
*>
(
reinterpret_cast
<
const
T
*>
(
&
data
));
return
*
const_cast
<
T
*>
(
reinterpret_cast
<
const
T
*>
(
&
data
));
}
else
{
}
else
{
// std::cout << " bad cast in variant " << std::endl;
// std::cout << " bad cast in variant " << std::endl;
throw
std
::
bad_cast
();
throw
std
::
bad_cast
();
}
}
}
}
size_t
TypeId
()
const
{
return
type_id
;
}
size_t
TypeId
()
const
{
return
type_id
;
}
private:
private:
static
inline
size_t
invalid_type
()
{
return
typeid
(
void
).
hash_code
();
}
static
inline
size_t
invalid_type
()
{
return
typeid
(
void
).
hash_code
();
}
typedef
VariantHelper
<
Ts
...
>
helper
;
typedef
VariantHelper
<
Ts
...
>
helper
;
size_t
type_id
;
size_t
type_id
;
RawData
<
helper
::
size
>
data
;
RawData
<
helper
::
size
>
data
;
};
};
template
<
typename
T
>
struct
Vistor
{
typedef
T
type_t
;
};
template
<
typename
T
>
struct
Vistor
{
typedef
T
type_t
;
};
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/attribute.cpp
浏览文件 @
aef98218
...
@@ -19,5 +19,5 @@ SOFTWARE.
...
@@ -19,5 +19,5 @@ SOFTWARE.
#include "attribute.h"
#include "attribute.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{}
namespace
framework
{}
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/attribute.h
浏览文件 @
aef98218
...
@@ -22,107 +22,110 @@ SOFTWARE.
...
@@ -22,107 +22,110 @@ SOFTWARE.
#include "framework.pb.h"
#include "framework.pb.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
class
BlockDesc
;
class
BlockDesc
;
class
Attribute
{
class
Attribute
{
public:
public:
static
Attribute
GetAttrValue
(
const
proto
::
OpDesc
::
Attr
&
attr_desc
)
{
static
Attribute
// std::cout << "begin get attr value" << std::endl;
GetAttrValue
(
const
proto
::
OpDesc
::
Attr
&
attr_desc
)
{
Attribute
attr
;
// std::cout << "begin get attr value" << std::endl;
switch
(
attr_desc
.
type
())
{
Attribute
attr
;
case
proto
::
AttrType
::
BOOLEAN
:
{
switch
(
attr_desc
.
type
())
{
attr
.
Set
<
bool
>
(
attr_desc
.
b
());
case
proto
::
AttrType
::
BOOLEAN
:
{
break
;
attr
.
Set
<
bool
>
(
attr_desc
.
b
());
}
break
;
case
proto
::
AttrType
::
INT
:
{
}
attr
.
Set
<
int
>
(
attr_desc
.
i
());
case
proto
::
AttrType
::
INT
:
{
break
;
attr
.
Set
<
int
>
(
attr_desc
.
i
());
}
break
;
case
proto
::
AttrType
::
FLOAT
:
{
}
attr
.
Set
<
float
>
(
attr_desc
.
f
());
case
proto
::
AttrType
::
FLOAT
:
{
break
;
attr
.
Set
<
float
>
(
attr_desc
.
f
());
}
break
;
case
proto
::
AttrType
::
STRING
:
{
}
attr
.
Set
<
std
::
string
>
(
attr_desc
.
s
());
case
proto
::
AttrType
::
STRING
:
{
break
;
attr
.
Set
<
std
::
string
>
(
attr_desc
.
s
());
}
break
;
case
proto
::
AttrType
::
BOOLEANS
:
{
}
std
::
vector
<
bool
>
val
(
attr_desc
.
bools_size
());
case
proto
::
AttrType
::
BOOLEANS
:
{
for
(
int
i
=
0
;
i
<
attr_desc
.
bools_size
();
++
i
)
{
std
::
vector
<
bool
>
val
(
attr_desc
.
bools_size
());
val
[
i
]
=
attr_desc
.
bools
(
i
);
for
(
int
i
=
0
;
i
<
attr_desc
.
bools_size
();
++
i
)
{
}
val
[
i
]
=
attr_desc
.
bools
(
i
);
attr
.
Set
<
std
::
vector
<
bool
>>
(
val
);
}
break
;
attr
.
Set
<
std
::
vector
<
bool
>>
(
val
);
}
break
;
case
proto
::
AttrType
::
INTS
:
{
}
std
::
vector
<
int
>
val
(
attr_desc
.
ints_size
());
case
proto
::
AttrType
::
INTS
:
{
for
(
int
i
=
0
;
i
<
attr_desc
.
ints_size
();
++
i
)
{
std
::
vector
<
int
>
val
(
attr_desc
.
ints_size
());
val
[
i
]
=
attr_desc
.
ints
(
i
);
for
(
int
i
=
0
;
i
<
attr_desc
.
ints_size
();
++
i
)
{
}
val
[
i
]
=
attr_desc
.
ints
(
i
);
attr
.
Set
<
std
::
vector
<
int
>>
(
val
);
}
break
;
attr
.
Set
<
std
::
vector
<
int
>>
(
val
);
}
break
;
case
proto
::
AttrType
::
FLOATS
:
{
}
std
::
vector
<
float
>
val
(
attr_desc
.
floats_size
());
case
proto
::
AttrType
::
FLOATS
:
{
for
(
int
i
=
0
;
i
<
attr_desc
.
floats_size
();
++
i
)
{
std
::
vector
<
float
>
val
(
attr_desc
.
floats_size
());
val
[
i
]
=
attr_desc
.
floats
(
i
);
for
(
int
i
=
0
;
i
<
attr_desc
.
floats_size
();
++
i
)
{
}
val
[
i
]
=
attr_desc
.
floats
(
i
);
attr
.
Set
<
std
::
vector
<
float
>>
(
val
);
}
break
;
attr
.
Set
<
std
::
vector
<
float
>>
(
val
);
}
break
;
case
proto
::
AttrType
::
STRINGS
:
{
}
std
::
vector
<
std
::
string
>
val
(
attr_desc
.
strings_size
());
case
proto
::
AttrType
::
STRINGS
:
{
for
(
int
i
=
0
;
i
<
attr_desc
.
strings_size
();
++
i
)
{
std
::
vector
<
std
::
string
>
val
(
attr_desc
.
strings_size
());
val
[
i
]
=
attr_desc
.
strings
(
i
);
for
(
int
i
=
0
;
i
<
attr_desc
.
strings_size
();
++
i
)
{
}
val
[
i
]
=
attr_desc
.
strings
(
i
);
attr
.
Set
<
std
::
vector
<
std
::
string
>>
(
val
);
}
break
;
attr
.
Set
<
std
::
vector
<
std
::
string
>>
(
val
);
}
break
;
case
proto
::
AttrType
::
LONG
:
{
}
attr
.
Set
<
int64_t
>
(
attr_desc
.
l
());
case
proto
::
AttrType
::
LONG
:
{
break
;
attr
.
Set
<
int64_t
>
(
attr_desc
.
l
());
}
break
;
default:
}
// std::cout << " not support " << std::endl;
default:
break
;
// std::cout << " not support " << std::endl;
}
break
;
// std::cout << "end get attr value" << std::endl;
}
return
attr
;
// std::cout << "end get attr value" << std::endl;
}
return
attr
;
}
Attribute
()
{}
Attribute
()
{}
template
<
typename
T
,
typename
...
Args
>
Attribute
&
Set
(
Args
&&
...
args
)
{
template
<
typename
T
,
typename
...
Args
>
variant_
.
Set
<
T
>
(
args
...);
Attribute
&
Set
(
Args
&&
...
args
)
{
return
*
this
;
variant_
.
Set
<
T
>
(
args
...);
}
return
*
this
;
}
template
<
typename
T
>
T
&
Get
()
const
{
return
variant_
.
Get
<
T
>
();
}
template
<
typename
T
>
T
&
Get
()
const
{
return
variant_
.
Get
<
T
>
();
}
private:
private:
Variant
<
int
,
float
,
std
::
string
,
std
::
vector
<
int
>
,
std
::
vector
<
floa
t
>
,
Variant
<
int
,
float
,
std
::
string
,
std
::
vector
<
in
t
>
,
std
::
vector
<
std
::
string
>
,
bool
,
std
::
vector
<
bool
>
,
BlockDesc
*
,
std
::
vector
<
float
>
,
std
::
vector
<
std
::
string
>
,
bool
,
int64_t
>
std
::
vector
<
bool
>
,
BlockDesc
*
,
int64_t
>
variant_
;
variant_
;
};
};
using
AttributeMap
=
std
::
unordered_map
<
std
::
string
,
Attribute
>
;
using
AttributeMap
=
std
::
unordered_map
<
std
::
string
,
Attribute
>
;
class
AttrReader
{
class
AttrReader
{
public:
public:
explicit
AttrReader
(
const
AttributeMap
&
attrs
)
:
attrs_
(
attrs
)
{}
explicit
AttrReader
(
const
AttributeMap
&
attrs
)
:
attrs_
(
attrs
)
{}
template
<
typename
T
>
inline
T
Get
(
const
std
::
string
&
name
)
const
{
template
<
typename
T
>
inline
T
Get
(
const
std
::
string
&
name
)
const
{
// PADDLE_ENFORCE(attrs_.count(name) != 0, "%s should be in
// PADDLE_ENFORCE(attrs_.count(name) != 0, "%s should
// AttributeMap",
// be in
// name);
// AttributeMap",
return
((
Attribute
)
attrs_
.
at
(
name
)).
Get
<
T
>
();
// name);
}
return
((
Attribute
)
attrs_
.
at
(
name
)).
Get
<
T
>
();
}
private:
private:
const
AttributeMap
&
attrs_
;
const
AttributeMap
&
attrs_
;
};
};
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/block_desc.cpp
浏览文件 @
aef98218
...
@@ -19,32 +19,32 @@ SOFTWARE.
...
@@ -19,32 +19,32 @@ SOFTWARE.
#include "block_desc.h"
#include "block_desc.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
std
::
vector
<
std
::
shared_ptr
<
VarDesc
>>
BlockDesc
::
Vars
()
const
{
std
::
vector
<
std
::
shared_ptr
<
VarDesc
>>
BlockDesc
::
Vars
()
const
{
std
::
vector
<
std
::
shared_ptr
<
VarDesc
>>
res
;
std
::
vector
<
std
::
shared_ptr
<
VarDesc
>>
res
;
for
(
const
auto
&
p
:
vars_
)
{
for
(
const
auto
&
p
:
vars_
)
{
res
.
push_back
(
p
.
second
);
res
.
push_back
(
p
.
second
);
}
}
return
res
;
return
res
;
}
}
std
::
vector
<
std
::
shared_ptr
<
OpDesc
>>
BlockDesc
::
Ops
()
const
{
std
::
vector
<
std
::
shared_ptr
<
OpDesc
>>
BlockDesc
::
Ops
()
const
{
std
::
vector
<
std
::
shared_ptr
<
OpDesc
>>
res
;
std
::
vector
<
std
::
shared_ptr
<
OpDesc
>>
res
;
for
(
const
auto
&
op
:
ops_
)
{
for
(
const
auto
&
op
:
ops_
)
{
res
.
push_back
(
op
);
res
.
push_back
(
op
);
}
}
return
res
;
return
res
;
}
}
BlockDesc
::
BlockDesc
(
const
proto
::
BlockDesc
&
desc
)
:
desc_
(
desc
)
{
BlockDesc
::
BlockDesc
(
const
proto
::
BlockDesc
&
desc
)
:
desc_
(
desc
)
{
for
(
const
proto
::
VarDesc
&
var_desc
:
desc_
.
vars
())
{
for
(
const
proto
::
VarDesc
&
var_desc
:
desc_
.
vars
())
{
vars_
[
var_desc
.
name
()].
reset
(
new
VarDesc
(
var_desc
));
vars_
[
var_desc
.
name
()].
reset
(
new
VarDesc
(
var_desc
));
}
}
for
(
const
proto
::
OpDesc
&
op_desc
:
desc_
.
ops
())
{
for
(
const
proto
::
OpDesc
&
op_desc
:
desc_
.
ops
())
{
ops_
.
emplace_back
(
new
framework
::
OpDesc
(
op_desc
));
ops_
.
emplace_back
(
new
framework
::
OpDesc
(
op_desc
));
}
}
}
}
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/block_desc.h
浏览文件 @
aef98218
...
@@ -24,46 +24,50 @@ SOFTWARE.
...
@@ -24,46 +24,50 @@ SOFTWARE.
#include "var_desc.h"
#include "var_desc.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
class
BlockDesc
:
PaddleMobileObject
{
class
BlockDesc
:
PaddleMobileObject
{
public:
public:
BlockDesc
(
const
proto
::
BlockDesc
&
desc
);
BlockDesc
(
const
proto
::
BlockDesc
&
desc
);
const
int
&
ID
()
const
{
return
desc_
.
idx
();
}
const
int
&
ID
()
const
{
return
desc_
.
idx
();
}
const
int
&
Parent
()
const
{
return
desc_
.
parent_idx
();
}
const
int
&
Parent
()
const
{
return
desc_
.
parent_idx
();
}
bool
operator
==
(
const
paddle_mobile
::
framework
::
BlockDesc
&
in_block
)
const
{
bool
operator
==
(
return
this
->
ID
()
==
in_block
.
ID
()
&&
this
->
Parent
()
==
in_block
.
Parent
();
const
paddle_mobile
::
framework
::
BlockDesc
&
in_block
)
const
{
}
return
this
->
ID
()
==
in_block
.
ID
()
&&
this
->
Parent
()
==
in_block
.
Parent
();
}
bool
operator
<
(
const
paddle_mobile
::
framework
::
BlockDesc
&
in_block
)
const
{
bool
operator
<
(
return
this
->
ID
()
<
in_block
.
ID
()
&&
this
->
Parent
()
<
in_block
.
Parent
();
const
paddle_mobile
::
framework
::
BlockDesc
&
in_block
)
const
{
}
return
this
->
ID
()
<
in_block
.
ID
()
&&
this
->
Parent
()
<
in_block
.
Parent
();
}
std
::
vector
<
std
::
shared_ptr
<
VarDesc
>>
Vars
()
const
;
std
::
vector
<
std
::
shared_ptr
<
VarDesc
>>
Vars
()
const
;
std
::
vector
<
std
::
shared_ptr
<
OpDesc
>>
Ops
()
const
;
std
::
vector
<
std
::
shared_ptr
<
OpDesc
>>
Ops
()
const
;
private:
private:
proto
::
BlockDesc
desc_
;
proto
::
BlockDesc
desc_
;
std
::
vector
<
std
::
shared_ptr
<
OpDesc
>>
ops_
;
std
::
vector
<
std
::
shared_ptr
<
OpDesc
>>
ops_
;
std
::
unordered_map
<
std
::
string
,
std
::
shared_ptr
<
VarDesc
>>
vars_
;
std
::
unordered_map
<
std
::
string
,
std
::
shared_ptr
<
VarDesc
>>
vars_
;
};
};
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
namespace
std
{
namespace
std
{
template
<
>
struct
hash
<
paddle_mobile
::
framework
::
BlockDesc
>
{
template
<
>
struct
hash
<
paddle_mobile
::
framework
::
BlockDesc
>
{
typedef
paddle_mobile
::
framework
::
BlockDesc
argument_type
;
typedef
paddle_mobile
::
framework
::
BlockDesc
argument_type
;
typedef
std
::
size_t
result_type
;
typedef
std
::
size_t
result_type
;
result_type
operator
()(
argument_type
const
&
s
)
const
noexcept
{
result_type
operator
()(
argument_type
const
&
s
)
const
noexcept
{
result_type
const
h1
(
std
::
hash
<
int
>
{}(
s
.
ID
()));
result_type
const
h1
(
std
::
hash
<
int
>
{}(
s
.
ID
()));
result_type
const
h2
(
std
::
hash
<
int
>
{}(
s
.
ID
()));
result_type
const
h2
(
std
::
hash
<
int
>
{}(
s
.
ID
()));
return
h1
^
(
h2
<<
1
);
return
h1
^
(
h2
<<
1
);
}
}
};
};
}
// namespace std
}
// namespace std
src/framework/data_layout.h
浏览文件 @
aef98218
...
@@ -19,49 +19,50 @@ limitations under the License. */
...
@@ -19,49 +19,50 @@ limitations under the License. */
#include <string>
#include <string>
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
enum
class
DataLayout
{
enum
class
DataLayout
{
kNHWC
=
0
,
kNHWC
=
0
,
kNCHW
=
1
,
kNCHW
=
1
,
kAnyLayout
=
2
,
kAnyLayout
=
2
,
};
};
inline
DataLayout
StringToDataLayout
(
const
std
::
string
&
str
)
{
inline
DataLayout
StringToDataLayout
(
const
std
::
string
&
str
)
{
std
::
string
s
(
str
);
std
::
string
s
(
str
);
for
(
size_t
i
=
0
;
i
<
s
.
size
();
++
i
)
{
for
(
size_t
i
=
0
;
i
<
s
.
size
();
++
i
)
{
s
[
i
]
=
toupper
(
s
[
i
]);
s
[
i
]
=
toupper
(
s
[
i
]);
}
}
if
(
s
==
"NHWC"
)
{
if
(
s
==
"NHWC"
)
{
return
DataLayout
::
kNHWC
;
return
DataLayout
::
kNHWC
;
}
else
if
(
s
==
"NCHW"
)
{
}
else
if
(
s
==
"NCHW"
)
{
return
DataLayout
::
kNCHW
;
return
DataLayout
::
kNCHW
;
}
else
if
(
s
==
"ANYLAYOUT"
)
{
}
else
if
(
s
==
"ANYLAYOUT"
)
{
return
DataLayout
::
kAnyLayout
;
return
DataLayout
::
kAnyLayout
;
}
else
{
}
else
{
// std::cout << "Unknown storage order string: %s", s;
// std::cout << "Unknown storage order string: %s", s;
}
}
}
}
inline
std
::
string
DataLayoutToString
(
const
DataLayout
&
data_layout
)
{
inline
std
::
string
DataLayoutToString
(
const
DataLayout
&
data_layout
)
{
switch
(
data_layout
)
{
switch
(
data_layout
)
{
case
DataLayout
::
kNHWC
:
case
DataLayout
::
kNHWC
:
return
"NHWC"
;
return
"NHWC"
;
case
DataLayout
::
kNCHW
:
case
DataLayout
::
kNCHW
:
return
"NCHW"
;
return
"NCHW"
;
case
DataLayout
::
kAnyLayout
:
case
DataLayout
::
kAnyLayout
:
return
"ANY_LAYOUT"
;
return
"ANY_LAYOUT"
;
default:
default:
break
;
break
;
// std::cout << "unknown DataLayou %d", data_layout;
// std::cout << "unknown DataLayou %d", data_layout;
}
}
}
}
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
DataLayout
&
l
)
{
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
out
<<
DataLayoutToString
(
l
);
const
DataLayout
&
l
)
{
return
out
;
out
<<
DataLayoutToString
(
l
);
}
return
out
;
}
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/data_transform.cpp
浏览文件 @
aef98218
...
@@ -21,67 +21,72 @@ SOFTWARE.
...
@@ -21,67 +21,72 @@ SOFTWARE.
#include "data_transform.h"
#include "data_transform.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
static
void
PassTensorData
(
Tensor
*
from
,
Tensor
*
to
)
{
static
void
PassTensorData
(
Tensor
*
from
,
Tensor
*
to
)
{
to
->
ShareDataWith
(
*
from
);
to
->
ShareDataWith
(
*
from
);
*
from
=
Tensor
();
*
from
=
Tensor
();
}
}
void
DataTransform
(
const
OpKernelType
&
expected_kernel_type
,
void
DataTransform
(
const
OpKernelType
&
expected_kernel_type
,
const
OpKernelType
&
kernel_type_for_var
,
const
OpKernelType
&
kernel_type_for_var
,
const
Tensor
&
input_tensor
,
Tensor
*
output_tensor
)
{
const
Tensor
&
input_tensor
,
Tensor
*
output_tensor
)
{
bool
transformed
=
false
;
bool
transformed
=
false
;
Tensor
in
;
Tensor
in
;
in
.
ShareDataWith
(
input_tensor
);
in
.
ShareDataWith
(
input_tensor
);
Tensor
out
;
Tensor
out
;
// // do layout transform
// // do layout transform
// if (NeedTransformLayout(expected_kernel_type.data_layout_,
// if (NeedTransformLayout(expected_kernel_type.data_layout_,
// kernel_type_for_var.data_layout_)) {
// kernel_type_for_var.data_layout_)) {
// TransDataLayout(kernel_type_for_var, expected_kernel_type, in, &out);
// TransDataLayout(kernel_type_for_var, expected_kernel_type, in,
// transformed = true;
// &out);
// PassTensorData(&out, &in);
// transformed = true;
// }
// PassTensorData(&out, &in);
//
// }
// // do data type transform
//
// if (expected_kernel_type.data_type_ != kernel_type_for_var.data_type_) {
// // do data type transform
// TransDataType(kernel_type_for_var, expected_kernel_type, in, &out);
// if (expected_kernel_type.data_type_ !=
// transformed = true;
// kernel_type_for_var.data_type_) {
// PassTensorData(&out, &in);
// TransDataType(kernel_type_for_var, expected_kernel_type, in,
// }
// &out);
//
// transformed = true;
// // do device transform
// PassTensorData(&out, &in);
// if (!platform::is_same_place(kernel_type_for_var.place_,
// }
// expected_kernel_type.place_)) {
//
// TransDataDevice(in, expected_kernel_type.place_, &out);
// // do device transform
// transformed = true;
// if (!platform::is_same_place(kernel_type_for_var.place_,
// PassTensorData(&out, &in);
// expected_kernel_type.place_)) {
// }
// TransDataDevice(in, expected_kernel_type.place_, &out);
//
// transformed = true;
// PADDLE_ENFORCE(transformed, "No transform is applied, please check!");
// PassTensorData(&out, &in);
// get output data
// }
output_tensor
->
ShareDataWith
(
in
);
//
}
// PADDLE_ENFORCE(transformed, "No transform is applied, please
// check!");
// get output data
output_tensor
->
ShareDataWith
(
in
);
}
void
CopyVariableWithTensor
(
const
Variable
&
in_var
,
const
Tensor
&
tensor
,
void
CopyVariableWithTensor
(
const
Variable
&
in_var
,
Variable
&
out_var
)
{
const
Tensor
&
tensor
,
Variable
&
out_var
)
{
// if (in_var.IsType<LoDTensor>()) {
// if (in_var.IsType<LoDTensor>()) {
// auto& in_lod_tensor = in_var.Get<LoDTensor>();
// auto& in_lod_tensor = in_var.Get<LoDTensor>();
// auto* tran_lod_tensor = out_var.GetMutable<LoDTensor>();
// auto* tran_lod_tensor = out_var.GetMutable<LoDTensor>();
// tran_lod_tensor->set_lod(in_lod_tensor.lod());
// tran_lod_tensor->set_lod(in_lod_tensor.lod());
// tran_lod_tensor->set_layout(in_lod_tensor.layout());
// tran_lod_tensor->set_layout(in_lod_tensor.layout());
// tran_lod_tensor->ShareDataWith(tensor);
// tran_lod_tensor->ShareDataWith(tensor);
// } else if (in_var.IsType<SelectedRows>()) {
// } else if (in_var.IsType<SelectedRows>()) {
// auto& in_selected_rows = in_var.Get<SelectedRows>();
// auto& in_selected_rows = in_var.Get<SelectedRows>();
// auto* trans_selected_rows = out_var.GetMutable<SelectedRows>();
// auto* trans_selected_rows =
// trans_selected_rows->set_height(in_selected_rows.height());
// out_var.GetMutable<SelectedRows>();
// trans_selected_rows->set_rows(in_selected_rows.rows());
// trans_selected_rows->set_height(in_selected_rows.height());
// trans_selected_rows->mutable_value()->ShareDataWith(tensor);
// trans_selected_rows->set_rows(in_selected_rows.rows());
// } else {
// trans_selected_rows->mutable_value()->ShareDataWith(tensor);
// PADDLE_THROW("unknown var type");
// } else {
// }
// PADDLE_THROW("unknown var type");
}
// }
}
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/data_transform.h
浏览文件 @
aef98218
...
@@ -28,14 +28,14 @@ SOFTWARE.
...
@@ -28,14 +28,14 @@ SOFTWARE.
#include "variable.h"
#include "variable.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
void
DataTransform
(
const
OpKernelType
&
expected_kernel_type
,
void
DataTransform
(
const
OpKernelType
&
expected_kernel_type
,
const
OpKernelType
&
kernel_type_for_var
,
const
OpKernelType
&
kernel_type_for_var
,
const
Tensor
&
input_tensor
,
Tensor
*
out
);
const
Tensor
&
input_tensor
,
Tensor
*
out
);
void
CopyVariableWithTensor
(
const
Variable
&
in_var
,
const
Tensor
&
tenso
r
,
void
CopyVariableWithTensor
(
const
Variable
&
in_va
r
,
Variable
&
out_var
);
const
Tensor
&
tensor
,
Variable
&
out_var
);
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/data_type.h
浏览文件 @
aef98218
...
@@ -21,23 +21,23 @@ SOFTWARE.
...
@@ -21,23 +21,23 @@ SOFTWARE.
#include "framework.pb.h"
#include "framework.pb.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
// inline proto::VarType::Type ToDataType(std::type_index type) {
// inline proto::VarType::Type ToDataType(std::type_index type) {
// using namespace paddle_mobile::framework::proto;
// using namespace paddle_mobile::framework::proto;
// if (typeid(float).hash_code() == type.hash_code()) {
// if (typeid(float).hash_code() == type.hash_code()) {
// return proto::VarType::FP32;
// return proto::VarType::FP32;
// } else if (typeid(double).hash_code() == type.hash_code()) {
// } else if (typeid(double).hash_code() == type.hash_code()) {
// return proto::VarType::FP64;
// return proto::VarType::FP64;
// } else if (typeid(int).hash_code() == type.hash_code()) {
// } else if (typeid(int).hash_code() == type.hash_code()) {
// return proto::VarType::INT32;
// return proto::VarType::INT32;
// } else if (typeid(int64_t).hash_code() == type.hash_code()) {
// } else if (typeid(int64_t).hash_code() == type.hash_code()) {
// return proto::VarType::INT64;
// return proto::VarType::INT64;
// } else if (typeid(bool).hash_code() == type.hash_code()) {
// } else if (typeid(bool).hash_code() == type.hash_code()) {
// return proto::VarType::BOOL;
// return proto::VarType::BOOL;
// } else {
// } else {
//// PADDLE_THROW("Not supported");
//// PADDLE_THROW("Not supported");
// }
// }
// }
// }
}
}
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/ddim.cc
浏览文件 @
aef98218
...
@@ -15,311 +15,320 @@ limitations under the License. */
...
@@ -15,311 +15,320 @@ limitations under the License. */
#include "ddim.h"
#include "ddim.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
/// @cond HIDDEN
/// @cond HIDDEN
template
<
int
i
>
Dim
<
i
>
make_dim
(
const
int64_t
*
d
)
{
template
<
int
i
>
Dim
<
i
>
make_dim
(
const
int64_t
*
d
)
{
return
Dim
<
i
>
(
*
d
,
make_dim
<
i
-
1
>
(
d
+
1
));
return
Dim
<
i
>
(
*
d
,
make_dim
<
i
-
1
>
(
d
+
1
));
}
}
template
<
>
Dim
<
0
>
make_dim
<
0
>
(
const
int64_t
*
d
)
{
return
Dim
<
0
>
(
*
d
);
}
template
<
>
Dim
<
0
>
make_dim
<
0
>
(
const
int64_t
*
d
)
{
return
Dim
<
0
>
(
*
d
);
}
void
make_ddim
(
DDim
&
ddim
,
const
int64_t
*
dims
,
int
n
)
{
void
make_ddim
(
DDim
&
ddim
,
const
int64_t
*
dims
,
int
n
)
{
switch
(
n
)
{
switch
(
n
)
{
case
0
:
case
0
:
ddim
=
make_dim
<
0
>
(
dims
);
ddim
=
make_dim
<
0
>
(
dims
);
break
;
break
;
case
1
:
case
1
:
ddim
=
make_dim
<
1
>
(
dims
);
ddim
=
make_dim
<
1
>
(
dims
);
break
;
break
;
case
2
:
case
2
:
ddim
=
make_dim
<
2
>
(
dims
);
ddim
=
make_dim
<
2
>
(
dims
);
break
;
break
;
case
3
:
case
3
:
ddim
=
make_dim
<
3
>
(
dims
);
ddim
=
make_dim
<
3
>
(
dims
);
break
;
break
;
case
4
:
case
4
:
ddim
=
make_dim
<
4
>
(
dims
);
ddim
=
make_dim
<
4
>
(
dims
);
break
;
break
;
case
5
:
case
5
:
ddim
=
make_dim
<
5
>
(
dims
);
ddim
=
make_dim
<
5
>
(
dims
);
break
;
break
;
case
6
:
case
6
:
ddim
=
make_dim
<
6
>
(
dims
);
ddim
=
make_dim
<
6
>
(
dims
);
break
;
break
;
case
7
:
case
7
:
ddim
=
make_dim
<
7
>
(
dims
);
ddim
=
make_dim
<
7
>
(
dims
);
break
;
break
;
case
8
:
case
8
:
ddim
=
make_dim
<
8
>
(
dims
);
ddim
=
make_dim
<
8
>
(
dims
);
break
;
break
;
case
9
:
case
9
:
ddim
=
make_dim
<
9
>
(
dims
);
ddim
=
make_dim
<
9
>
(
dims
);
break
;
break
;
default:
default:
// std::cout << "Dynamic dimensions must have between [1, 9]
// std::cout << "Dynamic dimensions must have between [1,
// dimensions.";
// 9]
break
;
// dimensions.";
}
break
;
}
}
}
/// @endcond
/// @endcond
DDim
make_ddim
(
std
::
initializer_list
<
int64_t
>
dims
)
{
DDim
result
(
make_dim
(
0
));
DDim
make_ddim
(
std
::
initializer_list
<
int64_t
>
dims
)
{
make_ddim
(
result
,
dims
.
begin
(),
dims
.
size
());
DDim
result
(
make_dim
(
0
));
return
result
;
make_ddim
(
result
,
dims
.
begin
(),
dims
.
size
());
}
return
result
;
}
DDim
make_ddim
(
const
std
::
vector
<
int64_t
>
&
dims
)
{
DDim
result
(
make_dim
(
0
));
DDim
make_ddim
(
const
std
::
vector
<
int64_t
>
&
dims
)
{
make_ddim
(
result
,
&
dims
[
0
],
dims
.
size
());
DDim
result
(
make_dim
(
0
));
return
result
;
make_ddim
(
result
,
&
dims
[
0
],
dims
.
size
());
}
return
result
;
}
DDim
make_ddim
(
const
std
::
vector
<
int
>
&
dims
)
{
std
::
vector
<
int64_t
>
res
(
dims
.
size
());
DDim
make_ddim
(
const
std
::
vector
<
int
>
&
dims
)
{
std
::
transform
(
dims
.
begin
(),
dims
.
end
(),
res
.
begin
(),
std
::
vector
<
int64_t
>
res
(
dims
.
size
());
[](
int
d
)
{
return
static_cast
<
int64_t
>
(
d
);
});
std
::
transform
(
dims
.
begin
(),
dims
.
end
(),
res
.
begin
(),
return
make_ddim
(
res
);
[](
int
d
)
{
return
static_cast
<
int64_t
>
(
d
);
});
}
return
make_ddim
(
res
);
}
/// @cond HIDDEN
// XXX For some reason, putting this in an anonymous namespace causes errors
/// @cond HIDDEN
struct
DynamicMutableIndexer
:
Vistor
<
int64_t
&>
{
// XXX For some reason, putting this in an anonymous namespace causes
public:
// errors
explicit
DynamicMutableIndexer
(
int
idx
)
:
idx_
(
idx
)
{}
struct
DynamicMutableIndexer
:
Vistor
<
int64_t
&>
{
public:
template
<
int
D
>
int64_t
&
operator
()(
Dim
<
D
>
&
dim
)
const
{
return
dim
[
idx_
];
}
explicit
DynamicMutableIndexer
(
int
idx
)
:
idx_
(
idx
)
{}
private:
template
<
int
D
>
int64_t
&
operator
()(
Dim
<
D
>
&
dim
)
const
{
int
idx_
;
return
dim
[
idx_
];
};
}
struct
DynamicConstIndexer
:
public
Vistor
<
int64_t
>
{
private:
public:
int
idx_
;
explicit
DynamicConstIndexer
(
int
idx
)
:
idx_
(
idx
)
{}
};
template
<
int
D
>
int64_t
operator
()(
const
Dim
<
D
>
&
dim
)
const
{
struct
DynamicConstIndexer
:
public
Vistor
<
int64_t
>
{
return
dim
[
idx_
];
public:
}
explicit
DynamicConstIndexer
(
int
idx
)
:
idx_
(
idx
)
{}
private:
template
<
int
D
>
int64_t
operator
()(
const
Dim
<
D
>
&
dim
)
const
{
int
idx_
;
return
dim
[
idx_
];
};
}
/// @endcond
private:
int
idx_
;
int64_t
&
DDim
::
operator
[](
int
idx
)
{
};
return
DDim
::
ApplyVistor
(
DynamicMutableIndexer
(
idx
),
*
this
);
}
/// @endcond
int64_t
DDim
::
operator
[](
int
idx
)
const
{
int64_t
&
DDim
::
operator
[](
int
idx
)
{
return
DDim
::
ApplyVistor
(
DynamicConstIndexer
(
idx
),
*
this
);
return
DDim
::
ApplyVistor
(
DynamicMutableIndexer
(
idx
),
*
this
);
}
}
int
DDim
::
size
()
const
{
return
arity
(
*
this
);
}
int64_t
DDim
::
operator
[](
int
idx
)
const
{
return
DDim
::
ApplyVistor
(
DynamicConstIndexer
(
idx
),
*
this
);
bool
DDim
::
operator
==
(
DDim
d
)
const
{
}
// if (var.which() != d.getVar().which()) {
// return false;
int
DDim
::
size
()
const
{
return
arity
(
*
this
);
}
// } else {
std
::
vector
<
int64_t
>
v1
=
vectorize
(
*
this
);
bool
DDim
::
operator
==
(
DDim
d
)
const
{
std
::
vector
<
int64_t
>
v2
=
vectorize
(
d
);
// if (var.which() != d.getVar().which()) {
// return false;
for
(
unsigned
int
i
=
0
;
i
<
v1
.
size
();
i
++
)
{
// } else {
if
(
v1
[
i
]
!=
v2
[
i
])
{
std
::
vector
<
int64_t
>
v1
=
vectorize
(
*
this
);
return
false
;
std
::
vector
<
int64_t
>
v2
=
vectorize
(
d
);
}
}
for
(
unsigned
int
i
=
0
;
i
<
v1
.
size
();
i
++
)
{
if
(
v1
[
i
]
!=
v2
[
i
])
{
return
true
;
return
false
;
// }
}
}
}
bool
DDim
::
operator
!=
(
DDim
d
)
const
{
return
!
(
*
this
==
d
);
}
return
true
;
// }
DDim
DDim
::
operator
+
(
DDim
d
)
const
{
}
std
::
vector
<
int64_t
>
v1
=
vectorize
(
*
this
);
std
::
vector
<
int64_t
>
v2
=
vectorize
(
d
);
bool
DDim
::
operator
!=
(
DDim
d
)
const
{
return
!
(
*
this
==
d
);
}
std
::
vector
<
int64_t
>
v3
;
DDim
DDim
::
operator
+
(
DDim
d
)
const
{
std
::
vector
<
int64_t
>
v1
=
vectorize
(
*
this
);
assert
(
v1
.
size
()
==
v2
.
size
());
std
::
vector
<
int64_t
>
v2
=
vectorize
(
d
);
for
(
unsigned
int
i
=
0
;
i
<
v1
.
size
();
i
++
)
{
std
::
vector
<
int64_t
>
v3
;
v3
.
push_back
(
v1
[
i
]
+
v2
[
i
]);
}
assert
(
v1
.
size
()
==
v2
.
size
());
return
make_ddim
(
v3
);
for
(
unsigned
int
i
=
0
;
i
<
v1
.
size
();
i
++
)
{
}
v3
.
push_back
(
v1
[
i
]
+
v2
[
i
]);
}
DDim
DDim
::
operator
*
(
DDim
d
)
const
{
std
::
vector
<
int64_t
>
v1
=
vectorize
(
*
this
);
return
make_ddim
(
v3
);
std
::
vector
<
int64_t
>
v2
=
vectorize
(
d
);
}
std
::
vector
<
int64_t
>
v3
;
DDim
DDim
::
operator
*
(
DDim
d
)
const
{
std
::
vector
<
int64_t
>
v1
=
vectorize
(
*
this
);
assert
(
v1
.
size
()
==
v2
.
size
());
std
::
vector
<
int64_t
>
v2
=
vectorize
(
d
);
for
(
unsigned
int
i
=
0
;
i
<
v1
.
size
();
i
++
)
{
std
::
vector
<
int64_t
>
v3
;
v3
.
push_back
(
v1
[
i
]
*
v2
[
i
]);
}
assert
(
v1
.
size
()
==
v2
.
size
());
return
make_ddim
(
v3
);
for
(
unsigned
int
i
=
0
;
i
<
v1
.
size
();
i
++
)
{
}
v3
.
push_back
(
v1
[
i
]
*
v2
[
i
]);
}
int64_t
get
(
const
DDim
&
ddim
,
int
idx
)
{
return
ddim
[
idx
];
}
return
make_ddim
(
v3
);
void
set
(
DDim
&
ddim
,
int
idx
,
int
value
)
{
ddim
[
idx
]
=
value
;
}
}
/// @cond HIDDEN
int64_t
get
(
const
DDim
&
ddim
,
int
idx
)
{
return
ddim
[
idx
];
}
struct
VectorizeVisitor
:
Vistor
<
void
>
{
std
::
vector
<
int64_t
>
&
vector
;
void
set
(
DDim
&
ddim
,
int
idx
,
int
value
)
{
ddim
[
idx
]
=
value
;
}
explicit
VectorizeVisitor
(
std
::
vector
<
int64_t
>
&
v
)
:
vector
(
v
)
{}
/// @cond HIDDEN
struct
VectorizeVisitor
:
Vistor
<
void
>
{
template
<
typename
T
>
void
operator
()(
const
T
&
t
)
{
std
::
vector
<
int64_t
>
&
vector
;
vector
.
push_back
(
t
.
head
);
this
->
operator
()(
t
.
tail
);
explicit
VectorizeVisitor
(
std
::
vector
<
int64_t
>
&
v
)
:
vector
(
v
)
{}
}
template
<
typename
T
>
void
operator
()(
const
T
&
t
)
{
void
operator
()(
const
Dim
<
0
>
&
t
)
{}
vector
.
push_back
(
t
.
head
);
};
this
->
operator
()(
t
.
tail
);
/// @endcond
}
std
::
vector
<
int64_t
>
vectorize
(
const
DDim
&
ddim
)
{
void
operator
()(
const
Dim
<
0
>
&
t
)
{}
std
::
vector
<
int64_t
>
result
;
};
VectorizeVisitor
visitor
(
result
);
/// @endcond
DDim
::
ApplyVistor
(
visitor
,
ddim
);
return
result
;
std
::
vector
<
int64_t
>
vectorize
(
const
DDim
&
ddim
)
{
}
std
::
vector
<
int64_t
>
result
;
VectorizeVisitor
visitor
(
result
);
// NOTE: framework::vectorize converts to type int64_t
DDim
::
ApplyVistor
(
visitor
,
ddim
);
// which does not fit cudnn inputs.
return
result
;
std
::
vector
<
int
>
vectorize2int
(
const
DDim
&
ddim
)
{
}
std
::
vector
<
int64_t
>
temp
=
vectorize
(
ddim
);
std
::
vector
<
int
>
result
(
temp
.
begin
(),
temp
.
end
());
// NOTE: framework::vectorize converts to type int64_t
return
result
;
// which does not fit cudnn inputs.
}
std
::
vector
<
int
>
vectorize2int
(
const
DDim
&
ddim
)
{
std
::
vector
<
int64_t
>
temp
=
vectorize
(
ddim
);
struct
ProductVisitor
:
Vistor
<
int64_t
>
{
std
::
vector
<
int
>
result
(
temp
.
begin
(),
temp
.
end
());
template
<
int
D
>
int64_t
operator
()(
const
Dim
<
D
>
&
dim
)
{
return
result
;
return
product
(
dim
);
}
}
};
struct
ProductVisitor
:
Vistor
<
int64_t
>
{
template
<
int
D
>
int64_t
operator
()(
const
Dim
<
D
>
&
dim
)
{
int64_t
product
(
const
DDim
&
ddim
)
{
return
product
(
dim
);
ProductVisitor
visitor
;
}
return
DDim
::
ApplyVistor
(
visitor
,
ddim
);
};
}
int64_t
product
(
const
DDim
&
ddim
)
{
struct
SliceVectorizeVisitor
:
Vistor
<
void
>
{
ProductVisitor
visitor
;
std
::
vector
<
int64_t
>
&
vector
;
return
DDim
::
ApplyVistor
(
visitor
,
ddim
);
int
begin
;
}
int
end
;
struct
SliceVectorizeVisitor
:
Vistor
<
void
>
{
SliceVectorizeVisitor
(
std
::
vector
<
int64_t
>
&
v
,
int
b
,
int
e
)
std
::
vector
<
int64_t
>
&
vector
;
:
vector
(
v
),
begin
(
b
),
end
(
e
)
{
int
begin
;
// PADDLE_ENFORCE(begin < end,
int
end
;
// "Begin index must be less than end index in ddim
// slice.");
SliceVectorizeVisitor
(
std
::
vector
<
int64_t
>
&
v
,
int
b
,
int
e
)
// PADDLE_ENFORCE(begin >= 0,
:
vector
(
v
),
begin
(
b
),
end
(
e
)
{
// "Begin index can't be less than zero in ddim slice.");
// PADDLE_ENFORCE(begin < end,
}
// "Begin index must be less than end index in
// ddim
template
<
int
S
>
void
operator
()(
const
Dim
<
S
>
&
dim
)
{
// slice.");
if
(
begin
==
0
)
{
// PADDLE_ENFORCE(begin >= 0,
vector
.
push_back
(
dim
.
head
);
// "Begin index can't be less than zero in
}
else
{
// ddim slice.");
--
begin
;
}
}
--
end
;
template
<
int
S
>
void
operator
()(
const
Dim
<
S
>
&
dim
)
{
if
(
end
>
0
)
{
if
(
begin
==
0
)
{
this
->
operator
()(
dim
.
tail
);
vector
.
push_back
(
dim
.
head
);
}
}
else
{
}
--
begin
;
}
void
operator
()(
const
Dim
<
0
>
&
dim
)
{
--
end
;
// PADDLE_ENFORCE(end == 0, "End index in ddim slice is out of bound.");
if
(
end
>
0
)
{
}
this
->
operator
()(
dim
.
tail
);
};
}
}
DDim
slice_ddim
(
const
DDim
&
ddim
,
int
begin
,
int
end
)
{
std
::
vector
<
int64_t
>
vec
;
void
operator
()(
const
Dim
<
0
>
&
dim
)
{
vec
.
reserve
(
end
-
begin
);
// PADDLE_ENFORCE(end == 0, "End index in ddim slice is out
SliceVectorizeVisitor
visitor
(
vec
,
begin
,
end
);
// of bound.");
// boost::apply_visitor(visitor, dim);
}
DDim
::
ApplyVistor
(
visitor
,
ddim
);
};
// visitor(ddim.var.Get<Dim<4>>());
return
make_ddim
(
vec
);
DDim
slice_ddim
(
const
DDim
&
ddim
,
int
begin
,
int
end
)
{
}
std
::
vector
<
int64_t
>
vec
;
vec
.
reserve
(
end
-
begin
);
/// \cond HIDDEN
SliceVectorizeVisitor
visitor
(
vec
,
begin
,
end
);
// boost::apply_visitor(visitor, dim);
struct
ArityVisitor
:
Vistor
<
int
>
{
DDim
::
ApplyVistor
(
visitor
,
ddim
);
template
<
int
D
>
int
operator
()(
Dim
<
D
>
)
const
{
return
D
;
}
// visitor(ddim.var.Get<Dim<4>>());
};
return
make_ddim
(
vec
);
}
/// \endcond
/// \cond HIDDEN
int
arity
(
const
DDim
&
d
)
{
ArityVisitor
arityVisitor
=
ArityVisitor
();
struct
ArityVisitor
:
Vistor
<
int
>
{
return
DDim
::
ApplyVistor
(
arityVisitor
,
d
);
template
<
int
D
>
int
operator
()(
Dim
<
D
>
)
const
{
return
D
;
}
// return arityVisitor(d.var.Get<Dim<4>>());
};
// return boost::apply_visitor(ArityVisitor(), d); }
}
/// \endcond
/// \cond HIDDEN
int
arity
(
const
DDim
&
d
)
{
/// \endcond
ArityVisitor
arityVisitor
=
ArityVisitor
();
return
DDim
::
ApplyVistor
(
arityVisitor
,
d
);
struct
OSVistor
:
Vistor
<
std
::
ostream
&>
{
// return arityVisitor(d.var.Get<Dim<4>>());
OSVistor
(
std
::
ostream
&
os
)
:
os_
(
os
)
{}
// return boost::apply_visitor(ArityVisitor(), d); }
}
template
<
int
D
>
std
::
ostream
&
operator
()(
Dim
<
D
>
dim
)
const
{
/// \cond HIDDEN
return
os_
<<
dim
;
}
/// \endcond
private:
struct
OSVistor
:
Vistor
<
std
::
ostream
&>
{
std
::
ostream
&
os_
;
OSVistor
(
std
::
ostream
&
os
)
:
os_
(
os
)
{}
};
template
<
int
D
>
std
::
ostream
&
operator
()(
Dim
<
D
>
dim
)
const
{
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
DDim
&
ddim
)
{
return
os_
<<
dim
;
auto
vistor
=
OSVistor
(
os
);
}
DDim
::
ApplyVistor
(
vistor
,
ddim
);
return
os
;
private:
}
std
::
ostream
&
os_
;
};
DDim
::
DDim
(
std
::
initializer_list
<
int64_t
>
init_list
)
{
*
this
=
make_ddim
(
init_list
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
DDim
&
ddim
)
{
}
auto
vistor
=
OSVistor
(
os
);
DDim
::
ApplyVistor
(
vistor
,
ddim
);
DDim
flatten_to_2d
(
const
DDim
&
src
,
int
num_col_dims
)
{
return
os
;
int
rank
=
src
.
size
();
}
return
make_ddim
({
product
(
slice_ddim
(
src
,
0
,
num_col_dims
)),
product
(
slice_ddim
(
src
,
num_col_dims
,
rank
))});
DDim
::
DDim
(
std
::
initializer_list
<
int64_t
>
init_list
)
{
}
*
this
=
make_ddim
(
init_list
);
}
DDim
flatten_to_1d
(
const
DDim
&
src
)
{
return
make_ddim
({
product
(
src
)});
}
DDim
flatten_to_2d
(
const
DDim
&
src
,
int
num_col_dims
)
{
DDim
stride
(
const
DDim
&
ddim
)
{
int
rank
=
src
.
size
();
std
::
vector
<
int64_t
>
strides
(
ddim
.
size
());
return
make_ddim
({
product
(
slice_ddim
(
src
,
0
,
num_col_dims
)),
strides
[
ddim
.
size
()
-
1
]
=
1
;
product
(
slice_ddim
(
src
,
num_col_dims
,
rank
))});
for
(
int
i
=
ddim
.
size
()
-
2
;
i
>=
0
;
--
i
)
{
}
strides
[
i
]
=
strides
[
i
+
1
]
*
ddim
[
i
+
1
];
}
DDim
flatten_to_1d
(
const
DDim
&
src
)
{
return
framework
::
make_ddim
(
strides
);
return
make_ddim
({
product
(
src
)});
}
}
DDim
stride_numel
(
const
framework
::
DDim
&
ddim
)
{
DDim
stride
(
const
DDim
&
ddim
)
{
std
::
vector
<
int64_t
>
strides
(
ddim
.
size
());
std
::
vector
<
int64_t
>
strides
(
ddim
.
size
());
strides
[
ddim
.
size
()
-
1
]
=
ddim
[
ddim
.
size
()
-
1
];
strides
[
ddim
.
size
()
-
1
]
=
1
;
for
(
int
i
=
ddim
.
size
()
-
2
;
i
>=
0
;
--
i
)
{
for
(
int
i
=
ddim
.
size
()
-
2
;
i
>=
0
;
--
i
)
{
strides
[
i
]
=
strides
[
i
+
1
]
*
ddim
[
i
];
strides
[
i
]
=
strides
[
i
+
1
]
*
ddim
[
i
+
1
];
}
}
return
framework
::
make_ddim
(
strides
);
return
framework
::
make_ddim
(
strides
);
}
}
}
// namespace framework
DDim
stride_numel
(
const
framework
::
DDim
&
ddim
)
{
std
::
vector
<
int64_t
>
strides
(
ddim
.
size
());
strides
[
ddim
.
size
()
-
1
]
=
ddim
[
ddim
.
size
()
-
1
];
for
(
int
i
=
ddim
.
size
()
-
2
;
i
>=
0
;
--
i
)
{
strides
[
i
]
=
strides
[
i
+
1
]
*
ddim
[
i
];
}
return
framework
::
make_ddim
(
strides
);
}
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/ddim.h
浏览文件 @
aef98218
...
@@ -22,140 +22,145 @@ limitations under the License. */
...
@@ -22,140 +22,145 @@ limitations under the License. */
#include <vector>
#include <vector>
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
/**
/**
* \brief A dynamically sized dimension.
* \brief A dynamically sized dimension.
*
*
* The number of dimensions must be between [1, 9].
* The number of dimensions must be between [1, 9].
*/
*/
struct
DDim
{
struct
DDim
{
typedef
Variant
<
Dim
<
0
>
,
Dim
<
1
>
,
Dim
<
2
>
,
Dim
<
3
>
,
Dim
<
4
>
,
Dim
<
5
>
,
Dim
<
6
>
,
typedef
Variant
<
Dim
<
0
>
,
Dim
<
1
>
,
Dim
<
2
>
,
Dim
<
3
>
,
Dim
<
4
>
,
Dim
<
5
>
,
Dim
<
7
>
,
Dim
<
8
>
,
Dim
<
9
>>
Dim
<
6
>
,
Dim
<
7
>
,
Dim
<
8
>
,
Dim
<
9
>>
DDimVar
;
DDimVar
;
DDimVar
var
;
DDimVar
var
;
template
<
typename
Vistor
>
template
<
typename
Vistor
>
static
typename
Vistor
::
type_t
ApplyVistor
(
Vistor
vistor
,
const
DDim
&
d
)
{
static
typename
Vistor
::
type_t
ApplyVistor
(
Vistor
vistor
,
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
0
>
).
hash_code
())
{
const
DDim
&
d
)
{
return
vistor
(
d
.
var
.
Get
<
Dim
<
0
>>
());
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
0
>
).
hash_code
())
{
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
1
>
).
hash_code
())
{
return
vistor
(
d
.
var
.
Get
<
Dim
<
0
>>
());
return
vistor
(
d
.
var
.
Get
<
Dim
<
1
>>
());
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
1
>
).
hash_code
())
{
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
2
>
).
hash_code
())
{
return
vistor
(
d
.
var
.
Get
<
Dim
<
1
>>
());
return
vistor
(
d
.
var
.
Get
<
Dim
<
2
>>
());
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
2
>
).
hash_code
())
{
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
3
>
).
hash_code
())
{
return
vistor
(
d
.
var
.
Get
<
Dim
<
2
>>
());
return
vistor
(
d
.
var
.
Get
<
Dim
<
3
>>
());
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
3
>
).
hash_code
())
{
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
4
>
).
hash_code
())
{
return
vistor
(
d
.
var
.
Get
<
Dim
<
3
>>
());
return
vistor
(
d
.
var
.
Get
<
Dim
<
4
>>
());
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
4
>
).
hash_code
())
{
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
5
>
).
hash_code
())
{
return
vistor
(
d
.
var
.
Get
<
Dim
<
4
>>
());
return
vistor
(
d
.
var
.
Get
<
Dim
<
5
>>
());
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
5
>
).
hash_code
())
{
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
6
>
).
hash_code
())
{
return
vistor
(
d
.
var
.
Get
<
Dim
<
5
>>
());
return
vistor
(
d
.
var
.
Get
<
Dim
<
6
>>
());
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
6
>
).
hash_code
())
{
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
7
>
).
hash_code
())
{
return
vistor
(
d
.
var
.
Get
<
Dim
<
6
>>
());
return
vistor
(
d
.
var
.
Get
<
Dim
<
7
>>
());
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
7
>
).
hash_code
())
{
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
8
>
).
hash_code
())
{
return
vistor
(
d
.
var
.
Get
<
Dim
<
7
>>
());
return
vistor
(
d
.
var
.
Get
<
Dim
<
8
>>
());
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
8
>
).
hash_code
())
{
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
9
>
).
hash_code
())
{
return
vistor
(
d
.
var
.
Get
<
Dim
<
8
>>
());
return
vistor
(
d
.
var
.
Get
<
Dim
<
9
>>
());
}
else
if
(
d
.
var
.
TypeId
()
==
typeid
(
Dim
<
9
>
).
hash_code
())
{
}
else
{
return
vistor
(
d
.
var
.
Get
<
Dim
<
9
>>
());
printf
(
" dim not support
\n
"
);
}
else
{
throw
std
::
bad_exception
();
printf
(
" dim not support
\n
"
);
// return typename Vistor::type_t();
throw
std
::
bad_exception
();
}
// return typename Vistor::type_t();
}
}
}
DDim
()
{
var
.
Set
<
Dim
<
1
>>
(
Dim
<
1
>
());
}
DDim
()
{
var
.
Set
<
Dim
<
1
>>
(
Dim
<
1
>
());
}
template
<
int
D
>
explicit
DDim
(
const
Dim
<
D
>
&
in
)
{
var
.
Set
<
Dim
<
D
>>
(
in
);
}
template
<
int
D
>
explicit
DDim
(
const
Dim
<
D
>
&
in
)
{
/*implicit*/
DDim
(
std
::
initializer_list
<
int64_t
>
init_list
);
var
.
Set
<
Dim
<
D
>>
(
in
);
}
template
<
int
D
>
DDim
&
operator
=
(
const
Dim
<
D
>
&
in
)
{
var
.
Set
<
Dim
<
D
>>
(
in
);
/*implicit*/
DDim
(
std
::
initializer_list
<
int64_t
>
init_list
);
return
*
this
;
}
template
<
int
D
>
DDim
&
operator
=
(
const
Dim
<
D
>
&
in
)
{
var
.
Set
<
Dim
<
D
>>
(
in
);
int64_t
&
operator
[](
int
idx
);
return
*
this
;
}
int64_t
operator
[](
int
idx
)
const
;
int64_t
&
operator
[](
int
idx
);
// template <typename Visitor>
// typename Visitor::result_type apply_visitor(Visitor& visitor) {
int64_t
operator
[](
int
idx
)
const
;
// return var.apply_visitor(visitor);
// }
// template <typename Visitor>
//
// typename Visitor::result_type apply_visitor(Visitor& visitor) {
// template <typename Visitor>
// return var.apply_visitor(visitor);
// typename Visitor::result_type apply_visitor(Visitor& visitor) const {
// }
// return var.apply_visitor(visitor);
//
// }
// template <typename Visitor>
// typename Visitor::result_type apply_visitor(Visitor& visitor)
DDimVar
getVar
()
{
return
var
;
}
// const {
// return var.apply_visitor(visitor);
bool
operator
==
(
DDim
d
)
const
;
// }
bool
operator
!=
(
DDim
d
)
const
;
DDimVar
getVar
()
{
return
var
;
}
DDim
operator
+
(
DDim
d
)
const
;
bool
operator
==
(
DDim
d
)
const
;
DDim
operator
*
(
DDim
d
)
const
;
bool
operator
!=
(
DDim
d
)
const
;
int
size
()
const
;
DDim
operator
+
(
DDim
d
)
const
;
};
DDim
operator
*
(
DDim
d
)
const
;
/**
* \brief Make a DDim from std::vector<int64_t>
int
size
()
const
;
*
};
* \param dims An vector of ints. Must be sized between [1, 9]
*/
/**
DDim
make_ddim
(
const
std
::
vector
<
int64_t
>
&
dims
);
* \brief Make a DDim from std::vector<int64_t>
*
DDim
make_ddim
(
const
std
::
vector
<
int
>
&
dims
);
* \param dims An vector of ints. Must be sized between [1, 9]
*/
/**
DDim
make_ddim
(
const
std
::
vector
<
int64_t
>
&
dims
);
* \brief Make a DDim from an initializer list
*
DDim
make_ddim
(
const
std
::
vector
<
int
>
&
dims
);
* \param dims An initializer list of ints. Must be sized between [1, 9]
*
/**
*/
* \brief Make a DDim from an initializer list
DDim
make_ddim
(
std
::
initializer_list
<
int64_t
>
dims
);
*
* \param dims An initializer list of ints. Must be sized between [1, 9]
int64_t
get
(
const
DDim
&
dim
,
int
idx
);
*
*/
void
set
(
DDim
&
dim
,
int
idx
,
int
val
);
DDim
make_ddim
(
std
::
initializer_list
<
int64_t
>
dims
);
std
::
vector
<
int64_t
>
vectorize
(
const
DDim
&
ddim
);
int64_t
get
(
const
DDim
&
dim
,
int
idx
);
std
::
vector
<
int
>
vectorize2int
(
const
DDim
&
ddim
);
void
set
(
DDim
&
dim
,
int
idx
,
int
val
);
int64_t
product
(
const
DDim
&
ddim
);
std
::
vector
<
int64_t
>
vectorize
(
const
DDim
&
ddim
);
/**
std
::
vector
<
int
>
vectorize2int
(
const
DDim
&
ddim
);
* \brief Slice a ddim
*
int64_t
product
(
const
DDim
&
ddim
);
* Slice dim with [begin, end).
* e.g. DDim d = make_ddim({1,2,3,4,5});
/**
* slice_ddim(d, 1, 3); ====> {2,3}
* \brief Slice a ddim
*/
*
DDim
slice_ddim
(
const
DDim
&
dim
,
int
begin
,
int
end
);
* Slice dim with [begin, end).
* e.g. DDim d = make_ddim({1,2,3,4,5});
/**
* slice_ddim(d, 1, 3); ====> {2,3}
* \brief What is the length of this dimension?
*/
*
DDim
slice_ddim
(
const
DDim
&
dim
,
int
begin
,
int
end
);
* \param Dynamic dimension to inspect
*/
/**
* \brief What is the length of this dimension?
*
* \param Dynamic dimension to inspect
*/
int
arity
(
const
DDim
&
ddim
);
int
arity
(
const
DDim
&
ddim
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
,
const
DDim
&
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
,
const
DDim
&
);
// Reshape a tensor to a matrix. The matrix's first dimension(column length)
// Reshape a tensor to a matrix. The matrix's first dimension(column
// will be the product of tensor's first `num_col_dims` dimensions.
// length)
DDim
flatten_to_2d
(
const
DDim
&
src
,
int
num_col_dims
);
// will be the product of tensor's first `num_col_dims` dimensions.
DDim
flatten_to_2d
(
const
DDim
&
src
,
int
num_col_dims
);
DDim
flatten_to_1d
(
const
DDim
&
src
);
DDim
flatten_to_1d
(
const
DDim
&
src
);
DDim
stride
(
const
DDim
&
ddim
);
DDim
stride
(
const
DDim
&
ddim
);
DDim
stride_numel
(
const
DDim
&
ddim
);
DDim
stride_numel
(
const
DDim
&
ddim
);
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/dim.h
浏览文件 @
aef98218
...
@@ -21,388 +21,410 @@
...
@@ -21,388 +21,410 @@
#include "platform/hostdevice.h"
#include "platform/hostdevice.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
// Statically sized, statically indexed dimension
// Statically sized, statically indexed dimension
template
<
int
i
>
struct
Dim
{
template
<
int
i
>
struct
Dim
{
static
constexpr
int
dimensions
=
i
;
static
constexpr
int
dimensions
=
i
;
template
<
typename
...
Args
>
template
<
typename
...
Args
>
HOSTDEVICE
Dim
(
int64_t
_head
,
Args
...
_tail
)
:
head
(
_head
),
tail
(
_tail
...)
{
HOSTDEVICE
Dim
(
int64_t
_head
,
Args
...
_tail
)
static_assert
(
sizeof
...(
_tail
)
==
i
-
1
,
:
head
(
_head
),
tail
(
_tail
...)
{
"Dim initialized with the wrong number of parameters"
);
static_assert
(
}
sizeof
...(
_tail
)
==
i
-
1
,
"Dim initialized with the wrong number of parameters"
);
}
HOSTDEVICE
HOSTDEVICE
Dim
(
int64_t
_head
,
const
Dim
<
i
-
1
>
&
_tail
)
:
head
(
_head
),
tail
(
_tail
)
{}
Dim
(
int64_t
_head
,
const
Dim
<
i
-
1
>
&
_tail
)
:
head
(
_head
),
tail
(
_tail
)
{}
HOSTDEVICE
HOSTDEVICE
Dim
()
:
head
(
0
),
tail
()
{}
Dim
()
:
head
(
0
),
tail
()
{}
/** Construct a Dim from a linear index and size. Uses Fortran order
/** Construct a Dim from a linear index and size. Uses Fortran
* indexing. */
* order
HOSTDEVICE
* indexing. */
Dim
(
int64_t
idx
,
const
Dim
<
i
>
&
size
)
HOSTDEVICE
:
head
(
idx
%
size
.
head
),
tail
(
idx
/
size
.
head
,
size
.
tail
)
{}
Dim
(
int64_t
idx
,
const
Dim
<
i
>
&
size
)
:
head
(
idx
%
size
.
head
),
tail
(
idx
/
size
.
head
,
size
.
tail
)
{}
/** Construct a Dim with each dimension set to the given index */
/** Construct a Dim with each dimension set to the given index */
HOSTDEVICE
HOSTDEVICE
Dim
(
int64_t
idx
)
:
head
(
idx
),
tail
(
idx
)
{}
Dim
(
int64_t
idx
)
:
head
(
idx
),
tail
(
idx
)
{}
HOSTDEVICE
HOSTDEVICE
bool
operator
==
(
const
Dim
<
i
>
&
o
)
const
{
bool
operator
==
(
const
Dim
<
i
>
&
o
)
const
{
return
(
head
==
o
.
head
)
&&
(
tail
==
o
.
tail
);
return
(
head
==
o
.
head
)
&&
(
tail
==
o
.
tail
);
}
}
HOSTDEVICE
HOSTDEVICE
bool
operator
!=
(
const
Dim
<
i
>
&
o
)
const
{
return
!
(
*
this
==
o
);
}
bool
operator
!=
(
const
Dim
<
i
>
&
o
)
const
{
return
!
(
*
this
==
o
);
}
HOSTDEVICE
HOSTDEVICE
int64_t
&
operator
[](
int
idx
);
int64_t
&
operator
[](
int
idx
);
HOSTDEVICE
HOSTDEVICE
int64_t
operator
[](
int
idx
)
const
;
int64_t
operator
[](
int
idx
)
const
;
HOST
std
::
string
to_string
()
const
;
HOST
std
::
string
to_string
()
const
;
int64_t
head
;
int64_t
head
;
Dim
<
i
-
1
>
tail
;
Dim
<
i
-
1
>
tail
;
};
};
// Base case specialization
// Base case specialization
template
<
>
struct
Dim
<
0
>
{
template
<
>
struct
Dim
<
0
>
{
static
constexpr
int
dimensions
=
0
;
static
constexpr
int
dimensions
=
0
;
HOSTDEVICE
HOSTDEVICE
Dim
(
int64_t
_head
)
{}
Dim
(
int64_t
_head
)
{}
HOSTDEVICE
HOSTDEVICE
Dim
()
{}
Dim
()
{}
HOSTDEVICE
HOSTDEVICE
Dim
(
int
idx
,
const
Dim
<
0
>
&
size
)
{
Dim
(
int
idx
,
const
Dim
<
0
>
&
size
)
{
#ifndef __CUDA_ARCH__
#ifndef __CUDA_ARCH__
if
(
idx
>
0
)
{
if
(
idx
>
0
)
{
throw
std
::
invalid_argument
(
"Index out of range."
);
throw
std
::
invalid_argument
(
"Index out of range."
);
}
}
#else
#else
PADDLE_ASSERT
(
idx
==
0
);
PADDLE_ASSERT
(
idx
==
0
);
#endif
#endif
}
}
HOSTDEVICE
HOSTDEVICE
bool
operator
==
(
const
Dim
<
0
>
&
o
)
const
{
return
true
;
}
bool
operator
==
(
const
Dim
<
0
>
&
o
)
const
{
return
true
;
}
HOSTDEVICE
HOSTDEVICE
bool
operator
!=
(
const
Dim
<
0
>
&
o
)
const
{
return
false
;
}
bool
operator
!=
(
const
Dim
<
0
>
&
o
)
const
{
return
false
;
}
HOSTDEVICE
HOSTDEVICE
int64_t
&
operator
[](
int
idx
);
int64_t
&
operator
[](
int
idx
);
HOSTDEVICE
HOSTDEVICE
int64_t
operator
[](
int
idx
)
const
;
int64_t
operator
[](
int
idx
)
const
;
};
};
namespace
{
namespace
{
// Helper for accessing Dim classes
// Helper for accessing Dim classes
template
<
int
i
>
struct
DimGetter
{
template
<
int
i
>
struct
DimGetter
{
// Return a copy if Dim is const
// Return a copy if Dim is const
template
<
typename
D
>
HOSTDEVICE
static
int64_t
impl
(
const
D
&
d
)
{
template
<
typename
D
>
return
DimGetter
<
i
-
1
>::
impl
(
d
.
tail
);
HOSTDEVICE
static
int64_t
impl
(
const
D
&
d
)
{
}
return
DimGetter
<
i
-
1
>::
impl
(
d
.
tail
);
// Return a reference if Dim is mutable
}
template
<
typename
D
>
HOSTDEVICE
static
int64_t
&
impl
(
D
&
d
)
{
// Return a reference if Dim is mutable
return
DimGetter
<
i
-
1
>::
impl
(
d
.
tail
);
template
<
typename
D
>
HOSTDEVICE
static
int64_t
&
impl
(
D
&
d
)
{
}
return
DimGetter
<
i
-
1
>::
impl
(
d
.
tail
);
};
}
};
// Eureka! We found the element!
template
<
>
struct
DimGetter
<
0
>
{
// Eureka! We found the element!
// Return a copy if Dim is const
template
<
>
struct
DimGetter
<
0
>
{
template
<
typename
D
>
HOSTDEVICE
static
int64_t
impl
(
const
D
&
d
)
{
// Return a copy if Dim is const
return
d
.
head
;
template
<
typename
D
>
}
HOSTDEVICE
static
int64_t
impl
(
const
D
&
d
)
{
// Return a reference if Dim is mutable
return
d
.
head
;
template
<
typename
D
>
HOSTDEVICE
static
int64_t
&
impl
(
D
&
d
)
{
return
d
.
head
;
}
}
};
// Return a reference if Dim is mutable
template
<
typename
D
>
HOSTDEVICE
static
int64_t
&
impl
(
D
&
d
)
{
template
<
int
D
>
HOSTDEVICE
int64_t
&
indexer
(
Dim
<
D
>
&
dim
,
int
idx
)
{
return
d
.
head
;
}
};
template
<
int
D
>
HOSTDEVICE
int64_t
&
indexer
(
Dim
<
D
>
&
dim
,
int
idx
)
{
#ifndef __CUDA_ARCH__
#ifndef __CUDA_ARCH__
if
(
idx
<
0
)
{
if
(
idx
<
0
)
{
throw
std
::
invalid_argument
(
"Tried to access a negative dimension"
);
throw
std
::
invalid_argument
(
}
"Tried to access a negative dimension"
);
}
#else
#else
PADDLE_ASSERT
(
idx
>=
0
);
PADDLE_ASSERT
(
idx
>=
0
);
#endif
#endif
if
(
idx
==
0
)
{
if
(
idx
==
0
)
{
return
dim
.
head
;
return
dim
.
head
;
}
}
return
indexer
(
dim
.
tail
,
idx
-
1
);
return
indexer
(
dim
.
tail
,
idx
-
1
);
}
}
template
<
>
HOSTDEVICE
int64_t
&
indexer
<
0
>
(
Dim
<
0
>
&
dim
,
int
idx
)
{
template
<
>
HOSTDEVICE
int64_t
&
indexer
<
0
>
(
Dim
<
0
>
&
dim
,
int
idx
)
{
#ifndef __CUDA_ARCH__
#ifndef __CUDA_ARCH__
throw
std
::
invalid_argument
(
"Invalid index"
);
throw
std
::
invalid_argument
(
"Invalid index"
);
#else
#else
PADDLE_ASSERT
(
false
);
PADDLE_ASSERT
(
false
);
#if CUDA_VERSION < 8000
#if CUDA_VERSION < 8000
// On CUDA versions previous to 8.0, only __shared__ variables
// On CUDA versions previous to 8.0, only __shared__ variables
// could be declared as static in the device code.
// could be declared as static in the device code.
int64_t
head
=
0
;
int64_t
head
=
0
;
#else
#else
static
int64_t
head
=
0
;
static
int64_t
head
=
0
;
#endif
#endif
return
head
;
return
head
;
#endif
#endif
}
}
template
<
int
D
>
HOSTDEVICE
int64_t
indexer
(
const
Dim
<
D
>
&
dim
,
int
idx
)
{
template
<
int
D
>
HOSTDEVICE
int64_t
indexer
(
const
Dim
<
D
>
&
dim
,
int
idx
)
{
#ifndef __CUDA_ARCH__
#ifndef __CUDA_ARCH__
if
(
idx
<
0
)
{
if
(
idx
<
0
)
{
throw
std
::
invalid_argument
(
"Tried to access a negative dimension"
);
throw
std
::
invalid_argument
(
}
"Tried to access a negative dimension"
);
}
#else
#else
PADDLE_ASSERT
(
idx
>=
0
);
PADDLE_ASSERT
(
idx
>=
0
);
#endif
#endif
if
(
idx
==
0
)
{
if
(
idx
==
0
)
{
return
dim
.
head
;
return
dim
.
head
;
}
}
return
indexer
(
dim
.
tail
,
idx
-
1
);
return
indexer
(
dim
.
tail
,
idx
-
1
);
}
}
template
<
>
HOSTDEVICE
int64_t
indexer
<
0
>
(
const
Dim
<
0
>
&
dim
,
int
idx
)
{
template
<
>
HOSTDEVICE
int64_t
indexer
<
0
>
(
const
Dim
<
0
>
&
dim
,
int
idx
)
{
#ifndef __CUDA_ARCH__
#ifndef __CUDA_ARCH__
throw
std
::
invalid_argument
(
"Invalid index"
);
throw
std
::
invalid_argument
(
"Invalid index"
);
#else
#else
PADDLE_ASSERT
(
false
);
PADDLE_ASSERT
(
false
);
#if CUDA_VERSION < 8000
#if CUDA_VERSION < 8000
// On CUDA versions previous to 8.0, only __shared__ variables
// On CUDA versions previous to 8.0, only __shared__ variables
// could be declared as static in the device code.
// could be declared as static in the device code.
int64_t
head
=
0
;
int64_t
head
=
0
;
#else
#else
static
int64_t
head
=
0
;
static
int64_t
head
=
0
;
#endif
#endif
return
head
;
return
head
;
#endif
#endif
}
}
}
// namespace
}
// namespace
// Static access to constant Dim
// Static access to constant Dim
template
<
int
i
,
int
l
>
HOSTDEVICE
int64_t
get
(
const
Dim
<
l
>
&
d
)
{
template
<
int
i
,
int
l
>
HOSTDEVICE
int64_t
get
(
const
Dim
<
l
>
&
d
)
{
return
DimGetter
<
i
>::
impl
(
d
);
return
DimGetter
<
i
>::
impl
(
d
);
}
}
// Static access to mutable Dim
// Static access to mutable Dim
template
<
int
i
,
int
l
>
HOSTDEVICE
int64_t
&
get
(
Dim
<
l
>
&
d
)
{
template
<
int
i
,
int
l
>
HOSTDEVICE
int64_t
&
get
(
Dim
<
l
>
&
d
)
{
return
DimGetter
<
i
>::
impl
(
d
);
return
DimGetter
<
i
>::
impl
(
d
);
}
}
// Dynamic access to constant Dim
// Dynamic access to constant Dim
template
<
int
l
>
HOSTDEVICE
int64_t
Dim
<
l
>::
operator
[](
int
i
)
const
{
template
<
int
l
>
HOSTDEVICE
int64_t
Dim
<
l
>::
operator
[](
int
i
)
const
{
// std::cout << "l: " << l << std::endl;
// std::cout << "l: " << l << std::endl;
return
indexer
(
*
this
,
i
);
return
indexer
(
*
this
,
i
);
}
}
// Dynamic access to mutable Dim
// Dynamic access to mutable Dim
template
<
int
l
>
HOSTDEVICE
int64_t
&
Dim
<
l
>::
operator
[](
int
i
)
{
template
<
int
l
>
HOSTDEVICE
int64_t
&
Dim
<
l
>::
operator
[](
int
i
)
{
return
indexer
(
*
this
,
i
);
return
indexer
(
*
this
,
i
);
}
}
// Dynamic access to constant Dim
// Dynamic access to constant Dim
inline
HOSTDEVICE
int64_t
Dim
<
0
>::
operator
[](
int
i
)
const
{
inline
HOSTDEVICE
int64_t
Dim
<
0
>::
operator
[](
int
i
)
const
{
return
indexer
(
*
this
,
i
);
return
indexer
(
*
this
,
i
);
}
}
// Dynamic access to mutable Dim
// Dynamic access to mutable Dim
inline
HOSTDEVICE
int64_t
&
Dim
<
0
>::
operator
[](
int
i
)
{
inline
HOSTDEVICE
int64_t
&
Dim
<
0
>::
operator
[](
int
i
)
{
return
indexer
(
*
this
,
i
);
return
indexer
(
*
this
,
i
);
}
}
// Dynamic access to constant Dim
// Dynamic access to constant Dim
// without std::enable_if will try to instantiate this on get<0>(d)
// without std::enable_if will try to instantiate this on get<0>(d)
template
<
int
l
>
template
<
int
l
>
HOSTDEVICE
typename
std
::
enable_if
<
(
l
>
0
),
int64_t
>::
type
get
(
const
Dim
<
l
>
&
d
,
HOSTDEVICE
typename
std
::
enable_if
<
(
l
>
0
),
int64_t
>::
type
int
i
)
{
get
(
const
Dim
<
l
>
&
d
,
int
i
)
{
return
d
[
i
];
return
d
[
i
];
}
}
// Dynamic access to mutable Dim
// Dynamic access to mutable Dim
template
<
int
l
>
template
<
int
l
>
HOSTDEVICE
typename
std
::
enable_if
<
(
l
>
0
),
int64_t
&>::
type
get
(
Dim
<
l
>
&
d
,
HOSTDEVICE
typename
std
::
enable_if
<
(
l
>
0
),
int64_t
&>::
type
int
i
)
{
get
(
Dim
<
l
>
&
d
,
int
i
)
{
return
d
[
i
];
return
d
[
i
];
}
}
// Dot product of two dims
// Dot product of two dims
template
<
int
i
>
template
<
int
i
>
HOSTDEVICE
int64_t
linearize
(
const
Dim
<
i
>
&
a
,
const
Dim
<
i
>
&
b
)
{
HOSTDEVICE
int64_t
linearize
(
const
Dim
<
i
>
&
a
,
const
Dim
<
i
>
&
b
)
{
return
a
.
head
*
b
.
head
+
linearize
(
a
.
tail
,
b
.
tail
);
return
a
.
head
*
b
.
head
+
linearize
(
a
.
tail
,
b
.
tail
);
}
}
// Base case dot product of two Dims
// Base case dot product of two Dims
// Notice it is inline because it is no longer a template
// Notice it is inline because it is no longer a template
template
<
>
template
<
>
HOSTDEVICE
inline
int64_t
linearize
(
const
Dim
<
0
>
&
a
,
const
Dim
<
0
>
&
b
)
{
HOSTDEVICE
inline
int64_t
linearize
(
const
Dim
<
0
>
&
a
,
const
Dim
<
0
>
&
b
)
{
return
0
;
return
0
;
}
}
// Product of a Dim
// Product of a Dim
template
<
int
i
>
HOSTDEVICE
int64_t
product
(
const
Dim
<
i
>
&
a
,
int
prod
=
1
)
{
template
<
int
i
>
return
prod
*
a
.
head
*
product
(
a
.
tail
);
HOSTDEVICE
int64_t
product
(
const
Dim
<
i
>
&
a
,
int
prod
=
1
)
{
}
return
prod
*
a
.
head
*
product
(
a
.
tail
);
}
// Base case product of a Dim
// Notice it is inline because it is no longer a template
// Base case product of a Dim
template
<
>
HOSTDEVICE
inline
int64_t
product
(
const
Dim
<
0
>
&
a
,
int
prod
)
{
// Notice it is inline because it is no longer a template
return
prod
;
template
<
>
}
HOSTDEVICE
inline
int64_t
product
(
const
Dim
<
0
>
&
a
,
int
prod
)
{
return
prod
;
// Is 0 <= idx_i < size_i for all i?
}
template
<
int
i
>
HOSTDEVICE
bool
contained
(
const
Dim
<
i
>
&
idx
,
const
Dim
<
i
>
&
size
)
{
// Is 0 <= idx_i < size_i for all i?
return
((
0
<=
idx
.
head
)
&&
(
idx
.
head
<
size
.
head
)
&&
template
<
int
i
>
contained
(
idx
.
tail
,
size
.
tail
));
HOSTDEVICE
bool
contained
(
const
Dim
<
i
>
&
idx
,
const
Dim
<
i
>
&
size
)
{
}
return
((
0
<=
idx
.
head
)
&&
(
idx
.
head
<
size
.
head
)
&&
contained
(
idx
.
tail
,
size
.
tail
));
// Base case of is 0 <= idx_i < size_i ?
}
// Notice it is inline because it is no longer a template
template
<
>
// Base case of is 0 <= idx_i < size_i ?
HOSTDEVICE
inline
bool
contained
(
const
Dim
<
0
>
&
idx
,
const
Dim
<
0
>
&
size
)
{
// Notice it is inline because it is no longer a template
return
true
;
template
<
>
}
HOSTDEVICE
inline
bool
contained
(
const
Dim
<
0
>
&
idx
,
const
Dim
<
0
>
&
size
)
{
/**
return
true
;
* \brief Compute exclusive prefix-multiply of a Dim.
}
*/
template
<
int
i
>
/**
HOSTDEVICE
Dim
<
i
>
ex_prefix_mul
(
const
Dim
<
i
>
&
src
,
int
mul
=
1
)
{
* \brief Compute exclusive prefix-multiply of a Dim.
return
Dim
<
i
>
(
mul
,
ex_prefix_mul
(
src
.
tail
,
mul
*
src
.
head
));
*/
}
template
<
int
i
>
HOSTDEVICE
Dim
<
i
>
ex_prefix_mul
(
const
Dim
<
i
>
&
src
,
int
mul
=
1
)
{
///\cond HIDDEN
return
Dim
<
i
>
(
mul
,
ex_prefix_mul
(
src
.
tail
,
mul
*
src
.
head
));
// Base case of ex_prefix_mul
}
// Notice it is inline because it is no longer a template
template
<
>
HOSTDEVICE
inline
Dim
<
0
>
ex_prefix_mul
(
const
Dim
<
0
>
&
src
,
int
mul
)
{
///\cond HIDDEN
return
Dim
<
0
>
();
// Base case of ex_prefix_mul
}
// Notice it is inline because it is no longer a template
///\endcond
template
<
>
HOSTDEVICE
inline
Dim
<
0
>
ex_prefix_mul
(
const
Dim
<
0
>
&
src
,
int
mul
)
{
/**
return
Dim
<
0
>
();
* Add two dimensions together
}
*/
///\endcond
template
<
int
i
>
HOSTDEVICE
Dim
<
i
>
dim_plus
(
const
Dim
<
i
>
&
a
,
const
Dim
<
i
>
&
b
)
{
return
Dim
<
i
>
(
a
.
head
+
b
.
head
,
dim_plus
(
a
.
tail
,
b
.
tail
));
/**
}
* Add two dimensions together
*/
// Base case
template
<
int
i
>
template
<
>
HOSTDEVICE
Dim
<
i
>
dim_plus
(
const
Dim
<
i
>
&
a
,
const
Dim
<
i
>
&
b
)
{
HOSTDEVICE
inline
Dim
<
0
>
dim_plus
(
const
Dim
<
0
>
&
a
,
const
Dim
<
0
>
&
b
)
{
return
Dim
<
i
>
(
a
.
head
+
b
.
head
,
dim_plus
(
a
.
tail
,
b
.
tail
));
return
Dim
<
0
>
();
}
}
// Base case
template
<
int
i
>
template
<
>
HOSTDEVICE
Dim
<
i
>
operator
+
(
const
Dim
<
i
>
&
lhs
,
const
Dim
<
i
>
&
rhs
)
{
HOSTDEVICE
inline
Dim
<
0
>
dim_plus
(
const
Dim
<
0
>
&
a
,
const
Dim
<
0
>
&
b
)
{
return
dim_plus
(
lhs
,
rhs
);
return
Dim
<
0
>
();
}
}
/**
template
<
int
i
>
* Multiply two dimensions together
HOSTDEVICE
Dim
<
i
>
operator
+
(
const
Dim
<
i
>
&
lhs
,
const
Dim
<
i
>
&
rhs
)
{
*/
return
dim_plus
(
lhs
,
rhs
);
template
<
int
i
>
HOSTDEVICE
Dim
<
i
>
dim_mult
(
const
Dim
<
i
>
&
a
,
const
Dim
<
i
>
&
b
)
{
}
return
Dim
<
i
>
(
a
.
head
*
b
.
head
,
dim_mult
(
a
.
tail
,
b
.
tail
));
}
/**
* Multiply two dimensions together
// Base case
*/
template
<
>
template
<
int
i
>
HOSTDEVICE
inline
Dim
<
0
>
dim_mult
(
const
Dim
<
0
>
&
a
,
const
Dim
<
0
>
&
b
)
{
HOSTDEVICE
Dim
<
i
>
dim_mult
(
const
Dim
<
i
>
&
a
,
const
Dim
<
i
>
&
b
)
{
return
Dim
<
0
>
();
return
Dim
<
i
>
(
a
.
head
*
b
.
head
,
dim_mult
(
a
.
tail
,
b
.
tail
));
}
}
template
<
int
i
>
// Base case
HOSTDEVICE
Dim
<
i
>
operator
*
(
const
Dim
<
i
>
&
lhs
,
const
Dim
<
i
>
&
rhs
)
{
template
<
>
return
dim_mult
(
lhs
,
rhs
);
HOSTDEVICE
inline
Dim
<
0
>
dim_mult
(
const
Dim
<
0
>
&
a
,
const
Dim
<
0
>
&
b
)
{
}
return
Dim
<
0
>
();
}
/**
* \brief Normalize strides to ensure any dimension with extent 1
template
<
int
i
>
* has stride 0.
HOSTDEVICE
Dim
<
i
>
operator
*
(
const
Dim
<
i
>
&
lhs
,
const
Dim
<
i
>
&
rhs
)
{
*
return
dim_mult
(
lhs
,
rhs
);
* \param size Dim object containing the size of an array
}
* \param stride Dim object containing stride of an array
* \return Dim object the same size as \p size with normalized strides
/**
*
* \brief Normalize strides to ensure any dimension with extent 1
*/
* has stride 0.
*
template
<
int
i
>
* \param size Dim object containing the size of an array
HOSTDEVICE
Dim
<
i
>
normalize_strides
(
const
Dim
<
i
>
&
size
,
const
Dim
<
i
>
&
stride
)
{
* \param stride Dim object containing stride of an array
int
norm_stride
=
size
.
head
==
1
?
0
:
stride
.
head
;
* \return Dim object the same size as \p size with normalized strides
return
Dim
<
i
>
(
norm_stride
,
normalize_strides
(
size
.
tail
,
stride
.
tail
));
*
}
*/
///\cond HIDDEN
template
<
int
i
>
HOSTDEVICE
Dim
<
i
>
normalize_strides
(
const
Dim
<
i
>
&
size
,
template
<
>
const
Dim
<
i
>
&
stride
)
{
HOSTDEVICE
inline
Dim
<
0
>
normalize_strides
(
const
Dim
<
0
>
&
size
,
int
norm_stride
=
size
.
head
==
1
?
0
:
stride
.
head
;
const
Dim
<
0
>
&
stride
)
{
return
Dim
<
i
>
(
norm_stride
,
return
Dim
<
0
>
();
normalize_strides
(
size
.
tail
,
stride
.
tail
));
}
}
///\endcond
///\cond HIDDEN
/**
template
<
>
* Helper function to create a Dim
HOSTDEVICE
inline
Dim
<
0
>
normalize_strides
(
const
Dim
<
0
>
&
size
,
*
const
Dim
<
0
>
&
stride
)
{
* \param idxes The type of Dim constructed depends on the number of params
return
Dim
<
0
>
();
*
}
*/
///\endcond
template
<
typename
...
Args
>
HOSTDEVICE
Dim
<
sizeof
...(
Args
)
>
make_dim
(
Args
...
idxes
)
{
/**
return
Dim
<
sizeof
...(
Args
)
>
(
idxes
...);
* Helper function to create a Dim
}
*
* \param idxes The type of Dim constructed depends on the number of
// Allows us to output a Dim
* params
// XXX For some reason, overloading fails to resolve this correctly
*
template
<
int
i
>
*/
typename
std
::
enable_if
<
(
i
>
1
),
std
::
ostream
&>::
type
operator
<<
(
std
::
ostream
&
os
,
const
Dim
<
i
>
&
d
)
{
template
<
typename
...
Args
>
os
<<
d
.
head
<<
", "
<<
d
.
tail
;
HOSTDEVICE
Dim
<
sizeof
...(
Args
)
>
make_dim
(
Args
...
idxes
)
{
return
os
;
return
Dim
<
sizeof
...(
Args
)
>
(
idxes
...);
}
}
// Base case that allows us to output a Dim
// Allows us to output a Dim
// XXX I wish this could be an overload instead of a template
// XXX For some reason, overloading fails to resolve this correctly
template
<
int
i
>
template
<
int
i
>
typename
std
::
enable_if
<
(
i
==
1
),
std
::
ostream
&>::
type
typename
std
::
enable_if
<
(
i
>
1
),
std
::
ostream
&>::
type
operator
<<
(
std
::
ostream
&
os
,
const
Dim
<
i
>
&
d
)
{
operator
<<
(
std
::
ostream
&
os
,
const
Dim
<
i
>
&
d
)
{
os
<<
d
.
head
;
os
<<
d
.
head
<<
", "
<<
d
.
tail
;
return
os
;
return
os
;
}
}
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Dim
<
0
>
&
d
)
{
// Base case that allows us to output a Dim
return
os
;
// XXX I wish this could be an overload instead of a template
}
template
<
int
i
>
typename
std
::
enable_if
<
(
i
==
1
),
std
::
ostream
&>::
type
template
<
int
i
>
HOST
std
::
string
Dim
<
i
>::
to_string
()
const
{
operator
<<
(
std
::
ostream
&
os
,
const
Dim
<
i
>
&
d
)
{
std
::
stringstream
stream
;
os
<<
d
.
head
;
return
os
;
stream
<<
*
this
;
}
return
stream
.
str
();
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Dim
<
0
>
&
d
)
{
}
return
os
;
}
template
<
int
D
>
HOSTDEVICE
Dim
<
D
>
linear_to_dimension
(
int
linear_index
,
Dim
<
D
>
extents
)
{
template
<
int
i
>
HOST
std
::
string
Dim
<
i
>::
to_string
()
const
{
Dim
<
D
>
result
;
std
::
stringstream
stream
;
for
(
int
i
=
0
;
i
<
D
-
1
;
++
i
)
{
stream
<<
*
this
;
result
[
i
]
=
linear_index
%
extents
[
i
];
linear_index
/=
extents
[
i
];
return
stream
.
str
();
}
}
result
[
D
-
1
]
=
linear_index
;
template
<
int
D
>
HOSTDEVICE
Dim
<
D
>
linear_to_dimension
(
int
linear_index
,
return
result
;
Dim
<
D
>
extents
)
{
}
Dim
<
D
>
result
;
}
// namespace framework
for
(
int
i
=
0
;
i
<
D
-
1
;
++
i
)
{
result
[
i
]
=
linear_index
%
extents
[
i
];
linear_index
/=
extents
[
i
];
}
result
[
D
-
1
]
=
linear_index
;
return
result
;
}
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/executor.cpp
浏览文件 @
aef98218
...
@@ -23,84 +23,93 @@ SOFTWARE.
...
@@ -23,84 +23,93 @@ SOFTWARE.
#include "variable.h"
#include "variable.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
template
<
typename
Dtype
>
template
<
typename
Dtype
>
Executor
<
Dtype
>::
Executor
(
const
Program
<
Dtype
>
p
)
:
program_
(
p
)
{
Executor
<
Dtype
>::
Executor
(
const
Program
<
Dtype
>
p
)
:
program_
(
p
)
{
if
(
use_optimize_
)
{
if
(
use_optimize_
)
{
to_predict_program_
=
program_
.
optimizeProgram
;
to_predict_program_
=
program_
.
optimizeProgram
;
}
else
{
}
else
{
to_predict_program_
=
program_
.
originProgram
;
to_predict_program_
=
program_
.
originProgram
;
}
}
const
std
::
vector
<
std
::
shared_ptr
<
BlockDesc
>>
blocks
=
const
std
::
vector
<
std
::
shared_ptr
<
BlockDesc
>>
blocks
=
to_predict_program_
->
Blocks
();
to_predict_program_
->
Blocks
();
// std::cout << " **block size " << blocks.size() << std::endl;
// std::cout << " **block size " << blocks.size() << std::endl;
for
(
int
i
=
0
;
i
<
blocks
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
blocks
.
size
();
++
i
)
{
std
::
shared_ptr
<
BlockDesc
>
block_desc
=
blocks
[
i
];
std
::
shared_ptr
<
BlockDesc
>
block_desc
=
blocks
[
i
];
std
::
vector
<
std
::
shared_ptr
<
OpDesc
>>
ops
=
block_desc
->
Ops
();
std
::
vector
<
std
::
shared_ptr
<
OpDesc
>>
ops
=
block_desc
->
Ops
();
// std::cout << " ops " << ops.size() << std::endl;
// std::cout << " ops " << ops.size() << std::endl;
for
(
int
j
=
0
;
j
<
ops
.
size
();
++
j
)
{
for
(
int
j
=
0
;
j
<
ops
.
size
();
++
j
)
{
std
::
shared_ptr
<
OpDesc
>
op
=
ops
[
j
];
std
::
shared_ptr
<
OpDesc
>
op
=
ops
[
j
];
// std::cout << " input 0 " << op->Input("Input")[0] << std::endl;
// std::cout << " input 0 " << op->Input("Input")[0]
if
(
op
->
Type
()
==
"conv2d"
&&
op
->
Input
(
"Input"
)[
0
]
==
"pixel"
)
{
// << std::endl;
// std::cout << " conv2d attr size: " << op->GetAttrMap().size()
if
(
op
->
Type
()
==
"conv2d"
&&
// << std::endl;
op
->
Input
(
"Input"
)[
0
]
==
"pixel"
)
{
// std::cout << " input size: " << op->GetInputs().size() <<
// std::cout << " conv2d attr size: " <<
// std::endl;
// op->GetAttrMap().size()
// << std::endl;
// std::cout << " input size: " <<
// op->GetInputs().size() <<
// std::endl;
// std::cout << " output size: " << op->GetOutputs().size() <<
// std::cout << " output size: " <<
// std::endl;
// op->GetOutputs().size() <<
// std::endl;
Attribute
strides_attr
=
op
->
GetAttrMap
().
at
(
"strides"
);
Attribute
strides_attr
=
op
->
GetAttrMap
().
at
(
"strides"
);
std
::
vector
<
int
>
stride
=
strides_attr
.
Get
<
std
::
vector
<
int
>>
();
std
::
vector
<
int
>
stride
=
for
(
int
k
=
0
;
k
<
stride
.
size
();
++
k
)
{
strides_attr
.
Get
<
std
::
vector
<
int
>>
();
// std::cout << " stride " << stride[k] << std::endl;
for
(
int
k
=
0
;
k
<
stride
.
size
();
++
k
)
{
}
// std::cout << " stride " << stride[k] <<
// std::endl;
}
std
::
shared_ptr
<
operators
::
ConvOp
<
Dtype
,
float
>>
conv
=
std
::
shared_ptr
<
operators
::
ConvOp
<
Dtype
,
float
>>
conv
=
std
::
make_shared
<
operators
::
ConvOp
<
Dtype
,
float
>>
(
std
::
make_shared
<
operators
::
ConvOp
<
Dtype
,
float
>>
(
op
->
Type
(),
op
->
GetInputs
(),
op
->
GetOutputs
(),
op
->
GetAttrMap
(),
op
->
Type
(),
op
->
GetInputs
(),
op
->
GetOutputs
(),
program_
.
scope
);
op
->
GetAttrMap
(),
program_
.
scope
);
ops_of_block_
[
*
block_desc
.
get
()].
push_back
(
conv
);
ops_of_block_
[
*
block_desc
.
get
()].
push_back
(
conv
);
}
}
}
}
}
}
}
}
template
<
typename
Dtype
>
template
<
typename
Dtype
>
std
::
shared_ptr
<
Tensor
>
Executor
<
Dtype
>::
predict
(
Tensor
&
t
)
{
std
::
shared_ptr
<
Tensor
>
Executor
<
Dtype
>::
predict
(
Tensor
&
t
)
{
// feed
// feed
auto
scope
=
program_
.
scope
;
auto
scope
=
program_
.
scope
;
Variable
*
g_feed_value
=
scope
->
Var
(
"pixel"
);
Variable
*
g_feed_value
=
scope
->
Var
(
"pixel"
);
auto
tensor
=
g_feed_value
->
GetMutable
<
Tensor
>
();
auto
tensor
=
g_feed_value
->
GetMutable
<
Tensor
>
();
tensor
->
ShareDataWith
(
t
);
tensor
->
ShareDataWith
(
t
);
Variable
*
con_output
=
scope
->
Var
(
"conv2d_0.tmp_0"
);
Variable
*
con_output
=
scope
->
Var
(
"conv2d_0.tmp_0"
);
Tensor
*
output_tensor
=
con_output
->
GetMutable
<
Tensor
>
();
Tensor
*
output_tensor
=
con_output
->
GetMutable
<
Tensor
>
();
output_tensor
->
mutable_data
<
float
>
({
1
,
16
,
32
,
32
});
output_tensor
->
mutable_data
<
float
>
({
1
,
16
,
32
,
32
});
// std::cout << typeid(output_tensor).name() << std::endl;
// std::cout << typeid(output_tensor).name() << std::endl;
// std::cout << "output_tensor dims: " << output_tensor->dims() << std::endl;
// std::cout << "output_tensor dims: " << output_tensor->dims() <<
// std::endl;
std
::
shared_ptr
<
Tensor
>
out_tensor
=
std
::
make_shared
<
LoDTensor
>
();
std
::
shared_ptr
<
Tensor
>
out_tensor
=
std
::
make_shared
<
LoDTensor
>
();
out_tensor
.
reset
(
output_tensor
);
out_tensor
.
reset
(
output_tensor
);
predict
(
t
,
0
);
predict
(
t
,
0
);
return
out_tensor
;
return
out_tensor
;
}
}
template
<
typename
Dtype
>
template
<
typename
Dtype
>
void
Executor
<
Dtype
>::
predict
(
const
Tensor
&
t
,
int
block_id
)
{
void
Executor
<
Dtype
>::
predict
(
const
Tensor
&
t
,
int
block_id
)
{
std
::
shared_ptr
<
BlockDesc
>
to_predict_block
=
std
::
shared_ptr
<
BlockDesc
>
to_predict_block
=
to_predict_program_
->
Block
(
block_id
);
to_predict_program_
->
Block
(
block_id
);
for
(
int
j
=
0
;
j
<
ops_of_block_
[
*
to_predict_block
.
get
()].
size
();
++
j
)
{
for
(
int
j
=
0
;
j
<
ops_of_block_
[
*
to_predict_block
.
get
()].
size
();
auto
op
=
ops_of_block_
[
*
to_predict_block
.
get
()][
j
];
++
j
)
{
// std::cout << "开始run" << std::endl;
auto
op
=
ops_of_block_
[
*
to_predict_block
.
get
()][
j
];
op
->
Run
();
// std::cout << "开始run" << std::endl;
}
op
->
Run
();
}
}
}
template
class
Executor
<
CPU
>;
template
class
Executor
<
CPU
>;
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/executor.h
浏览文件 @
aef98218
...
@@ -32,22 +32,22 @@ SOFTWARE.
...
@@ -32,22 +32,22 @@ SOFTWARE.
#include "variable.h"
#include "variable.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
template
<
typename
Dtype
>
class
Executor
{
template
<
typename
Dtype
>
class
Executor
{
public:
public:
Executor
(
const
Program
<
Dtype
>
p
);
Executor
(
const
Program
<
Dtype
>
p
);
std
::
shared_ptr
<
Tensor
>
predict
(
Tensor
&
t
);
std
::
shared_ptr
<
Tensor
>
predict
(
Tensor
&
t
);
private:
private:
const
framework
::
Program
<
Dtype
>
program_
;
const
framework
::
Program
<
Dtype
>
program_
;
std
::
shared_ptr
<
ProgramDesc
>
to_predict_program_
;
std
::
shared_ptr
<
ProgramDesc
>
to_predict_program_
;
void
predict
(
const
Tensor
&
t
,
int
block_id
);
void
predict
(
const
Tensor
&
t
,
int
block_id
);
std
::
map
<
framework
::
BlockDesc
,
std
::
map
<
framework
::
BlockDesc
,
std
::
vector
<
std
::
shared_ptr
<
OperatorBase
<
Dtype
>>>>
std
::
vector
<
std
::
shared_ptr
<
OperatorBase
<
Dtype
>>>>
ops_of_block_
;
ops_of_block_
;
bool
use_optimize_
=
false
;
bool
use_optimize_
=
false
;
};
};
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/framework.pb.cpp
浏览文件 @
aef98218
因为 它太大了无法显示 source diff 。你可以改为
查看blob
。
src/framework/framework.pb.h
浏览文件 @
aef98218
因为 它太大了无法显示 source diff 。你可以改为
查看blob
。
src/framework/lod_tensor.cc
浏览文件 @
aef98218
...
@@ -19,280 +19,304 @@ limitations under the License. */
...
@@ -19,280 +19,304 @@ limitations under the License. */
#include <string.h>
#include <string.h>
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
LoD
&
lod
)
{
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
LoD
&
lod
)
{
os
<<
"{"
;
os
<<
"{"
;
for
(
auto
&
v
:
lod
)
{
for
(
auto
&
v
:
lod
)
{
os
<<
"{"
;
os
<<
"{"
;
bool
is_first
=
true
;
bool
is_first
=
true
;
for
(
auto
&
i
:
v
)
{
for
(
auto
&
i
:
v
)
{
if
(
is_first
)
{
if
(
is_first
)
{
os
<<
i
;
os
<<
i
;
is_first
=
false
;
is_first
=
false
;
}
else
{
}
else
{
os
<<
", "
<<
i
;
os
<<
", "
<<
i
;
}
}
}
}
os
<<
"}"
;
os
<<
"}"
;
}
}
os
<<
"}"
;
os
<<
"}"
;
return
os
;
return
os
;
}
}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
LoDTensor
&
t
)
{
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
LoDTensor
&
t
)
{
// PADDLE_ENFORCE(t.type().hash_code() == typeid(float).hash_code());
// PADDLE_ENFORCE(t.type().hash_code() ==
// typeid(float).hash_code());
// if (!platform::is_cpu_place(t.place())) {
// LoDTensor tt;
// if (!platform::is_cpu_place(t.place())) {
// framework::TensorCopy(t, platform::CPUPlace(), &tt);
// LoDTensor tt;
// platform::DeviceContextPool &pool =
// framework::TensorCopy(t, platform::CPUPlace(), &tt);
// platform::DeviceContextPool::Instance(); auto &dev_ctx =
// platform::DeviceContextPool &pool =
// *pool.Get(t.place()); dev_ctx.Wait();
// platform::DeviceContextPool::Instance(); auto &dev_ctx =
//
// *pool.Get(t.place()); dev_ctx.Wait();
// os << tt;
//
// return os;
// os << tt;
// }
// return os;
// }
os
<<
"dim: "
<<
t
.
dims
()
<<
"
\n
"
;
os
<<
"lod: "
<<
t
.
lod
()
<<
"
\n
"
;
os
<<
"dim: "
<<
t
.
dims
()
<<
"
\n
"
;
os
<<
"lod: "
<<
t
.
lod
()
<<
"
\n
"
;
// only print first ten elements
int64_t
size
=
t
.
numel
()
<
10
?
t
.
numel
()
:
10
;
// only print first ten elements
for
(
int64_t
i
=
0
;
i
<
size
;
++
i
)
{
int64_t
size
=
t
.
numel
()
<
10
?
t
.
numel
()
:
10
;
os
<<
t
.
data
<
float
>
()[
i
]
<<
" "
;
for
(
int64_t
i
=
0
;
i
<
size
;
++
i
)
{
}
os
<<
t
.
data
<
float
>
()[
i
]
<<
" "
;
}
return
os
;
}
return
os
;
}
std
::
string
LoDToString
(
const
LoD
&
lod
)
{
std
::
ostringstream
stream
;
std
::
string
LoDToString
(
const
LoD
&
lod
)
{
stream
<<
lod
;
std
::
ostringstream
stream
;
return
stream
.
str
();
stream
<<
lod
;
}
return
stream
.
str
();
}
LoD
SliceInLevel
(
const
LoD
&
in
,
size_t
level
,
size_t
elem_begin
,
size_t
elem_end
)
{
LoD
SliceInLevel
(
const
LoD
&
in
,
size_t
level
,
size_t
elem_begin
,
// PADDLE_ENFORCE_LT(level, in.size());
size_t
elem_end
)
{
// PADDLE_ENFORCE_LT(elem_end, in[level].size());
// PADDLE_ENFORCE_LT(level, in.size());
// PADDLE_ENFORCE_LT(elem_end, in[level].size());
LoD
res
;
res
.
resize
(
in
.
size
()
-
level
);
LoD
res
;
// copy the first level
res
.
resize
(
in
.
size
()
-
level
);
res
[
0
].
assign
(
in
[
level
].
begin
()
+
elem_begin
,
// copy the first level
in
[
level
].
begin
()
+
elem_end
+
1
);
res
[
0
].
assign
(
in
[
level
].
begin
()
+
elem_begin
,
for
(
size_t
lvl
=
1
;
lvl
<
res
.
size
();
lvl
++
)
{
in
[
level
].
begin
()
+
elem_end
+
1
);
const
auto
&
in_level
=
in
[
level
+
lvl
];
for
(
size_t
lvl
=
1
;
lvl
<
res
.
size
();
lvl
++
)
{
const
auto
&
above_level
=
res
[
lvl
-
1
];
const
auto
&
in_level
=
in
[
level
+
lvl
];
auto
&
out_level
=
res
[
lvl
];
const
auto
&
above_level
=
res
[
lvl
-
1
];
out_level
.
assign
(
in_level
.
begin
()
+
above_level
.
front
(),
auto
&
out_level
=
res
[
lvl
];
in_level
.
begin
()
+
above_level
.
back
()
+
1
);
out_level
.
assign
(
in_level
.
begin
()
+
above_level
.
front
(),
}
in_level
.
begin
()
+
above_level
.
back
()
+
1
);
for
(
size_t
lvl
=
0
;
lvl
<
res
.
size
();
lvl
++
)
{
}
// to make the first offset equals 0, all the elements minus the first
for
(
size_t
lvl
=
0
;
lvl
<
res
.
size
();
lvl
++
)
{
// element
// to make the first offset equals 0, all the elements minus the
size_t
front
=
res
[
lvl
].
front
();
// first
for
(
auto
&
ele
:
res
[
lvl
])
{
// element
ele
-=
front
;
size_t
front
=
res
[
lvl
].
front
();
}
for
(
auto
&
ele
:
res
[
lvl
])
{
}
ele
-=
front
;
return
res
;
}
}
}
return
res
;
LoD
ToAbsOffset
(
const
LoD
&
in
)
{
}
// the lowest level stores relative offsets
if
(
in
.
empty
()
||
in
.
size
()
==
1
)
LoD
ToAbsOffset
(
const
LoD
&
in
)
{
return
in
;
// the lowest level stores relative offsets
LoD
result
=
in
;
if
(
in
.
empty
()
||
in
.
size
()
==
1
)
for
(
auto
level
=
static_cast
<
int
>
(
in
.
size
()
-
2
);
level
>=
0
;
level
--
)
{
return
in
;
for
(
size_t
i
=
0
;
i
<
in
[
level
].
size
();
++
i
)
{
LoD
result
=
in
;
size_t
index
=
in
[
level
][
i
];
for
(
auto
level
=
static_cast
<
int
>
(
in
.
size
()
-
2
);
level
>=
0
;
result
[
level
][
i
]
=
result
[
level
+
1
][
index
];
level
--
)
{
}
for
(
size_t
i
=
0
;
i
<
in
[
level
].
size
();
++
i
)
{
}
size_t
index
=
in
[
level
][
i
];
return
result
;
result
[
level
][
i
]
=
result
[
level
+
1
][
index
];
}
}
}
bool
operator
==
(
const
LoD
&
a
,
const
LoD
&
b
)
{
return
result
;
if
(
a
.
size
()
!=
b
.
size
())
{
}
return
false
;
}
bool
operator
==
(
const
LoD
&
a
,
const
LoD
&
b
)
{
if
(
a
.
size
()
!=
b
.
size
())
{
for
(
size_t
i
=
0
;
i
<
a
.
size
();
i
++
)
{
return
false
;
const
auto
&
a_level
=
a
[
i
];
}
const
auto
&
b_level
=
b
[
i
];
if
(
a_level
.
size
()
!=
b_level
.
size
())
{
for
(
size_t
i
=
0
;
i
<
a
.
size
();
i
++
)
{
return
false
;
const
auto
&
a_level
=
a
[
i
];
}
const
auto
&
b_level
=
b
[
i
];
for
(
size_t
j
=
0
;
j
<
a_level
.
size
();
j
++
)
{
if
(
a_level
.
size
()
!=
b_level
.
size
())
{
if
(
a_level
[
j
]
!=
b_level
[
j
])
{
return
false
;
return
false
;
}
}
for
(
size_t
j
=
0
;
j
<
a_level
.
size
();
j
++
)
{
}
if
(
a_level
[
j
]
!=
b_level
[
j
])
{
}
return
false
;
return
true
;
}
}
}
}
bool
CheckLoD
(
const
LoD
&
in
,
int
tensor_height
)
{
if
(
in
.
empty
())
return
true
;
for
(
const
auto
&
level
:
in
)
{
// check: there should be more than 2 offsets existing in each level.
if
(
level
.
size
()
<
2
)
return
false
;
// check: the first offset(the begin offset) of each level should be 0.
if
(
level
.
front
()
!=
0
)
return
false
;
// check: all the offsets in a level should be ascending(no same items
// allows).
if
(
!
std
::
is_sorted
(
level
.
begin
(),
level
.
begin
(),
[](
size_t
a
,
size_t
b
)
{
if
(
a
<
b
)
return
true
;
return
true
;
return
false
;
}
}))
{
std
::
cout
<<
"ascending error"
;
bool
CheckLoD
(
const
LoD
&
in
,
int
tensor_height
)
{
return
false
;
if
(
in
.
empty
())
}
return
true
;
}
for
(
const
auto
&
level
:
in
)
{
// check: the lowest level's last offset should equals `tensor_height` if
// check: there should be more than 2 offsets existing in each
// tensor_height>0.
// level.
if
(
tensor_height
>
0
&&
(
size_t
)
tensor_height
!=
in
.
back
().
back
())
if
(
level
.
size
()
<
2
)
return
false
;
return
false
;
// check: the first offset(the begin offset) of each level
// check: the higher level's last offset should equals the lower level's
// should be 0.
// size-1.
if
(
level
.
front
()
!=
0
)
// NOTE LoD store the levels from top to bottom, so the higher level goes
return
false
;
// first.
// check: all the offsets in a level should be ascending(no same
for
(
size_t
level
=
0
;
level
<
in
.
size
()
-
1
;
level
++
)
{
// items
if
(
in
[
level
].
back
()
!=
in
[
level
+
1
].
size
()
-
1
)
// allows).
return
false
;
if
(
!
std
::
is_sorted
(
level
.
begin
(),
level
.
begin
(),
}
[](
size_t
a
,
size_t
b
)
{
return
true
;
if
(
a
<
b
)
}
return
true
;
return
false
;
bool
CheckAbsLoD
(
const
LoD
&
in
,
int
tensor_height
)
{
}))
{
if
(
in
.
empty
())
std
::
cout
<<
"ascending error"
;
return
true
;
return
false
;
for
(
const
auto
&
level
:
in
)
{
}
// check: all the offsets in a level should be ascending(no same items
}
// allows).
// check: the lowest level's last offset should equals
if
(
!
std
::
is_sorted
(
level
.
begin
(),
level
.
begin
(),
[](
size_t
a
,
size_t
b
)
{
// `tensor_height` if
if
(
a
<
b
)
// tensor_height>0.
if
(
tensor_height
>
0
&&
(
size_t
)
tensor_height
!=
in
.
back
().
back
())
return
false
;
// check: the higher level's last offset should equals the lower
// level's
// size-1.
// NOTE LoD store the levels from top to bottom, so the higher level
// goes
// first.
for
(
size_t
level
=
0
;
level
<
in
.
size
()
-
1
;
level
++
)
{
if
(
in
[
level
].
back
()
!=
in
[
level
+
1
].
size
()
-
1
)
return
false
;
}
return
true
;
return
true
;
return
false
;
}
}))
{
return
false
;
bool
CheckAbsLoD
(
const
LoD
&
in
,
int
tensor_height
)
{
}
if
(
in
.
empty
())
return
true
;
// check: there should be more than 2 offsets existing in each level.
for
(
const
auto
&
level
:
in
)
{
if
(
level
.
size
()
<
2
)
// check: all the offsets in a level should be ascending(no same
return
false
;
// items
// allows).
// check: the first offset of each level should be 0, and the last should be
if
(
!
std
::
is_sorted
(
level
.
begin
(),
level
.
begin
(),
// the same(the height of underlying tensor).
[](
size_t
a
,
size_t
b
)
{
if
(
level
.
front
()
!=
0
)
if
(
a
<
b
)
return
false
;
return
true
;
if
(
tensor_height
<
0
)
{
return
false
;
tensor_height
=
level
.
back
();
}))
{
}
else
if
((
size_t
)
tensor_height
!=
level
.
back
())
{
return
false
;
return
false
;
}
}
}
// check: there should be more than 2 offsets existing in each
return
true
;
// level.
}
if
(
level
.
size
()
<
2
)
return
false
;
using
LoDAndOffset
=
std
::
pair
<
LoD
,
std
::
pair
<
size_t
,
size_t
>>
;
// check: the first offset of each level should be 0, and the
LoDAndOffset
GetSubLoDAndAbsoluteOffset
(
const
LoD
&
lod
,
size_t
start_idx
,
// last should be
size_t
end_idx
,
size_t
start_level
)
{
// the same(the height of underlying tensor).
LoD
sub_lod
;
if
(
level
.
front
()
!=
0
)
return
false
;
for
(
size_t
level_idx
=
start_level
;
level_idx
<
lod
.
size
();
++
level_idx
)
{
if
(
tensor_height
<
0
)
{
// PADDLE_ENFORCE_LE(start_idx, end_idx);
tensor_height
=
level
.
back
();
// PADDLE_ENFORCE_LT(end_idx, lod[level_idx].size());
}
else
if
((
size_t
)
tensor_height
!=
level
.
back
())
{
std
::
vector
<
size_t
>
level_lens
;
return
false
;
for
(
size_t
i
=
start_idx
;
i
<
end_idx
;
++
i
)
{
}
level_lens
.
push_back
(
lod
[
level_idx
][
i
+
1
]
-
lod
[
level_idx
][
i
]);
}
}
return
true
;
sub_lod
.
emplace_back
(
level_lens
);
}
start_idx
=
lod
[
level_idx
][
start_idx
];
end_idx
=
lod
[
level_idx
][
end_idx
];
using
LoDAndOffset
=
std
::
pair
<
LoD
,
std
::
pair
<
size_t
,
size_t
>>
;
}
LoDAndOffset
GetSubLoDAndAbsoluteOffset
(
const
LoD
&
lod
,
return
LoDAndOffset
{
sub_lod
,
{
start_idx
,
end_idx
}};
size_t
start_idx
,
}
size_t
end_idx
,
size_t
start_level
)
{
void
AppendLoD
(
LoD
*
lod
,
const
LoD
&
lod_length
)
{
LoD
sub_lod
;
// PADDLE_ENFORCE(
// lod->empty() || lod->size() == lod_length.size(),
for
(
size_t
level_idx
=
start_level
;
level_idx
<
lod
.
size
();
// "The lod_length should has the same size with the appended lod.");
++
level_idx
)
{
if
(
lod
->
empty
())
{
// PADDLE_ENFORCE_LE(start_idx, end_idx);
for
(
size_t
i
=
0
;
i
<
lod_length
.
size
();
++
i
)
{
// PADDLE_ENFORCE_LT(end_idx, lod[level_idx].size());
lod
->
emplace_back
(
1
,
0
);
// size = 1, value = 0;
std
::
vector
<
size_t
>
level_lens
;
}
for
(
size_t
i
=
start_idx
;
i
<
end_idx
;
++
i
)
{
*
lod
=
LoD
(
lod_length
.
size
(),
std
::
vector
<
size_t
>
({
0
}));
level_lens
.
push_back
(
lod
[
level_idx
][
i
+
1
]
-
}
lod
[
level_idx
][
i
]);
for
(
size_t
i
=
0
;
i
<
lod
->
size
();
++
i
)
{
}
auto
&
level
=
(
*
lod
)[
i
];
sub_lod
.
emplace_back
(
level_lens
);
for
(
size_t
len
:
lod_length
[
i
])
{
start_idx
=
lod
[
level_idx
][
start_idx
];
level
.
push_back
(
level
.
back
()
+
len
);
end_idx
=
lod
[
level_idx
][
end_idx
];
}
}
}
}
return
LoDAndOffset
{
sub_lod
,
{
start_idx
,
end_idx
}};
}
void
SerializeToStream
(
std
::
ostream
&
os
,
const
LoDTensor
&
tensor
)
{
{
// the 1st field, uint32_t version for LoDTensor
void
AppendLoD
(
LoD
*
lod
,
const
LoD
&
lod_length
)
{
constexpr
uint32_t
version
=
0
;
// PADDLE_ENFORCE(
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
version
),
sizeof
(
version
));
// lod->empty() || lod->size() == lod_length.size(),
}
// "The lod_length should has the same size with the appended
{
// lod.");
// the 2st field, LoD information
if
(
lod
->
empty
())
{
// uint64_t lod_level
for
(
size_t
i
=
0
;
i
<
lod_length
.
size
();
++
i
)
{
// uint64_t lod_level_1 size in byte.
lod
->
emplace_back
(
1
,
0
);
// size = 1, value = 0;
// int* lod_level_1 data
}
// ...
*
lod
=
LoD
(
lod_length
.
size
(),
std
::
vector
<
size_t
>
({
0
}));
auto
lod
=
tensor
.
lod
();
}
uint64_t
size
=
lod
.
size
();
for
(
size_t
i
=
0
;
i
<
lod
->
size
();
++
i
)
{
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
size
),
sizeof
(
size
));
auto
&
level
=
(
*
lod
)[
i
];
for
(
size_t
len
:
lod_length
[
i
])
{
for
(
auto
&
each
:
lod
)
{
level
.
push_back
(
level
.
back
()
+
len
);
size
=
each
.
size
()
*
sizeof
(
framework
::
LoD
::
value_type
::
value_type
);
}
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
size
),
sizeof
(
size
));
}
os
.
write
(
reinterpret_cast
<
const
char
*>
(
each
.
data
()),
}
static_cast
<
std
::
streamsize
>
(
size
));
}
void
SerializeToStream
(
std
::
ostream
&
os
,
const
LoDTensor
&
tensor
)
{
}
{
// the 1st field, uint32_t version for LoDTensor
// the 3st field, Tensor
constexpr
uint32_t
version
=
0
;
TensorToStream
(
os
,
static_cast
<
Tensor
>
(
tensor
));
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
version
),
}
sizeof
(
version
));
}
void
DeserializeFromStream
(
std
::
istream
&
is
,
LoDTensor
*
tensor
)
{
{
{
// the 2st field, LoD information
// the 1st field, unit32_t version for LoDTensor
// uint64_t lod_level
uint32_t
version
;
// uint64_t lod_level_1 size in byte.
is
.
read
(
reinterpret_cast
<
char
*>
(
&
version
),
sizeof
(
version
));
// int* lod_level_1 data
// PADDLE_ENFORCE_EQ(version, 0U, "Only version 0 is supported");
// ...
}
auto
lod
=
tensor
.
lod
();
{
uint64_t
size
=
lod
.
size
();
// the 2st field, LoD information
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
size
),
sizeof
(
size
));
uint64_t
lod_level
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
lod_level
),
sizeof
(
lod_level
));
for
(
auto
&
each
:
lod
)
{
auto
&
lod
=
*
tensor
->
mutable_lod
();
size
=
each
.
size
()
*
lod
.
resize
(
lod_level
);
sizeof
(
framework
::
LoD
::
value_type
::
value_type
);
for
(
uint64_t
i
=
0
;
i
<
lod_level
;
++
i
)
{
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
size
),
uint64_t
size
;
sizeof
(
size
));
is
.
read
(
reinterpret_cast
<
char
*>
(
&
size
),
sizeof
(
size
));
os
.
write
(
reinterpret_cast
<
const
char
*>
(
each
.
data
()),
std
::
vector
<
size_t
>
tmp
(
size
/
sizeof
(
size_t
));
static_cast
<
std
::
streamsize
>
(
size
));
is
.
read
(
reinterpret_cast
<
char
*>
(
tmp
.
data
()),
}
static_cast
<
std
::
streamsize
>
(
size
));
}
lod
[
i
]
=
tmp
;
// the 3st field, Tensor
}
TensorToStream
(
os
,
static_cast
<
Tensor
>
(
tensor
));
}
}
// the 3st filed, Tensor
TensorFromStream
(
is
,
static_cast
<
Tensor
*>
(
tensor
));
void
DeserializeFromStream
(
std
::
istream
&
is
,
LoDTensor
*
tensor
)
{
}
{
// the 1st field, unit32_t version for LoDTensor
}
// namespace framework
uint32_t
version
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
version
),
sizeof
(
version
));
// PADDLE_ENFORCE_EQ(version, 0U, "Only version 0 is
// supported");
}
{
// the 2st field, LoD information
uint64_t
lod_level
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
lod_level
),
sizeof
(
lod_level
));
auto
&
lod
=
*
tensor
->
mutable_lod
();
lod
.
resize
(
lod_level
);
for
(
uint64_t
i
=
0
;
i
<
lod_level
;
++
i
)
{
uint64_t
size
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
size
),
sizeof
(
size
));
std
::
vector
<
size_t
>
tmp
(
size
/
sizeof
(
size_t
));
is
.
read
(
reinterpret_cast
<
char
*>
(
tmp
.
data
()),
static_cast
<
std
::
streamsize
>
(
size
));
lod
[
i
]
=
tmp
;
}
}
// the 3st filed, Tensor
TensorFromStream
(
is
,
static_cast
<
Tensor
*>
(
tensor
));
}
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/lod_tensor.h
浏览文件 @
aef98218
...
@@ -23,178 +23,190 @@ limitations under the License. */
...
@@ -23,178 +23,190 @@ limitations under the License. */
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
/*
/*
* LoD is short for Level of Details.
* LoD is short for Level of Details.
*
*
* - in a level, each element indicates relative offset of the lower level
* - in a level, each element indicates relative offset of the lower
* - the first element should be 0 and that indicates that this sequence start
* level
* from 0
* - the first element should be 0 and that indicates that this sequence
* - each sequence's begin and end(no-inclusive) is level[id, id+1]
* start
*
* from 0
* For example:
* - each sequence's begin and end(no-inclusive) is level[id, id+1]
* 3-level LoD stores
*
*
* For example:
* 0 2 3
* 3-level LoD stores
* 0 2 4 7
*
* 0 2 5 7 10 12 15 20
* 0 2 3
*/
* 0 2 4 7
using
LoD
=
std
::
vector
<
std
::
vector
<
size_t
>>
;
* 0 2 5 7 10 12 15 20
*/
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
LoD
&
lod
);
using
LoD
=
std
::
vector
<
std
::
vector
<
size_t
>>
;
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
LoDTensor
&
t
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
LoD
&
lod
);
std
::
string
LoDToString
(
const
LoD
&
lod
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
LoDTensor
&
t
);
LoD
SliceInLevel
(
const
LoD
&
in
,
size_t
level
,
size_t
elem_begin
,
std
::
string
LoDToString
(
const
LoD
&
lod
);
size_t
elem_end
);
LoD
SliceInLevel
(
const
LoD
&
in
,
size_t
level
,
size_t
elem_begin
,
/*
size_t
elem_end
);
* Transform an LoD from relative offsets to absolute offsets.
*/
/*
LoD
ToAbsOffset
(
const
LoD
&
in
);
* Transform an LoD from relative offsets to absolute offsets.
*/
bool
operator
==
(
const
LoD
&
a
,
const
LoD
&
b
);
LoD
ToAbsOffset
(
const
LoD
&
in
);
/*
bool
operator
==
(
const
LoD
&
a
,
const
LoD
&
b
);
* Check whether this lod's format is valid.
*
/*
* ATTENTION:
* Check whether this lod's format is valid.
* - Empty lod is treated as valid.
*
*
* ATTENTION:
* It will check two things:
* - Empty lod is treated as valid.
*
*
* 1. all the offsets in a level should be ascending(no same items allows).
* It will check two things:
* 2. there should be more than 2 offsets existing in each level.
*
* 3. the higher level's last offset should equals the lower level's size-1.
* 1. all the offsets in a level should be ascending(no same items
* 4. the first offset(the begin offset) of each level should be 0.
* allows).
* 5. the lowest level's last offset should equals `tensor_height` if
* 2. there should be more than 2 offsets existing in each level.
* tensor_height>0.
* 3. the higher level's last offset should equals the lower level's
*/
* size-1.
* 4. the first offset(the begin offset) of each level should be 0.
bool
CheckLoD
(
const
LoD
&
in
,
int
tensor_height
=
-
1
);
* 5. the lowest level's last offset should equals `tensor_height` if
* tensor_height>0.
/*
*/
* Check whether this absolute lod's format is valid.
*
bool
CheckLoD
(
const
LoD
&
in
,
int
tensor_height
=
-
1
);
* ATTENTION:
* - Empty lod is treated as valid.
/*
*
* Check whether this absolute lod's format is valid.
* It will check two things:
*
* 1. all the offsets in a level should be ascending(no same items allows)
* ATTENTION:
* 2. there should be more than 2 offsets existing in each level.
* - Empty lod is treated as valid.
* 3. the first offset of each level should be 0, and the last should be the
*
* same(the height of underlying tensor) or `tensor_height` if
* It will check two things:
* tensor_height>0.
* 1. all the offsets in a level should be ascending(no same items
*/
* allows)
bool
CheckAbsLoD
(
const
LoD
&
in
,
int
tensor_height
=
-
1
);
* 2. there should be more than 2 offsets existing in each level.
* 3. the first offset of each level should be 0, and the last should
/*
* be the
* LoDTensor (Level of details Tensor)
* same(the height of underlying tensor) or `tensor_height` if
* see https://en.wikipedia.org/wiki/Level_of_details for reference.
* tensor_height>0.
*/
*/
class
LoDTensor
:
public
Tensor
{
bool
CheckAbsLoD
(
const
LoD
&
in
,
int
tensor_height
=
-
1
);
public:
LoDTensor
()
:
Tensor
()
{}
/*
* LoDTensor (Level of details Tensor)
explicit
LoDTensor
(
const
LoD
&
lod
)
:
lod_
(
lod
)
{}
* see https://en.wikipedia.org/wiki/Level_of_details for reference.
*/
void
set_lod
(
const
LoD
&
lod
)
{
lod_
=
lod
;
}
class
LoDTensor
:
public
Tensor
{
public:
const
LoD
&
lod
()
const
{
return
lod_
;
}
LoDTensor
()
:
Tensor
()
{}
LoD
*
mutable_lod
()
{
return
&
lod_
;
}
explicit
LoDTensor
(
const
LoD
&
lod
)
:
lod_
(
lod
)
{}
/*
void
set_lod
(
const
LoD
&
lod
)
{
lod_
=
lod
;
}
* Get the start offset and end offset of an element from LoD.
*/
const
LoD
&
lod
()
const
{
return
lod_
;
}
std
::
pair
<
size_t
,
size_t
>
lod_element
(
size_t
level
,
size_t
elem
)
const
{
// PADDLE_ENFORCE_LT(level, NumLevels());
LoD
*
mutable_lod
()
{
return
&
lod_
;
}
// PADDLE_ENFORCE_LT(elem, NumElements(level));
return
std
::
make_pair
((
lod_
)[
level
][
elem
],
(
lod_
)[
level
][
elem
+
1
]);
/*
}
* Get the start offset and end offset of an element from LoD.
*/
/*
std
::
pair
<
size_t
,
size_t
>
lod_element
(
size_t
level
,
* Number of LoDTensor's levels, each level has units of data, for example,
size_t
elem
)
const
{
* in the sentence's view, article, paragraph, sentence are 3 levels.
// PADDLE_ENFORCE_LT(level, NumLevels());
*/
// PADDLE_ENFORCE_LT(elem, NumElements(level));
size_t
NumLevels
()
const
{
return
lod_
.
size
();
}
return
std
::
make_pair
((
lod_
)[
level
][
elem
],
(
lod_
)[
level
][
elem
+
1
]);
/*
}
* Number of elements in a level.
*/
/*
size_t
NumElements
(
size_t
level
=
0
)
const
{
* Number of LoDTensor's levels, each level has units of data, for
// PADDLE_ENFORCE_LT(level, NumLevels());
* example,
// the last offset is the end of last element
* in the sentence's view, article, paragraph, sentence are 3
return
(
lod_
)[
level
].
size
()
-
1
;
* levels.
}
*/
size_t
NumLevels
()
const
{
return
lod_
.
size
();
}
private:
LoD
lod_
;
/*
};
* Number of elements in a level.
*/
/*
size_t
NumElements
(
size_t
level
=
0
)
const
{
* Expand the `source` to fit the LoD of `lod`. For example, a `source`
// PADDLE_ENFORCE_LT(level, NumLevels());
* LoDTensor is
// the last offset is the end of last element
* - LoD: [0, 2]
return
(
lod_
)[
level
].
size
()
-
1
;
* - tensor: [a0, a1]
}
* a `lod` is
* - LoD: [0 3 5]
private:
* returns a new LoDTensor
LoD
lod_
;
* - [a0 a0 a0 a1 a1]
};
*/
template
<
typename
T
>
/*
LoDTensor
LodExpand
(
const
LoDTensor
&
source
,
const
LoD
&
lod
,
size_t
level
)
{
* Expand the `source` to fit the LoD of `lod`. For example, a `source`
LoD
abs_lod
=
ToAbsOffset
(
lod
);
* LoDTensor is
const
auto
&
lod_level
=
lod
[
level
];
* - LoD: [0, 2]
size_t
num_instances
=
source
.
dims
()[
0
];
* - tensor: [a0, a1]
* a `lod` is
// new tensor
* - LoD: [0 3 5]
LoDTensor
tensor
;
* returns a new LoDTensor
tensor
.
set_lod
(
lod
);
* - [a0 a0 a0 a1 a1]
auto
dims
=
source
.
dims
();
*/
dims
[
0
]
=
lod_level
.
back
();
template
<
typename
T
>
tensor
.
Resize
(
dims
);
LoDTensor
LodExpand
(
const
LoDTensor
&
source
,
const
LoD
&
lod
,
tensor
.
mutable_data
<
T
>
();
size_t
level
)
{
LoD
abs_lod
=
ToAbsOffset
(
lod
);
// PADDLE_ENFORCE_EQ(num_instances, lod_level.size() - 1);
const
auto
&
lod_level
=
lod
[
level
];
for
(
size_t
ins
=
0
;
ins
<
num_instances
;
ins
++
)
{
size_t
num_instances
=
source
.
dims
()[
0
];
for
(
size_t
elem
=
lod_level
[
ins
];
elem
<
lod_level
[
ins
+
1
];
elem
++
)
{
auto
slice
=
tensor
.
Slice
(
elem
,
elem
+
1
);
// new tensor
TensorCopy
(
source
.
Slice
(
ins
,
ins
+
1
),
&
slice
);
LoDTensor
tensor
;
}
tensor
.
set_lod
(
lod
);
}
auto
dims
=
source
.
dims
();
return
tensor
;
dims
[
0
]
=
lod_level
.
back
();
}
tensor
.
Resize
(
dims
);
tensor
.
mutable_data
<
T
>
();
// Get the absolute offset of a lod[start_level][start_idx:end_idx] and
// relative length of details for every levels(i.e., [start_level: ]).
// PADDLE_ENFORCE_EQ(num_instances, lod_level.size() - 1);
//
for
(
size_t
ins
=
0
;
ins
<
num_instances
;
ins
++
)
{
// For example,
for
(
size_t
elem
=
lod_level
[
ins
];
elem
<
lod_level
[
ins
+
1
];
// lod = [[0, 3, 4, 8], [0, 9, 10, 11, 13, 17, 19, 22, 24]]
elem
++
)
{
// start_level = 0
auto
slice
=
tensor
.
Slice
(
elem
,
elem
+
1
);
// start_idx = 1
TensorCopy
(
source
.
Slice
(
ins
,
ins
+
1
),
&
slice
);
// end_idx = 3
}
//
}
// Returns:
return
tensor
;
// LoD = [[1, 4], [2, 4, 2, 3, 2]]
}
// pair<size_t, size_t> = {11, 24}
std
::
pair
<
LoD
,
std
::
pair
<
size_t
,
size_t
>>
// Get the absolute offset of a lod[start_level][start_idx:end_idx] and
GetSubLoDAndAbsoluteOffset
(
const
LoD
&
lod
,
size_t
start_idx
,
size_t
end_idx
,
// relative length of details for every levels(i.e., [start_level: ]).
size_t
start_level
);
//
// For example,
void
AppendLoD
(
LoD
*
lod
,
const
LoD
&
lod_length
);
// lod = [[0, 3, 4, 8], [0, 9, 10, 11, 13, 17, 19, 22, 24]]
// start_level = 0
/*
// start_idx = 1
* Serialize/Desiralize LoDTensor to std::ostream
// end_idx = 3
* You can pass ofstream or ostringstream to serilize to file
//
* or to a in memory string. GPU tensor will be copied to CPU.
// Returns:
*/
// LoD = [[1, 4], [2, 4, 2, 3, 2]]
void
SerializeToStream
(
std
::
ostream
&
os
,
const
LoDTensor
&
tensor
);
// pair<size_t, size_t> = {11, 24}
std
::
pair
<
LoD
,
std
::
pair
<
size_t
,
size_t
>>
void
DeserializeFromStream
(
std
::
istream
&
is
,
LoDTensor
*
tensor
);
GetSubLoDAndAbsoluteOffset
(
const
LoD
&
lod
,
size_t
start_idx
,
size_t
end_idx
,
size_t
start_level
);
}
// namespace framework
void
AppendLoD
(
LoD
*
lod
,
const
LoD
&
lod_length
);
/*
* Serialize/Desiralize LoDTensor to std::ostream
* You can pass ofstream or ostringstream to serilize to file
* or to a in memory string. GPU tensor will be copied to CPU.
*/
void
SerializeToStream
(
std
::
ostream
&
os
,
const
LoDTensor
&
tensor
);
void
DeserializeFromStream
(
std
::
istream
&
is
,
LoDTensor
*
tensor
);
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/op_desc.cpp
浏览文件 @
aef98218
...
@@ -5,55 +5,58 @@
...
@@ -5,55 +5,58 @@
#include "op_desc.h"
#include "op_desc.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
OpDesc
::
OpDesc
(
const
proto
::
OpDesc
&
desc
)
:
desc_
(
desc
)
{
OpDesc
::
OpDesc
(
const
proto
::
OpDesc
&
desc
)
:
desc_
(
desc
)
{
for
(
int
i
=
0
;
i
<
desc_
.
inputs_size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
desc_
.
inputs_size
();
++
i
)
{
const
proto
::
OpDesc
::
Var
&
var
=
desc_
.
inputs
(
i
);
const
proto
::
OpDesc
::
Var
&
var
=
desc_
.
inputs
(
i
);
std
::
vector
<
std
::
string
>
&
args
=
inputs_
[
var
.
parameter
()];
std
::
vector
<
std
::
string
>
&
args
=
inputs_
[
var
.
parameter
()];
int
arg_size
=
var
.
arguments_size
();
int
arg_size
=
var
.
arguments_size
();
for
(
int
j
=
0
;
j
<
arg_size
;
++
j
)
{
for
(
int
j
=
0
;
j
<
arg_size
;
++
j
)
{
args
.
push_back
(
var
.
arguments
(
j
));
args
.
push_back
(
var
.
arguments
(
j
));
}
}
}
}
for
(
int
i
=
0
;
i
<
desc_
.
outputs_size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
desc_
.
outputs_size
();
++
i
)
{
const
proto
::
OpDesc
::
Var
&
var
=
desc_
.
outputs
(
i
);
const
proto
::
OpDesc
::
Var
&
var
=
desc_
.
outputs
(
i
);
std
::
vector
<
std
::
string
>
&
args
=
outputs_
[
var
.
parameter
()];
std
::
vector
<
std
::
string
>
&
args
=
outputs_
[
var
.
parameter
()];
int
arg_size
=
var
.
arguments_size
();
int
arg_size
=
var
.
arguments_size
();
for
(
int
j
=
0
;
j
<
arg_size
;
++
j
)
{
for
(
int
j
=
0
;
j
<
arg_size
;
++
j
)
{
args
.
push_back
(
var
.
arguments
(
j
));
args
.
push_back
(
var
.
arguments
(
j
));
}
}
}
}
for
(
const
proto
::
OpDesc
::
Attr
&
attr
:
desc_
.
attrs
())
{
for
(
const
proto
::
OpDesc
::
Attr
&
attr
:
desc_
.
attrs
())
{
std
::
string
attr_name
=
attr
.
name
();
std
::
string
attr_name
=
attr
.
name
();
if
(
attr
.
type
()
!=
proto
::
AttrType
::
BLOCK
)
{
if
(
attr
.
type
()
!=
proto
::
AttrType
::
BLOCK
)
{
attrs_
[
attr_name
]
=
Attribute
::
GetAttrValue
(
attr
);
attrs_
[
attr_name
]
=
Attribute
::
GetAttrValue
(
attr
);
// if (attr.type() == proto::AttrType::INT){
// if (attr.type() == proto::AttrType::INT){
// std::cout << " attrName " << attr_name << " " <<
// std::cout << " attrName " << attr_name << " " <<
// attrs_[attr_name].Get<int>() << std::endl;
// attrs_[attr_name].Get<int>() << std::endl;
// }
// }
}
}
}
}
}
}
const
std
::
vector
<
std
::
string
>
&
OpDesc
::
Input
(
const
std
::
string
&
name
)
const
{
const
std
::
vector
<
std
::
string
>
&
return
inputs_
.
find
(
name
)
->
second
;
OpDesc
::
Input
(
const
std
::
string
&
name
)
const
{
}
return
inputs_
.
find
(
name
)
->
second
;
}
const
std
::
vector
<
std
::
string
>
&
OpDesc
::
Output
(
const
std
::
string
&
name
)
const
{
return
outputs_
.
find
(
name
)
->
second
;
const
std
::
vector
<
std
::
string
>
&
}
OpDesc
::
Output
(
const
std
::
string
&
name
)
const
{
return
outputs_
.
find
(
name
)
->
second
;
Attribute
OpDesc
::
GetAttr
(
const
std
::
string
&
name
)
const
{
}
auto
it
=
attrs_
.
find
(
name
);
return
it
->
second
;
Attribute
OpDesc
::
GetAttr
(
const
std
::
string
&
name
)
const
{
}
auto
it
=
attrs_
.
find
(
name
);
return
it
->
second
;
const
std
::
unordered_map
<
std
::
string
,
Attribute
>
&
OpDesc
::
GetAttrMap
()
const
{
}
return
attrs_
;
}
const
std
::
unordered_map
<
std
::
string
,
Attribute
>
&
OpDesc
::
GetAttrMap
()
const
{
}
// namespace framework
return
attrs_
;
}
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/op_desc.h
浏览文件 @
aef98218
...
@@ -23,29 +23,31 @@ SOFTWARE.
...
@@ -23,29 +23,31 @@ SOFTWARE.
#include "paddle_mobile_object.h"
#include "paddle_mobile_object.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
class
OpDesc
:
PaddleMobileObject
{
class
OpDesc
:
PaddleMobileObject
{
public:
public:
OpDesc
(
const
proto
::
OpDesc
&
desc
);
OpDesc
(
const
proto
::
OpDesc
&
desc
);
const
std
::
vector
<
std
::
string
>
&
Input
(
const
std
::
string
&
name
)
const
;
const
std
::
vector
<
std
::
string
>
&
const
std
::
vector
<
std
::
string
>
&
Output
(
const
std
::
string
&
name
)
const
;
Input
(
const
std
::
string
&
name
)
const
;
Attribute
GetAttr
(
const
std
::
string
&
name
)
const
;
const
std
::
vector
<
std
::
string
>
&
Output
(
const
std
::
string
&
name
)
const
;
Attribute
GetAttr
(
const
std
::
string
&
name
)
const
;
const
VariableNameMap
&
GetInputs
()
{
return
inputs_
;
}
const
VariableNameMap
&
GetInputs
()
{
return
inputs_
;
}
const
VariableNameMap
&
GetOutputs
()
{
return
outputs_
;
}
const
VariableNameMap
&
GetOutputs
()
{
return
outputs_
;
}
const
AttributeMap
&
GetAttrMap
()
const
;
const
AttributeMap
&
GetAttrMap
()
const
;
const
std
::
string
&
Type
()
{
return
desc_
.
type
();
};
const
std
::
string
&
Type
()
{
return
desc_
.
type
();
};
private:
private:
proto
::
OpDesc
desc_
;
proto
::
OpDesc
desc_
;
VariableNameMap
inputs_
;
VariableNameMap
inputs_
;
VariableNameMap
outputs_
;
VariableNameMap
outputs_
;
AttributeMap
attrs_
;
AttributeMap
attrs_
;
};
};
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/op_info.h
浏览文件 @
aef98218
...
@@ -22,70 +22,74 @@ SOFTWARE.
...
@@ -22,70 +22,74 @@ SOFTWARE.
#include "framework.pb.h"
#include "framework.pb.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
template
<
typename
Dtype
>
struct
OpInfo
{
template
<
typename
Dtype
>
struct
OpInfo
{
OpCreator
<
Dtype
>
creator_
;
OpCreator
<
Dtype
>
creator_
;
const
OpCreator
<
Dtype
>
&
Creator
()
const
{
const
OpCreator
<
Dtype
>
&
Creator
()
const
{
// PADDLE_ENFORCE_NOT_NULL(creator_,
// PADDLE_ENFORCE_NOT_NULL(creator_,
// "Operator Creator has not been registered");
// "Operator Creator has not been
return
creator_
;
// registered");
}
return
creator_
;
};
}
};
template
<
typename
Dtype
>
class
OpInfoMap
;
template
<
typename
Dtype
>
class
OpInfoMap
;
template
<
typename
Dtype
>
static
OpInfoMap
<
Dtype
>
*
g_op_info_map
=
nullptr
;
template
<
typename
Dtype
>
template
<
typename
Dtype
>
class
OpInfoMap
{
static
OpInfoMap
<
Dtype
>
*
g_op_info_map
=
nullptr
;
public:
static
OpInfoMap
&
Instance
()
{
template
<
typename
Dtype
>
class
OpInfoMap
{
if
(
g_op_info_map
<
Dtype
>
==
nullptr
)
{
public:
g_op_info_map
<
Dtype
>
=
new
OpInfoMap
();
static
OpInfoMap
&
Instance
()
{
}
if
(
g_op_info_map
<
Dtype
>
==
nullptr
)
{
return
*
g_op_info_map
<
Dtype
>
;
g_op_info_map
<
Dtype
>
=
new
OpInfoMap
();
};
}
return
*
g_op_info_map
<
Dtype
>
;
bool
Has
(
const
std
::
string
&
op_type
)
const
{
};
return
map_
.
find
(
op_type
)
!=
map_
.
end
();
}
bool
Has
(
const
std
::
string
&
op_type
)
const
{
return
map_
.
find
(
op_type
)
!=
map_
.
end
();
void
Insert
(
const
std
::
string
&
type
,
const
OpInfo
<
Dtype
>
&
info
)
{
}
// PADDLE_ENFORCE(!Has(type), "Operator %s has been registered", type);
map_
.
insert
({
type
,
info
});
void
Insert
(
const
std
::
string
&
type
,
const
OpInfo
<
Dtype
>
&
info
)
{
}
// PADDLE_ENFORCE(!Has(type), "Operator %s has been
// registered", type);
const
OpInfo
<
Dtype
>
&
Get
(
const
std
::
string
&
type
)
const
{
map_
.
insert
({
type
,
info
});
auto
op_info_ptr
=
GetNullable
(
type
);
}
// PADDLE_ENFORCE_NOT_NULL(op_info_ptr, "Operator %s has not been
// registered",
const
OpInfo
<
Dtype
>
&
Get
(
const
std
::
string
&
type
)
const
{
// type);
auto
op_info_ptr
=
GetNullable
(
type
);
return
*
op_info_ptr
;
// PADDLE_ENFORCE_NOT_NULL(op_info_ptr, "Operator %s has not
}
// been
// registered",
const
OpInfo
<
Dtype
>
*
GetNullable
(
const
std
::
string
&
type
)
const
{
// type);
auto
it
=
map_
.
find
(
type
);
return
*
op_info_ptr
;
if
(
it
==
map_
.
end
())
{
}
return
nullptr
;
}
else
{
const
OpInfo
<
Dtype
>
*
GetNullable
(
const
std
::
string
&
type
)
const
{
return
&
it
->
second
;
auto
it
=
map_
.
find
(
type
);
}
if
(
it
==
map_
.
end
())
{
}
return
nullptr
;
}
else
{
const
std
::
unordered_map
<
std
::
string
,
OpInfo
<
Dtype
>>
&
map
()
const
{
return
&
it
->
second
;
return
map_
;
}
}
}
std
::
unordered_map
<
std
::
string
,
OpInfo
<
Dtype
>>
*
mutable_map
()
{
const
std
::
unordered_map
<
std
::
string
,
OpInfo
<
Dtype
>>
&
map
()
const
{
return
&
map_
;
return
map_
;
}
}
private:
std
::
unordered_map
<
std
::
string
,
OpInfo
<
Dtype
>>
*
mutable_map
()
{
OpInfoMap
()
=
default
;
return
&
map_
;
std
::
unordered_map
<
std
::
string
,
OpInfo
<
Dtype
>>
map_
;
}
// DISABLE_COPY_AND_ASSIGN(OpInfoMap);
private:
};
OpInfoMap
()
=
default
;
std
::
unordered_map
<
std
::
string
,
OpInfo
<
Dtype
>>
map_
;
}
// namespace framework
// DISABLE_COPY_AND_ASSIGN(OpInfoMap);
};
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/op_kernel_type.h
浏览文件 @
aef98218
...
@@ -22,43 +22,51 @@ SOFTWARE.
...
@@ -22,43 +22,51 @@ SOFTWARE.
#include "framework.pb.h"
#include "framework.pb.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
struct
OpKernelType
{
struct
OpKernelType
{
struct
Hash
{
struct
Hash
{
size_t
operator
()(
const
OpKernelType
&
key
)
const
{
size_t
operator
()(
const
OpKernelType
&
key
)
const
{
int
data_type
=
static_cast
<
int
>
(
key
.
data_type_
)
<<
LEFT_SHIFT
;
int
data_type
=
static_cast
<
int
>
(
key
.
data_type_
)
int
data_layout
=
static_cast
<
int
>
(
key
.
data_layout_
)
<<
(
LEFT_SHIFT
*
2
);
<<
LEFT_SHIFT
;
int
data_layout
=
static_cast
<
int
>
(
key
.
data_layout_
)
<<
(
LEFT_SHIFT
*
2
);
std
::
hash
<
int
>
hasher
;
std
::
hash
<
int
>
hasher
;
return
hasher
(
data_type
+
data_layout
);
return
hasher
(
data_type
+
data_layout
);
}
}
};
};
// place, data_type, library_type kinds less than 2^8
// place, data_type, library_type kinds less than 2^8
constexpr
static
int
LEFT_SHIFT
=
8
;
constexpr
static
int
LEFT_SHIFT
=
8
;
proto
::
VarType
::
Type
data_type_
;
proto
::
VarType
::
Type
data_type_
;
DataLayout
data_layout_
;
DataLayout
data_layout_
;
OpKernelType
(
proto
::
VarType
::
Type
data_type
,
OpKernelType
(
proto
::
VarType
::
Type
data_type
,
DataLayout
data_layout
=
DataLayout
::
kAnyLayout
)
DataLayout
data_layout
=
DataLayout
::
kAnyLayout
)
:
data_type_
(
data_type
),
data_layout_
(
data_layout
)
{}
:
data_type_
(
data_type
),
data_layout_
(
data_layout
)
{}
bool
operator
==
(
const
OpKernelType
&
o
)
const
{
bool
operator
==
(
const
OpKernelType
&
o
)
const
{
return
data_type_
==
o
.
data_type_
&&
data_layout_
==
o
.
data_layout_
;
return
data_type_
==
o
.
data_type_
&&
}
data_layout_
==
o
.
data_layout_
;
}
bool
operator
!=
(
const
OpKernelType
&
o
)
const
{
return
!
(
*
this
==
o
);
}
bool
operator
!=
(
const
OpKernelType
&
o
)
const
{
};
return
!
(
*
this
==
o
);
}
};
inline
bool
NeedTransformLayout
(
const
DataLayout
&
l
,
const
DataLayout
&
r
)
{
inline
bool
NeedTransformLayout
(
const
DataLayout
&
l
,
return
l
!=
DataLayout
::
kAnyLayout
&&
r
!=
DataLayout
::
kAnyLayout
&&
l
!=
r
;
const
DataLayout
&
r
)
{
}
return
l
!=
DataLayout
::
kAnyLayout
&&
r
!=
DataLayout
::
kAnyLayout
&&
l
!=
r
;
}
inline
bool
TransFromNeeded
(
const
OpKernelType
&
l
,
const
OpKernelType
&
r
)
{
inline
bool
TransFromNeeded
(
const
OpKernelType
&
l
,
return
(
l
.
data_type_
!=
r
.
data_type_
)
||
const
OpKernelType
&
r
)
{
NeedTransformLayout
(
l
.
data_layout_
,
r
.
data_layout_
);
return
(
l
.
data_type_
!=
r
.
data_type_
)
||
}
NeedTransformLayout
(
l
.
data_layout_
,
r
.
data_layout_
);
}
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/op_proto_maker.h
浏览文件 @
aef98218
...
@@ -19,8 +19,8 @@ SOFTWARE.
...
@@ -19,8 +19,8 @@ SOFTWARE.
#pragma once
#pragma once
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
// this class not only make proto but also init attribute checkers.
// this class not only make proto but also init attribute checkers.
class
OpProtoAndCheckerMaker
{};
class
OpProtoAndCheckerMaker
{};
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/operator.cpp
浏览文件 @
aef98218
...
@@ -20,26 +20,26 @@ SOFTWARE.
...
@@ -20,26 +20,26 @@ SOFTWARE.
#include "op_info.h"
#include "op_info.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
template
<
typename
Dtype
>
template
<
typename
Dtype
>
OperatorBase
<
Dtype
>::
OperatorBase
(
const
std
::
string
&
type
,
OperatorBase
<
Dtype
>::
OperatorBase
(
const
std
::
string
&
type
,
const
VariableNameMap
&
inputs
,
const
VariableNameMap
&
inputs
,
const
VariableNameMap
&
outputs
,
const
VariableNameMap
&
outputs
,
const
AttributeMap
&
attrs
,
const
AttributeMap
&
attrs
,
std
::
shared_ptr
<
Scope
>
scope
)
std
::
shared_ptr
<
Scope
>
scope
)
:
type_
(
type
),
inputs_
(
inputs
),
outputs_
(
outputs
),
attrs_
(
attrs
),
:
type_
(
type
),
inputs_
(
inputs
),
outputs_
(
outputs
),
attrs_
(
attrs
),
scope_
(
scope
)
{
scope_
(
scope
)
{
CheckAllInputOutputSet
();
CheckAllInputOutputSet
();
}
}
template
<
typename
Dtype
>
void
OperatorBase
<
Dtype
>::
Run
()
{
RunImpl
();
}
template
<
typename
Dtype
>
void
OperatorBase
<
Dtype
>::
Run
()
{
RunImpl
();
}
template
<
typename
Dtype
>
template
<
typename
Dtype
>
void
OperatorBase
<
Dtype
>::
CheckAllInputOutputSet
()
const
{}
void
OperatorBase
<
Dtype
>::
CheckAllInputOutputSet
()
const
{}
template
class
OperatorBase
<
CPU
>;
template
class
OperatorBase
<
CPU
>;
template
class
OperatorWithKernel
<
CPU
>;
template
class
OperatorWithKernel
<
CPU
>;
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/operator.h
浏览文件 @
aef98218
...
@@ -33,53 +33,57 @@ SOFTWARE.
...
@@ -33,53 +33,57 @@ SOFTWARE.
#include "variable.h"
#include "variable.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
template
<
typename
Dtype
>
class
OperatorBase
:
PaddleMobileObject
{
template
<
typename
Dtype
>
class
OperatorBase
:
PaddleMobileObject
{
public:
public:
OperatorBase
(
const
std
::
string
&
type
,
const
VariableNameMap
&
inputs
,
OperatorBase
(
const
std
::
string
&
type
,
const
VariableNameMap
&
inputs
,
const
VariableNameMap
&
outputs
,
const
AttributeMap
&
attrs
,
const
VariableNameMap
&
outputs
,
std
::
shared_ptr
<
Scope
>
scope
);
const
AttributeMap
&
attrs
,
virtual
~
OperatorBase
()
{}
std
::
shared_ptr
<
Scope
>
scope
);
virtual
void
Run
();
virtual
~
OperatorBase
()
{}
const
VariableNameMap
&
Inputs
()
const
{
return
inputs_
;
}
virtual
void
Run
();
const
VariableNameMap
&
Outputs
()
const
{
return
outputs_
;
}
const
VariableNameMap
&
Inputs
()
const
{
return
inputs_
;
}
const
std
::
string
&
Type
()
const
{
return
type_
;
}
const
VariableNameMap
&
Outputs
()
const
{
return
outputs_
;
}
const
AttributeMap
&
Attrs
()
const
{
return
attrs_
;
}
const
std
::
string
&
Type
()
const
{
return
type_
;
}
const
AttributeMap
&
Attrs
()
const
{
return
attrs_
;
}
protected:
protected:
std
::
shared_ptr
<
Scope
>
scope_
;
std
::
shared_ptr
<
Scope
>
scope_
;
std
::
string
type_
;
std
::
string
type_
;
VariableNameMap
inputs_
;
VariableNameMap
inputs_
;
VariableNameMap
outputs_
;
VariableNameMap
outputs_
;
AttributeMap
attrs_
;
AttributeMap
attrs_
;
private:
private:
void
CheckAllInputOutputSet
()
const
;
void
CheckAllInputOutputSet
()
const
;
virtual
void
RunImpl
()
const
=
0
;
virtual
void
RunImpl
()
const
=
0
;
};
};
template
<
typename
Dtype
>
template
<
typename
Dtype
>
class
OperatorWithKernel
:
public
OperatorBase
<
Dtype
>
{
class
OperatorWithKernel
:
public
OperatorBase
<
Dtype
>
{
public:
public:
OperatorWithKernel
(
const
std
::
string
&
type
,
const
VariableNameMap
&
inputs
,
OperatorWithKernel
(
const
std
::
string
&
type
,
const
VariableNameMap
&
outputs
,
const
AttributeMap
&
attrs
,
const
VariableNameMap
&
inputs
,
std
::
shared_ptr
<
Scope
>
scope
)
const
VariableNameMap
&
outputs
,
:
OperatorBase
<
Dtype
>
(
type
,
inputs
,
outputs
,
attrs
,
scope
)
{}
const
AttributeMap
&
attrs
,
virtual
void
InferShape
()
const
=
0
;
std
::
shared_ptr
<
Scope
>
scope
)
:
OperatorBase
<
Dtype
>
(
type
,
inputs
,
outputs
,
attrs
,
scope
)
{}
virtual
void
InferShape
()
const
=
0
;
protected:
protected:
virtual
void
RunImpl
()
const
=
0
;
virtual
void
RunImpl
()
const
=
0
;
private:
private:
};
};
template
<
typename
Dtype
,
typename
P
>
class
OpKernelBase
:
PaddleMobileObject
{
template
<
typename
Dtype
,
typename
P
>
public:
class
OpKernelBase
:
PaddleMobileObject
{
virtual
void
Compute
(
const
P
&
para
)
const
=
0
;
public:
virtual
void
Compute
(
const
P
&
para
)
const
=
0
;
virtual
~
OpKernelBase
()
=
default
;
virtual
~
OpKernelBase
()
=
default
;
};
};
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/paddle_mobile_object.h
浏览文件 @
aef98218
...
@@ -23,14 +23,14 @@ SOFTWARE.
...
@@ -23,14 +23,14 @@ SOFTWARE.
namespace
paddle_mobile
{
namespace
paddle_mobile
{
class
PaddleMobileObject
{
class
PaddleMobileObject
{
public:
public:
virtual
inline
const
std
::
string
&
ToString
()
{
virtual
inline
const
std
::
string
&
ToString
()
{
char
address
[
128
]
=
{
0
};
char
address
[
128
]
=
{
0
};
sprintf
(
address
,
"%p"
,
this
);
sprintf
(
address
,
"%p"
,
this
);
return
std
::
string
(
address
);
return
std
::
string
(
address
);
}
}
private:
private:
};
};
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/program.cpp
浏览文件 @
aef98218
...
@@ -17,5 +17,5 @@ SOFTWARE.
...
@@ -17,5 +17,5 @@ SOFTWARE.
==============================================================================*/
==============================================================================*/
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{}
namespace
framework
{}
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/program.h
浏览文件 @
aef98218
...
@@ -24,17 +24,17 @@ SOFTWARE.
...
@@ -24,17 +24,17 @@ SOFTWARE.
#include "scope.h"
#include "scope.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
template
<
typename
Dtype
,
Precision
P
=
Precision
::
FP32
>
template
<
typename
Dtype
,
Precision
P
=
Precision
::
FP32
>
class
Program
:
PaddleMobileObject
{
class
Program
:
PaddleMobileObject
{
public:
public:
std
::
shared_ptr
<
ProgramDesc
>
originProgram
;
std
::
shared_ptr
<
ProgramDesc
>
originProgram
;
std
::
shared_ptr
<
ProgramDesc
>
optimizeProgram
;
std
::
shared_ptr
<
ProgramDesc
>
optimizeProgram
;
std
::
shared_ptr
<
Scope
>
scope
;
std
::
shared_ptr
<
Scope
>
scope
;
private:
private:
};
};
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/program_desc.cpp
浏览文件 @
aef98218
...
@@ -5,18 +5,18 @@
...
@@ -5,18 +5,18 @@
#include "program_desc.h"
#include "program_desc.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
ProgramDesc
::
ProgramDesc
(
const
proto
::
ProgramDesc
&
desc
)
:
desc_
(
desc
)
{
ProgramDesc
::
ProgramDesc
(
const
proto
::
ProgramDesc
&
desc
)
:
desc_
(
desc
)
{
for
(
auto
&
block_desc
:
*
desc_
.
mutable_blocks
())
{
for
(
auto
&
block_desc
:
*
desc_
.
mutable_blocks
())
{
// new framework::BlockDesc(block_desc)
// new framework::BlockDesc(block_desc)
blocks_
.
emplace_back
(
std
::
make_shared
<
BlockDesc
>
(
block_desc
));
blocks_
.
emplace_back
(
std
::
make_shared
<
BlockDesc
>
(
block_desc
));
}
}
}
}
std
::
shared_ptr
<
BlockDesc
>
ProgramDesc
::
Block
(
size_t
idx
)
{
std
::
shared_ptr
<
BlockDesc
>
ProgramDesc
::
Block
(
size_t
idx
)
{
return
blocks_
[
idx
];
return
blocks_
[
idx
];
}
}
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/program_desc.h
浏览文件 @
aef98218
...
@@ -25,18 +25,20 @@ SOFTWARE.
...
@@ -25,18 +25,20 @@ SOFTWARE.
#include "paddle_mobile_object.h"
#include "paddle_mobile_object.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
class
ProgramDesc
:
PaddleMobileObject
{
class
ProgramDesc
:
PaddleMobileObject
{
public:
public:
ProgramDesc
(
const
proto
::
ProgramDesc
&
desc
);
ProgramDesc
(
const
proto
::
ProgramDesc
&
desc
);
std
::
shared_ptr
<
BlockDesc
>
Block
(
size_t
idx
);
std
::
shared_ptr
<
BlockDesc
>
Block
(
size_t
idx
);
const
std
::
vector
<
std
::
shared_ptr
<
BlockDesc
>>
&
Blocks
()
{
return
blocks_
;
};
const
std
::
vector
<
std
::
shared_ptr
<
BlockDesc
>>
&
Blocks
()
{
return
blocks_
;
};
private:
private:
std
::
vector
<
std
::
shared_ptr
<
BlockDesc
>>
blocks_
;
std
::
vector
<
std
::
shared_ptr
<
BlockDesc
>>
blocks_
;
proto
::
ProgramDesc
desc_
;
proto
::
ProgramDesc
desc_
;
};
};
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/scope.cc
浏览文件 @
aef98218
...
@@ -4,113 +4,116 @@
...
@@ -4,113 +4,116 @@
#include <vector>
#include <vector>
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
Scope
&
Scope
::
NewScope
()
const
{
Scope
&
Scope
::
NewScope
()
const
{
std
::
unique_lock
<
std
::
mutex
>
lock
(
mutex_
);
std
::
unique_lock
<
std
::
mutex
>
lock
(
mutex_
);
kids_
.
push_back
(
new
Scope
(
this
));
kids_
.
push_back
(
new
Scope
(
this
));
return
*
kids_
.
back
();
return
*
kids_
.
back
();
}
}
Variable
*
Scope
::
Var
(
const
std
::
string
&
name
)
{
Variable
*
Scope
::
Var
(
const
std
::
string
&
name
)
{
auto
*
pvar
=
FindVarLocally
(
name
);
auto
*
pvar
=
FindVarLocally
(
name
);
if
(
pvar
!=
nullptr
)
{
if
(
pvar
!=
nullptr
)
{
return
pvar
;
return
pvar
;
};
};
pvar
=
new
Variable
;
pvar
=
new
Variable
;
vars_
[
name
]
=
pvar
;
vars_
[
name
]
=
pvar
;
pvar
->
name_
=
&
(
vars_
.
find
(
name
)
->
first
);
pvar
->
name_
=
&
(
vars_
.
find
(
name
)
->
first
);
return
pvar
;
return
pvar
;
}
}
// Variable* Scope::Var(std::string* name) {
// Variable* Scope::Var(std::string* name) {
// auto var_name = string::Sprintf("%p.%d", this, vars_.size());
// auto var_name = string::Sprintf("%p.%d", this,
// if (name != nullptr) {
// vars_.size());
// *name = var_name;
// if (name != nullptr) {
// }
// *name = var_name;
// return Var(var_name);
// }
// }
// return Var(var_name);
// }
Variable
*
Scope
::
FindVar
(
const
std
::
string
&
name
)
const
{
Variable
*
Scope
::
FindVar
(
const
std
::
string
&
name
)
const
{
auto
*
pvar
=
FindVarLocally
(
name
);
auto
*
pvar
=
FindVarLocally
(
name
);
if
(
pvar
!=
nullptr
)
{
if
(
pvar
!=
nullptr
)
{
return
pvar
;
return
pvar
;
}
}
return
(
parent_
==
nullptr
)
?
nullptr
:
parent_
->
FindVar
(
name
);
return
(
parent_
==
nullptr
)
?
nullptr
:
parent_
->
FindVar
(
name
);
}
}
const
Scope
*
Scope
::
FindScope
(
const
Variable
*
var
)
const
{
const
Scope
*
Scope
::
FindScope
(
const
Variable
*
var
)
const
{
for
(
auto
&
name_var
:
vars_
)
{
for
(
auto
&
name_var
:
vars_
)
{
if
(
name_var
.
second
==
var
)
{
if
(
name_var
.
second
==
var
)
{
return
this
;
return
this
;
}
}
}
}
return
(
parent_
==
nullptr
)
?
nullptr
:
parent_
->
FindScope
(
var
);
return
(
parent_
==
nullptr
)
?
nullptr
:
parent_
->
FindScope
(
var
);
}
}
void
Scope
::
DropKids
()
{
void
Scope
::
DropKids
()
{
for
(
Scope
*
s
:
kids_
)
{
for
(
Scope
*
s
:
kids_
)
{
delete
s
;
delete
s
;
}
}
kids_
.
clear
();
kids_
.
clear
();
}
}
std
::
vector
<
std
::
string
>
Scope
::
LocalVarNames
()
const
{
std
::
vector
<
std
::
string
>
Scope
::
LocalVarNames
()
const
{
std
::
vector
<
std
::
string
>
known_vars
;
std
::
vector
<
std
::
string
>
known_vars
;
known_vars
.
reserve
(
vars_
.
size
());
known_vars
.
reserve
(
vars_
.
size
());
for
(
auto
&
name_var
:
vars_
)
{
for
(
auto
&
name_var
:
vars_
)
{
known_vars
.
emplace_back
(
name_var
.
first
);
known_vars
.
emplace_back
(
name_var
.
first
);
}
}
return
known_vars
;
return
known_vars
;
}
}
void
Scope
::
DeleteScope
(
Scope
*
scope
)
const
{
void
Scope
::
DeleteScope
(
Scope
*
scope
)
const
{
std
::
unique_lock
<
std
::
mutex
>
lock
(
mutex_
);
std
::
unique_lock
<
std
::
mutex
>
lock
(
mutex_
);
auto
it
=
std
::
find
(
kids_
.
begin
(),
kids_
.
end
(),
scope
);
auto
it
=
std
::
find
(
kids_
.
begin
(),
kids_
.
end
(),
scope
);
kids_
.
erase
(
it
);
kids_
.
erase
(
it
);
delete
scope
;
delete
scope
;
// deferent
// deferent
}
}
void
Scope
::
EraseVars
(
const
std
::
vector
<
std
::
string
>
&
var_names
)
{
void
Scope
::
EraseVars
(
const
std
::
vector
<
std
::
string
>
&
var_names
)
{
std
::
set
<
std
::
string
>
var_set
(
var_names
.
begin
(),
var_names
.
end
());
std
::
set
<
std
::
string
>
var_set
(
var_names
.
begin
(),
var_names
.
end
());
for
(
auto
it
=
vars_
.
begin
();
it
!=
vars_
.
end
();)
{
for
(
auto
it
=
vars_
.
begin
();
it
!=
vars_
.
end
();)
{
if
(
var_set
.
find
(
it
->
first
)
!=
var_set
.
end
())
{
if
(
var_set
.
find
(
it
->
first
)
!=
var_set
.
end
())
{
delete
it
->
second
;
delete
it
->
second
;
it
=
vars_
.
erase
(
it
);
it
=
vars_
.
erase
(
it
);
}
else
{
}
else
{
++
it
;
++
it
;
}
}
}
}
}
}
void
Scope
::
Rename
(
const
std
::
string
&
origin_name
,
void
Scope
::
Rename
(
const
std
::
string
&
origin_name
,
const
std
::
string
&
new_name
)
const
{
const
std
::
string
&
new_name
)
const
{
auto
origin_it
=
vars_
.
find
(
origin_name
);
auto
origin_it
=
vars_
.
find
(
origin_name
);
if
(
origin_it
==
vars_
.
end
())
{
if
(
origin_it
==
vars_
.
end
())
{
return
;
return
;
}
}
auto
new_it
=
vars_
.
find
(
new_name
);
auto
new_it
=
vars_
.
find
(
new_name
);
if
(
new_it
!=
vars_
.
end
())
{
if
(
new_it
!=
vars_
.
end
())
{
return
;
return
;
}
}
vars_
[
new_name
]
=
origin_it
->
second
;
vars_
[
new_name
]
=
origin_it
->
second
;
vars_
.
erase
(
origin_it
);
vars_
.
erase
(
origin_it
);
}
}
//
//
// std::string Scope::Rename(const std::string& origin_name) const {
// std::string Scope::Rename(const std::string& origin_name)
// auto var_name = string::Sprintf("%p.%d", this, vars_.size());
// const {
// Rename(origin_name, var_name);
// auto var_name = string::Sprintf("%p.%d", this,
// return var_name;
// vars_.size());
// }
// Rename(origin_name, var_name);
// return var_name;
// }
Variable
*
Scope
::
FindVarLocally
(
const
std
::
string
&
name
)
const
{
Variable
*
Scope
::
FindVarLocally
(
const
std
::
string
&
name
)
const
{
auto
it
=
vars_
.
find
(
name
);
auto
it
=
vars_
.
find
(
name
);
if
(
it
!=
vars_
.
end
())
{
if
(
it
!=
vars_
.
end
())
{
return
it
->
second
;
return
it
->
second
;
}
}
return
nullptr
;
return
nullptr
;
}
}
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/scope.h
浏览文件 @
aef98218
...
@@ -24,57 +24,58 @@ SOFTWARE.
...
@@ -24,57 +24,58 @@ SOFTWARE.
#include <unordered_map> //std::unordered_map
#include <unordered_map> //std::unordered_map
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
class
Scope
{
class
Scope
{
public:
public:
Scope
()
{}
Scope
()
{}
~
Scope
()
{}
~
Scope
()
{}
Scope
&
NewScope
()
const
;
Scope
&
NewScope
()
const
;
/// Create a variable with given name if it doesn't exist.
/// Create a variable with given name if it doesn't exist.
Variable
*
Var
(
const
std
::
string
&
name
);
Variable
*
Var
(
const
std
::
string
&
name
);
/// Create a variable with a scope-unique name.
/// Create a variable with a scope-unique name.
Variable
*
Var
(
std
::
string
*
name
=
nullptr
);
Variable
*
Var
(
std
::
string
*
name
=
nullptr
);
void
EraseVars
(
const
std
::
vector
<
std
::
string
>
&
var_names
);
void
EraseVars
(
const
std
::
vector
<
std
::
string
>
&
var_names
);
/// Find a variable in the scope or any of its ancestors. Returns
/// Find a variable in the scope or any of its ancestors. Returns
/// nullptr if cannot find.
/// nullptr if cannot find.
Variable
*
FindVar
(
const
std
::
string
&
name
)
const
;
Variable
*
FindVar
(
const
std
::
string
&
name
)
const
;
const
Scope
*
parent
()
const
{
return
parent_
;
}
const
Scope
*
parent
()
const
{
return
parent_
;
}
/// Find the scope or an ancestor scope that contains the given variable.
/// Find the scope or an ancestor scope that contains the given
const
Scope
*
FindScope
(
const
Variable
*
var
)
const
;
/// variable.
const
Scope
*
FindScope
(
const
Variable
*
var
)
const
;
void
DeleteScope
(
Scope
*
scope
)
const
;
void
DeleteScope
(
Scope
*
scope
)
const
;
/// Drop all kids scopes belonged to this scope.
/// Drop all kids scopes belonged to this scope.
void
DropKids
();
void
DropKids
();
// enumerate all the variables current contains.
// enumerate all the variables current contains.
std
::
vector
<
std
::
string
>
LocalVarNames
()
const
;
std
::
vector
<
std
::
string
>
LocalVarNames
()
const
;
// Rename variable to a new name
// Rename variable to a new name
void
Rename
(
const
std
::
string
&
origin_name
,
void
Rename
(
const
std
::
string
&
origin_name
,
const
std
::
string
&
new_name
)
const
;
const
std
::
string
&
new_name
)
const
;
// Rename variable to a new name and return the new name
// Rename variable to a new name and return the new name
std
::
string
Rename
(
const
std
::
string
&
origin_name
)
const
;
std
::
string
Rename
(
const
std
::
string
&
origin_name
)
const
;
Variable
*
FindVarLocally
(
const
std
::
string
&
name
)
const
;
Variable
*
FindVarLocally
(
const
std
::
string
&
name
)
const
;
private:
private:
// Call Scope::NewScope for a sub-scope.
// Call Scope::NewScope for a sub-scope.
explicit
Scope
(
Scope
const
*
parent
)
:
parent_
(
parent
)
{}
explicit
Scope
(
Scope
const
*
parent
)
:
parent_
(
parent
)
{}
mutable
std
::
unordered_map
<
std
::
string
,
Variable
*>
vars_
;
mutable
std
::
unordered_map
<
std
::
string
,
Variable
*>
vars_
;
mutable
std
::
list
<
Scope
*>
kids_
;
mutable
std
::
list
<
Scope
*>
kids_
;
Scope
const
*
parent_
{
nullptr
};
Scope
const
*
parent_
{
nullptr
};
mutable
std
::
mutex
mutex_
;
mutable
std
::
mutex
mutex_
;
};
};
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/selected_rows.h
浏览文件 @
aef98218
...
@@ -24,57 +24,59 @@ SOFTWARE.
...
@@ -24,57 +24,59 @@ SOFTWARE.
#include "tensor.h"
#include "tensor.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
class
SelectedRows
{
class
SelectedRows
{
public:
public:
SelectedRows
(
const
std
::
vector
<
int64_t
>
&
rows
,
const
int64_t
&
height
)
SelectedRows
(
const
std
::
vector
<
int64_t
>
&
rows
,
:
rows_
(
rows
),
height_
(
height
)
{
const
int64_t
&
height
)
value_
.
reset
(
new
Tensor
());
:
rows_
(
rows
),
height_
(
height
)
{
}
value_
.
reset
(
new
Tensor
());
}
SelectedRows
()
{
SelectedRows
()
{
height_
=
0
;
height_
=
0
;
value_
.
reset
(
new
Tensor
());
value_
.
reset
(
new
Tensor
());
}
}
const
Tensor
&
value
()
const
{
return
*
value_
;
}
const
Tensor
&
value
()
const
{
return
*
value_
;
}
Tensor
*
mutable_value
()
{
return
value_
.
get
();
}
Tensor
*
mutable_value
()
{
return
value_
.
get
();
}
int64_t
height
()
const
{
return
height_
;
}
int64_t
height
()
const
{
return
height_
;
}
void
set_height
(
int64_t
height
)
{
height_
=
height
;
}
void
set_height
(
int64_t
height
)
{
height_
=
height
;
}
const
std
::
vector
<
int64_t
>
&
rows
()
const
{
return
rows_
;
}
const
std
::
vector
<
int64_t
>
&
rows
()
const
{
return
rows_
;
}
std
::
vector
<
int64_t
>
*
mutable_rows
()
{
return
&
rows_
;
}
std
::
vector
<
int64_t
>
*
mutable_rows
()
{
return
&
rows_
;
}
void
set_rows
(
const
std
::
vector
<
int64_t
>
&
rows
)
{
rows_
=
rows
;
}
void
set_rows
(
const
std
::
vector
<
int64_t
>
&
rows
)
{
rows_
=
rows
;
}
/**
/**
* get the index of id in rows
* get the index of id in rows
*/
*/
int64_t
index
(
int64_t
id
)
const
{
int64_t
index
(
int64_t
id
)
const
{
auto
it
=
std
::
find
(
rows_
.
begin
(),
rows_
.
end
(),
id
);
auto
it
=
std
::
find
(
rows_
.
begin
(),
rows_
.
end
(),
id
);
// PADDLE_ENFORCE(it != rows_.end(), "id should be in rows");
// PADDLE_ENFORCE(it != rows_.end(), "id should be in rows");
return
static_cast
<
int64_t
>
(
std
::
distance
(
rows_
.
begin
(),
it
));
return
static_cast
<
int64_t
>
(
std
::
distance
(
rows_
.
begin
(),
it
));
}
}
DDim
GetCompleteDims
()
const
{
DDim
GetCompleteDims
()
const
{
std
::
vector
<
int64_t
>
dims
=
vectorize
(
value_
->
dims
());
std
::
vector
<
int64_t
>
dims
=
vectorize
(
value_
->
dims
());
dims
[
0
]
=
height_
;
dims
[
0
]
=
height_
;
return
make_ddim
(
dims
);
return
make_ddim
(
dims
);
}
}
private:
private:
// Notice: rows can be duplicate. We can have {0, 4, 7, 0, 5, 7, 9} here.
// Notice: rows can be duplicate. We can have {0, 4, 7, 0, 5, 7, 9}
// SelectedRows are simply concated when adding together. Until a
// here.
// SelectedRows add a Tensor, will the duplicate rows be handled.
// SelectedRows are simply concated when adding together. Until a
std
::
vector
<
int64_t
>
rows_
;
// SelectedRows add a Tensor, will the duplicate rows be handled.
std
::
unique_ptr
<
Tensor
>
value_
{
nullptr
};
std
::
vector
<
int64_t
>
rows_
;
int64_t
height_
;
std
::
unique_ptr
<
Tensor
>
value_
{
nullptr
};
};
int64_t
height_
;
};
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/tensor.h
浏览文件 @
aef98218
...
@@ -25,287 +25,316 @@ limitations under the License. */
...
@@ -25,287 +25,316 @@ limitations under the License. */
#include "memory/t_malloc.h"
#include "memory/t_malloc.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
template
<
typename
...
T
>
struct
SizeOfTypeFunctor
;
template
<
typename
...
T
>
struct
SizeOfTypeFunctor
;
template
<
typename
T
>
struct
SizeOfTypeFunctor
<
T
>
{
template
<
typename
T
>
struct
SizeOfTypeFunctor
<
T
>
{
size_t
operator
()(
std
::
type_index
type
)
const
{
size_t
operator
()(
std
::
type_index
type
)
const
{
if
(
typeid
(
T
).
hash_code
()
==
type
.
hash_code
())
{
if
(
typeid
(
T
).
hash_code
()
==
type
.
hash_code
())
{
return
sizeof
(
T
);
return
sizeof
(
T
);
}
else
{
}
else
{
return
0UL
;
return
0UL
;
}
}
}
}
};
};
template
<
>
struct
SizeOfTypeFunctor
<>
{
template
<
>
struct
SizeOfTypeFunctor
<>
{
size_t
operator
()(
std
::
type_index
type
)
const
{
return
0UL
;
}
size_t
operator
()(
std
::
type_index
type
)
const
{
return
0UL
;
}
};
};
template
<
typename
HEAD
,
typename
...
TAIL
>
template
<
typename
HEAD
,
typename
...
TAIL
>
struct
SizeOfTypeFunctor
<
HEAD
,
TAIL
...
>
{
struct
SizeOfTypeFunctor
<
HEAD
,
TAIL
...
>
{
size_t
operator
()(
std
::
type_index
type
)
const
{
size_t
operator
()(
std
::
type_index
type
)
const
{
SizeOfTypeFunctor
<
HEAD
>
head
;
SizeOfTypeFunctor
<
HEAD
>
head
;
size_t
head_size
=
head
(
type
);
size_t
head_size
=
head
(
type
);
if
(
head_size
!=
0
)
{
if
(
head_size
!=
0
)
{
return
head_size
;
return
head_size
;
}
}
SizeOfTypeFunctor
<
TAIL
...
>
tail
;
SizeOfTypeFunctor
<
TAIL
...
>
tail
;
return
tail
(
type
);
return
tail
(
type
);
}
}
};
};
static
inline
size_t
SizeOfType
(
std
::
type_index
type
)
{
static
inline
size_t
SizeOfType
(
std
::
type_index
type
)
{
SizeOfTypeFunctor
<
int
,
float
,
double
,
int16_t
,
int64_t
,
bool
,
size_t
>
functor
;
SizeOfTypeFunctor
<
int
,
float
,
double
,
int16_t
,
int64_t
,
bool
,
size_t
size
=
functor
(
type
);
size_t
>
// PADDLE_ENFORCE(size != 0UL, "Cannot get size of type %s", type.name());
functor
;
return
size
;
size_t
size
=
functor
(
type
);
}
// PADDLE_ENFORCE(size != 0UL, "Cannot get size of type %s",
// type.name());
class
LoDTensor
;
return
size
;
}
class
Tensor
{
public:
class
LoDTensor
;
Tensor
()
:
offset_
(
0
)
{}
class
Tensor
{
/*! Return a pointer to mutable memory block. */
public:
template
<
typename
T
>
inline
T
*
data
()
{
Tensor
()
:
offset_
(
0
)
{}
check_memory_size
();
// PADDLE_ENFORCE(std::is_same<T, void>::value ||
/*! Return a pointer to mutable memory block. */
// holder_->type().hash_code() == typeid(T).hash_code(),
template
<
typename
T
>
inline
T
*
data
()
{
// "Tensor holds the wrong type, it holds %s",
check_memory_size
();
// this->holder_->type().name());
// PADDLE_ENFORCE(std::is_same<T, void>::value ||
return
reinterpret_cast
<
T
*>
(
reinterpret_cast
<
uintptr_t
>
(
holder_
->
ptr
())
+
// holder_->type().hash_code() ==
offset_
);
// typeid(T).hash_code(),
}
// "Tensor holds the wrong type, it holds %s",
// this->holder_->type().name());
/*! Return a pointer to constant memory block. */
return
reinterpret_cast
<
T
*>
(
template
<
typename
T
>
inline
const
T
*
data
()
const
{
reinterpret_cast
<
uintptr_t
>
(
holder_
->
ptr
())
+
offset_
);
check_memory_size
();
}
// PADDLE_ENFORCE(std::is_same<T, void>::value ||
// holder_->type().hash_code() == typeid(T).hash_code(),
/*! Return a pointer to constant memory block. */
// "Tensor holds the wrong type, it holds %s",
template
<
typename
T
>
inline
const
T
*
data
()
const
{
// this->holder_->type().name());
check_memory_size
();
// PADDLE_ENFORCE(std::is_same<T, void>::value ||
return
reinterpret_cast
<
const
T
*>
(
// holder_->type().hash_code() ==
reinterpret_cast
<
uintptr_t
>
(
holder_
->
ptr
())
+
offset_
);
// typeid(T).hash_code(),
}
// "Tensor holds the wrong type, it holds %s",
// this->holder_->type().name());
inline
bool
IsInitialized
()
const
{
return
holder_
!=
nullptr
;
}
return
reinterpret_cast
<
const
T
*>
(
/**
reinterpret_cast
<
uintptr_t
>
(
holder_
->
ptr
())
+
offset_
);
* @brief Return a pointer to mutable memory block.
}
* @note If not exist, then allocation.
*/
inline
bool
IsInitialized
()
const
{
return
holder_
!=
nullptr
;
}
template
<
typename
T
>
inline
T
*
mutable_data
()
{
static_assert
(
std
::
is_pod
<
T
>::
value
,
"T must be POD"
);
/**
return
reinterpret_cast
<
T
*>
(
mutable_data
(
typeid
(
T
)));
* @brief Return a pointer to mutable memory block.
}
* @note If not exist, then allocation.
*/
inline
void
*
mutable_data
(
std
::
type_index
type
)
{
template
<
typename
T
>
inline
T
*
mutable_data
()
{
if
(
holder_
!=
nullptr
)
{
static_assert
(
std
::
is_pod
<
T
>::
value
,
"T must be POD"
);
holder_
->
set_type
(
type
);
return
reinterpret_cast
<
T
*>
(
mutable_data
(
typeid
(
T
)));
}
}
// PADDLE_ENFORCE_GE(numel(), 0,
// "When calling this method, the Tensor's numel must be
inline
void
*
mutable_data
(
std
::
type_index
type
)
{
// " "equal or larger than zero. " "Please check
if
(
holder_
!=
nullptr
)
{
// Tensor::Resize has been called first.");
holder_
->
set_type
(
type
);
int64_t
size
=
numel
()
*
SizeOfType
(
type
);
}
/* some versions of boost::variant don't have operator!= */
// PADDLE_ENFORCE_GE(numel(), 0,
if
(
holder_
==
nullptr
||
holder_
->
size
()
<
size
+
offset_
)
{
// "When calling this method, the Tensor's
holder_
.
reset
(
new
PlaceholderImpl
(
size
,
type
));
// numel must be
// " "equal or larger than zero. " "Please
offset_
=
0
;
// check
}
// Tensor::Resize has been called first.");
return
reinterpret_cast
<
void
*>
(
int64_t
size
=
numel
()
*
SizeOfType
(
type
);
reinterpret_cast
<
uintptr_t
>
(
holder_
->
ptr
())
+
offset_
);
/* some versions of boost::variant don't have operator!= */
}
if
(
holder_
==
nullptr
||
holder_
->
size
()
<
size
+
offset_
)
{
holder_
.
reset
(
new
PlaceholderImpl
(
size
,
type
));
inline
void
*
mutable_data
()
{
// PADDLE_ENFORCE(this->holder_ != nullptr,
offset_
=
0
;
// "Cannot invoke mutable data if current hold nothing.");
}
return
mutable_data
(
holder_
->
type
());
return
reinterpret_cast
<
void
*>
(
}
reinterpret_cast
<
uintptr_t
>
(
holder_
->
ptr
())
+
offset_
);
}
/**
* @brief Return a pointer to mutable memory block.
inline
void
*
mutable_data
()
{
*
// PADDLE_ENFORCE(this->holder_ != nullptr,
* @param[in] dims The dimensions of the memory block.
// "Cannot invoke mutable data if current hold
* @param[in] place The place of the memory block.
// nothing.");
*
return
mutable_data
(
holder_
->
type
());
* @note If not exist, then allocation.
}
*/
template
<
typename
T
>
inline
T
*
mutable_data
(
DDim
dims
)
{
/**
static_assert
(
std
::
is_pod
<
T
>::
value
,
"T must be POD"
);
* @brief Return a pointer to mutable memory block.
Resize
(
dims
);
*
return
mutable_data
<
T
>
();
* @param[in] dims The dimensions of the memory block.
}
* @param[in] place The place of the memory block.
*
/*! Return the dimensions of the memory block. */
* @note If not exist, then allocation.
inline
const
DDim
&
dims
()
const
{
return
dims_
;
}
*/
template
<
typename
T
>
inline
T
*
mutable_data
(
DDim
dims
)
{
/*! Return the numel of the memory block. */
static_assert
(
std
::
is_pod
<
T
>::
value
,
"T must be POD"
);
inline
int64_t
numel
()
const
{
return
product
(
dims_
);
}
Resize
(
dims
);
return
mutable_data
<
T
>
();
/*! Resize the dimensions of the memory block. */
}
inline
Tensor
&
Resize
(
const
DDim
&
dims
)
{
dims_
=
dims
;
/*! Return the dimensions of the memory block. */
return
*
this
;
inline
const
DDim
&
dims
()
const
{
return
dims_
;
}
}
/*! Return the numel of the memory block. */
/*! The internal of two tensors share the same memory block. */
inline
int64_t
numel
()
const
{
return
product
(
dims_
);
}
inline
Tensor
&
ShareDataWith
(
const
Tensor
&
src
)
{
src
.
check_memory_size
();
/*! Resize the dimensions of the memory block. */
*
this
=
src
;
inline
Tensor
&
Resize
(
const
DDim
&
dims
)
{
return
*
this
;
dims_
=
dims
;
}
return
*
this
;
}
/**
* @brief Return a sub-tensor of the given tensor.
/*! The internal of two tensors share the same memory block. */
*
inline
Tensor
&
ShareDataWith
(
const
Tensor
&
src
)
{
* @param[in] begin_idx The index of the start row(inclusive) to slice.
src
.
check_memory_size
();
* The index number begins from 0.
*
this
=
src
;
* @param[in] end_idx The index of the end row(exclusive) to slice.
return
*
this
;
* The index number begins from 0.
}
*/
inline
Tensor
Slice
(
int
begin_idx
,
int
end_idx
)
const
{
/**
check_memory_size
();
* @brief Return a sub-tensor of the given tensor.
// PADDLE_ENFORCE_GE(begin_idx, 0,
*
// "The start row index must be greater than 0.");
* @param[in] begin_idx The index of the start row(inclusive) to
// PADDLE_ENFORCE_LE(end_idx, dims_[0], "The end row index is out of
* slice.
// bound."); PADDLE_ENFORCE_LT(
* The index number begins from 0.
// begin_idx, end_idx,
* @param[in] end_idx The index of the end row(exclusive) to
// "The start row index must be lesser than the end row index.");
* slice.
* The index number begins from 0.
if
(
dims_
[
0
]
==
1
)
{
*/
return
*
this
;
inline
Tensor
Slice
(
int
begin_idx
,
int
end_idx
)
const
{
}
else
{
check_memory_size
();
size_t
base
=
numel
()
/
dims_
[
0
];
// PADDLE_ENFORCE_GE(begin_idx, 0,
Tensor
dst
;
// "The start row index must be greater than
dst
.
holder_
=
holder_
;
// 0.");
dst
.
set_layout
(
layout_
);
// PADDLE_ENFORCE_LE(end_idx, dims_[0], "The end row index is
DDim
dst_dims
=
dims_
;
// out of
dst_dims
[
0
]
=
end_idx
-
begin_idx
;
// bound."); PADDLE_ENFORCE_LT(
dst
.
Resize
(
dst_dims
);
// begin_idx, end_idx,
dst
.
offset_
=
offset_
+
begin_idx
*
base
*
SizeOfType
(
type
());
// "The start row index must be lesser than the end row
return
dst
;
// index.");
}
}
if
(
dims_
[
0
]
==
1
)
{
return
*
this
;
std
::
type_index
type
()
const
{
}
else
{
// PADDLE_ENFORCE_NOT_NULL(
size_t
base
=
numel
()
/
dims_
[
0
];
// holder_, "Tensor not initialized yet when
Tensor
dst
;
// Tensor::type() is called.");
dst
.
holder_
=
holder_
;
return
holder_
->
type
();
dst
.
set_layout
(
layout_
);
}
DDim
dst_dims
=
dims_
;
dst_dims
[
0
]
=
end_idx
-
begin_idx
;
// memory size returns the holding memory size in byte.
dst
.
Resize
(
dst_dims
);
size_t
memory_size
()
const
{
dst
.
offset_
=
return
holder_
==
nullptr
?
0UL
:
holder_
->
size
()
-
offset_
;
offset_
+
begin_idx
*
base
*
SizeOfType
(
type
());
}
return
dst
;
}
inline
void
check_memory_size
()
const
{
}
// PADDLE_ENFORCE_NOT_NULL(
// holder_, "Tensor holds no memory. Call Tensor::mutable_data
std
::
type_index
type
()
const
{
// first.");
// PADDLE_ENFORCE_NOT_NULL(
// PADDLE_ENFORCE_LE(
// holder_, "Tensor not initialized yet
// numel() * SizeOfType(type()), memory_size(),
// when
// "Tensor's dims_ is out of bound. Call Tensor::mutable_data "
// Tensor::type() is called.");
// "first to re-allocate memory.\n"
return
holder_
->
type
();
// "or maybe the required data-type mismatches the data already
}
// stored.");
}
// memory size returns the holding memory size in byte.
size_t
memory_size
()
const
{
inline
DataLayout
layout
()
const
{
return
layout_
;
}
return
holder_
==
nullptr
?
0UL
:
holder_
->
size
()
-
offset_
;
}
inline
void
set_layout
(
const
DataLayout
layout
)
{
layout_
=
layout
;
}
inline
void
check_memory_size
()
const
{
private:
// PADDLE_ENFORCE_NOT_NULL(
/**
// holder_, "Tensor holds no memory. Call
* @note Placeholder hides type T, so it doesn't appear as a template
// Tensor::mutable_data
* parameter of Variable.
// first.");
*/
// PADDLE_ENFORCE_LE(
struct
Placeholder
{
// numel() * SizeOfType(type()), memory_size(),
virtual
~
Placeholder
()
=
default
;
// "Tensor's dims_ is out of bound. Call
// Tensor::mutable_data "
virtual
void
*
ptr
()
const
=
0
;
// "first to re-allocate memory.\n"
// "or maybe the required data-type mismatches the data
virtual
size_t
size
()
const
=
0
;
// already
// stored.");
virtual
std
::
type_index
type
()
const
=
0
;
}
virtual
void
set_type
(
std
::
type_index
type
)
=
0
;
inline
DataLayout
layout
()
const
{
return
layout_
;
}
};
inline
void
set_layout
(
const
DataLayout
layout
)
{
struct
PlaceholderImpl
:
public
Placeholder
{
layout_
=
layout
;
PlaceholderImpl
(
size_t
size
,
std
::
type_index
type
)
}
:
ptr_
(
static_cast
<
uint8_t
*>
(
memory
::
Alloc
(
size
)),
memory
::
PODDeleter
<
uint8_t
>
()),
private:
size_
(
size
),
type_
(
type
)
{
/**
// PADDLE_ENFORCE_NOT_NULL(ptr_, "Insufficient %s
* @note Placeholder hides type T, so it doesn't appear as a
// memory to allocation.",
* template
// (is_cpu_place(place_) ?
* parameter of Variable.
// "CPU" : "GPU"));
*/
}
struct
Placeholder
{
virtual
~
Placeholder
()
=
default
;
virtual
size_t
size
()
const
{
return
size_
;
}
virtual
void
*
ptr
()
const
=
0
;
virtual
void
*
ptr
()
const
{
return
static_cast
<
void
*>
(
ptr_
.
get
());
}
virtual
size_t
size
()
const
=
0
;
virtual
std
::
type_index
type
()
const
{
return
type_
;
}
virtual
std
::
type_index
type
()
const
=
0
;
virtual
void
set_type
(
std
::
type_index
type
)
{
type_
=
type
;
}
virtual
void
set_type
(
std
::
type_index
type
)
=
0
;
/*! the pointer of memory block. */
};
std
::
unique_ptr
<
uint8_t
,
memory
::
PODDeleter
<
uint8_t
>>
ptr_
;
struct
PlaceholderImpl
:
public
Placeholder
{
/*! the size of memory block. */
PlaceholderImpl
(
size_t
size
,
std
::
type_index
type
)
size_t
size_
;
:
ptr_
(
static_cast
<
uint8_t
*>
(
memory
::
Alloc
(
size
)),
memory
::
PODDeleter
<
uint8_t
>
()),
/* the current type of memory */
size_
(
size
),
type_
(
type
)
{
std
::
type_index
type_
;
// PADDLE_ENFORCE_NOT_NULL(ptr_,
};
// "Insufficient %s
// memory to allocation.",
/*! holds the memory block if allocated. */
// (is_cpu_place(place_)
std
::
shared_ptr
<
Placeholder
>
holder_
;
// ?
// "CPU" :
/**
// "GPU"));
* @brief points to elements dimensions.
}
*
* @note dims_ do not indicate the memory block size.
virtual
size_t
size
()
const
{
return
size_
;
}
*/
virtual
void
*
ptr
()
const
{
DDim
dims_
;
return
static_cast
<
void
*>
(
ptr_
.
get
());
}
/**
* @brief the layout of memory block, default is NHWC.
virtual
std
::
type_index
type
()
const
{
return
type_
;
}
*
* @note the memory allocation order, describe how weight/data is stored
virtual
void
set_type
(
std
::
type_index
type
)
{
type_
=
type
;
}
* For example, in 4-D Tensor(rank=4), there are three commonly
* used layout. They are
/*! the pointer of memory block. */
* NCHW, NHWC, CHWN.
std
::
unique_ptr
<
uint8_t
,
memory
::
PODDeleter
<
uint8_t
>>
ptr_
;
* N,C,H,W for respectively the batch size, the number of
* feature maps, the height, the width.
/*! the size of memory block. */
*/
size_t
size_
;
DataLayout
layout_
=
DataLayout
::
kNHWC
;
/* the current type of memory */
std
::
type_index
type_
;
/**
};
* @brief A PlaceHolder may be shared by more than one tensor.
*
/*! holds the memory block if allocated. */
* @note Some of them may be slices of the others. So the offset_
std
::
shared_ptr
<
Placeholder
>
holder_
;
* is introduced here to indicate the byte offset between
* PlaceHolder::ptr_ and where the tensor data really begins.
/**
*/
* @brief points to elements dimensions.
size_t
offset_
;
*
};
* @note dims_ do not indicate the memory block size.
*/
inline
Tensor
ReshapeToMatrix
(
const
Tensor
&
src
,
int
num_col_dims
)
{
Tensor
res
;
DDim
dims_
;
res
.
ShareDataWith
(
src
);
res
.
Resize
(
flatten_to_2d
(
src
.
dims
(),
num_col_dims
));
/**
return
res
;
* @brief the layout of memory block, default is NHWC.
}
*
* @note the memory allocation order, describe how weight/data is
}
// namespace framework
* stored
* For example, in 4-D Tensor(rank=4), there are three
* commonly
* used layout. They are
* NCHW, NHWC, CHWN.
* N,C,H,W for respectively the batch size, the number of
* feature maps, the height, the width.
*/
DataLayout
layout_
=
DataLayout
::
kNHWC
;
/**
* @brief A PlaceHolder may be shared by more than one tensor.
*
* @note Some of them may be slices of the others. So the offset_
* is introduced here to indicate the byte offset between
* PlaceHolder::ptr_ and where the tensor data really
* begins.
*/
size_t
offset_
;
};
inline
Tensor
ReshapeToMatrix
(
const
Tensor
&
src
,
int
num_col_dims
)
{
Tensor
res
;
res
.
ShareDataWith
(
src
);
res
.
Resize
(
flatten_to_2d
(
src
.
dims
(),
num_col_dims
));
return
res
;
}
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/tensor_util.cc
浏览文件 @
aef98218
...
@@ -18,183 +18,189 @@
...
@@ -18,183 +18,189 @@
#include <vector>
#include <vector>
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
void
TensorCopy
(
const
Tensor
&
src
,
Tensor
*
dst
)
{
void
TensorCopy
(
const
Tensor
&
src
,
Tensor
*
dst
)
{
// VLOG(3) << "TensorCopy " << src.dims() << " from " << src.place() << " to
// VLOG(3) << "TensorCopy " << src.dims() << " from " <<
// "
// src.place() << " to
// << dst_place;
// "
src
.
check_memory_size
();
// << dst_place;
src
.
check_memory_size
();
dst
->
Resize
(
src
.
dims
());
dst
->
set_layout
(
src
.
layout
());
dst
->
Resize
(
src
.
dims
());
auto
src_ptr
=
src
.
data
<
void
>
();
dst
->
set_layout
(
src
.
layout
());
auto
src_ptr
=
src
.
data
<
void
>
();
auto
dst_ptr
=
dst
->
mutable_data
(
src
.
type
());
auto
dst_ptr
=
dst
->
mutable_data
(
src
.
type
());
auto
size
=
src
.
numel
()
*
SizeOfType
(
src
.
type
());
auto
size
=
src
.
numel
()
*
SizeOfType
(
src
.
type
());
memory
::
Copy
(
dst_ptr
,
src_ptr
,
size
);
}
memory
::
Copy
(
dst_ptr
,
src_ptr
,
size
);
}
void
TensorCopySync
(
const
Tensor
&
src
,
Tensor
*
dst
)
{
// VLOG(3) << "TensorCopySync " << src.dims() << " from " << src.place()
void
TensorCopySync
(
const
Tensor
&
src
,
Tensor
*
dst
)
{
// << " to " << dst_place;
// VLOG(3) << "TensorCopySync " << src.dims() << " from " <<
src
.
check_memory_size
();
// src.place()
dst
->
Resize
(
src
.
dims
());
// << " to " << dst_place;
dst
->
set_layout
(
src
.
layout
());
src
.
check_memory_size
();
auto
src_ptr
=
src
.
data
<
void
>
();
dst
->
Resize
(
src
.
dims
());
auto
dst_ptr
=
dst
->
mutable_data
(
src
.
type
());
dst
->
set_layout
(
src
.
layout
());
auto
size
=
src
.
numel
()
*
SizeOfType
(
src
.
type
());
auto
src_ptr
=
src
.
data
<
void
>
();
memory
::
Copy
(
dst_ptr
,
src_ptr
,
size
);
auto
dst_ptr
=
dst
->
mutable_data
(
src
.
type
());
}
auto
size
=
src
.
numel
()
*
SizeOfType
(
src
.
type
());
memory
::
Copy
(
dst_ptr
,
src_ptr
,
size
);
template
<
typename
Predicate
>
struct
AnyDTypeVisitor
{
}
Predicate
predicate_
;
const
Tensor
&
tensor_
;
template
<
typename
Predicate
>
struct
AnyDTypeVisitor
{
Tensor
*
out_
;
Predicate
predicate_
;
const
Tensor
&
tensor_
;
AnyDTypeVisitor
(
Predicate
predicate
,
const
Tensor
&
tensor
,
Tensor
*
out
)
Tensor
*
out_
;
:
predicate_
(
predicate
),
tensor_
(
tensor
),
out_
(
out
)
{}
AnyDTypeVisitor
(
Predicate
predicate
,
const
Tensor
&
tensor
,
template
<
typename
T
>
void
operator
()()
const
{
Tensor
*
out
)
// auto t = EigenVector<T>::Flatten(tensor_);
:
predicate_
(
predicate
),
tensor_
(
tensor
),
out_
(
out
)
{}
// auto o = EigenScalar<bool>::From(*out_);
// return any of predicate_(t) is true.
template
<
typename
T
>
void
operator
()()
const
{
// o.device(*ctx_.eigen_device()) = predicate_(t).any();
// auto t = EigenVector<T>::Flatten(tensor_);
}
// auto o = EigenScalar<bool>::From(*out_);
};
// return any of predicate_(t) is true.
// o.device(*ctx_.eigen_device()) = predicate_(t).any();
template
<
typename
Predicate
>
}
inline
void
AnyImpl
(
Predicate
predicate
,
const
Tensor
&
tensor
,
};
framework
::
Tensor
*
out
)
{
VisitDataType
(
ToDataType
(
tensor
.
type
()),
template
<
typename
Predicate
>
AnyDTypeVisitor
<
Predicate
>
(
predicate
,
tensor
,
out
));
inline
void
AnyImpl
(
Predicate
predicate
,
const
Tensor
&
tensor
,
}
framework
::
Tensor
*
out
)
{
VisitDataType
(
ToDataType
(
tensor
.
type
()),
template
<
typename
Predicate
>
struct
AnyVisitor
{
AnyDTypeVisitor
<
Predicate
>
(
predicate
,
tensor
,
out
));
const
framework
::
Tensor
&
tensor_
;
}
Predicate
predicate_
;
template
<
typename
Predicate
>
struct
AnyVisitor
{
AnyVisitor
(
const
framework
::
Tensor
&
tensor
,
Predicate
predicate
)
const
framework
::
Tensor
&
tensor_
;
:
tensor_
(
tensor
),
predicate_
(
std
::
move
(
predicate
))
{}
Predicate
predicate_
;
bool
operator
()(
void
)
const
{
AnyVisitor
(
const
framework
::
Tensor
&
tensor
,
Predicate
predicate
)
framework
::
Tensor
out
;
:
tensor_
(
tensor
),
predicate_
(
std
::
move
(
predicate
))
{}
out
.
Resize
({
1
});
out
.
mutable_data
<
bool
>
();
bool
operator
()(
void
)
const
{
AnyImpl
(
predicate_
,
tensor_
,
&
out
);
framework
::
Tensor
out
;
return
this
->
GetResult
(
out
);
out
.
Resize
({
1
});
}
out
.
mutable_data
<
bool
>
();
AnyImpl
(
predicate_
,
tensor_
,
&
out
);
bool
GetResult
(
const
framework
::
Tensor
&
out
)
const
{
return
this
->
GetResult
(
out
);
return
*
out
.
data
<
bool
>
();
}
}
};
bool
GetResult
(
const
framework
::
Tensor
&
out
)
const
{
return
*
out
.
data
<
bool
>
();
template
<
typename
Predicate
>
}
inline
bool
Any
(
const
framework
::
Tensor
&
tensor
,
Predicate
predicate
)
{
};
AnyVisitor
<
Predicate
>
visitor
(
tensor
,
predicate
);
// return platform::VisitPlace(visitor);
template
<
typename
Predicate
>
return
visitor
();
inline
bool
Any
(
const
framework
::
Tensor
&
tensor
,
Predicate
predicate
)
{
}
AnyVisitor
<
Predicate
>
visitor
(
tensor
,
predicate
);
// return platform::VisitPlace(visitor);
struct
ContainsNANPredicate
{
return
visitor
();
template
<
typename
T
>
}
auto
operator
()(
const
T
&
eigen_vec
)
const
->
decltype
(
std
::
declval
<
T
>
().
isnan
())
{
struct
ContainsNANPredicate
{
// Cast eigen_vector to vector of bool. true if is inf.
template
<
typename
T
>
return
eigen_vec
.
isnan
();
auto
operator
()(
const
T
&
eigen_vec
)
const
}
->
decltype
(
std
::
declval
<
T
>
().
isnan
())
{
};
// Cast eigen_vector to vector of bool. true if is inf.
return
eigen_vec
.
isnan
();
bool
TensorContainsNAN
(
const
framework
::
Tensor
&
tensor
)
{
}
ContainsNANPredicate
predicate
;
};
return
Any
(
tensor
,
predicate
);
}
bool
TensorContainsNAN
(
const
framework
::
Tensor
&
tensor
)
{
ContainsNANPredicate
predicate
;
struct
ContainsInfPredicate
{
return
Any
(
tensor
,
predicate
);
template
<
typename
T
>
}
auto
operator
()(
const
T
&
eigen_vec
)
const
->
decltype
(
std
::
declval
<
T
>
().
isinf
())
{
struct
ContainsInfPredicate
{
// Cast eigen_vector to vector of bool. true if is inf.
template
<
typename
T
>
return
eigen_vec
.
isinf
();
auto
operator
()(
const
T
&
eigen_vec
)
const
}
->
decltype
(
std
::
declval
<
T
>
().
isinf
())
{
};
// Cast eigen_vector to vector of bool. true if is inf.
return
eigen_vec
.
isinf
();
bool
TensorContainsInf
(
const
framework
::
Tensor
&
tensor
)
{
}
ContainsInfPredicate
predicate
;
};
return
Any
(
tensor
,
predicate
);
}
bool
TensorContainsInf
(
const
framework
::
Tensor
&
tensor
)
{
ContainsInfPredicate
predicate
;
void
TensorToStream
(
std
::
ostream
&
os
,
const
Tensor
&
tensor
)
{
return
Any
(
tensor
,
predicate
);
{
// the 1st field, uint32_t version
}
constexpr
uint32_t
version
=
0
;
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
version
),
sizeof
(
version
));
void
TensorToStream
(
std
::
ostream
&
os
,
const
Tensor
&
tensor
)
{
}
{
// the 1st field, uint32_t version
{
// the 2nd field, tensor description
constexpr
uint32_t
version
=
0
;
// int32_t size
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
version
),
// void* protobuf message
sizeof
(
version
));
proto
::
VarType
::
TensorDesc
desc
;
}
desc
.
set_data_type
(
framework
::
ToDataType
(
tensor
.
type
()));
{
// the 2nd field, tensor description
auto
dims
=
framework
::
vectorize
(
tensor
.
dims
());
// int32_t size
auto
*
pb_dims
=
desc
.
mutable_dims
();
// void* protobuf message
pb_dims
->
Resize
(
static_cast
<
int
>
(
dims
.
size
()),
0
);
proto
::
VarType
::
TensorDesc
desc
;
std
::
copy
(
dims
.
begin
(),
dims
.
end
(),
pb_dims
->
begin
());
desc
.
set_data_type
(
framework
::
ToDataType
(
tensor
.
type
()));
int32_t
size
=
desc
.
ByteSize
();
auto
dims
=
framework
::
vectorize
(
tensor
.
dims
());
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
size
),
sizeof
(
size
));
auto
*
pb_dims
=
desc
.
mutable_dims
();
auto
out
=
desc
.
SerializeAsString
();
pb_dims
->
Resize
(
static_cast
<
int
>
(
dims
.
size
()),
0
);
os
.
write
(
out
.
data
(),
size
);
std
::
copy
(
dims
.
begin
(),
dims
.
end
(),
pb_dims
->
begin
());
}
int32_t
size
=
desc
.
ByteSize
();
{
// the 3rd field, tensor data
os
.
write
(
reinterpret_cast
<
const
char
*>
(
&
size
),
sizeof
(
size
));
uint64_t
size
=
tensor
.
memory_size
();
auto
out
=
desc
.
SerializeAsString
();
auto
*
data_ptr
=
tensor
.
data
<
void
>
();
os
.
write
(
out
.
data
(),
size
);
// PADDLE_ENFORCE(size < std::numeric_limits<std::streamsize>::max(),
}
// "Index overflow when writing tensor");
{
// the 3rd field, tensor data
uint64_t
size
=
tensor
.
memory_size
();
os
.
write
(
static_cast
<
const
char
*>
(
data_ptr
),
auto
*
data_ptr
=
tensor
.
data
<
void
>
();
static_cast
<
std
::
streamsize
>
(
size
));
// PADDLE_ENFORCE(size <
}
// std::numeric_limits<std::streamsize>::max(),
}
// "Index overflow when writing tensor");
struct
DeserializedDataFunctor
{
os
.
write
(
static_cast
<
const
char
*>
(
data_ptr
),
DeserializedDataFunctor
(
void
**
buf
,
Tensor
*
tensor
)
static_cast
<
std
::
streamsize
>
(
size
));
:
buf_
(
buf
),
tensor_
(
tensor
)
{}
}
}
template
<
typename
T
>
void
operator
()()
{
*
buf_
=
tensor_
->
mutable_data
<
T
>
();
struct
DeserializedDataFunctor
{
}
DeserializedDataFunctor
(
void
**
buf
,
Tensor
*
tensor
)
:
buf_
(
buf
),
tensor_
(
tensor
)
{}
void
**
buf_
;
Tensor
*
tensor_
;
template
<
typename
T
>
void
operator
()()
{
};
*
buf_
=
tensor_
->
mutable_data
<
T
>
();
}
void
TensorFromStream
(
std
::
istream
&
is
,
framework
::
Tensor
*
tensor
)
{
uint32_t
version
;
void
**
buf_
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
version
),
sizeof
(
version
));
Tensor
*
tensor_
;
// PADDLE_ENFORCE_EQ(version, 0U, "Only version 0 is supported");
};
proto
::
VarType
::
TensorDesc
desc
;
{
// int32_t size
void
TensorFromStream
(
std
::
istream
&
is
,
framework
::
Tensor
*
tensor
)
{
// proto buffer
uint32_t
version
;
int32_t
size
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
version
),
sizeof
(
version
));
is
.
read
(
reinterpret_cast
<
char
*>
(
&
size
),
sizeof
(
size
));
// PADDLE_ENFORCE_EQ(version, 0U, "Only version 0 is supported");
std
::
unique_ptr
<
char
[]
>
buf
(
new
char
[
size
]);
proto
::
VarType
::
TensorDesc
desc
;
is
.
read
(
reinterpret_cast
<
char
*>
(
buf
.
get
()),
size
);
{
// int32_t size
// PADDLE_ENFORCE(desc.ParseFromArray(buf.get(), size),
// proto buffer
// "Cannot parse tensor desc");
int32_t
size
;
}
is
.
read
(
reinterpret_cast
<
char
*>
(
&
size
),
sizeof
(
size
));
{
// read tensor
std
::
unique_ptr
<
char
[]
>
buf
(
new
char
[
size
]);
std
::
vector
<
int64_t
>
dims
;
is
.
read
(
reinterpret_cast
<
char
*>
(
buf
.
get
()),
size
);
dims
.
reserve
(
static_cast
<
size_t
>
(
desc
.
dims
().
size
()));
// PADDLE_ENFORCE(desc.ParseFromArray(buf.get(), size),
std
::
copy
(
desc
.
dims
().
begin
(),
desc
.
dims
().
end
(),
std
::
back_inserter
(
dims
));
// "Cannot parse tensor desc");
tensor
->
Resize
(
framework
::
make_ddim
(
dims
));
}
void
*
buf
;
{
// read tensor
std
::
vector
<
int64_t
>
dims
;
framework
::
VisitDataType
(
desc
.
data_type
(),
dims
.
reserve
(
static_cast
<
size_t
>
(
desc
.
dims
().
size
()));
DeserializedDataFunctor
(
&
buf
,
tensor
));
std
::
copy
(
desc
.
dims
().
begin
(),
desc
.
dims
().
end
(),
is
.
read
(
static_cast
<
char
*>
(
buf
),
tensor
->
memory_size
());
std
::
back_inserter
(
dims
));
}
tensor
->
Resize
(
framework
::
make_ddim
(
dims
));
}
void
*
buf
;
}
// namespace framework
framework
::
VisitDataType
(
desc
.
data_type
(),
DeserializedDataFunctor
(
&
buf
,
tensor
));
is
.
read
(
static_cast
<
char
*>
(
buf
),
tensor
->
memory_size
());
}
}
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/tensor_util.h
浏览文件 @
aef98218
...
@@ -20,47 +20,47 @@ limitations under the License. */
...
@@ -20,47 +20,47 @@ limitations under the License. */
#include <vector>
#include <vector>
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
void
TensorCopy
(
const
Tensor
&
src
,
Tensor
*
dst
);
void
TensorCopy
(
const
Tensor
&
src
,
Tensor
*
dst
);
void
TensorCopySync
(
const
Tensor
&
src
,
Tensor
*
dst
);
void
TensorCopySync
(
const
Tensor
&
src
,
Tensor
*
dst
);
template
<
typename
T
>
template
<
typename
T
>
void
TensorFromVector
(
const
std
::
vector
<
T
>
&
src
,
Tensor
*
dst
);
void
TensorFromVector
(
const
std
::
vector
<
T
>
&
src
,
Tensor
*
dst
);
template
<
typename
T
>
template
<
typename
T
>
void
TesnorToVector
(
const
Tensor
&
src
,
std
::
vector
<
T
>
*
dst
);
void
TesnorToVector
(
const
Tensor
&
src
,
std
::
vector
<
T
>
*
dst
);
bool
TensorContainsNAN
(
const
framework
::
Tensor
&
tensor
);
bool
TensorContainsNAN
(
const
framework
::
Tensor
&
tensor
);
bool
TensorContainsInf
(
const
framework
::
Tensor
&
tensor
);
bool
TensorContainsInf
(
const
framework
::
Tensor
&
tensor
);
void
TensorToStream
(
std
::
ostream
&
os
,
const
Tensor
&
tensor
);
void
TensorToStream
(
std
::
ostream
&
os
,
const
Tensor
&
tensor
);
void
TensorFromStream
(
std
::
istream
&
is
,
Tensor
*
tensor
);
void
TensorFromStream
(
std
::
istream
&
is
,
Tensor
*
tensor
);
//
//
// The implementation of template functions.
// The implementation of template functions.
//
//
template
<
typename
T
>
template
<
typename
T
>
void
TensorFromVector
(
const
std
::
vector
<
T
>
&
src
,
Tensor
*
dst
)
{
void
TensorFromVector
(
const
std
::
vector
<
T
>
&
src
,
Tensor
*
dst
)
{
auto
src_ptr
=
static_cast
<
const
void
*>
(
src
.
data
());
auto
src_ptr
=
static_cast
<
const
void
*>
(
src
.
data
());
dst
->
Resize
({
static_cast
<
int64_t
>
(
src
.
size
())});
dst
->
Resize
({
static_cast
<
int64_t
>
(
src
.
size
())});
auto
dst_ptr
=
static_cast
<
void
*>
(
dst
->
mutable_data
<
T
>
());
auto
dst_ptr
=
static_cast
<
void
*>
(
dst
->
mutable_data
<
T
>
());
auto
size
=
src
.
size
()
*
sizeof
(
T
);
auto
size
=
src
.
size
()
*
sizeof
(
T
);
memory
::
Copy
(
dst_ptr
,
src_ptr
,
size
);
memory
::
Copy
(
dst_ptr
,
src_ptr
,
size
);
}
}
template
<
typename
T
>
template
<
typename
T
>
void
TensorToVector
(
const
Tensor
&
src
,
std
::
vector
<
T
>
*
dst
)
{
void
TensorToVector
(
const
Tensor
&
src
,
std
::
vector
<
T
>
*
dst
)
{
auto
src_ptr
=
static_cast
<
const
void
*>
(
src
.
data
<
T
>
());
auto
src_ptr
=
static_cast
<
const
void
*>
(
src
.
data
<
T
>
());
auto
size
=
src
.
numel
()
*
sizeof
(
T
);
auto
size
=
src
.
numel
()
*
sizeof
(
T
);
dst
->
resize
(
src
.
numel
());
dst
->
resize
(
src
.
numel
());
auto
dst_ptr
=
static_cast
<
void
*>
(
dst
->
data
());
auto
dst_ptr
=
static_cast
<
void
*>
(
dst
->
data
());
memory
::
Copy
(
dst_ptr
,
src_ptr
,
size
);
memory
::
Copy
(
dst_ptr
,
src_ptr
,
size
);
}
}
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/var_desc.cpp
浏览文件 @
aef98218
...
@@ -20,9 +20,9 @@ SOFTWARE.
...
@@ -20,9 +20,9 @@ SOFTWARE.
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
VarDesc
::
VarDesc
(
const
proto
::
VarDesc
&
desc
)
:
desc_
(
desc
)
{}
VarDesc
::
VarDesc
(
const
proto
::
VarDesc
&
desc
)
:
desc_
(
desc
)
{}
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/var_desc.h
浏览文件 @
aef98218
...
@@ -22,67 +22,68 @@ SOFTWARE.
...
@@ -22,67 +22,68 @@ SOFTWARE.
#include "paddle_mobile_object.h"
#include "paddle_mobile_object.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
class
VarDesc
{
class
VarDesc
{
public:
public:
VarDesc
(
const
proto
::
VarDesc
&
desc
);
VarDesc
(
const
proto
::
VarDesc
&
desc
);
std
::
string
Name
()
const
{
return
desc_
.
name
();
}
std
::
string
Name
()
const
{
return
desc_
.
name
();
}
proto
::
VarType
::
Type
GetType
()
const
{
return
desc_
.
type
().
type
();
}
proto
::
VarType
::
Type
GetType
()
const
{
return
desc_
.
type
().
type
();
}
bool
Persistable
()
const
{
return
desc_
.
persistable
();
}
bool
Persistable
()
const
{
return
desc_
.
persistable
();
}
const
proto
::
VarType
::
ChannelDesc
&
channel_desc
()
const
{
const
proto
::
VarType
::
ChannelDesc
&
channel_desc
()
const
{
switch
(
desc_
.
type
().
type
())
{
switch
(
desc_
.
type
().
type
())
{
case
proto
::
VarType
::
CHANNEL
:
case
proto
::
VarType
::
CHANNEL
:
return
desc_
.
type
().
channel
();
return
desc_
.
type
().
channel
();
default:
default:
break
;
break
;
}
}
}
}
const
proto
::
VarType
::
TensorDesc
&
tensor_desc
()
const
{
const
proto
::
VarType
::
TensorDesc
&
tensor_desc
()
const
{
switch
(
desc_
.
type
().
type
())
{
switch
(
desc_
.
type
().
type
())
{
case
proto
::
VarType
::
SELECTED_ROWS
:
case
proto
::
VarType
::
SELECTED_ROWS
:
return
desc_
.
type
().
selected_rows
();
return
desc_
.
type
().
selected_rows
();
case
proto
::
VarType
::
LOD_TENSOR
:
case
proto
::
VarType
::
LOD_TENSOR
:
return
desc_
.
type
().
lod_tensor
().
tensor
();
return
desc_
.
type
().
lod_tensor
().
tensor
();
case
proto
::
VarType
::
LOD_TENSOR_ARRAY
:
case
proto
::
VarType
::
LOD_TENSOR_ARRAY
:
return
desc_
.
type
().
tensor_array
().
tensor
();
return
desc_
.
type
().
tensor_array
().
tensor
();
default:
default:
break
;
break
;
}
}
}
}
proto
::
VarType
::
Type
GetDataType
()
const
{
proto
::
VarType
::
Type
GetDataType
()
const
{
switch
(
desc_
.
type
().
type
())
{
switch
(
desc_
.
type
().
type
())
{
case
proto
::
VarType
::
CHANNEL
:
case
proto
::
VarType
::
CHANNEL
:
return
channel_desc
().
data_type
();
return
channel_desc
().
data_type
();
break
;
break
;
default:
default:
return
tensor_desc
().
data_type
();
return
tensor_desc
().
data_type
();
}
}
}
}
template
<
typename
T
>
template
<
typename
T
>
std
::
vector
<
T
>
RepeatedToVector
(
std
::
vector
<
T
>
RepeatedToVector
(
const
google
::
protobuf
::
RepeatedField
<
T
>
&
repeated_field
)
const
{
const
google
::
protobuf
::
RepeatedField
<
T
>
&
repeated_field
)
std
::
vector
<
T
>
ret
;
const
{
ret
.
reserve
(
repeated_field
.
size
());
std
::
vector
<
T
>
ret
;
std
::
copy
(
repeated_field
.
begin
(),
repeated_field
.
end
(),
ret
.
reserve
(
repeated_field
.
size
());
std
::
back_inserter
(
ret
));
std
::
copy
(
repeated_field
.
begin
(),
repeated_field
.
end
(),
return
ret
;
std
::
back_inserter
(
ret
));
}
return
ret
;
}
std
::
vector
<
int64_t
>
GetShape
()
const
{
std
::
vector
<
int64_t
>
GetShape
()
const
{
return
this
->
RepeatedToVector
(
tensor_desc
().
dims
());
return
this
->
RepeatedToVector
(
tensor_desc
().
dims
());
}
}
private:
private:
proto
::
VarDesc
desc_
;
proto
::
VarDesc
desc_
;
};
};
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/var_type.h
浏览文件 @
aef98218
...
@@ -23,16 +23,17 @@ SOFTWARE.
...
@@ -23,16 +23,17 @@ SOFTWARE.
#include "variable.h"
#include "variable.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
inline
proto
::
VarType
::
Type
ToVarType
(
std
::
type_index
type
)
{
inline
proto
::
VarType
::
Type
ToVarType
(
std
::
type_index
type
)
{
if
(
type
.
hash_code
()
==
typeid
(
LoDTensor
).
hash_code
())
{
if
(
type
.
hash_code
()
==
typeid
(
LoDTensor
).
hash_code
())
{
return
proto
::
VarType_Type_LOD_TENSOR
;
return
proto
::
VarType_Type_LOD_TENSOR
;
}
else
if
(
type
.
hash_code
()
==
typeid
(
SelectedRows
).
hash_code
())
{
}
else
if
(
type
.
hash_code
()
==
typeid
(
SelectedRows
).
hash_code
())
{
return
proto
::
VarType_Type_SELECTED_ROWS
;
return
proto
::
VarType_Type_SELECTED_ROWS
;
}
else
{
}
else
{
// PADDLE_THROW("ToVarType:Unsupported type %s", type.name());
// PADDLE_THROW("ToVarType:Unsupported type %s",
}
// type.name());
}
}
}
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/framework/variable.h
浏览文件 @
aef98218
...
@@ -26,72 +26,74 @@ SOFTWARE.
...
@@ -26,72 +26,74 @@ SOFTWARE.
#include <typeinfo>
#include <typeinfo>
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
class
Variable
:
public
PaddleMobileObject
{
class
Variable
:
public
PaddleMobileObject
{
public:
public:
Variable
()
{}
Variable
()
{}
~
Variable
()
{}
~
Variable
()
{}
template
<
typename
T
>
const
T
*
Get
()
const
{
template
<
typename
T
>
const
T
*
Get
()
const
{
return
static_cast
<
const
T
*>
(
holder_
->
Ptr
());
return
static_cast
<
const
T
*>
(
holder_
->
Ptr
());
}
}
bool
IsInitialized
()
const
{
return
holder_
!=
nullptr
;
}
bool
IsInitialized
()
const
{
return
holder_
!=
nullptr
;
}
const
std
::
string
*
Name
()
{
return
name_
;
}
const
std
::
string
*
Name
()
{
return
name_
;
}
template
<
typename
T
>
T
*
GetMutable
()
{
template
<
typename
T
>
T
*
GetMutable
()
{
if
(
!
IsType
<
T
>
())
{
if
(
!
IsType
<
T
>
())
{
if
(
*
Name
()
==
"pixel"
)
{
if
(
*
Name
()
==
"pixel"
)
{
// std::cout << " reset " << *Name() << std::endl;
// std::cout << " reset " << *Name() <<
}
// std::endl;
holder_
.
reset
(
new
PlaceholderImp
<
T
>
(
new
T
()));
}
}
holder_
.
reset
(
new
PlaceholderImp
<
T
>
(
new
T
()));
return
static_cast
<
T
*>
(
holder_
->
Ptr
());
}
}
return
static_cast
<
T
*>
(
holder_
->
Ptr
());
}
template
<
typename
T
>
bool
IsType
()
const
{
if
(
holder_
)
{
template
<
typename
T
>
bool
IsType
()
const
{
// printf("not null \n");
if
(
holder_
)
{
printf
(
" holder type : %s, this type %s
\n
"
,
holder_
->
Type
().
name
(),
// printf("not null \n");
typeid
(
T
).
name
());
printf
(
" holder type : %s, this type %s
\n
"
,
}
holder_
->
Type
().
name
(),
typeid
(
T
).
name
());
}
// std::cout << " " << holder_->Type() << " " << typeid(T) <<
// std::endl;
// std::cout << " " << holder_->Type() << " " <<
return
holder_
!=
nullptr
&&
holder_
->
Type
()
==
typeid
(
T
);
// typeid(T) <<
}
// std::endl;
return
holder_
!=
nullptr
&&
holder_
->
Type
()
==
typeid
(
T
);
void
Clear
()
{
holder_
.
reset
();
}
}
std
::
type_index
Type
()
const
{
return
holder_
->
Type
();
}
void
Clear
()
{
holder_
.
reset
();
}
void
SetName
(
const
std
::
string
*
name
)
{
name_
=
name
;
}
std
::
type_index
Type
()
const
{
return
holder_
->
Type
();
}
private:
void
SetName
(
const
std
::
string
*
name
)
{
name_
=
name
;
}
struct
Placeholder
{
Placeholder
()
=
default
;
private:
virtual
~
Placeholder
()
=
default
;
struct
Placeholder
{
Placeholder
()
=
default
;
virtual
const
std
::
type_info
&
Type
()
const
=
0
;
virtual
~
Placeholder
()
=
default
;
virtual
void
*
Ptr
()
const
=
0
;
};
virtual
const
std
::
type_info
&
Type
()
const
=
0
;
virtual
void
*
Ptr
()
const
=
0
;
template
<
typename
T
>
struct
PlaceholderImp
:
public
Placeholder
{
};
explicit
PlaceholderImp
(
T
*
ptr
)
:
ptr_
(
ptr
),
type_
(
typeid
(
T
))
{}
template
<
typename
T
>
struct
PlaceholderImp
:
public
Placeholder
{
virtual
const
std
::
type_info
&
Type
()
const
{
return
type_
;
}
explicit
PlaceholderImp
(
T
*
ptr
)
:
ptr_
(
ptr
),
type_
(
typeid
(
T
))
{}
virtual
void
*
Ptr
()
const
override
{
return
static_cast
<
void
*>
(
ptr_
.
get
());
virtual
const
std
::
type_info
&
Type
()
const
{
return
type_
;
}
}
virtual
void
*
Ptr
()
const
override
{
return
static_cast
<
void
*>
(
ptr_
.
get
());
std
::
unique_ptr
<
T
>
ptr_
;
}
const
std
::
type_info
&
type_
;
};
std
::
unique_ptr
<
T
>
ptr_
;
const
std
::
type_info
&
type_
;
std
::
unique_ptr
<
Placeholder
>
holder_
;
};
friend
class
Scope
;
const
std
::
string
*
name_
;
std
::
unique_ptr
<
Placeholder
>
holder_
;
};
friend
class
Scope
;
}
// namespace framework
const
std
::
string
*
name_
;
};
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/io.cpp
浏览文件 @
aef98218
...
@@ -28,357 +28,403 @@ SOFTWARE.
...
@@ -28,357 +28,403 @@ SOFTWARE.
namespace
paddle_mobile
{
namespace
paddle_mobile
{
void
ReadBinaryFile
(
const
std
::
string
&
filename
,
std
::
string
*
contents
)
{
void
ReadBinaryFile
(
const
std
::
string
&
filename
,
std
::
string
*
contents
)
{
std
::
ifstream
fin
(
filename
,
std
::
ios
::
in
|
std
::
ios
::
binary
);
std
::
ifstream
fin
(
filename
,
std
::
ios
::
in
|
std
::
ios
::
binary
);
fin
.
seekg
(
0
,
std
::
ios
::
end
);
fin
.
seekg
(
0
,
std
::
ios
::
end
);
contents
->
clear
();
contents
->
clear
();
contents
->
resize
(
fin
.
tellg
());
contents
->
resize
(
fin
.
tellg
());
fin
.
seekg
(
0
,
std
::
ios
::
beg
);
fin
.
seekg
(
0
,
std
::
ios
::
beg
);
fin
.
read
(
&
(
contents
->
at
(
0
)),
contents
->
size
());
fin
.
read
(
&
(
contents
->
at
(
0
)),
contents
->
size
());
fin
.
close
();
fin
.
close
();
}
template
<
typename
Dtype
,
Precision
P
>
void
Loader
<
Dtype
,
P
>::
LoadVar
(
framework
::
LoDTensor
*
tensor
,
const
std
::
string
&
file_path
)
{
// std::cout << " to load " << file_path << std::endl;
std
::
ifstream
is
(
file_path
);
std
::
streampos
pos
=
is
.
tellg
();
// save current position
is
.
seekg
(
0
,
std
::
ios
::
end
);
// std::cout << " file length = " << is.tellg() << std::endl;
is
.
seekg
(
pos
);
// restore saved position
// 1. version
uint32_t
version
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
version
),
sizeof
(
version
));
// std::cout << " version: " << version << std::endl;
// 2 Lod information
uint64_t
lod_level
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
lod_level
),
sizeof
(
lod_level
));
// std::cout << " load level: " << lod_level << std::endl;
// std::cout << " lod info: " << std::endl;
auto
&
lod
=
*
tensor
->
mutable_lod
();
lod
.
resize
(
lod_level
);
for
(
uint64_t
i
=
0
;
i
<
lod_level
;
++
i
)
{
uint64_t
size
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
size
),
sizeof
(
size
));
std
::
vector
<
size_t
>
tmp
(
size
/
sizeof
(
size_t
));
is
.
read
(
reinterpret_cast
<
char
*>
(
tmp
.
data
()),
static_cast
<
std
::
streamsize
>
(
size
));
for
(
int
j
=
0
;
j
<
tmp
.
size
();
++
j
)
{
// std::cout << " lod - " << tmp[j] << std::endl;
}
lod
[
i
]
=
tmp
;
}
// 3. tensor version
uint32_t
tensor_version
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
tensor_version
),
sizeof
(
tensor_version
));
// std::cout << " tensor_version: " << tensor_version << std::endl;
// 4. tensor desc
int32_t
size
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
size
),
sizeof
(
size
));
// std::cout << " tensor desc size: " << size << std::endl;
std
::
unique_ptr
<
char
[]
>
buf
(
new
char
[
size
]);
is
.
read
(
reinterpret_cast
<
char
*>
(
buf
.
get
()),
size
);
framework
::
proto
::
VarType
::
TensorDesc
desc
;
desc
.
ParseFromArray
(
buf
.
get
(),
size
);
// std::cout << " desc dims size " << desc.dims().size() << std::endl;
int
memory_size
=
1
;
for
(
int
l
=
0
;
l
<
desc
.
dims
().
size
();
++
l
)
{
// std::cout << " dim " << l << " value: " << desc.dims()[l] <<
// std::endl;
memory_size
*=
desc
.
dims
()[
l
];
}
std
::
vector
<
int64_t
>
dims
;
dims
.
reserve
(
static_cast
<
size_t
>
(
desc
.
dims
().
size
()));
std
::
copy
(
desc
.
dims
().
begin
(),
desc
.
dims
().
end
(),
std
::
back_inserter
(
dims
));
tensor
->
Resize
(
framework
::
make_ddim
(
dims
));
void
*
memory
;
int
type_size
=
0
;
// std::cout << " desc pre type: ";
switch
(
desc
.
data_type
())
{
case
framework
::
proto
::
VarType
::
FP16
:
// std::cout << "FP16" << std::endl;
type_size
=
2
;
break
;
case
framework
::
proto
::
VarType
::
FP32
:
type_size
=
4
;
memory
=
tensor
->
mutable_data
<
float
>
();
// std::cout << "FP32" << std::endl;
break
;
case
framework
::
proto
::
VarType
::
FP64
:
type_size
=
8
;
// std::cout << "FP64" << std::endl;
break
;
case
framework
::
proto
::
VarType
::
INT32
:
type_size
=
4
;
// std::cout << "INT32" << std::endl;
break
;
case
framework
::
proto
::
VarType
::
INT64
:
type_size
=
8
;
// std::cout << "INT64" << std::endl;
break
;
case
framework
::
proto
::
VarType
::
BOOL
:
type_size
=
1
;
// std::cout << "BOOL" << std::endl;
break
;
default:
break
;
// std::cout << " not support" << std::endl;
}
// std::cout << " malloc size: " << memory_size * type_size << std::endl;
is
.
read
(
static_cast
<
char
*>
(
memory
),
memory_size
*
type_size
);
// std::cout << " memory: " << memory << std::endl;
is
.
close
();
};
template
<
typename
Dtype
,
Precision
P
>
const
framework
::
Program
<
Dtype
,
P
>
Loader
<
Dtype
,
P
>::
Load
(
const
std
::
string
&
dirname
)
{
std
::
string
model_filename
=
dirname
+
"/__model__"
;
std
::
string
program_desc_str
;
ReadBinaryFile
(
model_filename
,
&
program_desc_str
);
framework
::
proto
::
ProgramDesc
program_desc_proto
;
program_desc_proto
.
ParseFromString
(
program_desc_str
);
std
::
shared_ptr
<
framework
::
ProgramDesc
>
originProgramDesc
=
std
::
make_shared
<
framework
::
ProgramDesc
>
(
program_desc_proto
);
framework
::
Program
<
Dtype
,
P
>
program
;
program
.
originProgram
=
originProgramDesc
;
std
::
shared_ptr
<
framework
::
Scope
>
scope
=
std
::
make_shared
<
framework
::
Scope
>
();
program
.
scope
=
scope
;
auto
block
=
originProgramDesc
->
Block
(
0
);
for
(
auto
block
:
originProgramDesc
->
Blocks
())
{
// std::cout << "for block" << std::endl;
for
(
int
i
=
0
;
i
<
block
->
Vars
().
size
();
++
i
)
{
std
::
shared_ptr
<
framework
::
VarDesc
>
var_desc
=
block
->
Vars
()[
i
];
auto
var
=
scope
->
Var
(
var_desc
->
Name
());
if
(
var_desc
->
GetType
()
==
framework
::
proto
::
VarType
::
LOD_TENSOR
)
{
if
(
var_desc
->
Persistable
()
&&
var_desc
->
GetType
()
!=
framework
::
proto
::
VarType
::
FEED_MINIBATCH
&&
var_desc
->
GetType
()
!=
framework
::
proto
::
VarType
::
FETCH_LIST
)
{
framework
::
LoDTensor
*
tensor
=
var
->
GetMutable
<
framework
::
LoDTensor
>
();
// to load
LoadVar
(
tensor
,
dirname
+
"/"
+
var_desc
->
Name
());
}
}
else
{
// std::cout << "非 lod" << std::endl;
}
}
}
#ifdef PADDLE_MOBILE_DEBUG
for
(
int
i
=
0
;
i
<
program_desc_proto
.
blocks
().
size
();
++
i
)
{
framework
::
proto
::
BlockDesc
block
=
program_desc_proto
.
blocks
()[
i
];
// std::cout << "block: " << block.idx() << std::endl;
for
(
int
j
=
0
;
j
<
block
.
ops
().
size
();
++
j
)
{
framework
::
proto
::
OpDesc
op
=
block
.
ops
()[
j
];
// std::cout << " op: " << op.type() << std::endl;
for
(
int
m
=
0
;
m
<
op
.
inputs_size
();
++
m
)
{
const
framework
::
proto
::
OpDesc
::
Var
&
var
=
op
.
inputs
(
m
);
// std::cout << " input parameter: " << var.parameter() <<
// std::endl;
for
(
int
n
=
0
;
n
<
var
.
arguments
().
size
();
++
n
)
{
// std::cout << " argument - " << var.arguments()[n] <<
// std::endl;
}
}
for
(
int
y
=
0
;
y
<
op
.
outputs_size
();
++
y
)
{
const
framework
::
proto
::
OpDesc
::
Var
&
var
=
op
.
outputs
(
y
);
// std::cout << " output parameter: " << var.parameter() <<
// std::endl;
for
(
int
z
=
0
;
z
<
var
.
arguments
().
size
();
++
z
)
{
// std::cout << " argument - " << var.arguments()[z] <<
// std::endl;
}
}
for
(
int
x
=
0
;
x
<
op
.
attrs
().
size
();
++
x
)
{
const
framework
::
proto
::
OpDesc_Attr
attr
=
op
.
attrs
()[
x
];
// std::cout << " attr name: " << attr.name() << std::endl;
// std::cout << " attr type: " << attr.type() << std::endl;
switch
(
attr
.
type
())
{
case
framework
::
proto
::
AttrType
::
BOOLEAN
:
// std::cout << " boolen: " << attr.b() << std::endl;
break
;
case
framework
::
proto
::
AttrType
::
INT
:
// std::cout << " int: " << attr.i() << std::endl;
break
;
case
framework
::
proto
::
AttrType
::
FLOAT
:
// std::cout << " float: " << attr.f() << std::endl;
case
framework
::
proto
::
AttrType
::
STRING
:
// std::cout << " string: " << attr.s() << std::endl;
case
framework
::
proto
::
AttrType
::
BOOLEANS
:
// std::vector<bool>
// bools(attr.bools_size());
for
(
int
y
=
0
;
y
<
attr
.
bools_size
();
++
y
)
{
// std::cout << " bool - " << attr.bools(y) <<
// std::endl;
}
case
framework
::
proto
::
AttrType
::
LONG
:
// std::cout << " long: " << attr.l() << std::endl;
case
framework
::
proto
::
AttrType
::
FLOATS
:
for
(
int
y
=
0
;
y
<
attr
.
floats_size
();
++
y
)
{
// std::cout << " float - " << y << ": " <<
// attr.floats(y)
// << std::endl;
}
case
framework
::
proto
::
AttrType
::
INTS
:
for
(
int
y
=
0
;
y
<
attr
.
ints_size
();
++
y
)
{
// std::cout << " int - " << y << ": " <<
// attr.ints(y)
// << std::endl;
}
case
framework
::
proto
::
AttrType
::
STRINGS
:
for
(
int
y
=
0
;
y
<
attr
.
strings_size
();
++
y
)
{
// std::cout << " string - " << y << ": " <<
// attr.strings(y)
// << std::endl;
}
}
}
}
}
for
(
int
k
=
0
;
k
<
block
.
vars
().
size
();
++
k
)
{
template
<
typename
Dtype
,
Precision
P
>
framework
::
proto
::
VarDesc
var
=
block
.
vars
()[
k
];
void
Loader
<
Dtype
,
P
>::
LoadVar
(
framework
::
LoDTensor
*
tensor
,
if
(
var
.
type
().
type
()
==
framework
::
proto
::
VarType
::
LOD_TENSOR
)
{
const
std
::
string
&
file_path
)
{
// std::cout << " var name: " << var.name() << std::endl;
// std::cout << " to load " << file_path << std::endl;
const
framework
::
proto
::
VarType
::
TensorDesc
&
tensor_desc
=
var
.
type
().
lod_tensor
().
tensor
();
// std::cout << " in var tensor desc dims size "
// << tensor_desc.dims().size() << std::endl;
int
memory_size
=
1
;
for
(
int
l
=
0
;
l
<
tensor_desc
.
dims
().
size
();
++
l
)
{
// std::cout << " var tensor desc dim " << l
// << " value: " << tensor_desc.dims()[l] <<
// std::endl;
}
}
if
(
var
.
persistable
()
&&
var
.
type
().
type
()
!=
framework
::
proto
::
VarType
::
FEED_MINIBATCH
&&
var
.
type
().
type
()
!=
framework
::
proto
::
VarType
::
FETCH_LIST
)
{
// std::cout << " to load " << var.name() << std::endl;
std
::
string
file_path
=
dirname
+
"/"
+
var
.
name
();
std
::
ifstream
is
(
file_path
);
std
::
ifstream
is
(
file_path
);
std
::
streampos
pos
=
is
.
tellg
();
// save current position
std
::
streampos
pos
=
is
.
tellg
();
// save current position
is
.
seekg
(
0
,
std
::
ios
::
end
);
is
.
seekg
(
0
,
std
::
ios
::
end
);
//
std::cout << " file length = " << is.tellg() << std::endl;
// std::cout << " file length = " << is.tellg() << std::endl;
is
.
seekg
(
pos
);
// restore saved position
is
.
seekg
(
pos
);
// restore saved position
// 1. version
// 1. version
uint32_t
version
;
uint32_t
version
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
version
),
sizeof
(
version
));
is
.
read
(
reinterpret_cast
<
char
*>
(
&
version
),
sizeof
(
version
));
//
std::cout << " version: " << version << std::endl;
// std::cout << " version: " << version << std::endl;
// 2 Lod information
// 2 Lod information
uint64_t
lod_level
;
uint64_t
lod_level
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
lod_level
),
sizeof
(
lod_level
));
is
.
read
(
reinterpret_cast
<
char
*>
(
&
lod_level
),
sizeof
(
lod_level
));
// std::cout << " load level: " << lod_level << std::endl;
// std::cout << " load level: " << lod_level << std::endl;
// std::cout << " lod info: " << std::endl;
// std::cout << " lod info: " << std::endl;
auto
&
lod
=
*
tensor
->
mutable_lod
();
lod
.
resize
(
lod_level
);
for
(
uint64_t
i
=
0
;
i
<
lod_level
;
++
i
)
{
for
(
uint64_t
i
=
0
;
i
<
lod_level
;
++
i
)
{
uint64_t
size
;
uint64_t
size
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
size
),
sizeof
(
size
));
is
.
read
(
reinterpret_cast
<
char
*>
(
&
size
),
sizeof
(
size
));
std
::
vector
<
size_t
>
tmp
(
size
/
sizeof
(
size_t
));
std
::
vector
<
size_t
>
tmp
(
size
/
sizeof
(
size_t
));
is
.
read
(
reinterpret_cast
<
char
*>
(
tmp
.
data
()),
is
.
read
(
reinterpret_cast
<
char
*>
(
tmp
.
data
()),
static_cast
<
std
::
streamsize
>
(
size
));
static_cast
<
std
::
streamsize
>
(
size
));
for
(
int
j
=
0
;
j
<
tmp
.
size
();
++
j
)
{
for
(
int
j
=
0
;
j
<
tmp
.
size
();
++
j
)
{
// std::cout << " lod - " << tmp[j] << std::endl;
// std::cout << " lod - " << tmp[j] << std::endl;
}
}
lod
[
i
]
=
tmp
;
}
}
// 3. tensor version
uint32_t
tensor_version
;
uint32_t
tensor_version
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
version
),
sizeof
(
version
));
is
.
read
(
reinterpret_cast
<
char
*>
(
&
tensor_version
),
// std::cout << " tensor_version: " << tensor_version <<
sizeof
(
tensor_version
));
//
std::endl;
//
std::cout << " tensor_version: " << tensor_version <<
std::endl;
// 4. tensor desc
int32_t
size
;
int32_t
size
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
size
),
sizeof
(
size
));
is
.
read
(
reinterpret_cast
<
char
*>
(
&
size
),
sizeof
(
size
));
//
std::cout << " tensor desc size: " << size << std::endl;
// std::cout << " tensor desc size: " << size << std::endl;
std
::
unique_ptr
<
char
[]
>
buf
(
new
char
[
size
]);
std
::
unique_ptr
<
char
[]
>
buf
(
new
char
[
size
]);
is
.
read
(
reinterpret_cast
<
char
*>
(
buf
.
get
()),
size
);
is
.
read
(
reinterpret_cast
<
char
*>
(
buf
.
get
()),
size
);
framework
::
proto
::
VarType
::
TensorDesc
desc
;
framework
::
proto
::
VarType
::
TensorDesc
desc
;
desc
.
ParseFromArray
(
buf
.
get
(),
size
);
desc
.
ParseFromArray
(
buf
.
get
(),
size
);
//
std::cout << " desc dims size " << desc.dims().size() <<
// std::cout << " desc dims size " << desc.dims().size() <<
//
std::endl;
// std::endl;
int
memory_size
=
1
;
int
memory_size
=
1
;
for
(
int
l
=
0
;
l
<
desc
.
dims
().
size
();
++
l
)
{
for
(
int
l
=
0
;
l
<
desc
.
dims
().
size
();
++
l
)
{
// std::cout << " dim " << l << " value: " <<
// std::cout << " dim " << l << " value: " << desc.dims()[l]
// desc.dims()[l]
// <<
// <<
std::endl;
//
std::endl;
memory_size
*=
desc
.
dims
()[
l
];
memory_size
*=
desc
.
dims
()[
l
];
}
}
std
::
vector
<
int64_t
>
dims
;
dims
.
reserve
(
static_cast
<
size_t
>
(
desc
.
dims
().
size
()));
std
::
copy
(
desc
.
dims
().
begin
(),
desc
.
dims
().
end
(),
std
::
back_inserter
(
dims
));
tensor
->
Resize
(
framework
::
make_ddim
(
dims
));
void
*
memory
;
int
type_size
=
0
;
int
type_size
=
0
;
//
std::cout << " desc pre type: ";
// std::cout << " desc pre type: ";
switch
(
desc
.
data_type
())
{
switch
(
desc
.
data_type
())
{
case
framework
::
proto
::
VarType
::
FP16
:
case
framework
::
proto
::
VarType
::
FP16
:
//
std::cout << "FP16" << std::endl;
//
std::cout << "FP16" << std::endl;
type_size
=
2
;
type_size
=
2
;
break
;
break
;
case
framework
::
proto
::
VarType
::
FP32
:
case
framework
::
proto
::
VarType
::
FP32
:
type_size
=
4
;
type_size
=
4
;
// std::cout << "FP32" << std::endl;
memory
=
tensor
->
mutable_data
<
float
>
();
break
;
// std::cout << "FP32" << std::endl;
break
;
case
framework
::
proto
::
VarType
::
FP64
:
case
framework
::
proto
::
VarType
::
FP64
:
type_size
=
8
;
type_size
=
8
;
//
std::cout << "FP64" << std::endl;
//
std::cout << "FP64" << std::endl;
break
;
break
;
case
framework
::
proto
::
VarType
::
INT32
:
case
framework
::
proto
::
VarType
::
INT32
:
type_size
=
4
;
type_size
=
4
;
//
std::cout << "INT32" << std::endl;
//
std::cout << "INT32" << std::endl;
break
;
break
;
case
framework
::
proto
::
VarType
::
INT64
:
case
framework
::
proto
::
VarType
::
INT64
:
type_size
=
8
;
type_size
=
8
;
//
std::cout << "INT64" << std::endl;
//
std::cout << "INT64" << std::endl;
break
;
break
;
case
framework
::
proto
::
VarType
::
BOOL
:
case
framework
::
proto
::
VarType
::
BOOL
:
type_size
=
1
;
type_size
=
1
;
//
std::cout << "BOOL" << std::endl;
//
std::cout << "BOOL" << std::endl;
break
;
break
;
default:
default:
break
;
break
;
//
std::cout << " not support" << std::endl;
//
std::cout << " not support" << std::endl;
}
}
// std::cout << " malloc size: " << memory_size * type_size
// std::cout << " malloc size: " << memory_size * type_size <<
// << std::endl;
// std::endl;
void
*
memory
=
malloc
(
memory_size
*
type_size
);
is
.
read
(
static_cast
<
char
*>
(
memory
),
memory_size
*
type_size
);
is
.
read
(
static_cast
<
char
*>
(
memory
),
memory_size
*
type_size
);
//
std::cout << " memory: " << memory << std::endl;
// std::cout << " memory: " << memory << std::endl;
is
.
close
();
is
.
close
();
}
else
{
};
// std::cout << " *not load "
// << " var : " << var.name() << std::endl;
template
<
typename
Dtype
,
Precision
P
>
}
const
framework
::
Program
<
Dtype
,
P
>
}
Loader
<
Dtype
,
P
>::
Load
(
const
std
::
string
&
dirname
)
{
}
std
::
string
model_filename
=
dirname
+
"/__model__"
;
std
::
string
program_desc_str
;
ReadBinaryFile
(
model_filename
,
&
program_desc_str
);
framework
::
proto
::
ProgramDesc
program_desc_proto
;
program_desc_proto
.
ParseFromString
(
program_desc_str
);
std
::
shared_ptr
<
framework
::
ProgramDesc
>
originProgramDesc
=
std
::
make_shared
<
framework
::
ProgramDesc
>
(
program_desc_proto
);
framework
::
Program
<
Dtype
,
P
>
program
;
program
.
originProgram
=
originProgramDesc
;
std
::
shared_ptr
<
framework
::
Scope
>
scope
=
std
::
make_shared
<
framework
::
Scope
>
();
program
.
scope
=
scope
;
auto
block
=
originProgramDesc
->
Block
(
0
);
for
(
auto
block
:
originProgramDesc
->
Blocks
())
{
// std::cout << "for block" << std::endl;
for
(
int
i
=
0
;
i
<
block
->
Vars
().
size
();
++
i
)
{
std
::
shared_ptr
<
framework
::
VarDesc
>
var_desc
=
block
->
Vars
()[
i
];
auto
var
=
scope
->
Var
(
var_desc
->
Name
());
if
(
var_desc
->
GetType
()
==
framework
::
proto
::
VarType
::
LOD_TENSOR
)
{
if
(
var_desc
->
Persistable
()
&&
var_desc
->
GetType
()
!=
framework
::
proto
::
VarType
::
FEED_MINIBATCH
&&
var_desc
->
GetType
()
!=
framework
::
proto
::
VarType
::
FETCH_LIST
)
{
framework
::
LoDTensor
*
tensor
=
var
->
GetMutable
<
framework
::
LoDTensor
>
();
// to load
LoadVar
(
tensor
,
dirname
+
"/"
+
var_desc
->
Name
());
}
}
else
{
// std::cout << "非 lod" << std::endl;
}
}
}
#ifdef PADDLE_MOBILE_DEBUG
for
(
int
i
=
0
;
i
<
program_desc_proto
.
blocks
().
size
();
++
i
)
{
framework
::
proto
::
BlockDesc
block
=
program_desc_proto
.
blocks
()[
i
];
// std::cout << "block: " << block.idx() << std::endl;
for
(
int
j
=
0
;
j
<
block
.
ops
().
size
();
++
j
)
{
framework
::
proto
::
OpDesc
op
=
block
.
ops
()[
j
];
// std::cout << " op: " << op.type() << std::endl;
for
(
int
m
=
0
;
m
<
op
.
inputs_size
();
++
m
)
{
const
framework
::
proto
::
OpDesc
::
Var
&
var
=
op
.
inputs
(
m
);
// std::cout << " input parameter: " <<
// var.parameter() <<
// std::endl;
for
(
int
n
=
0
;
n
<
var
.
arguments
().
size
();
++
n
)
{
// std::cout << " argument - " <<
// var.arguments()[n] <<
// std::endl;
}
}
for
(
int
y
=
0
;
y
<
op
.
outputs_size
();
++
y
)
{
const
framework
::
proto
::
OpDesc
::
Var
&
var
=
op
.
outputs
(
y
);
// std::cout << " output parameter: " <<
// var.parameter() <<
// std::endl;
for
(
int
z
=
0
;
z
<
var
.
arguments
().
size
();
++
z
)
{
// std::cout << " argument - " <<
// var.arguments()[z] <<
// std::endl;
}
}
for
(
int
x
=
0
;
x
<
op
.
attrs
().
size
();
++
x
)
{
const
framework
::
proto
::
OpDesc_Attr
attr
=
op
.
attrs
()[
x
];
// std::cout << " attr name: " << attr.name() <<
// std::endl;
// std::cout << " attr type: " << attr.type() <<
// std::endl;
switch
(
attr
.
type
())
{
case
framework
::
proto
::
AttrType
::
BOOLEAN
:
// std::cout << " boolen: " << attr.b() <<
// std::endl;
break
;
case
framework
::
proto
::
AttrType
::
INT
:
// std::cout << " int: " << attr.i() <<
// std::endl;
break
;
case
framework
::
proto
::
AttrType
::
FLOAT
:
// std::cout << " float: " << attr.f() <<
// std::endl;
case
framework
::
proto
::
AttrType
::
STRING
:
// std::cout << " string: " << attr.s() <<
// std::endl;
case
framework
::
proto
::
AttrType
::
BOOLEANS
:
// std::vector<bool>
// bools(attr.bools_size());
for
(
int
y
=
0
;
y
<
attr
.
bools_size
();
++
y
)
{
// std::cout << " bool - " <<
// attr.bools(y) <<
// std::endl;
}
case
framework
::
proto
::
AttrType
::
LONG
:
// std::cout << " long: " << attr.l() <<
// std::endl;
case
framework
::
proto
::
AttrType
::
FLOATS
:
for
(
int
y
=
0
;
y
<
attr
.
floats_size
();
++
y
)
{
// std::cout << " float - " << y <<
// ": " <<
// attr.floats(y)
// << std::endl;
}
case
framework
::
proto
::
AttrType
::
INTS
:
for
(
int
y
=
0
;
y
<
attr
.
ints_size
();
++
y
)
{
// std::cout << " int - " << y << ":
// " <<
// attr.ints(y)
// << std::endl;
}
case
framework
::
proto
::
AttrType
::
STRINGS
:
for
(
int
y
=
0
;
y
<
attr
.
strings_size
();
++
y
)
{
// std::cout << " string - " << y <<
// ": " <<
// attr.strings(y)
// << std::endl;
}
}
}
}
for
(
int
k
=
0
;
k
<
block
.
vars
().
size
();
++
k
)
{
framework
::
proto
::
VarDesc
var
=
block
.
vars
()[
k
];
if
(
var
.
type
().
type
()
==
framework
::
proto
::
VarType
::
LOD_TENSOR
)
{
// std::cout << " var name: " << var.name() <<
// std::endl;
const
framework
::
proto
::
VarType
::
TensorDesc
&
tensor_desc
=
var
.
type
().
lod_tensor
().
tensor
();
// std::cout << " in var tensor desc dims size "
// << tensor_desc.dims().size() <<
// std::endl;
int
memory_size
=
1
;
for
(
int
l
=
0
;
l
<
tensor_desc
.
dims
().
size
();
++
l
)
{
// std::cout << " var tensor desc dim " << l
// << " value: " <<
// tensor_desc.dims()[l] <<
// std::endl;
}
}
if
(
var
.
persistable
()
&&
var
.
type
().
type
()
!=
framework
::
proto
::
VarType
::
FEED_MINIBATCH
&&
var
.
type
().
type
()
!=
framework
::
proto
::
VarType
::
FETCH_LIST
)
{
// std::cout << " to load " << var.name() <<
// std::endl;
std
::
string
file_path
=
dirname
+
"/"
+
var
.
name
();
std
::
ifstream
is
(
file_path
);
std
::
streampos
pos
=
is
.
tellg
();
// save current position
is
.
seekg
(
0
,
std
::
ios
::
end
);
// std::cout << " file length = " << is.tellg() <<
// std::endl;
is
.
seekg
(
pos
);
// restore saved position
// 1. version
uint32_t
version
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
version
),
sizeof
(
version
));
// std::cout << " version: " << version <<
// std::endl;
// 2 Lod information
uint64_t
lod_level
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
lod_level
),
sizeof
(
lod_level
));
// std::cout << " load level: " << lod_level <<
// std::endl;
// std::cout << " lod info: " << std::endl;
for
(
uint64_t
i
=
0
;
i
<
lod_level
;
++
i
)
{
uint64_t
size
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
size
),
sizeof
(
size
));
std
::
vector
<
size_t
>
tmp
(
size
/
sizeof
(
size_t
));
is
.
read
(
reinterpret_cast
<
char
*>
(
tmp
.
data
()),
static_cast
<
std
::
streamsize
>
(
size
));
for
(
int
j
=
0
;
j
<
tmp
.
size
();
++
j
)
{
// std::cout << " lod - " << tmp[j] <<
// std::endl;
}
}
uint32_t
tensor_version
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
version
),
sizeof
(
version
));
// std::cout << " tensor_version: " <<
// tensor_version <<
// std::endl;
int32_t
size
;
is
.
read
(
reinterpret_cast
<
char
*>
(
&
size
),
sizeof
(
size
));
// std::cout << " tensor desc size: " << size <<
// std::endl;
std
::
unique_ptr
<
char
[]
>
buf
(
new
char
[
size
]);
is
.
read
(
reinterpret_cast
<
char
*>
(
buf
.
get
()),
size
);
framework
::
proto
::
VarType
::
TensorDesc
desc
;
desc
.
ParseFromArray
(
buf
.
get
(),
size
);
// std::cout << " desc dims size " <<
// desc.dims().size() <<
// std::endl;
int
memory_size
=
1
;
for
(
int
l
=
0
;
l
<
desc
.
dims
().
size
();
++
l
)
{
// std::cout << " dim " << l << " value: "
// <<
// desc.dims()[l]
// << std::endl;
memory_size
*=
desc
.
dims
()[
l
];
}
int
type_size
=
0
;
// std::cout << " desc pre type: ";
switch
(
desc
.
data_type
())
{
case
framework
::
proto
::
VarType
::
FP16
:
// std::cout << "FP16" << std::endl;
type_size
=
2
;
break
;
case
framework
::
proto
::
VarType
::
FP32
:
type_size
=
4
;
// std::cout << "FP32" << std::endl;
break
;
case
framework
::
proto
::
VarType
::
FP64
:
type_size
=
8
;
// std::cout << "FP64" << std::endl;
break
;
case
framework
::
proto
::
VarType
::
INT32
:
type_size
=
4
;
// std::cout << "INT32" << std::endl;
break
;
case
framework
::
proto
::
VarType
::
INT64
:
type_size
=
8
;
// std::cout << "INT64" << std::endl;
break
;
case
framework
::
proto
::
VarType
::
BOOL
:
type_size
=
1
;
// std::cout << "BOOL" << std::endl;
break
;
default:
break
;
// std::cout << " not support" <<
// std::endl;
}
// std::cout << " malloc size: " << memory_size *
// type_size
// << std::endl;
void
*
memory
=
malloc
(
memory_size
*
type_size
);
is
.
read
(
static_cast
<
char
*>
(
memory
),
memory_size
*
type_size
);
// std::cout << " memory: " << memory <<
// std::endl;
is
.
close
();
}
else
{
// std::cout << " *not load "
// << " var : " << var.name() << std::endl;
}
}
}
#endif
#endif
return
program
;
return
program
;
}
}
template
class
Loader
<
CPU
,
Precision
::
FP32
>;
template
class
Loader
<
CPU
,
Precision
::
FP32
>;
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/io.h
浏览文件 @
aef98218
...
@@ -27,13 +27,14 @@ SOFTWARE.
...
@@ -27,13 +27,14 @@ SOFTWARE.
namespace
paddle_mobile
{
namespace
paddle_mobile
{
template
<
typename
Dtype
,
Precision
P
=
Precision
::
FP32
>
template
<
typename
Dtype
,
Precision
P
=
Precision
::
FP32
>
class
Loader
:
PaddleMobileObject
{
class
Loader
:
PaddleMobileObject
{
public:
public:
const
framework
::
Program
<
Dtype
,
P
>
Load
(
const
std
::
string
&
dirname
);
const
framework
::
Program
<
Dtype
,
P
>
Load
(
const
std
::
string
&
dirname
);
private:
private:
void
LoadVar
(
framework
::
LoDTensor
*
tensor
,
const
std
::
string
&
file_path
);
void
LoadVar
(
framework
::
LoDTensor
*
tensor
,
};
const
std
::
string
&
file_path
);
};
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/memory/t_malloc.cc
浏览文件 @
aef98218
...
@@ -22,30 +22,30 @@ SOFTWARE.
...
@@ -22,30 +22,30 @@ SOFTWARE.
#include <cstring>
#include <cstring>
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
memory
{
namespace
memory
{
const
int
MALLOC_ALIGN
=
16
;
const
int
MALLOC_ALIGN
=
16
;
void
Copy
(
void
*
dst
,
const
void
*
src
,
size_t
num
)
{
void
Copy
(
void
*
dst
,
const
void
*
src
,
size_t
num
)
{
std
::
memcpy
(
dst
,
src
,
num
);
std
::
memcpy
(
dst
,
src
,
num
);
};
};
void
*
Alloc
(
size_t
size
)
{
void
*
Alloc
(
size_t
size
)
{
size_t
offset
=
sizeof
(
void
*
)
+
MALLOC_ALIGN
-
1
;
size_t
offset
=
sizeof
(
void
*
)
+
MALLOC_ALIGN
-
1
;
char
*
p
=
static_cast
<
char
*>
(
malloc
(
offset
+
size
));
char
*
p
=
static_cast
<
char
*>
(
malloc
(
offset
+
size
));
if
(
!
p
)
{
if
(
!
p
)
{
return
nullptr
;
return
nullptr
;
}
}
void
*
r
=
reinterpret_cast
<
void
*>
(
reinterpret_cast
<
size_t
>
(
p
+
offset
)
&
void
*
r
=
reinterpret_cast
<
void
*>
(
(
~
(
MALLOC_ALIGN
-
1
)));
reinterpret_cast
<
size_t
>
(
p
+
offset
)
&
(
~
(
MALLOC_ALIGN
-
1
)));
static_cast
<
void
**>
(
r
)[
-
1
]
=
p
;
static_cast
<
void
**>
(
r
)[
-
1
]
=
p
;
return
r
;
return
r
;
}
}
void
Free
(
void
*
ptr
)
{
void
Free
(
void
*
ptr
)
{
if
(
ptr
)
{
if
(
ptr
)
{
free
(
static_cast
<
void
**>
(
ptr
)[
-
1
]);
free
(
static_cast
<
void
**>
(
ptr
)[
-
1
]);
}
}
}
}
}
// namespace memory
}
// namespace memory
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/memory/t_malloc.h
浏览文件 @
aef98218
...
@@ -21,44 +21,44 @@ SOFTWARE.
...
@@ -21,44 +21,44 @@ SOFTWARE.
#include <type_traits>
#include <type_traits>
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
memory
{
namespace
memory
{
void
Copy
(
void
*
dst
,
const
void
*
src
,
size_t
num
);
void
Copy
(
void
*
dst
,
const
void
*
src
,
size_t
num
);
void
*
Alloc
(
size_t
size
);
void
*
Alloc
(
size_t
size
);
void
Free
(
void
*
ptr
);
void
Free
(
void
*
ptr
);
/**
/**
* \brief Free memory block in one place.
* \brief Free memory block in one place.
*
*
* \note In some cases, custom deleter is used to
* \note In some cases, custom deleter is used to
* deallocate the memory automatically for
* deallocate the memory automatically for
* std::unique_ptr<T> in tensor.h.
* std::unique_ptr<T> in tensor.h.
* static_cast
* static_cast
*/
*/
template
<
typename
T
>
class
PODDeleter
{
template
<
typename
T
>
class
PODDeleter
{
static_assert
(
std
::
is_pod
<
T
>::
value
,
"T must be POD"
);
static_assert
(
std
::
is_pod
<
T
>::
value
,
"T must be POD"
);
public:
public:
explicit
PODDeleter
(){};
explicit
PODDeleter
(){};
void
operator
()(
T
*
ptr
)
{
Free
(
static_cast
<
void
*>
(
ptr
));
}
void
operator
()(
T
*
ptr
)
{
Free
(
static_cast
<
void
*>
(
ptr
));
}
};
};
/**
/**
* \brief Free memory block in one place does not meet POD
* \brief Free memory block in one place does not meet POD
*
*
* \note In some cases, custom deleter is used to
* \note In some cases, custom deleter is used to
* deallocate the memory automatically for
* deallocate the memory automatically for
* std::unique_ptr<T> in tensor.h.
* std::unique_ptr<T> in tensor.h.
* reinterpret_cast
* reinterpret_cast
*/
*/
template
<
typename
T
>
class
PlainDeleter
{
template
<
typename
T
>
class
PlainDeleter
{
public:
public:
explicit
PlainDeleter
(){};
explicit
PlainDeleter
(){};
void
operator
()(
T
*
ptr
)
{
Free
(
reinterpret_cast
<
void
*>
(
ptr
));
}
void
operator
()(
T
*
ptr
)
{
Free
(
reinterpret_cast
<
void
*>
(
ptr
));
}
};
};
}
// namespace memory
}
// namespace memory
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/operators/conv_op.cpp
浏览文件 @
aef98218
...
@@ -22,55 +22,55 @@ SOFTWARE.
...
@@ -22,55 +22,55 @@ SOFTWARE.
#include "framework/operator.h"
#include "framework/operator.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
operators
{
namespace
operators
{
int
ConvOutputSize
(
int
input_size
,
int
filter_size
,
int
dilation
,
int
padding
,
int
ConvOutputSize
(
int
input_size
,
int
filter_size
,
int
dilation
,
int
stride
)
{
int
padding
,
int
stride
)
{
const
int
dkernel
=
dilation
*
(
filter_size
-
1
)
+
1
;
const
int
dkernel
=
dilation
*
(
filter_size
-
1
)
+
1
;
int
output_size
=
(
input_size
+
2
*
padding
-
dkernel
)
/
stride
+
1
;
int
output_size
=
(
input_size
+
2
*
padding
-
dkernel
)
/
stride
+
1
;
return
output_size
;
return
output_size
;
}
}
template
<
typename
Dtype
,
typename
T
>
template
<
typename
Dtype
,
typename
T
>
void
ConvOp
<
Dtype
,
T
>::
InferShape
()
const
{
void
ConvOp
<
Dtype
,
T
>::
InferShape
()
const
{
// std::cout << " begin get dims: " << std::endl;
// std::cout << " begin get dims: " << std::endl;
auto
in_dims
=
param_
.
Input
()
->
dims
();
auto
in_dims
=
param_
.
Input
()
->
dims
();
// std::cout << " end get in dims: " << std::endl;
// std::cout << " end get in dims: " << std::endl;
// std::cout << " in_dims: " << in_dims << std::endl;
// std::cout << " in_dims: " << in_dims << std::endl;
// std::cout << " begin get Filter " << std::endl;
// std::cout << " begin get Filter " << std::endl;
auto
filter_dims
=
param_
.
Filter
()
->
dims
();
auto
filter_dims
=
param_
.
Filter
()
->
dims
();
// std::cout << " end get Filter " << std::endl;
// std::cout << " end get Filter " << std::endl;
// std::cout << " begin get Attrs " << std::endl;
// std::cout << " begin get Attrs " << std::endl;
const
std
::
vector
<
int
>
&
strides
=
param_
.
Strides
();
const
std
::
vector
<
int
>
&
strides
=
param_
.
Strides
();
// std::cout << " end get Attrs " << strides[0] << std::endl;
// std::cout << " end get Attrs " << strides[0] << std::endl;
std
::
vector
<
int
>
paddings
=
param_
.
Paddings
();
std
::
vector
<
int
>
paddings
=
param_
.
Paddings
();
int
groups
=
param_
.
Groups
();
int
groups
=
param_
.
Groups
();
std
::
vector
<
int
>
dilations
=
param_
.
Dilations
();
std
::
vector
<
int
>
dilations
=
param_
.
Dilations
();
std
::
vector
<
int64_t
>
output_shape
({
in_dims
[
0
],
filter_dims
[
0
]});
std
::
vector
<
int64_t
>
output_shape
({
in_dims
[
0
],
filter_dims
[
0
]});
for
(
size_t
i
=
0
;
i
<
strides
.
size
();
++
i
)
{
for
(
size_t
i
=
0
;
i
<
strides
.
size
();
++
i
)
{
output_shape
.
push_back
(
ConvOutputSize
(
in_dims
[
i
+
2
],
filter_dims
[
i
+
2
],
output_shape
.
push_back
(
dilations
[
i
],
paddings
[
i
],
ConvOutputSize
(
in_dims
[
i
+
2
],
filter_dims
[
i
+
2
],
strides
[
i
]));
dilations
[
i
],
paddings
[
i
],
strides
[
i
]));
}
}
framework
::
DDim
ddim
=
framework
::
make_ddim
(
output_shape
);
framework
::
DDim
ddim
=
framework
::
make_ddim
(
output_shape
);
param_
.
Output
()
->
Resize
(
ddim
);
param_
.
Output
()
->
Resize
(
ddim
);
}
}
template
class
ConvOp
<
CPU
,
float
>;
template
class
ConvOp
<
CPU
,
float
>;
}
// namespace operators
}
// namespace operators
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/operators/conv_op.h
浏览文件 @
aef98218
...
@@ -22,31 +22,32 @@ SOFTWARE.
...
@@ -22,31 +22,32 @@ SOFTWARE.
#include "operators/kernel/conv_kernel.h"
#include "operators/kernel/conv_kernel.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
operators
{
namespace
operators
{
using
namespace
framework
;
using
namespace
framework
;
template
<
typename
DeviceType
,
typename
T
>
template
<
typename
DeviceType
,
typename
T
>
class
ConvOp
:
public
framework
::
OperatorWithKernel
<
DeviceType
>
{
class
ConvOp
:
public
framework
::
OperatorWithKernel
<
DeviceType
>
{
public:
public:
ConvOp
(
const
std
::
string
&
type
,
const
VariableNameMap
&
inputs
,
ConvOp
(
const
std
::
string
&
type
,
const
VariableNameMap
&
inputs
,
const
VariableNameMap
&
outputs
,
const
framework
::
AttributeMap
&
attrs
,
const
VariableNameMap
&
outputs
,
std
::
shared_ptr
<
framework
::
Scope
>
scope
)
const
framework
::
AttributeMap
&
attrs
,
:
framework
::
OperatorWithKernel
<
DeviceType
>
(
type
,
inputs
,
outputs
,
attrs
,
std
::
shared_ptr
<
framework
::
Scope
>
scope
)
scope
),
:
framework
::
OperatorWithKernel
<
DeviceType
>
(
param_
(
inputs
,
outputs
,
attrs
,
*
scope
)
{}
type
,
inputs
,
outputs
,
attrs
,
scope
),
param_
(
inputs
,
outputs
,
attrs
,
*
scope
)
{}
using
framework
::
OperatorWithKernel
<
DeviceType
>::
OperatorWithKernel
;
void
InferShape
()
const
override
;
using
framework
::
OperatorWithKernel
<
DeviceType
>::
OperatorWithKernel
;
void
InferShape
()
const
override
;
protected:
void
RunImpl
()
const
{
protected:
operators
::
ConvKernel
<
DeviceType
,
T
,
ConvParam
>
kernel
;
void
RunImpl
()
const
{
kernel
.
Compute
(
param_
);
operators
::
ConvKernel
<
DeviceType
,
T
,
ConvParam
>
kernel
;
}
kernel
.
Compute
(
param_
);
}
ConvParam
param_
;
};
ConvParam
param_
;
};
}
// operators
}
// operators
}
// paddle_mobile
}
// paddle_mobile
src/operators/kernel/arm/conv_kernel.cpp
浏览文件 @
aef98218
...
@@ -19,135 +19,150 @@ SOFTWARE.
...
@@ -19,135 +19,150 @@ SOFTWARE.
#include "operators/kernel/conv_kernel.h"
#include "operators/kernel/conv_kernel.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
operators
{
namespace
operators
{
bool
IsExpand
(
const
std
::
vector
<
int64_t
>
&
filter_dim
,
bool
IsExpand
(
const
std
::
vector
<
int64_t
>
&
filter_dim
,
const
std
::
vector
<
int
>
&
strides
,
const
std
::
vector
<
int
>
&
paddings
,
const
std
::
vector
<
int
>
&
strides
,
const
std
::
vector
<
int
>
&
dilations
)
{
const
std
::
vector
<
int
>
&
paddings
,
bool
filter_1
=
true
,
strides_1
=
true
,
padding_0
=
true
,
dilation_1
=
true
;
const
std
::
vector
<
int
>
&
dilations
)
{
for
(
size_t
j
=
0
;
j
<
strides
.
size
();
++
j
)
{
bool
filter_1
=
true
,
strides_1
=
true
,
padding_0
=
true
,
filter_1
=
filter_1
&&
(
static_cast
<
int
>
(
filter_dim
[
j
+
2
])
==
1
);
dilation_1
=
true
;
strides_1
=
strides_1
&&
(
strides
[
j
]
==
1
);
for
(
size_t
j
=
0
;
j
<
strides
.
size
();
++
j
)
{
padding_0
=
padding_0
&&
(
paddings
[
j
]
==
0
);
filter_1
=
dilation_1
=
dilation_1
&&
(
dilations
[
j
]
==
1
);
filter_1
&&
(
static_cast
<
int
>
(
filter_dim
[
j
+
2
])
==
1
);
}
strides_1
=
strides_1
&&
(
strides
[
j
]
==
1
);
return
!
(
filter_1
&&
strides_1
&&
padding_0
&&
dilation_1
);
padding_0
=
padding_0
&&
(
paddings
[
j
]
==
0
);
}
dilation_1
=
dilation_1
&&
(
dilations
[
j
]
==
1
);
}
template
<
>
return
!
(
filter_1
&&
strides_1
&&
padding_0
&&
dilation_1
);
void
ConvKernel
<
CPU
,
float
,
ConvParam
>::
Compute
(
const
ConvParam
&
param
)
const
{
}
const
Tensor
*
input
=
param
.
Input
();
template
<
>
std
::
cout
<<
" conv param "
<<
param
<<
std
::
endl
;
void
ConvKernel
<
CPU
,
float
,
ConvParam
>::
Compute
(
const
ConvParam
&
param
)
const
{
// The filter will be reshaped in the calculations,
const
Tensor
*
input
=
param
.
Input
();
// so here use an assignment operation,
// that avoids modifying the variable in the Scope.
std
::
cout
<<
" conv param "
<<
param
<<
std
::
endl
;
Tensor
filter
=
*
param
.
Filter
();
// The filter will be reshaped in the calculations,
Tensor
*
output
=
param
.
Output
();
// so here use an assignment operation,
// output->mutable_data<T>(context.GetPlace());
// that avoids modifying the variable in the Scope.
Tensor
filter
=
*
param
.
Filter
();
int
groups
=
param
.
Groups
();
std
::
vector
<
int
>
strides
=
param
.
Strides
();
Tensor
*
output
=
param
.
Output
();
std
::
vector
<
int
>
paddings
=
param
.
Paddings
();
// output->mutable_data<T>(context.GetPlace());
std
::
vector
<
int
>
dilations
=
param
.
Dilations
();
int
groups
=
param
.
Groups
();
std
::
cout
<<
" compute end get Attrs "
<<
strides
[
0
]
<<
std
::
endl
;
std
::
vector
<
int
>
strides
=
param
.
Strides
();
std
::
vector
<
int
>
paddings
=
param
.
Paddings
();
const
int
batch_size
=
static_cast
<
int
>
(
input
->
dims
()[
0
]);
std
::
vector
<
int
>
dilations
=
param
.
Dilations
();
// filter_shape_vec: {k_o, k_i, k_h, k_w} or {k_o, k_i, k_d, k_h, k_w}
std
::
cout
<<
" compute end get Attrs "
<<
strides
[
0
]
<<
std
::
endl
;
std
::
vector
<
int64_t
>
filter_shape_vec
(
framework
::
vectorize
(
filter
.
dims
()));
// output_shape_vec: {o_n, o_c, o_h, o_w} or {o_n, o_c, o_d, o_h, o_w}
const
int
batch_size
=
static_cast
<
int
>
(
input
->
dims
()[
0
]);
std
::
vector
<
int64_t
>
output_shape_vec
(
framework
::
vectorize
(
output
->
dims
()));
// filter_shape_vec: {k_o, k_i, k_h, k_w} or {k_o, k_i, k_d, k_h,
// use col_shape in the im2col calculation
// k_w}
// col_shape_vec: {i_c/g, k_h, k_w, o_h, o_w} or {i_c/g, k_d, k_h, k_w, o_d,
std
::
vector
<
int64_t
>
filter_shape_vec
(
// o_h, o_w}
framework
::
vectorize
(
filter
.
dims
()));
size_t
data_dim
=
filter_shape_vec
.
size
()
-
2
;
// output_shape_vec: {o_n, o_c, o_h, o_w} or {o_n, o_c, o_d, o_h,
std
::
vector
<
int64_t
>
col_shape_vec
(
1
+
2
*
data_dim
);
// o_w}
col_shape_vec
[
0
]
=
input
->
dims
()[
1
]
/
groups
;
std
::
vector
<
int64_t
>
output_shape_vec
(
for
(
size_t
j
=
0
;
j
<
data_dim
;
++
j
)
{
framework
::
vectorize
(
output
->
dims
()));
col_shape_vec
[
j
+
1
]
=
filter_shape_vec
[
j
+
2
];
col_shape_vec
[
j
+
1
+
data_dim
]
=
output_shape_vec
[
j
+
2
];
// use col_shape in the im2col calculation
}
// col_shape_vec: {i_c/g, k_h, k_w, o_h, o_w} or {i_c/g, k_d, k_h,
framework
::
DDim
col_shape
(
framework
::
make_ddim
(
col_shape_vec
));
// k_w, o_d,
// o_h, o_w}
// use col_matrix_shape in the gemm calculation
size_t
data_dim
=
filter_shape_vec
.
size
()
-
2
;
// size: (i_c/g * k_h * k_w, o_h * o_w) or (i_c/g * k_d * k_h * k_w, o_d *
std
::
vector
<
int64_t
>
col_shape_vec
(
1
+
2
*
data_dim
);
// o_h * o_w)
col_shape_vec
[
0
]
=
input
->
dims
()[
1
]
/
groups
;
framework
::
DDim
col_matrix_shape
=
for
(
size_t
j
=
0
;
j
<
data_dim
;
++
j
)
{
framework
::
flatten_to_2d
(
col_shape
,
data_dim
+
1
);
col_shape_vec
[
j
+
1
]
=
filter_shape_vec
[
j
+
2
];
col_shape_vec
[
j
+
1
+
data_dim
]
=
output_shape_vec
[
j
+
2
];
bool
is_expand
=
IsExpand
(
filter_shape_vec
,
strides
,
paddings
,
dilations
);
}
Tensor
col
;
framework
::
DDim
col_shape
(
framework
::
make_ddim
(
col_shape_vec
));
// col_matrix shares the same piece of data with col,
// but will be reshaped into a two-dimensional matrix shape
// use col_matrix_shape in the gemm calculation
// to call the matrix multiplication interface.
// size: (i_c/g * k_h * k_w, o_h * o_w) or (i_c/g * k_d * k_h * k_w,
Tensor
col_matrix
;
// o_d *
if
(
is_expand
)
{
// o_h * o_w)
col
.
mutable_data
<
float
>
(
col_shape
);
framework
::
DDim
col_matrix_shape
=
col_matrix
.
ShareDataWith
(
col
);
framework
::
flatten_to_2d
(
col_shape
,
data_dim
+
1
);
col_matrix
.
Resize
(
col_matrix_shape
);
}
bool
is_expand
=
IsExpand
(
filter_shape_vec
,
strides
,
paddings
,
dilations
);
framework
::
DDim
input_shape
=
framework
::
slice_ddim
(
Tensor
col
;
input
->
dims
(),
1
,
static_cast
<
int
>
(
input
->
dims
().
size
()));
// col_matrix shares the same piece of data with col,
// but will be reshaped into a two-dimensional matrix shape
framework
::
DDim
filter_matrix_shape
=
{
filter
.
dims
()[
0
],
// to call the matrix multiplication interface.
filter
.
numel
()
/
filter
.
dims
()[
0
]};
Tensor
col_matrix
;
filter
.
Resize
(
filter_matrix_shape
);
if
(
is_expand
)
{
col
.
mutable_data
<
float
>
(
col_shape
);
std
::
cout
<<
" input dim "
<<
input
->
dims
()
<<
std
::
endl
;
col_matrix
.
ShareDataWith
(
col
);
col_matrix
.
Resize
(
col_matrix_shape
);
std
::
cout
<<
" output dim "
<<
output
->
dims
()
<<
std
::
endl
;
}
framework
::
DDim
output_matrix_shape
=
{
framework
::
DDim
input_shape
=
framework
::
slice_ddim
(
output
->
dims
()[
1
],
input
->
dims
(),
1
,
static_cast
<
int
>
(
input
->
dims
().
size
()));
output
->
numel
()
/
(
output
->
dims
()[
0
]
*
output
->
dims
()[
1
])};
framework
::
DDim
filter_matrix_shape
=
{
// convolution operator: im2col(or vol2col) + gemm
filter
.
dims
()[
0
],
filter
.
numel
()
/
filter
.
dims
()[
0
]};
int
in_step
=
static_cast
<
int
>
(
input
->
dims
()[
1
])
/
groups
;
filter
.
Resize
(
filter_matrix_shape
);
int
out_step
=
static_cast
<
int
>
(
output
->
dims
()[
1
])
/
groups
;
std
::
cout
<<
" input dim "
<<
input
->
dims
()
<<
std
::
endl
;
math
::
Vol2ColFunctor
<
CPU
,
float
>
vol2col
;
math
::
Im2ColFunctor
<
math
::
ColFormat
::
kCFO
,
CPU
,
float
>
im2col
;
std
::
cout
<<
" output dim "
<<
output
->
dims
()
<<
std
::
endl
;
// auto& dev_ctx = context.template
framework
::
DDim
output_matrix_shape
=
{
// device_context<DeviceContext>();
output
->
dims
()[
1
],
for
(
int
i
=
0
;
i
<
batch_size
;
i
++
)
{
output
->
numel
()
/
(
output
->
dims
()[
0
]
*
output
->
dims
()[
1
])};
Tensor
in_batch
=
input
->
Slice
(
i
,
i
+
1
).
Resize
(
input_shape
);
Tensor
out_batch
=
output
->
Slice
(
i
,
i
+
1
).
Resize
(
output_matrix_shape
);
// convolution operator: im2col(or vol2col) + gemm
int
in_step
=
static_cast
<
int
>
(
input
->
dims
()[
1
])
/
groups
;
for
(
int
g
=
0
;
g
<
groups
;
g
++
)
{
int
out_step
=
static_cast
<
int
>
(
output
->
dims
()[
1
])
/
groups
;
Tensor
in_slice
=
in_batch
.
Slice
(
g
*
in_step
,
(
g
+
1
)
*
in_step
);
math
::
Vol2ColFunctor
<
CPU
,
float
>
vol2col
;
if
(
!
is_expand
)
{
math
::
Im2ColFunctor
<
math
::
ColFormat
::
kCFO
,
CPU
,
float
>
im2col
;
col
.
ShareDataWith
(
in_slice
);
col_matrix
.
ShareDataWith
(
col
);
// auto& dev_ctx = context.template
col_matrix
.
Resize
(
col_matrix_shape
);
// device_context<DeviceContext>();
}
else
if
(
data_dim
==
2U
)
{
for
(
int
i
=
0
;
i
<
batch_size
;
i
++
)
{
// im2col
Tensor
in_batch
=
input
->
Slice
(
i
,
i
+
1
).
Resize
(
input_shape
);
im2col
(
in_slice
,
dilations
,
strides
,
Tensor
out_batch
=
std
::
vector
<
int
>
{
paddings
[
0
],
paddings
[
1
],
paddings
[
0
],
output
->
Slice
(
i
,
i
+
1
).
Resize
(
output_matrix_shape
);
paddings
[
1
]},
&
col
);
for
(
int
g
=
0
;
g
<
groups
;
g
++
)
{
}
else
if
(
data_dim
==
3U
)
{
Tensor
in_slice
=
// vol2col
in_batch
.
Slice
(
g
*
in_step
,
(
g
+
1
)
*
in_step
);
vol2col
(
in_slice
,
dilations
,
strides
,
paddings
,
&
col
);
}
if
(
!
is_expand
)
{
col
.
ShareDataWith
(
in_slice
);
// gemm
col_matrix
.
ShareDataWith
(
col
);
Tensor
out_slice
=
out_batch
.
Slice
(
g
*
out_step
,
(
g
+
1
)
*
out_step
);
col_matrix
.
Resize
(
col_matrix_shape
);
Tensor
filter_slice
=
filter
.
Slice
(
g
*
out_step
,
(
g
+
1
)
*
out_step
);
}
else
if
(
data_dim
==
2U
)
{
math
::
matmul
<
float
>
(
filter_slice
,
false
,
col_matrix
,
false
,
float
(
1.0
),
// im2col
&
out_slice
,
float
(
0.0
));
im2col
(
in_slice
,
dilations
,
strides
,
}
std
::
vector
<
int
>
{
paddings
[
0
],
paddings
[
1
],
}
paddings
[
0
],
paddings
[
1
]},
}
&
col
);
}
else
if
(
data_dim
==
3U
)
{
template
class
ConvKernel
<
CPU
,
float
,
ConvParam
>;
// vol2col
vol2col
(
in_slice
,
dilations
,
strides
,
paddings
,
&
col
);
}
// namespace operators
}
// gemm
Tensor
out_slice
=
out_batch
.
Slice
(
g
*
out_step
,
(
g
+
1
)
*
out_step
);
Tensor
filter_slice
=
filter
.
Slice
(
g
*
out_step
,
(
g
+
1
)
*
out_step
);
math
::
matmul
<
float
>
(
filter_slice
,
false
,
col_matrix
,
false
,
float
(
1.0
),
&
out_slice
,
float
(
0.0
));
}
}
}
template
class
ConvKernel
<
CPU
,
float
,
ConvParam
>;
}
// namespace operators
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/operators/kernel/conv_kernel.h
浏览文件 @
aef98218
...
@@ -25,14 +25,15 @@ SOFTWARE.
...
@@ -25,14 +25,15 @@ SOFTWARE.
#pragma once;
#pragma once;
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
operators
{
namespace
operators
{
using
namespace
framework
;
using
namespace
framework
;
template
<
typename
DeviceType
,
typename
T
,
typename
P
>
template
<
typename
DeviceType
,
typename
T
,
typename
P
>
class
ConvKernel
:
public
framework
::
OpKernelBase
<
DeviceType
,
ConvParam
>
{
class
ConvKernel
public:
:
public
framework
::
OpKernelBase
<
DeviceType
,
ConvParam
>
{
void
Compute
(
const
ConvParam
&
param
)
const
;
public:
};
void
Compute
(
const
ConvParam
&
param
)
const
;
}
};
}
}
}
src/operators/kernel/fpga/conv_kernel.cpp
浏览文件 @
aef98218
...
@@ -19,11 +19,12 @@ SOFTWARE.
...
@@ -19,11 +19,12 @@ SOFTWARE.
#include "operators/kernel/conv_kernel.h"
#include "operators/kernel/conv_kernel.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
operators
{
namespace
operators
{
// template<>
// template<>
// void ConvKernel<FPGA, float>::Compute(const ConvParam ¶m) const {}
// void ConvKernel<FPGA, float>::Compute(const ConvParam ¶m) const
//
// {}
// template class ConvKernel<FPGA, float>;
//
}
// template class ConvKernel<FPGA, float>;
}
}
}
src/operators/math/im2col.cc
浏览文件 @
aef98218
...
@@ -16,275 +16,349 @@ limitations under the License. */
...
@@ -16,275 +16,349 @@ limitations under the License. */
#include "common/types.h"
#include "common/types.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
operators
{
namespace
operators
{
namespace
math
{
namespace
math
{
/*
/*
* im = [input_channels, input_height, input_width]
* im = [input_channels, input_height, input_width]
* col =
* col =
* [input_channels, filter_height, filter_width, output_height, output_width]
* [input_channels, filter_height, filter_width, output_height,
*/
* output_width]
template
<
class
T
>
class
Im2ColFunctor
<
ColFormat
::
kCFO
,
CPU
,
T
>
{
*/
public:
template
<
class
T
>
class
Im2ColFunctor
<
ColFormat
::
kCFO
,
CPU
,
T
>
{
void
operator
()(
const
framework
::
Tensor
&
im
,
const
std
::
vector
<
int
>
&
dilation
,
public:
const
std
::
vector
<
int
>
&
stride
,
void
operator
()(
const
framework
::
Tensor
&
im
,
const
std
::
vector
<
int
>
&
padding
,
framework
::
Tensor
*
col
)
{
const
std
::
vector
<
int
>
&
dilation
,
// PADDLE_ENFORCE(im.dims().size() == 3);
const
std
::
vector
<
int
>
&
stride
,
// PADDLE_ENFORCE(col->dims().size() == 5);
const
std
::
vector
<
int
>
&
padding
,
framework
::
Tensor
*
col
)
{
// PADDLE_ENFORCE(im.dims().size() == 3);
// PADDLE_ENFORCE(col->dims().size() == 5);
int
im_channels
=
im
.
dims
()[
0
];
int
im_channels
=
im
.
dims
()[
0
];
int
im_height
=
im
.
dims
()[
1
];
int
im_height
=
im
.
dims
()[
1
];
int
im_width
=
im
.
dims
()[
2
];
int
im_width
=
im
.
dims
()[
2
];
int
filter_height
=
col
->
dims
()[
1
];
int
filter_height
=
col
->
dims
()[
1
];
int
filter_width
=
col
->
dims
()[
2
];
int
filter_width
=
col
->
dims
()[
2
];
int
col_height
=
col
->
dims
()[
3
];
int
col_height
=
col
->
dims
()[
3
];
int
col_width
=
col
->
dims
()[
4
];
int
col_width
=
col
->
dims
()[
4
];
// PADDLE_ENFORCE_EQ((im_height + padding[0] + padding[2] -
// PADDLE_ENFORCE_EQ((im_height + padding[0] + padding[2]
// ((dilation[0] * (filter_height - 1) + 1))) /
// -
// stride[0] +
// ((dilation[0] * (filter_height - 1)
// 1,
// + 1))) /
// col_height,
// stride[0] +
// "Output_height and padding(padding_up, padding_down)
// 1,
// are " "inconsistent.");
// col_height,
// PADDLE_ENFORCE_EQ((im_width + padding[1] + padding[3] -
// "Output_height and
// ((dilation[1] * (filter_width - 1) + 1))) /
// padding(padding_up, padding_down)
// stride[1] +
// are " "inconsistent.");
// 1,
// PADDLE_ENFORCE_EQ((im_width + padding[1] + padding[3]
// col_width,
// -
// "Output_height and padding(padding_up, padding_down)
// ((dilation[1] * (filter_width - 1)
// are " "inconsistent.");
// + 1))) /
// stride[1] +
// 1,
// col_width,
// "Output_height and
// padding(padding_up, padding_down)
// are " "inconsistent.");
int
channels_col
=
im_channels
*
filter_height
*
filter_width
;
int
channels_col
=
im_channels
*
filter_height
*
filter_width
;
const
T
*
im_data
=
im
.
data
<
T
>
();
const
T
*
im_data
=
im
.
data
<
T
>
();
T
*
col_data
=
col
->
data
<
T
>
();
T
*
col_data
=
col
->
data
<
T
>
();
for
(
int
c
=
0
;
c
<
channels_col
;
++
c
)
{
for
(
int
c
=
0
;
c
<
channels_col
;
++
c
)
{
int
w_offset
=
c
%
filter_width
;
int
w_offset
=
c
%
filter_width
;
int
h_offset
=
(
c
/
filter_width
)
%
filter_height
;
int
h_offset
=
(
c
/
filter_width
)
%
filter_height
;
int
c_im
=
c
/
(
filter_width
*
filter_height
);
int
c_im
=
c
/
(
filter_width
*
filter_height
);
for
(
int
h
=
0
;
h
<
col_height
;
++
h
)
{
for
(
int
h
=
0
;
h
<
col_height
;
++
h
)
{
int
im_row_idx
=
h
*
stride
[
0
]
-
padding
[
0
]
+
h_offset
*
dilation
[
0
];
int
im_row_idx
=
h
*
stride
[
0
]
-
padding
[
0
]
+
for
(
int
w
=
0
;
w
<
col_width
;
++
w
)
{
h_offset
*
dilation
[
0
];
int
im_col_idx
=
w
*
stride
[
1
]
-
padding
[
1
]
+
w_offset
*
dilation
[
1
];
for
(
int
w
=
0
;
w
<
col_width
;
++
w
)
{
int
col_idx
=
(
c
*
col_height
+
h
)
*
col_width
+
w
;
int
im_col_idx
=
w
*
stride
[
1
]
-
padding
[
1
]
+
int
im_idx
=
(
im_row_idx
+
c_im
*
im_height
)
*
im_width
+
im_col_idx
;
w_offset
*
dilation
[
1
];
int
col_idx
=
(
c
*
col_height
+
h
)
*
col_width
+
w
;
int
im_idx
=
(
im_row_idx
+
c_im
*
im_height
)
*
im_width
+
im_col_idx
;
col_data
[
col_idx
]
=
(
im_row_idx
<
0
||
im_row_idx
>=
im_height
||
col_data
[
col_idx
]
=
im_col_idx
<
0
||
im_col_idx
>=
im_width
)
(
im_row_idx
<
0
||
?
static_cast
<
T
>
(
0
)
im_row_idx
>=
im_height
||
:
im_data
[
im_idx
];
im_col_idx
<
0
||
im_col_idx
>=
im_width
)
}
?
static_cast
<
T
>
(
0
)
}
:
im_data
[
im_idx
];
}
}
}
}
};
}
}
};
/*
/*
* im = [input_channels, input_height, input_width]
* im = [input_channels, input_height, input_width]
* col =
* col =
* [input_channels, filter_height, filter_width, output_height, output_width]
* [input_channels, filter_height, filter_width, output_height,
*/
* output_width]
template
<
class
T
>
class
Col2ImFunctor
<
ColFormat
::
kCFO
,
CPU
,
T
>
{
*/
public:
template
<
class
T
>
class
Col2ImFunctor
<
ColFormat
::
kCFO
,
CPU
,
T
>
{
void
operator
()(
const
framework
::
Tensor
&
col
,
public:
const
std
::
vector
<
int
>
&
dilation
,
void
operator
()(
const
framework
::
Tensor
&
col
,
const
std
::
vector
<
int
>
&
stride
,
const
std
::
vector
<
int
>
&
dilation
,
const
std
::
vector
<
int
>
&
padding
,
framework
::
Tensor
*
im
)
{
const
std
::
vector
<
int
>
&
stride
,
// PADDLE_ENFORCE(im->dims().size() == 3);
const
std
::
vector
<
int
>
&
padding
,
// PADDLE_ENFORCE(col.dims().size() == 5);
framework
::
Tensor
*
im
)
{
int
im_channels
=
im
->
dims
()[
0
];
// PADDLE_ENFORCE(im->dims().size() == 3);
int
im_height
=
im
->
dims
()[
1
];
// PADDLE_ENFORCE(col.dims().size() == 5);
int
im_width
=
im
->
dims
()[
2
];
int
im_channels
=
im
->
dims
()[
0
];
int
filter_height
=
col
.
dims
()[
1
];
int
im_height
=
im
->
dims
()[
1
];
int
filter_width
=
col
.
dims
()[
2
];
int
im_width
=
im
->
dims
()[
2
];
int
col_height
=
col
.
dims
()[
3
];
int
filter_height
=
col
.
dims
()[
1
];
int
col_width
=
col
.
dims
()[
4
];
int
filter_width
=
col
.
dims
()[
2
];
int
col_height
=
col
.
dims
()[
3
];
int
col_width
=
col
.
dims
()[
4
];
// PADDLE_ENFORCE_EQ((im_height + padding[0] + padding[2] -
// PADDLE_ENFORCE_EQ((im_height + padding[0] + padding[2]
// ((dilation[0] * (filter_height - 1) + 1))) /
// -
// stride[0] +
// ((dilation[0] * (filter_height - 1)
// 1,
// + 1))) /
// col_height,
// stride[0] +
// "Output_height and padding(padding_up, padding_down)
// 1,
// are " "inconsistent.");
// col_height,
// PADDLE_ENFORCE_EQ((im_width + padding[1] + padding[3] -
// "Output_height and
// ((dilation[1] * (filter_width - 1) + 1))) /
// padding(padding_up, padding_down)
// stride[1] +
// are " "inconsistent.");
// 1,
// PADDLE_ENFORCE_EQ((im_width + padding[1] + padding[3]
// col_width,
// -
// "Output_height and padding(padding_up, padding_down)
// ((dilation[1] * (filter_width - 1)
// are " "inconsistent.");
// + 1))) /
// stride[1] +
// 1,
// col_width,
// "Output_height and
// padding(padding_up, padding_down)
// are " "inconsistent.");
int
channels_col
=
im_channels
*
filter_height
*
filter_width
;
int
channels_col
=
im_channels
*
filter_height
*
filter_width
;
T
*
im_data
=
im
->
data
<
T
>
();
T
*
im_data
=
im
->
data
<
T
>
();
const
T
*
col_data
=
col
.
data
<
T
>
();
const
T
*
col_data
=
col
.
data
<
T
>
();
for
(
int
c
=
0
;
c
<
channels_col
;
++
c
)
{
for
(
int
c
=
0
;
c
<
channels_col
;
++
c
)
{
int
w_offset
=
c
%
filter_width
;
int
w_offset
=
c
%
filter_width
;
int
h_offset
=
(
c
/
filter_width
)
%
filter_height
;
int
h_offset
=
(
c
/
filter_width
)
%
filter_height
;
int
c_im
=
c
/
(
filter_width
*
filter_height
);
int
c_im
=
c
/
(
filter_width
*
filter_height
);
for
(
int
h
=
0
;
h
<
col_height
;
++
h
)
{
for
(
int
h
=
0
;
h
<
col_height
;
++
h
)
{
int
im_row_idx
=
h
*
stride
[
0
]
-
padding
[
0
]
+
h_offset
*
dilation
[
0
];
int
im_row_idx
=
h
*
stride
[
0
]
-
padding
[
0
]
+
for
(
int
w
=
0
;
w
<
col_width
;
++
w
)
{
h_offset
*
dilation
[
0
];
int
im_col_idx
=
w
*
stride
[
1
]
-
padding
[
1
]
+
w_offset
*
dilation
[
1
];
for
(
int
w
=
0
;
w
<
col_width
;
++
w
)
{
if
((
im_row_idx
)
>=
0
&&
(
im_row_idx
)
<
im_height
&&
int
im_col_idx
=
w
*
stride
[
1
]
-
padding
[
1
]
+
(
im_col_idx
)
>=
0
&&
(
im_col_idx
)
<
im_width
)
{
w_offset
*
dilation
[
1
];
im_data
[(
im_row_idx
+
c_im
*
im_height
)
*
im_width
+
im_col_idx
]
+=
if
((
im_row_idx
)
>=
0
&&
col_data
[(
c
*
col_height
+
h
)
*
col_width
+
w
];
(
im_row_idx
)
<
im_height
&&
}
(
im_col_idx
)
>=
0
&&
}
(
im_col_idx
)
<
im_width
)
{
}
im_data
[(
im_row_idx
+
c_im
*
im_height
)
*
}
im_width
+
}
im_col_idx
]
+=
};
col_data
[(
c
*
col_height
+
h
)
*
col_width
+
w
];
}
}
}
}
}
};
template
class
Im2ColFunctor
<
ColFormat
::
kCFO
,
CPU
,
float
>;
template
class
Im2ColFunctor
<
ColFormat
::
kCFO
,
CPU
,
float
>;
template
class
Im2ColFunctor
<
ColFormat
::
kCFO
,
CPU
,
double
>;
template
class
Im2ColFunctor
<
ColFormat
::
kCFO
,
CPU
,
double
>;
template
class
Col2ImFunctor
<
ColFormat
::
kCFO
,
CPU
,
float
>;
template
class
Col2ImFunctor
<
ColFormat
::
kCFO
,
CPU
,
float
>;
template
class
Col2ImFunctor
<
ColFormat
::
kCFO
,
CPU
,
double
>;
template
class
Col2ImFunctor
<
ColFormat
::
kCFO
,
CPU
,
double
>;
/*
/*
* im = [input_channels, input_height, input_width]
* im = [input_channels, input_height, input_width]
* col =
* col =
* [output_height, output_width, input_channels, filter_height, filter_width]
* [output_height, output_width, input_channels, filter_height,
*/
* filter_width]
template
<
class
T
>
class
Im2ColFunctor
<
ColFormat
::
kOCF
,
CPU
,
T
>
{
*/
public:
template
<
class
T
>
class
Im2ColFunctor
<
ColFormat
::
kOCF
,
CPU
,
T
>
{
void
operator
()(
const
framework
::
Tensor
&
im
,
const
std
::
vector
<
int
>
&
dilation
,
public:
const
std
::
vector
<
int
>
&
stride
,
void
operator
()(
const
framework
::
Tensor
&
im
,
const
std
::
vector
<
int
>
&
padding
,
framework
::
Tensor
*
col
)
{
const
std
::
vector
<
int
>
&
dilation
,
// PADDLE_ENFORCE(im.dims().size() == 3);
const
std
::
vector
<
int
>
&
stride
,
// PADDLE_ENFORCE(col->dims().size() == 5);
const
std
::
vector
<
int
>
&
padding
,
int
im_channels
=
im
.
dims
()[
0
];
framework
::
Tensor
*
col
)
{
int
im_height
=
im
.
dims
()[
1
];
// PADDLE_ENFORCE(im.dims().size() == 3);
int
im_width
=
im
.
dims
()[
2
];
// PADDLE_ENFORCE(col->dims().size() == 5);
int
filter_height
=
col
->
dims
()[
3
];
int
im_channels
=
im
.
dims
()[
0
];
int
filter_width
=
col
->
dims
()[
4
];
int
im_height
=
im
.
dims
()[
1
];
int
col_height
=
col
->
dims
()[
0
];
int
im_width
=
im
.
dims
()[
2
];
int
col_width
=
col
->
dims
()[
1
];
int
filter_height
=
col
->
dims
()[
3
];
int
filter_width
=
col
->
dims
()[
4
];
int
col_height
=
col
->
dims
()[
0
];
int
col_width
=
col
->
dims
()[
1
];
// PADDLE_ENFORCE_EQ(
// PADDLE_ENFORCE_EQ(
// (im_height + padding[0] + padding[2] - filter_height) / stride[0]
// (im_height + padding[0] + padding[2] -
// + 1, col_height, "Output_height and padding(padding_up,
// filter_height) / stride[0]
// padding_down) are " "inconsistent.");
// + 1, col_height, "Output_height and
// PADDLE_ENFORCE_EQ(
// padding(padding_up,
// (im_width + padding[1] + padding[3] - filter_width) / stride[1] +
// padding_down) are " "inconsistent.");
// 1, col_width, "col_width and padding(padding_left, padding_right)
// PADDLE_ENFORCE_EQ(
// are " "inconsistent.");
// (im_width + padding[1] + padding[3] -
// filter_width) / stride[1] +
// 1, col_width, "col_width and padding(padding_left,
// padding_right)
// are " "inconsistent.");
const
T
*
im_data
=
im
.
data
<
T
>
();
const
T
*
im_data
=
im
.
data
<
T
>
();
T
*
col_data
=
col
->
data
<
T
>
();
T
*
col_data
=
col
->
data
<
T
>
();
for
(
int
col_row_idx
=
0
;
col_row_idx
<
col_height
;
++
col_row_idx
)
{
for
(
int
col_row_idx
=
0
;
col_row_idx
<
col_height
;
for
(
int
col_col_idx
=
0
;
col_col_idx
<
col_width
;
++
col_col_idx
)
{
++
col_row_idx
)
{
for
(
int
channel
=
0
;
channel
<
im_channels
;
++
channel
)
{
for
(
int
col_col_idx
=
0
;
col_col_idx
<
col_width
;
for
(
int
filter_row_idx
=
0
;
filter_row_idx
<
filter_height
;
++
col_col_idx
)
{
++
filter_row_idx
)
{
for
(
int
channel
=
0
;
channel
<
im_channels
;
int
im_row_offset
=
++
channel
)
{
col_row_idx
*
stride
[
0
]
+
filter_row_idx
-
padding
[
0
];
for
(
int
filter_row_idx
=
0
;
for
(
int
filter_col_idx
=
0
;
filter_col_idx
<
filter_width
;
filter_row_idx
<
filter_height
;
++
filter_col_idx
)
{
++
filter_row_idx
)
{
int
im_col_offset
=
int
im_row_offset
=
col_col_idx
*
stride
[
1
]
+
filter_col_idx
-
padding
[
1
];
col_row_idx
*
stride
[
0
]
+
filter_row_idx
-
padding
[
0
];
for
(
int
filter_col_idx
=
0
;
filter_col_idx
<
filter_width
;
++
filter_col_idx
)
{
int
im_col_offset
=
col_col_idx
*
stride
[
1
]
+
filter_col_idx
-
padding
[
1
];
int
col_offset
=
int
col_offset
=
((((
col_row_idx
)
*
col_width
+
col_col_idx
)
*
im_channels
+
((((
col_row_idx
)
*
col_width
+
channel
)
*
col_col_idx
)
*
filter_height
+
im_channels
+
filter_row_idx
)
*
channel
)
*
filter_width
+
filter_height
+
filter_col_idx
;
filter_row_idx
)
*
filter_width
+
filter_col_idx
;
int
im_offset
=
(
channel
*
im_height
+
im_row_offset
)
*
im_width
+
int
im_offset
=
(
channel
*
im_height
+
im_col_offset
;
im_row_offset
)
*
col_data
[
col_offset
]
=
im_width
+
(
im_row_offset
<
0
||
im_row_offset
>=
im_height
||
im_col_offset
;
im_col_offset
<
0
||
im_col_offset
>=
im_width
)
col_data
[
col_offset
]
=
?
static_cast
<
T
>
(
0
)
(
im_row_offset
<
0
||
:
im_data
[
im_offset
];
im_row_offset
>=
im_height
||
}
im_col_offset
<
0
||
}
im_col_offset
>=
im_width
)
}
?
static_cast
<
T
>
(
0
)
}
:
im_data
[
im_offset
];
}
}
}
}
};
}
}
}
}
};
/*
/*
* im = [input_channels, input_height, input_width]
* im = [input_channels, input_height, input_width]
* col =
* col =
* [output_height, output_width, input_channels, filter_height, filter_width]
* [output_height, output_width, input_channels, filter_height,
*/
* filter_width]
template
<
class
T
>
class
Col2ImFunctor
<
ColFormat
::
kOCF
,
CPU
,
T
>
{
*/
public:
template
<
class
T
>
class
Col2ImFunctor
<
ColFormat
::
kOCF
,
CPU
,
T
>
{
void
operator
()(
const
framework
::
Tensor
&
col
,
public:
const
std
::
vector
<
int
>
&
dilation
,
void
operator
()(
const
framework
::
Tensor
&
col
,
const
std
::
vector
<
int
>
&
stride
,
const
std
::
vector
<
int
>
&
dilation
,
const
std
::
vector
<
int
>
&
padding
,
framework
::
Tensor
*
im
)
{
const
std
::
vector
<
int
>
&
stride
,
// PADDLE_ENFORCE(im->dims().size() == 3);
const
std
::
vector
<
int
>
&
padding
,
// PADDLE_ENFORCE(col.dims().size() == 5);
framework
::
Tensor
*
im
)
{
int
im_channels
=
im
->
dims
()[
0
];
// PADDLE_ENFORCE(im->dims().size() == 3);
int
im_height
=
im
->
dims
()[
1
];
// PADDLE_ENFORCE(col.dims().size() == 5);
int
im_width
=
im
->
dims
()[
2
];
int
im_channels
=
im
->
dims
()[
0
];
int
filter_height
=
col
.
dims
()[
3
];
int
im_height
=
im
->
dims
()[
1
];
int
filter_width
=
col
.
dims
()[
4
];
int
im_width
=
im
->
dims
()[
2
];
int
col_height
=
col
.
dims
()[
0
];
int
filter_height
=
col
.
dims
()[
3
];
int
col_width
=
col
.
dims
()[
1
];
int
filter_width
=
col
.
dims
()[
4
];
int
col_height
=
col
.
dims
()[
0
];
int
col_width
=
col
.
dims
()[
1
];
// PADDLE_ENFORCE_EQ(
// PADDLE_ENFORCE_EQ(
// (im_height + padding[0] + padding[2] - filter_height) / stride[0]
// (im_height + padding[0] + padding[2] -
// + 1, col_height, "Output_height and padding(padding_up,
// filter_height) / stride[0]
// padding_down) are " "inconsistent.");
// + 1, col_height, "Output_height and
// PADDLE_ENFORCE_EQ(
// padding(padding_up,
// (im_width + padding[1] + padding[3] - filter_width) / stride[1] +
// padding_down) are " "inconsistent.");
// 1, col_width, "col_width and padding(padding_left, padding_right)
// PADDLE_ENFORCE_EQ(
// are " "inconsistent.");
// (im_width + padding[1] + padding[3] -
// filter_width) / stride[1] +
// 1, col_width, "col_width and padding(padding_left,
// padding_right)
// are " "inconsistent.");
T
*
im_data
=
im
->
data
<
T
>
();
T
*
im_data
=
im
->
data
<
T
>
();
const
T
*
col_data
=
col
.
data
<
T
>
();
const
T
*
col_data
=
col
.
data
<
T
>
();
for
(
int
col_row_idx
=
0
;
col_row_idx
<
col_height
;
++
col_row_idx
)
{
for
(
int
col_row_idx
=
0
;
col_row_idx
<
col_height
;
for
(
int
col_col_idx
=
0
;
col_col_idx
<
col_width
;
++
col_col_idx
)
{
++
col_row_idx
)
{
for
(
int
channel
=
0
;
channel
<
im_channels
;
++
channel
)
{
for
(
int
col_col_idx
=
0
;
col_col_idx
<
col_width
;
for
(
int
filter_row_idx
=
0
;
filter_row_idx
<
filter_height
;
++
col_col_idx
)
{
++
filter_row_idx
)
{
for
(
int
channel
=
0
;
channel
<
im_channels
;
int
im_row_offset
=
++
channel
)
{
col_row_idx
*
stride
[
0
]
+
filter_row_idx
-
padding
[
0
];
for
(
int
filter_row_idx
=
0
;
for
(
int
filter_col_idx
=
0
;
filter_col_idx
<
filter_width
;
filter_row_idx
<
filter_height
;
++
filter_col_idx
)
{
++
filter_row_idx
)
{
int
im_col_offset
=
int
im_row_offset
=
col_col_idx
*
stride
[
1
]
+
filter_col_idx
-
padding
[
1
];
col_row_idx
*
stride
[
0
]
+
filter_row_idx
-
padding
[
0
];
for
(
int
filter_col_idx
=
0
;
filter_col_idx
<
filter_width
;
++
filter_col_idx
)
{
int
im_col_offset
=
col_col_idx
*
stride
[
1
]
+
filter_col_idx
-
padding
[
1
];
int
col_offset
=
int
col_offset
=
(((
col_row_idx
*
col_width
+
col_col_idx
)
*
im_channels
+
(((
col_row_idx
*
col_width
+
channel
)
*
col_col_idx
)
*
filter_height
+
im_channels
+
filter_row_idx
)
*
channel
)
*
filter_width
+
filter_height
+
filter_col_idx
;
filter_row_idx
)
*
filter_width
+
filter_col_idx
;
if
(
im_row_offset
>=
0
&&
im_row_offset
<
im_height
&&
if
(
im_row_offset
>=
0
&&
im_col_offset
>=
0
&&
im_col_offset
<
im_width
)
{
im_row_offset
<
im_height
&&
int
im_offset
=
im_col_offset
>=
0
&&
(
channel
*
im_height
+
im_row_offset
)
*
im_width
+
im_col_offset
<
im_width
)
{
im_col_offset
;
int
im_offset
=
im_data
[
im_offset
]
+=
col_data
[
col_offset
];
(
channel
*
im_height
+
}
im_row_offset
)
*
}
im_width
+
}
im_col_offset
;
}
im_data
[
im_offset
]
+=
}
col_data
[
col_offset
];
}
}
}
}
};
}
}
}
}
}
};
template
class
Im2ColFunctor
<
ColFormat
::
kOCF
,
CPU
,
float
>;
template
class
Im2ColFunctor
<
ColFormat
::
kOCF
,
CPU
,
float
>;
template
class
Im2ColFunctor
<
ColFormat
::
kOCF
,
CPU
,
double
>;
template
class
Im2ColFunctor
<
ColFormat
::
kOCF
,
CPU
,
double
>;
template
class
Col2ImFunctor
<
ColFormat
::
kOCF
,
CPU
,
float
>;
template
class
Col2ImFunctor
<
ColFormat
::
kOCF
,
CPU
,
float
>;
template
class
Col2ImFunctor
<
ColFormat
::
kOCF
,
CPU
,
double
>;
template
class
Col2ImFunctor
<
ColFormat
::
kOCF
,
CPU
,
double
>;
}
// namespace math
}
// namespace math
}
// namespace operators
}
// namespace operators
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/operators/math/im2col.h
浏览文件 @
aef98218
...
@@ -17,83 +17,96 @@ limitations under the License. */
...
@@ -17,83 +17,96 @@ limitations under the License. */
#include "framework/tensor.h"
#include "framework/tensor.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
operators
{
namespace
operators
{
namespace
math
{
namespace
math
{
/* The storage format of the coldata in the Im2ColFunctor and Col2ImFunctor. */
/* The storage format of the coldata in the Im2ColFunctor and
enum
class
ColFormat
{
kCFO
=
0
,
kOCF
=
1
};
* Col2ImFunctor. */
enum
class
ColFormat
{
kCFO
=
0
,
kOCF
=
1
};
/*
/*
* \brief Converts the image data of three dimensions(CHW) into a colData of
* \brief Converts the image data of three dimensions(CHW) into a
* five dimensions in the Im2ColFunctor calculation,
* colData of
* And in the Col2ImFunctor calculation, it is reversed.
* five dimensions in the Im2ColFunctor calculation,
*
* And in the Col2ImFunctor calculation, it is reversed.
* \param imData Image data.
*
* \param imShape The shape of imData,
* \param imData Image data.
* [input_channels, input_height, input_width].
* \param imShape The shape of imData,
* \param colData Column data.
* [input_channels, input_height, input_width].
* \param colShape The shape of colData.
* \param colData Column data.
*
* \param colShape The shape of colData.
* \param dilations dilation data.
*
* \param 2-dimension [dilation_height, dilation_width].
* \param dilations dilation data.
*
* \param 2-dimension [dilation_height, dilation_width].
* \param strides stride data.
*
* \param 2-dimension [stride_height, stride_width].
* \param strides stride data.
*
* \param 2-dimension [stride_height, stride_width].
* \param paddings padding data.
*
* \param 4-dimension [up_pad, left_pad, down_pad, right_pad].
* \param paddings padding data.
*
* \param 4-dimension [up_pad, left_pad, down_pad, right_pad].
* If the template argument Format is kCFO, the shape of colData is:
*
* [input_channels, filter_height, filter_width, output_height, output_width]
* If the template argument Format is kCFO, the shape of colData is:
* So, it is easy to reshape into a convolution matrix for convolution
* [input_channels, filter_height, filter_width, output_height,
* calculation based on matrix multiplication.
* output_width]
* The shape of convolution matrix is [height, width], where the height is equal
* So, it is easy to reshape into a convolution matrix for
* input_channels * filter_height * filter_width, and the width is equal
* convolution
* output_height * output_width.
* calculation based on matrix multiplication.
*
* The shape of convolution matrix is [height, width], where the
* Reshape:
* height is equal
* shape of colData shape of convolution matrix
* input_channels * filter_height * filter_width, and the width is
* [input_channels,
* equal
* filter_height,
* output_height * output_width.
* filter_width, ======> [height, width]
*
* output_height,
* Reshape:
* output_width]
* shape of colData shape of convolution matrix
*
* [input_channels,
* If the template argument Format is kOCF, the shape of colData is:
* filter_height,
* [output_height, output_width, input_channels, filter_height, filter_width]
* filter_width, ======> [height, width]
* So, it is easy to reshape into a sequence matrix for rnn calculation.
* output_height,
* The shape of sequence matrix is [seq_length, step_size], where the seq_length
* output_width]
* is equal output_height * output_width, and the step_size is equal
*
* input_channels * filter_height * filter_width.
* If the template argument Format is kOCF, the shape of colData is:
*
* [output_height, output_width, input_channels, filter_height,
* Reshape:
* filter_width]
* shape of colData shape of sequence matrix
* So, it is easy to reshape into a sequence matrix for rnn
* [output_height,
* calculation.
* output_width,
* The shape of sequence matrix is [seq_length, step_size], where
* input_channels, ======> [seqLength, stepSize]
* the seq_length
* filter_height,
* is equal output_height * output_width, and the step_size is equal
* filter_width]
* input_channels * filter_height * filter_width.
*
*
* \note The caller needs to ensure that imShape.inputChannels is equal to
* Reshape:
* colShape.inputChannels.
* shape of colData shape of sequence matrix
*/
* [output_height,
template
<
ColFormat
Format
,
typename
DeviceType
,
typename
T
>
* output_width,
class
Im2ColFunctor
{
* input_channels, ======> [seqLength, stepSize]
public:
* filter_height,
void
operator
()(
const
framework
::
Tensor
&
im
,
const
std
::
vector
<
int
>
&
dilation
,
* filter_width]
const
std
::
vector
<
int
>
&
stride
,
*
const
std
::
vector
<
int
>
&
padding
,
framework
::
Tensor
*
col
);
* \note The caller needs to ensure that imShape.inputChannels is
};
* equal to
* colShape.inputChannels.
*/
template
<
ColFormat
Format
,
typename
DeviceType
,
typename
T
>
class
Im2ColFunctor
{
public:
void
operator
()(
const
framework
::
Tensor
&
im
,
const
std
::
vector
<
int
>
&
dilation
,
const
std
::
vector
<
int
>
&
stride
,
const
std
::
vector
<
int
>
&
padding
,
framework
::
Tensor
*
col
);
};
template
<
ColFormat
Format
,
typename
DeviceType
,
typename
T
>
template
<
ColFormat
Format
,
typename
DeviceType
,
typename
T
>
class
Col2ImFunctor
{
class
Col2ImFunctor
{
public:
public:
void
operator
()(
const
framework
::
Tensor
&
col
,
void
operator
()(
const
framework
::
Tensor
&
col
,
const
std
::
vector
<
int
>
&
dilation
,
const
std
::
vector
<
int
>
&
dilation
,
const
std
::
vector
<
int
>
&
stride
,
const
std
::
vector
<
int
>
&
stride
,
const
std
::
vector
<
int
>
&
padding
,
framework
::
Tensor
*
im
);
const
std
::
vector
<
int
>
&
padding
,
};
framework
::
Tensor
*
im
);
};
}
// namespace math
}
// namespace math
}
// namespace operators
}
// namespace operators
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/operators/math/math_function.cc
浏览文件 @
aef98218
...
@@ -15,106 +15,125 @@ limitations under the License. */
...
@@ -15,106 +15,125 @@ limitations under the License. */
#include "math_function.h"
#include "math_function.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
operators
{
namespace
operators
{
namespace
math
{
namespace
math
{
template
<
>
template
<
>
void
gemm
<
float
>
(
const
CBLAS_TRANSPOSE
transA
,
const
CBLAS_TRANSPOSE
transB
,
void
gemm
<
float
>
(
const
CBLAS_TRANSPOSE
transA
,
const
int
M
,
const
int
N
,
const
int
K
,
const
float
alpha
,
const
CBLAS_TRANSPOSE
transB
,
const
int
M
,
const
float
*
A
,
const
float
*
B
,
const
float
beta
,
float
*
C
)
{
const
int
N
,
const
int
K
,
const
float
alpha
,
int
lda
=
(
transA
==
CblasNoTrans
)
?
K
:
M
;
const
float
*
A
,
const
float
*
B
,
const
float
beta
,
int
ldb
=
(
transB
==
CblasNoTrans
)
?
N
:
K
;
float
*
C
)
{
int
ldc
=
N
;
int
lda
=
(
transA
==
CblasNoTrans
)
?
K
:
M
;
cblas_sgemm
(
CblasRowMajor
,
transA
,
transB
,
M
,
N
,
K
,
alpha
,
A
,
lda
,
B
,
ldb
,
int
ldb
=
(
transB
==
CblasNoTrans
)
?
N
:
K
;
beta
,
C
,
ldc
);
int
ldc
=
N
;
}
cblas_sgemm
(
CblasRowMajor
,
transA
,
transB
,
M
,
N
,
K
,
alpha
,
A
,
lda
,
B
,
ldb
,
beta
,
C
,
ldc
);
template
<
>
}
void
gemm
<
double
>
(
const
CBLAS_TRANSPOSE
transA
,
const
CBLAS_TRANSPOSE
transB
,
const
int
M
,
const
int
N
,
const
int
K
,
const
double
alpha
,
template
<
>
const
double
*
A
,
const
double
*
B
,
const
double
beta
,
void
gemm
<
double
>
(
const
CBLAS_TRANSPOSE
transA
,
double
*
C
)
{
const
CBLAS_TRANSPOSE
transB
,
const
int
M
,
int
lda
=
(
transA
==
CblasNoTrans
)
?
K
:
M
;
const
int
N
,
const
int
K
,
const
double
alpha
,
int
ldb
=
(
transB
==
CblasNoTrans
)
?
N
:
K
;
const
double
*
A
,
const
double
*
B
,
int
ldc
=
N
;
const
double
beta
,
double
*
C
)
{
cblas_dgemm
(
CblasRowMajor
,
transA
,
transB
,
M
,
N
,
K
,
alpha
,
A
,
lda
,
B
,
ldb
,
int
lda
=
(
transA
==
CblasNoTrans
)
?
K
:
M
;
beta
,
C
,
ldc
);
int
ldb
=
(
transB
==
CblasNoTrans
)
?
N
:
K
;
}
int
ldc
=
N
;
cblas_dgemm
(
CblasRowMajor
,
transA
,
transB
,
M
,
N
,
K
,
alpha
,
A
,
template
<
>
lda
,
B
,
ldb
,
beta
,
C
,
ldc
);
void
gemm
<
float
>
(
const
bool
transA
,
const
bool
transB
,
const
int
M
,
const
int
N
,
}
const
int
K
,
const
float
alpha
,
const
float
*
A
,
const
int
lda
,
const
float
*
B
,
const
int
ldb
,
const
float
beta
,
float
*
C
,
template
<
>
const
int
ldc
)
{
void
gemm
<
float
>
(
const
bool
transA
,
const
bool
transB
,
const
int
M
,
cblas_sgemm
(
CblasRowMajor
,
transA
==
false
?
CblasNoTrans
:
CblasTrans
,
const
int
N
,
const
int
K
,
const
float
alpha
,
transB
==
false
?
CblasNoTrans
:
CblasTrans
,
M
,
N
,
K
,
alpha
,
A
,
const
float
*
A
,
const
int
lda
,
const
float
*
B
,
lda
,
B
,
ldb
,
beta
,
C
,
ldc
);
const
int
ldb
,
const
float
beta
,
float
*
C
,
}
const
int
ldc
)
{
cblas_sgemm
(
CblasRowMajor
,
template
<
>
transA
==
false
?
CblasNoTrans
:
CblasTrans
,
void
gemm
<
double
>
(
const
bool
transA
,
const
bool
transB
,
const
int
M
,
transB
==
false
?
CblasNoTrans
:
CblasTrans
,
M
,
N
,
const
int
N
,
const
int
K
,
const
double
alpha
,
const
double
*
A
,
K
,
alpha
,
A
,
lda
,
B
,
ldb
,
beta
,
C
,
ldc
);
const
int
lda
,
const
double
*
B
,
const
int
ldb
,
}
const
double
beta
,
double
*
C
,
const
int
ldc
)
{
cblas_dgemm
(
CblasRowMajor
,
transA
==
false
?
CblasNoTrans
:
CblasTrans
,
template
<
>
transB
==
false
?
CblasNoTrans
:
CblasTrans
,
M
,
N
,
K
,
alpha
,
A
,
void
gemm
<
double
>
(
const
bool
transA
,
const
bool
transB
,
const
int
M
,
lda
,
B
,
ldb
,
beta
,
C
,
ldc
);
const
int
N
,
const
int
K
,
const
double
alpha
,
}
const
double
*
A
,
const
int
lda
,
const
double
*
B
,
const
int
ldb
,
const
double
beta
,
double
*
C
,
template
<
>
const
int
ldc
)
{
void
matmul
<
float
>
(
const
framework
::
Tensor
&
matrix_a
,
bool
trans_a
,
cblas_dgemm
(
CblasRowMajor
,
const
framework
::
Tensor
&
matrix_b
,
bool
trans_b
,
float
alpha
,
transA
==
false
?
CblasNoTrans
:
CblasTrans
,
framework
::
Tensor
*
matrix_out
,
float
beta
)
{
transB
==
false
?
CblasNoTrans
:
CblasTrans
,
M
,
N
,
auto
dim_a
=
matrix_a
.
dims
();
K
,
alpha
,
A
,
lda
,
B
,
ldb
,
beta
,
C
,
ldc
);
auto
dim_b
=
matrix_b
.
dims
();
}
auto
dim_out
=
matrix_out
->
dims
();
// PADDLE_ENFORCE(dim_a.size() == 2 && dim_b.size() == 2 && dim_out.size() ==
template
<
>
// 2,
void
matmul
<
float
>
(
const
framework
::
Tensor
&
matrix_a
,
bool
trans_a
,
// "The input and output of matmul be matrix");
const
framework
::
Tensor
&
matrix_b
,
bool
trans_b
,
//
float
alpha
,
framework
::
Tensor
*
matrix_out
,
// PADDLE_ENFORCE(platform::is_cpu_place(matrix_a.place()) &&
float
beta
)
{
// platform::is_cpu_place(matrix_b.place()) &&
auto
dim_a
=
matrix_a
.
dims
();
// platform::is_cpu_place(matrix_out->place()),
auto
dim_b
=
matrix_b
.
dims
();
// "Matrix must all be in CPUPlace");
auto
dim_out
=
matrix_out
->
dims
();
// PADDLE_ENFORCE(dim_a.size() == 2 && dim_b.size() == 2 &&
int
M
=
dim_out
[
0
];
// dim_out.size() ==
int
N
=
dim_out
[
1
];
// 2,
int
K
=
(
trans_a
==
false
)
?
dim_a
[
1
]
:
dim_a
[
0
];
// "The input and output of matmul be matrix");
//
CBLAS_TRANSPOSE
transA
=
(
trans_a
==
false
)
?
CblasNoTrans
:
CblasTrans
;
// PADDLE_ENFORCE(platform::is_cpu_place(matrix_a.place()) &&
CBLAS_TRANSPOSE
transB
=
(
trans_b
==
false
)
?
CblasNoTrans
:
CblasTrans
;
// platform::is_cpu_place(matrix_b.place())
// &&
gemm
<
float
>
(
transA
,
transB
,
M
,
N
,
K
,
alpha
,
matrix_a
.
data
<
float
>
(),
// platform::is_cpu_place(matrix_out->place()),
matrix_b
.
data
<
float
>
(),
beta
,
matrix_out
->
data
<
float
>
());
// "Matrix must all be in CPUPlace");
}
int
M
=
dim_out
[
0
];
template
<
>
int
N
=
dim_out
[
1
];
void
matmul
<
double
>
(
const
framework
::
Tensor
&
matrix_a
,
bool
trans_a
,
int
K
=
(
trans_a
==
false
)
?
dim_a
[
1
]
:
dim_a
[
0
];
const
framework
::
Tensor
&
matrix_b
,
bool
trans_b
,
double
alpha
,
framework
::
Tensor
*
matrix_out
,
double
beta
)
{
CBLAS_TRANSPOSE
transA
=
auto
dim_a
=
matrix_a
.
dims
();
(
trans_a
==
false
)
?
CblasNoTrans
:
CblasTrans
;
auto
dim_b
=
matrix_b
.
dims
();
CBLAS_TRANSPOSE
transB
=
auto
dim_out
=
matrix_out
->
dims
();
(
trans_b
==
false
)
?
CblasNoTrans
:
CblasTrans
;
// PADDLE_ENFORCE(dim_a.size() == 2 && dim_b.size() == 2 && dim_out.size() ==
// 2,
gemm
<
float
>
(
transA
,
transB
,
M
,
N
,
K
,
alpha
,
// "The input and output of matmul be matrix");
matrix_a
.
data
<
float
>
(),
matrix_b
.
data
<
float
>
(),
//
beta
,
matrix_out
->
data
<
float
>
());
// PADDLE_ENFORCE(platform::is_cpu_place(matrix_a.place()) &&
}
// platform::is_cpu_place(matrix_b.place()) &&
// platform::is_cpu_place(matrix_out->place()),
template
<
>
// "Matrix must all be in CPUPlace");
void
matmul
<
double
>
(
const
framework
::
Tensor
&
matrix_a
,
bool
trans_a
,
const
framework
::
Tensor
&
matrix_b
,
bool
trans_b
,
int
M
=
dim_out
[
0
];
double
alpha
,
framework
::
Tensor
*
matrix_out
,
int
N
=
dim_out
[
1
];
double
beta
)
{
int
K
=
(
trans_a
==
false
)
?
dim_a
[
1
]
:
dim_a
[
0
];
auto
dim_a
=
matrix_a
.
dims
();
auto
dim_b
=
matrix_b
.
dims
();
CBLAS_TRANSPOSE
transA
=
(
trans_a
==
false
)
?
CblasNoTrans
:
CblasTrans
;
auto
dim_out
=
matrix_out
->
dims
();
CBLAS_TRANSPOSE
transB
=
(
trans_b
==
false
)
?
CblasNoTrans
:
CblasTrans
;
// PADDLE_ENFORCE(dim_a.size() == 2 && dim_b.size() == 2 &&
// dim_out.size() ==
gemm
<
double
>
(
transA
,
transB
,
M
,
N
,
K
,
alpha
,
matrix_a
.
data
<
double
>
(),
// 2,
matrix_b
.
data
<
double
>
(),
beta
,
matrix_out
->
data
<
double
>
());
// "The input and output of matmul be matrix");
}
//
// PADDLE_ENFORCE(platform::is_cpu_place(matrix_a.place()) &&
}
// namespace math
// platform::is_cpu_place(matrix_b.place())
}
// namespace operators
// &&
// platform::is_cpu_place(matrix_out->place()),
// "Matrix must all be in CPUPlace");
int
M
=
dim_out
[
0
];
int
N
=
dim_out
[
1
];
int
K
=
(
trans_a
==
false
)
?
dim_a
[
1
]
:
dim_a
[
0
];
CBLAS_TRANSPOSE
transA
=
(
trans_a
==
false
)
?
CblasNoTrans
:
CblasTrans
;
CBLAS_TRANSPOSE
transB
=
(
trans_b
==
false
)
?
CblasNoTrans
:
CblasTrans
;
gemm
<
double
>
(
transA
,
transB
,
M
,
N
,
K
,
alpha
,
matrix_a
.
data
<
double
>
(),
matrix_b
.
data
<
double
>
(),
beta
,
matrix_out
->
data
<
double
>
());
}
}
// namespace math
}
// namespace operators
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/operators/math/math_function.h
浏览文件 @
aef98218
...
@@ -19,24 +19,26 @@ limitations under the License. */
...
@@ -19,24 +19,26 @@ limitations under the License. */
#include <cmath>
#include <cmath>
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
operators
{
namespace
operators
{
namespace
math
{
namespace
math
{
template
<
typename
T
>
template
<
typename
T
>
void
gemm
(
const
CBLAS_TRANSPOSE
transA
,
const
CBLAS_TRANSPOSE
transB
,
void
gemm
(
const
CBLAS_TRANSPOSE
transA
,
const
int
M
,
const
int
N
,
const
int
K
,
const
T
alpha
,
const
T
*
A
,
const
CBLAS_TRANSPOSE
transB
,
const
int
M
,
const
int
N
,
const
T
*
B
,
const
T
beta
,
T
*
C
);
const
int
K
,
const
T
alpha
,
const
T
*
A
,
const
T
*
B
,
const
T
beta
,
T
*
C
);
template
<
typename
T
>
void
gemm
(
const
bool
transA
,
const
bool
transB
,
const
int
M
,
const
int
N
,
template
<
typename
T
>
const
int
K
,
const
T
alpha
,
const
T
*
A
,
const
int
lda
,
const
T
*
B
,
void
gemm
(
const
bool
transA
,
const
bool
transB
,
const
int
M
,
const
int
ldb
,
const
T
beta
,
T
*
C
,
const
int
ldc
);
const
int
N
,
const
int
K
,
const
T
alpha
,
const
T
*
A
,
const
int
lda
,
const
T
*
B
,
const
int
ldb
,
const
T
beta
,
// matrix multiply with continuous memory
T
*
C
,
const
int
ldc
);
template
<
typename
T
>
void
matmul
(
const
framework
::
Tensor
&
matrix_a
,
bool
trans_a
,
// matrix multiply with continuous memory
const
framework
::
Tensor
&
matrix_b
,
bool
trans_b
,
T
alpha
,
template
<
typename
T
>
framework
::
Tensor
*
matrix_out
,
T
beta
);
void
matmul
(
const
framework
::
Tensor
&
matrix_a
,
bool
trans_a
,
}
// namespace math
const
framework
::
Tensor
&
matrix_b
,
bool
trans_b
,
}
// namespace operators
T
alpha
,
framework
::
Tensor
*
matrix_out
,
T
beta
);
}
// namespace math
}
// namespace operators
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/operators/math/vol2col.cc
浏览文件 @
aef98218
...
@@ -15,179 +15,212 @@ limitations under the License. */
...
@@ -15,179 +15,212 @@ limitations under the License. */
#include "vol2col.h"
#include "vol2col.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
operators
{
namespace
operators
{
namespace
math
{
namespace
math
{
using
Tensor
=
paddle_mobile
::
framework
::
Tensor
;
using
Tensor
=
paddle_mobile
::
framework
::
Tensor
;
/*
/*
* vol = [input_channels, input_depth, input_height, input_width]
* vol = [input_channels, input_depth, input_height, input_width]
* col =
* col =
* [input_channels, filter_depth, filter_height, filter_width,
* [input_channels, filter_depth, filter_height, filter_width,
* output_depth, output_height, output_width]
* output_depth, output_height, output_width]
*/
*/
template
<
typename
T
>
class
Vol2ColFunctor
<
CPU
,
T
>
{
template
<
typename
T
>
class
Vol2ColFunctor
<
CPU
,
T
>
{
public:
public:
void
operator
()(
const
Tensor
&
vol
,
const
std
::
vector
<
int
>
&
dilations
,
void
operator
()(
const
Tensor
&
vol
,
const
std
::
vector
<
int
>
&
strides
,
const
std
::
vector
<
int
>
&
dilations
,
const
std
::
vector
<
int
>
&
paddings
,
Tensor
*
col
)
const
{
const
std
::
vector
<
int
>
&
strides
,
// PADDLE_ENFORCE(vol.dims().size() == 4);
const
std
::
vector
<
int
>
&
paddings
,
// PADDLE_ENFORCE(col->dims().size() == 7);
Tensor
*
col
)
const
{
// PADDLE_ENFORCE(vol.dims().size() == 4);
int
input_channels
=
vol
.
dims
()[
0
];
// PADDLE_ENFORCE(col->dims().size() == 7);
int
input_depth
=
vol
.
dims
()[
1
];
int
input_height
=
vol
.
dims
()[
2
];
int
input_channels
=
vol
.
dims
()[
0
];
int
input_width
=
vol
.
dims
()[
3
];
int
input_depth
=
vol
.
dims
()[
1
];
int
filter_depth
=
col
->
dims
()[
1
];
int
input_height
=
vol
.
dims
()[
2
];
int
filter_height
=
col
->
dims
()[
2
];
int
input_width
=
vol
.
dims
()[
3
];
int
filter_width
=
col
->
dims
()[
3
];
int
filter_depth
=
col
->
dims
()[
1
];
int
output_depth
=
col
->
dims
()[
4
];
int
filter_height
=
col
->
dims
()[
2
];
int
output_height
=
col
->
dims
()[
5
];
int
filter_width
=
col
->
dims
()[
3
];
int
output_width
=
col
->
dims
()[
6
];
int
output_depth
=
col
->
dims
()[
4
];
int
channels_col
=
int
output_height
=
col
->
dims
()[
5
];
input_channels
*
filter_depth
*
filter_height
*
filter_width
;
int
output_width
=
col
->
dims
()[
6
];
int
channels_col
=
input_channels
*
filter_depth
*
// PADDLE_ENFORCE_EQ((input_depth + 2 * paddings[0] -
filter_height
*
filter_width
;
// ((dilations[0] * (filter_depth - 1) + 1))) /
// strides[0] +
// PADDLE_ENFORCE_EQ((input_depth + 2 * paddings[0] -
// 1,
// ((dilations[0] * (filter_depth - 1)
// output_depth,
// + 1))) /
// "input_depth and output_depth are "
// strides[0] +
// "mismatching.");
// 1,
// PADDLE_ENFORCE_EQ((input_height + 2 * paddings[1] -
// output_depth,
// ((dilations[1] * (filter_height - 1) + 1))) /
// "input_depth and output_depth are "
// strides[1] +
// "mismatching.");
// 1,
// PADDLE_ENFORCE_EQ((input_height + 2 * paddings[1] -
// output_height,
// ((dilations[1] * (filter_height -
// "input_height and output_height are "
// 1) + 1))) /
// "mismatching.");
// strides[1] +
// PADDLE_ENFORCE_EQ((input_width + 2 * paddings[2] -
// 1,
// ((dilations[2] * (filter_width - 1) + 1))) /
// output_height,
// strides[2] +
// "input_height and output_height are
// 1,
// "
// output_width,
// "mismatching.");
// "input_width and output_width are "
// PADDLE_ENFORCE_EQ((input_width + 2 * paddings[2] -
// "mismatching.");
// ((dilations[2] * (filter_width - 1)
// + 1))) /
const
T
*
vol_data
=
vol
.
data
<
T
>
();
// strides[2] +
T
*
col_data
=
col
->
data
<
T
>
();
// 1,
// output_width,
for
(
int
c
=
0
;
c
<
channels_col
;
++
c
)
{
// "input_width and output_width are "
int
w_offset
=
c
%
filter_width
;
// "mismatching.");
int
h_offset
=
(
c
/
filter_width
)
%
filter_height
;
int
d_offset
=
(
c
/
filter_width
/
filter_height
)
%
filter_depth
;
const
T
*
vol_data
=
vol
.
data
<
T
>
();
int
c_in
=
c
/
filter_width
/
filter_height
/
filter_depth
;
T
*
col_data
=
col
->
data
<
T
>
();
for
(
int
d
=
0
;
d
<
output_depth
;
++
d
)
{
int
d_pad
=
d
*
strides
[
0
]
-
paddings
[
0
]
+
d_offset
*
dilations
[
0
];
for
(
int
c
=
0
;
c
<
channels_col
;
++
c
)
{
for
(
int
h
=
0
;
h
<
output_height
;
++
h
)
{
int
w_offset
=
c
%
filter_width
;
int
h_pad
=
h
*
strides
[
1
]
-
paddings
[
1
]
+
h_offset
*
dilations
[
1
];
int
h_offset
=
(
c
/
filter_width
)
%
filter_height
;
for
(
int
w
=
0
;
w
<
output_width
;
++
w
)
{
int
d_offset
=
int
w_pad
=
w
*
strides
[
2
]
-
paddings
[
2
]
+
w_offset
*
dilations
[
2
];
(
c
/
filter_width
/
filter_height
)
%
filter_depth
;
int
c_in
=
int
col_idx
=
c
/
filter_width
/
filter_height
/
filter_depth
;
((
c
*
output_depth
+
d
)
*
output_height
+
h
)
*
output_width
+
w
;
for
(
int
d
=
0
;
d
<
output_depth
;
++
d
)
{
int
vol_idx
=
int
d_pad
=
d
*
strides
[
0
]
-
paddings
[
0
]
+
((
c_in
*
input_depth
+
d_pad
)
*
input_height
+
h_pad
)
*
d_offset
*
dilations
[
0
];
input_width
+
for
(
int
h
=
0
;
h
<
output_height
;
++
h
)
{
w_pad
;
int
h_pad
=
h
*
strides
[
1
]
-
paddings
[
1
]
+
col_data
[
col_idx
]
=
h_offset
*
dilations
[
1
];
(
h_pad
<
0
||
h_pad
>=
input_height
||
w_pad
<
0
||
for
(
int
w
=
0
;
w
<
output_width
;
++
w
)
{
w_pad
>=
input_width
||
d_pad
<
0
||
d_pad
>=
input_depth
)
int
w_pad
=
w
*
strides
[
2
]
-
paddings
[
2
]
+
?
static_cast
<
T
>
(
0
)
w_offset
*
dilations
[
2
];
:
vol_data
[
vol_idx
];
}
int
col_idx
=
((
c
*
output_depth
+
d
)
*
}
output_height
+
}
h
)
*
}
output_width
+
}
w
;
};
int
vol_idx
=
((
c_in
*
input_depth
+
d_pad
)
*
/*
input_height
+
* vol = [input_channels,input_depth, input_height, input_width]
h_pad
)
*
* col =
input_width
+
* [input_channels, filter_depth, filter_height, filter_width,
w_pad
;
* output_depth, output_height, output_width]
col_data
[
col_idx
]
=
*/
(
h_pad
<
0
||
h_pad
>=
input_height
||
template
<
typename
T
>
class
Col2VolFunctor
<
CPU
,
T
>
{
w_pad
<
0
||
w_pad
>=
input_width
||
public:
d_pad
<
0
||
d_pad
>=
input_depth
)
void
operator
()(
const
Tensor
&
col
,
const
std
::
vector
<
int
>
&
dilations
,
?
static_cast
<
T
>
(
0
)
const
std
::
vector
<
int
>
&
strides
,
:
vol_data
[
vol_idx
];
const
std
::
vector
<
int
>
&
paddings
,
Tensor
*
vol
)
const
{
}
// PADDLE_ENFORCE(vol->dims().size() == 4);
}
// PADDLE_ENFORCE(col.dims().size() == 7);
}
}
int
input_channels
=
vol
->
dims
()[
0
];
}
int
input_depth
=
vol
->
dims
()[
1
];
};
int
input_height
=
vol
->
dims
()[
2
];
int
input_width
=
vol
->
dims
()[
3
];
/*
int
filter_depth
=
col
.
dims
()[
1
];
* vol = [input_channels,input_depth, input_height, input_width]
int
filter_height
=
col
.
dims
()[
2
];
* col =
int
filter_width
=
col
.
dims
()[
3
];
* [input_channels, filter_depth, filter_height, filter_width,
int
output_depth
=
col
.
dims
()[
4
];
* output_depth, output_height, output_width]
int
output_height
=
col
.
dims
()[
5
];
*/
int
output_width
=
col
.
dims
()[
6
];
template
<
typename
T
>
class
Col2VolFunctor
<
CPU
,
T
>
{
int
channels_col
=
public:
input_channels
*
filter_depth
*
filter_height
*
filter_width
;
void
operator
()(
const
Tensor
&
col
,
const
std
::
vector
<
int
>
&
dilations
,
// PADDLE_ENFORCE_EQ((input_depth + 2 * paddings[0] -
const
std
::
vector
<
int
>
&
strides
,
// ((dilations[0] * (filter_depth - 1) + 1))) /
const
std
::
vector
<
int
>
&
paddings
,
// strides[0] +
Tensor
*
vol
)
const
{
// 1,
// PADDLE_ENFORCE(vol->dims().size() == 4);
// output_depth,
// PADDLE_ENFORCE(col.dims().size() == 7);
// "input_depth and output_depth are "
// "mismatching.");
int
input_channels
=
vol
->
dims
()[
0
];
// PADDLE_ENFORCE_EQ((input_height + 2 * paddings[1] -
int
input_depth
=
vol
->
dims
()[
1
];
// ((dilations[1] * (filter_height - 1) + 1))) /
int
input_height
=
vol
->
dims
()[
2
];
// strides[1] +
int
input_width
=
vol
->
dims
()[
3
];
// 1,
int
filter_depth
=
col
.
dims
()[
1
];
// output_height,
int
filter_height
=
col
.
dims
()[
2
];
// "input_height and output_height are "
int
filter_width
=
col
.
dims
()[
3
];
// "mismatching.");
int
output_depth
=
col
.
dims
()[
4
];
// PADDLE_ENFORCE_EQ((input_width + 2 * paddings[2] -
int
output_height
=
col
.
dims
()[
5
];
// ((dilations[2] * (filter_width - 1) + 1))) /
int
output_width
=
col
.
dims
()[
6
];
// strides[2] +
int
channels_col
=
input_channels
*
filter_depth
*
// 1,
filter_height
*
filter_width
;
// output_width,
// "input_width and output_width are "
// PADDLE_ENFORCE_EQ((input_depth + 2 * paddings[0] -
// "mismatching.");
// ((dilations[0] * (filter_depth - 1)
T
*
vol_data
=
vol
->
data
<
T
>
();
// + 1))) /
const
T
*
col_data
=
col
.
data
<
T
>
();
// strides[0] +
// 1,
for
(
int
c
=
0
;
c
<
channels_col
;
++
c
)
{
// output_depth,
int
w_offset
=
c
%
filter_width
;
// "input_depth and output_depth are "
int
h_offset
=
(
c
/
filter_width
)
%
filter_height
;
// "mismatching.");
int
d_offset
=
(
c
/
filter_width
/
filter_height
)
%
filter_depth
;
// PADDLE_ENFORCE_EQ((input_height + 2 * paddings[1] -
int
cIm
=
c
/
filter_width
/
filter_height
/
filter_depth
;
// ((dilations[1] * (filter_height -
for
(
int
d
=
0
;
d
<
output_depth
;
++
d
)
{
// 1) + 1))) /
int
d_pad
=
d
*
strides
[
0
]
-
paddings
[
0
]
+
d_offset
*
dilations
[
0
];
// strides[1] +
for
(
int
h
=
0
;
h
<
output_height
;
++
h
)
{
// 1,
int
h_pad
=
h
*
strides
[
1
]
-
paddings
[
1
]
+
h_offset
*
dilations
[
1
];
// output_height,
for
(
int
w
=
0
;
w
<
output_width
;
++
w
)
{
// "input_height and output_height are
int
w_pad
=
w
*
strides
[
2
]
-
paddings
[
2
]
+
w_offset
*
dilations
[
2
];
// "
// "mismatching.");
if
(
h_pad
>=
0
&&
h_pad
<
input_height
&&
w_pad
>=
0
&&
// PADDLE_ENFORCE_EQ((input_width + 2 * paddings[2] -
w_pad
<
input_width
&&
d_pad
>=
0
&&
d_pad
<
input_depth
)
{
// ((dilations[2] * (filter_width - 1)
int
vol_idx
=
// + 1))) /
((
cIm
*
input_depth
+
d_pad
)
*
input_height
+
h_pad
)
*
// strides[2] +
input_width
+
// 1,
w_pad
;
// output_width,
// "input_width and output_width are "
int
col_idx
=
// "mismatching.");
((
c
*
output_depth
+
d
)
*
output_height
+
h
)
*
output_width
+
T
*
vol_data
=
vol
->
data
<
T
>
();
w
;
const
T
*
col_data
=
col
.
data
<
T
>
();
vol_data
[
vol_idx
]
+=
col_data
[
col_idx
];
}
for
(
int
c
=
0
;
c
<
channels_col
;
++
c
)
{
}
int
w_offset
=
c
%
filter_width
;
}
int
h_offset
=
(
c
/
filter_width
)
%
filter_height
;
}
int
d_offset
=
}
(
c
/
filter_width
/
filter_height
)
%
filter_depth
;
}
int
cIm
=
};
c
/
filter_width
/
filter_height
/
filter_depth
;
for
(
int
d
=
0
;
d
<
output_depth
;
++
d
)
{
template
class
Vol2ColFunctor
<
CPU
,
float
>;
int
d_pad
=
d
*
strides
[
0
]
-
paddings
[
0
]
+
template
class
Vol2ColFunctor
<
CPU
,
double
>;
d_offset
*
dilations
[
0
];
template
class
Col2VolFunctor
<
CPU
,
float
>;
for
(
int
h
=
0
;
h
<
output_height
;
++
h
)
{
template
class
Col2VolFunctor
<
CPU
,
double
>;
int
h_pad
=
h
*
strides
[
1
]
-
paddings
[
1
]
+
h_offset
*
dilations
[
1
];
}
// namespace math
for
(
int
w
=
0
;
w
<
output_width
;
++
w
)
{
}
// namespace operators
int
w_pad
=
w
*
strides
[
2
]
-
paddings
[
2
]
+
w_offset
*
dilations
[
2
];
if
(
h_pad
>=
0
&&
h_pad
<
input_height
&&
w_pad
>=
0
&&
w_pad
<
input_width
&&
d_pad
>=
0
&&
d_pad
<
input_depth
)
{
int
vol_idx
=
((
cIm
*
input_depth
+
d_pad
)
*
input_height
+
h_pad
)
*
input_width
+
w_pad
;
int
col_idx
=
((
c
*
output_depth
+
d
)
*
output_height
+
h
)
*
output_width
+
w
;
vol_data
[
vol_idx
]
+=
col_data
[
col_idx
];
}
}
}
}
}
}
};
template
class
Vol2ColFunctor
<
CPU
,
float
>;
template
class
Vol2ColFunctor
<
CPU
,
double
>;
template
class
Col2VolFunctor
<
CPU
,
float
>;
template
class
Col2VolFunctor
<
CPU
,
double
>;
}
// namespace math
}
// namespace operators
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/operators/math/vol2col.h
浏览文件 @
aef98218
...
@@ -18,66 +18,78 @@ limitations under the License. */
...
@@ -18,66 +18,78 @@ limitations under the License. */
#include "framework/tensor.h"
#include "framework/tensor.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
operators
{
namespace
operators
{
namespace
math
{
namespace
math
{
/*
/*
* \brief Converts the feature data of four dimensions(CDHW) into a colData of
* \brief Converts the feature data of four dimensions(CDHW) into a
* seven dimensions in the Vol2ColFunctor calculation,
* colData of
* And in the Col2VolFunctor calculation, it is reversed.
* seven dimensions in the Vol2ColFunctor calculation,
*
* And in the Col2VolFunctor calculation, it is reversed.
* \param volData Vol data.
*
* \param volShape The shape of volData,
* \param volData Vol data.
* [input_channels, input_depth, input_height, input_width].
* \param volShape The shape of volData,
* \param colData Column data.
* [input_channels, input_depth, input_height,
* \param colShape The shape of colData.
* input_width].
*
* \param colData Column data.
* \param dilations dilation data.
* \param colShape The shape of colData.
* \param 3-dimension [dilation_depth, dilation_height, dilation_width].
*
*
* \param dilations dilation data.
* \param strides stride data.
* \param 3-dimension [dilation_depth, dilation_height,
* \param 3-dimension [stride_depth, stride_height, stride_width].
* dilation_width].
*
*
* \param paddings padding data.
* \param strides stride data.
* \param 3-dimension [d_pad, h_pad, w_pad].
* \param 3-dimension [stride_depth, stride_height, stride_width].
*
*
* The shape of colData is:
* \param paddings padding data.
* [input_channels, filter_depth, filter_height, filter_width, output_depth,
* \param 3-dimension [d_pad, h_pad, w_pad].
* output_height, output_width]
*
* So, it is easy to reshape into a convolution matrix for convolution
* The shape of colData is:
* calculation based on matrix multiplication.
* [input_channels, filter_depth, filter_height, filter_width,
* The shape of convolution matrix is [height, width], where the height is equal
* output_depth,
* input_channels * filter_depth * filter_height * filter_width, and the width
* output_height, output_width]
* is equal output_depth * output_height * output_width.
* So, it is easy to reshape into a convolution matrix for
*
* convolution
* Reshape:
* calculation based on matrix multiplication.
* shape of colData shape of convolution matrix
* The shape of convolution matrix is [height, width], where the
* [input_channels,
* height is equal
* filter_depth,
* input_channels * filter_depth * filter_height * filter_width, and
* filter_height,
* the width
* filter_width, ======> [height, width]
* is equal output_depth * output_height * output_width.
* output_depth,
*
* output_height,
* Reshape:
* output_width]
* shape of colData shape of convolution matrix
*
* [input_channels,
* \note The caller needs to ensure that volShape.inputChannels is equal to
* filter_depth,
* colShape.inputChannels.
* filter_height,
*/
* filter_width, ======> [height, width]
using
Tensor
=
paddle_mobile
::
framework
::
Tensor
;
* output_depth,
* output_height,
* output_width]
*
* \note The caller needs to ensure that volShape.inputChannels is
* equal to
* colShape.inputChannels.
*/
using
Tensor
=
paddle_mobile
::
framework
::
Tensor
;
template
<
typename
DeviceType
,
typename
T
>
class
Vol2ColFunctor
{
template
<
typename
DeviceType
,
typename
T
>
class
Vol2ColFunctor
{
public:
public:
void
operator
()(
const
Tensor
&
vol
,
const
std
::
vector
<
int
>
&
dilations
,
void
operator
()(
const
Tensor
&
vol
,
const
std
::
vector
<
int
>
&
strides
,
const
std
::
vector
<
int
>
&
dilations
,
const
std
::
vector
<
int
>
&
paddings
,
Tensor
*
col
)
const
;
const
std
::
vector
<
int
>
&
strides
,
};
const
std
::
vector
<
int
>
&
paddings
,
Tensor
*
col
)
const
;
};
template
<
typename
DeviceType
,
typename
T
>
class
Col2VolFunctor
{
template
<
typename
DeviceType
,
typename
T
>
class
Col2VolFunctor
{
public:
public:
void
operator
()(
const
Tensor
&
col
,
const
std
::
vector
<
int
>
&
dilations
,
void
operator
()(
const
Tensor
&
col
,
const
std
::
vector
<
int
>
&
strides
,
const
std
::
vector
<
int
>
&
dilations
,
const
std
::
vector
<
int
>
&
paddings
,
Tensor
*
vol
)
const
;
const
std
::
vector
<
int
>
&
strides
,
};
const
std
::
vector
<
int
>
&
paddings
,
Tensor
*
vol
)
const
;
};
}
// namespace math
}
// namespace math
}
// namespace operators
}
// namespace operators
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/operators/op_param.cpp
浏览文件 @
aef98218
...
@@ -19,25 +19,26 @@ SOFTWARE.
...
@@ -19,25 +19,26 @@ SOFTWARE.
#include "op_param.h"
#include "op_param.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
operators
{
namespace
operators
{
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
ConvParam
&
conv_param
)
{
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
os
<<
"parameter of conv: "
<<
std
::
endl
;
const
ConvParam
&
conv_param
)
{
os
<<
" stride: "
os
<<
"parameter of conv: "
<<
std
::
endl
;
<<
" ("
<<
conv_param
.
Strides
()[
0
]
<<
conv_param
.
Strides
()[
1
]
<<
") "
os
<<
" stride: "
<<
std
::
endl
;
<<
" ("
<<
conv_param
.
Strides
()[
0
]
<<
conv_param
.
Strides
()[
1
]
os
<<
" paddings: "
<<
") "
<<
std
::
endl
;
<<
" ("
<<
conv_param
.
Paddings
()[
0
]
<<
conv_param
.
Paddings
()[
1
]
<<
") "
os
<<
" paddings: "
<<
std
::
endl
;
<<
" ("
<<
conv_param
.
Paddings
()[
0
]
<<
conv_param
.
Paddings
()[
1
]
os
<<
" dilations: "
<<
") "
<<
std
::
endl
;
<<
" ("
<<
conv_param
.
Dilations
()[
0
]
<<
conv_param
.
Dilations
()[
1
]
<<
") "
os
<<
" dilations: "
<<
std
::
endl
;
<<
" ("
<<
conv_param
.
Dilations
()[
0
]
<<
conv_param
.
Dilations
()[
1
]
os
<<
" groups: "
<<
conv_param
.
Groups
()
<<
std
::
endl
;
<<
") "
<<
std
::
endl
;
os
<<
" input dims: "
<<
conv_param
.
Input
()
->
dims
()
<<
std
::
endl
;
os
<<
" groups: "
<<
conv_param
.
Groups
()
<<
std
::
endl
;
os
<<
" filter dims: "
<<
conv_param
.
Filter
()
->
dims
()
<<
std
::
endl
;
os
<<
" input dims: "
<<
conv_param
.
Input
()
->
dims
()
<<
std
::
endl
;
os
<<
" output dims: "
<<
conv_param
.
Output
()
->
dims
()
<<
std
::
endl
;
os
<<
" filter dims: "
<<
conv_param
.
Filter
()
->
dims
()
<<
std
::
endl
;
return
os
;
os
<<
" output dims: "
<<
conv_param
.
Output
()
->
dims
()
<<
std
::
endl
;
}
return
os
;
}
}
// namespace operators
}
// namespace operators
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/operators/op_param.h
浏览文件 @
aef98218
...
@@ -25,86 +25,92 @@ SOFTWARE.
...
@@ -25,86 +25,92 @@ SOFTWARE.
#include "framework/variable.h"
#include "framework/variable.h"
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
operators
{
namespace
operators
{
using
namespace
framework
;
using
namespace
framework
;
class
OpParam
:
PaddleMobileObject
{
class
OpParam
:
PaddleMobileObject
{
public:
public:
protected:
protected:
template
<
typename
T
>
template
<
typename
T
>
static
T
*
InputFrom
(
const
VariableNameMap
&
inputs
,
const
Scope
&
scope
)
{
static
T
*
InputFrom
(
const
VariableNameMap
&
inputs
,
return
GetVarValue
<
T
>
(
"Input"
,
inputs
,
scope
);
const
Scope
&
scope
)
{
}
return
GetVarValue
<
T
>
(
"Input"
,
inputs
,
scope
);
}
template
<
typename
T
>
static
T
*
OutputFrom
(
const
VariableNameMap
&
outputs
,
const
Scope
&
scope
)
{
template
<
typename
T
>
return
GetVarValue
<
T
>
(
"Output"
,
outputs
,
scope
);
static
T
*
OutputFrom
(
const
VariableNameMap
&
outputs
,
}
const
Scope
&
scope
)
{
return
GetVarValue
<
T
>
(
"Output"
,
outputs
,
scope
);
template
<
typename
T
>
}
static
T
*
FilterFrom
(
const
VariableNameMap
&
inputs
,
const
Scope
&
scope
)
{
return
GetVarValue
<
T
>
(
"Filter"
,
inputs
,
scope
);
template
<
typename
T
>
}
static
T
*
FilterFrom
(
const
VariableNameMap
&
inputs
,
const
Scope
&
scope
)
{
template
<
typename
T
>
return
GetVarValue
<
T
>
(
"Filter"
,
inputs
,
scope
);
static
const
T
GetAttr
(
std
::
string
key
,
const
AttributeMap
&
map
)
{
}
return
((
Attribute
)
map
.
at
(
key
)).
Get
<
T
>
();
}
template
<
typename
T
>
static
const
T
GetAttr
(
std
::
string
key
,
const
AttributeMap
&
map
)
{
template
<
typename
T
>
return
((
Attribute
)
map
.
at
(
key
)).
Get
<
T
>
();
static
T
*
GetVarValue
(
std
::
string
key
,
const
VariableNameMap
&
var_map
,
}
const
Scope
&
scope
)
{
auto
var_vec
=
var_map
.
at
(
key
);
template
<
typename
T
>
if
(
var_vec
.
size
())
{
static
T
*
GetVarValue
(
std
::
string
key
,
// std::cout << " get var value -- " << var_vec[0] << std::endl;
const
VariableNameMap
&
var_map
,
auto
var
=
scope
.
FindVar
(
var_vec
[
0
]);
const
Scope
&
scope
)
{
return
var
->
GetMutable
<
T
>
();
auto
var_vec
=
var_map
.
at
(
key
);
}
else
{
if
(
var_vec
.
size
())
{
return
nullptr
;
// std::cout << " get var value -- " << var_vec[0] <<
}
// std::endl;
}
auto
var
=
scope
.
FindVar
(
var_vec
[
0
]);
};
return
var
->
GetMutable
<
T
>
();
}
else
{
class
ConvParam
:
OpParam
{
return
nullptr
;
public:
}
ConvParam
(
const
VariableNameMap
&
inputs
,
const
VariableNameMap
&
outputs
,
}
const
framework
::
AttributeMap
&
attrs
,
};
const
framework
::
Scope
&
scope
)
{
filter_
=
FilterFrom
<
framework
::
LoDTensor
>
(
inputs
,
scope
);
class
ConvParam
:
OpParam
{
input_
=
InputFrom
<
framework
::
Tensor
>
(
inputs
,
scope
);
public:
output_
=
OutputFrom
<
framework
::
Tensor
>
(
outputs
,
scope
);
ConvParam
(
const
VariableNameMap
&
inputs
,
strides_
=
GetAttr
<
std
::
vector
<
int
>>
(
"strides"
,
attrs
);
const
VariableNameMap
&
outputs
,
paddings_
=
GetAttr
<
std
::
vector
<
int
>>
(
"paddings"
,
attrs
);
const
framework
::
AttributeMap
&
attrs
,
dilations_
=
GetAttr
<
std
::
vector
<
int
>>
(
"dilations"
,
attrs
);
const
framework
::
Scope
&
scope
)
{
groups
=
GetAttr
<
int
>
(
"groups"
,
attrs
);
filter_
=
FilterFrom
<
framework
::
LoDTensor
>
(
inputs
,
scope
);
}
input_
=
InputFrom
<
framework
::
Tensor
>
(
inputs
,
scope
);
output_
=
OutputFrom
<
framework
::
Tensor
>
(
outputs
,
scope
);
const
Tensor
*
Input
()
const
{
return
input_
;
}
strides_
=
GetAttr
<
std
::
vector
<
int
>>
(
"strides"
,
attrs
);
paddings_
=
GetAttr
<
std
::
vector
<
int
>>
(
"paddings"
,
attrs
);
const
LoDTensor
*
Filter
()
const
{
return
filter_
;
}
dilations_
=
GetAttr
<
std
::
vector
<
int
>>
(
"dilations"
,
attrs
);
groups
=
GetAttr
<
int
>
(
"groups"
,
attrs
);
Tensor
*
Output
()
const
{
return
output_
;
}
}
const
std
::
vector
<
int
>
&
Strides
()
const
{
return
strides_
;
}
const
Tensor
*
Input
()
const
{
return
input_
;
}
const
std
::
vector
<
int
>
&
Paddings
()
const
{
return
paddings_
;
}
const
LoDTensor
*
Filter
()
const
{
return
filter_
;
}
const
std
::
vector
<
int
>
&
Dilations
()
const
{
return
dilations_
;
}
Tensor
*
Output
()
const
{
return
output_
;
}
const
int
&
Groups
()
const
{
return
groups
;
}
const
std
::
vector
<
int
>
&
Strides
()
const
{
return
strides_
;
}
private:
const
std
::
vector
<
int
>
&
Paddings
()
const
{
return
paddings_
;
}
Tensor
*
input_
;
Tensor
*
output_
;
const
std
::
vector
<
int
>
&
Dilations
()
const
{
return
dilations_
;
}
LoDTensor
*
filter_
;
std
::
vector
<
int
>
strides_
;
const
int
&
Groups
()
const
{
return
groups
;
}
std
::
vector
<
int
>
paddings_
;
std
::
vector
<
int
>
dilations_
;
private:
int
groups
;
Tensor
*
input_
;
};
Tensor
*
output_
;
LoDTensor
*
filter_
;
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
ConvParam
&
conv_param
);
std
::
vector
<
int
>
strides_
;
std
::
vector
<
int
>
paddings_
;
}
// namespace operators
std
::
vector
<
int
>
dilations_
;
int
groups
;
};
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
ConvParam
&
conv_param
);
}
// namespace operators
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/platform/data_type.h
浏览文件 @
aef98218
...
@@ -19,106 +19,107 @@ limitations under the License. */
...
@@ -19,106 +19,107 @@ limitations under the License. */
#include <typeindex>
#include <typeindex>
namespace
paddle_mobile
{
namespace
paddle_mobile
{
namespace
framework
{
namespace
framework
{
inline
proto
::
VarType
::
Type
ToDataType
(
std
::
type_index
type
)
{
inline
proto
::
VarType
::
Type
ToDataType
(
std
::
type_index
type
)
{
/*if (typeid(platform::float16).hash_code() == type.hash_code()) {
/*if (typeid(platform::float16).hash_code() == type.hash_code()) {
return proto::VarType::FP16;
return proto::VarType::FP16;
} else */
} else */
if
(
typeid
(
const
float
).
hash_code
()
==
type
.
hash_code
())
{
if
(
typeid
(
const
float
).
hash_code
()
==
type
.
hash_code
())
{
// CPPLint complains Using C-style cast. Use static_cast<float>() instead
// CPPLint complains Using C-style cast. Use
// One fix to this is to replace float with const float because
// static_cast<float>() instead
// typeid(T) == typeid(const T)
// One fix to this is to replace float with const float because
// http://en.cppreference.com/w/cpp/language/typeid
// typeid(T) == typeid(const T)
return
proto
::
VarType
::
FP32
;
// http://en.cppreference.com/w/cpp/language/typeid
}
else
if
(
typeid
(
const
double
).
hash_code
()
==
type
.
hash_code
())
{
return
proto
::
VarType
::
FP32
;
return
proto
::
VarType
::
FP64
;
}
else
if
(
typeid
(
const
double
).
hash_code
()
==
type
.
hash_code
())
{
}
else
if
(
typeid
(
const
int
).
hash_code
()
==
type
.
hash_code
())
{
return
proto
::
VarType
::
FP64
;
return
proto
::
VarType
::
INT32
;
}
else
if
(
typeid
(
const
int
).
hash_code
()
==
type
.
hash_code
())
{
}
else
if
(
typeid
(
const
int64_t
).
hash_code
()
==
type
.
hash_code
())
{
return
proto
::
VarType
::
INT32
;
return
proto
::
VarType
::
INT64
;
}
else
if
(
typeid
(
const
int64_t
).
hash_code
()
==
type
.
hash_code
())
{
}
else
if
(
typeid
(
const
bool
).
hash_code
()
==
type
.
hash_code
())
{
return
proto
::
VarType
::
INT64
;
return
proto
::
VarType
::
BOOL
;
}
else
if
(
typeid
(
const
bool
).
hash_code
()
==
type
.
hash_code
())
{
}
else
{
return
proto
::
VarType
::
BOOL
;
// PADDLE_THROW("Not supported");
}
else
{
// std::cout << "Not supported";
// PADDLE_THROW("Not supported");
}
// std::cout << "Not supported";
}
}
}
inline
std
::
type_index
ToTypeIndex
(
proto
::
VarType
::
Type
type
)
{
inline
std
::
type_index
ToTypeIndex
(
proto
::
VarType
::
Type
type
)
{
switch
(
type
)
{
switch
(
type
)
{
// case proto::VarType::FP16:
// case proto::VarType::FP16:
// return typeid(platform::float16);
// return typeid(platform::float16);
case
proto
::
VarType
::
FP32
:
case
proto
::
VarType
::
FP32
:
return
typeid
(
float
);
return
typeid
(
float
);
case
proto
::
VarType
::
FP64
:
case
proto
::
VarType
::
FP64
:
return
typeid
(
double
);
return
typeid
(
double
);
case
proto
::
VarType
::
INT32
:
case
proto
::
VarType
::
INT32
:
return
typeid
(
int
);
return
typeid
(
int
);
case
proto
::
VarType
::
INT64
:
case
proto
::
VarType
::
INT64
:
return
typeid
(
int64_t
);
return
typeid
(
int64_t
);
case
proto
::
VarType
::
BOOL
:
case
proto
::
VarType
::
BOOL
:
return
typeid
(
bool
);
return
typeid
(
bool
);
default:
default:
// PADDLE_THROW("Not support type %d", type);
// PADDLE_THROW("Not support type %d", type);
printf
(
"Not support type %d"
,
type
);
printf
(
"Not support type %d"
,
type
);
}
}
}
}
template
<
typename
Visitor
>
template
<
typename
Visitor
>
inline
void
VisitDataType
(
proto
::
VarType
::
Type
type
,
Visitor
visitor
)
{
inline
void
VisitDataType
(
proto
::
VarType
::
Type
type
,
Visitor
visitor
)
{
switch
(
type
)
{
switch
(
type
)
{
// case proto::VarType::FP16:
// case proto::VarType::FP16:
// visitor.template operator()<platform::float16>();
// visitor.template operator()<platform::float16>();
// break;
// break;
case
proto
::
VarType
::
FP32
:
case
proto
::
VarType
::
FP32
:
visitor
.
template
operator
()
<
float
>();
visitor
.
template
operator
()
<
float
>();
break
;
break
;
case
proto
::
VarType
::
FP64
:
case
proto
::
VarType
::
FP64
:
visitor
.
template
operator
()
<
double
>();
visitor
.
template
operator
()
<
double
>();
break
;
break
;
case
proto
::
VarType
::
INT32
:
case
proto
::
VarType
::
INT32
:
visitor
.
template
operator
()
<
int
>();
visitor
.
template
operator
()
<
int
>();
break
;
break
;
case
proto
::
VarType
::
INT64
:
case
proto
::
VarType
::
INT64
:
visitor
.
template
operator
()
<
int64_t
>();
visitor
.
template
operator
()
<
int64_t
>();
break
;
break
;
case
proto
::
VarType
::
BOOL
:
case
proto
::
VarType
::
BOOL
:
visitor
.
template
operator
()
<
bool
>();
visitor
.
template
operator
()
<
bool
>();
break
;
break
;
default:
default:
// PADDLE_THROW("Not supported");
// PADDLE_THROW("Not supported");
printf
(
"Not supported"
);
printf
(
"Not supported"
);
}
}
}
}
inline
std
::
string
DataTypeToString
(
const
proto
::
VarType
::
Type
type
)
{
inline
std
::
string
DataTypeToString
(
const
proto
::
VarType
::
Type
type
)
{
switch
(
type
)
{
switch
(
type
)
{
case
proto
::
VarType
::
FP16
:
case
proto
::
VarType
::
FP16
:
return
"float16"
;
return
"float16"
;
case
proto
::
VarType
::
FP32
:
case
proto
::
VarType
::
FP32
:
return
"float32"
;
return
"float32"
;
case
proto
::
VarType
::
FP64
:
case
proto
::
VarType
::
FP64
:
return
"float64"
;
return
"float64"
;
case
proto
::
VarType
::
INT16
:
case
proto
::
VarType
::
INT16
:
return
"int16"
;
return
"int16"
;
case
proto
::
VarType
::
INT32
:
case
proto
::
VarType
::
INT32
:
return
"int32"
;
return
"int32"
;
case
proto
::
VarType
::
INT64
:
case
proto
::
VarType
::
INT64
:
return
"int64"
;
return
"int64"
;
case
proto
::
VarType
::
BOOL
:
case
proto
::
VarType
::
BOOL
:
return
"bool"
;
return
"bool"
;
default:
default:
// PADDLE_THROW("Not support type %d", type);
// PADDLE_THROW("Not support type %d", type);
printf
(
"Not support type %d"
,
type
);
printf
(
"Not support type %d"
,
type
);
}
}
}
}
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
proto
::
VarType
::
Type
&
type
)
{
const
proto
::
VarType
::
Type
&
type
)
{
out
<<
DataTypeToString
(
type
);
out
<<
DataTypeToString
(
type
);
return
out
;
return
out
;
}
}
}
// namespace framework
}
// namespace framework
}
// namespace paddle_mobile
}
// namespace paddle_mobile
src/platform/macros.h
浏览文件 @
aef98218
...
@@ -17,9 +17,9 @@ limitations under the License. */
...
@@ -17,9 +17,9 @@ limitations under the License. */
// Disable the copy and assignment operator for a class.
// Disable the copy and assignment operator for a class.
#ifndef DISABLE_COPY_AND_ASSIGN
#ifndef DISABLE_COPY_AND_ASSIGN
#define DISABLE_COPY_AND_ASSIGN(classname) \
#define DISABLE_COPY_AND_ASSIGN(classname) \
private:
\
private:
\
classname(const classname &) = delete;
\
classname(const classname &) = delete;
\
classname(classname &&) = delete;
\
classname(classname &&) = delete;
\
classname &operator=(const classname &) = delete;
\
classname &operator=(const classname &) = delete;
\
classname &operator=(classname &&) = delete
classname &operator=(classname &&) = delete
#endif
#endif
android-cmake/android.toolchain.cmake
→
tools/
android-cmake/android.toolchain.cmake
浏览文件 @
aef98218
文件已移动
ios-cmake/ios.toolchain.cmake
→
tools/
ios-cmake/ios.toolchain.cmake
浏览文件 @
aef98218
文件已移动
.clang_format.hook
→
tools/pre-commit.hooks/
.clang_format.hook
浏览文件 @
aef98218
文件已移动
tools/pre-commit.hooks/.copyright.hook
0 → 100644
浏览文件 @
aef98218
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
import argparse
import io, re
import sys, os
import subprocess
import platform
COPYRIGHT = '''
Copyright (c) 2016 Baidu, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
'''
LANG_COMMENT_MARK = None
NEW_LINE_MARK = None
COPYRIGHT_HEADER = None
if platform.system() == "Windows":
NEW_LINE_MARK = "\r\n"
else:
NEW_LINE_MARK = '\n'
COPYRIGHT_HEADER = COPYRIGHT.split(NEW_LINE_MARK)[1]
p = re.search('(\d{4})', COPYRIGHT_HEADER).group(0)
process = subprocess.Popen(["date", "+%Y"], stdout=subprocess.PIPE)
date, err = process.communicate()
date = date.decode("utf-8").rstrip("\n")
COPYRIGHT_HEADER = COPYRIGHT_HEADER.replace(p, date)
def generate_copyright(template, lang='C'):
if lang == 'Python':
LANG_COMMENT_MARK = '#'
else:
LANG_COMMENT_MARK = "//"
lines = template.split(NEW_LINE_MARK)
BLANK = " "
ans = LANG_COMMENT_MARK + BLANK + COPYRIGHT_HEADER + NEW_LINE_MARK
for lino, line in enumerate(lines):
if lino == 0 or lino == 1 or lino == len(lines) - 1: continue
if len(line) == 0:
BLANK = ""
else:
BLANK = " "
ans += LANG_COMMENT_MARK + BLANK + line + NEW_LINE_MARK
return ans + "\n"
def lang_type(filename):
if filename.endswith(".py"):
return "Python"
elif filename.endswith(".h"):
return "C"
elif filename.endswith(".c"):
return "C"
elif filename.endswith(".hpp"):
return "C"
elif filename.endswith(".cc"):
return "C"
elif filename.endswith(".cpp"):
return "C"
elif filename.endswith(".cu"):
return "C"
elif filename.endswith(".cuh"):
return "C"
elif filename.endswith(".go"):
return "C"
elif filename.endswith(".proto"):
return "C"
else:
print("Unsupported filetype %s", filename)
exit(0)
PYTHON_ENCODE = re.compile("^[ \t\v]*#.*?coding[:=][ \t]*([-_.a-zA-Z0-9]+)")
def main(argv=None):
parser = argparse.ArgumentParser(
description='Checker for copyright declaration.')
parser.add_argument('filenames', nargs='*', help='Filenames to check')
args = parser.parse_args(argv)
retv = 0
for filename in args.filenames:
fd = io.open(filename, encoding="utf-8")
first_line = fd.readline()
second_line = fd.readline()
if "COPYRIGHT (C)" in first_line.upper(): continue
if first_line.startswith("#!") or PYTHON_ENCODE.match(
second_line) != None or PYTHON_ENCODE.match(first_line) != None:
continue
original_contents = io.open(filename, encoding="utf-8").read()
new_contents = generate_copyright(
COPYRIGHT, lang_type(filename)) + original_contents
print('Auto Insert Copyright Header {}'.format(filename))
retv = 1
with io.open(filename, 'w') as output_file:
output_file.write(new_contents)
return retv
if __name__ == '__main__':
exit(main())
tools/pre-commit.hooks/clang-format.bash
0 → 100755
浏览文件 @
aef98218
#!/bin/bash
set
-e
readonly
VERSION
=
"version 3."
version
=
$(
clang-format
-version
)
if
!
[[
$version
==
*
"
$VERSION
"
*
]]
;
then
echo
"clang-format version check failed."
echo
"a version contains '
$VERSION
' is needed, but get '
$version
'"
echo
"you can install the right version, and make an soft-link to '
\$
PATH' env"
exit
-1
fi
clang-format
$@
tools/pre-commit.hooks/copyright.py
0 → 100755
浏览文件 @
aef98218
# Copyright (c) 2016 Baidu, Inc. All Rights Reserved.
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from
__future__
import
absolute_import
from
__future__
import
print_function
from
__future__
import
unicode_literals
import
argparse
import
io
,
re
import
sys
,
os
import
subprocess
import
platform
COPYRIGHT
=
'''
/* Copyright (c) 2016 Baidu, Inc. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
==============================================================================*/
'''
LANG_COMMENT_MARK
=
None
NEW_LINE_MARK
=
None
COPYRIGHT_HEADER
=
None
if
platform
.
system
()
==
"Windows"
:
NEW_LINE_MARK
=
"
\r\n
"
else
:
NEW_LINE_MARK
=
'
\n
'
COPYRIGHT_HEADER
=
COPYRIGHT
.
split
(
NEW_LINE_MARK
)[
1
]
p
=
re
.
search
(
'(\d{4})'
,
COPYRIGHT_HEADER
).
group
(
0
)
process
=
subprocess
.
Popen
([
"date"
,
"+%Y"
],
stdout
=
subprocess
.
PIPE
)
date
,
err
=
process
.
communicate
()
date
=
date
.
decode
(
"utf-8"
).
rstrip
(
"
\n
"
)
COPYRIGHT_HEADER
=
COPYRIGHT_HEADER
.
replace
(
p
,
date
)
def
generate_copyright
(
template
,
lang
=
'C'
):
if
lang
==
'Python'
:
LANG_COMMENT_MARK
=
'#'
else
:
LANG_COMMENT_MARK
=
"//"
lines
=
template
.
split
(
NEW_LINE_MARK
)
BLANK
=
" "
ans
=
LANG_COMMENT_MARK
+
BLANK
+
COPYRIGHT_HEADER
+
NEW_LINE_MARK
for
lino
,
line
in
enumerate
(
lines
):
if
lino
==
0
or
lino
==
1
or
lino
==
len
(
lines
)
-
1
:
continue
if
len
(
line
)
==
0
:
BLANK
=
""
else
:
BLANK
=
" "
ans
+=
LANG_COMMENT_MARK
+
BLANK
+
line
+
NEW_LINE_MARK
return
ans
+
"
\n
"
def
lang_type
(
filename
):
if
filename
.
endswith
(
".py"
):
return
"Python"
elif
filename
.
endswith
(
".h"
):
return
"C"
elif
filename
.
endswith
(
".c"
):
return
"C"
elif
filename
.
endswith
(
".hpp"
):
return
"C"
elif
filename
.
endswith
(
".cc"
):
return
"C"
elif
filename
.
endswith
(
".cpp"
):
return
"C"
elif
filename
.
endswith
(
".cu"
):
return
"C"
elif
filename
.
endswith
(
".cuh"
):
return
"C"
elif
filename
.
endswith
(
".go"
):
return
"C"
elif
filename
.
endswith
(
".proto"
):
return
"C"
else
:
print
(
"Unsupported filetype %s"
,
filename
)
exit
(
0
)
PYTHON_ENCODE
=
re
.
compile
(
"^[
\t\v
]*#.*?coding[:=][
\t
]*([-_.a-zA-Z0-9]+)"
)
def
main
(
argv
=
None
):
parser
=
argparse
.
ArgumentParser
(
description
=
'Checker for copyright declaration.'
)
parser
.
add_argument
(
'filenames'
,
nargs
=
'*'
,
help
=
'Filenames to check'
)
args
=
parser
.
parse_args
(
argv
)
retv
=
0
for
filename
in
args
.
filenames
:
fd
=
io
.
open
(
filename
,
encoding
=
"utf-8"
)
first_line
=
fd
.
readline
()
second_line
=
fd
.
readline
()
if
"COPYRIGHT "
in
first_line
.
upper
():
continue
if
first_line
.
startswith
(
"#!"
)
or
PYTHON_ENCODE
.
match
(
second_line
)
!=
None
or
PYTHON_ENCODE
.
match
(
first_line
)
!=
None
:
continue
original_contents
=
io
.
open
(
filename
,
encoding
=
"utf-8"
).
read
()
new_contents
=
generate_copyright
(
COPYRIGHT
,
lang_type
(
filename
))
+
original_contents
print
(
'Auto Insert Copyright Header {}'
.
format
(
filename
))
retv
=
1
with
io
.
open
(
filename
,
'w'
)
as
output_file
:
output_file
.
write
(
new_contents
)
return
retv
if
__name__
==
'__main__'
:
exit
(
main
())
tools/pre-commit.hooks/cpplint.bash
0 → 100755
浏览文件 @
aef98218
#!/bin/bash
TOTAL_ERRORS
=
0
#iclang-tidy *.[ch]pp -checks=*
# The trick to remove deleted files: https://stackoverflow.com/a/2413151
for
file
in
$(
git diff
--cached
--name-status
|
awk
'$1 != "D" {print $2}'
|grep
-v
".pb."
|
grep
-v
"third-party/"
)
;
do
cpplint
$file
TOTAL_ERRORS
=
$(
expr
$TOTAL_ERRORS
+
$?
)
;
done
exit
$TOTAL_ERRORS
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录