Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
gaoqiong
MIGraphX
Commits
59504832
Commit
59504832
authored
Oct 08, 2018
by
Paul
Browse files
Fix fusion errors
parent
dd11be6f
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
93 additions
and
83 deletions
+93
-83
src/include/migraph/check_shapes.hpp
src/include/migraph/check_shapes.hpp
+18
-5
src/targets/gpu/fuse_ops.cpp
src/targets/gpu/fuse_ops.cpp
+75
-78
No files found.
src/include/migraph/check_shapes.hpp
View file @
59504832
...
@@ -32,13 +32,20 @@ struct check_shapes
...
@@ -32,13 +32,20 @@ struct check_shapes
return
name
+
": "
;
return
name
+
": "
;
}
}
const
check_shapes
&
has
(
std
::
size_t
n
)
const
std
::
size_t
size
(
)
const
{
{
if
(
begin
==
end
)
return
0
;
assert
(
begin
!=
nullptr
);
assert
(
begin
!=
nullptr
);
assert
(
end
!=
nullptr
);
assert
(
end
!=
nullptr
);
if
(
end
-
begin
!=
n
)
return
end
-
begin
;
}
const
check_shapes
&
has
(
std
::
size_t
n
)
const
{
if
(
size
()
!=
n
)
MIGRAPH_THROW
(
prefix
()
+
"Wrong number of arguments: expected "
+
std
::
to_string
(
n
)
+
MIGRAPH_THROW
(
prefix
()
+
"Wrong number of arguments: expected "
+
std
::
to_string
(
n
)
+
" but given "
+
std
::
to_string
(
end
-
begin
));
" but given "
+
std
::
to_string
(
size
()
));
return
*
this
;
return
*
this
;
}
}
...
@@ -113,10 +120,10 @@ struct check_shapes
...
@@ -113,10 +120,10 @@ struct check_shapes
template
<
class
F
>
template
<
class
F
>
bool
same
(
F
f
)
const
bool
same
(
F
f
)
const
{
{
assert
(
begin
!=
nullptr
);
assert
(
end
!=
nullptr
);
if
(
begin
==
end
)
if
(
begin
==
end
)
return
true
;
return
true
;
assert
(
begin
!=
nullptr
);
assert
(
end
!=
nullptr
);
auto
&&
key
=
f
(
*
begin
);
auto
&&
key
=
f
(
*
begin
);
return
this
->
all_of
([
&
](
const
shape
&
s
)
{
return
f
(
s
)
==
key
;
});
return
this
->
all_of
([
&
](
const
shape
&
s
)
{
return
f
(
s
)
==
key
;
});
}
}
...
@@ -124,6 +131,8 @@ struct check_shapes
...
@@ -124,6 +131,8 @@ struct check_shapes
template
<
class
Predicate
>
template
<
class
Predicate
>
bool
all_of
(
Predicate
p
)
const
bool
all_of
(
Predicate
p
)
const
{
{
if
(
begin
==
end
)
return
true
;
assert
(
begin
!=
nullptr
);
assert
(
begin
!=
nullptr
);
assert
(
end
!=
nullptr
);
assert
(
end
!=
nullptr
);
return
std
::
all_of
(
begin
,
end
,
p
);
return
std
::
all_of
(
begin
,
end
,
p
);
...
@@ -131,6 +140,10 @@ struct check_shapes
...
@@ -131,6 +140,10 @@ struct check_shapes
const
shape
*
get
(
long
i
)
const
shape
*
get
(
long
i
)
{
{
if
(
i
>=
size
())
MIGRAPH_THROW
(
prefix
()
+
"Accessing shape out of bounds"
);
assert
(
begin
!=
nullptr
);
assert
(
end
!=
nullptr
);
if
(
i
<
0
)
if
(
i
<
0
)
return
end
-
i
;
return
end
-
i
;
return
begin
+
i
;
return
begin
+
i
;
...
...
src/targets/gpu/fuse_ops.cpp
View file @
59504832
...
@@ -74,6 +74,40 @@ struct fusion
...
@@ -74,6 +74,40 @@ struct fusion
MIGRAPH_THROW
(
"Creating operator failed"
);
MIGRAPH_THROW
(
"Creating operator failed"
);
return
result
;
return
result
;
}
}
shape
get_workspace
(
context
&
)
{
// TODO: Use zero workspace for now
std
::
size_t
ws_size
=
0
;
// int algo_count = 1;
// miopenConvFwdAlgorithm_t algo;
// miopenFusionPlanConvolutionGetAlgo(fp.get(), 1, &algo_count, &algo);
// miopenFusionPlanGetWorkSpaceSize(ctx.handle.get(), fp.get(), &ws_size, algo);
return
shape
{
shape
::
int8_type
,
{
ws_size
}};
}
void
compile
(
context
&
ctx
)
{
auto
status
=
miopenCompileFusionPlan
(
ctx
.
handle
.
get
(),
fp
.
get
());
if
(
status
!=
miopenStatusSuccess
)
MIGRAPH_THROW
(
"Compiling fusion plan failed"
);
}
argument
execute
(
context
&
ctx
,
const
fused_operator_args
&
fargs
,
const
argument
&
x
,
const
argument
&
y
)
const
{
auto
x_td
=
make_tensor
(
x
.
get_shape
());
auto
y_td
=
make_tensor
(
y
.
get_shape
());
auto
status
=
miopenExecuteFusionPlan
(
ctx
.
handle
.
get
(),
fp
.
get
(),
x_td
.
get
(),
x
.
implicit
(),
y_td
.
get
(),
y
.
implicit
(),
fargs
.
get
());
if
(
status
!=
miopenStatusSuccess
)
MIGRAPH_THROW
(
"Failed to execute fusion plan"
);
return
y
;
}
};
};
MIGRAPH_PRED_MATCHER
(
bias_shape
,
instruction_ref
ins
)
MIGRAPH_PRED_MATCHER
(
bias_shape
,
instruction_ref
ins
)
...
@@ -141,8 +175,8 @@ struct miopen_conv_bias
...
@@ -141,8 +175,8 @@ struct miopen_conv_bias
miopen_conv_bias
(
op
::
convolution
c
,
shape
input
,
shape
weights
,
shape
b
)
:
op
(
c
),
f
(
input
)
miopen_conv_bias
(
op
::
convolution
c
,
shape
input
,
shape
weights
,
shape
b
)
:
op
(
c
),
f
(
input
)
{
{
f
.
create_conv
(
op
,
weights
);
conv
=
f
.
create_conv
(
op
,
weights
);
f
.
create_bias
(
b
);
bias
=
f
.
create_bias
(
b
);
}
}
std
::
string
name
()
const
{
return
"gpu::conv_bias"
;
}
std
::
string
name
()
const
{
return
"gpu::conv_bias"
;
}
...
@@ -153,35 +187,19 @@ struct miopen_conv_bias
...
@@ -153,35 +187,19 @@ struct miopen_conv_bias
return
op
.
compute_shape
({
inputs
.
at
(
0
),
inputs
.
at
(
1
)});
return
op
.
compute_shape
({
inputs
.
at
(
0
),
inputs
.
at
(
1
)});
}
}
argument
argument
compute
(
context
&
ctx
,
const
shape
&
output_shape
,
const
std
::
vector
<
argument
>&
args
)
const
compute
(
context
&
ctx
,
const
shape
&
,
const
std
::
vector
<
argument
>&
args
)
const
{
{
auto
fargs
=
make_fused_args
();
auto
fargs
=
make_fused_args
();
float
alpha
=
1
,
beta
=
0
;
float
alpha
=
1
,
beta
=
0
;
auto
x
=
make_tensor
(
args
[
0
].
get_shape
());
auto
y
=
make_tensor
(
output_shape
);
miopenSetOpArgsConvForward
(
fargs
.
get
(),
conv
,
&
alpha
,
&
beta
,
args
[
1
].
implicit
());
miopenSetOpArgsConvForward
(
fargs
.
get
(),
conv
,
&
alpha
,
&
beta
,
args
[
1
].
implicit
());
miopenSetOpArgsBiasForward
(
fargs
.
get
(),
bias
,
&
alpha
,
&
beta
,
args
[
3
].
implicit
());
miopenSetOpArgsBiasForward
(
fargs
.
get
(),
bias
,
&
alpha
,
&
beta
,
args
[
3
].
implicit
());
miopenExecuteFusionPlan
(
ctx
.
handle
.
get
(),
return
f
.
execute
(
ctx
,
fargs
,
args
[
0
],
args
[
4
]);
f
.
get
(),
x
.
get
(),
args
[
0
].
implicit
(),
y
.
get
(),
args
[
4
].
implicit
(),
fargs
.
get
());
return
args
.
at
(
4
);
}
}
shape
compile
(
context
&
ctx
)
shape
compile
(
context
&
ctx
)
{
{
int
algo_count
=
1
;
f
.
compile
(
ctx
);
miopenConvFwdAlgorithm_t
algo
;
return
f
.
get_workspace
(
ctx
);
miopenFusionPlanConvolutionGetAlgo
(
f
.
get
(),
1
,
&
algo_count
,
&
algo
);
std
::
size_t
ws_size
=
0
;
miopenFusionPlanGetWorkSpaceSize
(
ctx
.
handle
.
get
(),
f
.
get
(),
&
ws_size
,
algo
);
auto
status
=
miopenCompileFusionPlan
(
ctx
.
handle
.
get
(),
f
.
get
());
if
(
status
!=
miopenStatusSuccess
)
MIGRAPH_THROW
(
"Compiling fusion plan failed"
);
return
shape
{
shape
::
int8_type
,
{
ws_size
}};
}
}
};
};
...
@@ -191,12 +209,13 @@ struct miopen_conv_bias_relu
...
@@ -191,12 +209,13 @@ struct miopen_conv_bias_relu
fusion
f
;
fusion
f
;
fusion
::
op_t
conv
;
fusion
::
op_t
conv
;
fusion
::
op_t
bias
;
fusion
::
op_t
bias
;
fusion
::
op_t
relu
;
miopen_conv_bias_relu
(
op
::
convolution
c
,
shape
input
,
shape
weights
,
shape
b
)
:
op
(
c
),
f
(
input
)
miopen_conv_bias_relu
(
op
::
convolution
c
,
shape
input
,
shape
weights
,
shape
b
)
:
op
(
c
),
f
(
input
)
{
{
f
.
create_conv
(
op
,
weights
);
conv
=
f
.
create_conv
(
op
,
weights
);
f
.
create_bias
(
b
);
bias
=
f
.
create_bias
(
b
);
f
.
create_relu
();
relu
=
f
.
create_relu
();
}
}
std
::
string
name
()
const
{
return
"gpu::conv_bias_relu"
;
}
std
::
string
name
()
const
{
return
"gpu::conv_bias_relu"
;
}
...
@@ -207,35 +226,20 @@ struct miopen_conv_bias_relu
...
@@ -207,35 +226,20 @@ struct miopen_conv_bias_relu
return
op
.
compute_shape
({
inputs
.
at
(
0
),
inputs
.
at
(
1
)});
return
op
.
compute_shape
({
inputs
.
at
(
0
),
inputs
.
at
(
1
)});
}
}
argument
argument
compute
(
context
&
ctx
,
const
shape
&
output_shape
,
const
std
::
vector
<
argument
>&
args
)
const
compute
(
context
&
ctx
,
const
shape
&
,
const
std
::
vector
<
argument
>&
args
)
const
{
{
auto
fargs
=
make_fused_args
();
auto
fargs
=
make_fused_args
();
float
alpha
=
1
,
beta
=
0
;
float
alpha
=
1
,
beta
=
0
;
auto
x
=
make_tensor
(
args
[
0
].
get_shape
());
auto
y
=
make_tensor
(
output_shape
);
miopenSetOpArgsConvForward
(
fargs
.
get
(),
conv
,
&
alpha
,
&
beta
,
args
[
1
].
implicit
());
miopenSetOpArgsConvForward
(
fargs
.
get
(),
conv
,
&
alpha
,
&
beta
,
args
[
1
].
implicit
());
miopenSetOpArgsBiasForward
(
fargs
.
get
(),
bias
,
&
alpha
,
&
beta
,
args
[
3
].
implicit
());
miopenSetOpArgsBiasForward
(
fargs
.
get
(),
bias
,
&
alpha
,
&
beta
,
args
[
3
].
implicit
());
miopenExecuteFusionPlan
(
ctx
.
handle
.
get
(),
miopenSetOpArgsActivForward
(
fargs
.
get
(),
relu
,
&
alpha
,
&
beta
,
0
,
0
,
0
);
f
.
get
(),
return
f
.
execute
(
ctx
,
fargs
,
args
[
0
],
args
[
4
]);
x
.
get
(),
args
[
0
].
implicit
(),
y
.
get
(),
args
[
4
].
implicit
(),
fargs
.
get
());
return
args
.
at
(
4
);
}
}
shape
compile
(
context
&
ctx
)
shape
compile
(
context
&
ctx
)
{
{
int
algo_count
=
1
;
f
.
compile
(
ctx
);
miopenConvFwdAlgorithm_t
algo
;
return
f
.
get_workspace
(
ctx
);
miopenFusionPlanConvolutionGetAlgo
(
f
.
get
(),
1
,
&
algo_count
,
&
algo
);
std
::
size_t
ws_size
=
0
;
miopenFusionPlanGetWorkSpaceSize
(
ctx
.
handle
.
get
(),
f
.
get
(),
&
ws_size
,
algo
);
auto
status
=
miopenCompileFusionPlan
(
ctx
.
handle
.
get
(),
f
.
get
());
if
(
status
!=
miopenStatusSuccess
)
MIGRAPH_THROW
(
"Compiling fusion plan failed"
);
return
shape
{
shape
::
int8_type
,
{
ws_size
}};
}
}
};
};
...
@@ -243,7 +247,27 @@ template <class... Ms>
...
@@ -243,7 +247,27 @@ template <class... Ms>
auto
conv_bias
(
Ms
...
ms
)
auto
conv_bias
(
Ms
...
ms
)
{
{
return
match
::
name
(
"gpu::add"
)(
return
match
::
name
(
"gpu::add"
)(
match
::
either_arg
(
0
,
1
)(
bias_shape
().
bind
(
"bias"
),
fusable_conv
().
bind
(
"conv"
)),
ms
...);
match
::
either_arg
(
0
,
1
)(
match
::
arg
(
0
)(
bias_shape
()).
bind
(
"bias"
),
fusable_conv
().
bind
(
"conv"
)),
ms
...);
}
template
<
class
Op
>
void
apply_conv_bias
(
context
&
ctx
,
program
&
p
,
match
::
matcher_result
r
)
{
auto
conv_ins
=
r
.
instructions
[
"conv"
];
auto
bias_ins
=
r
.
instructions
[
"bias"
];
auto
ins
=
r
.
result
;
auto
input_ins
=
conv_ins
->
inputs
().
at
(
0
);
auto
weights_ins
=
conv_ins
->
inputs
().
at
(
1
);
auto
conv_op
=
any_cast
<
miopen_convolution
>
(
conv_ins
->
get_operator
()).
op
;
auto
alloc_ins
=
ins
->
inputs
().
back
();
auto
old_ws_ins
=
conv_ins
->
inputs
().
at
(
2
);
Op
cb
{
conv_op
,
input_ins
->
get_shape
(),
weights_ins
->
get_shape
(),
bias_ins
->
get_shape
()};
// TODO: Insert ws allocation
auto
ws
=
cb
.
compile
(
ctx
);
p
.
replace_instruction
(
ins
,
cb
,
input_ins
,
weights_ins
,
old_ws_ins
,
bias_ins
,
alloc_ins
);
}
}
struct
match_conv_bias
struct
match_conv_bias
...
@@ -256,52 +280,25 @@ struct match_conv_bias
...
@@ -256,52 +280,25 @@ struct match_conv_bias
void
apply
(
program
&
p
,
match
::
matcher_result
r
)
const
void
apply
(
program
&
p
,
match
::
matcher_result
r
)
const
{
{
auto
conv_ins
=
r
.
instructions
[
"conv"
];
apply_conv_bias
<
miopen_conv_bias
>
(
*
ctx
,
p
,
r
);
auto
bias_ins
=
r
.
instructions
[
"bias"
];
auto
ins
=
r
.
result
;
auto
input_ins
=
conv_ins
->
inputs
().
at
(
0
);
auto
weights_ins
=
conv_ins
->
inputs
().
at
(
1
);
auto
conv_op
=
any_cast
<
miopen_convolution
>
(
conv_ins
->
get_operator
()).
op
;
auto
alloc_ins
=
ins
->
inputs
().
back
();
auto
old_ws_ins
=
conv_ins
->
inputs
().
at
(
2
);
miopen_conv_bias
cb
{
conv_op
,
input_ins
->
get_shape
(),
weights_ins
->
get_shape
(),
bias_ins
->
get_shape
()};
// TODO: Insert ws allocation
auto
ws
=
cb
.
compile
(
*
ctx
);
p
.
replace_instruction
(
ins
,
cb
,
input_ins
,
weights_ins
,
old_ws_ins
,
bias_ins
,
alloc_ins
);
}
}
};
};
struct
match_conv_bias_relu
struct
match_conv_bias_relu
{
{
context
*
ctx
=
nullptr
;
context
*
ctx
=
nullptr
;
auto
matcher
()
const
{
return
match
::
name
(
"gpu::relu"
)(
conv_bias
());
}
auto
matcher
()
const
{
return
match
::
name
(
"gpu::relu"
)(
match
::
arg
(
0
)(
conv_bias
())
)
;
}
void
apply
(
program
&
p
,
match
::
matcher_result
r
)
const
void
apply
(
program
&
p
,
match
::
matcher_result
r
)
const
{
{
auto
conv_ins
=
r
.
instructions
[
"conv"
];
apply_conv_bias
<
miopen_conv_bias_relu
>
(
*
ctx
,
p
,
r
);
auto
bias_ins
=
r
.
instructions
[
"bias"
];
auto
ins
=
r
.
result
;
auto
input_ins
=
conv_ins
->
inputs
().
at
(
0
);
auto
weights_ins
=
conv_ins
->
inputs
().
at
(
1
);
auto
conv_op
=
any_cast
<
miopen_convolution
>
(
conv_ins
->
get_operator
()).
op
;
auto
alloc_ins
=
ins
->
inputs
().
back
();
auto
old_ws_ins
=
conv_ins
->
inputs
().
at
(
2
);
miopen_conv_bias_relu
cbr
{
conv_op
,
input_ins
->
get_shape
(),
weights_ins
->
get_shape
(),
bias_ins
->
get_shape
()};
// TODO: Insert ws allocation
auto
ws
=
cbr
.
compile
(
*
ctx
);
p
.
replace_instruction
(
ins
,
cbr
,
input_ins
,
weights_ins
,
old_ws_ins
,
bias_ins
,
alloc_ins
);
}
}
};
};
void
fuse_ops
::
apply
(
program
&
p
)
const
void
fuse_ops
::
apply
(
program
&
p
)
const
{
{
match
::
find_matches
(
p
,
match_add_relu
{},
match_conv_bias_relu
{
ctx
},
match_conv_bias
{
ctx
});
// match::find_matches(p, match_conv_bias_relu{ctx}, match_conv_bias{ctx}, match_add_relu{});
match
::
find_matches
(
p
,
match_conv_bias
{
ctx
},
match_add_relu
{});
}
}
}
// namespace gpu
}
// namespace gpu
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment