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
124f7d55
Commit
124f7d55
authored
Oct 12, 2023
by
Umang Yadav
Browse files
Merge branch 'develop' into resnet50_partition
parents
350bbea2
34b68ee4
Changes
288
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
692 additions
and
57 deletions
+692
-57
src/include/migraphx/tmp_dir.hpp
src/include/migraphx/tmp_dir.hpp
+1
-0
src/include/migraphx/type_name.hpp
src/include/migraphx/type_name.hpp
+1
-1
src/include/migraphx/verify.hpp
src/include/migraphx/verify.hpp
+96
-8
src/include/migraphx/verify_args.hpp
src/include/migraphx/verify_args.hpp
+9
-5
src/onnx/broadcast_qdq.cpp
src/onnx/broadcast_qdq.cpp
+76
-0
src/onnx/include/migraphx/onnx/broadcast_qdq.hpp
src/onnx/include/migraphx/onnx/broadcast_qdq.hpp
+56
-0
src/onnx/onnx_parser.cpp
src/onnx/onnx_parser.cpp
+1
-1
src/onnx/parse_castlike.cpp
src/onnx/parse_castlike.cpp
+53
-0
src/onnx/parse_constant.cpp
src/onnx/parse_constant.cpp
+26
-3
src/onnx/parse_constant_of_shape.cpp
src/onnx/parse_constant_of_shape.cpp
+28
-19
src/onnx/parse_depthtospace.cpp
src/onnx/parse_depthtospace.cpp
+1
-2
src/onnx/parse_qlinearadd.cpp
src/onnx/parse_qlinearadd.cpp
+154
-0
src/onnx/parse_reshape.cpp
src/onnx/parse_reshape.cpp
+1
-2
src/onnx/parse_resize.cpp
src/onnx/parse_resize.cpp
+2
-1
src/onnx/parse_roialign.cpp
src/onnx/parse_roialign.cpp
+7
-4
src/onnx/parse_spacetodepth.cpp
src/onnx/parse_spacetodepth.cpp
+1
-2
src/optimize_module.cpp
src/optimize_module.cpp
+7
-3
src/process.cpp
src/process.cpp
+167
-1
src/program.cpp
src/program.cpp
+1
-1
src/propagate_constant.cpp
src/propagate_constant.cpp
+4
-4
No files found.
src/include/migraphx/tmp_dir.hpp
View file @
124f7d55
...
...
@@ -34,6 +34,7 @@ struct MIGRAPHX_EXPORT tmp_dir
{
fs
::
path
path
;
tmp_dir
(
const
std
::
string
&
prefix
=
""
);
tmp_dir
(
tmp_dir
&&
)
=
default
;
void
execute
(
const
std
::
string
&
exe
,
const
std
::
string
&
args
)
const
;
...
...
src/include/migraphx/type_name.hpp
View file @
124f7d55
...
...
@@ -34,7 +34,7 @@ template <class PrivateMigraphTypeNameProbe>
std
::
string
compute_type_name
()
{
std
::
string
name
;
#ifdef
_MSC_VER
#if
def
ined(
_MSC_VER
) && !defined(__clang__)
name
=
typeid
(
PrivateMigraphTypeNameProbe
).
name
();
name
=
name
.
substr
(
7
);
#else
...
...
src/include/migraphx/verify.hpp
View file @
124f7d55
...
...
@@ -29,10 +29,13 @@
#include <functional>
#include <iostream>
#include <numeric>
#include <assert.h>
#include <migraphx/float_equal.hpp>
#include <migraphx/config.hpp>
#include <migraphx/env.hpp>
MIGRAPHX_DECLARE_ENV_VAR
(
MIGRAPHX_VERIFY_ENABLE_ALLCLOSE
)
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
verify
{
...
...
@@ -87,8 +90,7 @@ struct not_finite_fn
template
<
class
T
>
bool
operator
()(
T
x
)
const
{
using
std
::
isfinite
;
return
not
isfinite
(
x
);
return
not
std
::
isfinite
(
static_cast
<
double
>
(
x
));
}
};
static
constexpr
not_finite_fn
not_finite
{};
...
...
@@ -98,8 +100,7 @@ struct compare_mag_fn
template
<
class
T
,
class
U
>
bool
operator
()(
T
x
,
U
y
)
const
{
using
std
::
fabs
;
return
fabs
(
x
)
<
fabs
(
y
);
return
std
::
fabs
(
x
)
<
std
::
fabs
(
y
);
}
};
static
constexpr
compare_mag_fn
compare_mag
{};
...
...
@@ -187,16 +188,103 @@ double rms_range(const R1& r1, const R2& r2)
return
std
::
numeric_limits
<
range_value
<
R1
>>::
max
();
}
template
<
class
R
>
double
get_rms_tol
(
const
R
&
,
std
::
size_t
tolerance
=
80
)
{
double
threshold
=
std
::
numeric_limits
<
range_value
<
R
>>::
epsilon
()
*
tolerance
;
return
threshold
;
}
/*
C++ doesn't support named arguments, this is just wrapper that helps distinguish between actual
results v/s expected results arguments.
*/
template
<
class
T
>
struct
expected
{
expected
()
=
default
;
explicit
expected
(
const
T
&
input
)
:
x
(
&
input
)
{}
const
T
&
data
()
const
{
assert
(
x
!=
nullptr
);
return
*
x
;
}
private:
const
T
*
x
=
nullptr
;
};
// deduction guide for templated expected class
template
<
class
T
>
expected
(
const
T
&
)
->
expected
<
T
>
;
struct
tolerance
{
double
rms_tol
=
0.001
;
double
atol
=
0.001
;
double
rtol
=
0.001
;
};
/*
MIGraphX implementation of numpy's np.allclose() which checks if elementwise absolute diff is within
tolerance using this formula: abs(a - b) < atol + rtol(abs(b))
*/
template
<
class
R1
,
class
R2
>
bool
allclose
(
const
R1
&
r1
,
const
R2
&
r2
,
tolerance
tols
)
{
std
::
size_t
n
=
range_distance
(
r1
);
if
(
n
==
range_distance
(
r2
))
{
auto
idx
=
mismatch_idx
(
r1
,
r2
,
[
&
](
auto
x
,
auto
y
)
{
return
abs_diff
(
double
(
x
),
double
(
y
))
<
tols
.
atol
+
tols
.
rtol
*
std
::
abs
(
double
(
y
));
});
return
idx
>=
range_distance
(
r1
);
}
return
false
;
}
template
<
class
R1
,
class
R2
>
bool
verify_range
(
const
R1
&
r1
,
const
R2
&
r2
,
double
tolerance
=
80
,
double
*
out_error
=
nullptr
)
bool
verify_rms_range
(
const
R1
&
r1
,
const
R2
&
r2
,
std
::
size_t
tolerance
=
80
,
double
*
out_rms_error
=
nullptr
)
{
double
threshold
=
std
::
numeric_limits
<
range_value
<
R1
>>::
epsilon
()
*
tolerance
;
double
threshold
=
get_rms_tol
(
r1
,
tolerance
)
;
auto
error
=
rms_range
(
r1
,
r2
);
if
(
out_error
!=
nullptr
)
*
out_error
=
error
;
if
(
out_
rms_
error
!=
nullptr
)
*
out_
rms_
error
=
error
;
return
error
<=
threshold
;
}
template
<
class
R1
,
class
R2
>
bool
verify_range_with_tolerance
(
const
R1
&
r1
,
const
expected
<
R2
>&
r2
,
tolerance
tols
=
tolerance
{},
double
*
out_rms_error
=
nullptr
)
{
auto
rms_error
=
rms_range
(
r1
,
r2
.
data
());
// disable ewise_verify by default for now, it requires lot of tests to be fixed
bool
ewise_verify
=
true
;
if
(
enabled
(
MIGRAPHX_VERIFY_ENABLE_ALLCLOSE
{}))
{
ewise_verify
=
allclose
(
r1
,
r2
.
data
(),
tols
);
}
if
(
out_rms_error
!=
nullptr
)
*
out_rms_error
=
rms_error
;
return
rms_error
<=
tols
.
rms_tol
and
ewise_verify
;
}
// expected argument should be passed as second, but if it is passed as the first by mistake then
// flip the order
template
<
class
R1
,
class
R2
>
bool
verify_range_with_tolerance
(
const
expected
<
R1
>&
r1
,
const
R2
&
r2
,
tolerance
tols
=
tolerance
{},
double
*
out_rms_error
=
nullptr
)
{
return
verify_rms_range
(
r2
,
r1
,
tols
,
out_rms_error
);
}
}
// namespace verify
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
...
...
src/include/migraphx/verify_args.hpp
View file @
124f7d55
...
...
@@ -31,11 +31,15 @@
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
MIGRAPHX_EXPORT
bool
verify_args
(
const
std
::
string
&
name
,
const
argument
&
ref_arg
,
const
argument
&
target_arg
,
double
tolerance
=
80
);
MIGRAPHX_EXPORT
bool
verify_args
(
const
std
::
string
&
name
,
const
argument
&
target_arg
,
const
verify
::
expected
<
argument
>&
ref_arg
,
verify
::
tolerance
);
MIGRAPHX_EXPORT
bool
verify_args_with_tolerance
(
const
std
::
string
&
name
,
const
argument
&
target_arg
,
const
verify
::
expected
<
argument
>&
ref_arg
,
std
::
size_t
tolerance
=
80
);
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
...
...
src/onnx/broadcast_qdq.cpp
0 → 100644
View file @
124f7d55
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2023 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/onnx/broadcast_qdq.hpp>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
onnx
{
// This method is to prep for quantizelinear or dequantizelinear operation for
// either the broadcasting of weight-scale or zero-points of qlinearadd operator
// outputs: operator op (inputs x, broadcasted: scale (float) & zero_pt (8-bit))
instruction_ref
bcast_qdq_instr
(
const
std
::
string
&
op_name
,
instruction_ref
x_in
,
instruction_ref
arg_fscale
,
instruction_ref
arg_z_pt
,
const
onnx_parser
::
node_info
&
info
)
{
auto
in_lens
=
x_in
->
get_shape
().
lens
();
// prep 1: broadcast scale. it can come as a scalar or a 1-D tensor.
instruction_ref
bcast_scale
;
if
(
arg_fscale
->
get_shape
().
elements
()
>
1
)
bcast_scale
=
info
.
add_instruction
(
migraphx
::
make_op
(
"broadcast"
,
{{
"axis"
,
0
},
{
"out_lens"
,
in_lens
}}),
arg_fscale
);
else
bcast_scale
=
info
.
add_instruction
(
migraphx
::
make_op
(
"multibroadcast"
,
{{
"out_lens"
,
in_lens
}}),
arg_fscale
);
// prep 2: broadcast zero point. it can come as a scalar or a 1-D tensor.
instruction_ref
bcast_zero_pt
;
if
(
arg_z_pt
->
get_shape
().
elements
()
>
1
)
bcast_zero_pt
=
info
.
add_instruction
(
migraphx
::
make_op
(
"broadcast"
,
{{
"axis"
,
0
},
{
"out_lens"
,
in_lens
}}),
arg_z_pt
);
else
bcast_zero_pt
=
info
.
add_instruction
(
migraphx
::
make_op
(
"multibroadcast"
,
{{
"out_lens"
,
in_lens
}}),
arg_z_pt
);
// op_name is either quantizelinear or dequantizelinear:
return
info
.
add_instruction
(
migraphx
::
make_op
(
op_name
),
x_in
,
bcast_scale
,
bcast_zero_pt
);
}
// Multibroadcast a scaler..
instruction_ref
bcast_scalar_instr
(
const
migraphx
::
shape
&
shape_out
,
instruction_ref
arg_in
,
const
onnx_parser
::
node_info
&
info
)
{
auto
bcast_instr_out
=
info
.
add_instruction
(
migraphx
::
make_op
(
"multibroadcast"
,
{{
"out_lens"
,
shape_out
.
lens
()}}),
arg_in
);
return
bcast_instr_out
;
}
}
// namespace onnx
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
src/onnx/include/migraphx/onnx/broadcast_qdq.hpp
0 → 100644
View file @
124f7d55
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2023 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_AMDMIGRAPHX_ONNX_BROADCAST_QDQ_HPP
#define MIGRAPHX_GUARD_AMDMIGRAPHX_ONNX_BROADCAST_QDQ_HPP
#include <string>
#include <migraphx/onnx/op_parser.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/instruction.hpp>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
onnx
{
// This method is to prep for quantizelinear or dequantizelinear operation for
// either the broadcasting of weight-scale or zero-points of qlinearadd operator
// outputs: operator op (inputs x, broadcasted: scale (float) & zero_pt (8-bit))
instruction_ref
bcast_qdq_instr
(
const
std
::
string
&
op_name
,
instruction_ref
x_in
,
instruction_ref
arg_fscale
,
instruction_ref
arg_z_pt
,
const
onnx_parser
::
node_info
&
info
);
// Multibroadcast a scaler..
instruction_ref
bcast_scalar_instr
(
const
migraphx
::
shape
&
shape_out
,
instruction_ref
arg_in
,
const
onnx_parser
::
node_info
&
info
);
}
// namespace onnx
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
#endif
src/onnx/onnx_parser.cpp
View file @
124f7d55
...
...
@@ -244,7 +244,7 @@ void onnx_parser::parse_from(std::istream& is, std::string name)
this
->
filename
=
std
::
move
(
name
);
auto
parent_path
=
fs
::
path
(
this
->
filename
).
parent_path
();
if
(
not
parent_path
.
empty
())
this
->
path
=
parent_path
;
this
->
path
=
parent_path
.
string
()
;
onnx
::
ModelProto
model
;
if
(
model
.
ParseFromIstream
(
&
is
))
...
...
src/onnx/parse_castlike.cpp
0 → 100644
View file @
124f7d55
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2023 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/onnx/op_parser.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/instruction.hpp>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
onnx
{
struct
parse_castlike
:
op_parser
<
parse_castlike
>
{
std
::
vector
<
op_desc
>
operators
()
const
{
return
{{
"CastLike"
}};
}
instruction_ref
parse
(
const
op_desc
&
/*opd*/
,
const
onnx_parser
&
/*parser*/
,
const
onnx_parser
::
node_info
&
info
,
const
std
::
vector
<
instruction_ref
>&
args
)
const
{
if
(
not
(
args
.
size
()
==
2
))
{
MIGRAPHX_THROW
(
"PARSE_CASTLIKE: CastLike must have exactly 2 inputs!"
);
}
shape
::
type_t
target_type
=
args
[
1
]
->
get_shape
().
type
();
return
info
.
add_instruction
(
make_op
(
"convert"
,
{{
"target_type"
,
target_type
}}),
args
[
0
]);
}
};
}
// namespace onnx
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
src/onnx/parse_constant.cpp
View file @
124f7d55
...
...
@@ -25,6 +25,7 @@
#include <migraphx/ranges.hpp>
#include <migraphx/literal.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/stringutils.hpp>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
...
...
@@ -39,16 +40,38 @@ struct parse_constant : op_parser<parse_constant>
onnx_parser
::
node_info
info
,
const
std
::
vector
<
instruction_ref
>&
/*args*/
)
const
{
literal
v
=
parser
.
parse_value
(
info
.
attributes
.
at
(
"value"
));
static
const
std
::
vector
<
std
::
string
>
attributes
=
{
"value"
,
"value_float"
,
"value_floats"
,
"value_int"
,
"value_ints"
};
std
::
vector
<
std
::
string
>
present_attributes
;
std
::
copy_if
(
attributes
.
begin
(),
attributes
.
end
(),
std
::
back_inserter
(
present_attributes
),
[
&
](
const
std
::
string
&
a
)
{
return
contains
(
info
.
attributes
,
a
);
});
if
(
present_attributes
.
empty
())
{
MIGRAPHX_THROW
(
"Constant node does not contain any supported attribute"
);
}
if
(
present_attributes
.
size
()
>
1
)
{
MIGRAPHX_THROW
(
"Constant contains multiple attributes: "
+
join_strings
(
std
::
move
(
present_attributes
),
", "
));
}
// cppcheck-suppress accessMoved
auto
&&
attr
=
info
.
attributes
[
present_attributes
[
0
]];
literal
v
=
parser
.
parse_value
(
attr
);
// return empty literal
if
(
v
.
get_shape
().
elements
()
==
0
)
{
return
info
.
add_literal
(
literal
{
v
.
get_shape
().
type
()});
}
auto
dim_size
=
info
.
attributes
.
at
(
"value"
).
t
().
dims_size
();
// if dim_size is 0, it is a scalar
if
(
dim_size
==
0
)
if
(
attr
.
has_t
()
and
attr
.
t
().
dim
s
_size
()
==
0
)
{
migraphx
::
shape
scalar_shape
{
v
.
get_shape
().
type
()};
return
info
.
add_literal
(
migraphx
::
literal
{
scalar_shape
,
v
.
data
()});
...
...
src/onnx/parse_constant_of_shape.cpp
View file @
124f7d55
...
...
@@ -49,6 +49,8 @@ struct parse_constant_of_shape : op_parser<parse_constant_of_shape>
{
MIGRAPHX_THROW
(
"ConstantOfShape: attribute value can contain only 1 elements!"
);
}
// convert to a scalar literal
l_val
=
literal
(
shape
{
l_val
.
get_shape
().
type
(),
{
1
},
{
0
}},
l_val
.
data
());
}
else
{
...
...
@@ -64,30 +66,37 @@ struct parse_constant_of_shape : op_parser<parse_constant_of_shape>
migraphx
::
shape
s
;
// input is empty, output is a scalar
auto
type
=
l_val
.
get_shape
().
type
();
// empty input tensor, output is a scalar
if
(
args
[
0
]
->
get_shape
().
elements
()
==
0
)
migraphx
::
argument
input
=
args
[
0
]
->
eval
();
if
(
not
input
.
empty
()
)
{
s
=
migraphx
::
shape
{
type
,
{
1
},
{
0
}};
// empty input tensor, output is a scalar
if
(
args
[
0
]
->
get_shape
().
elements
()
==
0
)
{
s
=
migraphx
::
shape
{
type
,
{
1
},
{
0
}};
}
else
{
std
::
vector
<
std
::
size_t
>
dims
;
input
.
visit
([
&
](
auto
ia
)
{
dims
.
assign
(
ia
.
begin
(),
ia
.
end
());
});
s
=
migraphx
::
shape
{
type
,
dims
};
}
literal
l_out
{};
l_val
.
visit
([
&
](
auto
val
)
{
using
val_type
=
std
::
remove_cv_t
<
typename
decltype
(
val
)
::
value_type
>
;
// l_val contains only one element
std
::
vector
<
val_type
>
out_vec
(
s
.
elements
(),
val
.
front
());
l_out
=
literal
(
s
,
out_vec
);
});
return
info
.
add_literal
(
l_out
);
}
// has variable input (dynamic shape buffer)
else
{
migraphx
::
argument
in
=
args
[
0
]
->
eval
();
check_arg_empty
(
in
,
"ConstantOfShape: dynamic shape is not supported"
);
std
::
vector
<
std
::
size_t
>
dims
;
in
.
visit
([
&
](
auto
input
)
{
dims
.
assign
(
input
.
begin
(),
input
.
end
());
});
s
=
migraphx
::
shape
{
type
,
dims
};
auto
dv_lit
=
info
.
add_literal
(
l_val
);
auto
alloc_ins
=
info
.
add_instruction
(
make_op
(
"allocate"
,
{{
"buf_type"
,
type
}}),
args
[
0
]);
return
info
.
add_instruction
(
make_op
(
"fill"
),
dv_lit
,
alloc_ins
);
}
literal
l_out
{};
l_val
.
visit
([
&
](
auto
val
)
{
using
val_type
=
std
::
remove_cv_t
<
typename
decltype
(
val
)
::
value_type
>
;
// l_val contains only one element
std
::
vector
<
val_type
>
out_vec
(
s
.
elements
(),
val
.
front
());
l_out
=
literal
(
s
,
out_vec
);
});
return
info
.
add_literal
(
l_out
);
}
}
};
...
...
src/onnx/parse_depthtospace.cpp
View file @
124f7d55
...
...
@@ -87,8 +87,7 @@ struct parse_depthtospace : op_parser<parse_depthtospace>
auto
temp1
=
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
lens1
}}),
args
[
0
]);
auto
temp2
=
info
.
add_instruction
(
make_op
(
"transpose"
,
{{
"permutation"
,
perm
}}),
temp1
);
return
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
lens2
}}),
info
.
make_contiguous
(
temp2
));
return
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
lens2
}}),
temp2
);
}
};
...
...
src/onnx/parse_qlinearadd.cpp
0 → 100644
View file @
124f7d55
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2023 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/onnx/op_parser.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/common.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/onnx/checks.hpp>
#include <migraphx/onnx/broadcast_qdq.hpp>
#include <migraphx/instruction.hpp>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
onnx
{
/*
*********************************************************************************
* Reference: see QLinearAdd in *
* https://github.com/microsoft/onnxruntime/blob/main/docs/ContribOperators.md *
*********************************************************************************
com.microsoft.QLinearAdd
Performs element-wise binary addition on 8 bit data types (with Numpy-style broadcasting support).
C = (A_scale * (A - A_zero_point) + B_scale * (B - B_zero_point))/C_scale + C_zero_point
Version
This version of the operator has been available since version 1 of the 'com.microsoft' operator
set.
Inputs (7 - 8)
A : T
First operand.
A_scale : tensor(float)
Input A's scale. It's a scalar, which means a per-tensor/layer quantization.
A_zero_point (optional) : T
Input A zero point. Default value is 0 if it's not specified. It's a scalar, which means a
per-tensor/layer quantization.
B : T
Second operand.
B_scale : tensor(float)
Input B's scale. It's a scalar, which means a per-tensor/layer quantization.
B_zero_point (optional) : T
Input B zero point. Default value is 0 if it's not specified. It's a scalar, which means a
per-tensor/layer quantization.
C_scale : tensor(float)
Output scale. It's a scalar, which means a per-tensor/layer quantization.
C_zero_point (optional) : T
Output zero point. Default value is 0 if it's not specified. It's a scalar, which means a
per-tensor/layer quantization.
Outputs
C : T
Result, has same element type as two inputs
Type Constraints
T : tensor(uint8), tensor(int8)
Constrain input and output types to 8 bit signed and unsigned tensors.
*/
struct
parse_qlinearadd
:
op_parser
<
parse_qlinearadd
>
{
std
::
vector
<
op_desc
>
operators
()
const
{
return
{{
"QLinearAdd"
}};
}
// basic type checking for QLinearAdd Operator
void
check_inputs
(
const
std
::
vector
<
instruction_ref
>&
args
)
const
{
if
(
args
.
size
()
<
7
)
MIGRAPHX_THROW
(
"QLINEARADD: missing inputs"
);
const
auto
&
in_a
=
args
[
0
];
const
auto
&
in_b
=
args
[
3
];
auto
sh_a
=
in_a
->
get_shape
();
auto
sh_b
=
in_b
->
get_shape
();
auto
type_a
=
sh_a
.
type
();
auto
type_b
=
sh_b
.
type
();
if
(
type_a
!=
migraphx
::
shape
::
int8_type
and
type_a
!=
migraphx
::
shape
::
uint8_type
)
MIGRAPHX_THROW
(
"QLINEARADD: unsupported input type"
);
if
(
type_b
!=
migraphx
::
shape
::
int8_type
and
type_b
!=
migraphx
::
shape
::
uint8_type
)
MIGRAPHX_THROW
(
"QLINEARADD: unsupported input type"
);
if
(
type_a
!=
type_b
)
MIGRAPHX_THROW
(
"QLINEARADD: mismatched input types"
);
}
instruction_ref
parse
(
const
op_desc
&
/* opd */
,
const
onnx_parser
&
/*parser*/
,
const
onnx_parser
::
node_info
&
info
,
const
std
::
vector
<
instruction_ref
>&
args
)
const
{
check_inputs
(
args
);
// A
const
auto
&
in_a
=
args
[
0
];
const
auto
&
in_scale_a
=
args
[
1
];
const
auto
&
in_zero_pt_a
=
args
[
2
];
auto
dquant_a
=
bcast_qdq_instr
(
"dequantizelinear"
,
in_a
,
in_scale_a
,
in_zero_pt_a
,
info
);
// B
const
auto
&
in_b
=
args
[
3
];
const
auto
&
in_scale_b
=
args
[
4
];
const
auto
&
in_zero_pt_b
=
args
[
5
];
auto
dquant_b
=
bcast_qdq_instr
(
"dequantizelinear"
,
in_b
,
in_scale_b
,
in_zero_pt_b
,
info
);
// C = A + B
auto
out_c
=
info
.
add_common_op
(
"add"
,
dquant_a
,
dquant_b
);
const
auto
&
in_scale_c
=
args
[
6
];
// zero_pt for C is supplied as the last optional argument..
if
(
args
.
size
()
==
8
)
return
(
bcast_qdq_instr
(
"quantizelinear"
,
out_c
,
in_scale_c
,
args
[
7
],
info
));
// if no zero_pt: just broadcast the scale..
auto
bcast_scale_c
=
bcast_scalar_instr
(
out_c
->
get_shape
(),
in_scale_c
,
info
);
return
(
info
.
add_instruction
(
migraphx
::
make_op
(
"quantizelinear"
),
out_c
,
bcast_scale_c
));
}
};
}
// namespace onnx
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
src/onnx/parse_reshape.cpp
View file @
124f7d55
...
...
@@ -53,8 +53,7 @@ struct parse_reshape : op_parser<parse_reshape>
s
.
visit
([
&
](
auto
v
)
{
copy
(
v
,
std
::
back_inserter
(
dims
));
});
}
auto
cont
=
info
.
add_instruction
(
make_op
(
"contiguous"
),
args
[
0
]);
return
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
dims
}}),
cont
);
return
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
dims
}}),
args
[
0
]);
}
};
...
...
src/onnx/parse_resize.cpp
View file @
124f7d55
...
...
@@ -320,7 +320,8 @@ struct parse_resize : op_parser<parse_resize>
// get the number of dimensions
std
::
size_t
n_dim
=
out_lens
.
size
();
auto
vvv_ind
=
std
::
vector
(
n_dim
,
std
::
vector
(
2
,
std
::
vector
<
size_t
>
(
out_elements
)));
std
::
vector
<
std
::
vector
<
std
::
size_t
>>
vv_ind
(
2
,
std
::
vector
<
std
::
size_t
>
(
out_elements
));
std
::
vector
<
std
::
vector
<
std
::
vector
<
std
::
size_t
>>>
vvv_ind
(
n_dim
,
vv_ind
);
std
::
vector
<
std
::
vector
<
float
>>
delta
(
n_dim
,
std
::
vector
<
float
>
(
out_elements
));
shape_for_each
(
out_s
,
[
&
](
const
auto
&
out_idx_v
,
size_t
out_idx
)
{
...
...
src/onnx/parse_roialign.cpp
View file @
124f7d55
...
...
@@ -37,15 +37,18 @@ struct parse_roialign : op_parser<parse_roialign>
std
::
vector
<
op_desc
>
operators
()
const
{
return
{{
"RoiAlign"
}};
}
instruction_ref
parse
(
const
op_desc
&
/*opd*/
,
const
onnx_parser
&
/*
parser
*/
,
const
onnx_parser
&
parser
,
onnx_parser
::
node_info
info
,
const
std
::
vector
<
instruction_ref
>&
args
)
const
{
std
::
string
coord_trans_mode
=
"half_pixel"
;
if
(
contains
(
info
.
attributes
,
"coordinate_transformation_mode"
))
std
::
string
coord_trans_mode
=
parser
.
opset_version
>=
16
?
"half_pixel"
:
"output_half_pixel"
;
if
(
const
auto
*
a
=
"coordinate_transformation_mode"
;
contains
(
info
.
attributes
,
a
))
{
coord_trans_mode
=
info
.
attributes
.
at
(
"coordinate_transformation_mode"
).
s
();
coord_trans_mode
=
info
.
attributes
.
at
(
a
).
s
();
}
if
(
not
contains
({
"half_pixel"
,
"output_half_pixel"
},
coord_trans_mode
))
{
MIGRAPHX_THROW
(
"coordinate_transformation_mode
\"
"
+
coord_trans_mode
+
...
...
src/onnx/parse_spacetodepth.cpp
View file @
124f7d55
...
...
@@ -73,8 +73,7 @@ struct parse_spacetodepth : op_parser<parse_spacetodepth>
std
::
vector
<
int64_t
>
perm
=
{
0
,
3
,
5
,
1
,
2
,
4
};
auto
temp1
=
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
trans_lens
}}),
args
[
0
]);
auto
temp2
=
info
.
add_instruction
(
make_op
(
"transpose"
,
{{
"permutation"
,
perm
}}),
temp1
);
return
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
res_lens
}}),
info
.
make_contiguous
(
temp2
));
return
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
res_lens
}}),
temp2
);
}
};
...
...
src/optimize_module.cpp
View file @
124f7d55
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-202
2
Advanced Micro Devices, Inc. All rights reserved.
* Copyright (c) 2015-202
3
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
...
...
@@ -36,8 +36,12 @@ void optimize_module::apply(module_pass_manager& mpm) const
{
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
mpm
.
run_pass
(
simplify_reshapes
{});
mpm
.
run_pass
(
simplify_algebra
{});
// loop to further optimize after initial transformations
for
(
int
j
=
0
;
j
<
2
;
j
++
)
{
mpm
.
run_pass
(
simplify_reshapes
{});
mpm
.
run_pass
(
simplify_algebra
{});
}
mpm
.
run_pass
(
eliminate_common_subexpression
{});
mpm
.
run_pass
(
dead_code_elimination
{});
mpm
.
run_pass
(
propagate_constant
{});
...
...
src/process.cpp
View file @
124f7d55
...
...
@@ -26,13 +26,23 @@
#include <migraphx/env.hpp>
#include <functional>
#include <iostream>
#include <optional>
#ifdef _WIN32
// cppcheck-suppress definePrefix
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#else
#include <unistd.h>
#endif
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
MIGRAPHX_DECLARE_ENV_VAR
(
MIGRAPHX_TRACE_CMD_EXECUTE
)
#ifndef _WIN32
std
::
function
<
void
(
const
char
*
)
>
redirect_to
(
std
::
ostream
&
os
)
{
return
[
&
](
const
char
*
x
)
{
os
<<
x
;
};
...
...
@@ -74,6 +84,155 @@ int exec(const std::string& cmd, std::function<void(process::writer)> std_in)
});
}
#else
constexpr
std
::
size_t
MIGRAPHX_PROCESS_BUFSIZE
=
4096
;
class
pipe
{
public:
explicit
pipe
(
bool
inherit_handle
=
true
)
{
SECURITY_ATTRIBUTES
attrs
;
attrs
.
nLength
=
sizeof
(
SECURITY_ATTRIBUTES
);
attrs
.
bInheritHandle
=
inherit_handle
?
TRUE
:
FALSE
;
attrs
.
lpSecurityDescriptor
=
nullptr
;
if
(
CreatePipe
(
&
m_read
,
&
m_write
,
&
attrs
,
0
)
==
FALSE
)
throw
GetLastError
();
if
(
SetHandleInformation
(
&
m_read
,
HANDLE_FLAG_INHERIT
,
0
)
==
FALSE
)
throw
GetLastError
();
}
pipe
(
const
pipe
&
)
=
delete
;
pipe
&
operator
=
(
const
pipe
&
)
=
delete
;
pipe
(
pipe
&&
)
=
default
;
~
pipe
()
{
CloseHandle
(
m_read
);
m_read
=
nullptr
;
CloseHandle
(
m_write
);
m_write
=
nullptr
;
}
std
::
optional
<
std
::
pair
<
bool
,
DWORD
>>
read
(
LPVOID
buffer
,
DWORD
length
)
const
{
DWORD
bytes_read
;
if
(
ReadFile
(
m_read
,
buffer
,
length
,
&
bytes_read
,
nullptr
)
==
FALSE
)
{
DWORD
error
{
GetLastError
()};
if
(
error
!=
ERROR_MORE_DATA
)
{
return
std
::
nullopt
;
}
return
{{
true
,
bytes_read
}};
}
return
{{
false
,
bytes_read
}};
}
HANDLE
get_read_handle
()
const
{
return
m_read
;
}
bool
write
(
LPCVOID
buffer
,
DWORD
length
)
const
{
DWORD
bytes_written
;
return
WriteFile
(
m_write
,
buffer
,
length
,
&
bytes_written
,
nullptr
)
==
TRUE
;
}
HANDLE
get_write_handle
()
const
{
return
m_write
;
}
private:
HANDLE
m_write
=
nullptr
,
m_read
=
nullptr
;
};
template
<
typename
F
>
int
exec
(
const
std
::
string
&
cmd
,
F
f
)
{
try
{
if
(
enabled
(
MIGRAPHX_TRACE_CMD_EXECUTE
{}))
std
::
cout
<<
cmd
<<
std
::
endl
;
STARTUPINFO
info
;
PROCESS_INFORMATION
process_info
;
pipe
in
{},
out
{};
ZeroMemory
(
&
info
,
sizeof
(
STARTUPINFO
));
info
.
cb
=
sizeof
(
STARTUPINFO
);
info
.
hStdError
=
out
.
get_write_handle
();
info
.
hStdOutput
=
out
.
get_write_handle
();
info
.
hStdInput
=
in
.
get_read_handle
();
info
.
dwFlags
|=
STARTF_USESTDHANDLES
;
ZeroMemory
(
&
process_info
,
sizeof
(
process_info
));
if
(
CreateProcess
(
nullptr
,
const_cast
<
LPSTR
>
(
cmd
.
c_str
()),
nullptr
,
nullptr
,
TRUE
,
0
,
nullptr
,
nullptr
,
&
info
,
&
process_info
)
==
FALSE
)
{
return
GetLastError
();
}
f
(
in
,
out
);
WaitForSingleObject
(
process_info
.
hProcess
,
INFINITE
);
DWORD
status
{};
GetExitCodeProcess
(
process_info
.
hProcess
,
&
status
);
CloseHandle
(
process_info
.
hProcess
);
CloseHandle
(
process_info
.
hThread
);
return
static_cast
<
int
>
(
status
);
}
// cppcheck-suppress catchExceptionByValue
catch
(
DWORD
last_error
)
{
return
last_error
;
}
}
int
exec
(
const
std
::
string
&
cmd
)
{
TCHAR
buffer
[
MIGRAPHX_PROCESS_BUFSIZE
];
HANDLE
std_out
{
GetStdHandle
(
STD_OUTPUT_HANDLE
)};
return
(
std_out
==
nullptr
or
std_out
==
INVALID_HANDLE_VALUE
)
?
GetLastError
()
:
exec
(
cmd
,
[
&
](
const
pipe
&
,
const
pipe
&
out
)
{
for
(;;)
{
if
(
auto
result
=
out
.
read
(
buffer
,
MIGRAPHX_PROCESS_BUFSIZE
))
{
auto
[
more_data
,
bytes_read
]
=
*
result
;
if
(
not
more_data
or
bytes_read
==
0
)
break
;
DWORD
written
;
if
(
WriteFile
(
std_out
,
buffer
,
bytes_read
,
&
written
,
nullptr
)
==
FALSE
)
break
;
}
}
});
}
int
exec
(
const
std
::
string
&
cmd
,
std
::
function
<
void
(
process
::
writer
)
>
std_in
)
{
return
exec
(
cmd
,
[
&
](
const
pipe
&
in
,
const
pipe
&
)
{
std_in
([
&
](
const
char
*
buffer
,
std
::
size_t
n
)
{
in
.
write
(
buffer
,
n
);
});
});
}
#endif
struct
process_impl
{
std
::
string
command
{};
...
...
@@ -119,7 +278,14 @@ process& process::cwd(const fs::path& p)
return
*
this
;
}
void
process
::
exec
()
{
impl
->
check_exec
(
impl
->
get_command
(),
redirect_to
(
std
::
cout
));
}
void
process
::
exec
()
{
#ifndef _WIN32
impl
->
check_exec
(
impl
->
get_command
(),
redirect_to
(
std
::
cout
));
#else
impl
->
check_exec
(
impl
->
get_command
());
#endif
}
void
process
::
write
(
std
::
function
<
void
(
process
::
writer
)
>
pipe_in
)
{
...
...
src/program.cpp
View file @
124f7d55
...
...
@@ -352,7 +352,7 @@ void program::finalize()
template
<
class
T
>
std
::
string
classify
(
T
x
)
{
switch
(
std
::
fpclassify
(
x
))
switch
(
std
::
fpclassify
(
static_cast
<
double
>
(
x
)
))
{
case
FP_INFINITE
:
return
"inf"
;
case
FP_NAN
:
return
"nan"
;
...
...
src/propagate_constant.cpp
View file @
124f7d55
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-202
2
Advanced Micro Devices, Inc. All rights reserved.
* Copyright (c) 2015-202
3
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
...
...
@@ -35,10 +35,10 @@ inline namespace MIGRAPHX_INLINE_NS {
MIGRAPHX_DECLARE_ENV_VAR
(
MIGRAPHX_TRACE_PROPAGATE_CONSTANT
)
bool
skip_prop
o
gate
(
instruction_ref
ins
)
bool
skip_prop
a
gate
(
instruction_ref
ins
)
{
if
(
ins
->
name
()
==
"contiguous"
)
return
skip_prop
o
gate
(
ins
->
inputs
().
front
());
return
skip_prop
a
gate
(
ins
->
inputs
().
front
());
auto
&&
s
=
ins
->
get_shape
();
if
(
s
.
broadcasted
()
and
not
s
.
scalar
())
return
true
;
...
...
@@ -47,7 +47,7 @@ bool skip_propogate(instruction_ref ins)
return
false
;
}
bool
is_const_ins
(
instruction_ref
ins
)
{
return
ins
->
can_eval
()
and
not
skip_prop
o
gate
(
ins
);
}
bool
is_const_ins
(
instruction_ref
ins
)
{
return
ins
->
can_eval
()
and
not
skip_prop
a
gate
(
ins
);
}
void
propagate_constant
::
apply
(
module
&
m
)
const
{
...
...
Prev
1
2
3
4
5
6
7
8
…
15
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