Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
MIGraphX
Commits
f7079e51
"docs/archive_en_US/Tutorial/QuickStart.md" did not exist on "39782f1209f0855f49318b9e0fa042fdcf45ba7f"
Commit
f7079e51
authored
Apr 08, 2023
by
Paul
Browse files
Merge
parents
79eac1b8
f6e22d56
Changes
89
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
730 additions
and
65 deletions
+730
-65
doc/src/driver/compile.rst
doc/src/driver/compile.rst
+4
-0
doc/src/driver/read.rst
doc/src/driver/read.rst
+9
-1
examples/migraphx/migraphx_driver/README.md
examples/migraphx/migraphx_driver/README.md
+5
-1
src/CMakeLists.txt
src/CMakeLists.txt
+3
-0
src/common.cpp
src/common.cpp
+18
-7
src/cpp_generator.cpp
src/cpp_generator.cpp
+28
-8
src/driver/argument_parser.hpp
src/driver/argument_parser.hpp
+15
-7
src/driver/main.cpp
src/driver/main.cpp
+105
-17
src/driver/perf.cpp
src/driver/perf.cpp
+8
-19
src/driver/perf.hpp
src/driver/perf.hpp
+4
-2
src/fuse_reduce.cpp
src/fuse_reduce.cpp
+350
-0
src/include/migraphx/common.hpp
src/include/migraphx/common.hpp
+5
-0
src/include/migraphx/compile_options.hpp
src/include/migraphx/compile_options.hpp
+9
-1
src/include/migraphx/convolution.hpp
src/include/migraphx/convolution.hpp
+96
-0
src/include/migraphx/cpp_generator.hpp
src/include/migraphx/cpp_generator.hpp
+5
-0
src/include/migraphx/fuse_reduce.hpp
src/include/migraphx/fuse_reduce.hpp
+43
-0
src/include/migraphx/matcher.hpp
src/include/migraphx/matcher.hpp
+19
-1
src/include/migraphx/module.hpp
src/include/migraphx/module.hpp
+2
-0
src/include/migraphx/msgpack.hpp
src/include/migraphx/msgpack.hpp
+1
-0
src/include/migraphx/onnx.hpp
src/include/migraphx/onnx.hpp
+1
-1
No files found.
doc/src/driver/compile.rst
View file @
f7079e51
...
@@ -32,6 +32,10 @@ Disable fast math optimization
...
@@ -32,6 +32,10 @@ Disable fast math optimization
Perform an exhaustive search to find the fastest version of generated kernels for selected backend
Perform an exhaustive search to find the fastest version of generated kernels for selected backend
.. options:: --split-single-dyn-dim
Enable the split single dynamic dimension pass
.. option:: --fp16
.. option:: --fp16
Quantize for fp16
Quantize for fp16
...
...
doc/src/driver/read.rst
View file @
f7079e51
...
@@ -24,7 +24,7 @@ Load as MIGraphX JSON
...
@@ -24,7 +24,7 @@ Load as MIGraphX JSON
.. option:: --batch [unsigned int] (Default: 1)
.. option:: --batch [unsigned int] (Default: 1)
Set batch size for model
For a static model, set batch size. For a dynamic batch model, sets the batch size at runtime.
.. option:: --nhwc
.. option:: --nhwc
...
@@ -46,6 +46,14 @@ Trim instructions from the end (Default: 0)
...
@@ -46,6 +46,14 @@ Trim instructions from the end (Default: 0)
Dim of a parameter (format: "@name d1 d2 dn")
Dim of a parameter (format: "@name d1 d2 dn")
.. options:: --dyn-input-dim [std::vector<std::string>]
Set dynamic dimensions of a parameter using JSON formatting (format "@name" "dynamic_dimension_json")
.. options:: --default-dyn-dim
Set the default dynamic dimension (format {min:x, max:y, optimals:[o1,o2,...]})
.. option:: --optimize, -O
.. option:: --optimize, -O
Optimize when reading
Optimize when reading
...
...
examples/migraphx/migraphx_driver/README.md
View file @
f7079e51
...
@@ -29,7 +29,7 @@ See below for a comprehensive list of commands and option arguments, as well as
...
@@ -29,7 +29,7 @@ See below for a comprehensive list of commands and option arguments, as well as
| --tf | Load file as a tensorflow graph |
| --tf | Load file as a tensorflow graph |
| --migraphx | Load file as a migraphx graph |
| --migraphx | Load file as a migraphx graph |
| --migraphx-json | Load file as a migraphx JSON graph |
| --migraphx-json | Load file as a migraphx JSON graph |
| --batch |
Set batch size for the model
|
| --batch |
For a static model, set batch size. For a dynamic batch model, sets the batch size at runtime.
|
| --nhwc | Treat tensorflow format as nhwc |
| --nhwc | Treat tensorflow format as nhwc |
| --nchw | Treat tensorflow format as nchw |
| --nchw | Treat tensorflow format as nchw |
| --skip-unknown-operators | Skip unknown operators when parsing and continue to parse |
| --skip-unknown-operators | Skip unknown operators when parsing and continue to parse |
...
@@ -44,12 +44,16 @@ See below for a comprehensive list of commands and option arguments, as well as
...
@@ -44,12 +44,16 @@ See below for a comprehensive list of commands and option arguments, as well as
| --output
\|
-o | Output to file |
| --output
\|
-o | Output to file |
| --fill0 | Fill parameter with 0s |
| --fill0 | Fill parameter with 0s |
| --fill1 | Fill parameter with 1s |
| --fill1 | Fill parameter with 1s |
| --input-dim | Set static dimensions of a parameter |
| --dyn-input-dim | Set dynamic dimensions of a parameter |
| --default-dyn-dim | Set default dynamic dimension |
| --gpu | Compile on the gpu |
| --gpu | Compile on the gpu |
| --cpu | Compile on the cpu |
| --cpu | Compile on the cpu |
| --ref | Compile on the reference implementation |
| --ref | Compile on the reference implementation |
| --enable-offload-copy | Enable implicit offload copying |
| --enable-offload-copy | Enable implicit offload copying |
| --disable-fast-math | Disable fast math optimization |
| --disable-fast-math | Disable fast math optimization |
| --exhaustive-tune | Enable exhaustive search to find fastest kernel |
| --exhaustive-tune | Enable exhaustive search to find fastest kernel |
| --split-single-dyn-dim | Enable split_single_dyn_dim compiler pass |
| --fp16 | Quantize for fp16 |
| --fp16 | Quantize for fp16 |
| --int8 | Quantize for int8 |
| --int8 | Quantize for int8 |
| --tolerance | Tolerance for errors |
| --tolerance | Tolerance for errors |
...
...
src/CMakeLists.txt
View file @
f7079e51
...
@@ -50,6 +50,7 @@ add_library(migraphx
...
@@ -50,6 +50,7 @@ add_library(migraphx
env.cpp
env.cpp
file_buffer.cpp
file_buffer.cpp
fuse_pointwise.cpp
fuse_pointwise.cpp
fuse_reduce.cpp
generate.cpp
generate.cpp
inline_module.cpp
inline_module.cpp
insert_pad.cpp
insert_pad.cpp
...
@@ -73,6 +74,7 @@ add_library(migraphx
...
@@ -73,6 +74,7 @@ add_library(migraphx
process.cpp
process.cpp
program.cpp
program.cpp
propagate_constant.cpp
propagate_constant.cpp
promote_literals.cpp
quantization.cpp
quantization.cpp
quantize_fp16.cpp
quantize_fp16.cpp
quantize_int8.cpp
quantize_int8.cpp
...
@@ -91,6 +93,7 @@ add_library(migraphx
...
@@ -91,6 +93,7 @@ add_library(migraphx
shape.cpp
shape.cpp
simplify_algebra.cpp
simplify_algebra.cpp
simplify_reshapes.cpp
simplify_reshapes.cpp
split_single_dyn_dim.cpp
tmp_dir.cpp
tmp_dir.cpp
value.cpp
value.cpp
verify_args.cpp
verify_args.cpp
...
...
src/common.cpp
View file @
f7079e51
...
@@ -89,8 +89,8 @@ std::vector<shape::dynamic_dimension> compute_broadcasted_dyn_dims(shape s0, sha
...
@@ -89,8 +89,8 @@ std::vector<shape::dynamic_dimension> compute_broadcasted_dyn_dims(shape s0, sha
}
}
else
if
(
a
==
1
or
b
==
1
)
else
if
(
a
==
1
or
b
==
1
)
{
{
// setting opt
to 0
, may need to be changed
// setting opt
imals to empty
, may need to be changed
return
shape
::
dynamic_dimension
{
std
::
max
(
a
.
min
,
b
.
min
),
std
::
max
(
a
.
max
,
b
.
max
)
,
0
};
return
shape
::
dynamic_dimension
{
std
::
max
(
a
.
min
,
b
.
min
),
std
::
max
(
a
.
max
,
b
.
max
)};
}
}
else
else
{
{
...
@@ -148,10 +148,8 @@ shape common_shape(const std::vector<shape>& shapes)
...
@@ -148,10 +148,8 @@ shape common_shape(const std::vector<shape>& shapes)
return
{
compute_common_types
(
shapes
),
compute_common_lens
(
shapes
)};
return
{
compute_common_types
(
shapes
),
compute_common_lens
(
shapes
)};
}
}
instruction_ref
insert_common_op
(
module
&
m
,
std
::
vector
<
instruction_ref
>
instruction_ref
ins
,
insert_common_args
(
module
&
m
,
instruction_ref
ins
,
std
::
vector
<
instruction_ref
>
inputs
)
const
operation
&
op
,
std
::
vector
<
instruction_ref
>
inputs
)
{
{
if
(
std
::
any_of
(
if
(
std
::
any_of
(
inputs
.
cbegin
(),
inputs
.
cend
(),
[](
auto
input
)
{
return
input
->
get_shape
().
dynamic
();
}))
inputs
.
cbegin
(),
inputs
.
cend
(),
[](
auto
input
)
{
return
input
->
get_shape
().
dynamic
();
}))
...
@@ -210,7 +208,20 @@ instruction_ref insert_common_op(module& m,
...
@@ -210,7 +208,20 @@ instruction_ref insert_common_op(module& m,
return
input
;
return
input
;
});
});
}
}
return
m
.
insert_instruction
(
ins
,
op
,
inputs
);
return
inputs
;
}
std
::
vector
<
instruction_ref
>
add_common_args
(
module
&
m
,
std
::
vector
<
instruction_ref
>
inputs
)
{
return
insert_common_args
(
m
,
m
.
end
(),
std
::
move
(
inputs
));
}
instruction_ref
insert_common_op
(
module
&
m
,
instruction_ref
ins
,
const
operation
&
op
,
std
::
vector
<
instruction_ref
>
inputs
)
{
return
m
.
insert_instruction
(
ins
,
op
,
insert_common_args
(
m
,
ins
,
std
::
move
(
inputs
)));
}
}
instruction_ref
add_common_op
(
module
&
m
,
const
operation
&
op
,
std
::
vector
<
instruction_ref
>
inputs
)
instruction_ref
add_common_op
(
module
&
m
,
const
operation
&
op
,
std
::
vector
<
instruction_ref
>
inputs
)
...
...
src/cpp_generator.cpp
View file @
f7079e51
...
@@ -106,6 +106,13 @@ cpp_generator::function& cpp_generator::function::set_generic_types(const module
...
@@ -106,6 +106,13 @@ cpp_generator::function& cpp_generator::function::set_generic_types(const module
return
*
this
;
return
*
this
;
}
}
cpp_generator
::
function
&
cpp_generator
::
function
::
add_generic_param
(
const
std
::
string
&
pname
)
{
params
.
push_back
({
pname
,
"T"
+
pname
});
tparams
.
push_back
(
"class T"
+
pname
);
return
*
this
;
}
struct
cpp_generator_impl
struct
cpp_generator_impl
{
{
std
::
stringstream
fs
{};
std
::
stringstream
fs
{};
...
@@ -182,7 +189,8 @@ std::string cpp_generator::generate_point_op(const operation& op,
...
@@ -182,7 +189,8 @@ std::string cpp_generator::generate_point_op(const operation& op,
std
::
string
cpp_generator
::
str
()
const
{
return
impl
->
fs
.
str
();
}
std
::
string
cpp_generator
::
str
()
const
{
return
impl
->
fs
.
str
();
}
cpp_generator
::
function
cpp_generator
::
generate_module
(
const
module
&
m
)
cpp_generator
::
function
cpp_generator
::
generate_module
(
const
module
&
m
,
const
generate_module_callback
&
g
)
{
{
function
f
;
function
f
;
auto
name
=
transform_string
(
m
.
name
(),
[](
char
c
)
{
auto
name
=
transform_string
(
m
.
name
(),
[](
char
c
)
{
...
@@ -195,13 +203,7 @@ cpp_generator::function cpp_generator::generate_module(const module& m)
...
@@ -195,13 +203,7 @@ cpp_generator::function cpp_generator::generate_module(const module& m)
if
(
ins
->
name
()
==
"@literal"
)
if
(
ins
->
name
()
==
"@literal"
)
return
shape
::
cpp_type
(
ins
->
get_shape
().
type
())
+
"("
+
return
shape
::
cpp_type
(
ins
->
get_shape
().
type
())
+
"("
+
ins
->
get_literal
().
to_string
()
+
")"
;
ins
->
get_literal
().
to_string
()
+
")"
;
std
::
vector
<
std
::
string
>
args
;
auto
s
=
g
(
ins
,
names
);
std
::
transform
(
ins
->
inputs
().
begin
(),
ins
->
inputs
().
end
(),
std
::
back_inserter
(
args
),
[
&
](
auto
i
)
{
return
names
.
at
(
i
);
});
auto
s
=
this
->
generate_point_op
(
ins
->
get_operator
(),
args
);
if
(
impl
->
fresult
)
if
(
impl
->
fresult
)
return
impl
->
fresult
(
ins
->
get_shape
())
+
'('
+
s
+
')'
;
return
impl
->
fresult
(
ins
->
get_shape
())
+
'('
+
s
+
')'
;
else
else
...
@@ -210,6 +212,24 @@ cpp_generator::function cpp_generator::generate_module(const module& m)
...
@@ -210,6 +212,24 @@ cpp_generator::function cpp_generator::generate_module(const module& m)
return
f
;
return
f
;
}
}
std
::
vector
<
std
::
string
>
cpp_generator
::
to_args
(
const
std
::
vector
<
instruction_ref
>&
inputs
,
const
std
::
unordered_map
<
instruction_ref
,
std
::
string
>&
names
)
{
std
::
vector
<
std
::
string
>
args
;
std
::
transform
(
inputs
.
begin
(),
inputs
.
end
(),
std
::
back_inserter
(
args
),
[
&
](
auto
i
)
{
return
names
.
at
(
i
);
});
return
args
;
}
cpp_generator
::
function
cpp_generator
::
generate_module
(
const
module
&
m
)
{
return
this
->
generate_module
(
m
,
[
&
](
auto
ins
,
const
auto
&
names
)
{
return
this
->
generate_point_op
(
ins
->
get_operator
(),
to_args
(
ins
->
inputs
(),
names
));
});
}
std
::
string
cpp_generator
::
create_function
(
const
cpp_generator
::
function
&
f
)
std
::
string
cpp_generator
::
create_function
(
const
cpp_generator
::
function
&
f
)
{
{
impl
->
function_count
++
;
impl
->
function_count
++
;
...
...
src/driver/argument_parser.hpp
View file @
f7079e51
...
@@ -148,13 +148,21 @@ struct value_parser
...
@@ -148,13 +148,21 @@ struct value_parser
template
<
MIGRAPHX_REQUIRES
(
not
std
::
is_enum
<
T
>{}
and
not
is_multi_value
<
T
>
{})
>
template
<
MIGRAPHX_REQUIRES
(
not
std
::
is_enum
<
T
>{}
and
not
is_multi_value
<
T
>
{})
>
static
T
apply
(
const
std
::
string
&
x
)
static
T
apply
(
const
std
::
string
&
x
)
{
{
T
result
;
// handle whitespace in string
std
::
stringstream
ss
;
if
constexpr
(
std
::
is_same
<
T
,
std
::
string
>
{})
ss
.
str
(
x
);
{
ss
>>
result
;
return
x
;
if
(
ss
.
fail
())
}
throw
std
::
runtime_error
(
"Failed to parse '"
+
x
+
"' as "
+
type_name
<
T
>::
apply
());
else
return
result
;
{
T
result
;
std
::
stringstream
ss
;
ss
.
str
(
x
);
ss
>>
result
;
if
(
ss
.
fail
())
throw
std
::
runtime_error
(
"Failed to parse '"
+
x
+
"' as "
+
type_name
<
T
>::
apply
());
return
result
;
}
}
}
template
<
MIGRAPHX_REQUIRES
(
std
::
is_enum
<
T
>{}
and
not
is_multi_value
<
T
>
{})
>
template
<
MIGRAPHX_REQUIRES
(
std
::
is_enum
<
T
>{}
and
not
is_multi_value
<
T
>
{})
>
...
...
src/driver/main.cpp
View file @
f7079e51
...
@@ -33,6 +33,7 @@
...
@@ -33,6 +33,7 @@
#include <migraphx/tf.hpp>
#include <migraphx/tf.hpp>
#include <migraphx/onnx.hpp>
#include <migraphx/onnx.hpp>
#include <migraphx/stringutils.hpp>
#include <migraphx/stringutils.hpp>
#include <migraphx/convert_to_json.hpp>
#include <migraphx/load_save.hpp>
#include <migraphx/load_save.hpp>
#include <migraphx/json.hpp>
#include <migraphx/json.hpp>
#include <migraphx/version.h>
#include <migraphx/version.h>
...
@@ -68,7 +69,9 @@ struct loader
...
@@ -68,7 +69,9 @@ struct loader
bool
brief
=
false
;
bool
brief
=
false
;
std
::
string
output_type
;
std
::
string
output_type
;
std
::
string
output
;
std
::
string
output
;
std
::
string
default_dyn_dim
;
std
::
vector
<
std
::
string
>
param_dims
;
std
::
vector
<
std
::
string
>
param_dims
;
std
::
vector
<
std
::
string
>
dyn_param_dims
;
std
::
vector
<
std
::
string
>
output_names
;
std
::
vector
<
std
::
string
>
output_names
;
void
parse
(
argument_parser
&
ap
)
void
parse
(
argument_parser
&
ap
)
...
@@ -83,7 +86,11 @@ struct loader
...
@@ -83,7 +86,11 @@ struct loader
ap
(
file_type
,
{
"--tf"
},
ap
.
help
(
"Load as tensorflow"
),
ap
.
set_value
(
"tf"
));
ap
(
file_type
,
{
"--tf"
},
ap
.
help
(
"Load as tensorflow"
),
ap
.
set_value
(
"tf"
));
ap
(
file_type
,
{
"--migraphx"
},
ap
.
help
(
"Load as MIGraphX"
),
ap
.
set_value
(
"migraphx"
));
ap
(
file_type
,
{
"--migraphx"
},
ap
.
help
(
"Load as MIGraphX"
),
ap
.
set_value
(
"migraphx"
));
ap
(
file_type
,
{
"--migraphx-json"
},
ap
.
help
(
"Load as MIGraphX JSON"
),
ap
.
set_value
(
"json"
));
ap
(
file_type
,
{
"--migraphx-json"
},
ap
.
help
(
"Load as MIGraphX JSON"
),
ap
.
set_value
(
"json"
));
ap
(
batch
,
{
"--batch"
},
ap
.
help
(
"Set batch size for model"
));
ap
(
batch
,
{
"--batch"
},
ap
.
help
(
"For a static model, sets default_dim_value size (commonly batch size). For a "
"dynamic batch model, sets the batch "
"size at runtime."
));
ap
(
is_nhwc
,
{
"--nhwc"
},
ap
.
help
(
"Treat tensorflow format as nhwc"
),
ap
.
set_value
(
true
));
ap
(
is_nhwc
,
{
"--nhwc"
},
ap
.
help
(
"Treat tensorflow format as nhwc"
),
ap
.
set_value
(
true
));
ap
(
skip_unknown_operators
,
ap
(
skip_unknown_operators
,
{
"--skip-unknown-operators"
},
{
"--skip-unknown-operators"
},
...
@@ -96,7 +103,16 @@ struct loader
...
@@ -96,7 +103,16 @@ struct loader
ap
.
help
(
"Dim of a parameter (format:
\"
@name d1 d2 dn
\"
)"
),
ap
.
help
(
"Dim of a parameter (format:
\"
@name d1 d2 dn
\"
)"
),
ap
.
append
(),
ap
.
append
(),
ap
.
nargs
(
2
));
ap
.
nargs
(
2
));
ap
(
dyn_param_dims
,
{
"--dyn-input-dim"
},
ap
.
help
(
"Dynamic dimensions of a parameter (format:
\"
@name_1
\"
\"
[{min:x, max:y, "
"optimals:[o1,o2,...]}, dim2,dim3, ...]
\"
,
\"
@name_2
\"
, ... You can supply a "
"single integer value for a dimension to specify it as fixed."
),
ap
.
append
(),
ap
.
nargs
(
2
));
ap
(
default_dyn_dim
,
{
"--default-dyn-dim"
},
ap
.
help
(
"Default dynamic dimension (format:
\"
{min:x, max:y, optimals:[o1,o2]}
\"
)."
));
ap
(
output_names
,
ap
(
output_names
,
{
"--output-names"
},
{
"--output-names"
},
ap
.
help
(
"Names of node output (format:
\"
name_1 name_2 name_n
\"
)"
),
ap
.
help
(
"Names of node output (format:
\"
name_1 name_2 name_n
\"
)"
),
...
@@ -147,6 +163,40 @@ struct loader
...
@@ -147,6 +163,40 @@ struct loader
return
map_input_dims
;
return
map_input_dims
;
}
}
static
auto
parse_dyn_dims_json
(
const
std
::
string
&
dd_json
)
{
// expecting a json string like "[{min:1,max:64,optimals:[1,2,4,8]},3,224,224]"
auto
v
=
from_json_string
(
convert_to_json
(
dd_json
));
std
::
vector
<
migraphx
::
shape
::
dynamic_dimension
>
dyn_dims
;
std
::
transform
(
v
.
begin
(),
v
.
end
(),
std
::
back_inserter
(
dyn_dims
),
[
&
](
auto
x
)
{
if
(
x
.
is_object
())
return
from_value
<
migraphx
::
shape
::
dynamic_dimension
>
(
x
);
auto
d
=
x
.
template
to
<
std
::
size_t
>();
return
migraphx
::
shape
::
dynamic_dimension
{
d
,
d
};
});
return
dyn_dims
;
}
static
auto
parse_dyn_dims_map
(
const
std
::
vector
<
std
::
string
>&
param_dyn_dims
)
{
// expecting vector of strings formatted like
// {"@param_name_0", "dd_json_0", "@param_name_1", "dd_json_1", ...}
std
::
unordered_map
<
std
::
string
,
std
::
vector
<
shape
::
dynamic_dimension
>>
map_dyn_input_dims
;
std
::
string
name
=
""
;
for
(
auto
&&
x
:
param_dyn_dims
)
{
if
(
x
[
0
]
==
'@'
)
{
name
=
x
.
substr
(
1
);
}
else
{
map_dyn_input_dims
[
name
]
=
parse_dyn_dims_json
(
x
);
}
}
return
map_dyn_input_dims
;
}
static
auto
parse_output_names
(
const
std
::
vector
<
std
::
string
>&
output_names_info
)
static
auto
parse_output_names
(
const
std
::
vector
<
std
::
string
>&
output_names_info
)
{
{
std
::
vector
<
std
::
string
>
output_node_names
;
std
::
vector
<
std
::
string
>
output_node_names
;
...
@@ -158,13 +208,44 @@ struct loader
...
@@ -158,13 +208,44 @@ struct loader
return
output_node_names
;
return
output_node_names
;
}
}
tf_options
get_tf_options
()
const
{
auto
map_input_dims
=
parse_param_dims
(
param_dims
);
auto
output_node_names
=
parse_output_names
(
output_names
);
tf_options
options
;
options
.
is_nhwc
=
is_nhwc
;
options
.
batch_size
=
batch
;
options
.
map_input_dims
=
map_input_dims
;
options
.
output_node_names
=
output_node_names
;
return
options
;
}
onnx_options
get_onnx_options
()
const
{
auto
map_input_dims
=
parse_param_dims
(
param_dims
);
auto
map_dyn_input_dims
=
parse_dyn_dims_map
(
dyn_param_dims
);
onnx_options
options
;
if
(
default_dyn_dim
.
empty
())
{
options
.
default_dim_value
=
batch
;
}
else
{
auto
v
=
from_json_string
(
convert_to_json
(
default_dyn_dim
));
options
.
default_dyn_dim_value
=
from_value
<
migraphx
::
shape
::
dynamic_dimension
>
(
v
);
}
options
.
skip_unknown_operators
=
skip_unknown_operators
;
options
.
print_program_on_error
=
true
;
options
.
map_input_dims
=
map_input_dims
;
options
.
map_dyn_input_dims
=
map_dyn_input_dims
;
return
options
;
}
program
load
()
program
load
()
{
{
program
p
;
program
p
;
if
(
model
.
empty
())
if
(
model
.
empty
())
{
{
auto
map_input_dims
=
parse_param_dims
(
param_dims
);
auto
output_node_names
=
parse_output_names
(
output_names
);
if
(
file_type
.
empty
())
if
(
file_type
.
empty
())
{
{
if
(
ends_with
(
file
,
".onnx"
))
if
(
ends_with
(
file
,
".onnx"
))
...
@@ -179,16 +260,11 @@ struct loader
...
@@ -179,16 +260,11 @@ struct loader
std
::
cout
<<
"Reading: "
<<
file
<<
std
::
endl
;
std
::
cout
<<
"Reading: "
<<
file
<<
std
::
endl
;
if
(
file_type
==
"onnx"
)
if
(
file_type
==
"onnx"
)
{
{
onnx_options
options
;
p
=
parse_onnx
(
file
,
get_onnx_options
());
options
.
default_dim_value
=
batch
;
options
.
skip_unknown_operators
=
skip_unknown_operators
;
options
.
print_program_on_error
=
true
;
options
.
map_input_dims
=
map_input_dims
;
p
=
parse_onnx
(
file
,
options
);
}
}
else
if
(
file_type
==
"tf"
)
else
if
(
file_type
==
"tf"
)
{
{
p
=
parse_tf
(
file
,
tf_options
{
is_nhwc
,
batch
,
map_input_dims
,
output_node_names
}
);
p
=
parse_tf
(
file
,
get_
tf_options
()
);
}
}
else
if
(
file_type
==
"json"
)
else
if
(
file_type
==
"json"
)
{
{
...
@@ -289,14 +365,21 @@ struct program_params
...
@@ -289,14 +365,21 @@ struct program_params
ap
(
fill1
,
{
"--fill1"
},
ap
.
help
(
"Fill parameter with 1s"
),
ap
.
append
(),
ap
.
nargs
(
2
));
ap
(
fill1
,
{
"--fill1"
},
ap
.
help
(
"Fill parameter with 1s"
),
ap
.
append
(),
ap
.
nargs
(
2
));
}
}
auto
generate
(
const
program
&
p
,
const
target
&
t
,
bool
offload
)
auto
generate
(
const
program
&
p
,
const
target
&
t
,
bool
offload
,
unsigned
batch
)
{
{
parameter_map
m
;
parameter_map
m
;
auto
param_shapes
=
p
.
get_parameter_shapes
();
std
::
unordered_map
<
std
::
string
,
shape
>
static_param_shapes
;
std
::
transform
(
param_shapes
.
cbegin
(),
param_shapes
.
cend
(),
std
::
inserter
(
static_param_shapes
,
static_param_shapes
.
end
()),
[
&
](
const
auto
&
x
)
{
return
std
::
make_pair
(
x
.
first
,
x
.
second
.
to_static
(
batch
));
});
for
(
auto
&&
s
:
fill0
)
for
(
auto
&&
s
:
fill0
)
m
[
s
]
=
fill_argument
(
p
.
get
_param
eter
_shape
(
s
),
0
);
m
[
s
]
=
fill_argument
(
static
_param_shape
s
.
at
(
s
),
0
);
for
(
auto
&&
s
:
fill1
)
for
(
auto
&&
s
:
fill1
)
m
[
s
]
=
fill_argument
(
p
.
get
_param
eter
_shape
(
s
),
1
);
m
[
s
]
=
fill_argument
(
static
_param_shape
s
.
at
(
s
),
1
);
fill_param_map
(
m
,
p
,
t
,
offload
);
fill_param_map
(
m
,
static_param_shapes
,
t
,
offload
);
return
m
;
return
m
;
}
}
};
};
...
@@ -353,13 +436,18 @@ struct compiler
...
@@ -353,13 +436,18 @@ struct compiler
{
"--exhaustive-tune"
},
{
"--exhaustive-tune"
},
ap
.
help
(
"Exhastively search for best tuning parameters for kernels"
),
ap
.
help
(
"Exhastively search for best tuning parameters for kernels"
),
ap
.
set_value
(
true
));
ap
.
set_value
(
true
));
ap
(
co
.
split_single_dyn_dim
,
{
"--split-single-dyn-dim"
},
ap
.
help
(
"If there is a single non-fixed dynamic dimension in the model, then split to "
"static submodules"
),
ap
.
set_value
(
true
));
ap
(
quantize
,
{
"--fp16"
},
ap
.
help
(
"Quantize for fp16"
),
ap
.
set_value
(
precision
::
fp16
));
ap
(
quantize
,
{
"--fp16"
},
ap
.
help
(
"Quantize for fp16"
),
ap
.
set_value
(
precision
::
fp16
));
ap
(
quantize
,
{
"--int8"
},
ap
.
help
(
"Quantize for int8"
),
ap
.
set_value
(
precision
::
int8
));
ap
(
quantize
,
{
"--int8"
},
ap
.
help
(
"Quantize for int8"
),
ap
.
set_value
(
precision
::
int8
));
}
}
auto
params
(
const
program
&
p
)
auto
params
(
const
program
&
p
)
{
{
return
parameters
.
generate
(
p
,
ct
.
get_target
(),
co
.
offload_copy
);
return
parameters
.
generate
(
p
,
ct
.
get_target
(),
co
.
offload_copy
,
l
.
batch
);
}
}
program
compile
()
program
compile
()
...
@@ -432,7 +520,7 @@ struct verify : command<verify>
...
@@ -432,7 +520,7 @@ struct verify : command<verify>
std
::
cout
<<
p
<<
std
::
endl
;
std
::
cout
<<
p
<<
std
::
endl
;
auto
t
=
c
.
ct
.
get_target
();
auto
t
=
c
.
ct
.
get_target
();
auto
m
=
c
.
parameters
.
generate
(
p
,
t
,
true
);
auto
m
=
c
.
parameters
.
generate
(
p
,
t
,
true
,
c
.
l
.
batch
);
if
(
per_instruction
)
if
(
per_instruction
)
{
{
...
...
src/driver/perf.cpp
View file @
f7079e51
...
@@ -39,36 +39,25 @@ auto get_hash(const T& x)
...
@@ -39,36 +39,25 @@ auto get_hash(const T& x)
return
std
::
hash
<
T
>
{}(
x
);
return
std
::
hash
<
T
>
{}(
x
);
}
}
parameter_map
fill_param_map
(
parameter_map
&
m
,
const
program
&
p
,
const
target
&
t
,
bool
offload
)
parameter_map
fill_param_map
(
parameter_map
&
m
,
const
std
::
unordered_map
<
std
::
string
,
shape
>&
param_shapes
,
const
target
&
t
,
bool
offload
)
{
{
for
(
auto
&&
x
:
p
.
get_parameter
_shapes
()
)
for
(
auto
&&
x
:
p
aram
_shapes
)
{
{
argument
&
arg
=
m
[
x
.
first
];
argument
&
arg
=
m
[
x
.
first
];
if
(
arg
.
empty
())
if
(
arg
.
empty
())
{
assert
(
not
x
.
second
.
dynamic
());
arg
=
generate_argument
(
x
.
second
,
get_hash
(
x
.
first
));
arg
=
generate_argument
(
x
.
second
,
get_hash
(
x
.
first
));
}
if
(
not
offload
)
if
(
not
offload
)
arg
=
t
.
copy_to
(
arg
);
arg
=
t
.
copy_to
(
arg
);
}
}
return
m
;
return
m
;
}
}
parameter_map
fill_param_map
(
parameter_map
&
m
,
const
program
&
p
,
bool
gpu
)
{
for
(
auto
&&
x
:
p
.
get_parameter_shapes
())
{
argument
&
arg
=
m
[
x
.
first
];
if
(
arg
.
empty
())
arg
=
generate_argument
(
x
.
second
,
get_hash
(
x
.
first
));
#ifdef HAVE_GPU
if
(
gpu
)
arg
=
gpu
::
to_gpu
(
arg
);
#else
(
void
)
gpu
;
#endif
}
return
m
;
}
parameter_map
create_param_map
(
const
program
&
p
,
const
target
&
t
,
bool
offload
)
parameter_map
create_param_map
(
const
program
&
p
,
const
target
&
t
,
bool
offload
)
{
{
parameter_map
m
;
parameter_map
m
;
...
...
src/driver/perf.hpp
View file @
f7079e51
...
@@ -30,8 +30,10 @@ namespace migraphx {
...
@@ -30,8 +30,10 @@ namespace migraphx {
namespace
driver
{
namespace
driver
{
inline
namespace
MIGRAPHX_INLINE_NS
{
inline
namespace
MIGRAPHX_INLINE_NS
{
parameter_map
parameter_map
fill_param_map
(
parameter_map
&
m
,
fill_param_map
(
parameter_map
&
m
,
const
program
&
p
,
const
target
&
t
,
bool
offload
=
false
);
const
std
::
unordered_map
<
std
::
string
,
shape
>&
param_shapes
,
const
target
&
t
,
bool
offload
=
false
);
parameter_map
create_param_map
(
const
program
&
p
,
const
target
&
t
,
bool
offload
=
false
);
parameter_map
create_param_map
(
const
program
&
p
,
const
target
&
t
,
bool
offload
=
false
);
parameter_map
fill_param_map
(
parameter_map
&
m
,
const
program
&
p
,
bool
gpu
);
parameter_map
fill_param_map
(
parameter_map
&
m
,
const
program
&
p
,
bool
gpu
);
...
...
src/fuse_reduce.cpp
0 → 100644
View file @
f7079e51
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2022 Advanced Micro Devices, 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.
*/
#include <migraphx/fuse_reduce.hpp>
#include <migraphx/pass_manager.hpp>
#include <migraphx/dead_code_elimination.hpp>
#include <migraphx/instruction.hpp>
#include <migraphx/program.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/iterator_for.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/check_shapes.hpp>
#include <migraphx/matcher.hpp>
#include <migraphx/register_op.hpp>
#include <iterator>
#include <map>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
struct
fused_reduce
{
std
::
vector
<
std
::
int64_t
>
axes
{};
template
<
class
Self
,
class
F
>
static
auto
reflect
(
Self
&
self
,
F
f
)
{
return
pack
(
f
(
self
.
axes
,
"axes"
));
}
shape
compute_shape
(
const
std
::
vector
<
shape
>&
inputs
,
std
::
vector
<
module_ref
>
mods
)
const
{
if
(
mods
.
size
()
!=
1
)
MIGRAPHX_THROW
(
"should have one submodule."
);
auto
*
sm
=
mods
.
front
();
if
(
sm
->
get_output_shapes
().
size
()
!=
1
)
MIGRAPHX_THROW
(
"Only one output supported"
);
auto
names
=
sm
->
get_parameter_names
();
check_shapes
{
inputs
,
*
this
}.
has
(
names
.
size
()).
same_ndims
();
std
::
sort
(
names
.
begin
(),
names
.
end
());
auto
shapes
=
sm
->
get_parameter_shapes
();
// Check dimension matches for each input
if
(
not
equal
(
names
,
inputs
,
[
&
](
const
auto
&
name
,
const
auto
&
input
)
{
return
shapes
.
at
(
name
).
lens
()
==
input
.
lens
();
}))
MIGRAPHX_THROW
(
"Dimenstion does not match the submodule."
);
const
auto
&
s
=
inputs
.
at
(
0
);
auto
lens
=
s
.
lens
();
if
(
lens
!=
sm
->
get_output_shapes
().
front
().
lens
())
{
for
(
const
auto
&
axis
:
axes
)
{
lens
[
axis
]
=
1
;
}
}
return
shape
::
from_permutation
(
sm
->
get_output_shapes
().
front
().
type
(),
lens
,
find_permutation
(
inputs
));
}
std
::
string
name
()
const
{
return
"fused_reduce"
;
}
};
MIGRAPHX_REGISTER_OP
(
fused_reduce
);
static
std
::
unordered_map
<
instruction_ref
,
instruction_ref
>
get_ins_param_map
(
const
std
::
vector
<
instruction_ref
>&
inputs
,
const_module_ref
sm
)
{
std
::
unordered_map
<
instruction_ref
,
instruction_ref
>
result
;
auto
names
=
sm
->
get_parameter_names
();
std
::
sort
(
names
.
begin
(),
names
.
end
());
assert
(
names
.
size
()
==
inputs
.
size
());
std
::
transform
(
names
.
begin
(),
names
.
end
(),
inputs
.
begin
(),
std
::
inserter
(
result
,
result
.
end
()),
[
&
](
const
auto
&
name
,
auto
input
)
{
return
std
::
make_pair
(
input
,
sm
->
get_parameter
(
name
));
});
return
result
;
}
static
void
insert_params
(
module_ref
sm
,
instruction_ref
ins
,
std
::
unordered_map
<
instruction_ref
,
instruction_ref
>&
map_ins
)
{
auto
n
=
sm
->
get_parameter_shapes
().
size
();
for
(
auto
input
:
ins
->
inputs
())
{
if
(
contains
(
map_ins
,
input
))
continue
;
auto
s
=
shape
{
input
->
get_shape
().
type
(),
input
->
get_shape
().
lens
()};
map_ins
[
input
]
=
sm
->
add_parameter
(
"x"
+
std
::
to_string
(
n
++
),
s
);
}
}
static
auto
insert_ins_in_submodule
(
module_ref
sm
,
instruction_ref
ins
,
std
::
unordered_map
<
instruction_ref
,
instruction_ref
>&
map_ins
)
{
insert_params
(
sm
,
ins
,
map_ins
);
return
sm
->
add_instructions
({
ins
},
map_ins
);
}
static
auto
insert_ins_in_submodule
(
module_ref
sm
,
instruction_ref
ins
)
{
std
::
unordered_map
<
instruction_ref
,
instruction_ref
>
map_ins
;
return
insert_ins_in_submodule
(
sm
,
ins
,
map_ins
);
}
static
auto
insert_module_in_submodule
(
module_ref
sm
,
instruction_ref
ins
,
std
::
unordered_map
<
instruction_ref
,
instruction_ref
>&
map_ins
)
{
insert_params
(
sm
,
ins
,
map_ins
);
auto
*
m
=
ins
->
module_inputs
().
front
();
auto
param_map
=
get_ins_param_map
(
ins
->
inputs
(),
m
);
for
(
auto
&&
[
input
,
param
]
:
param_map
)
{
map_ins
[
param
]
=
map_ins
.
at
(
input
);
}
return
sm
->
add_instructions
(
m
,
map_ins
);
}
static
std
::
vector
<
instruction_ref
>
find_inputs
(
module_ref
sm
,
const
module
&
parent
,
const
std
::
unordered_map
<
instruction_ref
,
instruction_ref
>&
map_ins
)
{
std
::
vector
<
instruction_ref
>
result
;
std
::
map
<
std
::
string
,
instruction_ref
>
names
;
for
(
auto
&&
[
input
,
param
]
:
map_ins
)
{
if
(
not
sm
->
has_instruction
(
param
))
continue
;
if
(
param
->
name
()
!=
"@param"
)
continue
;
if
(
not
parent
.
has_instruction
(
input
))
continue
;
auto
v
=
param
->
get_operator
().
to_value
();
auto
name
=
v
.
at
(
"parameter"
).
to
<
std
::
string
>
();
names
[
name
]
=
input
;
}
std
::
transform
(
names
.
begin
(),
names
.
end
(),
std
::
back_inserter
(
result
),
[](
const
auto
&
p
)
{
return
p
.
second
;
});
assert
(
result
.
size
()
==
sm
->
get_parameter_shapes
().
size
());
return
result
;
}
static
void
create_reduce_modules
(
module_pass_manager
&
mpm
)
{
std
::
size_t
n
=
0
;
for
(
auto
ins
:
iterator_for
(
mpm
.
get_module
()))
{
if
(
not
ins
->
get_operator
().
attributes
().
get
(
"reduce"
,
false
))
continue
;
if
(
ins
->
inputs
().
size
()
!=
1
)
continue
;
auto
*
rm
=
mpm
.
create_module
(
mpm
.
get_module
().
name
()
+
":"
+
ins
->
name
()
+
std
::
to_string
(
n
++
));
rm
->
set_bypass
();
rm
->
add_return
(
insert_ins_in_submodule
(
rm
,
ins
));
auto
v
=
ins
->
get_operator
().
to_value
();
mpm
.
get_module
().
replace_instruction
(
ins
,
make_op
(
"fused_reduce"
,
{{
"axes"
,
v
[
"axes"
]}}),
ins
->
inputs
(),
{
rm
});
}
}
template
<
class
...
Ms
>
static
auto
match_broadcast
(
Ms
...
ms
)
{
return
match
::
skip
(
match
::
name
(
"contiguous"
))(
match
::
name
(
"multibroadcast"
)(
match
::
arg
(
0
)(
ms
...),
match
::
used_once
()).
bind
(
"broadcast"
));
}
template
<
class
...
Ms
>
static
auto
any_input
(
Ms
...
ms
)
{
return
match
::
any_of
[
match
::
inputs
()](
match
::
any
(
ms
...).
bind
(
"input"
));
}
static
auto
match_broadcastable_input
(
const
std
::
string
&
op
,
const
std
::
string
&
name
)
{
auto
match_op
=
match
::
name
(
op
)(
match
::
used_once
()).
bind
(
name
);
auto
match_op_input
=
any_input
(
match_op
,
match
::
used_once
());
auto
broadcast_match_op_input
=
any_input
(
match_broadcast
(
match_op
),
match
::
used_once
());
return
match
::
any_of
(
match_op_input
,
broadcast_match_op_input
);
}
namespace
{
struct
find_pointwise_reduce
{
auto
matcher
()
const
{
return
match
::
name
(
"fused_reduce"
)(
match_broadcastable_input
(
"pointwise"
,
"pointwise"
));
}
void
apply
(
module_pass_manager
&
mpm
,
const
match
::
matcher_result
&
r
)
const
{
auto
reduce
=
r
.
result
;
auto
input
=
r
.
instructions
[
"pointwise"
];
const
auto
*
pm
=
input
->
module_inputs
().
front
();
const
auto
*
old_rm
=
reduce
->
module_inputs
().
front
();
auto
*
rm
=
mpm
.
create_module
(
pm
->
name
()
+
":"
+
old_rm
->
name
());
rm
->
set_bypass
();
std
::
unordered_map
<
instruction_ref
,
instruction_ref
>
map_ins
;
// Insert pointwise
auto
rins
=
insert_ins_in_submodule
(
rm
,
input
,
map_ins
).
front
();
map_ins
[
input
]
=
rins
;
if
(
contains
(
r
.
instructions
,
"broadcast"
))
{
auto
broadcast
=
r
.
instructions
[
"broadcast"
];
map_ins
[
broadcast
]
=
insert_ins_in_submodule
(
rm
,
broadcast
,
map_ins
).
front
();
}
// Insert fused_reduce
rm
->
add_return
(
insert_module_in_submodule
(
rm
,
reduce
,
map_ins
));
auto
new_inputs
=
find_inputs
(
rm
,
mpm
.
get_module
(),
map_ins
);
mpm
.
get_module
().
replace_instruction
(
reduce
,
reduce
->
get_operator
(),
new_inputs
,
{
rm
});
}
};
struct
find_reduce_pointwise
{
auto
matcher
()
const
{
return
match
::
name
(
"pointwise"
)(
match_broadcastable_input
(
"fused_reduce"
,
"reduce"
));
}
void
apply
(
module_pass_manager
&
mpm
,
const
match
::
matcher_result
&
r
)
const
{
auto
pw
=
r
.
result
;
auto
reduce
=
r
.
instructions
[
"reduce"
];
auto
input
=
r
.
instructions
[
"input"
];
const
auto
*
pm
=
pw
->
module_inputs
().
front
();
const
auto
*
old_rm
=
reduce
->
module_inputs
().
front
();
auto
*
rm
=
mpm
.
create_module
(
old_rm
->
name
()
+
":"
+
pm
->
name
());
rm
->
set_bypass
();
std
::
unordered_map
<
instruction_ref
,
instruction_ref
>
map_ins
;
// Copy module instructions
insert_module_in_submodule
(
rm
,
reduce
,
map_ins
);
if
(
contains
(
r
.
instructions
,
"broadcast"
))
{
auto
broadcast
=
r
.
instructions
[
"broadcast"
];
map_ins
[
broadcast
->
inputs
().
front
()]
=
rm
->
get_returns
().
front
();
auto
bout
=
insert_ins_in_submodule
(
rm
,
broadcast
,
map_ins
);
map_ins
[
input
]
=
bout
.
front
();
}
else
{
map_ins
[
input
]
=
rm
->
get_returns
().
front
();
}
auto
out
=
insert_ins_in_submodule
(
rm
,
pw
,
map_ins
);
rm
->
replace_return
(
out
);
auto
new_inputs
=
find_inputs
(
rm
,
mpm
.
get_module
(),
map_ins
);
mpm
.
get_module
().
replace_instruction
(
pw
,
reduce
->
get_operator
(),
new_inputs
,
{
rm
});
}
};
struct
find_reduce_reduce
{
auto
matcher
()
const
{
return
match
::
name
(
"fused_reduce"
)(
match_broadcastable_input
(
"fused_reduce"
,
"reduce"
));
}
void
apply
(
module_pass_manager
&
mpm
,
const
match
::
matcher_result
&
r
)
const
{
auto
reduce1
=
r
.
result
;
auto
reduce2
=
r
.
instructions
[
"reduce"
];
auto
input
=
r
.
instructions
[
"input"
];
if
(
reduce1
->
get_operator
()
!=
reduce2
->
get_operator
())
return
;
const
auto
*
rm1
=
reduce1
->
module_inputs
().
front
();
const
auto
*
rm2
=
reduce2
->
module_inputs
().
front
();
auto
*
rm
=
mpm
.
create_module
(
rm1
->
name
()
+
":"
+
rm2
->
name
());
rm
->
set_bypass
();
std
::
unordered_map
<
instruction_ref
,
instruction_ref
>
map_ins
;
// Copy reduce1 instructions
insert_module_in_submodule
(
rm
,
reduce2
,
map_ins
);
if
(
contains
(
r
.
instructions
,
"broadcast"
))
{
auto
broadcast
=
r
.
instructions
[
"broadcast"
];
map_ins
[
broadcast
->
inputs
().
front
()]
=
rm
->
get_returns
().
front
();
auto
bout
=
insert_ins_in_submodule
(
rm
,
broadcast
,
map_ins
);
map_ins
[
input
]
=
bout
.
front
();
}
else
{
map_ins
[
input
]
=
rm
->
get_returns
().
front
();
}
auto
out
=
insert_module_in_submodule
(
rm
,
reduce1
,
map_ins
);
rm
->
replace_return
(
out
);
auto
new_inputs
=
find_inputs
(
rm
,
mpm
.
get_module
(),
map_ins
);
mpm
.
get_module
().
replace_instruction
(
reduce1
,
reduce1
->
get_operator
(),
new_inputs
,
{
rm
});
}
};
}
// namespace
void
fuse_reduce
::
apply
(
module_pass_manager
&
mpm
)
const
{
create_reduce_modules
(
mpm
);
mpm
.
run_pass
(
dead_code_elimination
{});
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
match
::
find_matches
(
mpm
,
find_reduce_pointwise
{},
find_pointwise_reduce
{},
find_reduce_reduce
{});
mpm
.
run_pass
(
dead_code_elimination
{});
}
}
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
src/include/migraphx/common.hpp
View file @
f7079e51
...
@@ -41,6 +41,11 @@ std::vector<shape::dynamic_dimension> compute_broadcasted_dyn_dims(shape s0, sha
...
@@ -41,6 +41,11 @@ std::vector<shape::dynamic_dimension> compute_broadcasted_dyn_dims(shape s0, sha
shape
common_shape
(
const
std
::
vector
<
shape
>&
shapes
);
shape
common_shape
(
const
std
::
vector
<
shape
>&
shapes
);
std
::
vector
<
instruction_ref
>
insert_common_args
(
module
&
m
,
instruction_ref
ins
,
std
::
vector
<
instruction_ref
>
inputs
);
std
::
vector
<
instruction_ref
>
add_common_args
(
module
&
m
,
std
::
vector
<
instruction_ref
>
inputs
);
instruction_ref
insert_common_op
(
module
&
m
,
instruction_ref
insert_common_op
(
module
&
m
,
instruction_ref
ins
,
instruction_ref
ins
,
const
operation
&
op
,
const
operation
&
op
,
...
...
src/include/migraphx/compile_options.hpp
View file @
f7079e51
...
@@ -32,9 +32,17 @@ inline namespace MIGRAPHX_INLINE_NS {
...
@@ -32,9 +32,17 @@ inline namespace MIGRAPHX_INLINE_NS {
struct
compile_options
struct
compile_options
{
{
bool
offload_copy
=
false
;
/**
* Have MIGX allocate memory for parameters and add instructions
* to copy parameters and output to/from an offload device like a GPU.
*/
bool
offload_copy
=
false
;
bool
fast_math
=
true
;
bool
fast_math
=
true
;
bool
exhaustive_tune
=
false
;
bool
exhaustive_tune
=
false
;
/// Use the split_single_dyn_dim pass
bool
split_single_dyn_dim
=
false
;
tracer
trace
{};
tracer
trace
{};
};
};
...
...
src/include/migraphx/convolution.hpp
0 → 100644
View file @
f7079e51
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2022 Advanced Micro Devices, 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.
*/
#ifndef MIGRAPHX_GUARD_RTGLIB_CONVOLUTION_HPP
#define MIGRAPHX_GUARD_RTGLIB_CONVOLUTION_HPP
#include <migraphx/config.hpp>
#include <migraphx/dfor.hpp>
#include <migraphx/par_for.hpp>
#include <migraphx/shape_for_each.hpp>
#include <migraphx/tensor_view.hpp>
#include <vector>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
template
<
class
Output
,
class
T
,
class
Padding
,
class
Stride
>
void
convolution
(
Output
output
,
T
input
,
T
weights
,
Padding
padding
,
Stride
stride
,
int
group
)
{
auto
output_shape
=
output
.
get_shape
();
auto
in_lens
=
input
.
get_shape
().
lens
();
auto
wei_lens
=
weights
.
get_shape
().
lens
();
auto
wei_n
=
wei_lens
[
0
];
auto
wei_c
=
wei_lens
[
1
];
std
::
vector
<
std
::
size_t
>
win_size
(
wei_lens
.
begin
()
+
1
,
wei_lens
.
end
());
par_for
(
output_shape
.
elements
(),
[
&
](
auto
i
)
{
auto
idx_o
=
output_shape
.
multi
(
i
);
auto
w
=
idx_o
[
1
];
auto
n_dim
=
idx_o
.
size
();
std
::
vector
<
std
::
ptrdiff_t
>
win_start
;
for
(
std
::
size_t
dim
=
2
;
dim
<
n_dim
;
++
dim
)
{
auto
d_2
=
dim
-
2
;
win_start
.
push_back
(
std
::
ptrdiff_t
(
idx_o
[
dim
]
*
stride
[
d_2
])
-
std
::
ptrdiff_t
(
padding
[
d_2
]));
}
const
auto
group_id
=
w
/
(
wei_n
/
group
);
shape
win_shape
{
output_shape
.
type
(),
win_size
};
double
acc
=
0.0
;
shape_for_each
(
win_shape
,
[
&
](
auto
idx_win
)
{
auto
k
=
idx_win
[
0
];
const
auto
in_ch
=
group_id
*
wei_c
+
k
;
std
::
vector
<
std
::
ptrdiff_t
>
idx
(
idx_o
.
begin
(),
idx_o
.
end
());
idx
[
1
]
=
in_ch
;
std
::
transform
(
idx_win
.
begin
()
+
1
,
idx_win
.
end
(),
win_start
.
begin
(),
idx
.
begin
()
+
2
,
[](
std
::
ptrdiff_t
ii
,
std
::
ptrdiff_t
jj
)
{
return
ii
+
jj
;
});
std
::
vector
<
std
::
ptrdiff_t
>
idx_wei
(
idx_o
.
size
());
idx_wei
[
0
]
=
w
;
std
::
copy
(
idx_win
.
begin
(),
idx_win
.
end
(),
idx_wei
.
begin
()
+
1
);
if
(
std
::
all_of
(
idx
.
begin
()
+
2
,
idx
.
end
(),
[
&
](
auto
ii
)
{
return
ii
>=
0
;
})
and
std
::
equal
(
idx
.
begin
(),
idx
.
end
(),
in_lens
.
begin
(),
in_lens
.
end
(),
std
::
less
<
std
::
ptrdiff_t
>
{}))
{
acc
+=
input
(
idx
.
begin
(),
idx
.
end
())
*
weights
(
idx_wei
.
begin
(),
idx_wei
.
end
());
}
});
output
[
i
]
=
acc
;
});
}
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
#endif
src/include/migraphx/cpp_generator.hpp
View file @
f7079e51
...
@@ -77,6 +77,7 @@ struct cpp_generator
...
@@ -77,6 +77,7 @@ struct cpp_generator
function
&
set_types
(
const
module
&
m
);
function
&
set_types
(
const
module
&
m
);
function
&
set_types
(
const
module
&
m
,
const
std
::
function
<
std
::
string
(
shape
)
>&
parse
);
function
&
set_types
(
const
module
&
m
,
const
std
::
function
<
std
::
string
(
shape
)
>&
parse
);
function
&
set_generic_types
(
const
module
&
m
);
function
&
set_generic_types
(
const
module
&
m
);
function
&
add_generic_param
(
const
std
::
string
&
pname
);
};
};
cpp_generator
();
cpp_generator
();
...
@@ -105,6 +106,10 @@ struct cpp_generator
...
@@ -105,6 +106,10 @@ struct cpp_generator
std
::
string
create_function
(
const
function
&
f
);
std
::
string
create_function
(
const
function
&
f
);
static
std
::
vector
<
std
::
string
>
to_args
(
const
std
::
vector
<
instruction_ref
>&
inputs
,
const
std
::
unordered_map
<
instruction_ref
,
std
::
string
>&
names
);
private:
private:
std
::
unique_ptr
<
cpp_generator_impl
>
impl
;
std
::
unique_ptr
<
cpp_generator_impl
>
impl
;
};
};
...
...
src/include/migraphx/fuse_reduce.hpp
0 → 100644
View file @
f7079e51
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2022 Advanced Micro Devices, 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.
*/
#ifndef MIGRAPHX_GUARD_MIGRAPHX_FUSE_REDUCE_HPP
#define MIGRAPHX_GUARD_MIGRAPHX_FUSE_REDUCE_HPP
#include <migraphx/config.hpp>
#include <string>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
struct
module_pass_manager
;
struct
fuse_reduce
{
std
::
string
name
()
const
{
return
"fuse_reduce"
;
}
void
apply
(
module_pass_manager
&
mpm
)
const
;
};
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
#endif // MIGRAPHX_GUARD_MIGRAPHX_FUSE_POINTWISE_HPP
src/include/migraphx/matcher.hpp
View file @
f7079e51
...
@@ -347,6 +347,7 @@ match::matcher_result find_match(module& modl, M&& m)
...
@@ -347,6 +347,7 @@ match::matcher_result find_match(module& modl, M&& m)
}
}
MIGRAPHX_DECLARE_ENV_VAR
(
MIGRAPHX_TRACE_MATCHES
)
MIGRAPHX_DECLARE_ENV_VAR
(
MIGRAPHX_TRACE_MATCHES
)
MIGRAPHX_DECLARE_ENV_VAR
(
MIGRAPHX_VALIDATE_MATCHES
)
/// Find matches for an instruction in the module
/// Find matches for an instruction in the module
template
<
class
Mod
,
class
...
Ms
>
template
<
class
Mod
,
class
...
Ms
>
...
@@ -356,7 +357,11 @@ void find_matches(Mod& mod, instruction_ref ins, Ms&&... ms)
...
@@ -356,7 +357,11 @@ void find_matches(Mod& mod, instruction_ref ins, Ms&&... ms)
const
const
#endif
#endif
int
trace
=
value_of
(
MIGRAPHX_TRACE_MATCHES
{});
int
trace
=
value_of
(
MIGRAPHX_TRACE_MATCHES
{});
bool
match
=
false
;
#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 5
const
#endif
bool
validate
=
enabled
(
MIGRAPHX_VALIDATE_MATCHES
{});
bool
match
=
false
;
each_args
(
each_args
(
[
&
](
auto
&&
m
)
{
[
&
](
auto
&&
m
)
{
if
(
match
)
if
(
match
)
...
@@ -371,7 +376,20 @@ void find_matches(Mod& mod, instruction_ref ins, Ms&&... ms)
...
@@ -371,7 +376,20 @@ void find_matches(Mod& mod, instruction_ref ins, Ms&&... ms)
std
::
cout
<<
"Matched by "
<<
get_type_name
(
m
)
<<
std
::
endl
;
std
::
cout
<<
"Matched by "
<<
get_type_name
(
m
)
<<
std
::
endl
;
get_module
(
mod
).
debug_print
(
ins
);
get_module
(
mod
).
debug_print
(
ins
);
}
}
// If its already invalid dont validate it again
bool
invalidated
=
validate
and
get_module
(
mod
).
validate
()
!=
get_module
(
mod
).
end
();
m
.
apply
(
mod
,
r
);
m
.
apply
(
mod
,
r
);
if
(
validate
and
not
invalidated
)
{
auto
invalid
=
get_module
(
mod
).
validate
();
if
(
invalid
!=
get_module
(
mod
).
end
())
{
std
::
cout
<<
"Invalid program from match: "
<<
get_type_name
(
m
)
<<
std
::
endl
;
std
::
cout
<<
"Invalid instructions: "
<<
std
::
endl
;
get_module
(
mod
).
debug_print
(
invalid
->
inputs
());
get_module
(
mod
).
debug_print
(
invalid
);
}
}
match
=
true
;
match
=
true
;
},
},
ms
...);
ms
...);
...
...
src/include/migraphx/module.hpp
View file @
f7079e51
...
@@ -178,6 +178,8 @@ struct module
...
@@ -178,6 +178,8 @@ struct module
bool
has_instruction
(
instruction_ref
ins
)
const
;
bool
has_instruction
(
instruction_ref
ins
)
const
;
std
::
vector
<
instruction_ref
>
get_returns
()
const
;
std
::
size_t
size
()
const
;
std
::
size_t
size
()
const
;
instruction_ref
begin
()
const
;
instruction_ref
begin
()
const
;
instruction_ref
end
()
const
;
instruction_ref
end
()
const
;
...
...
src/include/migraphx/msgpack.hpp
View file @
f7079e51
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
#include <migraphx/config.hpp>
#include <migraphx/config.hpp>
#include <migraphx/value.hpp>
#include <migraphx/value.hpp>
#include <functional>
namespace
migraphx
{
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
inline
namespace
MIGRAPHX_INLINE_NS
{
...
...
src/include/migraphx/onnx.hpp
View file @
f7079e51
...
@@ -37,7 +37,7 @@ struct onnx_options
...
@@ -37,7 +37,7 @@ struct onnx_options
std
::
size_t
default_dim_value
=
0
;
std
::
size_t
default_dim_value
=
0
;
/// Default dynamic dimension size (if both default_dim_value and default_dyn_dim_value set
/// Default dynamic dimension size (if both default_dim_value and default_dyn_dim_value set
/// parser throws)
/// parser throws)
shape
::
dynamic_dimension
default_dyn_dim_value
=
{
1
,
1
,
0
};
shape
::
dynamic_dimension
default_dyn_dim_value
=
{
1
,
1
};
/// Explicitly specify the dims of an input
/// Explicitly specify the dims of an input
std
::
unordered_map
<
std
::
string
,
std
::
vector
<
std
::
size_t
>>
map_input_dims
=
{};
std
::
unordered_map
<
std
::
string
,
std
::
vector
<
std
::
size_t
>>
map_input_dims
=
{};
/// Explicitly specify dynamic dims of an input (if both map_input_dims and map_dyn_input_dims
/// Explicitly specify dynamic dims of an input (if both map_input_dims and map_dyn_input_dims
...
...
Prev
1
2
3
4
5
Next
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