Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Crayon鑫
Paddle
提交
1b5647d7
P
Paddle
项目概览
Crayon鑫
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
1b5647d7
编写于
5月 06, 2022
作者:
A
Allen Guo
提交者:
GitHub
5月 06, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[IPU] clean ipu related code (#42511)
* clean code * fix ci * fix ci * fix ci 2
上级
6ff35e17
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
561 addition
and
502 deletion
+561
-502
paddle/fluid/platform/device/ipu/ipu_backend.cc
paddle/fluid/platform/device/ipu/ipu_backend.cc
+7
-9
paddle/fluid/platform/device/ipu/ipu_backend.h
paddle/fluid/platform/device/ipu/ipu_backend.h
+30
-32
paddle/fluid/platform/device/ipu/ipu_compiler.cc
paddle/fluid/platform/device/ipu/ipu_compiler.cc
+147
-37
paddle/fluid/platform/device/ipu/ipu_compiler.h
paddle/fluid/platform/device/ipu/ipu_compiler.h
+3
-33
paddle/fluid/platform/device/ipu/ipu_device.cc
paddle/fluid/platform/device/ipu/ipu_device.cc
+6
-2
paddle/fluid/platform/device/ipu/ipu_device.h
paddle/fluid/platform/device/ipu/ipu_device.h
+1
-1
paddle/fluid/platform/device/ipu/ipu_executor.cc
paddle/fluid/platform/device/ipu/ipu_executor.cc
+51
-17
paddle/fluid/platform/device/ipu/ipu_executor.h
paddle/fluid/platform/device/ipu/ipu_executor.h
+17
-13
paddle/fluid/platform/device/ipu/ipu_strategy.cc
paddle/fluid/platform/device/ipu/ipu_strategy.cc
+2
-0
paddle/fluid/platform/device/ipu/ipu_utils.cc
paddle/fluid/platform/device/ipu/ipu_utils.cc
+109
-75
paddle/fluid/platform/device/ipu/ipu_utils.h
paddle/fluid/platform/device/ipu/ipu_utils.h
+46
-176
paddle/fluid/platform/device/ipu/popart_canonicalization/activation_ops.cc
...form/device/ipu/popart_canonicalization/activation_ops.cc
+3
-3
paddle/fluid/platform/device/ipu/popart_canonicalization/canonicalization_utils.cc
...ice/ipu/popart_canonicalization/canonicalization_utils.cc
+2
-65
paddle/fluid/platform/device/ipu/popart_canonicalization/canonicalization_utils.h
...vice/ipu/popart_canonicalization/canonicalization_utils.h
+1
-4
paddle/fluid/platform/device/ipu/popart_canonicalization/logic_ops.cc
.../platform/device/ipu/popart_canonicalization/logic_ops.cc
+9
-0
paddle/fluid/platform/device/ipu/popart_canonicalization/math_ops.cc
...d/platform/device/ipu/popart_canonicalization/math_ops.cc
+78
-2
paddle/fluid/platform/device/ipu/popart_canonicalization/nn_ops.cc
...uid/platform/device/ipu/popart_canonicalization/nn_ops.cc
+1
-1
paddle/fluid/platform/device/ipu/popart_canonicalization/op_builder.cc
...platform/device/ipu/popart_canonicalization/op_builder.cc
+1
-1
paddle/fluid/platform/device/ipu/popart_canonicalization/tensor_ops.cc
...platform/device/ipu/popart_canonicalization/tensor_ops.cc
+47
-31
未找到文件。
paddle/fluid/platform/device/ipu/ipu_backend.cc
浏览文件 @
1b5647d7
...
...
@@ -13,12 +13,10 @@ See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/fluid/platform/device/ipu/ipu_backend.h"
#include "paddle/fluid/platform/device/ipu/ipu_utils.h"
#include "paddle/fluid/framework/framework.pb.h"
#include "paddle/fluid/framework/ir/graph.h"
#include "paddle/fluid/framework/ir/graph_helper.h"
#include "paddle/fluid/framework/ir/node.h"
#include "paddle/fluid/framework/operator.h"
#include "paddle/fluid/platform/device/ipu/ipu_compiler.h"
#include "paddle/fluid/platform/device/ipu/ipu_executor.h"
namespace
paddle
{
namespace
platform
{
...
...
@@ -40,7 +38,7 @@ IpuBackend::~IpuBackend() {
executor_
.
reset
();
}
void
IpuBackend
::
Compile
(
Graph
*
graph
,
void
IpuBackend
::
Compile
(
framework
::
ir
::
Graph
*
graph
,
const
std
::
vector
<
std
::
string
>&
feed_list
,
const
std
::
vector
<
std
::
string
>&
fetch_list
)
{
VLOG
(
10
)
<<
"enter IpuBackend::Compile"
;
...
...
@@ -63,8 +61,8 @@ void IpuBackend::Compile(Graph* graph,
VLOG
(
10
)
<<
"leave IpuBackend::Compile"
;
}
void
IpuBackend
::
Run
(
const
std
::
vector
<
const
Tensor
*>&
inputs
,
const
std
::
vector
<
Tensor
*>&
outputs
,
void
IpuBackend
::
Run
(
const
std
::
vector
<
const
framework
::
Tensor
*>&
inputs
,
const
std
::
vector
<
framework
::
Tensor
*>&
outputs
,
const
framework
::
ExecutionContext
&
ctx
)
{
timer_
->
Start
();
executor_
->
Run
(
inputs
,
outputs
,
ctx
);
...
...
@@ -82,7 +80,7 @@ void IpuBackend::Reset() {
executor_
.
reset
();
}
void
IpuBackend
::
SetScope
(
const
Scope
&
scope
)
{
void
IpuBackend
::
SetScope
(
const
framework
::
Scope
&
scope
)
{
scope_
=
&
scope
;
executor_
->
SetScope
(
&
scope
);
}
...
...
paddle/fluid/platform/device/ipu/ipu_backend.h
浏览文件 @
1b5647d7
...
...
@@ -18,26 +18,25 @@ limitations under the License. */
#include <popart/names.hpp>
#include <popart/tensorinfo.hpp>
#include "paddle/fluid/framework/
operator
.h"
#include "paddle/fluid/framework/
ir/graph
.h"
#include "paddle/fluid/framework/scope.h"
#include "paddle/fluid/framework/tensor.h"
#include "paddle/fluid/platform/device/ipu/ipu_compiler.h"
#include "paddle/fluid/platform/device/ipu/ipu_device.h"
#include "paddle/fluid/platform/device/ipu/ipu_executor.h"
#include "paddle/fluid/platform/device/ipu/ipu_strategy.h"
#include "paddle/fluid/platform/device/ipu/ipu_utils.h"
#include "paddle/fluid/platform/enforce.h"
#include "paddle/fluid/platform/timer.h"
namespace
paddle
{
namespace
framework
{
class
ExecutionContext
;
}
// namespace framework
}
// namespace paddle
namespace
paddle
{
namespace
platform
{
namespace
ipu
{
// IpuBackend is the center of paddle-ipu, its function include:
// 1. Compile paddle model to popart model
// 2. Run popart model, inference or training
// 3. Request and release device
// 4. Other helper function
class
IpuStrategy
;
class
Compiler
;
class
Executor
;
class
IpuBackend
{
public:
static
IpuBackend
*
GetInstance
();
...
...
@@ -46,47 +45,46 @@ class IpuBackend {
IpuBackend
();
~
IpuBackend
();
// what compile does include(call compiler_):
// 1. map paddle-op -> poart op
// 2. construct popart onnx compute graph
void
Compile
(
Graph
*
graph
,
const
std
::
vector
<
std
::
string
>
&
feed_list
,
// What compile method does:
// Convert paddle ops to popart ops;
// Construct a popart graph, which is a onnx compute graph;
// Load the graph and weights to ipu.
void
Compile
(
framework
::
ir
::
Graph
*
graph
,
const
std
::
vector
<
std
::
string
>
&
feed_list
,
const
std
::
vector
<
std
::
string
>
&
fetch_list
);
// what run does include:
// 1. construct forward onnx graph
// 2. graph-level optimization
// 3. autodiff
void
Run
(
const
std
::
vector
<
const
Tensor
*>
&
inputs
,
const
std
::
vector
<
Tensor
*>
&
outputs
,
// Run the compiled graph on ipu
void
Run
(
const
std
::
vector
<
const
framework
::
Tensor
*>
&
inputs
,
const
std
::
vector
<
framework
::
Tensor
*>
&
outputs
,
const
framework
::
ExecutionContext
&
ctx
);
// Sync weights from IPU while training
void
WeightsToHost
();
//
d
etach IPU manually
//
D
etach IPU manually
void
Detach
();
//
r
eset manually
//
c
all it before destruct works
//
R
eset manually
//
C
all it before destruct works
void
Reset
();
void
SetScope
(
const
Scope
&
scope
);
const
Scope
*
GetScope
()
{
return
scope_
;
}
void
SetScope
(
const
framework
::
Scope
&
scope
);
const
framework
::
Scope
*
GetScope
()
{
return
scope_
;
}
void
SetIpuStrategy
(
const
IpuStrategy
&
strategy
);
const
IpuStrategy
*
GetIpuStrategy
()
{
return
ipu_strategy_
;
}
//
s
ave compiled model to onnx
//
S
ave compiled model to onnx
void
SaveModelProto
(
const
std
::
string
&
path
);
private:
//
n
ot own
const
Scope
*
scope_
=
nullptr
;
//
N
ot own
const
framework
::
Scope
*
scope_
=
nullptr
;
const
IpuStrategy
*
ipu_strategy_
=
nullptr
;
//
o
wn
//
O
wn
std
::
unique_ptr
<
Compiler
>
compiler_
;
std
::
unique_ptr
<
Executor
>
executor_
;
std
::
unique_ptr
<
platform
::
Timer
>
timer_
;
std
::
unique_ptr
<
Timer
>
timer_
;
bool
is_compiled_
=
false
;
...
...
paddle/fluid/platform/device/ipu/ipu_compiler.cc
浏览文件 @
1b5647d7
...
...
@@ -20,12 +20,110 @@
#include <popart/sgd.hpp>
#include "paddle/fluid/framework/ir/graph_helper.h"
#include "paddle/fluid/platform/device/ipu/ipu_names.h"
#include "paddle/fluid/platform/device/ipu/ipu_strategy.h"
#include "paddle/fluid/platform/device/ipu/ipu_utils.h"
namespace
paddle
{
namespace
platform
{
namespace
ipu
{
namespace
{
struct
CustomOpAttrVisitor
:
public
boost
::
static_visitor
<
void
>
{
CustomOpAttrVisitor
(
std
::
map
<
std
::
string
,
popart
::
any
>*
attr
,
const
std
::
string
&
attr_name
)
:
attrs_
(
attr
),
attr_name_
(
attr_name
)
{}
mutable
std
::
map
<
std
::
string
,
popart
::
any
>*
attrs_
;
std
::
string
attr_name_
;
void
operator
()(
int
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
float
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
string
&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
vector
<
int
>&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
vector
<
float
>&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
vector
<
std
::
string
>&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
bool
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
vector
<
bool
>&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
BlockDesc
*
desc
)
const
{
PADDLE_THROW
(
platform
::
errors
::
Unavailable
(
"Unsupported calling method for `BlockDesc` type when extracting "
"custom operator attributes."
));
}
void
operator
()(
const
std
::
vector
<
BlockDesc
*>&
v
)
const
{
PADDLE_THROW
(
platform
::
errors
::
Unavailable
(
"Unsupported calling method for `BlockDesc` type when extracting "
"custom operator attributes."
));
}
void
operator
()(
int64_t
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
vector
<
int64_t
>&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
vector
<
double
>&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
boost
::
blank
)
const
{
PADDLE_THROW
(
platform
::
errors
::
Unavailable
(
"Unsupported calling method for `boost::blank` type when extracting "
"custom operator attributes."
));
}
};
struct
ConstantOpAttrVisitor
:
public
boost
::
static_visitor
<
void
>
{
ConstantOpAttrVisitor
(
framework
::
LoDTensor
*
tensor
,
VarType
::
Type
dtype
)
:
tensor_
(
tensor
),
dtype_
(
dtype
)
{}
framework
::
LoDTensor
*
tensor_
;
VarType
::
Type
dtype_
;
void
operator
()(
const
std
::
vector
<
int
>&
vec
)
const
{
framework
::
TensorFromVector
<
int
>
(
vec
,
tensor_
);
}
void
operator
()(
const
std
::
vector
<
float
>&
vec
)
const
{
if
(
dtype_
==
VarType
::
FP16
)
{
std
::
vector
<
float16
>
vec_fp16
;
std
::
transform
(
vec
.
begin
(),
vec
.
end
(),
std
::
back_inserter
(
vec_fp16
),
[](
float
f
)
->
float16
{
return
float16
(
f
);
});
framework
::
TensorFromVector
<
float16
>
(
vec_fp16
,
tensor_
);
}
else
{
framework
::
TensorFromVector
<
float
>
(
vec
,
tensor_
);
}
}
void
operator
()(
const
std
::
vector
<
bool
>&
vec
)
const
{
framework
::
TensorFromVector
<
bool
>
(
vec
,
tensor_
);
}
void
operator
()(
const
std
::
vector
<
int64_t
>&
vec
)
const
{
framework
::
TensorFromVector
<
int64_t
>
(
vec
,
tensor_
);
}
void
operator
()(
const
std
::
vector
<
double
>&
vec
)
const
{
framework
::
TensorFromVector
<
double
>
(
vec
,
tensor_
);
}
#define RAISE_ERROR \
PADDLE_THROW( \
platform::errors::InvalidArgument("Constant value must be a vector"))
void
operator
()(
int
v
)
const
{
RAISE_ERROR
;
}
void
operator
()(
float
v
)
const
{
RAISE_ERROR
;
}
void
operator
()(
const
std
::
string
&
v
)
const
{
RAISE_ERROR
;
}
void
operator
()(
const
std
::
vector
<
std
::
string
>&
v
)
const
{
RAISE_ERROR
;
}
void
operator
()(
bool
v
)
const
{
RAISE_ERROR
;
}
void
operator
()(
BlockDesc
*
desc
)
const
{
RAISE_ERROR
;
}
void
operator
()(
const
std
::
vector
<
BlockDesc
*>&
v
)
const
{
RAISE_ERROR
;
}
void
operator
()(
int64_t
v
)
const
{
RAISE_ERROR
;
}
void
operator
()(
boost
::
blank
)
const
{
RAISE_ERROR
;
}
#undef RAISE_ERROR
};
popart
::
AdamMode
AdamModeFromStr
(
const
std
::
string
&
str
,
const
bool
&
use_no_bias_optimizer
)
{
if
(
str
==
"adam"
)
{
...
...
@@ -117,6 +215,34 @@ TO GetCastSigAttrAllowNull(std::string attr, OpDesc* op_desc) {
}
}
// Helper for adding namescope info
struct
NameScopeHelper
{
NameScopeHelper
(
const
OpDesc
*
op
,
popart
::
Builder
*
builder
);
~
NameScopeHelper
()
{
if
(
pushed_
)
{
builder_
->
popNameScope
();
}
}
bool
pushed_
=
false
;
popart
::
Builder
*
builder_
;
};
NameScopeHelper
::
NameScopeHelper
(
const
OpDesc
*
op
,
popart
::
Builder
*
builder
)
:
builder_
(
builder
)
{
auto
op_namescope
=
BOOST_GET_CONST
(
std
::
string
,
op
->
GetAttr
(
sOpNamescope
));
if
(
op_namescope
.
empty
()
||
op_namescope
==
"/"
)
{
return
;
}
op_namescope
.
pop_back
();
op_namescope
.
erase
(
op_namescope
.
begin
());
builder
->
pushNameScope
(
op_namescope
);
pushed_
=
true
;
}
}
// namespace
GraphHelper
::
GraphHelper
(
const
Graph
*
g
)
{
graph
=
g
;
sorted_ops
=
framework
::
ir
::
TopologySortOperations
(
*
g
);
...
...
@@ -181,14 +307,12 @@ void Compiler::RegisterOpFunc() {
auto op_type = op_desc->Type(); \
VLOG(10) << "build op:" << op_type << " args " << #Args; \
auto inputs = GetOpInputs(op_desc); \
auto output_names = GetOpOutputs(op_desc); \
auto debug_context = BuildDebugContext(op_desc); \
auto aiGraphcoreOpset = builder_->aiGraphcoreOpset1(); \
auto aiOnnxOpset = builder_->aiOnnxOpset11(); \
NameScopeHelper ns_helper(op_desc, builder_.get()); \
auto output_ids = OnnxImpl(inputs Args, debug_context); \
PostLower(output_ids, op_desc); \
InsertTensors(output_names, output_ids); \
}}, // NOLINT
#include "paddle/fluid/platform/device/ipu/supported_ops_autogen.h"
#include "paddle/fluid/platform/device/ipu/supported_ops_custom.h"
...
...
@@ -219,7 +343,7 @@ void Compiler::InitInputs(const std::vector<std::string>& feed_list) {
auto
*
node
=
graph_helper_
->
vars_name_map
[
feed_name
];
auto
*
var_desc
=
node
->
Var
();
VLOG
(
10
)
<<
"feed_name= "
<<
var_desc
->
Name
();
auto
data_type
=
VarType2PopartType
(
var_desc
->
GetDataType
());
auto
data_type
=
VarType2Popart
D
Type
(
var_desc
->
GetDataType
());
popart
::
TensorInfo
input_info
{
data_type
,
var_desc
->
GetShape
()};
VLOG
(
10
)
<<
"popart input_info = "
<<
input_info
;
popart
::
TensorId
tensor_id
=
...
...
@@ -255,8 +379,9 @@ void Compiler::LowerConstants(const Scope* scope) {
auto
shape
=
BOOST_GET_CONST
(
std
::
vector
<
int64_t
>
,
op_desc
->
GetAttr
(
"dims"
));
auto
dtype_
=
BOOST_GET_CONST
(
int
,
op_desc
->
GetAttr
(
"dtype"
));
auto
dtype
=
PopartType2VarType
(
OnnxDtype2PopartType
(
dtype_
));
auto
tensor_name
=
op_desc
->
Output
(
"__outputs__"
)[
0
];
auto
dtype
=
PopartDType2VarType
(
OnnxDType2PopartType
(
static_cast
<
ONNXDataType
>
(
dtype_
)));
auto
tensor_name
=
GetOpOutputs
(
op_desc
).
front
();
auto
*
var
=
kid_scope
.
Var
(
tensor_name
);
VLOG
(
10
)
<<
"lowering constant: "
<<
tensor_name
;
auto
*
tensor
=
var
->
GetMutable
<
framework
::
LoDTensor
>
();
...
...
@@ -267,7 +392,7 @@ void Compiler::LowerConstants(const Scope* scope) {
tensor
->
Resize
(
ddim
);
auto
const_data
=
std
::
unique_ptr
<
popart
::
ConstVoidData
>
();
popart
::
TensorInfo
tensor_info
(
P
dDataType2Popart
Type
(
tensor
->
dtype
()),
popart
::
TensorInfo
tensor_info
(
P
hiDType2PopartD
Type
(
tensor
->
dtype
()),
shape
);
const_data
.
reset
(
new
popart
::
ConstVoidData
(
tensor
->
data
(),
tensor_info
));
NameScopeHelper
ns_helper
(
op_desc
,
builder_
.
get
());
...
...
@@ -303,7 +428,7 @@ void Compiler::LowerWeights(const Scope* scope) {
var
,
platform
::
errors
::
NotFound
(
"Tensor %s is not found in the scope"
,
var_name
));
auto
tensor
=
var
->
Get
<
framework
::
LoDTensor
>
();
auto
dtype
=
P
dDataType2Popart
Type
(
tensor
.
dtype
());
auto
dtype
=
P
hiDType2PopartD
Type
(
tensor
.
dtype
());
auto
shape
=
std
::
vector
<
int64_t
>
();
for
(
size_t
i
=
0
;
i
<
tensor
.
dims
().
size
();
++
i
)
{
shape
.
push_back
(
tensor
.
dims
().
at
(
i
));
...
...
@@ -336,11 +461,9 @@ void Compiler::LowerBody() {
// pass
}
else
if
(
op_type
==
"popart_checkpointoutput"
)
{
auto
inputs
=
GetOpInputs
(
op_desc
);
auto
outputs
=
GetOpOutputs
(
op_desc
);
NameScopeHelper
ns_helper
(
op_desc
,
builder_
.
get
());
auto
output_ids
=
builder_
->
checkpointOutput
(
inputs
);
PostLower
(
output_ids
,
op_desc
);
InsertTensors
(
outputs
,
output_ids
);
}
else
if
(
op_type
==
"popart_custom_op"
)
{
auto
inputs
=
GetOpInputs
(
op_desc
);
auto
outputs
=
GetOpOutputs
(
op_desc
);
...
...
@@ -359,10 +482,8 @@ void Compiler::LowerBody() {
builder_
->
customOp
(
it
->
second
.
popart_op
,
it
->
second
.
popart_op
.
version
,
inputs
,
outputs
.
size
(),
attributes
,
debug_context
);
PostLower
(
output_ids
,
op_desc
);
InsertTensors
(
outputs
,
output_ids
);
}
else
if
(
op_type
==
"popart_printtensor"
)
{
auto
inputs
=
GetOpInputs
(
op_desc
);
auto
outputs
=
GetOpOutputs
(
op_desc
);
auto
debug_context
=
BuildDebugContext
(
op_desc
);
auto
print_gradient
=
BOOST_GET_CONST
(
int64_t
,
op_desc
->
GetAttr
(
"print_gradient"
));
...
...
@@ -371,7 +492,6 @@ void Compiler::LowerBody() {
auto
output_ids
=
builder_
->
aiGraphcoreOpset1
().
printtensor
(
inputs
,
print_gradient
,
debug_context
,
title
);
PostLower
(
output_ids
,
op_desc
);
InsertTensors
(
outputs
,
output_ids
);
}
else
{
auto
itr
=
name_function_
.
find
(
op_type
);
if
(
itr
!=
name_function_
.
end
())
{
...
...
@@ -601,23 +721,6 @@ void Compiler::LowerOptimizer(const Scope* scope) {
}
}
void
Compiler
::
InsertTensors
(
const
std
::
vector
<
std
::
string
>&
output_names
,
const
std
::
vector
<
std
::
string
>&
tensor_ids
)
{
PADDLE_ENFORCE_EQ
(
output_names
.
size
(),
tensor_ids
.
size
(),
platform
::
errors
::
Fatal
(
"InsertTensors size mismatch"
));
for
(
int
i
=
0
;
i
<
tensor_ids
.
size
();
i
++
)
{
std
::
string
tensor_id
=
tensor_ids
[
i
];
resources_
->
tensors
.
emplace
(
output_names
[
i
],
tensor_ids
[
i
]);
}
}
void
Compiler
::
InsertTensors
(
const
std
::
vector
<
std
::
string
>&
output_names
,
const
std
::
string
&
tensor_id
)
{
PADDLE_ENFORCE_EQ
(
output_names
.
size
(),
1
,
platform
::
errors
::
Fatal
(
"InsertTensors size mismatch"
));
resources_
->
tensors
.
emplace
(
output_names
[
0
],
tensor_id
);
}
void
Compiler
::
PostLower
(
const
std
::
vector
<
std
::
string
>&
tensor_ids
,
const
OpDesc
*
op_desc
)
{
// Set pipline
...
...
@@ -637,13 +740,26 @@ void Compiler::PostLower(const std::vector<std::string>& tensor_ids,
<<
" for op: "
<<
op_desc
->
Type
();
}
}
// Record output tensors
auto
pd_outs
=
GetOpOutputs
(
op_desc
);
PADDLE_ENFORCE_EQ
(
pd_outs
.
size
(),
tensor_ids
.
size
(),
platform
::
errors
::
Fatal
(
"paddle and popart op have different outputs"
));
for
(
int
i
=
0
;
i
<
tensor_ids
.
size
();
++
i
)
{
resources_
->
tensors
.
emplace
(
pd_outs
[
i
],
tensor_ids
[
i
]);
}
for
(
auto
&
tensor_id
:
tensor_ids
)
{
PostLower
(
tensor_id
,
op_desc
,
true
);
}
}
void
Compiler
::
PostLower
(
const
std
::
string
&
tensor_id
,
const
OpDesc
*
op_desc
)
{
// Record output tensor
auto
pd_outs
=
GetOpOutputs
(
op_desc
);
PADDLE_ENFORCE_EQ
(
pd_outs
.
size
(),
1
,
platform
::
errors
::
Fatal
(
"paddle and popart op have different outputs"
));
resources_
->
tensors
.
emplace
(
pd_outs
[
0
],
tensor_id
);
PostLower
(
tensor_id
,
op_desc
,
false
);
}
...
...
@@ -718,13 +834,7 @@ std::string Compiler::GetFP16ModelProto() {
return
graph_transformer
.
getModelProto
();
}
std
::
string
Compiler
::
GetModelProto
()
{
if
(
ipu_strategy_
->
enable_fp16
)
{
return
GetFP16ModelProto
();
}
else
{
return
builder_
->
getModelProto
();
}
}
std
::
string
Compiler
::
GetModelProto
()
{
return
builder_
->
getModelProto
();
}
void
Compiler
::
SaveModelProto
(
const
std
::
string
&
path
)
{
builder_
->
saveModelProto
(
path
);
...
...
paddle/fluid/platform/device/ipu/ipu_compiler.h
浏览文件 @
1b5647d7
...
...
@@ -17,16 +17,15 @@
#include <popart/builder.hpp>
#include <popart/graphtransformer.hpp>
#include <popart/optimizer.hpp>
#include "paddle/fluid/framework/ir/graph.h"
#include "paddle/fluid/framework/scope.h"
#include "paddle/fluid/platform/device/ipu/ipu_names.h"
#include "paddle/fluid/platform/device/ipu/ipu_strategy.h"
#include "paddle/fluid/platform/device/ipu/ipu_utils.h"
namespace
paddle
{
namespace
platform
{
namespace
ipu
{
class
IpuStrategy
;
struct
CompilerResources
{
// popart input tensor_ids
std
::
vector
<
popart
::
TensorId
>
inputs
;
...
...
@@ -81,30 +80,6 @@ struct GraphHelper {
std
::
vector
<
int
>
sorted_vars_id
;
};
// Helper for adding namescope info
struct
NameScopeHelper
{
NameScopeHelper
(
const
OpDesc
*
op
,
popart
::
Builder
*
builder
)
:
builder_
(
builder
)
{
auto
op_namescope
=
BOOST_GET_CONST
(
std
::
string
,
op
->
GetAttr
(
sOpNamescope
));
if
(
op_namescope
.
empty
()
||
op_namescope
==
"/"
)
{
return
;
}
op_namescope
.
pop_back
();
op_namescope
.
erase
(
op_namescope
.
begin
());
builder
->
pushNameScope
(
op_namescope
);
pushed_
=
true
;
}
~
NameScopeHelper
()
{
if
(
pushed_
)
{
builder_
->
popNameScope
();
}
}
bool
pushed_
=
false
;
popart
::
Builder
*
builder_
;
};
class
Compiler
{
public:
Compiler
();
...
...
@@ -138,11 +113,6 @@ class Compiler {
const
std
::
vector
<
std
::
string
>
&
GetOpOutputs
(
const
OpDesc
*
op
);
const
std
::
string
GetNameScope
(
const
OpDesc
*
op
);
popart
::
DebugContext
BuildDebugContext
(
const
OpDesc
*
op
);
void
InsertTensors
(
const
std
::
vector
<
std
::
string
>
&
output_names
,
const
std
::
vector
<
std
::
string
>
&
tensor_ids
);
void
InsertTensors
(
const
std
::
vector
<
std
::
string
>
&
output_names
,
const
std
::
string
&
tensor_id
);
void
PostLower
(
const
std
::
vector
<
std
::
string
>
&
,
const
OpDesc
*
);
void
PostLower
(
const
std
::
string
&
,
const
OpDesc
*
);
void
PostLower
(
const
std
::
string
&
,
const
OpDesc
*
,
bool
);
...
...
paddle/fluid/platform/device/ipu/ipu_device.cc
浏览文件 @
1b5647d7
...
...
@@ -13,14 +13,17 @@ See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/fluid/platform/device/ipu/ipu_device.h"
#include <popart/devicemanager.hpp>
#include "paddle/fluid/platform/enforce.h"
namespace
paddle
{
namespace
platform
{
namespace
ipu
{
// TODO(alleng) merge with ipu_utils
static
bool
GetBoolEnv
(
std
::
string
str
)
{
namespace
{
const
bool
GetBoolEnv
(
const
std
::
string
&
str
)
{
char
*
str_val
=
getenv
(
str
.
c_str
());
if
(
str_val
==
NULL
)
{
return
false
;
...
...
@@ -32,6 +35,7 @@ static bool GetBoolEnv(std::string str) {
return
val
;
}
}
}
// namespace
int
GetNumDevices
()
{
bool
ipu_model
=
GetBoolEnv
(
"POPLAR_IPUMODEL"
);
...
...
paddle/fluid/platform/device/ipu/ipu_device.h
浏览文件 @
1b5647d7
...
...
@@ -14,7 +14,7 @@ limitations under the License. */
#pragma once
#include <
popart/devicemanager.hpp
>
#include <
vector
>
namespace
paddle
{
namespace
platform
{
...
...
paddle/fluid/platform/device/ipu/ipu_executor.cc
浏览文件 @
1b5647d7
...
...
@@ -14,12 +14,17 @@ limitations under the License. */
#include "paddle/fluid/platform/device/ipu/ipu_executor.h"
using
float16
=
paddle
::
platform
::
float16
;
#include "paddle/fluid/framework/operator.h"
#include "paddle/fluid/platform/device/ipu/ipu_compiler.h"
#include "paddle/fluid/platform/device/ipu/ipu_names.h"
#include "paddle/fluid/platform/device/ipu/ipu_strategy.h"
namespace
paddle
{
namespace
platform
{
namespace
ipu
{
namespace
{
// Get paddle prefix and popart postfix of weight states
// Format: {popart_postfix, paddle_prefix}
std
::
vector
<
std
::
pair
<
std
::
string
,
std
::
string
>>
GetOptPrePostfix
(
...
...
@@ -54,6 +59,35 @@ std::vector<std::pair<std::string, std::string>> GetOptPrePostfix(
return
pre_post_fix
;
}
class
PdIArray
final
:
public
popart
::
IArray
{
public:
explicit
PdIArray
(
const
Tensor
*
tensor
)
{
tensor_
.
ShareDataWith
(
*
tensor
);
for
(
int
i
=
0
;
i
<
tensor
->
dims
().
size
();
++
i
)
{
shape_
.
push_back
(
tensor
->
dims
().
at
(
i
));
}
}
public:
void
*
data
()
{
return
tensor_
.
data
();
}
popart
::
DataType
dataType
()
const
{
return
PhiDType2PopartDType
(
tensor_
.
dtype
());
}
std
::
size_t
rank
()
const
{
return
tensor_
.
dims
().
size
();
}
int64_t
dim
(
size_t
index
)
const
{
return
tensor_
.
dims
().
at
(
index
);
}
std
::
size_t
nelms
()
const
{
return
std
::
accumulate
(
shape_
.
begin
(),
shape_
.
end
(),
static_cast
<
int64_t
>
(
1
),
std
::
multiplies
<
int64_t
>
());
}
const
popart
::
Shape
shape
()
const
{
return
shape_
;
}
private:
Tensor
tensor_
;
std
::
vector
<
int64_t
>
shape_
;
};
}
// namespace
Executor
::~
Executor
()
{
Detach
();
session_
.
reset
();
...
...
@@ -110,15 +144,15 @@ void Executor::Run(const std::vector<const Tensor *> &inputs,
VLOG
(
10
)
<<
"enter Executor::Run"
;
// inputs
std
::
map
<
popart
::
TensorId
,
popart
::
IArray
&>
popart_inputs
;
std
::
map
<
popart
::
TensorId
,
P
addle
IArray
>
input_wrappers
;
std
::
map
<
popart
::
TensorId
,
P
d
IArray
>
input_wrappers
;
for
(
size_t
i
=
0
;
i
<
inputs
.
size
();
i
++
)
{
auto
tensor_id
=
compiler_resources_
->
inputs
[
i
];
input_wrappers
.
emplace
(
tensor_id
,
P
addle
IArray
(
inputs
[
i
]));
input_wrappers
.
emplace
(
tensor_id
,
P
d
IArray
(
inputs
[
i
]));
popart_inputs
.
emplace
(
tensor_id
,
input_wrappers
.
at
(
tensor_id
));
}
// anchors
std
::
map
<
popart
::
TensorId
,
popart
::
IArray
&>
popart_anchors
;
std
::
map
<
popart
::
TensorId
,
P
addle
IArray
>
anchor_wrappers
;
std
::
map
<
popart
::
TensorId
,
P
d
IArray
>
anchor_wrappers
;
for
(
size_t
i
=
0
;
i
<
outputs
.
size
();
i
++
)
{
auto
tensor_id
=
compiler_resources_
->
outputs
[
i
];
// get dims & dtype from session
...
...
@@ -140,10 +174,10 @@ void Executor::Run(const std::vector<const Tensor *> &inputs,
auto
*
tensor
=
outputs
[
i
];
tensor
->
Resize
(
phi
::
make_ddim
(
output_shape
));
auto
fetch_dtype
=
fetch_info
.
dataType
();
auto
paddle_type
=
PopartType2VarType
(
fetch_dtype
);
auto
paddle_type
=
Popart
D
Type2VarType
(
fetch_dtype
);
tensor
->
mutable_data
(
ctx
.
GetPlace
(),
framework
::
TransToPhiDataType
(
paddle_type
));
anchor_wrappers
.
emplace
(
tensor_id
,
P
addle
IArray
(
tensor
));
anchor_wrappers
.
emplace
(
tensor_id
,
P
d
IArray
(
tensor
));
popart_anchors
.
emplace
(
tensor_id
,
anchor_wrappers
.
at
(
tensor_id
));
}
VLOG
(
10
)
<<
"Prepared inputs/anchors"
;
...
...
@@ -203,16 +237,16 @@ void Executor::AcquireDevice() {
device_
=
popart
::
DeviceManager
::
createDeviceManager
().
acquireDeviceById
(
device_id
);
PADDLE_ENFORCE_NOT_NULL
(
device_
,
platform
::
errors
::
Unavailable
(
"Can't attach IPU in distribution, ipu_num = %d."
,
RequestIpus
(
ipu_strategy_
->
num_ipus
)));
device_
,
errors
::
Unavailable
(
"Can't attach IPU in distribution, ipu_num = %d."
,
RequestIpus
(
ipu_strategy_
->
num_ipus
)));
}
else
{
device_
=
popart
::
DeviceManager
::
createDeviceManager
().
acquireAvailableDevice
(
RequestIpus
(
ipu_strategy_
->
num_ipus
));
PADDLE_ENFORCE_NOT_NULL
(
device_
,
platform
::
errors
::
Unavailable
(
"Can't attach IPU, ipu_num = %d."
,
RequestIpus
(
ipu_strategy_
->
num_ipus
)));
PADDLE_ENFORCE_NOT_NULL
(
device_
,
errors
::
Unavailable
(
"Can't attach IPU, ipu_num = %d."
,
RequestIpus
(
ipu_strategy_
->
num_ipus
)));
}
VLOG
(
10
)
<<
"leave Executor::AcquireDevice"
;
}
...
...
@@ -260,13 +294,13 @@ void Executor::SetWeightsIO() {
void
Executor
::
ConvertWeights
(
bool
align_to_popart
)
{
for
(
auto
weight_pair
:
executor_resources_
->
weights_and_opt_state
)
{
auto
paddle_var
=
scope_
->
GetVar
(
weight_pair
.
second
);
auto
paddle_var_dtype
=
P
dDataType2Popart
Type
(
auto
paddle_var_dtype
=
P
hiDType2PopartD
Type
(
paddle_var
->
GetMutable
<
framework
::
LoDTensor
>
()
->
dtype
());
PADDLE_ENFORCE_EQ
((
paddle_var_dtype
==
popart
::
DataType
::
FLOAT
||
paddle_var_dtype
==
popart
::
DataType
::
FLOAT16
),
true
,
platform
::
errors
::
InvalidArgument
(
errors
::
InvalidArgument
(
"Currently, we only support FLOAT16 and FLOAT with "
"Paddle, but received type is %s."
,
paddle_var_dtype
));
...
...
@@ -276,7 +310,7 @@ void Executor::ConvertWeights(bool align_to_popart) {
PADDLE_ENFORCE_EQ
((
popart_var_dtype
==
popart
::
DataType
::
FLOAT
||
popart_var_dtype
==
popart
::
DataType
::
FLOAT16
),
true
,
platform
::
errors
::
InvalidArgument
(
errors
::
InvalidArgument
(
"Currently, we only support FLOAT16 and FLOAT with "
"popart, but received type is %s."
,
popart_var_dtype
));
...
...
@@ -310,8 +344,8 @@ void Executor::ConvertWeights(bool align_to_popart) {
num_elem
*
sizeof
(
float
));
}
}
else
{
PADDLE_THROW
(
platform
::
errors
::
Unimplemented
(
"Convert Paddle FLOAT16 to popart FLOAT"
));
PADDLE_THROW
(
errors
::
Unimplemented
(
"Convert Paddle FLOAT16 to popart FLOAT"
));
}
}
}
...
...
paddle/fluid/platform/device/ipu/ipu_executor.h
浏览文件 @
1b5647d7
...
...
@@ -22,17 +22,21 @@ limitations under the License. */
#include <popart/tensorinfo.hpp>
#include <popdist/popdist_poplar.hpp>
#include "paddle/fluid/framework/operator.h"
#include "paddle/fluid/framework/scope.h"
#include "paddle/fluid/platform/device/ipu/ipu_compiler.h"
#include "paddle/fluid/platform/device/ipu/ipu_names.h"
#include "paddle/fluid/platform/device/ipu/ipu_strategy.h"
#include "paddle/fluid/platform/device/ipu/ipu_utils.h"
namespace
paddle
{
namespace
framework
{
class
ExecutionContext
;
}
// namespace framework
}
// namespace paddle
namespace
paddle
{
namespace
platform
{
namespace
ipu
{
struct
CompilerResources
;
class
IpuStrategy
;
struct
ExecutorResources
{
// map<tensor_id, paddle_var_ptr>
popart
::
WeightsIO
weights_io
;
...
...
@@ -45,18 +49,18 @@ class Executor {
Executor
()
=
default
;
~
Executor
();
//
b
uild popart session
//
B
uild popart session
void
Prepare
(
const
std
::
string
&
proto
);
//
r
un popart session
//
R
un popart session
void
Run
(
const
std
::
vector
<
const
Tensor
*>
&
inputs
,
const
std
::
vector
<
Tensor
*>
&
outputs
,
const
framework
::
ExecutionContext
&
ctx
);
//
s
ync weights from popart to paddle
//
S
ync weights from popart to paddle
void
WeightsToHost
();
//
d
etach IPU
//
D
etach IPU
void
Detach
();
// Scope
...
...
@@ -83,16 +87,16 @@ class Executor {
void
WeightsToPaddle
();
private:
//
n
ot own
//
N
ot own
const
Scope
*
scope_
=
nullptr
;
const
IpuStrategy
*
ipu_strategy_
=
nullptr
;
CompilerResources
*
compiler_resources_
=
nullptr
;
//
d
eviceinfo for popart session
//
D
eviceinfo for popart session
std
::
shared_ptr
<
popart
::
DeviceInfo
>
device_
;
//
p
opart session, where graph running
//
P
opart session, where graph running
std
::
unique_ptr
<
popart
::
Session
>
session_
;
//
one OneSession means
a graph
//
A ExecutorResources corresponds to
a graph
std
::
unique_ptr
<
ExecutorResources
>
executor_resources_
;
};
...
...
paddle/fluid/platform/device/ipu/ipu_strategy.cc
浏览文件 @
1b5647d7
...
...
@@ -316,8 +316,10 @@ IpuStrategy::IpuStrategy() {
RegisterSetter
(
bool_options
,
"enable_half_partial"
,
[
&
](
bool
value
)
{
if
(
value
)
{
popart_options
.
partialsTypeMatMuls
=
"half"
;
popart_options
.
convolutionOptions
.
insert
({{
"partialsType"
,
"half"
}});
}
else
{
popart_options
.
partialsTypeMatMuls
=
"float"
;
popart_options
.
convolutionOptions
.
insert
({{
"partialsType"
,
"float"
}});
}
});
...
...
paddle/fluid/platform/device/ipu/ipu_utils.cc
浏览文件 @
1b5647d7
...
...
@@ -13,133 +13,111 @@ See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/fluid/platform/device/ipu/ipu_utils.h"
#include <cmath>
namespace
paddle
{
namespace
platform
{
namespace
ipu
{
void
*
PaddleIArray
::
data
()
{
return
tensor_
.
data
();
}
popart
::
DataType
PaddleIArray
::
dataType
()
const
{
return
PdDataType2PopartType
(
tensor_
.
dtype
());
}
std
::
size_t
PaddleIArray
::
rank
()
const
{
return
tensor_
.
dims
().
size
();
}
int64_t
PaddleIArray
::
dim
(
size_t
index
)
const
{
return
tensor_
.
dims
().
at
(
index
);
}
std
::
size_t
PaddleIArray
::
nelms
()
const
{
return
std
::
accumulate
(
shape_
.
begin
(),
shape_
.
end
(),
static_cast
<
int64_t
>
(
1
),
std
::
multiplies
<
int64_t
>
());
}
const
popart
::
Shape
PaddleIArray
::
shape
()
const
{
return
shape_
;
}
popart
::
DataType
VarType2PopartType
(
const
framework
::
proto
::
VarType
::
Type
type
)
{
const
popart
::
DataType
VarType2PopartDType
(
const
VarType
::
Type
type
)
{
switch
(
type
)
{
case
framework
::
proto
::
VarType
::
UINT8
:
case
VarType
::
UINT8
:
return
popart
::
DataType
::
UINT8
;
case
framework
::
proto
::
VarType
::
INT8
:
case
VarType
::
INT8
:
return
popart
::
DataType
::
INT8
;
case
framework
::
proto
::
VarType
::
INT16
:
case
VarType
::
INT16
:
return
popart
::
DataType
::
INT16
;
case
framework
::
proto
::
VarType
::
INT32
:
case
VarType
::
INT32
:
return
popart
::
DataType
::
INT32
;
case
framework
::
proto
::
VarType
::
INT64
:
case
VarType
::
INT64
:
return
popart
::
DataType
::
INT64
;
case
framework
::
proto
::
VarType
::
BOOL
:
case
VarType
::
BOOL
:
return
popart
::
DataType
::
BOOL
;
case
framework
::
proto
::
VarType
::
FP64
:
case
VarType
::
FP64
:
return
popart
::
DataType
::
DOUBLE
;
case
framework
::
proto
::
VarType
::
FP32
:
case
VarType
::
FP32
:
return
popart
::
DataType
::
FLOAT
;
case
framework
::
proto
::
VarType
::
FP16
:
case
VarType
::
FP16
:
return
popart
::
DataType
::
FLOAT16
;
case
framework
::
proto
::
VarType
::
BF16
:
case
VarType
::
BF16
:
return
popart
::
DataType
::
BFLOAT16
;
case
framework
::
proto
::
VarType
::
COMPLEX64
:
case
VarType
::
COMPLEX64
:
return
popart
::
DataType
::
COMPLEX64
;
case
framework
::
proto
::
VarType
::
COMPLEX128
:
case
VarType
::
COMPLEX128
:
return
popart
::
DataType
::
COMPLEX128
;
default:
PADDLE_THROW
(
p
addle
::
p
latform
::
errors
::
Unimplemented
(
"Unsupported
Paddle var
type."
));
PADDLE_THROW
(
platform
::
errors
::
Unimplemented
(
"Unsupported
VarType::Type when converting to popart data
type."
));
}
}
popart
::
DataType
PdDataType2PopartType
(
const
paddle
::
experimental
::
DataType
type
)
{
const
popart
::
DataType
PhiDType2PopartDType
(
const
phi
::
DataType
type
)
{
switch
(
type
)
{
case
p
addle
::
experimental
::
DataType
::
UINT8
:
case
p
hi
::
DataType
::
UINT8
:
return
popart
::
DataType
::
UINT8
;
case
p
addle
::
experimental
::
DataType
::
INT8
:
case
p
hi
::
DataType
::
INT8
:
return
popart
::
DataType
::
INT8
;
case
p
addle
::
experimental
::
DataType
::
INT16
:
case
p
hi
::
DataType
::
INT16
:
return
popart
::
DataType
::
INT16
;
case
p
addle
::
experimental
::
DataType
::
INT32
:
case
p
hi
::
DataType
::
INT32
:
return
popart
::
DataType
::
INT32
;
case
p
addle
::
experimental
::
DataType
::
INT64
:
case
p
hi
::
DataType
::
INT64
:
return
popart
::
DataType
::
INT64
;
case
p
addle
::
experimental
::
DataType
::
BOOL
:
case
p
hi
::
DataType
::
BOOL
:
return
popart
::
DataType
::
BOOL
;
case
p
addle
::
experimental
::
DataType
::
FLOAT64
:
case
p
hi
::
DataType
::
FLOAT64
:
return
popart
::
DataType
::
DOUBLE
;
case
p
addle
::
experimental
::
DataType
::
FLOAT32
:
case
p
hi
::
DataType
::
FLOAT32
:
return
popart
::
DataType
::
FLOAT
;
case
p
addle
::
experimental
::
DataType
::
FLOAT16
:
case
p
hi
::
DataType
::
FLOAT16
:
return
popart
::
DataType
::
FLOAT16
;
case
p
addle
::
experimental
::
DataType
::
BFLOAT16
:
case
p
hi
::
DataType
::
BFLOAT16
:
return
popart
::
DataType
::
BFLOAT16
;
case
p
addle
::
experimental
::
DataType
::
COMPLEX64
:
case
p
hi
::
DataType
::
COMPLEX64
:
return
popart
::
DataType
::
COMPLEX64
;
case
p
addle
::
experimental
::
DataType
::
COMPLEX128
:
case
p
hi
::
DataType
::
COMPLEX128
:
return
popart
::
DataType
::
COMPLEX128
;
default:
PADDLE_THROW
(
p
addle
::
p
latform
::
errors
::
Unimplemented
(
"Unsupported
Paddle
data type."
));
PADDLE_THROW
(
platform
::
errors
::
Unimplemented
(
"Unsupported
phi::DataType when converting to popart
data type."
));
}
}
framework
::
proto
::
VarType
::
Type
PopartType2VarType
(
const
popart
::
DataType
type
)
{
const
VarType
::
Type
PopartDType2VarType
(
const
popart
::
DataType
type
)
{
switch
(
type
)
{
case
popart
::
DataType
::
UINT8
:
return
framework
::
proto
::
VarType
::
UINT8
;
return
VarType
::
UINT8
;
case
popart
::
DataType
::
INT8
:
return
framework
::
proto
::
VarType
::
INT8
;
return
VarType
::
INT8
;
case
popart
::
DataType
::
INT16
:
return
framework
::
proto
::
VarType
::
INT16
;
return
VarType
::
INT16
;
case
popart
::
DataType
::
INT32
:
return
framework
::
proto
::
VarType
::
INT32
;
return
VarType
::
INT32
;
case
popart
::
DataType
::
INT64
:
return
framework
::
proto
::
VarType
::
INT64
;
return
VarType
::
INT64
;
case
popart
::
DataType
::
BOOL
:
return
framework
::
proto
::
VarType
::
BOOL
;
return
VarType
::
BOOL
;
case
popart
::
DataType
::
DOUBLE
:
return
framework
::
proto
::
VarType
::
FP64
;
return
VarType
::
FP64
;
case
popart
::
DataType
::
FLOAT
:
return
framework
::
proto
::
VarType
::
FP32
;
return
VarType
::
FP32
;
case
popart
::
DataType
::
FLOAT16
:
return
framework
::
proto
::
VarType
::
FP16
;
return
VarType
::
FP16
;
case
popart
::
DataType
::
BFLOAT16
:
return
framework
::
proto
::
VarType
::
BF16
;
return
VarType
::
BF16
;
case
popart
::
DataType
::
COMPLEX64
:
return
framework
::
proto
::
VarType
::
COMPLEX64
;
return
VarType
::
COMPLEX64
;
case
popart
::
DataType
::
COMPLEX128
:
return
framework
::
proto
::
VarType
::
COMPLEX128
;
return
VarType
::
COMPLEX128
;
default:
PADDLE_THROW
(
p
addle
::
platform
::
errors
::
Unavailable
(
"Unsupported
Paddle
var type."
));
PADDLE_THROW
(
p
latform
::
errors
::
Unimplemented
(
"Unsupported
popart::DataType when converting to
var type."
));
}
}
popart
::
DataType
OnnxDtype2PopartType
(
const
int
type
)
{
auto
dtype
=
static_cast
<
ONNXDataType
>
(
type
);
switch
(
dtype
)
{
const
popart
::
DataType
OnnxDType2PopartType
(
const
ONNXDataType
type
)
{
switch
(
type
)
{
case
ONNXDataType
::
BOOL
:
return
popart
::
DataType
::
BOOL
;
case
ONNXDataType
::
INT16
:
...
...
@@ -166,12 +144,69 @@ popart::DataType OnnxDtype2PopartType(const int type) {
return
popart
::
DataType
::
COMPLEX128
;
default:
PADDLE_THROW
(
platform
::
errors
::
Unimplemented
(
"Unsupported ONNX data type: %d."
,
dtype
));
"Unsupported ONNXDataType when converting to popart data type."
));
}
}
const
ONNXDataType
VarType2OnnxDType
(
const
VarType
::
Type
type
)
{
switch
(
type
)
{
case
VarType
::
BOOL
:
return
ONNXDataType
::
BOOL
;
case
VarType
::
INT16
:
return
ONNXDataType
::
INT16
;
case
VarType
::
INT32
:
return
ONNXDataType
::
INT32
;
case
VarType
::
INT64
:
return
ONNXDataType
::
INT64
;
case
VarType
::
FP16
:
return
ONNXDataType
::
FLOAT16
;
case
VarType
::
FP32
:
return
ONNXDataType
::
FLOAT
;
case
VarType
::
FP64
:
return
ONNXDataType
::
DOUBLE
;
case
VarType
::
UINT8
:
return
ONNXDataType
::
UINT8
;
case
VarType
::
INT8
:
return
ONNXDataType
::
INT8
;
case
VarType
::
BF16
:
return
ONNXDataType
::
BFLOAT16
;
case
VarType
::
COMPLEX64
:
return
ONNXDataType
::
COMPLEX64
;
case
VarType
::
COMPLEX128
:
return
ONNXDataType
::
COMPLEX128
;
default:
PADDLE_THROW
(
platform
::
errors
::
Unimplemented
(
"Unsupported VarType::Type when converting to onnx data type."
));
}
}
const
std
::
string
VarType2PopartStr
(
const
VarType
::
Type
type
)
{
switch
(
type
)
{
case
VarType
::
UINT8
:
return
"UINT8"
;
case
VarType
::
INT8
:
return
"INT8"
;
case
VarType
::
INT16
:
return
"INT16"
;
case
VarType
::
INT32
:
return
"INT32"
;
case
VarType
::
INT64
:
return
"INT64"
;
case
VarType
::
BOOL
:
return
"BOOL"
;
case
VarType
::
FP64
:
return
"DOUBLE"
;
case
VarType
::
FP32
:
return
"FLOAT"
;
case
VarType
::
FP16
:
return
"FLOAT16"
;
default:
PADDLE_THROW
(
platform
::
errors
::
Unavailable
(
"Unsupported VarType::Type when converting to popart type string."
));
}
}
// count num should > 0
bool
GetBoolEnv
(
std
::
string
str
)
{
const
bool
GetBoolEnv
(
const
std
::
string
&
str
)
{
char
*
str_val
=
getenv
(
str
.
c_str
());
if
(
str_val
==
NULL
)
{
return
false
;
...
...
@@ -184,8 +219,7 @@ bool GetBoolEnv(std::string str) {
}
}
int
RequestIpus
(
const
int
num_ipus
)
{
// num_ipus must be pow(2, n);
const
int
RequestIpus
(
const
int
num_ipus
)
{
return
std
::
pow
(
2
,
ceil
(
log2
(
num_ipus
)));
}
...
...
paddle/fluid/platform/device/ipu/ipu_utils.h
浏览文件 @
1b5647d7
...
...
@@ -19,155 +19,32 @@ limitations under the License. */
#include <popart/tensorinfo.hpp>
#include <popart/vendored/any.hpp>
#include "paddle/fluid/framework/convert_utils.h"
#include "paddle/fluid/framework/ir/graph.h"
#include "paddle/fluid/framework/lod_tensor.h"
#include "paddle/fluid/framework/scope.h"
#include "paddle/fluid/framework/tensor_util.h"
#include "paddle/fluid/platform/float16.h"
using
float16
=
paddle
::
platform
::
float16
;
using
Tensor
=
paddle
::
framework
::
Tensor
;
using
LoDTensor
=
paddle
::
framework
::
LoDTensor
;
using
Scope
=
paddle
::
framework
::
Scope
;
using
OpDesc
=
paddle
::
framework
::
OpDesc
;
using
Graph
=
paddle
::
framework
::
ir
::
Graph
;
using
Node
=
paddle
::
framework
::
ir
::
Node
;
using
BlockDesc
=
paddle
::
framework
::
BlockDesc
;
using
VarType
=
paddle
::
framework
::
proto
::
VarType
;
namespace
paddle
{
namespace
platform
{
namespace
ipu
{
using
float16
=
platform
::
float16
;
using
Tensor
=
framework
::
Tensor
;
using
LoDTensor
=
framework
::
LoDTensor
;
using
Scope
=
framework
::
Scope
;
using
OpDesc
=
framework
::
OpDesc
;
using
Graph
=
framework
::
ir
::
Graph
;
using
Node
=
framework
::
ir
::
Node
;
using
BlockDesc
=
framework
::
BlockDesc
;
// onnx dtype
// https://github.com/onnx/onnx/blob/master/onnx/onnx-ml.proto3
enum
ONNXDataType
:
int
{
UNDEFINED
=
0
,
FLOAT
=
1
,
UINT8
=
2
,
INT8
=
3
,
UINT16
=
4
,
INT16
=
5
,
INT32
=
6
,
INT64
=
7
,
STRING
=
8
,
BOOL
=
9
,
FLOAT16
=
10
,
DOUBLE
=
11
,
UINT32
=
12
,
UINT64
=
13
,
COMPLEX64
=
14
,
COMPLEX128
=
15
,
BFLOAT16
=
16
};
class
PaddleIArray
final
:
public
popart
::
IArray
{
public:
explicit
PaddleIArray
(
const
Tensor
*
tensor
)
{
tensor_
.
ShareDataWith
(
*
tensor
);
for
(
int
i
=
0
;
i
<
tensor
->
dims
().
size
();
++
i
)
{
shape_
.
push_back
(
tensor
->
dims
().
at
(
i
));
}
}
public:
void
*
data
();
popart
::
DataType
dataType
()
const
;
std
::
size_t
rank
()
const
;
int64_t
dim
(
size_t
index
)
const
;
std
::
size_t
nelms
()
const
;
const
popart
::
Shape
shape
()
const
;
private:
Tensor
tensor_
;
std
::
vector
<
int64_t
>
shape_
;
};
popart
::
DataType
VarType2PopartType
(
const
framework
::
proto
::
VarType
::
Type
type
);
popart
::
DataType
PdDataType2PopartType
(
const
paddle
::
experimental
::
DataType
type
);
framework
::
proto
::
VarType
::
Type
PopartType2VarType
(
const
popart
::
DataType
type
);
popart
::
DataType
OnnxDtype2PopartType
(
const
int
type
);
bool
GetBoolEnv
(
std
::
string
str
);
template
<
typename
T
>
std
::
unique_ptr
<
popart
::
NDArrayWrapper
<
T
>>
Tensor2IArray
(
const
Tensor
&
tensor
)
{
auto
dtype
=
PdDataType2PopartType
(
tensor
.
dtype
());
auto
shape
=
std
::
vector
<
int64_t
>
();
for
(
size_t
i
=
0
;
i
<
tensor
.
dims
().
size
();
++
i
)
{
shape
.
push_back
(
tensor
.
dims
().
at
(
i
));
}
popart
::
TensorInfo
tensor_info
(
dtype
,
shape
);
return
std
::
make_unique
<
popart
::
NDArrayWrapper
<
T
>>
(
reinterpret_cast
<
T
*>
(
tensor
.
data
()),
tensor_info
);
}
template
<
typename
T
>
std
::
unique_ptr
<
popart
::
NDArrayWrapper
<
T
>>
LoDTensor2IArray
(
LoDTensor
const
&
lod_tensor
)
{
if
(
lod_tensor
.
lod
().
size
()
==
0
)
{
return
Tensor2IArray
<
T
>
(
lod_tensor
);
}
else
{
PADDLE_THROW
(
platform
::
errors
::
Unimplemented
(
"LoDTensor2IArray is Unimplemented"
));
}
}
template
<
typename
T
>
T
GetSingleVarFromScope
(
const
Scope
*
scope
,
const
std
::
string
&
var_name
)
{
auto
var
=
scope
->
GetVar
(
var_name
);
auto
tensor
=
var
->
Get
<
framework
::
LoDTensor
>
();
// check dtype is ?
return
tensor
.
data
<
T
>
()[
0
];
}
struct
CustomOpAttrVisitor
:
public
boost
::
static_visitor
<
void
>
{
explicit
CustomOpAttrVisitor
(
std
::
map
<
std
::
string
,
popart
::
any
>*
attr
,
const
std
::
string
&
attr_name
)
:
attrs_
(
attr
),
attr_name_
(
attr_name
)
{}
mutable
std
::
map
<
std
::
string
,
popart
::
any
>*
attrs_
;
std
::
string
attr_name_
;
void
operator
()(
int
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
float
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
string
&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
vector
<
int
>&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
vector
<
float
>&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
vector
<
std
::
string
>&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
bool
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
vector
<
bool
>&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
BlockDesc
*
desc
)
const
{
PADDLE_THROW
(
platform
::
errors
::
Unavailable
(
"Unsupported calling method for `BlockDesc` type."
));
}
void
operator
()(
const
std
::
vector
<
BlockDesc
*>&
v
)
const
{
PADDLE_THROW
(
platform
::
errors
::
Unavailable
(
"Unsupported calling method for `BlockDesc` type."
));
}
void
operator
()(
int64_t
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
vector
<
int64_t
>&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
const
std
::
vector
<
double
>&
v
)
const
{
attrs_
->
emplace
(
attr_name_
,
v
);
}
void
operator
()(
boost
::
blank
)
const
{
PADDLE_THROW
(
platform
::
errors
::
Unavailable
(
"Unsupported calling method for `boost::blank` type."
));
}
};
struct
IpuCustomOpIdentifier
{
IpuCustomOpIdentifier
(
const
std
::
string
&
_paddle_op
,
const
std
::
string
&
_popart_op
,
...
...
@@ -185,51 +62,44 @@ struct IpuCustomOpIdentifier {
popart
::
OperatorIdentifier
popart_op
;
};
struct
ConstantOpAttrVisitor
:
public
boost
::
static_visitor
<
void
>
{
explicit
ConstantOpAttrVisitor
(
framework
::
LoDTensor
*
tensor
,
framework
::
proto
::
VarType
::
Type
dtype
)
:
tensor_
(
tensor
),
dtype_
(
dtype
)
{}
framework
::
LoDTensor
*
tensor_
;
framework
::
proto
::
VarType
::
Type
dtype_
;
void
operator
()(
const
std
::
vector
<
int
>&
vec
)
const
{
framework
::
TensorFromVector
<
int
>
(
vec
,
tensor_
);
}
void
operator
()(
const
std
::
vector
<
float
>&
vec
)
const
{
if
(
dtype_
==
framework
::
proto
::
VarType
::
FP16
)
{
std
::
vector
<
float16
>
vec_fp16
;
std
::
transform
(
vec
.
begin
(),
vec
.
end
(),
std
::
back_inserter
(
vec_fp16
),
[](
float
f
)
->
float16
{
return
float16
(
f
);
});
framework
::
TensorFromVector
<
float16
>
(
vec_fp16
,
tensor_
);
}
else
{
framework
::
TensorFromVector
<
float
>
(
vec
,
tensor_
);
}
}
void
operator
()(
const
std
::
vector
<
bool
>&
vec
)
const
{
framework
::
TensorFromVector
<
bool
>
(
vec
,
tensor_
);
}
void
operator
()(
const
std
::
vector
<
int64_t
>&
vec
)
const
{
framework
::
TensorFromVector
<
int64_t
>
(
vec
,
tensor_
);
}
void
operator
()(
const
std
::
vector
<
double
>&
vec
)
const
{
framework
::
TensorFromVector
<
double
>
(
vec
,
tensor_
);
}
void
RaiseError
()
const
{
PADDLE_THROW
(
platform
::
errors
::
InvalidArgument
(
"Constant value must be a vector"
));
}
void
operator
()(
int
v
)
const
{
RaiseError
();
}
void
operator
()(
float
v
)
const
{
RaiseError
();
}
void
operator
()(
const
std
::
string
&
v
)
const
{
RaiseError
();
}
void
operator
()(
const
std
::
vector
<
std
::
string
>&
v
)
const
{
RaiseError
();
}
void
operator
()(
bool
v
)
const
{
RaiseError
();
}
void
operator
()(
BlockDesc
*
desc
)
const
{
RaiseError
();
}
void
operator
()(
const
std
::
vector
<
BlockDesc
*>&
v
)
const
{
RaiseError
();
}
void
operator
()(
int64_t
v
)
const
{
RaiseError
();
}
void
operator
()(
boost
::
blank
)
const
{
RaiseError
();
}
// Onnx dtype
// https://github.com/onnx/onnx/blob/master/onnx/onnx-ml.proto3
enum
ONNXDataType
:
int
{
UNDEFINED
=
0
,
FLOAT
=
1
,
UINT8
=
2
,
INT8
=
3
,
UINT16
=
4
,
INT16
=
5
,
INT32
=
6
,
INT64
=
7
,
STRING
=
8
,
BOOL
=
9
,
FLOAT16
=
10
,
DOUBLE
=
11
,
UINT32
=
12
,
UINT64
=
13
,
COMPLEX64
=
14
,
COMPLEX128
=
15
,
BFLOAT16
=
16
};
int
RequestIpus
(
const
int
num_ipus
);
// VarType::Type to popart::DataType
const
popart
::
DataType
VarType2PopartDType
(
const
VarType
::
Type
type
);
// phi::DataType to popart::DataType
const
popart
::
DataType
PhiDType2PopartDType
(
const
phi
::
DataType
type
);
// popart::DataType to VarType::Type
const
VarType
::
Type
PopartDType2VarType
(
const
popart
::
DataType
type
);
// ONNXDataType to popart::DataType
const
popart
::
DataType
OnnxDType2PopartType
(
const
ONNXDataType
type
);
// VarType::Type to ONNXDataType
const
ONNXDataType
VarType2OnnxDType
(
const
VarType
::
Type
type
);
// VarType::Type to String in Popart
const
std
::
string
VarType2PopartStr
(
const
VarType
::
Type
type
);
// Get bool from envirnment varaible
const
bool
GetBoolEnv
(
const
std
::
string
&
str
);
// Request number of ipus must be pow(2, n)
const
int
RequestIpus
(
const
int
num_ipus
);
}
// namespace ipu
}
// namespace platform
...
...
paddle/fluid/platform/device/ipu/popart_canonicalization/activation_ops.cc
浏览文件 @
1b5647d7
...
...
@@ -56,15 +56,15 @@ Node *gelu_handler(Graph *graph, Node *node) {
auto
sqrt2
=
CreateConst
(
graph
,
node
,
{},
{},
{{
"value"
,
std
::
vector
<
float
>
{
1.4142135623730951
}},
{
"dims"
,
std
::
vector
<
int64_t
>
{
1
}},
{
"dtype"
,
GetOutputVarD
t
ype
(
node
)}});
{
"dtype"
,
GetOutputVarD
T
ype
(
node
)}});
auto
zero_point_five
=
CreateConst
(
graph
,
node
,
{},
{},
{{
"value"
,
std
::
vector
<
float
>
{
0.5
}},
{
"dims"
,
std
::
vector
<
int64_t
>
{
1
}},
{
"dtype"
,
GetOutputVarD
t
ype
(
node
)}});
{
"dtype"
,
GetOutputVarD
T
ype
(
node
)}});
auto
one
=
CreateConst
(
graph
,
node
,
{},
{},
{{
"value"
,
std
::
vector
<
float
>
{
1
}},
{
"dims"
,
std
::
vector
<
int64_t
>
{
1
}},
{
"dtype"
,
GetOutputVarD
t
ype
(
node
)}});
{
"dtype"
,
GetOutputVarD
T
ype
(
node
)}});
auto
div
=
CreateBaseOp
(
graph
,
node
,
"popart_div"
,
{
GetInputVarNode
(
"X"
,
node
),
sqrt2
->
outputs
[
0
]},
{},
{});
...
...
paddle/fluid/platform/device/ipu/popart_canonicalization/canonicalization_utils.cc
浏览文件 @
1b5647d7
...
...
@@ -18,7 +18,6 @@ namespace paddle {
namespace
platform
{
namespace
ipu
{
// This avoids the static initialisation order fiasco,
std
::
unordered_map
<
std
::
string
,
SymbolHandler
>
&
SymbolHandlers
()
{
static
std
::
unordered_map
<
std
::
string
,
SymbolHandler
>
symbol_handlers
;
return
symbol_handlers
;
...
...
@@ -34,8 +33,6 @@ bool RegisterHandler(const std::string &symbol, const SymbolHandler &handler) {
return
new_handler
;
}
// Return a pointer to a handler if one is registered for this kind of node or
// an empty std::function otherwise.
SymbolHandler
GetHandler
(
const
std
::
string
&
kind
)
{
auto
it
=
SymbolHandlers
().
find
(
kind
);
if
(
it
!=
SymbolHandlers
().
end
())
{
...
...
@@ -84,66 +81,6 @@ void CopyOpAttr(const std::string &attr_name, OpDesc *op, OpDesc *new_op,
}
}
const
int
VarType2OnnxDtype
(
const
int
type
)
{
auto
dtype
=
static_cast
<
framework
::
proto
::
VarType
::
Type
>
(
type
);
switch
(
dtype
)
{
case
framework
::
proto
::
VarType
::
BOOL
:
return
static_cast
<
int
>
(
ONNXDataType
::
BOOL
);
case
framework
::
proto
::
VarType
::
INT16
:
return
static_cast
<
int
>
(
ONNXDataType
::
INT16
);
case
framework
::
proto
::
VarType
::
INT32
:
return
static_cast
<
int
>
(
ONNXDataType
::
INT32
);
case
framework
::
proto
::
VarType
::
INT64
:
return
static_cast
<
int
>
(
ONNXDataType
::
INT64
);
case
framework
::
proto
::
VarType
::
FP16
:
return
static_cast
<
int
>
(
ONNXDataType
::
FLOAT16
);
case
framework
::
proto
::
VarType
::
FP32
:
return
static_cast
<
int
>
(
ONNXDataType
::
FLOAT
);
case
framework
::
proto
::
VarType
::
FP64
:
return
static_cast
<
int
>
(
ONNXDataType
::
DOUBLE
);
case
framework
::
proto
::
VarType
::
UINT8
:
return
static_cast
<
int
>
(
ONNXDataType
::
UINT8
);
case
framework
::
proto
::
VarType
::
INT8
:
return
static_cast
<
int
>
(
ONNXDataType
::
INT8
);
case
framework
::
proto
::
VarType
::
BF16
:
return
static_cast
<
int
>
(
ONNXDataType
::
BFLOAT16
);
case
framework
::
proto
::
VarType
::
COMPLEX64
:
return
static_cast
<
int
>
(
ONNXDataType
::
COMPLEX64
);
case
framework
::
proto
::
VarType
::
COMPLEX128
:
return
static_cast
<
int
>
(
ONNXDataType
::
COMPLEX128
);
default:
PADDLE_THROW
(
platform
::
errors
::
Unimplemented
(
"Unsupported data type: %d."
,
dtype
));
}
}
const
std
::
string
VarType2PopStr
(
const
int
type
)
{
auto
dtype
=
static_cast
<
framework
::
proto
::
VarType
::
Type
>
(
type
);
switch
(
dtype
)
{
case
framework
::
proto
::
VarType
::
UINT8
:
return
"UINT8"
;
case
framework
::
proto
::
VarType
::
INT8
:
return
"INT8"
;
case
framework
::
proto
::
VarType
::
INT16
:
return
"INT16"
;
case
framework
::
proto
::
VarType
::
INT32
:
return
"INT32"
;
case
framework
::
proto
::
VarType
::
INT64
:
return
"INT64"
;
case
framework
::
proto
::
VarType
::
BOOL
:
return
"BOOL"
;
case
framework
::
proto
::
VarType
::
FP64
:
return
"DOUBLE"
;
case
framework
::
proto
::
VarType
::
FP32
:
return
"FLOAT"
;
case
framework
::
proto
::
VarType
::
FP16
:
return
"FLOAT16"
;
default:
PADDLE_THROW
(
paddle
::
platform
::
errors
::
Unavailable
(
"Unsupported data type."
));
}
}
Node
*
GetInputVarNode
(
const
std
::
string
&
input_name
,
const
Node
*
op_node
,
const
int
id
)
{
auto
var_name
=
op_node
->
Op
()
->
Input
(
input_name
).
at
(
id
);
...
...
@@ -180,7 +117,7 @@ const bool is_float_equal(float a, float b, float eps) {
return
std
::
fabs
(
a
-
b
)
<=
eps
;
}
const
int
GetOutputVarD
t
ype
(
const
Node
*
node
,
const
std
::
string
&
output_name
)
{
const
int
GetOutputVarD
T
ype
(
const
Node
*
node
,
const
std
::
string
&
output_name
)
{
auto
out_node
=
GetOutputVarNode
(
output_name
,
node
);
PADDLE_ENFORCE_NOT_NULL
(
out_node
,
platform
::
errors
::
Unavailable
(
"Node's out node does not exist."
));
...
...
@@ -188,7 +125,7 @@ const int GetOutputVarDtype(const Node *node, const std::string &output_name) {
PADDLE_ENFORCE_NOT_NULL
(
var
,
platform
::
errors
::
Unavailable
(
"Node is not a variable."
));
auto
proto_var_type
=
var
->
GetDataType
();
return
VarType2OnnxDtype
(
proto_var_type
);
return
static_cast
<
int
>
(
VarType2OnnxDType
(
proto_var_type
)
);
}
}
// namespace ipu
...
...
paddle/fluid/platform/device/ipu/popart_canonicalization/canonicalization_utils.h
浏览文件 @
1b5647d7
...
...
@@ -68,9 +68,6 @@ void ClearNode(Node *node);
void
CopyOpAttr
(
const
std
::
string
&
attr_name
,
OpDesc
*
op
,
OpDesc
*
new_op
,
bool
override
=
false
);
const
int
VarType2OnnxDtype
(
const
int
type
);
const
std
::
string
VarType2PopStr
(
const
int
type
);
Node
*
GetInputVarNode
(
const
std
::
string
&
input_name
,
const
Node
*
op_node
,
const
int
id
=
0
);
Node
*
GetOutputVarNode
(
const
std
::
string
&
output_name
,
const
Node
*
op_node
,
...
...
@@ -81,7 +78,7 @@ Node *GetOutputVarNodeByVarName(const std::string &var_name,
const
Node
*
op_node
);
const
bool
is_float_equal
(
float
a
,
float
b
,
float
eps
=
1e-8
);
const
int
GetOutputVarD
t
ype
(
const
Node
*
node
,
const
int
GetOutputVarD
T
ype
(
const
Node
*
node
,
const
std
::
string
&
output_name
=
"Out"
);
}
// namespace ipu
...
...
paddle/fluid/platform/device/ipu/popart_canonicalization/logic_ops.cc
浏览文件 @
1b5647d7
...
...
@@ -28,6 +28,14 @@ Node *equal_handler(Graph *graph, Node *node) {
return
new_node
;
}
Node
*
not_equal_handler
(
Graph
*
graph
,
Node
*
node
)
{
auto
equal_node
=
CreateBaseOp
(
graph
,
node
,
"popart_equal"
,
{
GetInputVarNode
(
"X"
,
node
),
GetInputVarNode
(
"Y"
,
node
)},
{});
return
CreateBaseOp
(
graph
,
node
,
"popart_logical_not"
,
{
equal_node
->
outputs
[
0
]},
node
->
outputs
,
{});
}
Node
*
logical_not_handler
(
Graph
*
graph
,
Node
*
node
)
{
return
CreateBaseOp
(
graph
,
node
,
"popart_logical_not"
,
{
GetInputVarNode
(
"X"
,
node
)},
...
...
@@ -64,6 +72,7 @@ Node *less_than_handler(Graph *graph, Node *node) {
}
// namespace paddle
REGISTER_HANDLER
(
equal
,
equal_handler
);
REGISTER_HANDLER
(
not_equal
,
not_equal_handler
);
REGISTER_HANDLER
(
logical_not
,
logical_not_handler
);
REGISTER_HANDLER
(
logical_or
,
logical_or_handler
);
REGISTER_HANDLER
(
logical_and
,
logical_and_handler
);
...
...
paddle/fluid/platform/device/ipu/popart_canonicalization/math_ops.cc
浏览文件 @
1b5647d7
...
...
@@ -41,7 +41,7 @@ Node *pow_handler(Graph *graph, Node *node) {
// Op(pow) -> Op(Constant)->Var(const_out)->Op(Pow)
auto
value_
=
BOOST_GET_CONST
(
float
,
op
->
GetAttr
(
"factor"
));
auto
attrs
=
MakeConstAttrMapFromValue
<
float
>
(
value_
,
{
1
},
GetOutputVarD
t
ype
(
node
));
MakeConstAttrMapFromValue
<
float
>
(
value_
,
{
1
},
GetOutputVarD
T
ype
(
node
));
auto
new_node_const
=
CreateConst
(
graph
,
node
,
{},
{},
attrs
);
return
CreateBaseOp
(
graph
,
node
,
"popart_pow"
,
{
GetInputVarNode
(
"X"
,
node
),
...
...
@@ -134,7 +134,7 @@ Node *matmul_handler(Graph *graph, Node *node) {
}
else
{
auto
o_node
=
CreateBaseOp
(
graph
,
node
,
"popart_matmul"
,
{
x_node
,
y_node
},
{});
auto
attr
=
MakeConstAttrMapFromValue
(
alpha
,
{
1
},
GetOutputVarD
t
ype
(
node
));
auto
attr
=
MakeConstAttrMapFromValue
(
alpha
,
{
1
},
GetOutputVarD
T
ype
(
node
));
auto
const_node
=
CreateConst
(
graph
,
node
,
{},
{},
attr
);
return
CreateBaseOp
(
graph
,
node
,
"popart_mul"
,
{
o_node
->
outputs
[
0
],
const_node
->
outputs
[
0
]},
...
...
@@ -299,6 +299,80 @@ Node *cross_entropy2_handler(Graph *graph, Node *node) {
}
}
Node
*
softmax_with_cross_entropy_handler
(
Graph
*
graph
,
Node
*
node
)
{
auto
*
op
=
node
->
Op
();
auto
ignoreIndex
=
BOOST_GET_CONST
(
int
,
op
->
GetAttr
(
"ignore_index"
));
auto
axis
=
BOOST_GET_CONST
(
int
,
op
->
GetAttr
(
"axis"
));
auto
soft_label
=
BOOST_GET_CONST
(
bool
,
op
->
GetAttr
(
"soft_label"
));
if
(
soft_label
)
{
PADDLE_THROW
(
platform
::
errors
::
InvalidArgument
(
"soft_label is not supported yet in IPU"
));
}
Node
*
new_cast
=
nullptr
;
if
(
GetInputVarNode
(
"Label"
,
node
)
->
Var
()
->
GetDataType
()
==
framework
::
proto
::
VarType
::
INT32
)
{
new_cast
=
GetInputVarNode
(
"Label"
,
node
);
}
else
{
auto
new_cast
=
CreateCast
(
graph
,
node
,
{
GetInputVarNode
(
"Label"
,
node
)},
{},
framework
::
proto
::
VarType
::
INT32
);
new_cast
=
new_cast
->
outputs
[
0
];
}
auto
softmax_node
=
CreateSoftmaxOpset11
(
graph
,
node
,
{
GetInputVarNode
(
"Logits"
,
node
)},
{},
axis
);
auto
label_shape_
=
GetInputVarNode
(
"Label"
,
node
)
->
Var
()
->
GetShape
();
if
(
label_shape_
[
label_shape_
.
size
()
-
1
]
!=
1
)
{
auto
log
=
CreateBaseOp
(
graph
,
node
,
"popart_log"
,
{
softmax_node
->
outputs
[
0
]},
{},
{});
// softmax_with_cross_entropy is split to several ops in python.
// reduction is not needed here.
return
CreateBaseOp
(
graph
,
node
,
"popart_nllloss_v2"
,
{
log
->
outputs
[
0
],
new_cast
},
{
GetOutputVarNode
(
"Loss"
,
node
)},
{
{
"reduction"
,
2
},
// popart::ReductionType::NoReduction
{
"ignoreIndex"
,
ignoreIndex
},
{
"inputIsLogProbability"
,
true
},
});
}
else
{
std
::
vector
<
int64_t
>
new_shape_
{
label_shape_
[
0
]};
auto
const_before_loss
=
CreateBaseOp
(
graph
,
node
,
"popart_constant"
,
{},
{},
{{
"value"
,
new_shape_
},
{
"dims"
,
std
::
vector
<
int64_t
>
{
static_cast
<
int64_t
>
(
new_shape_
.
size
())}},
{
"dtype"
,
ONNXDataType
::
INT64
}});
auto
reshape_before_loss
=
CreateBaseOp
(
graph
,
node
,
"popart_reshape"
,
{
new_cast
,
const_before_loss
->
outputs
[
0
]},
{},
{});
auto
log
=
CreateBaseOp
(
graph
,
node
,
"popart_log"
,
{
softmax_node
->
outputs
[
0
]},
{},
{});
auto
nllloss
=
CreateBaseOp
(
graph
,
node
,
"popart_nllloss_v2"
,
{
log
->
outputs
[
0
],
reshape_before_loss
->
outputs
[
0
]},
{},
{
{
"reduction"
,
2
},
// popart::ReductionType::NoReduction
{
"ignoreIndex"
,
ignoreIndex
},
{
"inputIsLogProbability"
,
true
},
});
auto
const_after_loss
=
CreateBaseOp
(
graph
,
node
,
"popart_constant"
,
{},
{},
{{
"value"
,
label_shape_
},
{
"dims"
,
std
::
vector
<
int64_t
>
{
static_cast
<
int64_t
>
(
label_shape_
.
size
())}},
{
"dtype"
,
ONNXDataType
::
INT64
}});
auto
reshape_after_loss
=
CreateBaseOp
(
graph
,
node
,
"popart_reshape"
,
{
nllloss
->
outputs
[
0
],
const_after_loss
->
outputs
[
0
]},
{
GetOutputVarNode
(
"Loss"
,
node
)},
{});
return
reshape_after_loss
;
}
}
Node
*
cumsum_handler
(
Graph
*
graph
,
Node
*
node
)
{
auto
*
op
=
node
->
Op
();
auto
exclusive
=
BOOST_GET_CONST
(
bool
,
op
->
GetAttr
(
"exclusive"
));
...
...
@@ -378,6 +452,8 @@ REGISTER_HANDLER(matmul, matmul_handler);
REGISTER_HANDLER
(
sum
,
sum_handler
);
REGISTER_HANDLER
(
softmax
,
softmax_handler
);
REGISTER_HANDLER
(
scale
,
scale_handler
);
REGISTER_HANDLER
(
softmax_with_cross_entropy
,
softmax_with_cross_entropy_handler
);
REGISTER_HANDLER
(
cross_entropy2
,
cross_entropy2_handler
);
REGISTER_HANDLER
(
cumsum
,
cumsum_handler
);
REGISTER_HANDLER
(
matmul_v2
,
matmul_v2_handler
);
...
...
paddle/fluid/platform/device/ipu/popart_canonicalization/nn_ops.cc
浏览文件 @
1b5647d7
...
...
@@ -299,7 +299,7 @@ Node *dropout_handler(Graph *graph, Node *node) {
CreateConst
(
graph
,
node
,
{},
{},
{{
"value"
,
std
::
vector
<
float
>
{
1
-
dropout_prob_
}},
{
"dims"
,
std
::
vector
<
int64_t
>
{
1
}},
{
"dtype"
,
GetOutputVarD
t
ype
(
node
)}});
{
"dtype"
,
GetOutputVarD
T
ype
(
node
)}});
return
CreateBaseOp
(
graph
,
node
,
"popart_mul"
,
{
GetInputVarNode
(
"X"
,
node
),
scale
->
outputs
[
0
]},
{
GetOutputVarNode
(
"Out"
,
node
)},
{});
...
...
paddle/fluid/platform/device/ipu/popart_canonicalization/op_builder.cc
浏览文件 @
1b5647d7
...
...
@@ -124,7 +124,7 @@ Node *CreateConst(Graph *graph, Node *node, const std::vector<Node *> &inputs,
Node
*
CreateCast
(
Graph
*
graph
,
Node
*
node
,
const
std
::
vector
<
Node
*>
&
inputs
,
const
std
::
vector
<
Node
*>
&
outputs
,
const
int
otype
)
{
auto
to
=
VarType2Pop
Str
(
otype
);
auto
to
=
VarType2Pop
artStr
(
static_cast
<
VarType
::
Type
>
(
otype
)
);
return
CreateBaseOp
(
graph
,
node
,
"popart_cast"
,
inputs
,
outputs
,
{{
"to"
,
to
}});
}
...
...
paddle/fluid/platform/device/ipu/popart_canonicalization/tensor_ops.cc
浏览文件 @
1b5647d7
...
...
@@ -23,12 +23,14 @@ namespace {
Node
*
fill_constant_handler
(
Graph
*
graph
,
Node
*
node
)
{
auto
*
op
=
node
->
Op
();
if
(
!
op
->
Input
(
"ShapeTensor"
).
empty
())
{
auto
op_inputs
=
op
->
Inputs
();
if
(
op_inputs
.
find
(
"ShapeTensor"
)
!=
op_inputs
.
end
()
&&
!
op
->
Input
(
"ShapeTensor"
).
empty
())
{
PADDLE_THROW
(
platform
::
errors
::
Unimplemented
(
"op fill_constant with ShapeTensor"
));
}
auto
dtype_
=
BOOST_GET_CONST
(
int
,
op
->
GetAttr
(
"dtype"
));
auto
dtype
=
VarType2OnnxD
type
(
dtype_
);
auto
dtype
=
VarType2OnnxD
Type
(
static_cast
<
VarType
::
Type
>
(
dtype_
)
);
auto
dims
=
BOOST_GET_CONST
(
std
::
vector
<
int64_t
>
,
op
->
GetAttr
(
"shape"
));
auto
value_
=
BOOST_GET_CONST
(
float
,
op
->
GetAttr
(
"value"
));
size_t
size
=
1
;
...
...
@@ -37,19 +39,20 @@ Node *fill_constant_handler(Graph *graph, Node *node) {
}
Attribute
value
;
switch
(
dtype_
)
{
case
framework
::
proto
::
VarType
::
FP32
:
case
VarType
::
FP16
:
case
VarType
::
FP32
:
value
=
std
::
vector
<
float
>
(
size
,
value_
);
break
;
case
framework
::
proto
::
VarType
::
FP64
:
case
VarType
::
FP64
:
value
=
std
::
vector
<
double
>
(
size
,
value_
);
break
;
case
framework
::
proto
::
VarType
::
INT32
:
case
VarType
::
INT32
:
value
=
std
::
vector
<
int
>
(
size
,
value_
);
break
;
case
framework
::
proto
::
VarType
::
INT64
:
case
VarType
::
INT64
:
value
=
std
::
vector
<
int64_t
>
(
size
,
value_
);
break
;
case
framework
::
proto
::
VarType
::
BOOL
:
case
VarType
::
BOOL
:
value
=
std
::
vector
<
bool
>
(
size
,
value_
);
break
;
default:
...
...
@@ -66,7 +69,7 @@ Node *gaussian_random_handler(Graph *graph, Node *node) {
auto
*
op
=
node
->
Op
();
auto
shape
=
BOOST_GET_CONST
(
std
::
vector
<
int64_t
>
,
op
->
GetAttr
(
"shape"
));
auto
dtype_
=
BOOST_GET_CONST
(
int
,
op
->
GetAttr
(
"dtype"
));
auto
dtype
=
VarType2OnnxD
type
(
dtype_
);
auto
dtype
=
VarType2OnnxD
Type
(
static_cast
<
VarType
::
Type
>
(
dtype_
)
);
auto
mean
=
BOOST_GET_CONST
(
float
,
op
->
GetAttr
(
"mean"
));
auto
scale
=
BOOST_GET_CONST
(
float
,
op
->
GetAttr
(
"std"
));
// seed not work
...
...
@@ -86,7 +89,7 @@ Node *uniform_random_handler(Graph *graph, Node *node) {
auto
*
op
=
node
->
Op
();
auto
shape
=
BOOST_GET_CONST
(
std
::
vector
<
int64_t
>
,
op
->
GetAttr
(
"shape"
));
auto
dtype_
=
BOOST_GET_CONST
(
int
,
op
->
GetAttr
(
"dtype"
));
auto
dtype
=
VarType2OnnxD
type
(
dtype_
);
auto
dtype
=
VarType2OnnxD
Type
(
static_cast
<
VarType
::
Type
>
(
dtype_
)
);
auto
high
=
BOOST_GET_CONST
(
float
,
op
->
GetAttr
(
"max"
));
auto
low
=
BOOST_GET_CONST
(
float
,
op
->
GetAttr
(
"min"
));
// seed not work
...
...
@@ -172,9 +175,21 @@ Node *squeeze_handler(Graph *graph, Node *node) {
Node
*
cast_handler
(
Graph
*
graph
,
Node
*
node
)
{
auto
*
op
=
node
->
Op
();
auto
otype
=
BOOST_GET_CONST
(
int
,
op
->
GetAttr
(
"out_dtype"
));
auto
new_node_cast
=
CreateCast
(
graph
,
node
,
node
->
inputs
,
node
->
outputs
,
otype
);
return
new_node_cast
;
auto
new_node
=
CreateCast
(
graph
,
node
,
node
->
inputs
,
node
->
outputs
,
otype
);
// Cast op created in mixed-precison has no pipline attrs
auto
&
prev_nodes
=
node
->
inputs
.
front
()
->
inputs
;
if
(
!
prev_nodes
.
empty
())
{
auto
*
prev_op
=
prev_nodes
.
front
()
->
Op
();
if
(
!
new_node
->
Op
()
->
HasAttr
(
sIpuIndexAttr
)
&&
prev_op
->
HasAttr
(
sIpuIndexAttr
))
{
CopyOpAttr
(
sIpuIndexAttr
,
prev_op
,
new_node
->
Op
());
}
if
(
!
new_node
->
Op
()
->
HasAttr
(
sIpuStageAttr
)
&&
prev_op
->
HasAttr
(
sIpuStageAttr
))
{
CopyOpAttr
(
sIpuStageAttr
,
prev_op
,
new_node
->
Op
());
}
}
return
new_node
;
}
Node
*
lookup_table_op_handler
(
Graph
*
graph
,
Node
*
node
,
...
...
@@ -192,7 +207,7 @@ Node *lookup_table_op_handler(Graph *graph, Node *node,
auto
concat_const
=
CreateConst
(
graph
,
node
,
{},
{},
{{
"value"
,
const_value_
},
{
"dims"
,
const_shape_
},
{
"dtype"
,
GetOutputVarD
t
ype
(
node
)}});
{
"dtype"
,
GetOutputVarD
T
ype
(
node
)}});
auto
axes
=
CreateConst
(
graph
,
node
,
{},
{},
{{
"value"
,
std
::
vector
<
int64_t
>
{
0
}},
{
"dims"
,
std
::
vector
<
int64_t
>
{
1
}},
...
...
@@ -397,7 +412,7 @@ Node *expand_handler(Graph *graph, Node *node) {
// cast to int64
expand_times
=
CreateCast
(
graph
,
node
,
{
GetInputVarNode
(
"ExpandTimes"
,
node
)},
{},
framework
::
proto
::
VarType
::
INT64
);
VarType
::
INT64
);
}
else
{
auto
expand_times_i32
=
BOOST_GET_CONST
(
std
::
vector
<
int
>
,
op
->
GetAttr
(
"expand_times"
));
...
...
@@ -423,27 +438,28 @@ Node *assign_handler(Graph *graph, Node *node) {
Node
*
assign_value_handler
(
Graph
*
graph
,
Node
*
node
)
{
auto
*
op
=
node
->
Op
();
auto
dtype_
=
BOOST_GET_CONST
(
int
,
op
->
GetAttr
(
"dtype"
));
auto
dtype
=
VarType2OnnxD
type
(
dtype_
);
auto
dtype
=
VarType2OnnxD
Type
(
static_cast
<
VarType
::
Type
>
(
dtype_
)
);
auto
dims_
=
BOOST_GET_CONST
(
std
::
vector
<
int
>
,
op
->
GetAttr
(
"shape"
));
std
::
vector
<
int64_t
>
dims
(
dims_
.
begin
(),
dims_
.
end
());
Attribute
values
;
std
::
string
value_name
;
switch
(
dtype_
)
{
case
framework
::
proto
::
VarType
::
BOOL
:
{
case
VarType
::
BOOL
:
{
value_name
=
"bool_values"
;
auto
vec_int
=
BOOST_GET_CONST
(
std
::
vector
<
int
>
,
op
->
GetAttr
(
value_name
));
std
::
vector
<
bool
>
vec_bool
(
vec_int
.
begin
(),
vec_int
.
end
());
values
=
vec_bool
;
}
break
;
case
framework
::
proto
::
VarType
::
INT32
:
case
VarType
::
INT32
:
value_name
=
"int32_values"
;
values
=
BOOST_GET_CONST
(
std
::
vector
<
int
>
,
op
->
GetAttr
(
value_name
));
break
;
case
framework
::
proto
::
VarType
::
FP32
:
case
VarType
::
FP16
:
case
VarType
::
FP32
:
value_name
=
"fp32_values"
;
values
=
BOOST_GET_CONST
(
std
::
vector
<
float
>
,
op
->
GetAttr
(
value_name
));
break
;
case
framework
::
proto
::
VarType
::
INT64
:
case
VarType
::
INT64
:
value_name
=
"int64_values"
;
values
=
BOOST_GET_CONST
(
std
::
vector
<
int64_t
>
,
op
->
GetAttr
(
value_name
));
break
;
...
...
@@ -463,39 +479,40 @@ Node *fill_any_like_handler(Graph *graph, Node *node) {
auto
*
op
=
node
->
Op
();
auto
value
=
BOOST_GET_CONST
(
float
,
op
->
GetAttr
(
"value"
));
auto
x_shape
=
GetInputVarNode
(
"X"
,
node
)
->
Var
()
->
GetShape
();
auto
dtype
=
BOOST_GET_CONST
(
int
,
op
->
GetAttr
(
"dtype"
));
auto
x_dtype
=
static_cast
<
framework
::
proto
::
VarType
::
Type
>
(
dtype
);
auto
dtype
_
=
BOOST_GET_CONST
(
int
,
op
->
GetAttr
(
"dtype"
));
auto
dtype
=
static_cast
<
VarType
::
Type
>
(
dtype_
);
size_t
size
=
1
;
for
(
auto
&
dim
:
x_shape
)
{
size
*=
dim
;
}
Attribute
out_value
;
switch
(
x_dtype
)
{
case
framework
::
proto
::
VarType
::
FP32
:
switch
(
dtype
)
{
case
VarType
::
FP16
:
case
VarType
::
FP32
:
out_value
=
std
::
vector
<
float
>
(
size
,
value
);
break
;
case
framework
::
proto
::
VarType
::
FP64
:
case
VarType
::
FP64
:
out_value
=
std
::
vector
<
double
>
(
size
,
value
);
break
;
case
framework
::
proto
::
VarType
::
INT32
:
case
VarType
::
INT32
:
out_value
=
std
::
vector
<
int
>
(
size
,
value
);
break
;
case
framework
::
proto
::
VarType
::
INT64
:
case
VarType
::
INT64
:
out_value
=
std
::
vector
<
int64_t
>
(
size
,
value
);
break
;
case
framework
::
proto
::
VarType
::
BOOL
:
case
VarType
::
BOOL
:
out_value
=
std
::
vector
<
int64_t
>
(
size
,
value
);
break
;
default:
PADDLE_THROW
(
platform
::
errors
::
Unimplemented
(
"fill_any_like dtype: %d"
,
x_
dtype
));
platform
::
errors
::
Unimplemented
(
"fill_any_like dtype: %d"
,
dtype
));
}
return
CreateConst
(
graph
,
node
,
node
->
inputs
,
node
->
outputs
,
AttributeMap
{
{
"value"
,
out_value
},
{
"dims"
,
x_shape
},
{
"dtype"
,
VarType2OnnxD
t
ype
(
dtype
)},
{
"dtype"
,
VarType2OnnxD
T
ype
(
dtype
)},
});
}
...
...
@@ -538,8 +555,7 @@ Node *one_hot_v2_handler(Graph *graph, Node *node) {
{
"dims"
,
std
::
vector
<
int64_t
>
{
1
}},
{
"dtype"
,
ONNXDataType
::
INT32
}});
Node
*
value_tensor
=
nullptr
;
if
(
GetOutputVarNode
(
"Out"
,
node
)
->
Var
()
->
GetDataType
()
==
framework
::
proto
::
VarType
::
FP16
)
{
if
(
GetOutputVarNode
(
"Out"
,
node
)
->
Var
()
->
GetDataType
()
==
VarType
::
FP16
)
{
value_tensor
=
CreateConst
(
graph
,
node
,
{},
{},
{{
"value"
,
std
::
vector
<
float
>
{
0
,
1
}},
{
"dims"
,
std
::
vector
<
int64_t
>
{
2
}},
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录