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
124f7d55
Commit
124f7d55
authored
Oct 12, 2023
by
Umang Yadav
Browse files
Merge branch 'develop' into resnet50_partition
parents
350bbea2
34b68ee4
Changes
288
Show 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
...
@@ -34,6 +34,7 @@ struct MIGRAPHX_EXPORT tmp_dir
{
{
fs
::
path
path
;
fs
::
path
path
;
tmp_dir
(
const
std
::
string
&
prefix
=
""
);
tmp_dir
(
const
std
::
string
&
prefix
=
""
);
tmp_dir
(
tmp_dir
&&
)
=
default
;
void
execute
(
const
std
::
string
&
exe
,
const
std
::
string
&
args
)
const
;
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>
...
@@ -34,7 +34,7 @@ template <class PrivateMigraphTypeNameProbe>
std
::
string
compute_type_name
()
std
::
string
compute_type_name
()
{
{
std
::
string
name
;
std
::
string
name
;
#ifdef
_MSC_VER
#if
def
ined(
_MSC_VER
) && !defined(__clang__)
name
=
typeid
(
PrivateMigraphTypeNameProbe
).
name
();
name
=
typeid
(
PrivateMigraphTypeNameProbe
).
name
();
name
=
name
.
substr
(
7
);
name
=
name
.
substr
(
7
);
#else
#else
...
...
src/include/migraphx/verify.hpp
View file @
124f7d55
...
@@ -29,10 +29,13 @@
...
@@ -29,10 +29,13 @@
#include <functional>
#include <functional>
#include <iostream>
#include <iostream>
#include <numeric>
#include <numeric>
#include <assert.h>
#include <migraphx/float_equal.hpp>
#include <migraphx/float_equal.hpp>
#include <migraphx/config.hpp>
#include <migraphx/config.hpp>
#include <migraphx/env.hpp>
MIGRAPHX_DECLARE_ENV_VAR
(
MIGRAPHX_VERIFY_ENABLE_ALLCLOSE
)
namespace
migraphx
{
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
verify
{
namespace
verify
{
...
@@ -87,8 +90,7 @@ struct not_finite_fn
...
@@ -87,8 +90,7 @@ struct not_finite_fn
template
<
class
T
>
template
<
class
T
>
bool
operator
()(
T
x
)
const
bool
operator
()(
T
x
)
const
{
{
using
std
::
isfinite
;
return
not
std
::
isfinite
(
static_cast
<
double
>
(
x
));
return
not
isfinite
(
x
);
}
}
};
};
static
constexpr
not_finite_fn
not_finite
{};
static
constexpr
not_finite_fn
not_finite
{};
...
@@ -98,8 +100,7 @@ struct compare_mag_fn
...
@@ -98,8 +100,7 @@ struct compare_mag_fn
template
<
class
T
,
class
U
>
template
<
class
T
,
class
U
>
bool
operator
()(
T
x
,
U
y
)
const
bool
operator
()(
T
x
,
U
y
)
const
{
{
using
std
::
fabs
;
return
std
::
fabs
(
x
)
<
std
::
fabs
(
y
);
return
fabs
(
x
)
<
fabs
(
y
);
}
}
};
};
static
constexpr
compare_mag_fn
compare_mag
{};
static
constexpr
compare_mag_fn
compare_mag
{};
...
@@ -187,16 +188,103 @@ double rms_range(const R1& r1, const R2& r2)
...
@@ -187,16 +188,103 @@ double rms_range(const R1& r1, const R2& r2)
return
std
::
numeric_limits
<
range_value
<
R1
>>::
max
();
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
>
template
<
class
R1
,
class
R2
>
bool
verify_rang
e
(
const
R1
&
r1
,
const
R2
&
r2
,
double
tolerance
=
80
,
double
*
out_error
=
nullptr
)
bool
allclos
e
(
const
R1
&
r1
,
const
R2
&
r2
,
tolerance
tols
)
{
{
double
threshold
=
std
::
numeric_limits
<
range_value
<
R1
>>::
epsilon
()
*
tolerance
;
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_rms_range
(
const
R1
&
r1
,
const
R2
&
r2
,
std
::
size_t
tolerance
=
80
,
double
*
out_rms_error
=
nullptr
)
{
double
threshold
=
get_rms_tol
(
r1
,
tolerance
);
auto
error
=
rms_range
(
r1
,
r2
);
auto
error
=
rms_range
(
r1
,
r2
);
if
(
out_error
!=
nullptr
)
if
(
out_
rms_
error
!=
nullptr
)
*
out_error
=
error
;
*
out_
rms_
error
=
error
;
return
error
<=
threshold
;
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 verify
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
}
// namespace migraphx
...
...
src/include/migraphx/verify_args.hpp
View file @
124f7d55
...
@@ -31,11 +31,15 @@
...
@@ -31,11 +31,15 @@
namespace
migraphx
{
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
inline
namespace
MIGRAPHX_INLINE_NS
{
MIGRAPHX_EXPORT
MIGRAPHX_EXPORT
bool
verify_args
(
const
std
::
string
&
name
,
bool
verify_args
(
const
std
::
string
&
name
,
const
argument
&
ref_arg
,
const
argument
&
target_arg
,
const
argument
&
target_arg
,
double
tolerance
=
80
);
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_INLINE_NS
}
// namespace migraphx
}
// 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)
...
@@ -244,7 +244,7 @@ void onnx_parser::parse_from(std::istream& is, std::string name)
this
->
filename
=
std
::
move
(
name
);
this
->
filename
=
std
::
move
(
name
);
auto
parent_path
=
fs
::
path
(
this
->
filename
).
parent_path
();
auto
parent_path
=
fs
::
path
(
this
->
filename
).
parent_path
();
if
(
not
parent_path
.
empty
())
if
(
not
parent_path
.
empty
())
this
->
path
=
parent_path
;
this
->
path
=
parent_path
.
string
()
;
onnx
::
ModelProto
model
;
onnx
::
ModelProto
model
;
if
(
model
.
ParseFromIstream
(
&
is
))
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 @@
...
@@ -25,6 +25,7 @@
#include <migraphx/ranges.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/literal.hpp>
#include <migraphx/literal.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/stringutils.hpp>
namespace
migraphx
{
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
inline
namespace
MIGRAPHX_INLINE_NS
{
...
@@ -39,16 +40,38 @@ struct parse_constant : op_parser<parse_constant>
...
@@ -39,16 +40,38 @@ struct parse_constant : op_parser<parse_constant>
onnx_parser
::
node_info
info
,
onnx_parser
::
node_info
info
,
const
std
::
vector
<
instruction_ref
>&
/*args*/
)
const
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
// return empty literal
if
(
v
.
get_shape
().
elements
()
==
0
)
if
(
v
.
get_shape
().
elements
()
==
0
)
{
{
return
info
.
add_literal
(
literal
{
v
.
get_shape
().
type
()});
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 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
()};
migraphx
::
shape
scalar_shape
{
v
.
get_shape
().
type
()};
return
info
.
add_literal
(
migraphx
::
literal
{
scalar_shape
,
v
.
data
()});
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>
...
@@ -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!"
);
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
else
{
{
...
@@ -64,6 +66,9 @@ struct parse_constant_of_shape : op_parser<parse_constant_of_shape>
...
@@ -64,6 +66,9 @@ struct parse_constant_of_shape : op_parser<parse_constant_of_shape>
migraphx
::
shape
s
;
migraphx
::
shape
s
;
// input is empty, output is a scalar
// input is empty, output is a scalar
auto
type
=
l_val
.
get_shape
().
type
();
auto
type
=
l_val
.
get_shape
().
type
();
migraphx
::
argument
input
=
args
[
0
]
->
eval
();
if
(
not
input
.
empty
())
{
// empty input tensor, output is a scalar
// empty input tensor, output is a scalar
if
(
args
[
0
]
->
get_shape
().
elements
()
==
0
)
if
(
args
[
0
]
->
get_shape
().
elements
()
==
0
)
{
{
...
@@ -71,14 +76,10 @@ struct parse_constant_of_shape : op_parser<parse_constant_of_shape>
...
@@ -71,14 +76,10 @@ struct parse_constant_of_shape : op_parser<parse_constant_of_shape>
}
}
else
else
{
{
migraphx
::
argument
in
=
args
[
0
]
->
eval
();
check_arg_empty
(
in
,
"ConstantOfShape: dynamic shape is not supported"
);
std
::
vector
<
std
::
size_t
>
dims
;
std
::
vector
<
std
::
size_t
>
dims
;
in
.
visit
([
&
](
auto
i
nput
)
{
dims
.
assign
(
i
nput
.
begin
(),
i
nput
.
end
());
});
input
.
visit
([
&
](
auto
i
a
)
{
dims
.
assign
(
i
a
.
begin
(),
i
a
.
end
());
});
s
=
migraphx
::
shape
{
type
,
dims
};
s
=
migraphx
::
shape
{
type
,
dims
};
}
}
literal
l_out
{};
literal
l_out
{};
l_val
.
visit
([
&
](
auto
val
)
{
l_val
.
visit
([
&
](
auto
val
)
{
using
val_type
=
std
::
remove_cv_t
<
typename
decltype
(
val
)
::
value_type
>
;
using
val_type
=
std
::
remove_cv_t
<
typename
decltype
(
val
)
::
value_type
>
;
...
@@ -86,9 +87,17 @@ struct parse_constant_of_shape : op_parser<parse_constant_of_shape>
...
@@ -86,9 +87,17 @@ struct parse_constant_of_shape : op_parser<parse_constant_of_shape>
std
::
vector
<
val_type
>
out_vec
(
s
.
elements
(),
val
.
front
());
std
::
vector
<
val_type
>
out_vec
(
s
.
elements
(),
val
.
front
());
l_out
=
literal
(
s
,
out_vec
);
l_out
=
literal
(
s
,
out_vec
);
});
});
return
info
.
add_literal
(
l_out
);
return
info
.
add_literal
(
l_out
);
}
}
// has variable input (dynamic shape buffer)
else
{
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
);
}
}
}
}
};
};
...
...
src/onnx/parse_depthtospace.cpp
View file @
124f7d55
...
@@ -87,8 +87,7 @@ struct parse_depthtospace : op_parser<parse_depthtospace>
...
@@ -87,8 +87,7 @@ struct parse_depthtospace : op_parser<parse_depthtospace>
auto
temp1
=
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
lens1
}}),
args
[
0
]);
auto
temp1
=
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
lens1
}}),
args
[
0
]);
auto
temp2
=
info
.
add_instruction
(
make_op
(
"transpose"
,
{{
"permutation"
,
perm
}}),
temp1
);
auto
temp2
=
info
.
add_instruction
(
make_op
(
"transpose"
,
{{
"permutation"
,
perm
}}),
temp1
);
return
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
lens2
}}),
return
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
lens2
}}),
temp2
);
info
.
make_contiguous
(
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>
...
@@ -53,8 +53,7 @@ struct parse_reshape : op_parser<parse_reshape>
s
.
visit
([
&
](
auto
v
)
{
copy
(
v
,
std
::
back_inserter
(
dims
));
});
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
}}),
args
[
0
]);
return
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
dims
}}),
cont
);
}
}
};
};
...
...
src/onnx/parse_resize.cpp
View file @
124f7d55
...
@@ -320,7 +320,8 @@ struct parse_resize : op_parser<parse_resize>
...
@@ -320,7 +320,8 @@ struct parse_resize : op_parser<parse_resize>
// get the number of dimensions
// get the number of dimensions
std
::
size_t
n_dim
=
out_lens
.
size
();
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
));
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
)
{
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>
...
@@ -37,15 +37,18 @@ struct parse_roialign : op_parser<parse_roialign>
std
::
vector
<
op_desc
>
operators
()
const
{
return
{{
"RoiAlign"
}};
}
std
::
vector
<
op_desc
>
operators
()
const
{
return
{{
"RoiAlign"
}};
}
instruction_ref
parse
(
const
op_desc
&
/*opd*/
,
instruction_ref
parse
(
const
op_desc
&
/*opd*/
,
const
onnx_parser
&
/*
parser
*/
,
const
onnx_parser
&
parser
,
onnx_parser
::
node_info
info
,
onnx_parser
::
node_info
info
,
const
std
::
vector
<
instruction_ref
>&
args
)
const
const
std
::
vector
<
instruction_ref
>&
args
)
const
{
{
std
::
string
coord_trans_mode
=
"half_pixel"
;
std
::
string
coord_trans_mode
=
if
(
contains
(
info
.
attributes
,
"coordinate_transformation_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
))
if
(
not
contains
({
"half_pixel"
,
"output_half_pixel"
},
coord_trans_mode
))
{
{
MIGRAPHX_THROW
(
"coordinate_transformation_mode
\"
"
+
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>
...
@@ -73,8 +73,7 @@ struct parse_spacetodepth : op_parser<parse_spacetodepth>
std
::
vector
<
int64_t
>
perm
=
{
0
,
3
,
5
,
1
,
2
,
4
};
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
temp1
=
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
trans_lens
}}),
args
[
0
]);
auto
temp2
=
info
.
add_instruction
(
make_op
(
"transpose"
,
{{
"permutation"
,
perm
}}),
temp1
);
auto
temp2
=
info
.
add_instruction
(
make_op
(
"transpose"
,
{{
"permutation"
,
perm
}}),
temp1
);
return
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
res_lens
}}),
return
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
res_lens
}}),
temp2
);
info
.
make_contiguous
(
temp2
));
}
}
};
};
...
...
src/optimize_module.cpp
View file @
124f7d55
/*
/*
* The MIT License (MIT)
* 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
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* of this software and associated documentation files (the "Software"), to deal
...
@@ -35,9 +35,13 @@ inline namespace MIGRAPHX_INLINE_NS {
...
@@ -35,9 +35,13 @@ inline namespace MIGRAPHX_INLINE_NS {
void
optimize_module
::
apply
(
module_pass_manager
&
mpm
)
const
void
optimize_module
::
apply
(
module_pass_manager
&
mpm
)
const
{
{
for
(
int
i
=
0
;
i
<
2
;
i
++
)
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
// loop to further optimize after initial transformations
for
(
int
j
=
0
;
j
<
2
;
j
++
)
{
{
mpm
.
run_pass
(
simplify_reshapes
{});
mpm
.
run_pass
(
simplify_reshapes
{});
mpm
.
run_pass
(
simplify_algebra
{});
mpm
.
run_pass
(
simplify_algebra
{});
}
mpm
.
run_pass
(
eliminate_common_subexpression
{});
mpm
.
run_pass
(
eliminate_common_subexpression
{});
mpm
.
run_pass
(
dead_code_elimination
{});
mpm
.
run_pass
(
dead_code_elimination
{});
mpm
.
run_pass
(
propagate_constant
{});
mpm
.
run_pass
(
propagate_constant
{});
...
...
src/process.cpp
View file @
124f7d55
...
@@ -26,13 +26,23 @@
...
@@ -26,13 +26,23 @@
#include <migraphx/env.hpp>
#include <migraphx/env.hpp>
#include <functional>
#include <functional>
#include <iostream>
#include <iostream>
#include <optional>
#ifdef _WIN32
// cppcheck-suppress definePrefix
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#else
#include <unistd.h>
#include <unistd.h>
#endif
namespace
migraphx
{
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
inline
namespace
MIGRAPHX_INLINE_NS
{
MIGRAPHX_DECLARE_ENV_VAR
(
MIGRAPHX_TRACE_CMD_EXECUTE
)
MIGRAPHX_DECLARE_ENV_VAR
(
MIGRAPHX_TRACE_CMD_EXECUTE
)
#ifndef _WIN32
std
::
function
<
void
(
const
char
*
)
>
redirect_to
(
std
::
ostream
&
os
)
std
::
function
<
void
(
const
char
*
)
>
redirect_to
(
std
::
ostream
&
os
)
{
{
return
[
&
](
const
char
*
x
)
{
os
<<
x
;
};
return
[
&
](
const
char
*
x
)
{
os
<<
x
;
};
...
@@ -74,6 +84,155 @@ int exec(const std::string& cmd, std::function<void(process::writer)> std_in)
...
@@ -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
struct
process_impl
{
{
std
::
string
command
{};
std
::
string
command
{};
...
@@ -119,7 +278,14 @@ process& process::cwd(const fs::path& p)
...
@@ -119,7 +278,14 @@ process& process::cwd(const fs::path& p)
return
*
this
;
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
)
void
process
::
write
(
std
::
function
<
void
(
process
::
writer
)
>
pipe_in
)
{
{
...
...
src/program.cpp
View file @
124f7d55
...
@@ -352,7 +352,7 @@ void program::finalize()
...
@@ -352,7 +352,7 @@ void program::finalize()
template
<
class
T
>
template
<
class
T
>
std
::
string
classify
(
T
x
)
std
::
string
classify
(
T
x
)
{
{
switch
(
std
::
fpclassify
(
x
))
switch
(
std
::
fpclassify
(
static_cast
<
double
>
(
x
)
))
{
{
case
FP_INFINITE
:
return
"inf"
;
case
FP_INFINITE
:
return
"inf"
;
case
FP_NAN
:
return
"nan"
;
case
FP_NAN
:
return
"nan"
;
...
...
src/propagate_constant.cpp
View file @
124f7d55
/*
/*
* The MIT License (MIT)
* 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
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* of this software and associated documentation files (the "Software"), to deal
...
@@ -35,10 +35,10 @@ inline namespace MIGRAPHX_INLINE_NS {
...
@@ -35,10 +35,10 @@ inline namespace MIGRAPHX_INLINE_NS {
MIGRAPHX_DECLARE_ENV_VAR
(
MIGRAPHX_TRACE_PROPAGATE_CONSTANT
)
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"
)
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
();
auto
&&
s
=
ins
->
get_shape
();
if
(
s
.
broadcasted
()
and
not
s
.
scalar
())
if
(
s
.
broadcasted
()
and
not
s
.
scalar
())
return
true
;
return
true
;
...
@@ -47,7 +47,7 @@ bool skip_propogate(instruction_ref ins)
...
@@ -47,7 +47,7 @@ bool skip_propogate(instruction_ref ins)
return
false
;
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
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