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
7f97b8ef
Unverified
Commit
7f97b8ef
authored
Oct 07, 2022
by
Ted Themistokleous
Committed by
GitHub
Oct 07, 2022
Browse files
Merge branch 'simplify_1_mul_div_ops' into divide_by_zero_check
parents
2ba401f0
d1fed367
Changes
448
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
372 additions
and
134 deletions
+372
-134
src/onnx/parse_lpnormalization.cpp
src/onnx/parse_lpnormalization.cpp
+1
-1
src/onnx/parse_matmul.cpp
src/onnx/parse_matmul.cpp
+2
-1
src/onnx/parse_mod.cpp
src/onnx/parse_mod.cpp
+26
-26
src/onnx/parse_nonmaxsuppression.cpp
src/onnx/parse_nonmaxsuppression.cpp
+17
-10
src/onnx/parse_nonzero.cpp
src/onnx/parse_nonzero.cpp
+1
-1
src/onnx/parse_pad.cpp
src/onnx/parse_pad.cpp
+1
-1
src/onnx/parse_pooling.cpp
src/onnx/parse_pooling.cpp
+2
-2
src/onnx/parse_pow.cpp
src/onnx/parse_pow.cpp
+1
-1
src/onnx/parse_resize.cpp
src/onnx/parse_resize.cpp
+2
-2
src/onnx/parse_reversesequence.cpp
src/onnx/parse_reversesequence.cpp
+1
-1
src/opt/memory_coloring.cpp
src/opt/memory_coloring.cpp
+1
-1
src/opt/memory_coloring_impl.cpp
src/opt/memory_coloring_impl.cpp
+16
-16
src/opt/memory_coloring_impl.hpp
src/opt/memory_coloring_impl.hpp
+2
-2
src/pad_calc.cpp
src/pad_calc.cpp
+90
-0
src/process.cpp
src/process.cpp
+1
-1
src/program.cpp
src/program.cpp
+94
-50
src/py/migraphx_py.cpp
src/py/migraphx_py.cpp
+53
-16
src/quantization.cpp
src/quantization.cpp
+1
-1
src/replace_allocate.cpp
src/replace_allocate.cpp
+1
-1
src/rewrite_gelu.cpp
src/rewrite_gelu.cpp
+59
-0
No files found.
src/onnx/parse_lpnormalization.cpp
View file @
7f97b8ef
...
...
@@ -31,7 +31,7 @@ namespace migraphx {
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
onnx
{
//
!
Parser for LpNormalization ONNX operator.
// Parser for LpNormalization ONNX operator.
/*!
Normalizes a tensor by the L1 or L2 norms along a given axis.
Norms that evaluate to 0 are changed to 1 to prevent division by zero.
...
...
src/onnx/parse_matmul.cpp
View file @
7f97b8ef
...
...
@@ -67,7 +67,8 @@ struct parse_matmul : op_parser<parse_matmul>
instruction_ref
bl0
=
l0
;
instruction_ref
bl1
=
l1
;
if
(
!
std
::
equal
(
l0_lens
.
rbegin
()
+
2
,
l0_lens
.
rend
(),
l1_lens
.
rbegin
()
+
2
,
l1_lens
.
rend
()))
if
(
not
std
::
equal
(
l0_lens
.
rbegin
()
+
2
,
l0_lens
.
rend
(),
l1_lens
.
rbegin
()
+
2
,
l1_lens
.
rend
()))
{
auto
l0_it
=
l0_lens
.
begin
()
+
l0_lens
.
size
()
-
2
;
std
::
vector
<
std
::
size_t
>
l0_broadcasted_lens
(
l0_lens
.
begin
(),
l0_it
);
...
...
src/
targets/gpu/include/migraphx/gpu/where.h
pp
→
src/
onnx/parse_mod.c
pp
View file @
7f97b8ef
...
...
@@ -21,44 +21,44 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MIGRAPHX_GUARD_RTGLIB_WHERE_HPP
#define MIGRAPHX_GUARD_RTGLIB_WHERE_HPP
#include <migraphx/gpu/oper.hpp>
#include <migraphx/gpu/device/where.hpp>
#include <migraphx/onnx/op_parser.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/instruction.hpp>
#include <migraphx/make_op.hpp>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
gpu
{
namespace
onnx
{
struct
hip_where
:
ternary_device
<
hip_where
,
device
::
where
>
struct
parse_mod
:
op_parser
<
parse_mod
>
{
shape
compute_shape
(
const
std
::
vector
<
shape
>&
inputs
)
const
std
::
vector
<
op_desc
>
operators
()
const
{
return
{{
"Mod"
}};
}
instruction_ref
parse
(
const
op_desc
&
/*opd*/
,
const
onnx_parser
&
parser
,
onnx_parser
::
node_info
info
,
std
::
vector
<
instruction_ref
>
args
)
const
{
check_shapes
{
inputs
,
*
this
}.
has
(
4
).
same_dims
();
auto
s1
=
inputs
.
at
(
1
);
auto
s2
=
inputs
.
at
(
2
);
if
(
s1
==
s2
and
s1
.
packed
())
{
return
s1
;
}
else
if
(
s1
.
packed
()
!=
s2
.
packed
())
std
::
string
mod
=
"mod"
;
if
(
is_type_float
(
args
[
0
]
->
get_shape
().
type
())
or
is_type_float
(
args
[
1
]
->
get_shape
().
type
()))
{
return
s1
.
packed
()
?
s1
:
s2
;
if
(
not
contains
(
info
.
attributes
,
"fmod"
))
{
MIGRAPHX_THROW
(
"Mod operator with float args and fmod=0 invalid"
);
}
}
else
if
(
s1
.
broadcasted
()
!=
s2
.
broadcasted
())
{
return
s1
.
broadcasted
()
?
s2
.
with_lens
(
s1
.
lens
())
:
s1
.
with_lens
(
s1
.
lens
());
}
else
if
(
contains
(
info
.
attributes
,
"fmod"
))
{
return
{
s1
.
type
(),
s1
.
lens
()};
if
(
parser
.
parse_value
(
info
.
attributes
.
at
(
"fmod"
)).
at
<
int
>
()
==
1
)
{
mod
=
"fmod"
;
}
}
return
info
.
add_common_op
(
mod
,
args
[
0
],
args
[
1
]);
}
};
}
// namespace
gpu
}
// namespace
onnx
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
#endif
src/
targets/gpu/include/migraphx/gpu/add.h
pp
→
src/
onnx/parse_nonmaxsuppression.c
pp
View file @
7f97b8ef
...
...
@@ -21,22 +21,29 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MIGRAPHX_GUARD_RTGLIB_ADD_HPP
#define MIGRAPHX_GUARD_RTGLIB_ADD_HPP
#include <migraphx/gpu/oper.hpp>
#include <migraphx/gpu/device/add.hpp>
#include <migraphx/onnx/op_parser.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/make_op.hpp>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
gpu
{
namespace
onnx
{
struct
hip_add
:
binary_device
<
hip_add
,
device
::
add
>
struct
parse_nonmaxsuppression
:
op_parser
<
parse_nonmaxsuppression
>
{
std
::
vector
<
op_desc
>
operators
()
const
{
return
{{
"NonMaxSuppression"
,
"nonmaxsuppression"
}};
}
instruction_ref
parse
(
const
op_desc
&
opd
,
const
onnx_parser
&
parser
,
const
onnx_parser
::
node_info
&
info
,
const
std
::
vector
<
instruction_ref
>&
args
)
const
{
auto
op
=
parser
.
load
(
opd
.
op_name
,
info
);
op
.
from_value
({{
"use_dyn_output"
,
parser
.
use_dyn_output
}});
return
info
.
add_instruction
(
op
,
args
);
}
};
}
// namespace
gpu
}
// namespace
onnx
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
#endif
src/onnx/parse_nonzero.cpp
View file @
7f97b8ef
...
...
@@ -37,7 +37,7 @@ static std::vector<std::size_t> nonzero_indices(const std::vector<T>& data)
std
::
vector
<
std
::
size_t
>
indices
;
for
(
std
::
size_t
i
=
0
;
i
<
data
.
size
();
++
i
)
{
if
(
!
float_equal
(
data
[
i
],
0
))
if
(
not
float_equal
(
data
[
i
],
0
))
indices
.
push_back
(
i
);
}
...
...
src/onnx/parse_pad.cpp
View file @
7f97b8ef
...
...
@@ -160,7 +160,7 @@ struct parse_pad : op_parser<parse_pad>
if
(
args
.
size
()
==
3
)
{
auto
val_ins
=
args
.
at
(
2
);
if
(
!
val_ins
->
can_eval
())
if
(
not
val_ins
->
can_eval
())
{
MIGRAPHX_THROW
(
"PARSE_PAD: input value must be constant"
);
}
...
...
src/onnx/parse_pooling.cpp
View file @
7f97b8ef
...
...
@@ -157,7 +157,7 @@ struct parse_pooling : op_parser<parse_pooling>
std
::
vector
<
int64_t
>
slice_end
;
tune_padding_size
(
values
,
paddings
,
count_include_pad
,
slice_start
);
if
(
!
slice_start
.
empty
())
if
(
not
slice_start
.
empty
())
{
// calculate expected output shape
orig_padding
.
insert
(
orig_padding
.
begin
()
+
kdims
,
2
,
0
);
...
...
@@ -180,7 +180,7 @@ struct parse_pooling : op_parser<parse_pooling>
op
.
from_value
(
values
);
auto
l1
=
info
.
add_instruction
(
op
,
l0
);
if
(
!
slice_start
.
empty
())
if
(
not
slice_start
.
empty
())
{
std
::
vector
<
int64_t
>
axes
(
kdims
);
std
::
iota
(
axes
.
begin
(),
axes
.
end
(),
2
);
...
...
src/onnx/parse_pow.cpp
View file @
7f97b8ef
...
...
@@ -46,7 +46,7 @@ auto compute_type(shape::type_t t1, shape::type_t t2)
int
it1
=
t1
;
int
it2
=
t2
;
if
(
!
contains
(
op_order
,
it1
)
or
!
contains
(
op_order
,
it2
))
if
(
not
contains
(
op_order
,
it1
)
or
not
contains
(
op_order
,
it2
))
{
MIGRAPHX_THROW
(
"PARSE_POW: Input data type not supported!"
);
}
...
...
src/onnx/parse_resize.cpp
View file @
7f97b8ef
...
...
@@ -56,7 +56,7 @@ const auto& get_nearest_op(const std::string& mode)
return
static_cast
<
std
::
size_t
>
(
std
::
ceil
((
val
)));
}}};
if
(
!
contains
(
nearest_ops
,
mode
))
if
(
not
contains
(
nearest_ops
,
mode
))
{
MIGRAPHX_THROW
(
"PARSE_RESIZE: nearest_mode "
+
mode
+
" not supported!"
);
}
...
...
@@ -86,7 +86,7 @@ const auto& get_original_idx_op(const std::string& mode)
return
(
idx
+
0.5
)
/
scale
;
}}};
if
(
!
contains
(
idx_ops
,
mode
))
if
(
not
contains
(
idx_ops
,
mode
))
{
MIGRAPHX_THROW
(
"PARSE_RESIZE: coordinate_transformation_mode "
+
mode
+
" not supported!"
);
}
...
...
src/onnx/parse_reversesequence.cpp
View file @
7f97b8ef
...
...
@@ -31,7 +31,7 @@ namespace migraphx {
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
onnx
{
//
!
Parser for ReverseSequence ONNX operator.
// Parser for ReverseSequence ONNX operator.
/*!
Reverses the data along the time axis for the batches along the batch axis.
The sequence lengths can be given to reverse up to the given length for each batch, keeping the
...
...
src/opt/memory_coloring.cpp
View file @
7f97b8ef
...
...
@@ -29,7 +29,7 @@ inline namespace MIGRAPHX_INLINE_NS {
void
memory_coloring
::
apply
(
module
&
m
)
const
{
if
(
!
enabled
(
MIGRAPHX_DISABLE_MEMORY_COLORING
{}))
if
(
not
enabled
(
MIGRAPHX_DISABLE_MEMORY_COLORING
{}))
{
memory_coloring_impl
opt
(
&
m
,
allocation_op
,
verify
);
opt
.
run
();
...
...
src/opt/memory_coloring_impl.cpp
View file @
7f97b8ef
...
...
@@ -42,7 +42,7 @@ void memory_coloring_impl::run()
{
MIGRAPHX_DEBUG
(
dump_intervals
());
// Coloring
while
(
!
alloc_queue
.
empty
())
while
(
not
alloc_queue
.
empty
())
{
interval_ptr
interval
=
alloc_queue
.
top
();
allocate
(
interval
);
...
...
@@ -72,7 +72,7 @@ bool memory_coloring_impl::allocate(interval_ptr interval)
if
(
conflict_table
.
find
(
vn
)
!=
conflict_table
.
end
())
{
std
::
set
<
int
>&
vn_set
=
conflict_table
[
vn
];
const
std
::
set
<
int
>&
vn_set
=
conflict_table
[
vn
];
for
(
const
auto
&
iter
:
vn_set
)
{
live_range
*
range
=
live_ranges
[
iter
];
...
...
@@ -96,7 +96,7 @@ bool memory_coloring_impl::allocate(interval_ptr interval)
}
std
::
size_t
offset
=
0
;
while
(
!
conflict_queue
.
empty
())
while
(
not
conflict_queue
.
empty
())
{
live_range
*
range
=
conflict_queue
.
top
();
std
::
size_t
iter_offset
=
range
->
offset
;
...
...
@@ -149,7 +149,7 @@ void memory_coloring_impl::build()
{
def_interval
=
instr2_live
[
p_iter
];
bool
is_lit
=
is_literal
(
iter
);
if
(
is_allocate
(
iter
)
||
is_lit
)
if
(
is_allocate
(
iter
)
or
is_lit
)
{
live_range
&
range
=
def_interval
->
segment
;
def_interval
->
result
=
iter
->
get_shape
();
...
...
@@ -157,12 +157,12 @@ void memory_coloring_impl::build()
range
.
begin
=
cur_points
;
def_interval
->
def_point
=
cur_points
;
range
.
size
=
(
iter
->
get_shape
()).
bytes
();
if
(
!
is_lit
||
unify_literals
)
if
(
not
is_lit
or
unify_literals
)
alloc_queue
.
push
(
def_interval
);
live_set
.
erase
(
range
.
vn
);
}
}
else
if
(
!
is_param
(
iter
)
&&
!
is_outline
(
iter
)
&&
!
is_check_context
(
iter
))
else
if
(
not
is_param
(
iter
)
&&
not
is_outline
(
iter
)
&&
not
is_check_context
(
iter
))
{
is_dead
=
true
;
}
...
...
@@ -179,7 +179,7 @@ void memory_coloring_impl::build()
if
(
not
p_mod
->
has_instruction
(
arg
))
continue
;
if
(
is_param
(
arg
)
||
is_outline
(
arg
))
if
(
is_param
(
arg
)
or
is_outline
(
arg
))
{
if
(
is_output_param
(
arg
))
is_dead
=
false
;
...
...
@@ -235,7 +235,7 @@ void memory_coloring_impl::rewrite()
if
(
interval
->
get_begin
()
==
invalid_offset
)
continue
;
if
(
!
unify_literals
&&
interval
->
is_literal
)
if
(
not
unify_literals
&&
interval
->
is_literal
)
continue
;
std
::
size_t
offset
=
0
;
...
...
@@ -267,12 +267,12 @@ void memory_coloring_impl::verify()
{
for
(
int
i
=
0
;
i
<
num_of_lives
;
++
i
)
{
live_interval
&
interval
=
live_intervals
[
i
];
live_range
&
segment
=
interval
.
segment
;
const
live_interval
&
interval
=
live_intervals
[
i
];
const
live_range
&
segment
=
interval
.
segment
;
if
(
segment
.
begin
==
invalid_offset
)
{
// if(
!
interval.is_live_on_entry)
// if(
not
interval.is_live_on_entry)
// MIGRAPHX_THROW("interval is not live on entry");
continue
;
}
...
...
@@ -284,13 +284,13 @@ void memory_coloring_impl::verify()
int
vn
=
segment
.
vn
;
if
(
conflict_table
.
find
(
vn
)
!=
conflict_table
.
end
())
{
std
::
set
<
int
>&
vn_set
=
conflict_table
[
vn
];
const
std
::
set
<
int
>&
vn_set
=
conflict_table
[
vn
];
for
(
const
auto
&
iter
:
vn_set
)
{
live_range
*
range
=
live_ranges
[
iter
];
if
(
range
->
offset
==
invalid_offset
)
continue
;
if
(
!
is_disjoin
(
*
range
,
segment
))
if
(
not
is_disjoin
(
*
range
,
segment
))
MIGRAPHX_THROW
(
"range and segment is not disjoined"
);
}
}
...
...
@@ -319,8 +319,8 @@ void memory_coloring_impl::dump_intervals()
{
std
::
cout
<<
" segment:"
<<
i
;
std
::
cout
<<
" =>"
;
std
::
set
<
int
>&
table
=
conflict_table
[
i
];
for
(
auto
&
iter
:
table
)
const
std
::
set
<
int
>&
table
=
conflict_table
[
i
];
for
(
const
auto
&
iter
:
table
)
{
std
::
cout
<<
(
iter
)
<<
","
;
}
...
...
@@ -357,7 +357,7 @@ void live_interval::dump()
std
::
cout
<<
"id:"
<<
id
;
segment
.
dump
();
std
::
cout
<<
" uses:"
;
for
(
auto
&
iter
:
use_points
)
for
(
const
auto
&
iter
:
use_points
)
{
std
::
cout
<<
" "
<<
get_ins_enum
(
iter
)
<<
","
;
}
...
...
src/opt/memory_coloring_impl.hpp
View file @
7f97b8ef
...
...
@@ -125,11 +125,11 @@ struct memory_coloring_impl
static
bool
is_disjoin
(
const
live_range
&
range1
,
const
live_range
&
range2
)
{
if
((
range1
.
size
==
0
)
||
(
range2
.
size
==
0
))
if
((
range1
.
size
==
0
)
or
(
range2
.
size
==
0
))
return
false
;
auto
end1
=
range1
.
offset
+
range1
.
size
-
1
;
auto
end2
=
range2
.
offset
+
range2
.
size
-
1
;
return
((
end1
<
range2
.
offset
)
||
(
end2
<
range1
.
offset
));
return
((
end1
<
range2
.
offset
)
or
(
end2
<
range1
.
offset
));
}
void
verify
();
#ifdef MIGRAPHX_DEBUG_OPT
...
...
src/pad_calc.cpp
0 → 100644
View file @
7f97b8ef
/*
* 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/pad_calc.hpp>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
void
calculate_padding
(
int64_t
idx
,
std
::
vector
<
int64_t
>&
pads
,
int64_t
input_dim
,
int64_t
stride
,
int64_t
dilation
,
int64_t
weight_dim
,
bool
is_same_upper
)
{
int64_t
output_dim
=
(
input_dim
+
stride
-
1
)
/
stride
;
// round up result
int64_t
new_weight_dim
=
weight_dim
+
(
weight_dim
-
1
)
*
(
dilation
-
1
);
int64_t
pad
=
std
::
max
(
static_cast
<
int64_t
>
(
0
),
(
output_dim
-
1
)
*
stride
+
new_weight_dim
-
input_dim
);
auto
pad_ndims
=
pads
.
size
()
/
2
;
if
(
is_same_upper
)
{
pads
[
idx
]
=
pad
/
2
;
pads
[
idx
+
pad_ndims
]
=
pad
-
pad
/
2
;
}
else
{
pads
[
idx
+
pad_ndims
]
=
pad
/
2
;
pads
[
idx
]
=
pad
-
pad
/
2
;
}
}
std
::
vector
<
std
::
size_t
>
calc_dyn_auto_pad
(
std
::
vector
<
std
::
size_t
>
tensor_lens
,
std
::
vector
<
std
::
size_t
>
k_lens
,
std
::
vector
<
std
::
size_t
>
strides
,
std
::
vector
<
std
::
size_t
>
dilations
,
bool
use_upper
)
{
std
::
vector
<
std
::
size_t
>
padding
;
padding
.
resize
(
2
*
k_lens
.
size
());
for
(
std
::
size_t
i
=
0
;
i
<
padding
.
size
()
/
2
;
i
++
)
{
std
::
ptrdiff_t
input_dim
=
tensor_lens
[
i
];
std
::
ptrdiff_t
stride
=
strides
[
i
];
std
::
ptrdiff_t
weight_dim
=
k_lens
[
i
];
std
::
ptrdiff_t
dilation
=
dilations
[
i
];
std
::
ptrdiff_t
output_dim
=
(
input_dim
+
stride
-
1
)
/
stride
;
// round up result
std
::
ptrdiff_t
new_weight_dim
=
weight_dim
+
(
weight_dim
-
1
)
*
(
dilation
-
1
);
std
::
size_t
pad
=
std
::
max
(
static_cast
<
std
::
ptrdiff_t
>
(
0
),
(
output_dim
-
1
)
*
stride
+
new_weight_dim
-
input_dim
);
auto
pad_ndims
=
padding
.
size
()
/
2
;
if
(
use_upper
)
{
padding
[
i
]
=
pad
/
2
;
padding
[
i
+
pad_ndims
]
=
pad
-
pad
/
2
;
}
else
{
padding
[
i
+
pad_ndims
]
=
pad
/
2
;
padding
[
i
]
=
pad
-
pad
/
2
;
}
}
return
padding
;
}
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
src/process.cpp
View file @
7f97b8ef
...
...
@@ -50,7 +50,7 @@ int exec(const std::string& cmd, const std::function<void(const char*)>& std_out
{
// TODO: Use execve instead of popen
std
::
unique_ptr
<
FILE
,
decltype
(
closer
)
>
pipe
(
popen
(
cmd
.
c_str
(),
"r"
),
closer
);
// NOLINT
if
(
!
pipe
)
if
(
not
pipe
)
MIGRAPHX_THROW
(
"popen() failed: "
+
cmd
);
std
::
array
<
char
,
128
>
buffer
;
while
(
fgets
(
buffer
.
data
(),
buffer
.
size
(),
pipe
.
get
())
!=
nullptr
)
...
...
src/program.cpp
View file @
7f97b8ef
...
...
@@ -37,6 +37,7 @@
#include <migraphx/output_iterator.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/marker.hpp>
#include <migraphx/supported_segments.hpp>
#include <iostream>
#include <sstream>
#include <algorithm>
...
...
@@ -77,11 +78,11 @@ program& program::operator=(program p)
void
program
::
assign
(
const
program
&
p
)
{
if
(
!
impl
)
if
(
not
impl
)
{
impl
=
std
::
make_unique
<
program_impl
>
();
}
else
if
(
!
impl
->
modules
.
empty
())
else
if
(
not
impl
->
modules
.
empty
())
{
impl
->
modules
.
clear
();
}
...
...
@@ -167,13 +168,37 @@ target_assignments program::get_target_assignments(const std::vector<target>& ta
target_assignments
p
;
const
auto
*
mod
=
get_main_module
();
for
(
auto
it
:
iterator_for
(
*
mod
))
std
::
vector
<
std
::
pair
<
target
,
supported_segments
>>
target_subgraphs
;
target_subgraphs
.
reserve
(
targets
.
size
());
std
::
transform
(
targets
.
begin
(),
targets
.
end
(),
std
::
back_inserter
(
target_subgraphs
),
[
&
](
const
auto
&
t
)
{
return
std
::
make_pair
(
t
,
t
.
find_supported
(
mod
,
m
));
});
for
(
const
auto
ins
:
iterator_for
(
*
mod
))
{
auto
t
=
std
::
max_element
(
targets
.
begin
(),
targets
.
end
(),
[
it
,
m
](
const
target
&
lhs
,
const
target
&
rhs
)
{
return
lhs
.
is_supported
(
it
,
m
)
<
rhs
.
is_supported
(
it
,
m
);
});
p
.
add_assignment
(
it
,
t
->
name
());
if
(
contains
(
p
,
ins
))
{
continue
;
}
for
(
const
auto
&
[
target
,
subgraph
]
:
target_subgraphs
)
{
// can't pass a structured binding into lambda in C++17 so create a variable for it
const
auto
&
t
=
target
;
for
(
const
auto
&
segment
:
subgraph
)
{
const
auto
&
instructions
=
segment
.
instructions
;
if
(
not
contains
(
instructions
,
ins
))
{
continue
;
}
std
::
transform
(
instructions
.
begin
(),
instructions
.
end
(),
std
::
inserter
(
p
,
p
.
end
()),
[
&
](
auto
instr
)
{
return
std
::
make_pair
(
instr
,
t
.
name
());
});
}
}
}
return
p
;
}
...
...
@@ -317,9 +342,12 @@ std::vector<argument> generic_eval(const module* mod,
if
(
not
contains
(
params
,
param_name
))
MIGRAPHX_THROW
(
"Parameter not found: "
+
param_name
);
auto
param
=
params
[
param_name
];
if
(
param
.
get_shape
()
!=
ins
->
get_shape
())
// TODO: may want to check correct number of dimensions and/or was within bounds
if
(
not
ins
->
get_shape
().
dynamic
()
and
param
.
get_shape
()
!=
ins
->
get_shape
())
{
MIGRAPHX_THROW
(
"Incorrect shape {"
+
to_string
(
param
.
get_shape
())
+
"} for parameter: "
+
param_name
);
}
return
param
;
}));
}
...
...
@@ -362,7 +390,10 @@ std::vector<argument> generic_eval(const module* mod,
}));
}
assert
(
results
.
find
(
ins
)
!=
results
.
end
());
assert
(
results
.
at
(
ins
).
get_shape
()
==
ins
->
get_shape
());
if
(
not
ins
->
get_shape
().
dynamic
())
{
assert
(
results
.
at
(
ins
).
get_shape
()
==
ins
->
get_shape
());
}
}
return
{
results
.
at
(
std
::
prev
(
mod
->
end
()))};
}
...
...
@@ -377,7 +408,7 @@ std::vector<argument> generic_eval(const program& p,
return
generic_eval
(
mm
,
ctx
,
params
,
{},
make_trace
);
}
std
::
vector
<
argument
>
program
::
eval
(
parameter_map
params
)
const
std
::
vector
<
argument
>
program
::
eval
(
parameter_map
params
,
execution_environment
exec_env
)
const
{
auto
&
ctx
=
this
->
impl
->
ctx
;
#ifndef NDEBUG
...
...
@@ -402,6 +433,12 @@ std::vector<argument> program::eval(parameter_map params) const
#endif
auto
trace_level
=
value_of
(
MIGRAPHX_TRACE_EVAL
{});
std
::
vector
<
argument
>
ret
;
if
(
exec_env
.
async
)
{
ctx
.
wait_for
(
exec_env
.
queue
);
}
if
(
trace_level
>
0
)
{
...
...
@@ -413,49 +450,56 @@ std::vector<argument> program::eval(parameter_map params) const
ins_out
[
x
]
=
ss
.
str
();
});
ret
urn
generic_eval
(
*
this
,
ctx
,
std
::
move
(
params
),
with_check_context
([
&
](
auto
&
ins
,
auto
f
,
auto
&&
check_context
)
{
ctx
.
finish
();
std
::
cout
<<
"Run instruction: "
<<
ins_out
.
at
(
ins
)
<<
std
::
endl
;
timer
t
{};
auto
result
=
check_context
(
f
);
double
t1
=
t
.
record
<
milliseconds
>
();
ctx
.
finish
();
double
t2
=
t
.
record
<
milliseconds
>
();
std
::
cout
<<
"Time: "
<<
t1
<<
"ms, "
<<
t2
<<
"ms"
<<
std
::
endl
;
if
(
trace_level
>
1
and
ins
->
name
().
front
()
!=
'@'
and
ins
->
name
()
!=
"load"
and
not
result
.
empty
())
{
target
tgt
=
make_target
(
this
->
impl
->
target_name
);
auto
buffer
=
tgt
.
copy_from
(
result
);
if
(
trace_level
==
2
)
{
std
::
cout
<<
"Output has "
<<
to_string_range
(
classify_argument
(
buffer
))
<<
std
::
endl
;
std
::
cout
<<
"Output: "
;
preview_argument
(
std
::
cout
,
buffer
);
std
::
cout
<<
std
::
endl
;
}
else
{
std
::
cout
<<
"Output: "
<<
buffer
<<
std
::
endl
;
}
}
return
result
;
}));
ret
=
generic_eval
(
*
this
,
ctx
,
std
::
move
(
params
),
with_check_context
([
&
](
auto
&
ins
,
auto
f
,
auto
&&
check_context
)
{
ctx
.
finish
();
std
::
cout
<<
"Run instruction: "
<<
ins_out
.
at
(
ins
)
<<
std
::
endl
;
timer
t
{};
auto
result
=
check_context
(
f
);
double
t1
=
t
.
record
<
milliseconds
>
();
ctx
.
finish
();
double
t2
=
t
.
record
<
milliseconds
>
();
std
::
cout
<<
"Time: "
<<
t1
<<
"ms, "
<<
t2
<<
"ms"
<<
std
::
endl
;
if
(
trace_level
>
1
and
ins
->
name
().
front
()
!=
'@'
and
ins
->
name
()
!=
"load"
and
not
result
.
empty
())
{
target
tgt
=
make_target
(
this
->
impl
->
target_name
);
auto
buffer
=
tgt
.
copy_from
(
result
);
if
(
trace_level
==
2
)
{
std
::
cout
<<
"Output has "
<<
to_string_range
(
classify_argument
(
buffer
))
<<
std
::
endl
;
std
::
cout
<<
"Output: "
;
preview_argument
(
std
::
cout
,
buffer
);
std
::
cout
<<
std
::
endl
;
}
else
{
std
::
cout
<<
"Output: "
<<
buffer
<<
std
::
endl
;
}
}
return
result
;
}));
}
else
{
ret
urn
generic_eval
(
*
this
,
ctx
,
std
::
move
(
params
),
with_check_context
([
&
](
auto
&
,
auto
f
,
auto
&&
check_context
)
{
return
check_context
(
f
);
}));
ret
=
generic_eval
(
*
this
,
ctx
,
std
::
move
(
params
),
with_check_context
([
&
](
auto
&
,
auto
f
,
auto
&&
check_context
)
{
return
check_context
(
f
);
}));
}
if
(
exec_env
.
async
)
{
ctx
.
finish_on
(
exec_env
.
queue
);
}
return
ret
;
}
const
int
program_file_version
=
5
;
...
...
src/py/migraphx_py.cpp
View file @
7f97b8ef
...
...
@@ -40,6 +40,7 @@
#include <migraphx/register_target.hpp>
#include <migraphx/json.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/op/common.hpp>
#ifdef HAVE_GPU
#include <migraphx/gpu/hip.hpp>
...
...
@@ -82,7 +83,7 @@ void visit_py(T x, F f)
{
f
(
x
.
template
cast
<
bool
>());
}
else
if
(
py
::
isinstance
<
py
::
int_
>
(
x
))
else
if
(
py
::
isinstance
<
py
::
int_
>
(
x
)
or
py
::
hasattr
(
x
,
"__index__"
)
)
{
f
(
x
.
template
cast
<
int
>());
}
...
...
@@ -263,12 +264,13 @@ MIGRAPHX_PYBIND11_MODULE(migraphx, m)
py
::
class_
<
migraphx
::
argument
>
(
m
,
"argument"
,
py
::
buffer_protocol
())
.
def_buffer
([](
migraphx
::
argument
&
x
)
->
py
::
buffer_info
{
return
to_buffer_info
(
x
);
})
.
def
(
"__init__"
,
[](
migraphx
::
argument
&
x
,
py
::
buffer
b
)
{
py
::
buffer_info
info
=
b
.
request
();
new
(
&
x
)
migraphx
::
argument
(
to_shape
(
info
),
info
.
ptr
);
})
.
def
(
py
::
init
([](
py
::
buffer
b
)
{
py
::
buffer_info
info
=
b
.
request
();
return
migraphx
::
argument
(
to_shape
(
info
),
info
.
ptr
);
}))
.
def
(
"get_shape"
,
&
migraphx
::
argument
::
get_shape
)
.
def
(
"data_ptr"
,
[](
migraphx
::
argument
&
x
)
{
return
reinterpret_cast
<
std
::
uintptr_t
>
(
x
.
data
());
})
.
def
(
"tolist"
,
[](
migraphx
::
argument
&
x
)
{
py
::
list
l
{
x
.
get_shape
().
elements
()};
...
...
@@ -324,6 +326,7 @@ MIGRAPHX_PYBIND11_MODULE(migraphx, m)
.
def
(
"get_parameter_names"
,
&
migraphx
::
program
::
get_parameter_names
)
.
def
(
"get_parameter_shapes"
,
&
migraphx
::
program
::
get_parameter_shapes
)
.
def
(
"get_output_shapes"
,
&
migraphx
::
program
::
get_output_shapes
)
.
def
(
"is_compiled"
,
&
migraphx
::
program
::
is_compiled
)
.
def
(
"compile"
,
[](
migraphx
::
program
&
p
,
const
migraphx
::
target
&
t
,
bool
offload_copy
,
bool
fast_math
)
{
...
...
@@ -352,24 +355,58 @@ MIGRAPHX_PYBIND11_MODULE(migraphx, m)
}
return
p
.
eval
(
pm
);
})
.
def
(
"run_async"
,
[](
migraphx
::
program
&
p
,
py
::
dict
params
,
std
::
uintptr_t
stream
,
std
::
string
stream_name
)
{
migraphx
::
parameter_map
pm
;
for
(
auto
x
:
params
)
{
std
::
string
key
=
x
.
first
.
cast
<
std
::
string
>
();
py
::
buffer
b
=
x
.
second
.
cast
<
py
::
buffer
>
();
py
::
buffer_info
info
=
b
.
request
();
pm
[
key
]
=
migraphx
::
argument
(
to_shape
(
info
),
info
.
ptr
);
}
migraphx
::
execution_environment
exec_env
{
migraphx
::
any_ptr
(
reinterpret_cast
<
void
*>
(
stream
),
stream_name
),
true
};
return
p
.
eval
(
pm
,
exec_env
);
})
.
def
(
"sort"
,
&
migraphx
::
program
::
sort
)
.
def
(
"print"
,
[](
const
migraphx
::
program
&
p
)
{
std
::
cout
<<
p
<<
std
::
endl
;
})
.
def
(
"__eq__"
,
std
::
equal_to
<
migraphx
::
program
>
{})
.
def
(
"__ne__"
,
std
::
not_equal_to
<
migraphx
::
program
>
{})
.
def
(
"__repr__"
,
[](
const
migraphx
::
program
&
p
)
{
return
migraphx
::
to_string
(
p
);
});
py
::
class_
<
migraphx
::
operation
>
(
m
,
"op"
)
.
def
(
py
::
init
([](
const
std
::
string
&
name
,
py
::
kwargs
kwargs
)
{
migraphx
::
value
v
=
migraphx
::
value
::
object
{};
if
(
kwargs
)
{
v
=
migraphx
::
to_value
(
kwargs
);
}
return
migraphx
::
make_op
(
name
,
v
);
}))
py
::
class_
<
migraphx
::
operation
>
op
(
m
,
"op"
);
op
.
def
(
py
::
init
([](
const
std
::
string
&
name
,
py
::
kwargs
kwargs
)
{
migraphx
::
value
v
=
migraphx
::
value
::
object
{};
if
(
kwargs
)
{
v
=
migraphx
::
to_value
(
kwargs
);
}
return
migraphx
::
make_op
(
name
,
v
);
}))
.
def
(
"name"
,
&
migraphx
::
operation
::
name
);
py
::
enum_
<
migraphx
::
op
::
pooling_mode
>
(
op
,
"pooling_mode"
)
.
value
(
"average"
,
migraphx
::
op
::
pooling_mode
::
average
)
.
value
(
"max"
,
migraphx
::
op
::
pooling_mode
::
max
)
.
value
(
"lpnorm"
,
migraphx
::
op
::
pooling_mode
::
lpnorm
);
py
::
enum_
<
migraphx
::
op
::
rnn_direction
>
(
op
,
"rnn_direction"
)
.
value
(
"forward"
,
migraphx
::
op
::
rnn_direction
::
forward
)
.
value
(
"reverse"
,
migraphx
::
op
::
rnn_direction
::
reverse
)
.
value
(
"bidirectional"
,
migraphx
::
op
::
rnn_direction
::
bidirectional
);
m
.
def
(
"argument_from_pointer"
,
[](
const
migraphx
::
shape
shape
,
const
int64_t
address
)
{
return
migraphx
::
argument
(
shape
,
reinterpret_cast
<
void
*>
(
address
));
},
py
::
arg
(
"shape"
),
py
::
arg
(
"address"
));
m
.
def
(
"parse_tf"
,
[](
const
std
::
string
&
filename
,
...
...
src/quantization.cpp
View file @
7f97b8ef
...
...
@@ -70,7 +70,7 @@ void quantize_int8(program& prog,
{
std
::
set
<
std
::
string
>
op_names
=
{
"convolution"
,
"dot"
};
std
::
set
<
std
::
string
>
input_ins_names
(
ins_names
.
begin
(),
ins_names
.
end
());
if
(
!
std
::
includes
(
if
(
not
std
::
includes
(
op_names
.
begin
(),
op_names
.
end
(),
input_ins_names
.
begin
(),
input_ins_names
.
end
()))
{
MIGRAPHX_THROW
(
"QUANTIZE_INT8: only support DOT and CONVOLUTION operation"
);
...
...
src/replace_allocate.cpp
View file @
7f97b8ef
...
...
@@ -73,7 +73,7 @@ void insert_submod_allocations(instruction_ref ins, module& mod, const allocatio
name_shapes
.
insert
(
ps
.
begin
(),
ps
.
end
());
}
for
(
auto
&
pn
:
name_shapes
)
for
(
const
auto
&
pn
:
name_shapes
)
{
const
auto
&
s
=
pn
.
second
;
instruction_ref
output
{};
...
...
src/rewrite_gelu.cpp
0 → 100644
View file @
7f97b8ef
/*
* 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/rewrite_gelu.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/matcher.hpp>
#include <migraphx/match/gelu_erf.hpp>
#include <migraphx/common.hpp>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
struct
find_gelu_erf
{
auto
matcher
()
const
{
return
match
::
gelu_erf
();
}
void
apply
(
module
&
m
,
const
match
::
matcher_result
&
r
)
const
{
auto
ins
=
r
.
result
;
auto
x
=
r
.
instructions
[
"x"
];
if
(
x
->
get_shape
().
type
()
!=
migraphx
::
shape
::
half_type
)
return
;
auto
lit
=
m
.
add_literal
(
literal
{
shape
{
x
->
get_shape
().
type
()},
{
1.702
f
}});
auto
mul
=
insert_common_op
(
m
,
ins
,
make_op
(
"mul"
),
{
x
,
lit
});
auto
sig
=
m
.
insert_instruction
(
ins
,
make_op
(
"neg"
),
mul
);
sig
=
m
.
insert_instruction
(
ins
,
make_op
(
"exp"
),
sig
);
auto
one
=
m
.
add_literal
(
literal
{
shape
{
x
->
get_shape
().
type
()},
{
1.0
f
}});
sig
=
insert_common_op
(
m
,
ins
,
make_op
(
"add"
),
{
sig
,
one
});
sig
=
m
.
insert_instruction
(
ins
,
make_op
(
"div"
),
x
,
sig
);
m
.
replace_instruction
(
ins
,
sig
);
}
};
void
rewrite_gelu
::
apply
(
module
&
m
)
const
{
match
::
find_matches
(
m
,
find_gelu_erf
{});
}
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
Prev
1
2
3
4
5
6
7
8
9
10
…
23
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