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
859dfa42
Commit
859dfa42
authored
Nov 09, 2023
by
charlie
Browse files
Merge branch 'develop' of github.com:ROCmSoftwarePlatform/AMDMIGraphX into simplify_dyn_reshape
parents
e055c6e5
35e5298e
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
729 additions
and
151 deletions
+729
-151
src/include/migraphx/op/normalize_attribute.hpp
src/include/migraphx/op/normalize_attribute.hpp
+2
-0
src/include/migraphx/op/slice.hpp
src/include/migraphx/op/slice.hpp
+322
-136
src/normalize_attributes.cpp
src/normalize_attributes.cpp
+8
-8
src/onnx/parse_slice.cpp
src/onnx/parse_slice.cpp
+3
-0
test/op_shape_test.cpp
test/op_shape_test.cpp
+230
-5
test/ref/slice.cpp
test/ref/slice.cpp
+163
-1
tools/accuracy/requirements.txt
tools/accuracy/requirements.txt
+1
-1
No files found.
src/include/migraphx/op/normalize_attribute.hpp
View file @
859dfa42
...
...
@@ -40,6 +40,8 @@ namespace op {
* 2. use_rank (default) vs use_len:
* `use_rank` sets the max value/index of the attribute as the rank of lens.
* `use_lens` sets the max value/index as the corresponding value in lens at the axes index.
* Uses the dynamic_dimension.max value for dynamic shapes. Returns the original vector
* (no normalization) if any of dynamic_dimension[axes] are not fixed.
* 3. `clip_min` vs. `not_clip_min` (default):
* Clip values less than the minimum to the minimum or not.
* 4. `include_min` vs. `exclude_min` (default):
...
...
src/include/migraphx/op/slice.hpp
View file @
859dfa42
...
...
@@ -38,6 +38,18 @@ namespace op {
/**
* Slice operator that accepts variable axes, starts and ends.
* All of `starts`, `ends`, and `axes` must be supplied by either
* their attribute or an input (but not both).
*
* Valid calls:
* slice(input); axes, starts, ends set
* slice(input, starts); axes, ends set
* slice(input, ends); starts, axes set
* slice(input, axes); starts, ends set
* slice(input, starts, ends); axes set
* slice(input, starts, axes); ends set
* slice(input, ends, axes); starts set
* slice(input, start, ends, axes); none set
*
* Attributes:
* axes: constant axes to slice over (optional)
...
...
@@ -46,8 +58,8 @@ namespace op {
*
* Parameters:
* data: the input tensor to slice (dynamic or static shape)
* input_starts: starting indic
i
es of slice (optional, static shape)
* input_ends: ending indic
i
es of slice (optional, static shape)
* input_starts: starting indices of slice (optional, static shape)
* input_ends: ending indices of slice (optional, static shape)
* input_axes: axes to slice over (optional, static shape)
*/
struct
slice
...
...
@@ -56,6 +68,18 @@ struct slice
std
::
vector
<
int64_t
>
starts
{};
std
::
vector
<
int64_t
>
ends
{};
/**
* Named arrays for the set attribute possibilities.
*/
static
constexpr
std
::
array
<
bool
,
3
>
all_set
=
{
true
,
true
,
true
};
static
constexpr
std
::
array
<
bool
,
3
>
ends_axes
=
{
false
,
true
,
true
};
static
constexpr
std
::
array
<
bool
,
3
>
starts_axes
=
{
true
,
false
,
true
};
static
constexpr
std
::
array
<
bool
,
3
>
starts_ends
=
{
true
,
true
,
false
};
static
constexpr
std
::
array
<
bool
,
3
>
axes_only
=
{
false
,
false
,
true
};
static
constexpr
std
::
array
<
bool
,
3
>
ends_only
=
{
false
,
true
,
false
};
static
constexpr
std
::
array
<
bool
,
3
>
starts_only
=
{
true
,
false
,
false
};
static
constexpr
std
::
array
<
bool
,
3
>
none_set
=
{
false
,
false
,
false
};
template
<
class
Self
,
class
F
>
static
auto
reflect
(
Self
&
self
,
F
f
)
{
...
...
@@ -63,24 +87,26 @@ struct slice
}
/**
* Ensure that attribute vectors axes, starts, and ends are all the same size and values are
* within limits.
* Ensure that attribute axes is within limits.
* Will attempt to normalize starts and ends; but will use the dynamic_dimension.max
* values for dynamic shapes. This makes it so you have to renormalize for
* non-fixed dynamic_dimensions.
*/
value
attributes
()
const
{
value
normalize
=
value
::
object
{};
normalize
[
"axes"
]
=
value
::
array
{
normalize_attribute
::
include_min
};
normalize
[
"starts"
]
=
value
::
array
{
normalize_attribute
::
clip_max
,
normalize_attribute
::
clip_min
,
normalize_attribute
::
include_max
,
normalize_attribute
::
use_len
,
normalize_attribute
::
include_min
};
normalize
[
"ends"
]
=
value
::
array
{
normalize_attribute
::
clip_max
,
normalize_attribute
::
clip_min
,
normalize_attribute
::
include_max
,
normalize_attribute
::
use_len
,
normalize_attribute
::
include_min
};
return
{{
"normalize_axes"
,
normalize
}};
value
normalize
_axes
=
value
::
object
{};
normalize
_axes
[
"axes"
]
=
value
::
array
{
normalize_attribute
::
include_min
};
normalize
_axes
[
"starts"
]
=
value
::
array
{
normalize_attribute
::
clip_max
,
normalize_attribute
::
clip_min
,
normalize_attribute
::
include_max
,
normalize_attribute
::
use_len
,
normalize_attribute
::
include_min
};
normalize
_axes
[
"ends"
]
=
value
::
array
{
normalize_attribute
::
clip_max
,
normalize_attribute
::
clip_min
,
normalize_attribute
::
include_max
,
normalize_attribute
::
use_len
,
normalize_attribute
::
include_min
};
return
{{
"normalize_axes"
,
normalize
_axes
}};
}
std
::
string
name
()
const
{
return
"slice"
;
}
...
...
@@ -88,7 +114,7 @@ struct slice
/**
* Computes the slice output shape dimensions for given starts, ends,and axes.
* Templated to also handle tensor views.
* Possib
i
ly different type between [in_starts, in_ends] and [in_axes] if in_axes is this
* Possibly different type between [in_starts, in_ends] and [in_axes] if in_axes is this
* object's axes attribute. Assumes in_starts and in_ends are normalized; in_axes are valid.
*/
template
<
class
A
,
class
B
>
...
...
@@ -104,62 +130,160 @@ struct slice
return
new_lens
;
}
shape
normalize_compute_shape
(
std
::
vector
<
shape
>
inputs
)
const
/// Get the attributes that are non-empty
std
::
array
<
bool
,
3
>
get_set_attributes
()
const
{
check_shapes
{
inputs
,
*
this
,
true
}.
has
(
1
,
3
,
4
);
auto
input_shape
=
inputs
[
0
];
if
(
inputs
.
size
()
==
1
)
std
::
array
<
std
::
vector
<
int64_t
>
,
3
>
attrs
=
{
this
->
starts
,
this
->
ends
,
this
->
axes
};
std
::
array
<
bool
,
3
>
bool_vec
;
std
::
transform
(
attrs
.
cbegin
(),
attrs
.
cend
(),
bool_vec
.
begin
(),
[](
auto
a
)
{
return
not
a
.
empty
();
});
return
bool_vec
;
}
/// Helper function for normalize_compute_shape()
shape
compute_two_or_more
(
std
::
vector
<
shape
>
inputs
)
const
{
auto
input_shape
=
inputs
[
0
];
auto
set_attributes
=
get_set_attributes
();
// check that inputs [1, end) are all 1D, have the same
// dimension, and are static
check_shapes
{
inputs
.
begin
()
+
1
,
inputs
.
end
(),
std
::
string
(
"SLICE: inputs (starts, ends, and input_axes)"
),
false
}
.
only_dims
(
1
)
.
same_dims
();
auto
dds
=
input_shape
.
to_dynamic
().
dyn_dims
();
if
(
inputs
.
size
()
==
2
)
{
auto
t
=
input_shape
.
type
();
if
(
input_shape
.
dynamic
()
and
std
::
any_of
(
axes
.
begin
(),
axes
.
end
(),
[
&
](
auto
axis
)
{
return
not
input_shape
.
dyn_dims
()[
axis
].
is_fixed
();
}))
if
(
set_attributes
==
ends_axes
)
{
MIGRAPHX_THROW
(
"SLICE: slicing is not allowed on non-fixed dynamic input axis "
);
// attr ends and axes set; inputs are (data, input_starts)
if
(
inputs
[
1
].
lens
().
at
(
0
)
!=
axes
.
size
())
{
MIGRAPHX_THROW
(
"SLICE: 2 input and attributes mismatch"
);
}
std
::
for_each
(
axes
.
cbegin
(),
axes
.
cend
(),
[
&
](
const
auto
&
axis
)
{
dds
.
at
(
axis
)
=
{
0
,
dds
.
at
(
axis
).
max
};
});
}
if
(
input_shape
.
dynamic
()
)
else
if
(
set_attributes
==
starts_axes
)
{
return
shape
{
t
,
lens_calc
(
input_shape
.
min_lens
(),
starts
,
ends
,
axes
),
lens_calc
(
input_shape
.
max_lens
(),
starts
,
ends
,
axes
),
{}};
// attr starts and axes set; inputs are (data, input_ends)
if
(
inputs
[
1
].
lens
().
at
(
0
)
!=
axes
.
size
())
{
MIGRAPHX_THROW
(
"SLICE: 2 input and attributes mismatch"
);
}
std
::
for_each
(
axes
.
cbegin
(),
axes
.
cend
(),
[
&
](
const
auto
&
axis
)
{
dds
.
at
(
axis
)
=
{
0
,
dds
.
at
(
axis
).
max
};
});
}
else
if
(
set_attributes
==
starts_ends
)
{
// attr starts and ends set; inputs are (data, input_axes)
if
(
inputs
[
1
].
lens
().
at
(
0
)
!=
starts
.
size
())
{
MIGRAPHX_THROW
(
"SLICE: 2 input and attributes mismatch"
);
}
std
::
transform
(
dds
.
begin
(),
dds
.
end
(),
dds
.
begin
(),
[](
auto
dd
)
{
return
shape
::
dynamic_dimension
{
0
,
dd
.
max
};
});
}
else
{
return
shape
{
t
,
lens_calc
(
input_shape
.
lens
(),
starts
,
ends
,
axes
),
input_shape
.
strides
()};
MIGRAPHX_THROW
(
"SLICE: Invalid 2 input and attributes configuration"
);
}
}
else
else
if
(
inputs
.
size
()
==
3
)
{
// check that starts, ends, and optionally input_axes are all 1D, have the same
// dimension, and are static
check_shapes
{
inputs
.
begin
()
+
1
,
inputs
.
end
(),
std
::
string
(
"SLICE: inputs (starts, ends, and input_axes)"
),
false
}
.
only_dims
(
1
)
.
same_dims
();
auto
dds
=
input_shape
.
to_dynamic
().
dyn_dims
();
if
(
inputs
.
size
()
==
3
)
if
(
set_attributes
==
axes_only
)
{
// attr axes set; inputs are (data, input_starts, input_ends)
if
(
inputs
[
1
].
lens
().
at
(
0
)
!=
axes
.
size
())
{
MIGRAPHX_THROW
(
"SLICE: inputs starts and ends do not have the same dimension "
"as the axes attribute"
);
MIGRAPHX_THROW
(
"SLICE: 3 input and attributes mismatch"
);
}
std
::
for_each
(
axes
.
cbegin
(),
axes
.
cend
(),
[
&
](
const
auto
&
axis
)
{
dds
.
at
(
axis
)
=
{
0
,
dds
.
at
(
axis
).
max
};
});
}
else
else
if
(
set_attributes
==
ends_only
)
{
// attr ends set; inputs are (data, input_starts, input_axes)
if
(
inputs
[
1
].
lens
().
at
(
0
)
!=
ends
.
size
())
{
MIGRAPHX_THROW
(
"SLICE: 3 input and attributes mismatch"
);
}
std
::
transform
(
dds
.
begin
(),
dds
.
end
(),
dds
.
begin
(),
[](
auto
dd
)
{
return
shape
::
dynamic_dimension
{
0
,
dd
.
max
};
});
}
else
if
(
set_attributes
==
starts_only
)
{
// if axes is an input, then all the output dimensions could be 0 to the max value
// attr starts set; inputs are (data, input_ends, input_axes)
if
(
inputs
[
1
].
lens
().
at
(
0
)
!=
starts
.
size
())
{
MIGRAPHX_THROW
(
"SLICE: 3 input and attributes mismatch"
);
}
std
::
transform
(
dds
.
begin
(),
dds
.
end
(),
dds
.
begin
(),
[](
auto
dd
)
{
return
shape
::
dynamic_dimension
{
0
,
dd
.
max
};
});
}
return
shape
{
input_shape
.
type
(),
dds
};
else
{
MIGRAPHX_THROW
(
"Invalid 3 input and attributes configuration"
);
}
}
else
{
// all 4 inputs (data, inputs_starts, input_ends, input_axes)
std
::
transform
(
dds
.
begin
(),
dds
.
end
(),
dds
.
begin
(),
[](
auto
dd
)
{
return
shape
::
dynamic_dimension
{
0
,
dd
.
max
};
});
}
return
shape
{
input_shape
.
type
(),
dds
};
}
// uses the normalize_axes flag to normalize axes, starts, and ends
shape
normalize_compute_shape
(
std
::
vector
<
shape
>
inputs
)
const
{
check_shapes
{
inputs
,
*
this
,
true
}.
has
(
1
,
2
,
3
,
4
);
if
(
inputs
.
size
()
==
1
)
{
auto
input_shape
=
inputs
[
0
];
auto
set_attributes
=
get_set_attributes
();
if
(
set_attributes
!=
all_set
)
{
MIGRAPHX_THROW
(
"SLICE 1_arg: Invalid 1 input and attributes configuration"
);
}
// NOTE: make sure to update how normalization works here if this type of slicing is
// changed to be allowed
if
(
input_shape
.
dynamic
()
and
std
::
any_of
(
axes
.
begin
(),
axes
.
end
(),
[
&
](
auto
axis
)
{
return
not
input_shape
.
dyn_dims
()[
axis
].
is_fixed
();
}))
{
MIGRAPHX_THROW
(
"SLICE 1_arg: slicing is not allowed on non-fixed dynamic input axis "
);
}
if
(
input_shape
.
dynamic
())
{
return
shape
{
input_shape
.
type
(),
lens_calc
(
input_shape
.
min_lens
(),
this
->
starts
,
this
->
ends
,
this
->
axes
),
lens_calc
(
input_shape
.
max_lens
(),
this
->
starts
,
this
->
ends
,
this
->
axes
),
{}};
}
else
{
return
shape
{
input_shape
.
type
(),
lens_calc
(
input_shape
.
lens
(),
this
->
starts
,
this
->
ends
,
this
->
axes
),
input_shape
.
strides
()};
}
}
else
{
return
compute_two_or_more
(
inputs
);
}
}
...
...
@@ -194,14 +318,14 @@ struct slice
/**
* Calculates the starting offset for the sliced tensor (for aliasing).
* Used
when the starts and/or the axes are inputs
.
* Used
for 2-4 inputs to `slice
.
*
* \param s static input shape
* \param input_starts starting indices of slice
* \param ax_vec axes to slice on
*/
template
<
class
IndView
,
class
Axes
>
auto
compute_offset
(
const
shape
&
s
,
const
IndView
&
input_starts
,
const
Axes
&
ax_vec
)
const
template
<
class
T
>
auto
compute_offset
(
const
shape
&
s
,
const
T
&
input_starts
,
const
T
&
ax_vec
)
const
{
auto
ret
=
0
;
for
(
std
::
size_t
i
=
0
;
i
<
ax_vec
.
size
();
++
i
)
...
...
@@ -212,106 +336,168 @@ struct slice
return
ret
*
s
.
type_size
();
}
std
::
unordered_map
<
std
::
string
,
std
::
vector
<
int64_t
>>
normalize_inputs
(
const
shape
&
input_shape
,
const
std
::
vector
<
int64_t
>&
input_starts
,
const
std
::
vector
<
int64_t
>&
input_ends
)
const
{
auto
attrs
=
this
->
attributes
().
at
(
"normalize_axes"
);
return
{{
"input_starts"
,
normalize_indices
(
input_starts
,
this
->
axes
,
input_shape
,
attrs
.
at
(
"starts"
),
"Slice variable input_starts"
)},
{
"input_ends"
,
normalize_indices
(
input_ends
,
this
->
axes
,
input_shape
,
attrs
.
at
(
"ends"
),
"Slice variable input_ends"
)}};
}
/**
* Three input version of the normalize_inputs.
* This one also checks that the input_axes are valid.
* If given, normalize the inputs. Otherwise get from operator attributes.
* Return the values in a map.
*
* Parameters
* input_shape: static shape of the input
* input_starts: optional
* input_ends: optional
* input_ends: optional
*/
std
::
unordered_map
<
std
::
string
,
std
::
vector
<
int64_t
>>
normalize_
input
s
(
shape
input_shape
,
const
std
::
vector
<
int64_t
>&
input_starts
,
const
std
::
vector
<
int64_t
>&
input_ends
,
const
std
::
vector
<
int64_t
>&
input_axes
)
const
normalize_
starts_ends_axe
s
(
shape
input_shape
,
const
optional
<
std
::
vector
<
int64_t
>
>
&
input_starts
,
const
optional
<
std
::
vector
<
int64_t
>
>
&
input_ends
,
const
optional
<
std
::
vector
<
int64_t
>
>
&
input_axes
)
const
{
auto
attrs
=
this
->
attributes
().
at
(
"normalize_axes"
);
auto
norm_axes
=
normalize_axes
(
input_axes
,
input_shape
,
attrs
.
at
(
"axes"
),
"Slice variable input_axes"
);
return
{{
"input_starts"
,
normalize_indices
(
input_starts
,
norm_axes
,
input_shape
,
attrs
.
at
(
"starts"
),
"Slice variable input_starts"
)},
{
"input_ends"
,
normalize_indices
(
input_ends
,
norm_axes
,
input_shape
,
attrs
.
at
(
"ends"
),
"Slice variable input ends"
)},
{
"input_axes"
,
norm_axes
}};
auto
axes_attrs
=
this
->
attributes
().
at
(
"normalize_axes"
);
std
::
vector
<
int64_t
>
norm_starts
;
std
::
vector
<
int64_t
>
norm_ends
;
std
::
vector
<
int64_t
>
norm_axes
;
if
(
input_axes
)
{
norm_axes
=
normalize_axes
(
input_axes
.
value
(),
input_shape
,
axes_attrs
.
at
(
"axes"
),
"Slice variable input_axes"
);
}
else
{
norm_axes
=
this
->
axes
;
}
if
(
input_starts
)
{
norm_starts
=
normalize_indices
(
input_starts
.
value
(),
norm_axes
,
input_shape
,
axes_attrs
.
at
(
"starts"
),
"Slice variable input_starts"
);
}
else
{
norm_starts
=
this
->
starts
;
}
if
(
input_ends
)
{
norm_ends
=
normalize_indices
(
input_ends
.
value
(),
norm_axes
,
input_shape
,
axes_attrs
.
at
(
"ends"
),
"Slice variable input ends"
);
}
else
{
norm_ends
=
this
->
ends
;
}
return
{{
"norm_starts"
,
norm_starts
},
{
"norm_ends"
,
norm_ends
},
{
"norm_axes"
,
norm_axes
}};
}
argument
compute
(
const
dyn_output
&
dyn_out
,
std
::
vector
<
argument
>
args
)
const
{
auto
input
=
args
[
0
];
auto
input_shape
=
input
.
get_shape
();
switch
(
args
.
size
())
if
(
args
.
size
()
==
1
)
{
case
1
:
{
std
::
size_t
offset
=
compute_offset
(
input_shape
);
return
{
dyn_out
.
computed_shape
,
[
=
]
{
return
input
.
data
()
+
offset
;
}};
}
case
3
:
{
shape
calc_shape
;
std
::
size_t
offset
=
0
;
visit_all
(
args
[
1
],
args
[
2
])([
&
](
auto
input_starts
,
auto
input_ends
)
{
auto
norm_inputs
=
normalize_inputs
(
input_shape
,
input_starts
.
template
to_vector
<
int64_t
>(),
input_ends
.
template
to_vector
<
int64_t
>());
offset
=
compute_offset
(
input_shape
,
norm_inputs
.
at
(
"input_starts"
),
this
->
axes
);
calc_shape
=
{
input_shape
.
type
(),
lens_calc
(
input_shape
.
lens
(),
norm_inputs
.
at
(
"input_starts"
),
norm_inputs
.
at
(
"input_ends"
),
this
->
axes
),
input_shape
.
strides
()};
});
return
{
calc_shape
,
[
=
]
{
return
input
.
data
()
+
offset
;
}};
}
case
4
:
{
shape
calc_shape
;
std
::
size_t
offset
=
0
;
visit_all
(
args
[
1
],
args
[
2
],
args
[
3
])(
[
&
](
auto
input_starts
,
auto
input_ends
,
auto
input_axes
)
{
auto
norm_inputs
=
normalize_inputs
(
input_shape
,
input_starts
.
template
to_vector
<
int64_t
>(),
input_ends
.
template
to_vector
<
int64_t
>(),
input_axes
.
template
to_vector
<
int64_t
>());
offset
=
compute_offset
(
input_shape
,
norm_inputs
.
at
(
"input_starts"
),
norm_inputs
.
at
(
"input_axes"
));
calc_shape
=
shape
{
input_shape
.
type
(),
lens_calc
(
input_shape
.
lens
(),
norm_inputs
.
at
(
"input_starts"
),
norm_inputs
.
at
(
"input_ends"
),
norm_inputs
.
at
(
"input_axes"
)),
input_shape
.
strides
()};
else
{
// Note that we re-normalize both the attributes and inputs because of the non-fixed
// dynamic input shape case. It's possible to only re-normalize if slicing over
// non-fixed dynamic_dimensions.
auto
set_attributes
=
get_set_attributes
();
std
::
unordered_map
<
std
::
string
,
std
::
vector
<
int64_t
>>
norm_inputs
;
if
(
set_attributes
==
ends_axes
)
{
// attr ends and axes set; inputs are (data, input_starts)
args
[
1
].
visit
([
&
](
auto
input_starts
)
{
norm_inputs
=
normalize_starts_ends_axes
(
input_shape
,
input_starts
.
template
to_vector
<
int64_t
>(),
this
->
ends
,
this
->
axes
);
});
}
else
if
(
set_attributes
==
starts_axes
)
{
// attr starts and axes set; inputs are (data, input_ends)
args
[
1
].
visit
([
&
](
auto
input_ends
)
{
norm_inputs
=
normalize_starts_ends_axes
(
input_shape
,
this
->
starts
,
input_ends
.
template
to_vector
<
int64_t
>(),
this
->
axes
);
});
}
else
if
(
set_attributes
==
starts_ends
)
{
// attr starts and ends set; inputs are (data, input_axes)
args
[
1
].
visit
([
&
](
auto
input_axes
)
{
norm_inputs
=
normalize_starts_ends_axes
(
input_shape
,
this
->
starts
,
this
->
ends
,
input_axes
.
template
to_vector
<
int64_t
>());
});
}
else
if
(
set_attributes
==
axes_only
)
{
// attr axes set; inputs are (data, input_starts, input_ends)
visit_all
(
args
[
1
],
args
[
2
])([
&
](
auto
input_starts
,
auto
input_ends
)
{
norm_inputs
=
normalize_starts_ends_axes
(
input_shape
,
input_starts
.
template
to_vector
<
int64_t
>(),
input_ends
.
template
to_vector
<
int64_t
>(),
this
->
axes
);
});
}
else
if
(
set_attributes
==
ends_only
)
{
// attr ends set; inputs are (data, input_starts, input_axes)
visit_all
(
args
[
1
],
args
[
2
])([
&
](
auto
input_starts
,
auto
input_axes
)
{
norm_inputs
=
normalize_starts_ends_axes
(
input_shape
,
input_starts
.
template
to_vector
<
int64_t
>(),
this
->
ends
,
input_axes
.
template
to_vector
<
int64_t
>());
});
}
else
if
(
set_attributes
==
starts_only
)
{
// attr starts set; inputs are (data, input_ends, input_axes)
visit_all
(
args
[
1
],
args
[
2
])([
&
](
auto
input_ends
,
auto
input_axes
)
{
norm_inputs
=
normalize_starts_ends_axes
(
input_shape
,
this
->
starts
,
input_ends
.
template
to_vector
<
int64_t
>(),
input_axes
.
template
to_vector
<
int64_t
>());
});
}
else
{
// no attr set, all inputs
visit_all
(
args
[
1
],
args
[
2
],
args
[
3
])(
[
&
](
auto
input_starts
,
auto
input_ends
,
auto
input_axes
)
{
norm_inputs
=
normalize_starts_ends_axes
(
input_shape
,
input_starts
.
template
to_vector
<
int64_t
>(),
input_ends
.
template
to_vector
<
int64_t
>(),
input_axes
.
template
to_vector
<
int64_t
>());
});
}
auto
offset
=
compute_offset
(
input_shape
,
norm_inputs
.
at
(
"norm_starts"
),
norm_inputs
.
at
(
"norm_axes"
));
shape
calc_shape
=
shape
{
input_shape
.
type
(),
lens_calc
(
input_shape
.
lens
(),
norm_inputs
.
at
(
"norm_starts"
),
norm_inputs
.
at
(
"norm_ends"
),
norm_inputs
.
at
(
"norm_axes"
)),
input_shape
.
strides
()};
return
{
calc_shape
,
[
=
]
{
return
input
.
data
()
+
offset
;
}};
}
default:
{
// Should never get here; covering in case some code change occurs
MIGRAPHX_THROW
(
"SLICE: invalid number of inputs"
);
}
}
}
std
::
ptrdiff_t
output_alias
(
const
std
::
vector
<
shape
>&
)
const
{
return
0
;
}
...
...
src/normalize_attributes.cpp
View file @
859dfa42
...
...
@@ -66,15 +66,15 @@ auto tune_attribute(const std::vector<int64_t>& vec,
{
if
(
input_shape
.
dynamic
())
{
// return the unchanged `vec` if the dynamic_dimensions at `axes` are not fixed
if
(
std
::
any_of
(
axes
.
begin
(),
axes
.
end
(),
[
&
](
auto
ax
)
{
return
not
input_shape
.
dyn_dims
().
at
(
ax
).
is_fixed
();
}))
{
return
vec
;
}
std
::
transform
(
axes
.
begin
(),
axes
.
end
(),
max_vals
.
begin
(),
[
&
](
auto
i
)
{
const
auto
&
dd
=
input_shape
.
dyn_dims
().
at
(
i
);
if
(
not
dd
.
is_fixed
())
{
MIGRAPHX_THROW
(
"NORMALIZE_ATTR: 'use_lens' on a non-fixed dynamic dimension, axis="
+
std
::
to_string
(
i
));
}
return
dd
.
max
;
return
input_shape
.
dyn_dims
().
at
(
i
).
max
;
});
}
else
...
...
src/onnx/parse_slice.cpp
View file @
859dfa42
...
...
@@ -46,6 +46,9 @@ struct parse_slice : op_parser<parse_slice>
void
always_insert
(
instruction_ref
arg
)
{
op_args
.
insert
(
op_args
.
begin
(),
arg
);
}
/**
* Either insert argument into `this->op_args` or return the constant value of the argument
*/
std
::
vector
<
int64_t
>
insert
(
instruction_ref
arg
)
{
std
::
vector
<
int64_t
>
result
;
...
...
test/op_shape_test.cpp
View file @
859dfa42
...
...
@@ -3233,6 +3233,64 @@ TEST_CASE(slice_static_shape)
TEST_CASE
(
slice_var_inputs_static_shape0
)
{
// attr ends and axes set; inputs are (data, input_starts)
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
expect_shape
(
migraphx
::
shape
{
migraphx
::
shape
::
float_type
,
{{
3
,
3
},
{
0
,
4
},
{
0
,
4
}}},
migraphx
::
make_op
(
"slice"
,
{{
"ends"
,
{
2
,
3
}},
{
"axes"
,
{
1
,
2
}}}),
input
,
starts
);
}
TEST_CASE
(
slice_var_inputs_static_mismatch_error0
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
throws_shape
(
migraphx
::
make_op
(
"slice"
,
{{
"ends"
,
{
2
,
3
,
4
}},
{
"axes"
,
{
0
,
1
,
2
}}}),
input
,
starts
);
}
TEST_CASE
(
slice_var_inputs_static_shape1
)
{
// attr starts and axes set; inputs are (data, input_ends)
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
ends
{
migraphx
::
shape
::
int64_type
,
{
2
}};
expect_shape
(
migraphx
::
shape
{
migraphx
::
shape
::
float_type
,
{{
3
,
3
},
{
0
,
4
},
{
0
,
4
}}},
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
0
,
1
}},
{
"axes"
,
{
1
,
2
}}}),
input
,
ends
);
}
TEST_CASE
(
slice_var_inputs_static_mismatch_error1
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
ends
{
migraphx
::
shape
::
int64_type
,
{
2
}};
throws_shape
(
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
0
,
1
,
2
}},
{
"axes"
,
{
0
,
1
,
2
}}}),
input
,
ends
);
}
TEST_CASE
(
slice_var_inputs_static_shape2
)
{
// attr starts and ends set; inputs are (data, input_axes)
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
axes
{
migraphx
::
shape
::
int64_type
,
{
2
}};
expect_shape
(
migraphx
::
shape
{
migraphx
::
shape
::
float_type
,
{{
0
,
3
},
{
0
,
4
},
{
0
,
4
}}},
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
0
,
1
}},
{
"ends"
,
{
1
,
2
}}}),
input
,
axes
);
}
TEST_CASE
(
slice_var_inputs_static_mismatch_error2
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
axes
{
migraphx
::
shape
::
int64_type
,
{
2
}};
throws_shape
(
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
0
,
1
,
2
}},
{
"ends"
,
{
3
,
4
,
4
}}}),
input
,
axes
);
}
TEST_CASE
(
slice_var_inputs_static_shape3
)
{
// attr axes set; inputs are (data, input_starts, input_ends)
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
ends
{
migraphx
::
shape
::
int64_type
,
{
2
}};
...
...
@@ -3243,7 +3301,57 @@ TEST_CASE(slice_var_inputs_static_shape0)
ends
);
}
TEST_CASE
(
slice_var_inputs_static_shape1
)
TEST_CASE
(
slice_var_inputs_static_mismatch_error3
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
ends
{
migraphx
::
shape
::
int64_type
,
{
2
}};
throws_shape
(
migraphx
::
make_op
(
"slice"
,
{{
"axes"
,
{
0
,
1
,
2
}}}),
input
,
starts
,
ends
);
}
TEST_CASE
(
slice_var_inputs_static_shape4
)
{
// attr ends set; inputs are (data, input_starts, input_axes)
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
axes
{
migraphx
::
shape
::
int64_type
,
{
2
}};
expect_shape
(
migraphx
::
shape
{
migraphx
::
shape
::
float_type
,
{{
0
,
3
},
{
0
,
4
},
{
0
,
4
}}},
migraphx
::
make_op
(
"slice"
,
{{
"ends"
,
{
3
,
4
}}}),
input
,
starts
,
axes
);
}
TEST_CASE
(
slice_var_inputs_static_mismatch_error4
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
axes
{
migraphx
::
shape
::
int64_type
,
{
2
}};
throws_shape
(
migraphx
::
make_op
(
"slice"
,
{{
"ends"
,
{
3
,
3
,
3
}}}),
input
,
starts
,
axes
);
}
TEST_CASE
(
slice_var_inputs_static_shape5
)
{
// attr starts set; inputs are (data, input_ends, input_axes)
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
ends
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
axes
{
migraphx
::
shape
::
int64_type
,
{
2
}};
expect_shape
(
migraphx
::
shape
{
migraphx
::
shape
::
float_type
,
{{
0
,
3
},
{
0
,
4
},
{
0
,
4
}}},
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
0
,
2
}}}),
input
,
ends
,
axes
);
}
TEST_CASE
(
slice_var_inputs_static_mismatch_error5
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
ends
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
axes
{
migraphx
::
shape
::
int64_type
,
{
2
}};
throws_shape
(
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
0
,
1
,
2
}}}),
input
,
ends
,
axes
);
}
TEST_CASE
(
slice_var_inputs_static_shape6
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
...
...
@@ -3257,7 +3365,7 @@ TEST_CASE(slice_var_inputs_static_shape1)
axes
);
}
TEST_CASE
(
slice_var_inputs_static_error
0
)
TEST_CASE
(
slice_var_inputs_static_
mismatch_
error
6
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{
3
,
4
,
4
}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
...
...
@@ -3268,17 +3376,125 @@ TEST_CASE(slice_var_inputs_static_error0)
TEST_CASE
(
slice_var_inputs_dyn_shape0
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
2
,
4
,
{
2
,
4
}},
{
2
,
4
,
{
2
,
4
}}}};
// attr ends and axes set; inputs are (data, input_starts)
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
4
,
6
},
{
4
,
6
}}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
expect_shape
(
migraphx
::
shape
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
0
,
6
},
{
0
,
6
}}},
migraphx
::
make_op
(
"slice"
,
{{
"ends"
,
{
2
,
3
}},
{
"axes"
,
{
1
,
2
}}}),
input
,
starts
);
}
TEST_CASE
(
slice_var_inputs_dyn_mismatch_error0
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
4
,
6
},
{
4
,
6
}}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
throws_shape
(
migraphx
::
make_op
(
"slice"
,
{{
"ends"
,
{
2
,
3
,
4
}},
{
"axes"
,
{
0
,
1
,
2
}}}),
input
,
starts
);
}
TEST_CASE
(
slice_var_inputs_dyn_shape1
)
{
// attr starts and axes set; inputs are (data, input_ends)
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
4
,
6
},
{
4
,
6
}}};
migraphx
::
shape
ends
{
migraphx
::
shape
::
int64_type
,
{
2
}};
expect_shape
(
migraphx
::
shape
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
0
,
4
},
{
0
,
4
}}},
expect_shape
(
migraphx
::
shape
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
0
,
6
},
{
0
,
6
}}},
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
0
,
1
}},
{
"axes"
,
{
1
,
2
}}}),
input
,
ends
);
}
TEST_CASE
(
slice_var_inputs_dyn_mismatch_error1
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
4
,
6
},
{
4
,
6
}}};
migraphx
::
shape
ends
{
migraphx
::
shape
::
int64_type
,
{
2
}};
throws_shape
(
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
0
,
1
,
2
}},
{
"axes"
,
{
0
,
1
,
2
}}}),
input
,
ends
);
}
TEST_CASE
(
slice_var_inputs_dyn_shape2
)
{
// attr starts and ends set; inputs are (data, input_axes)
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
4
,
6
},
{
4
,
6
}}};
migraphx
::
shape
axes
{
migraphx
::
shape
::
int64_type
,
{
2
}};
expect_shape
(
migraphx
::
shape
{
migraphx
::
shape
::
float_type
,
{{
0
,
6
},
{
0
,
6
},
{
0
,
6
}}},
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
0
,
1
}},
{
"ends"
,
{
8
,
8
}}}),
input
,
axes
);
}
TEST_CASE
(
slice_var_inputs_dyn_mismatch_error2
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
4
,
6
},
{
4
,
6
}}};
migraphx
::
shape
axes
{
migraphx
::
shape
::
int64_type
,
{
2
}};
throws_shape
(
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
0
,
1
,
2
}},
{
"ends"
,
{
3
,
4
,
4
}}}),
input
,
axes
);
}
TEST_CASE
(
slice_var_inputs_dyn_shape3
)
{
// attr axes set; inputs are (data, input_starts, input_ends)
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
4
,
6
},
{
4
,
6
}}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
ends
{
migraphx
::
shape
::
int64_type
,
{
2
}};
expect_shape
(
migraphx
::
shape
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
0
,
6
},
{
0
,
6
}}},
migraphx
::
make_op
(
"slice"
,
{{
"axes"
,
{
1
,
2
}}}),
input
,
starts
,
ends
);
}
TEST_CASE
(
slice_var_inputs_dyn_shape1
)
TEST_CASE
(
slice_var_inputs_dyn_mismatch_error3
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
4
,
6
},
{
4
,
6
}}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
ends
{
migraphx
::
shape
::
int64_type
,
{
2
}};
throws_shape
(
migraphx
::
make_op
(
"slice"
,
{{
"axes"
,
{
0
,
1
,
2
}}}),
input
,
starts
,
ends
);
}
TEST_CASE
(
slice_var_inputs_dyn_shape4
)
{
// attr ends set; inputs are (data, input_starts, input_axes)
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
4
,
6
},
{
4
,
6
}}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
axes
{
migraphx
::
shape
::
int64_type
,
{
2
}};
expect_shape
(
migraphx
::
shape
{
migraphx
::
shape
::
float_type
,
{{
0
,
6
},
{
0
,
6
},
{
0
,
6
}}},
migraphx
::
make_op
(
"slice"
,
{{
"ends"
,
{
3
,
4
}}}),
input
,
starts
,
axes
);
}
TEST_CASE
(
slice_var_inputs_dyn_mismatch_error4
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
4
,
6
},
{
4
,
6
}}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
axes
{
migraphx
::
shape
::
int64_type
,
{
2
}};
throws_shape
(
migraphx
::
make_op
(
"slice"
,
{{
"ends"
,
{
3
,
3
,
3
}}}),
input
,
starts
,
axes
);
}
TEST_CASE
(
slice_var_inputs_dyn_shape5
)
{
// attr starts set; inputs are (data, input_ends, input_axes)
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
4
,
6
},
{
4
,
6
}}};
migraphx
::
shape
ends
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
axes
{
migraphx
::
shape
::
int64_type
,
{
2
}};
expect_shape
(
migraphx
::
shape
{
migraphx
::
shape
::
float_type
,
{{
0
,
6
},
{
0
,
6
},
{
0
,
6
}}},
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
0
,
2
}}}),
input
,
ends
,
axes
);
}
TEST_CASE
(
slice_var_inputs_dyn_mismatch_error5
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
4
,
6
},
{
4
,
6
}}};
migraphx
::
shape
ends
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
axes
{
migraphx
::
shape
::
int64_type
,
{
2
}};
throws_shape
(
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
0
,
1
,
2
}}}),
input
,
ends
,
axes
);
}
TEST_CASE
(
slice_var_inputs_dyn_shape6
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
2
,
4
,
{
2
,
4
}},
{
2
,
4
,
{
2
,
4
}}}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
...
...
@@ -3292,6 +3508,15 @@ TEST_CASE(slice_var_inputs_dyn_shape1)
axes
);
}
TEST_CASE
(
slice_var_inputs_dyn_mismatch_error6
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
float_type
,
{{
3
,
6
},
{
4
,
6
},
{
4
,
6
}}};
migraphx
::
shape
starts
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
ends
{
migraphx
::
shape
::
int64_type
,
{
2
}};
migraphx
::
shape
axes
{
migraphx
::
shape
::
int64_type
,
{
3
}};
throws_shape
(
migraphx
::
make_op
(
"slice"
),
input
,
starts
,
ends
,
axes
);
}
TEST_CASE
(
slice_dyn_shape0
)
{
migraphx
::
shape
input
{
migraphx
::
shape
::
int32_type
,
{{
2
,
3
},
{
7
,
7
},
{
2
,
3
}}};
...
...
test/ref/slice.cpp
View file @
859dfa42
...
...
@@ -157,7 +157,169 @@ TEST_CASE(slice_var_inputs_static2)
EXPECT
(
migraphx
::
verify
::
verify_rms_range
(
results_vector
,
gold
));
}
TEST_CASE
(
slice_var_inputs_dyn
)
TEST_CASE
(
slice_var_inputs_dyn0
)
{
migraphx
::
program
p
;
auto
*
mm
=
p
.
get_main_module
();
migraphx
::
shape
s0
{
migraphx
::
shape
::
int32_type
,
{{
2
,
4
,
{
2
,
4
}},
{
2
,
4
,
{
2
,
4
}},
{
3
,
8
}}};
auto
input
=
mm
->
add_parameter
(
"input"
,
s0
);
migraphx
::
shape
s1
{
migraphx
::
shape
::
int32_type
,
{
1
}};
auto
starts
=
mm
->
add_parameter
(
"starts"
,
s1
);
mm
->
add_instruction
(
migraphx
::
make_op
(
"slice"
,
{{
"axes"
,
{
2
}},
{
"ends"
,
{
10
}}}),
input
,
starts
);
p
.
compile
(
migraphx
::
make_target
(
"ref"
));
migraphx
::
parameter_map
params
;
migraphx
::
shape
s2
{
migraphx
::
shape
::
int32_type
,
{
2
,
2
,
3
}};
std
::
vector
<
int
>
input_data
(
2
*
2
*
3
);
std
::
iota
(
input_data
.
begin
(),
input_data
.
end
(),
0
);
std
::
vector
<
int
>
start_data
=
{
1
};
params
[
"input"
]
=
migraphx
::
argument
(
s2
,
input_data
.
data
());
params
[
"starts"
]
=
migraphx
::
argument
(
s1
,
start_data
.
data
());
auto
result
=
p
.
eval
(
params
).
back
();
std
::
vector
<
int
>
gold
=
{
1
,
2
,
4
,
5
,
7
,
8
,
10
,
11
};
std
::
vector
<
int
>
results_vector
(
2
*
2
*
2
);
result
.
visit
([
&
](
auto
output
)
{
results_vector
.
assign
(
output
.
begin
(),
output
.
end
());
});
EXPECT
(
migraphx
::
verify
::
verify_rms_range
(
results_vector
,
gold
));
}
TEST_CASE
(
slice_var_inputs_dyn1
)
{
migraphx
::
program
p
;
auto
*
mm
=
p
.
get_main_module
();
migraphx
::
shape
s0
{
migraphx
::
shape
::
int32_type
,
{{
2
,
4
,
{
2
,
4
}},
{
2
,
4
,
{
2
,
4
}},
{
3
,
8
}}};
auto
input
=
mm
->
add_parameter
(
"input"
,
s0
);
migraphx
::
shape
s1
{
migraphx
::
shape
::
int32_type
,
{
1
}};
auto
ends
=
mm
->
add_parameter
(
"ends"
,
s1
);
mm
->
add_instruction
(
migraphx
::
make_op
(
"slice"
,
{{
"axes"
,
{
2
}},
{
"starts"
,
{
-
5
}}}),
input
,
ends
);
p
.
compile
(
migraphx
::
make_target
(
"ref"
));
migraphx
::
parameter_map
params
;
migraphx
::
shape
s2
{
migraphx
::
shape
::
int32_type
,
{
2
,
2
,
3
}};
std
::
vector
<
int
>
input_data
(
2
*
2
*
3
);
std
::
iota
(
input_data
.
begin
(),
input_data
.
end
(),
0
);
std
::
vector
<
int
>
ends_data
=
{
3
};
params
[
"input"
]
=
migraphx
::
argument
(
s2
,
input_data
.
data
());
params
[
"ends"
]
=
migraphx
::
argument
(
s1
,
ends_data
.
data
());
auto
result
=
p
.
eval
(
params
).
back
();
std
::
vector
<
int
>
gold
=
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
};
std
::
vector
<
int
>
results_vector
(
2
*
2
*
3
);
result
.
visit
([
&
](
auto
output
)
{
results_vector
.
assign
(
output
.
begin
(),
output
.
end
());
});
EXPECT
(
migraphx
::
verify
::
verify_rms_range
(
results_vector
,
gold
));
}
TEST_CASE
(
slice_var_inputs_dyn2
)
{
migraphx
::
program
p
;
auto
*
mm
=
p
.
get_main_module
();
migraphx
::
shape
s0
{
migraphx
::
shape
::
int32_type
,
{{
2
,
4
,
{
2
,
4
}},
{
2
,
4
,
{
2
,
4
}},
{
3
,
8
}}};
auto
input
=
mm
->
add_parameter
(
"input"
,
s0
);
migraphx
::
shape
s1
{
migraphx
::
shape
::
int32_type
,
{
1
}};
auto
axes
=
mm
->
add_parameter
(
"axes"
,
s1
);
mm
->
add_instruction
(
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
1
}},
{
"ends"
,
{
-
1
}}}),
input
,
axes
);
p
.
compile
(
migraphx
::
make_target
(
"ref"
));
migraphx
::
parameter_map
params
;
migraphx
::
shape
s2
{
migraphx
::
shape
::
int32_type
,
{
2
,
2
,
3
}};
std
::
vector
<
int
>
input_data
(
2
*
2
*
3
);
std
::
iota
(
input_data
.
begin
(),
input_data
.
end
(),
0
);
std
::
vector
<
int
>
axes_data
=
{
2
};
params
[
"input"
]
=
migraphx
::
argument
(
s2
,
input_data
.
data
());
params
[
"axes"
]
=
migraphx
::
argument
(
s1
,
axes_data
.
data
());
auto
result
=
p
.
eval
(
params
).
back
();
std
::
vector
<
int
>
gold
=
{
1
,
4
,
7
,
10
};
std
::
vector
<
int
>
results_vector
(
2
*
2
*
1
);
result
.
visit
([
&
](
auto
output
)
{
results_vector
.
assign
(
output
.
begin
(),
output
.
end
());
});
EXPECT
(
migraphx
::
verify
::
verify_rms_range
(
results_vector
,
gold
));
}
TEST_CASE
(
slice_var_inputs_dyn3
)
{
migraphx
::
program
p
;
auto
*
mm
=
p
.
get_main_module
();
migraphx
::
shape
s0
{
migraphx
::
shape
::
int32_type
,
{{
2
,
4
,
{
2
,
4
}},
{
2
,
4
,
{
2
,
4
}},
{
3
,
8
}}};
auto
input
=
mm
->
add_parameter
(
"input"
,
s0
);
migraphx
::
shape
s1
{
migraphx
::
shape
::
int32_type
,
{
1
}};
auto
starts
=
mm
->
add_parameter
(
"starts"
,
s1
);
auto
ends
=
mm
->
add_parameter
(
"ends"
,
s1
);
mm
->
add_instruction
(
migraphx
::
make_op
(
"slice"
,
{{
"axes"
,
{
2
}}}),
input
,
starts
,
ends
);
p
.
compile
(
migraphx
::
make_target
(
"ref"
));
migraphx
::
parameter_map
params
;
migraphx
::
shape
s2
{
migraphx
::
shape
::
int32_type
,
{
2
,
2
,
3
}};
std
::
vector
<
int
>
input_data
(
2
*
2
*
3
);
std
::
iota
(
input_data
.
begin
(),
input_data
.
end
(),
0
);
std
::
vector
<
int
>
starts_data
=
{
1
};
std
::
vector
<
int
>
ends_data
=
{
std
::
numeric_limits
<
int
>::
max
()};
params
[
"input"
]
=
migraphx
::
argument
(
s2
,
input_data
.
data
());
params
[
"starts"
]
=
migraphx
::
argument
(
s1
,
starts_data
.
data
());
params
[
"ends"
]
=
migraphx
::
argument
(
s1
,
ends_data
.
data
());
auto
result
=
p
.
eval
(
params
).
back
();
std
::
vector
<
int
>
gold
=
{
1
,
2
,
4
,
5
,
7
,
8
,
10
,
11
};
std
::
vector
<
int
>
results_vector
(
2
*
2
*
2
);
result
.
visit
([
&
](
auto
output
)
{
results_vector
.
assign
(
output
.
begin
(),
output
.
end
());
});
EXPECT
(
migraphx
::
verify
::
verify_rms_range
(
results_vector
,
gold
));
}
TEST_CASE
(
slice_var_inputs_dyn4
)
{
migraphx
::
program
p
;
auto
*
mm
=
p
.
get_main_module
();
migraphx
::
shape
s0
{
migraphx
::
shape
::
int32_type
,
{{
2
,
4
,
{
2
,
4
}},
{
2
,
4
,
{
2
,
4
}},
{
3
,
8
}}};
auto
input
=
mm
->
add_parameter
(
"input"
,
s0
);
migraphx
::
shape
s1
{
migraphx
::
shape
::
int32_type
,
{
1
}};
auto
starts
=
mm
->
add_parameter
(
"starts"
,
s1
);
auto
axes
=
mm
->
add_parameter
(
"axes"
,
s1
);
mm
->
add_instruction
(
migraphx
::
make_op
(
"slice"
,
{{
"ends"
,
{
std
::
numeric_limits
<
int
>::
max
()}}}),
input
,
starts
,
axes
);
p
.
compile
(
migraphx
::
make_target
(
"ref"
));
migraphx
::
parameter_map
params
;
migraphx
::
shape
s2
{
migraphx
::
shape
::
int32_type
,
{
2
,
2
,
3
}};
std
::
vector
<
int
>
input_data
(
2
*
2
*
3
);
std
::
iota
(
input_data
.
begin
(),
input_data
.
end
(),
0
);
std
::
vector
<
int
>
starts_data
=
{
1
};
std
::
vector
<
int
>
axes_data
=
{
2
};
params
[
"input"
]
=
migraphx
::
argument
(
s2
,
input_data
.
data
());
params
[
"starts"
]
=
migraphx
::
argument
(
s1
,
starts_data
.
data
());
params
[
"axes"
]
=
migraphx
::
argument
(
s1
,
axes_data
.
data
());
auto
result
=
p
.
eval
(
params
).
back
();
std
::
vector
<
int
>
gold
=
{
1
,
2
,
4
,
5
,
7
,
8
,
10
,
11
};
std
::
vector
<
int
>
results_vector
(
2
*
2
*
2
);
result
.
visit
([
&
](
auto
output
)
{
results_vector
.
assign
(
output
.
begin
(),
output
.
end
());
});
EXPECT
(
migraphx
::
verify
::
verify_rms_range
(
results_vector
,
gold
));
}
TEST_CASE
(
slice_var_inputs_dyn5
)
{
migraphx
::
program
p
;
auto
*
mm
=
p
.
get_main_module
();
migraphx
::
shape
s0
{
migraphx
::
shape
::
int32_type
,
{{
2
,
4
,
{
2
,
4
}},
{
2
,
4
,
{
2
,
4
}},
{
3
,
8
}}};
auto
input
=
mm
->
add_parameter
(
"input"
,
s0
);
migraphx
::
shape
s1
{
migraphx
::
shape
::
int32_type
,
{
1
}};
auto
ends
=
mm
->
add_parameter
(
"ends"
,
s1
);
auto
axes
=
mm
->
add_parameter
(
"axes"
,
s1
);
mm
->
add_instruction
(
migraphx
::
make_op
(
"slice"
,
{{
"starts"
,
{
-
4
}}}),
input
,
ends
,
axes
);
p
.
compile
(
migraphx
::
make_target
(
"ref"
));
migraphx
::
parameter_map
params
;
migraphx
::
shape
s2
{
migraphx
::
shape
::
int32_type
,
{
2
,
2
,
3
}};
std
::
vector
<
int
>
input_data
(
2
*
2
*
3
);
std
::
iota
(
input_data
.
begin
(),
input_data
.
end
(),
0
);
std
::
vector
<
int
>
ends_data
=
{
2
};
std
::
vector
<
int
>
axes_data
=
{
2
};
params
[
"input"
]
=
migraphx
::
argument
(
s2
,
input_data
.
data
());
params
[
"ends"
]
=
migraphx
::
argument
(
s1
,
ends_data
.
data
());
params
[
"axes"
]
=
migraphx
::
argument
(
s1
,
axes_data
.
data
());
auto
result
=
p
.
eval
(
params
).
back
();
std
::
vector
<
int
>
gold
=
{
0
,
1
,
3
,
4
,
6
,
7
,
9
,
10
};
std
::
vector
<
int
>
results_vector
(
2
*
2
*
2
);
result
.
visit
([
&
](
auto
output
)
{
results_vector
.
assign
(
output
.
begin
(),
output
.
end
());
});
EXPECT
(
migraphx
::
verify
::
verify_rms_range
(
results_vector
,
gold
));
}
TEST_CASE
(
slice_var_inputs_dyn6
)
{
migraphx
::
program
p
;
auto
*
mm
=
p
.
get_main_module
();
...
...
tools/accuracy/requirements.txt
View file @
859dfa42
...
...
@@ -22,4 +22,4 @@
# THE SOFTWARE.
#####################################################################################
numpy==1.21.6
onnxruntime==1.16.
1
onnxruntime==1.16.
2
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