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
0c98c38e
"sgl-kernel/vscode:/vscode.git/clone" did not exist on "08f8f4901650c7da9a68c9eb19bbac81f296ff9c"
Unverified
Commit
0c98c38e
authored
Sep 12, 2023
by
Ted Themistokleous
Committed by
GitHub
Sep 12, 2023
Browse files
Merge branch 'develop' into enable_navi_32_ci
parents
1612d8f3
64b306ab
Changes
190
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
552 additions
and
239 deletions
+552
-239
src/include/migraphx/op/gather.hpp
src/include/migraphx/op/gather.hpp
+7
-8
src/include/migraphx/op/nonmaxsuppression.hpp
src/include/migraphx/op/nonmaxsuppression.hpp
+2
-2
src/include/migraphx/op/nonzero.hpp
src/include/migraphx/op/nonzero.hpp
+4
-4
src/include/migraphx/op/pooling.hpp
src/include/migraphx/op/pooling.hpp
+103
-23
src/include/migraphx/op/reduce_op.hpp
src/include/migraphx/op/reduce_op.hpp
+2
-2
src/include/migraphx/op/reverse.hpp
src/include/migraphx/op/reverse.hpp
+5
-5
src/include/migraphx/op/roialign.hpp
src/include/migraphx/op/roialign.hpp
+5
-6
src/include/migraphx/op/scatter.hpp
src/include/migraphx/op/scatter.hpp
+1
-1
src/include/migraphx/op/slice.hpp
src/include/migraphx/op/slice.hpp
+216
-66
src/include/migraphx/pad_calc.hpp
src/include/migraphx/pad_calc.hpp
+9
-1
src/include/migraphx/ranges.hpp
src/include/migraphx/ranges.hpp
+1
-1
src/include/migraphx/shape.hpp
src/include/migraphx/shape.hpp
+1
-1
src/include/migraphx/shape_for_each.hpp
src/include/migraphx/shape_for_each.hpp
+9
-5
src/include/migraphx/simplify_reshapes.hpp
src/include/migraphx/simplify_reshapes.hpp
+1
-0
src/include/migraphx/stringutils.hpp
src/include/migraphx/stringutils.hpp
+5
-1
src/memory_coloring.cpp
src/memory_coloring.cpp
+5
-3
src/normalize_attributes.cpp
src/normalize_attributes.cpp
+42
-14
src/onnx/parse_pooling.cpp
src/onnx/parse_pooling.cpp
+33
-22
src/onnx/parse_resize.cpp
src/onnx/parse_resize.cpp
+19
-25
src/onnx/parse_slice.cpp
src/onnx/parse_slice.cpp
+82
-49
No files found.
src/include/migraphx/op/gather.hpp
View file @
0c98c38e
/*
/*
* 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
...
@@ -125,13 +125,12 @@ struct gather
...
@@ -125,13 +125,12 @@ struct gather
auto
out_lens
=
data
.
get_shape
().
lens
();
auto
out_lens
=
data
.
get_shape
().
lens
();
out_lens
[
axis
]
=
indices
.
get_shape
().
elements
();
out_lens
[
axis
]
=
indices
.
get_shape
().
elements
();
migraphx
::
shape
out_comp_shape
{
data
.
get_shape
().
type
(),
out_lens
};
migraphx
::
shape
out_comp_shape
{
data
.
get_shape
().
type
(),
out_lens
};
shape_for_each
(
out_comp_shape
,
[
&
](
const
auto
&
out_idx
)
{
shape_for_each
(
out_comp_shape
,
[
&
](
const
auto
&
out_idx_v
,
size_t
out_idx
)
{
auto
data_idx
=
out_idx
;
auto
data_idx
=
out_idx
_v
;
auto
in_index
=
indices
[
data_idx
[
axis
]];
auto
in_index
=
indices
[
data_idx
[
axis
]];
in_index
=
(
in_index
<
0
)
?
in_index
+
axis_dim_size
:
in_index
;
in_index
=
(
in_index
<
0
)
?
in_index
+
axis_dim_size
:
in_index
;
data_idx
[
axis
]
=
in_index
;
data_idx
[
axis
]
=
in_index
;
output
[
out_comp_shape
.
index
(
out_idx
.
begin
(),
out_idx
.
end
())]
=
output
[
out_idx
]
=
data
(
data_idx
.
begin
(),
data_idx
.
end
());
data
(
data_idx
.
begin
(),
data_idx
.
end
());
});
});
}
}
});
});
...
...
src/include/migraphx/op/nonmaxsuppression.hpp
View file @
0c98c38e
/*
/*
* 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
...
@@ -258,7 +258,7 @@ struct nonmaxsuppression
...
@@ -258,7 +258,7 @@ struct nonmaxsuppression
selected_boxes_inside_class
.
reserve
(
max_output_shape
.
elements
());
selected_boxes_inside_class
.
reserve
(
max_output_shape
.
elements
());
// iterate over batches and classes
// iterate over batches and classes
shape
comp_s
{
shape
::
double_type
,
{
num_batches
,
num_classes
}};
shape
comp_s
{
shape
::
double_type
,
{
num_batches
,
num_classes
}};
shape_for_each
(
comp_s
,
[
&
](
auto
idx
)
{
shape_for_each
(
comp_s
,
[
&
](
const
auto
&
idx
)
{
auto
batch_idx
=
idx
[
0
];
auto
batch_idx
=
idx
[
0
];
auto
class_idx
=
idx
[
1
];
auto
class_idx
=
idx
[
1
];
// index offset for this class
// index offset for this class
...
...
src/include/migraphx/op/nonzero.hpp
View file @
0c98c38e
/*
/*
* 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
...
@@ -56,10 +56,10 @@ struct nonzero
...
@@ -56,10 +56,10 @@ struct nonzero
std
::
vector
<
std
::
vector
<
std
::
size_t
>>
vec_idx
;
std
::
vector
<
std
::
vector
<
std
::
size_t
>>
vec_idx
;
auto
s
=
args
.
front
().
get_shape
();
auto
s
=
args
.
front
().
get_shape
();
args
.
front
().
visit
([
&
](
auto
v
)
{
args
.
front
().
visit
([
&
](
auto
v
)
{
shape_for_each
(
s
,
[
&
](
auto
idx
)
{
shape_for_each
(
s
,
[
&
](
const
auto
&
idx_v
,
size_t
idx
)
{
if
(
not
float_equal
(
v
[
s
.
index
(
idx
)
],
0
))
if
(
not
float_equal
(
v
[
idx
],
0
))
{
{
vec_idx
.
push_back
(
idx
);
vec_idx
.
push_back
(
idx
_v
);
}
}
});
});
});
});
...
...
src/include/migraphx/op/pooling.hpp
View file @
0c98c38e
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
#include <migraphx/config.hpp>
#include <migraphx/config.hpp>
#include <migraphx/value.hpp>
#include <migraphx/value.hpp>
#include <migraphx/argument.hpp>
#include <migraphx/argument.hpp>
#include <migraphx/pad_calc.hpp>
#include <migraphx/par_for.hpp>
#include <migraphx/par_for.hpp>
#include <migraphx/shape_for_each.hpp>
#include <migraphx/shape_for_each.hpp>
#include <migraphx/dyn_output.hpp>
#include <migraphx/dyn_output.hpp>
...
@@ -40,10 +41,20 @@ namespace migraphx {
...
@@ -40,10 +41,20 @@ namespace migraphx {
inline
namespace
MIGRAPHX_INLINE_NS
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
op
{
namespace
op
{
// The Pooling operator mostly follows the specifications for the Onnx pooling op.
// It assumes an NCHW layout, extended to support any number of spatial dimensions
// from 1 on up; dimensions are <batch index, channels, spatial dimensions...>
//
struct
pooling
struct
pooling
{
{
// Class members mode, ceil_mode, padding_mode have similar names but refer to separate
// concepts.
pooling_mode
mode
=
{
pooling_mode
::
average
};
pooling_mode
mode
=
{
pooling_mode
::
average
};
// If the input has rank other than 4 then padding, stride, lengths must all be specified
// since the defaults have 2-dimensions. Exception: padding not required if
// padding_mode != default_
// Padding along each spatial input dimension
// Padding along each spatial input dimension
// Can be ndim or 2*ndim values where ndim is size of lengths
// Can be ndim or 2*ndim values where ndim is size of lengths
// ndim values means pad the same before and after each dimension
// ndim values means pad the same before and after each dimension
...
@@ -63,13 +74,14 @@ struct pooling
...
@@ -63,13 +74,14 @@ struct pooling
// ceiling mode is a flag affecting output size
// ceiling mode is a flag affecting output size
// or equivalently, placements of the pooling kernel.
// or equivalently, placements of the pooling kernel.
// When true, round the size upwards, possibly
// When true, round the size upwards. When false, round down so that all
// including partial placements where the kernel extends beyond the edge
// of input and even padding. When false, round down so that all
// kernel placements fit but some input values may be dropped.
// kernel placements fit but some input values may be dropped.
bool
ceil_mode
=
false
;
bool
ceil_mode
=
false
;
int
lp_order
=
2
;
int
lp_order
=
2
;
// Mode for auto padding. default_ indicates no auto padding.
padding_mode_t
padding_mode
=
padding_mode_t
::
default_
;
// Global pooling with dynamic shape input
// Global pooling with dynamic shape input
bool
dyn_global
=
false
;
bool
dyn_global
=
false
;
...
@@ -84,6 +96,7 @@ struct pooling
...
@@ -84,6 +96,7 @@ struct pooling
{
{
return
pack
(
f
(
self
.
mode
,
"mode"
),
return
pack
(
f
(
self
.
mode
,
"mode"
),
f
(
self
.
padding
,
"padding"
),
f
(
self
.
padding
,
"padding"
),
f
(
self
.
padding_mode
,
"padding_mode"
),
f
(
self
.
stride
,
"stride"
),
f
(
self
.
stride
,
"stride"
),
f
(
self
.
lengths
,
"lengths"
),
f
(
self
.
lengths
,
"lengths"
),
f
(
self
.
ceil_mode
,
"ceil_mode"
),
f
(
self
.
ceil_mode
,
"ceil_mode"
),
...
@@ -97,7 +110,8 @@ struct pooling
...
@@ -97,7 +110,8 @@ struct pooling
{
{
if
(
dyn_global
)
if
(
dyn_global
)
return
;
return
;
if
((
padding
.
size
()
!=
stride
.
size
()
and
(
padding
.
size
())
!=
stride
.
size
()
*
2
)
or
if
((
padding_mode
!=
default_
and
padding
.
size
()
!=
stride
.
size
()
and
(
padding
.
size
())
!=
stride
.
size
()
*
2
)
or
stride
.
size
()
!=
lengths
.
size
())
stride
.
size
()
!=
lengths
.
size
())
{
{
MIGRAPHX_THROW
(
"POOLING: inconsistent attribute sizes"
);
MIGRAPHX_THROW
(
"POOLING: inconsistent attribute sizes"
);
...
@@ -137,8 +151,19 @@ struct pooling
...
@@ -137,8 +151,19 @@ struct pooling
std
::
size_t
padding_factor
=
2
*
padding
[
i
];
std
::
size_t
padding_factor
=
2
*
padding
[
i
];
if
(
padding
.
size
()
==
2
*
kdims
)
if
(
padding
.
size
()
==
2
*
kdims
)
padding_factor
=
padding
[
i
]
+
padding
[
i
+
kdims
];
padding_factor
=
padding
[
i
]
+
padding
[
i
+
kdims
];
assert
(
input_lens
[
i
+
2
]
+
padding_factor
>=
lengths
[
i
]);
std
::
size_t
dim_size
;
std
::
size_t
dim_size
=
input_lens
[
i
+
2
]
+
padding_factor
-
lengths
[
i
];
if
(
input_lens
[
i
+
2
]
+
padding_factor
<
lengths
[
i
])
{
if
(
padding_mode
==
default_
)
MIGRAPHX_THROW
(
"POOLING: not enough padding for the given kernel size"
);
// lengths can be legitimately larger only if we're doing auto padding
// with a dynamic shape, in which case given padding is ignored. Set a dummy value.
dim_size
=
2
;
}
else
{
dim_size
=
input_lens
[
i
+
2
]
+
padding_factor
-
lengths
[
i
];
}
std
::
size_t
len
=
std
::
size_t
len
=
(
ceil_mode
)
(
ceil_mode
)
?
dim_size
/
stride
[
i
]
+
?
dim_size
/
stride
[
i
]
+
...
@@ -151,17 +176,13 @@ struct pooling
...
@@ -151,17 +176,13 @@ struct pooling
shape
normalize_compute_shape
(
std
::
vector
<
shape
>
inputs
)
const
shape
normalize_compute_shape
(
std
::
vector
<
shape
>
inputs
)
const
{
{
check_shapes
{
inputs
,
*
this
,
true
}.
has
(
1
);
check_shapes
{
inputs
,
*
this
,
true
}.
has
(
1
)
.
min_ndims
(
3
)
;
check_attribute_size
();
check_attribute_size
();
const
shape
&
input
=
inputs
.
at
(
0
);
const
shape
&
input
=
inputs
.
at
(
0
);
auto
padding
_size
=
padding
.
size
();
auto
stride
_size
=
stride
.
size
();
size_t
kdims
=
input
.
ndim
()
-
2
;
size_t
kdims
=
input
.
ndim
()
-
2
;
if
(
input
.
ndim
()
<
3
)
if
(
input
.
ndim
()
!=
stride_size
+
2
)
{
MIGRAPHX_THROW
(
"POOLING: input must have 3 or more dimensions and be nonempty"
);
}
if
(
input
.
ndim
()
*
2
!=
padding_size
+
4
and
input
.
ndim
()
!=
padding_size
+
2
)
{
{
MIGRAPHX_THROW
(
"POOLING: input and attribute size mismatch!"
);
MIGRAPHX_THROW
(
"POOLING: input and attribute size mismatch!"
);
}
}
...
@@ -179,6 +200,28 @@ struct pooling
...
@@ -179,6 +200,28 @@ struct pooling
}
}
return
{
input
.
type
(),
output_dyn_dims
};
return
{
input
.
type
(),
output_dyn_dims
};
}
}
else
if
(
padding_mode
!=
default_
)
{
const
size_t
num_spatial_dims
=
inputs
[
0
].
ndim
()
-
2
;
const
shape
&
x_shape
=
inputs
[
0
];
// same as convolution::dynamic_compute_shape()
for
(
std
::
size_t
i
=
0
;
i
<
num_spatial_dims
;
++
i
)
{
auto
ceil_div
=
[](
std
::
size_t
x
,
std
::
size_t
y
)
{
return
(
x
+
y
-
1
)
/
y
;
};
auto
s
=
stride
[
i
];
auto
x
=
x_shape
.
dyn_dims
()[
i
+
2
];
std
::
set
<
std
::
size_t
>
optimals
{};
std
::
transform
(
x
.
optimals
.
begin
(),
x
.
optimals
.
end
(),
std
::
inserter
(
optimals
,
optimals
.
begin
()),
[
&
](
auto
o
)
{
return
ceil_div
(
o
,
s
);
});
output_dyn_dims
.
push_back
(
shape
::
dynamic_dimension
{
ceil_div
(
x
.
min
,
s
),
ceil_div
(
x
.
max
,
s
),
optimals
});
}
return
{
input
.
type
(),
output_dyn_dims
};
}
else
else
{
{
// does not compute optimals
// does not compute optimals
...
@@ -267,6 +310,7 @@ struct pooling
...
@@ -267,6 +310,7 @@ struct pooling
Out
&
output
,
Out
&
output
,
const
In
&
input
,
const
In
&
input
,
const
std
::
vector
<
std
::
size_t
>&
kernel_dims
,
const
std
::
vector
<
std
::
size_t
>&
kernel_dims
,
const
std
::
vector
<
std
::
size_t
>&
padding_vals
,
Op
op
)
const
Op
op
)
const
{
{
auto
in_s
=
input
.
get_shape
();
auto
in_s
=
input
.
get_shape
();
...
@@ -284,8 +328,8 @@ struct pooling
...
@@ -284,8 +328,8 @@ struct pooling
for
(
std
::
size_t
dim
=
2
;
dim
<
n_dim
;
++
dim
)
for
(
std
::
size_t
dim
=
2
;
dim
<
n_dim
;
++
dim
)
{
{
auto
d_2
=
dim
-
2
;
auto
d_2
=
dim
-
2
;
int
start
=
int
start
=
static_cast
<
int
>
(
idx_o
[
dim
]
*
stride
[
d_2
])
-
static_cast
<
int
>
(
idx_o
[
dim
]
*
stride
[
d_2
])
-
static_cast
<
int
>
(
padding
[
d_2
]);
static_cast
<
int
>
(
padding
_vals
[
d_2
]);
int
end
;
int
end
;
// NOLINT
// NOLINT
if
(
count_include_pad
and
ceil_mode
and
(
mode
!=
pooling_mode
::
max
))
if
(
count_include_pad
and
ceil_mode
and
(
mode
!=
pooling_mode
::
max
))
...
@@ -297,7 +341,7 @@ struct pooling
...
@@ -297,7 +341,7 @@ struct pooling
// Check if this kernel extends beyond the padding at end of dimension
// Check if this kernel extends beyond the padding at end of dimension
end
=
std
::
min
(
start
+
kernel_dims
[
d_2
],
end
=
std
::
min
(
start
+
kernel_dims
[
d_2
],
in_lens
[
dim
]
+
static_cast
<
int
>
(
padding
[
d_2
]));
in_lens
[
dim
]
+
static_cast
<
int
>
(
padding
_vals
[
d_2
]));
}
}
else
else
{
{
...
@@ -316,11 +360,12 @@ struct pooling
...
@@ -316,11 +360,12 @@ struct pooling
}
}
shape
win_shape
{
output_shape
.
type
(),
win_size
};
shape
win_shape
{
output_shape
.
type
(),
win_size
};
auto
pool_size
=
win_shape
.
elements
();
auto
pool_size
=
win_shape
.
elements
();
double
output_val
=
op
.
template
init
<
Type
>();
double
output_val
=
op
.
template
init
<
Type
>();
// for each element in the window...
// for each element in the window...
shape_for_each
(
win_shape
,
[
&
](
auto
idx_w
)
{
shape_for_each
(
win_shape
,
[
&
](
const
auto
&
idx_w
)
{
// the coordinates of this element
// the coordinates of this element
auto
idx
=
idx_o
;
auto
idx
=
idx_o
;
...
@@ -354,30 +399,65 @@ struct pooling
...
@@ -354,30 +399,65 @@ struct pooling
argument
compute
(
const
dyn_output
&
dyn_out
,
std
::
vector
<
argument
>
args
)
const
argument
compute
(
const
dyn_output
&
dyn_out
,
std
::
vector
<
argument
>
args
)
const
{
{
argument
result
{
dyn_out
.
computed_shape
}
;
argument
result
;
auto
input_lens
=
args
[
0
].
get_shape
().
lens
();
auto
input_lens
=
args
[
0
].
get_shape
().
lens
();
std
::
vector
<
std
::
size_t
>
kernel_dims
;
std
::
vector
<
std
::
size_t
>
kernel_dims
;
shape
output_shape
;
// If we have to auto-calculate padding, it will be passed to calc_pooling() as an argument
// instead of the member variable padding.
std
::
vector
<
std
::
size_t
>
temp_padding
(
padding
);
if
(
dyn_global
)
if
(
dyn_global
)
{
{
// for dynamic GlobalPooling, there's no padding
kernel_dims
.
insert
(
kernel_dims
.
end
(),
input_lens
.
begin
()
+
2
,
input_lens
.
end
());
kernel_dims
.
insert
(
kernel_dims
.
end
(),
input_lens
.
begin
()
+
2
,
input_lens
.
end
());
output_shape
=
dyn_out
.
computed_shape
;
result
=
dyn_out
.
computed_shape
;
}
}
else
else
if
((
padding_mode
!=
op
::
padding_mode_t
::
default_
))
{
// if padding_mode is set, input was a dynamic size. Calculate padded size now.
// kernel_lens is the same as kernel_dims, but prepended with the 2 non-
// spatial dimensions. For size computations, it's used like the weights
// tensor for convolutions.
std
::
vector
<
std
::
size_t
>
kernel_lens
;
kernel_lens
.
insert
(
kernel_lens
.
end
(),
input_lens
.
begin
(),
input_lens
.
begin
()
+
2
);
kernel_lens
.
insert
(
kernel_lens
.
end
(),
lengths
.
begin
(),
lengths
.
end
());
kernel_dims
=
this
->
lengths
;
auto
type
=
args
[
0
].
get_shape
().
type
();
// dilation not currently supported for pooling, so default to all 1's
temp_padding
=
calc_dyn_auto_pad
(
input_lens
,
kernel_lens
,
stride
,
{
1
,
1
},
bool
(
padding_mode
==
op
::
same_upper
));
output_shape
=
compute_padded_pool_shape
(
args
[
0
].
get_shape
(),
shape
(
type
,
kernel_dims
),
temp_padding
,
stride
,
{
1
,
1
});
result
=
argument
(
output_shape
);
}
else
// fixed/static input
{
{
kernel_dims
=
this
->
lengths
;
kernel_dims
=
this
->
lengths
;
output_shape
=
dyn_out
.
computed_shape
;
result
=
dyn_out
.
computed_shape
;
}
}
// Perform the computation and populate result
visit_all
(
result
,
args
[
0
])([
&
](
auto
output
,
auto
input
)
{
visit_all
(
result
,
args
[
0
])([
&
](
auto
output
,
auto
input
)
{
using
type
=
typename
decltype
(
output
)
::
value_type
;
using
type
=
typename
decltype
(
output
)
::
value_type
;
switch
(
mode
)
switch
(
mode
)
{
{
case
migraphx
::
op
::
pooling_mode
::
average
:
case
migraphx
::
op
::
pooling_mode
::
average
:
calc_pooling
<
type
>
(
dyn_out
.
computed_shape
,
output
,
input
,
kernel_dims
,
avg_pool
{});
calc_pooling
<
type
>
(
output_shape
,
output
,
input
,
kernel_dims
,
temp_padding
,
avg_pool
{});
break
;
break
;
case
migraphx
::
op
::
pooling_mode
::
max
:
case
migraphx
::
op
::
pooling_mode
::
max
:
calc_pooling
<
type
>
(
dyn_out
.
computed_shape
,
output
,
input
,
kernel_dims
,
max_pool
{});
calc_pooling
<
type
>
(
output_shape
,
output
,
input
,
kernel_dims
,
temp_padding
,
max_pool
{});
break
;
break
;
case
migraphx
::
op
::
pooling_mode
::
lpnorm
:
case
migraphx
::
op
::
pooling_mode
::
lpnorm
:
calc_pooling
<
type
>
(
calc_pooling
<
type
>
(
dyn_out
.
com
put
ed
_shape
,
output
,
input
,
kernel_dims
,
lpnorm_pool
{
lp_order
});
out
put_shape
,
output
,
input
,
kernel_dims
,
temp_padding
,
lpnorm_pool
{
lp_order
});
break
;
break
;
}
}
});
});
...
...
src/include/migraphx/op/reduce_op.hpp
View file @
0c98c38e
/*
/*
* 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
...
@@ -163,7 +163,7 @@ struct reduce_op : op_name<Derived>
...
@@ -163,7 +163,7 @@ struct reduce_op : op_name<Derived>
auto
&
self
=
static_cast
<
const
Derived
&>
(
*
this
);
auto
&
self
=
static_cast
<
const
Derived
&>
(
*
this
);
auto
data_idx
=
out_idx
;
auto
data_idx
=
out_idx
;
accumulator
val
=
self
.
init
();
accumulator
val
=
self
.
init
();
shape_for_each
(
batch_shape
,
[
&
](
auto
b_idx
)
{
shape_for_each
(
batch_shape
,
[
&
](
const
auto
&
b_idx
)
{
this
->
tune_dims
(
tuned_axes
,
b_idx
,
data_idx
);
this
->
tune_dims
(
tuned_axes
,
b_idx
,
data_idx
);
accumulator
x
=
input
(
data_idx
.
begin
(),
data_idx
.
end
());
accumulator
x
=
input
(
data_idx
.
begin
(),
data_idx
.
end
());
val
=
self
.
op
()(
accumulator
{
self
.
input
()(
x
)},
val
);
val
=
self
.
op
()(
accumulator
{
self
.
input
()(
x
)},
val
);
...
...
src/include/migraphx/op/reverse.hpp
View file @
0c98c38e
/*
/*
* 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
...
@@ -70,13 +70,13 @@ struct reverse
...
@@ -70,13 +70,13 @@ struct reverse
argument
result
{
s
};
argument
result
{
s
};
auto
lens
=
s
.
lens
();
auto
lens
=
s
.
lens
();
visit_all
(
result
,
args
.
front
())([
&
](
auto
output
,
auto
input
)
{
visit_all
(
result
,
args
.
front
())([
&
](
auto
output
,
auto
input
)
{
shape_for_each
(
s
,
[
&
](
const
auto
&
out_idx
)
{
shape_for_each
(
s
,
[
&
](
const
auto
&
out_idx_v
,
size_t
out_idx
)
{
auto
in_idx
=
out_idx
;
auto
in_idx
=
out_idx
_v
;
for
(
const
auto
&
axis
:
axes
)
for
(
const
auto
&
axis
:
axes
)
{
{
in_idx
[
axis
]
=
lens
[
axis
]
-
1
-
out_idx
[
axis
];
in_idx
[
axis
]
=
lens
[
axis
]
-
1
-
out_idx
_v
[
axis
];
}
}
output
[
s
.
index
(
out_idx
)
]
=
input
[
s
.
index
(
in_idx
)];
output
[
out_idx
]
=
input
[
s
.
index
(
in_idx
)];
});
});
});
});
...
...
src/include/migraphx/op/roialign.hpp
View file @
0c98c38e
/*
/*
* 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
...
@@ -113,10 +113,9 @@ struct roialign
...
@@ -113,10 +113,9 @@ struct roialign
{
{
std
::
vector
<
pos_weight
>
results
(
bin_grid_size
[
0
]
*
bin_grid_size
[
1
]
*
output_height
*
std
::
vector
<
pos_weight
>
results
(
bin_grid_size
[
0
]
*
bin_grid_size
[
1
]
*
output_height
*
output_width
);
output_width
);
shape_for_each
(
comp_s
,
[
&
](
auto
idx
)
{
shape_for_each
(
comp_s
,
[
&
](
const
auto
&
idx_v
,
size_t
index
)
{
std
::
array
<
std
::
size_t
,
2
>
p
=
{
idx
[
0
],
idx
[
1
]};
std
::
array
<
std
::
size_t
,
2
>
p
=
{
idx_v
[
0
],
idx_v
[
1
]};
std
::
array
<
std
::
size_t
,
2
>
i
=
{
idx
[
2
],
idx
[
3
]};
std
::
array
<
std
::
size_t
,
2
>
i
=
{
idx_v
[
2
],
idx_v
[
3
]};
auto
index
=
comp_s
.
index
(
idx
);
std
::
array
<
float
,
2
>
xy
{};
std
::
array
<
float
,
2
>
xy
{};
std
::
array
<
int64_t
,
2
>
low
{};
std
::
array
<
int64_t
,
2
>
low
{};
...
@@ -255,7 +254,7 @@ struct roialign
...
@@ -255,7 +254,7 @@ struct roialign
std
::
vector
<
std
::
size_t
>
comp_lens1
=
{
channels
,
out_dims
[
0
],
out_dims
[
1
]};
std
::
vector
<
std
::
size_t
>
comp_lens1
=
{
channels
,
out_dims
[
0
],
out_dims
[
1
]};
shape
comp_s1
{
migraphx
::
shape
::
float_type
,
comp_lens1
};
shape
comp_s1
{
migraphx
::
shape
::
float_type
,
comp_lens1
};
std
::
vector
<
int64_t
>
vec_index
(
channels
,
0
);
std
::
vector
<
int64_t
>
vec_index
(
channels
,
0
);
shape_for_each
(
comp_s1
,
[
&
](
auto
idx
)
{
shape_for_each
(
comp_s1
,
[
&
](
const
auto
&
idx
)
{
auto
c
=
idx
[
0
];
auto
c
=
idx
[
0
];
auto
ph
=
idx
[
1
];
auto
ph
=
idx
[
1
];
auto
pw
=
idx
[
2
];
auto
pw
=
idx
[
2
];
...
...
src/include/migraphx/op/scatter.hpp
View file @
0c98c38e
/*
/*
* 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
...
...
src/include/migraphx/op/slice.hpp
View file @
0c98c38e
...
@@ -27,19 +27,34 @@
...
@@ -27,19 +27,34 @@
#include <migraphx/check_shapes.hpp>
#include <migraphx/check_shapes.hpp>
#include <migraphx/argument.hpp>
#include <migraphx/argument.hpp>
#include <migraphx/config.hpp>
#include <migraphx/config.hpp>
#include <migraphx/dyn_output.hpp>
#include <migraphx/value.hpp>
#include <migraphx/value.hpp>
#include <migraphx/dyn_output.hpp>
#include <migraphx/op/normalize_attribute.hpp>
#include <migraphx/op/normalize_attribute.hpp>
#include <migraphx/normalize_attributes.hpp>
namespace
migraphx
{
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
op
{
namespace
op
{
/**
* Slice operator that accepts variable axes, starts and ends.
*
* Attributes:
* axes: constant axes to slice over (optional)
* starts: constant slice starting indices (optional)
* ends: constant slice ending indices (optional)
*
* Parameters:
* data: the input tensor to slice (dynamic or static shape)
* input_starts: starting indicies of slice (optional, static shape)
* input_ends: ending indicies of slice (optional, static shape)
* input_axes: axes to slice over (optional, static shape)
*/
struct
slice
struct
slice
{
{
std
::
vector
<
int64_t
>
axes
;
std
::
vector
<
int64_t
>
axes
{}
;
std
::
vector
<
int64_t
>
starts
;
std
::
vector
<
int64_t
>
starts
{}
;
std
::
vector
<
int64_t
>
ends
;
std
::
vector
<
int64_t
>
ends
{}
;
template
<
class
Self
,
class
F
>
template
<
class
Self
,
class
F
>
static
auto
reflect
(
Self
&
self
,
F
f
)
static
auto
reflect
(
Self
&
self
,
F
f
)
...
@@ -48,8 +63,8 @@ struct slice
...
@@ -48,8 +63,8 @@ struct slice
}
}
/**
/**
* Ensure that attribute vectors axes, starts, and ends are all the same size and values are
in
* Ensure that attribute vectors axes, starts, and ends are all the same size and values are
* limits.
*
within
limits.
*/
*/
value
attributes
()
const
value
attributes
()
const
{
{
...
@@ -70,100 +85,235 @@ struct slice
...
@@ -70,100 +85,235 @@ struct slice
std
::
string
name
()
const
{
return
"slice"
;
}
std
::
string
name
()
const
{
return
"slice"
;
}
auto
compute_offset
(
const
shape
&
s
)
const
/**
{
* Computes the slice output shape dimensions for given starts, ends,and axes.
const
std
::
vector
<
std
::
size_t
>&
lens
=
s
.
lens
();
* Templated to also handle tensor views.
const
std
::
vector
<
std
::
size_t
>&
strides
=
s
.
strides
();
* Possibily different type between [in_starts, in_ends] and [in_axes] if in_axes is this
auto
offset
=
0
;
* object's axes attribute. Assumes in_starts and in_ends are normalized; in_axes are valid.
if
(
not
axes
.
empty
())
*/
{
template
<
class
A
,
class
B
>
for
(
std
::
size_t
i
=
0
;
i
<
axes
.
size
();
i
++
)
std
::
vector
<
std
::
size_t
>
{
lens_calc
(
const
std
::
vector
<
std
::
size_t
>&
lengths
,
A
in_starts
,
A
in_ends
,
B
in_axes
)
const
auto
axis
=
axes
[
i
];
offset
+=
starts
[
i
]
*
strides
[
axis
];
}
}
else
{
{
for
(
std
::
size_t
axis
=
0
;
axis
<
lens
.
size
();
axis
++
)
auto
new_lens
=
lengths
;
for
(
std
::
size_t
i
=
0
;
i
<
in_axes
.
size
();
++
i
)
{
{
offset
+=
starts
[
axis
]
*
strides
[
axis
];
auto
axis
=
in_axes
[
i
];
new_lens
[
axis
]
=
in_ends
[
i
]
-
in_starts
[
i
];
}
}
}
return
new_lens
;
return
offset
;
}
}
shape
normalize_compute_shape
(
std
::
vector
<
shape
>
inputs
)
const
shape
normalize_compute_shape
(
std
::
vector
<
shape
>
inputs
)
const
{
{
check_shapes
{
inputs
,
*
this
,
true
}.
has
(
1
);
check_shapes
{
inputs
,
*
this
,
true
}.
has
(
1
,
3
,
4
);
auto
input_shape
=
inputs
[
0
];
auto
input_shape
=
inputs
[
0
];
if
(
inputs
.
size
()
==
1
)
{
auto
t
=
input_shape
.
type
();
auto
t
=
input_shape
.
type
();
// TODO: When support for dynamic shapes is added to normalize_attributes,
// remove this restriction.
if
(
input_shape
.
dynamic
()
and
std
::
any_of
(
axes
.
begin
(),
axes
.
end
(),
[
&
](
auto
axis
)
{
if
(
input_shape
.
dynamic
()
and
std
::
any_of
(
axes
.
begin
(),
axes
.
end
(),
[
&
](
auto
axis
)
{
return
not
input_shape
.
dyn_dims
()[
axis
].
is_fixed
();
return
not
input_shape
.
dyn_dims
()[
axis
].
is_fixed
();
}))
}))
{
{
MIGRAPHX_THROW
(
"SLICE: slicing is not allowed on non-fixed dynamic input axis "
);
MIGRAPHX_THROW
(
"SLICE: slicing is not allowed on non-fixed dynamic input axis "
);
}
}
// For a static shape, old_lens will be adjusted to a new size
// for those axes that are sliced.
// For dynamic shape, the adjusted old_lens become the new max values,
// while updating the old mins and optimals if possible.
std
::
vector
<
std
::
size_t
>
new_mins
;
std
::
vector
<
std
::
size_t
>
old_lens
;
std
::
vector
<
std
::
size_t
>
old_strides
;
// Doesn't handle optimals
if
(
input_shape
.
dynamic
())
if
(
input_shape
.
dynamic
())
{
{
old_lens
=
input_shape
.
max_lens
();
return
shape
{
t
,
new_mins
=
input_shape
.
min_lens
();
lens_calc
(
input_shape
.
min_lens
(),
starts
,
ends
,
axes
),
lens_calc
(
input_shape
.
max_lens
(),
starts
,
ends
,
axes
),
{}};
}
else
{
return
shape
{
t
,
lens_calc
(
input_shape
.
lens
(),
starts
,
ends
,
axes
),
input_shape
.
strides
()};
}
}
else
{
// 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
(
inputs
[
1
].
lens
().
at
(
0
)
!=
axes
.
size
())
{
MIGRAPHX_THROW
(
"SLICE: inputs starts and ends do not have the same dimension "
"as the axes attribute"
);
}
std
::
for_each
(
axes
.
cbegin
(),
axes
.
cend
(),
[
&
](
const
auto
&
axis
)
{
dds
.
at
(
axis
)
=
{
0
,
dds
.
at
(
axis
).
max
};
});
}
}
else
else
{
{
old_lens
=
input_shape
.
lens
();
// if axes is an input, then all the output dimensions could be 0 to the max value
// For static shape (including during eval step after a dynamic input) the strides are
std
::
transform
(
dds
.
begin
(),
dds
.
end
(),
dds
.
begin
(),
[](
auto
dd
)
{
// indexed into the pre-slice array, so they are larger than the apparent size of the
return
shape
::
dynamic_dimension
{
0
,
dd
.
max
};
// resulting shape.
});
old_strides
=
input_shape
.
strides
();
}
return
shape
{
input_shape
.
type
(),
dds
};
}
}
}
std
::
vector
<
std
::
size_t
>
new_lens
=
old_lens
;
/**
* Calculates the starting offset for the sliced tensor.
* Used in compute when only data input and all other information are in the attributes.
*
* \param s static input shape
*/
auto
compute_offset
(
const
shape
&
s
)
const
{
const
std
::
vector
<
std
::
size_t
>&
lens
=
s
.
lens
();
const
std
::
vector
<
std
::
size_t
>&
strides
=
s
.
strides
();
auto
offset
=
0
;
if
(
not
axes
.
empty
())
{
for
(
std
::
size_t
i
=
0
;
i
<
axes
.
size
();
i
++
)
for
(
std
::
size_t
i
=
0
;
i
<
axes
.
size
();
i
++
)
{
{
auto
axis
=
axes
[
i
];
auto
axis
=
axes
[
i
];
size_t
sliced_length
=
ends
[
i
]
-
starts
[
i
];
offset
+=
starts
[
i
]
*
strides
[
axis
];
// A Numpy indexing convention: a slice size larger than the actual dimension
}
// is legal and the "ends" value is clipped to the axis size
}
new_lens
[
axis
]
=
std
::
min
(
new_lens
[
axis
],
sliced_length
);
else
if
(
input_shape
.
dynamic
())
{
for
(
std
::
size_t
axis
=
0
;
axis
<
lens
.
size
();
axis
++
)
{
{
// TODO: when non-fixed shape slicing is allowed, this will be different than
offset
+=
starts
[
axis
]
*
strides
[
axis
];
// sliced_length, making use of TBD start/end values.
std
::
size_t
sliced_min_length
=
ends
[
i
]
-
starts
[
i
];
// if the slice size is smaller than maxes but larger than mins
new_mins
[
axis
]
=
std
::
min
(
sliced_min_length
,
new_mins
[
axis
]);
}
}
}
}
if
(
input_shape
.
dynamic
())
return
offset
*
s
.
type_size
();
}
/**
* Calculates the starting offset for the sliced tensor (for aliasing).
* Used when the starts and/or the axes are inputs.
*
* \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
{
{
return
shape
{
t
,
new_mins
,
new_lens
,
{}};
auto
ret
=
0
;
for
(
std
::
size_t
i
=
0
;
i
<
ax_vec
.
size
();
++
i
)
{
auto
axis
=
ax_vec
[
i
];
ret
+=
input_starts
[
i
]
*
s
.
strides
().
at
(
axis
);
}
}
else
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
{
{
return
shape
{
t
,
new_lens
,
old_strides
};
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.
*/
std
::
unordered_map
<
std
::
string
,
std
::
vector
<
int64_t
>>
normalize_inputs
(
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
{
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
}};
}
}
argument
compute
(
const
dyn_output
&
dyn_out
,
std
::
vector
<
argument
>
args
)
const
argument
compute
(
const
dyn_output
&
dyn_out
,
std
::
vector
<
argument
>
args
)
const
{
{
auto
input
=
args
[
0
];
auto
input
=
args
[
0
];
auto
input_shape
=
input
.
get_shape
();
auto
offset
=
compute_offset
(
input
.
get_shape
())
*
dyn_out
.
computed_shape
.
type_size
();
switch
(
args
.
size
())
{
case
1
:
{
std
::
size_t
offset
=
compute_offset
(
input_shape
);
return
{
dyn_out
.
computed_shape
,
[
=
]
{
return
input
.
data
()
+
offset
;
}};
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
()};
});
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
;
}
std
::
ptrdiff_t
output_alias
(
const
std
::
vector
<
shape
>&
)
const
{
return
0
;
}
};
};
...
...
src/include/migraphx/pad_calc.hpp
View file @
0c98c38e
/*
/*
* 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
...
@@ -62,6 +62,14 @@ shape compute_padded_shape(const shape& input,
...
@@ -62,6 +62,14 @@ shape compute_padded_shape(const shape& input,
const
std
::
vector
<
std
::
size_t
>&
stride
,
const
std
::
vector
<
std
::
size_t
>&
stride
,
const
std
::
vector
<
std
::
size_t
>&
dilation
);
const
std
::
vector
<
std
::
size_t
>&
dilation
);
// Used for dynamic auto padding of pooling operators where padding needs to be computed at
// evaulation time.
shape
compute_padded_pool_shape
(
const
shape
&
input
,
const
shape
&
kernel
,
const
std
::
vector
<
std
::
size_t
>&
padding
,
const
std
::
vector
<
std
::
size_t
>&
stride
,
const
std
::
vector
<
std
::
size_t
>&
dilation
);
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
}
// namespace migraphx
...
...
src/include/migraphx/ranges.hpp
View file @
0c98c38e
...
@@ -205,7 +205,7 @@ void transform(Range1&& r1, Range2&& r2, Iterator it, F f)
...
@@ -205,7 +205,7 @@ void transform(Range1&& r1, Range2&& r2, Iterator it, F f)
}
}
template
<
class
Range
>
template
<
class
Range
>
auto
reverse
(
Range
&
r
)
auto
reverse
(
Range
&
&
r
)
{
{
return
range
(
std
::
make_reverse_iterator
(
r
.
end
()),
std
::
make_reverse_iterator
(
r
.
begin
()));
return
range
(
std
::
make_reverse_iterator
(
r
.
end
()),
std
::
make_reverse_iterator
(
r
.
begin
()));
}
}
...
...
src/include/migraphx/shape.hpp
View file @
0c98c38e
...
@@ -263,7 +263,7 @@ struct MIGRAPHX_EXPORT shape
...
@@ -263,7 +263,7 @@ struct MIGRAPHX_EXPORT shape
/// no padding
/// no padding
bool
packed
()
const
;
bool
packed
()
const
;
/// Returns true i
s
the shape has been transposed. That is the strides are not in descending
/// Returns true i
f
the shape has been transposed. That is the strides are not in descending
/// order
/// order
bool
transposed
()
const
;
bool
transposed
()
const
;
...
...
src/include/migraphx/shape_for_each.hpp
View file @
0c98c38e
/*
/*
* 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
...
@@ -37,11 +37,11 @@ inline namespace MIGRAPHX_INLINE_NS {
...
@@ -37,11 +37,11 @@ inline namespace MIGRAPHX_INLINE_NS {
template
<
class
F
>
template
<
class
F
>
void
shape_for_each
(
const
migraphx
::
shape
&
s
,
F
f
)
void
shape_for_each
(
const
migraphx
::
shape
&
s
,
F
f
)
{
{
// Ensure calls to f use const ref to vector
auto
call
=
[
&
f
](
const
std
::
vector
<
std
::
size_t
>&
i
)
{
f
(
i
);
};
std
::
vector
<
std
::
size_t
>
indices
(
s
.
lens
().
size
());
std
::
vector
<
std
::
size_t
>
indices
(
s
.
lens
().
size
());
const
auto
&
index_const_ref
=
indices
;
shape
ss
{
s
.
type
(),
s
.
lens
()};
shape
ss
{
s
.
type
(),
s
.
lens
()};
for
(
std
::
size_t
i
=
0
;
i
<
ss
.
elements
();
i
++
)
size_t
max
=
ss
.
elements
();
for
(
std
::
size_t
i
=
0
;
i
<
max
;
i
++
)
{
{
std
::
transform
(
ss
.
strides
().
begin
(),
std
::
transform
(
ss
.
strides
().
begin
(),
ss
.
strides
().
end
(),
ss
.
strides
().
end
(),
...
@@ -51,9 +51,13 @@ void shape_for_each(const migraphx::shape& s, F f)
...
@@ -51,9 +51,13 @@ void shape_for_each(const migraphx::shape& s, F f)
assert
(
len
>
0
and
stride
>
0
);
assert
(
len
>
0
and
stride
>
0
);
return
(
i
/
stride
)
%
len
;
return
(
i
/
stride
)
%
len
;
});
});
call
(
indices
);
if
constexpr
(
std
::
is_invocable
<
F
,
decltype
(
index_const_ref
),
decltype
(
i
)
>
{})
f
(
index_const_ref
,
i
);
else
f
(
index_const_ref
);
}
}
}
}
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
}
// namespace migraphx
...
...
src/include/migraphx/simplify_reshapes.hpp
View file @
0c98c38e
...
@@ -38,6 +38,7 @@ struct module;
...
@@ -38,6 +38,7 @@ struct module;
*/
*/
struct
MIGRAPHX_EXPORT
simplify_reshapes
struct
MIGRAPHX_EXPORT
simplify_reshapes
{
{
size_t
depth
=
4
;
std
::
string
name
()
const
{
return
"simplify_reshapes"
;
}
std
::
string
name
()
const
{
return
"simplify_reshapes"
;
}
void
apply
(
module
&
m
)
const
;
void
apply
(
module
&
m
)
const
;
};
};
...
...
src/include/migraphx/stringutils.hpp
View file @
0c98c38e
...
@@ -86,7 +86,7 @@ inline std::string join_strings(Strings strings, const std::string& delim)
...
@@ -86,7 +86,7 @@ inline std::string join_strings(Strings strings, const std::string& delim)
inline
std
::
vector
<
std
::
string
>
split_string
(
const
std
::
string
&
s
,
char
delim
)
inline
std
::
vector
<
std
::
string
>
split_string
(
const
std
::
string
&
s
,
char
delim
)
{
{
std
::
vector
<
std
::
string
>
elems
;
std
::
vector
<
std
::
string
>
elems
;
std
::
stringstream
ss
(
s
+
' '
);
std
::
stringstream
ss
(
s
+
delim
);
std
::
string
item
;
std
::
string
item
;
while
(
std
::
getline
(
ss
,
item
,
delim
))
while
(
std
::
getline
(
ss
,
item
,
delim
))
{
{
...
@@ -149,6 +149,10 @@ interpolate_string(const std::string& input, F f, std::string start = "${", std:
...
@@ -149,6 +149,10 @@ interpolate_string(const std::string& input, F f, std::string start = "${", std:
result
.
append
(
it
,
next_start
);
result
.
append
(
it
,
next_start
);
if
(
next_start
==
input
.
end
())
if
(
next_start
==
input
.
end
())
break
;
break
;
if
(
next_end
==
input
.
end
())
{
throw
std
::
runtime_error
(
"Unbalanced brackets"
);
}
auto
r
=
f
(
next_start
+
start
.
size
(),
next_end
);
auto
r
=
f
(
next_start
+
start
.
size
(),
next_end
);
result
.
append
(
r
.
begin
(),
r
.
end
());
result
.
append
(
r
.
begin
(),
r
.
end
());
it
=
next_end
+
end
.
size
();
it
=
next_end
+
end
.
size
();
...
...
src/memory_coloring.cpp
View file @
0c98c38e
...
@@ -23,9 +23,9 @@
...
@@ -23,9 +23,9 @@
*/
*/
#include <migraphx/memory_coloring.hpp>
#include <migraphx/memory_coloring.hpp>
#include <migraphx/module.hpp>
#include <migraphx/module.hpp>
#include <migraphx/operators.hpp>
#include <migraphx/instruction.hpp>
#include <migraphx/instruction.hpp>
#include <migraphx/iterator_for.hpp>
#include <migraphx/iterator_for.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/functional.hpp>
#include <migraphx/functional.hpp>
#include <migraphx/algorithm.hpp>
#include <migraphx/algorithm.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/ranges.hpp>
...
@@ -382,7 +382,8 @@ void memory_coloring::apply(module& m) const
...
@@ -382,7 +382,8 @@ void memory_coloring::apply(module& m) const
auto
s
=
ins
->
get_shape
();
auto
s
=
ins
->
get_shape
();
std
::
size_t
offset
=
seg
.
first
*
alignment
;
std
::
size_t
offset
=
seg
.
first
*
alignment
;
assert
(
offset
<
n
);
assert
(
offset
<
n
);
m
.
replace_instruction
(
ins
,
op
::
load
{
s
,
offset
},
mem
);
m
.
replace_instruction
(
ins
,
make_op
(
"load"
,
{{
"shape"
,
to_value
(
s
)},
{
"offset"
,
offset
}}),
mem
);
}
}
// Replace zero allocation
// Replace zero allocation
...
@@ -391,7 +392,8 @@ void memory_coloring::apply(module& m) const
...
@@ -391,7 +392,8 @@ void memory_coloring::apply(module& m) const
if
(
ins
->
name
()
!=
allocation_op
)
if
(
ins
->
name
()
!=
allocation_op
)
continue
;
continue
;
assert
(
ins
->
get_shape
().
bytes
()
==
0
);
assert
(
ins
->
get_shape
().
bytes
()
==
0
);
m
.
replace_instruction
(
ins
,
op
::
load
{
ins
->
get_shape
(),
0
},
mem
);
m
.
replace_instruction
(
ins
,
make_op
(
"load"
,
{{
"shape"
,
to_value
(
ins
->
get_shape
())},
{
"offset"
,
0
}}),
mem
);
}
}
// Remove scratch parameter if its not used
// Remove scratch parameter if its not used
...
...
src/normalize_attributes.cpp
View file @
0c98c38e
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
#include <migraphx/normalize_attributes.hpp>
#include <migraphx/normalize_attributes.hpp>
#include <migraphx/stringutils.hpp>
#include <migraphx/stringutils.hpp>
#include <migraphx/op/normalize_attribute.hpp>
#include <migraphx/op/normalize_attribute.hpp>
#include <migraphx/op/common.hpp>
namespace
migraphx
{
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
inline
namespace
MIGRAPHX_INLINE_NS
{
...
@@ -49,6 +49,10 @@ auto tune_attribute(const std::vector<int64_t>& vec,
...
@@ -49,6 +49,10 @@ auto tune_attribute(const std::vector<int64_t>& vec,
Message
m
)
Message
m
)
{
{
std
::
vector
<
int64_t
>
result
(
vec
);
std
::
vector
<
int64_t
>
result
(
vec
);
if
(
result
.
empty
())
{
return
result
;
};
int64_t
n_rank
=
input_shape
.
ndim
();
int64_t
n_rank
=
input_shape
.
ndim
();
std
::
vector
<
op
::
normalize_attribute
>
vec_attrs
=
val
.
to_vector
<
op
::
normalize_attribute
>
();
std
::
vector
<
op
::
normalize_attribute
>
vec_attrs
=
val
.
to_vector
<
op
::
normalize_attribute
>
();
if
(
contains
(
vec_attrs
,
op
::
normalize_attribute
::
use_output
))
if
(
contains
(
vec_attrs
,
op
::
normalize_attribute
::
use_output
))
...
@@ -187,15 +191,21 @@ bool normalize_attributes(operation& op, const shape& input_shape)
...
@@ -187,15 +191,21 @@ bool normalize_attributes(operation& op, const shape& input_shape)
auto
attrs
=
op
.
attributes
();
auto
attrs
=
op
.
attributes
();
auto
val
=
op
.
to_value
();
auto
val
=
op
.
to_value
();
if
(
attrs
.
contains
(
"normalize_padding"
))
if
(
attrs
.
contains
(
"normalize_padding"
))
{
bool
use_auto_padding
=
(
val
.
contains
(
"padding_mode"
)
and
(
val
.
at
(
"padding_mode"
).
to
<
int
>
()
!=
migraphx
::
op
::
padding_mode_t
::
default_
));
if
(
not
use_auto_padding
)
{
{
auto
padding
=
val
.
at
(
attrs
.
at
(
"normalize_padding"
).
to
<
std
::
string
>
());
auto
padding
=
val
.
at
(
attrs
.
at
(
"normalize_padding"
).
to
<
std
::
string
>
());
auto
padding_size
=
padding
.
size
();
auto
padding_size
=
padding
.
size
();
auto
padding_start
=
2
;
auto
padding_start
=
2
;
if
(
padding_size
==
2
*
(
input_shape
.
ndim
()
-
padding_start
))
if
(
padding_size
==
2
*
(
input_shape
.
ndim
()
-
padding_start
))
tuned
=
true
;
tuned
=
true
;
else
if
(
padding_size
!=
(
input_shape
.
ndim
()
-
padding_start
))
else
if
(
padding_size
!=
(
input_shape
.
ndim
()
-
padding_start
))
MIGRAPHX_THROW
(
"inconsistent padding size"
);
{
MIGRAPHX_THROW
(
"normalize_attributes: inconsistent padding vector size "
);
}
else
else
{
{
auto
result
=
tune_pad_attribute
(
padding
);
auto
result
=
tune_pad_attribute
(
padding
);
...
@@ -204,6 +214,7 @@ bool normalize_attributes(operation& op, const shape& input_shape)
...
@@ -204,6 +214,7 @@ bool normalize_attributes(operation& op, const shape& input_shape)
tuned
=
true
;
tuned
=
true
;
}
}
}
}
}
if
(
not
attrs
.
contains
(
"normalize_axes"
))
if
(
not
attrs
.
contains
(
"normalize_axes"
))
{
{
return
tuned
;
return
tuned
;
...
@@ -251,5 +262,22 @@ bool normalize_attributes(operation& op, const shape& input_shape)
...
@@ -251,5 +262,22 @@ bool normalize_attributes(operation& op, const shape& input_shape)
return
tuned
;
return
tuned
;
}
}
std
::
vector
<
int64_t
>
normalize_axes
(
const
std
::
vector
<
int64_t
>&
axes
,
const
shape
&
input_shape
,
const
value
&
attr_val
,
const
std
::
string
&
prefix
)
{
return
tune_attribute
(
axes
,
{},
attr_val
,
input_shape
,
[
&
]
{
return
prefix
;
});
}
std
::
vector
<
int64_t
>
normalize_indices
(
const
std
::
vector
<
int64_t
>&
indices
,
const
std
::
vector
<
int64_t
>&
axes
,
const
shape
&
input_shape
,
const
value
&
attr_val
,
const
std
::
string
&
prefix
)
{
return
tune_attribute
(
indices
,
axes
,
attr_val
,
input_shape
,
[
&
]
{
return
prefix
;
});
}
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
}
// namespace migraphx
src/onnx/parse_pooling.cpp
View file @
0c98c38e
/*
/*
* 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
...
@@ -151,26 +151,6 @@ struct parse_pooling : op_parser<parse_pooling>
...
@@ -151,26 +151,6 @@ struct parse_pooling : op_parser<parse_pooling>
kdims
,
paddings
.
size
()
/
2
,
"PARSE_POOLING: inconsistent explicit paddings"
);
kdims
,
paddings
.
size
()
/
2
,
"PARSE_POOLING: inconsistent explicit paddings"
);
}
}
if
(
contains
(
info
.
attributes
,
"auto_pad"
))
{
if
(
in_shape
.
dynamic
())
{
MIGRAPHX_THROW
(
"PARSE_POOLING: Auto padding pooling with dynamic input shape not supported"
);
}
else
{
values
[
"padding"
].
clear
();
// return paddings could be empty, then setting to 0 for no padding
cal_auto_padding_size
(
info
,
values
,
values
[
"lengths"
].
to_vector
<
std
::
size_t
>
(),
{
1
,
1
},
in_shape
.
lens
(),
paddings
);
}
}
if
(
paddings
.
size
()
!=
2
*
kdims
)
if
(
paddings
.
size
()
!=
2
*
kdims
)
{
{
paddings
.
resize
(
kdims
*
2
);
paddings
.
resize
(
kdims
*
2
);
...
@@ -192,6 +172,36 @@ struct parse_pooling : op_parser<parse_pooling>
...
@@ -192,6 +172,36 @@ struct parse_pooling : op_parser<parse_pooling>
// used to calculate the supposed output shape
// used to calculate the supposed output shape
std
::
vector
<
int64_t
>
orig_padding
=
paddings
;
std
::
vector
<
int64_t
>
orig_padding
=
paddings
;
// TODO: add parsing for dilations
if
(
contains
(
info
.
attributes
,
"auto_pad"
)
and
to_upper
(
info
.
attributes
[
"auto_pad"
].
s
())
!=
"NOTSET"
)
{
auto
auto_pad
=
to_upper
(
info
.
attributes
[
"auto_pad"
].
s
());
// don't use the given padding sizes, if any
// values["padding"].clear();
if
(
in_shape
.
dynamic
())
{
// set padding_mode to trigger auto padding at runtime
bool
is_same_upper
=
(
auto_pad
.
find
(
"SAME_UPPER"
)
!=
std
::
string
::
npos
);
values
[
"padding_mode"
]
=
is_same_upper
?
to_value
(
op
::
padding_mode_t
::
same_upper
)
:
to_value
(
op
::
padding_mode_t
::
same_lower
);
}
else
{
// Calculate auto padding
// dilations (argument 4) not supported; default to all 1's
cal_auto_padding_size
(
info
,
values
,
values
[
"lengths"
].
to_vector
<
std
::
size_t
>
(),
std
::
vector
<
size_t
>
(
in_shape
.
ndim
()
-
2
,
1
),
in_shape
.
lens
(),
paddings
);
values
[
"padding"
]
=
paddings
;
// default padding_mode indicates that padding sizes are not calculated dynamically
values
[
"padding_mode"
]
=
migraphx
::
op
::
padding_mode_t
::
default_
;
}
}
std
::
vector
<
int64_t
>
slice_start
;
std
::
vector
<
int64_t
>
slice_start
;
std
::
vector
<
int64_t
>
slice_end
;
std
::
vector
<
int64_t
>
slice_end
;
tune_padding_size
(
values
,
paddings
,
count_include_pad
,
slice_start
);
tune_padding_size
(
values
,
paddings
,
count_include_pad
,
slice_start
);
...
@@ -208,8 +218,9 @@ struct parse_pooling : op_parser<parse_pooling>
...
@@ -208,8 +218,9 @@ struct parse_pooling : op_parser<parse_pooling>
orig_padding
.
insert
(
orig_padding
.
begin
(),
2
,
0
);
orig_padding
.
insert
(
orig_padding
.
begin
(),
2
,
0
);
op
::
pad
pad
{
orig_padding
,
0.0
f
};
op
::
pad
pad
{
orig_padding
,
0.0
f
};
shape
padded_shape
=
pad
.
compute_shape
({
l0
->
get_shape
()});
shape
padded_shape
=
pad
.
compute_shape
({
l0
->
get_shape
()});
auto
out_lens
=
make_op
(
"pooling"
,
values
).
compute_shape
({
padded_shape
}).
lens
();
// make an op just to get its output shape
auto
out_lens
=
make_op
(
"pooling"
,
values
).
compute_shape
({
padded_shape
}).
lens
();
// compute slice_end information
// compute slice_end information
slice_end
.
resize
(
slice_start
.
size
());
slice_end
.
resize
(
slice_start
.
size
());
std
::
transform
(
out_lens
.
begin
()
+
2
,
std
::
transform
(
out_lens
.
begin
()
+
2
,
...
...
src/onnx/parse_resize.cpp
View file @
0c98c38e
/*
/*
* 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
...
@@ -97,22 +97,19 @@ const auto& get_original_idx_op(const std::string& mode)
...
@@ -97,22 +97,19 @@ const auto& get_original_idx_op(const std::string& mode)
static
std
::
vector
<
int
>
static
std
::
vector
<
int
>
calc_neighbor_points
(
const
std
::
vector
<
std
::
vector
<
std
::
vector
<
std
::
size_t
>>>&
vvv_ind
,
calc_neighbor_points
(
const
std
::
vector
<
std
::
vector
<
std
::
vector
<
std
::
size_t
>>>&
vvv_ind
,
int
i_dim
,
int
i_dim
,
const
std
::
vector
<
std
::
vector
<
std
::
size_t
>>
&
vec_dims
,
std
::
vector
<
std
::
vector
<
std
::
size_t
>>
vec_dims
,
const
shape
&
in_s
)
const
shape
&
in_s
)
{
{
if
(
i_dim
==
vvv_ind
.
size
())
if
(
i_dim
==
vvv_ind
.
size
())
{
{
std
::
vector
<
int
>
vec_ind
;
std
::
vector
<
int
>
vec_ind
(
vec_dims
.
size
());
vec_ind
.
resize
(
vec_dims
.
size
());
std
::
transform
(
vec_dims
.
begin
(),
vec_dims
.
end
(),
vec_ind
.
begin
(),
[
&
](
auto
idx
)
{
std
::
transform
(
vec_dims
.
begin
(),
vec_dims
.
end
(),
vec_ind
.
begin
(),
[
&
](
auto
idx
)
{
return
static_cast
<
int
>
(
in_s
.
index
(
idx
));
return
static_cast
<
int
>
(
in_s
.
index
(
idx
));
});
});
return
vec_ind
;
return
vec_ind
;
}
}
const
auto
&
vv_ind
=
vvv_ind
[
i_dim
];
const
auto
&
vv_lo
=
vvv_ind
[
i_dim
][
0
];
const
auto
&
vv_lo
=
vv_ind
.
at
(
0
);
std
::
vector
<
std
::
vector
<
std
::
size_t
>>
vec_dims1
;
std
::
vector
<
std
::
vector
<
std
::
size_t
>>
vec_dims1
;
for
(
std
::
size_t
start
=
0
;
start
<
vec_dims
.
size
();
start
+=
vv_lo
.
size
())
for
(
std
::
size_t
start
=
0
;
start
<
vec_dims
.
size
();
start
+=
vv_lo
.
size
())
{
{
...
@@ -126,8 +123,8 @@ calc_neighbor_points(const std::vector<std::vector<std::vector<std::size_t>>>& v
...
@@ -126,8 +123,8 @@ calc_neighbor_points(const std::vector<std::vector<std::vector<std::size_t>>>& v
});
});
}
}
const
auto
&
vv_hi
=
vv_ind
.
at
(
1
)
;
const
auto
&
vv_hi
=
vv
v
_ind
[
i_dim
][
1
]
;
for
(
std
::
size_t
start
=
0
;
start
<
vec_dims
.
size
();
start
+=
vv_
lo
.
size
())
for
(
std
::
size_t
start
=
0
;
start
<
vec_dims
.
size
();
start
+=
vv_
hi
.
size
())
{
{
std
::
transform
(
vv_hi
.
begin
(),
std
::
transform
(
vv_hi
.
begin
(),
vv_hi
.
end
(),
vv_hi
.
end
(),
...
@@ -138,8 +135,8 @@ calc_neighbor_points(const std::vector<std::vector<std::vector<std::size_t>>>& v
...
@@ -138,8 +135,8 @@ calc_neighbor_points(const std::vector<std::vector<std::vector<std::size_t>>>& v
return
dim
;
return
dim
;
});
});
}
}
vec_dims
.
clear
();
return
calc_neighbor_points
(
vvv_ind
,
i_dim
+
1
,
vec_dims1
,
in_s
);
return
calc_neighbor_points
(
vvv_ind
,
i_dim
+
1
,
std
::
move
(
vec_dims1
)
,
in_s
);
}
}
static
std
::
string
get_coord_trans_mode
(
const
onnx_parser
::
attribute_map
&
attr
)
static
std
::
string
get_coord_trans_mode
(
const
onnx_parser
::
attribute_map
&
attr
)
...
@@ -240,7 +237,7 @@ struct parse_resize : op_parser<parse_resize>
...
@@ -240,7 +237,7 @@ struct parse_resize : op_parser<parse_resize>
auto
arg_out_s
=
arg
->
eval
();
auto
arg_out_s
=
arg
->
eval
();
check_arg_empty
(
arg_out_s
,
check_arg_empty
(
arg_out_s
,
"PARSE_"
+
opd
.
op_name
+
": dynamic output size is not supported!"
);
"PARSE_"
+
opd
.
op_name
+
": dynamic output size is not supported!"
);
arg_out_s
.
visit
([
&
](
auto
ol
)
{
out_lens
.
assign
(
ol
.
begin
(),
ol
.
end
());
});
arg_out_s
.
visit
([
&
](
const
auto
&
ol
)
{
out_lens
.
assign
(
ol
.
begin
(),
ol
.
end
());
});
if
(
out_lens
.
size
()
!=
in_lens
.
size
())
if
(
out_lens
.
size
()
!=
in_lens
.
size
())
{
{
...
@@ -267,7 +264,7 @@ struct parse_resize : op_parser<parse_resize>
...
@@ -267,7 +264,7 @@ struct parse_resize : op_parser<parse_resize>
"PARSE_"
+
opd
.
op_name
+
"PARSE_"
+
opd
.
op_name
+
": dynamic input scale is not supported!"
);
": dynamic input scale is not supported!"
);
arg_scale
.
visit
([
&
](
auto
v
)
{
vec_scale
.
assign
(
v
.
begin
(),
v
.
end
());
});
arg_scale
.
visit
([
&
](
const
auto
&
v
)
{
vec_scale
.
assign
(
v
.
begin
(),
v
.
end
());
});
if
(
in_lens
.
size
()
!=
vec_scale
.
size
())
if
(
in_lens
.
size
()
!=
vec_scale
.
size
())
{
{
MIGRAPHX_THROW
(
"PARSE_"
+
opd
.
op_name
+
MIGRAPHX_THROW
(
"PARSE_"
+
opd
.
op_name
+
...
@@ -300,15 +297,15 @@ struct parse_resize : op_parser<parse_resize>
...
@@ -300,15 +297,15 @@ struct parse_resize : op_parser<parse_resize>
// map out_idx to in_idx
// map out_idx to in_idx
auto
nearest_op
=
get_nearest_op
(
nearest_mode
);
auto
nearest_op
=
get_nearest_op
(
nearest_mode
);
shape_for_each
(
out_s
,
[
&
](
auto
idx
)
{
shape_for_each
(
out_s
,
[
&
](
const
auto
&
out_idx_v
,
size_t
out_
idx
)
{
auto
in_idx
=
idx
;
std
::
vector
<
size_t
>
in_idx
(
out_idx_v
.
size
())
;
for
(
auto
ii
=
0
;
ii
<
in_lens
.
size
();
++
ii
)
for
(
auto
ii
=
0
;
ii
<
in_lens
.
size
();
++
ii
)
{
{
auto
idx_val
=
idx_op
(
in_lens
[
ii
],
out_lens
[
ii
],
idx
[
ii
],
vec_scale
[
ii
]);
auto
idx_val
=
idx_op
(
in_lens
[
ii
],
out_lens
[
ii
],
out_
idx
_v
[
ii
],
vec_scale
[
ii
]);
in_idx
[
ii
]
=
nearest_op
(
in_lens
[
ii
],
idx_val
);
in_idx
[
ii
]
=
nearest_op
(
in_lens
[
ii
],
idx_val
);
}
}
ind
[
out_
s
.
index
(
idx
)
]
=
static_cast
<
int64_t
>
(
in_s
.
index
(
in_idx
));
ind
[
out_idx
]
=
static_cast
<
int64_t
>
(
in_s
.
index
(
in_idx
));
});
});
shape
ind_s
{
shape
::
int32_type
,
out_lens
};
shape
ind_s
{
shape
::
int32_type
,
out_lens
};
...
@@ -323,24 +320,21 @@ struct parse_resize : op_parser<parse_resize>
...
@@ -323,24 +320,21 @@ 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
();
std
::
vector
<
std
::
vector
<
std
::
size_t
>>
vv_ind
(
2
,
std
::
vector
<
std
::
size_t
>
(
out_elements
));
auto
vvv_ind
=
std
::
vector
(
n_dim
,
std
::
vector
(
2
,
std
::
vector
<
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
,
[
&
](
auto
idx
)
{
shape_for_each
(
out_s
,
[
&
](
const
auto
&
out_idx_v
,
size_t
out_idx
)
{
auto
in_idx
=
idx
;
auto
out_idx
=
out_s
.
index
(
idx
);
for
(
auto
ii
=
0
;
ii
<
in_lens
.
size
();
++
ii
)
for
(
auto
ii
=
0
;
ii
<
in_lens
.
size
();
++
ii
)
{
{
auto
idx_val
=
idx_op
(
in_lens
[
ii
],
out_lens
[
ii
],
idx
[
ii
],
vec_scale
[
ii
]);
auto
idx_val
=
idx_op
(
in_lens
[
ii
],
out_lens
[
ii
],
out_
idx
_v
[
ii
],
vec_scale
[
ii
]);
vvv_ind
[
ii
][
0
][
out_idx
]
=
nearest_floor
(
in_lens
[
ii
],
idx_val
);
vvv_ind
[
ii
][
0
][
out_idx
]
=
nearest_floor
(
in_lens
[
ii
],
idx_val
);
vvv_ind
[
ii
][
1
][
out_idx
]
=
nearest_ceil
(
in_lens
[
ii
],
idx_val
);
vvv_ind
[
ii
][
1
][
out_idx
]
=
nearest_ceil
(
in_lens
[
ii
],
idx_val
);
delta
[
ii
][
out_idx
]
=
idx_val
-
vvv_ind
[
ii
][
0
][
out_idx
];
delta
[
ii
][
out_idx
]
=
idx_val
-
vvv_ind
[
ii
][
0
][
out_idx
];
}
}
});
});
std
::
vector
<
std
::
vector
<
std
::
size_t
>>
vec_dims
(
out_eleme
nts
);
auto
ind
=
calc_neighbor_poi
nts
(
auto
ind
=
calc_neighbor_points
(
vvv_ind
,
0
,
vec_dims
,
in_s
);
vvv_ind
,
0
,
std
::
vector
<
std
::
vector
<
std
::
size_t
>>
(
out_elements
)
,
in_s
);
auto
ind_lens
=
out_lens
;
auto
ind_lens
=
out_lens
;
ind_lens
[
0
]
*=
(
std
::
size_t
{
1
}
<<
n_dim
);
ind_lens
[
0
]
*=
(
std
::
size_t
{
1
}
<<
n_dim
);
shape
ind_s
{
shape
::
int32_type
,
ind_lens
};
shape
ind_s
{
shape
::
int32_type
,
ind_lens
};
...
...
src/onnx/parse_slice.cpp
View file @
0c98c38e
...
@@ -34,16 +34,65 @@ namespace onnx {
...
@@ -34,16 +34,65 @@ namespace onnx {
struct
parse_slice
:
op_parser
<
parse_slice
>
struct
parse_slice
:
op_parser
<
parse_slice
>
{
{
std
::
vector
<
op_desc
>
operators
()
const
{
return
{{
"Slice"
}};
}
std
::
vector
<
op_desc
>
operators
()
const
{
return
{{
"Slice"
}};
}
struct
slice_desc
{
op
::
slice
op
;
std
::
vector
<
instruction_ref
>
op_args
;
std
::
vector
<
int64_t
>
steps
;
std
::
vector
<
int64_t
>
raxes
;
void
always_insert
(
instruction_ref
arg
)
{
op_args
.
insert
(
op_args
.
begin
(),
arg
);
}
std
::
vector
<
int64_t
>
insert
(
instruction_ref
arg
)
{
std
::
vector
<
int64_t
>
result
;
migraphx
::
argument
arg_value
=
arg
->
eval
();
if
(
arg_value
.
empty
())
{
op_args
.
insert
(
op_args
.
begin
(),
arg
);
}
else
{
arg_value
.
visit
([
&
](
auto
s
)
{
result
.
assign
(
s
.
begin
(),
s
.
end
());
});
}
return
result
;
}
};
instruction_ref
parse
(
const
op_desc
&
/*opd*/
,
instruction_ref
parse
(
const
op_desc
&
/*opd*/
,
const
onnx_parser
&
parser
,
const
onnx_parser
&
parser
,
const
onnx_parser
::
node_info
&
info
,
const
std
::
vector
<
instruction_ref
>&
args
)
const
{
auto
sd
=
construct_slice_desc
(
parser
,
info
,
args
);
auto
ins
=
info
.
add_instruction
(
sd
.
op
,
sd
.
op_args
);
if
(
not
sd
.
raxes
.
empty
())
{
ins
=
info
.
add_instruction
(
make_op
(
"reverse"
,
{{
"axes"
,
sd
.
raxes
}}),
ins
);
}
// If any steps are other than default 1, add a "steps" op
if
(
std
::
any_of
(
sd
.
steps
.
begin
(),
sd
.
steps
.
end
(),
[](
auto
s
)
{
return
std
::
abs
(
s
)
!=
1
;
}))
{
std
::
vector
<
int64_t
>
nsteps
;
std
::
transform
(
sd
.
steps
.
begin
(),
sd
.
steps
.
end
(),
std
::
back_inserter
(
nsteps
),
[](
auto
s
)
{
return
std
::
abs
(
s
);
});
return
ins
=
info
.
add_instruction
(
make_op
(
"step"
,
{{
"axes"
,
sd
.
op
.
axes
},
{
"steps"
,
nsteps
}}),
ins
);
}
else
return
ins
;
}
slice_desc
construct_slice_desc
(
const
onnx_parser
&
parser
,
onnx_parser
::
node_info
info
,
onnx_parser
::
node_info
info
,
std
::
vector
<
instruction_ref
>
args
)
const
std
::
vector
<
instruction_ref
>
args
)
const
{
{
op
::
slice
op
;
slice_desc
sd
;
std
::
vector
<
int64_t
>
steps
;
// slice can have up to 5 inputs, we first check the 5th one
// slice can have up to 5 inputs, we first check the 5th one
// to decide whether MIGRAPHX can handle this slice.
// to decide whether MIGRAPHX can handle this slice.
...
@@ -51,89 +100,73 @@ struct parse_slice : op_parser<parse_slice>
...
@@ -51,89 +100,73 @@ struct parse_slice : op_parser<parse_slice>
{
{
migraphx
::
argument
step_arg
=
args
.
back
()
->
eval
();
migraphx
::
argument
step_arg
=
args
.
back
()
->
eval
();
check_arg_empty
(
step_arg
,
"PARSE_SLICE: cannot handle variable steps for slice"
);
check_arg_empty
(
step_arg
,
"PARSE_SLICE: cannot handle variable steps for slice"
);
step_arg
.
visit
([
&
](
auto
s
)
{
steps
.
assign
(
s
.
begin
(),
s
.
end
());
});
step_arg
.
visit
([
&
](
auto
s
)
{
sd
.
steps
.
assign
(
s
.
begin
(),
s
.
end
());
});
}
}
if
(
args
.
size
()
>=
4
)
if
(
args
.
size
()
>=
4
)
{
{
migraphx
::
argument
axes_arg
=
args
.
at
(
3
)
->
eval
();
sd
.
op
.
axes
=
sd
.
insert
(
args
.
at
(
3
));
check_arg_empty
(
axes_arg
,
"PARSE_SLICE: cannot handle variable axes for slice"
);
axes_arg
.
visit
([
&
](
auto
s
)
{
op
.
axes
.
assign
(
s
.
begin
(),
s
.
end
());
});
}
}
else
if
(
contains
(
info
.
attributes
,
"axes"
))
else
if
(
contains
(
info
.
attributes
,
"axes"
))
{
{
literal
s
=
parser
.
parse_value
(
info
.
attributes
.
at
(
"axes"
));
literal
s
=
parser
.
parse_value
(
info
.
attributes
.
at
(
"axes"
));
s
.
visit
([
&
](
auto
v
)
{
copy
(
v
,
std
::
back_inserter
(
op
.
axes
));
});
s
.
visit
([
&
](
auto
v
)
{
copy
(
v
,
std
::
back_inserter
(
sd
.
op
.
axes
));
});
}
}
if
(
args
.
size
()
>=
3
)
if
(
args
.
size
()
>=
3
)
{
{
migraphx
::
argument
end_arg
=
args
.
at
(
2
)
->
eval
();
sd
.
op
.
ends
=
sd
.
insert
(
args
.
at
(
2
));
check_arg_empty
(
end_arg
,
"PARSE_SLICE: cannot handle variable ends for slice"
);
end_arg
.
visit
([
&
](
auto
s
)
{
op
.
ends
.
assign
(
s
.
begin
(),
s
.
end
());
});
}
}
else
if
(
contains
(
info
.
attributes
,
"ends"
))
else
if
(
contains
(
info
.
attributes
,
"ends"
))
{
{
literal
s
=
parser
.
parse_value
(
info
.
attributes
.
at
(
"ends"
));
literal
s
=
parser
.
parse_value
(
info
.
attributes
.
at
(
"ends"
));
s
.
visit
([
&
](
auto
v
)
{
copy
(
v
,
std
::
back_inserter
(
op
.
ends
));
});
s
.
visit
([
&
](
auto
v
)
{
copy
(
v
,
std
::
back_inserter
(
sd
.
op
.
ends
));
});
}
}
if
(
args
.
size
()
>=
2
)
if
(
args
.
size
()
>=
2
)
{
{
migraphx
::
argument
start_arg
=
args
.
at
(
1
)
->
eval
();
sd
.
op
.
starts
=
sd
.
insert
(
args
.
at
(
1
));
check_arg_empty
(
start_arg
,
"PARSE_SLICE: cannot handle variable starts for slice"
);
start_arg
.
visit
([
&
](
auto
s
)
{
op
.
starts
.
assign
(
s
.
begin
(),
s
.
end
());
});
}
}
else
if
(
contains
(
info
.
attributes
,
"starts"
))
else
if
(
contains
(
info
.
attributes
,
"starts"
))
{
{
literal
s
=
parser
.
parse_value
(
info
.
attributes
.
at
(
"starts"
));
literal
s
=
parser
.
parse_value
(
info
.
attributes
.
at
(
"starts"
));
s
.
visit
([
&
](
auto
v
)
{
copy
(
v
,
std
::
back_inserter
(
op
.
starts
));
});
s
.
visit
([
&
](
auto
v
)
{
copy
(
v
,
std
::
back_inserter
(
sd
.
op
.
starts
));
});
}
}
// data input argument
sd
.
always_insert
(
args
.
at
(
0
));
// If axes arg is not given, the default is all of them.
// If axes arg is not given, the default is all of them.
if
(
op
.
axes
.
empty
())
if
(
sd
.
op
.
axes
.
empty
()
and
sd
.
op_args
.
size
()
<
3
)
{
{
std
::
vector
<
int64_t
>
axes
(
args
[
0
]
->
get_shape
().
ndim
());
std
::
vector
<
int64_t
>
axes
(
args
[
0
]
->
get_shape
().
ndim
());
std
::
iota
(
axes
.
begin
(),
axes
.
end
(),
int64_t
{
0
});
std
::
iota
(
axes
.
begin
(),
axes
.
end
(),
int64_t
{
0
});
op
.
axes
=
axes
;
sd
.
op
.
axes
=
axes
;
}
}
std
::
vector
<
int64_t
>
raxes
;
if
(
not
sd
.
steps
.
empty
())
{
if
(
sd
.
op
.
starts
.
empty
()
or
sd
.
op
.
ends
.
empty
())
MIGRAPHX_THROW
(
"PARSE_SLICE: steps and variable starts and ends is not supported"
);
if
(
sd
.
op
.
axes
.
empty
())
MIGRAPHX_THROW
(
"PARSE_SLICE: steps and variable axes is not supported"
);
}
assert
(
steps
.
empty
()
or
steps
.
size
()
==
op
.
axes
.
size
());
assert
(
sd
.
steps
.
empty
()
or
sd
.
steps
.
size
()
==
sd
.
op
.
axes
.
size
());
assert
(
op
.
axes
.
size
()
==
op
.
starts
.
size
());
assert
(
op
.
axes
.
size
()
==
op
.
ends
.
size
());
// If any axes have negative step, prepare to add a "reverse" op
// If any axes have negative step, prepare to add a "reverse" op
for
(
auto
i
:
range
(
steps
.
size
()))
for
(
auto
i
:
range
(
sd
.
steps
.
size
()))
{
{
if
(
steps
[
i
]
>=
0
)
if
(
sd
.
steps
[
i
]
>=
0
)
continue
;
continue
;
op
.
starts
[
i
]
+=
1
;
sd
.
op
.
starts
[
i
]
+=
1
;
if
(
op
.
starts
[
i
]
==
0
)
if
(
sd
.
op
.
starts
[
i
]
==
0
)
op
.
starts
[
i
]
=
INT_MAX
;
sd
.
op
.
starts
[
i
]
=
INT_MAX
;
op
.
ends
[
i
]
+=
1
;
sd
.
op
.
ends
[
i
]
+=
1
;
raxes
.
push_back
(
op
.
axes
[
i
]);
sd
.
raxes
.
push_back
(
sd
.
op
.
axes
[
i
]);
std
::
swap
(
op
.
starts
[
i
],
op
.
ends
[
i
]);
std
::
swap
(
sd
.
op
.
starts
[
i
],
sd
.
op
.
ends
[
i
]);
}
auto
ins
=
info
.
add_instruction
(
op
,
args
[
0
]);
if
(
not
raxes
.
empty
())
{
ins
=
info
.
add_instruction
(
make_op
(
"reverse"
,
{{
"axes"
,
raxes
}}),
ins
);
}
}
// If any steps are other than default 1, add a "steps" op
return
sd
;
if
(
std
::
any_of
(
steps
.
begin
(),
steps
.
end
(),
[](
auto
s
)
{
return
std
::
abs
(
s
)
!=
1
;
}))
{
std
::
vector
<
int64_t
>
nsteps
;
std
::
transform
(
steps
.
begin
(),
steps
.
end
(),
std
::
back_inserter
(
nsteps
),
[](
auto
s
)
{
return
std
::
abs
(
s
);
});
return
ins
=
info
.
add_instruction
(
make_op
(
"step"
,
{{
"axes"
,
op
.
axes
},
{
"steps"
,
nsteps
}}),
ins
);
}
else
return
ins
;
}
}
};
};
...
...
Prev
1
2
3
4
5
6
…
10
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