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
19bbfb2b
Commit
19bbfb2b
authored
Sep 15, 2023
by
Brian Pickrell
Browse files
first version that runs with resize_downsample_f_dyn_test
parent
72b691a1
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
280 additions
and
99 deletions
+280
-99
src/onnx/parse_resize.cpp
src/onnx/parse_resize.cpp
+220
-95
test/onnx/gen_onnx.py
test/onnx/gen_onnx.py
+25
-2
test/onnx/onnx_test.cpp
test/onnx/onnx_test.cpp
+35
-2
test/onnx/resize_downsample_f_test.onnx
test/onnx/resize_downsample_f_test.onnx
+0
-0
No files found.
src/onnx/parse_resize.cpp
View file @
19bbfb2b
...
@@ -206,16 +206,17 @@ struct parse_resize : op_parser<parse_resize>
...
@@ -206,16 +206,17 @@ struct parse_resize : op_parser<parse_resize>
MIGRAPHX_THROW
(
"PARSE_"
+
opd
.
op_name
+
": exclude_outside 1 is not supported!"
);
MIGRAPHX_THROW
(
"PARSE_"
+
opd
.
op_name
+
": exclude_outside 1 is not supported!"
);
}
}
// input data shape info
// input data shape info
. Convert static lens to dynamic to simplify referencing them later
auto
in_s
=
args
[
0
]
->
get_shape
();
auto
in_s
=
args
[
0
]
->
get_shape
()
.
to_dynamic
()
;
auto
in_len
s
=
in_s
.
len
s
();
std
::
vector
<
migraphx
::
shape
::
dynamic_dimension
>
in_dim
s
=
in_s
.
dyn_dim
s
();
// output shape is explicitly specified
// output shape is explicitly specified
std
::
vector
<
std
::
size_t
>
out_lens
(
in_
len
s
.
size
());
std
::
vector
<
size_t
>
out_lens
(
in_
dim
s
.
size
());
// scale
// scale
std
::
vector
<
double
>
vec_scale
;
std
::
vector
<
double
>
vec_scale
;
// Infer either output size or scale, depending on input type
for
(
const
auto
&
arg
:
args
)
for
(
const
auto
&
arg
:
args
)
{
{
if
(
arg
->
name
()
==
"undefined"
or
arg
==
args
.
front
())
if
(
arg
->
name
()
==
"undefined"
or
arg
==
args
.
front
())
...
@@ -223,6 +224,12 @@ struct parse_resize : op_parser<parse_resize>
...
@@ -223,6 +224,12 @@ struct parse_resize : op_parser<parse_resize>
continue
;
continue
;
}
}
// this is just developer code, figure out real requirement
if
(
arg
!=
args
[
0
]
and
arg
->
get_shape
().
dynamic
())
{
MIGRAPHX_THROW
(
"parse_resize: no other dynamic shapes allowed"
);
}
// skipped empty input
// skipped empty input
auto
lens
=
arg
->
get_shape
().
lens
();
auto
lens
=
arg
->
get_shape
().
lens
();
if
(
lens
.
empty
())
if
(
lens
.
empty
())
...
@@ -237,139 +244,257 @@ struct parse_resize : op_parser<parse_resize>
...
@@ -237,139 +244,257 @@ 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
([
&
](
const
auto
&
ol
)
{
out_lens
.
assign
(
ol
.
begin
(),
ol
.
end
());
});
if
(
out_lens
.
size
()
!=
in_lens
.
size
())
// reallocate a vector and copy the values to it. All dimensions except batch, even
// if originally dynamic, are required to be fixed so we can refer to their max
// value WLOG.
arg_out_s
.
visit
([
&
](
auto
ol
)
{
// todo: assign doesn't work with dynamic shapes
auto
ols
=
ol
.
get_shape
().
to_dynamic
();
for
(
auto
it
=
ols
.
dyn_dims
().
begin
();
it
!=
ols
.
dyn_dims
().
end
();
it
++
)
{
out_lens
.
push_back
(
it
->
max
);
}
// out_lens.assign(ol.begin(), ol.end());
});
if
(
out_lens
.
size
()
!=
in_dims
.
size
())
{
{
MIGRAPHX_THROW
(
"PARSE_"
+
opd
.
op_name
+
MIGRAPHX_THROW
(
"PARSE_"
+
opd
.
op_name
+
": specified output size does not match input size"
);
": specified output size does not match input size"
);
}
}
// compute the scale
// compute the scale in each dimension
vec_scale
.
resize
(
in_lens
.
size
());
vec_scale
.
resize
(
in_dims
.
size
());
std
::
transform
(
in_lens
.
begin
(),
in_lens
.
end
(),
std
::
transform
(
in_dims
.
begin
(),
in_dims
.
end
(),
out_lens
.
begin
(),
out_lens
.
begin
(),
vec_scale
.
begin
(),
vec_scale
.
begin
(),
[](
auto
iss
,
auto
oss
)
{
return
1.0
*
oss
/
iss
;
});
[](
auto
iss
,
auto
oss
)
{
return
double
(
1.0
*
oss
/
iss
.
max
)
;
});
}
}
else
else
{
{
// scale input
// scale input
if
(
lens
[
0
]
==
in_
len
s
.
size
())
if
(
lens
[
0
]
==
in_
dim
s
.
size
())
{
{
auto
arg_scale
=
arg
->
eval
();
auto
arg_scale
=
arg
->
eval
();
check_arg_empty
(
arg_scale
,
check_arg_empty
(
arg_scale
,
"PARSE_"
+
opd
.
op_name
+
"PARSE_"
+
opd
.
op_name
+
": dynamic input scale is not supported!"
);
": dynamic input scale is not supported!"
);
arg_scale
.
visit
([
&
](
const
auto
&
v
)
{
vec_scale
.
assign
(
v
.
begin
(),
v
.
end
());
});
arg_scale
.
visit
([
&
](
auto
v
)
{
vec_scale
.
assign
(
v
.
begin
(),
v
.
end
());
});
if
(
in_
len
s
.
size
()
!=
vec_scale
.
size
())
if
(
in_
dim
s
.
size
()
!=
vec_scale
.
size
())
{
{
MIGRAPHX_THROW
(
"PARSE_"
+
opd
.
op_name
+
MIGRAPHX_THROW
(
"PARSE_"
+
opd
.
op_name
+
": ranks of input and scale are different!"
);
": ranks of input and scale are different!"
);
}
}
std
::
transform
(
in_
len
s
.
begin
(),
std
::
transform
(
in_
dim
s
.
begin
(),
in_
len
s
.
end
(),
in_
dim
s
.
end
(),
vec_scale
.
begin
(),
vec_scale
.
begin
(),
out_lens
.
begin
(),
out_lens
.
begin
(),
[
&
](
auto
idx
,
auto
scale
)
{
[
&
](
auto
idx
,
auto
scale
)
{
return
static_cast
<
std
::
size_t
>
(
idx
*
scale
);
// inferred output size is floor(idx.max * scale)
return
idx
.
max
*
scale
;
});
});
}
}
}
}
}
}
shape
out_s
{
in_s
.
type
(),
out_lens
};
// Dynamic batch: Only args[0] can have a dynamic shape, only the 0'th
std
::
size_t
out_elements
=
out_s
.
elements
();
// dimension--batch size--can be non-fixed, and the only resize mode allowed is "nearest"
auto
idx_op
=
get_original_idx_op
(
coord_trans_mode
);
if
(
args
[
0
]
->
get_shape
().
dynamic
())
// reshape input to one-dimension
std
::
vector
<
int64_t
>
rsp_lens
=
{
static_cast
<
int64_t
>
(
in_s
.
elements
())};
args
[
0
]
=
info
.
make_contiguous
(
args
[
0
]);
auto
rsp
=
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
rsp_lens
}}),
args
[
0
]);
if
(
mode
==
"nearest"
)
{
{
std
::
vector
<
int
>
ind
(
out_elements
);
if
(
mode
==
"nearest"
)
{
// map out_idx to in_idx
auto
some_dims
=
args
[
0
]
->
get_shape
().
dyn_dims
();
auto
nearest_op
=
get_nearest_op
(
nearest_mode
);
shape_for_each
(
out_s
,
[
&
](
const
auto
&
out_idx_v
,
size_t
out_idx
)
{
bool
mostly_fixed
=
std
::
vector
<
size_t
>
in_idx
(
out_idx_v
.
size
());
std
::
all_of
(
some_dims
.
begin
()
+
1
,
for
(
auto
ii
=
0
;
ii
<
in_lens
.
size
();
++
ii
)
some_dims
.
end
(),
{
[](
shape
::
dynamic_dimension
dd
)
{
return
dd
.
is_fixed
();
});
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
);
if
(
not
mostly_fixed
)
}
MIGRAPHX_THROW
(
"PARSE_"
+
opd
.
op_name
+
ind
[
out_idx
]
=
static_cast
<
int64_t
>
(
in_s
.
index
(
in_idx
));
": dynamic shape inputs other than batch size are not supported"
);
});
// TODO: Add support for channel dimension
// take max_lens() to get static dimension set
// Drop the 0'th dimension,
auto
fixed_dims
=
args
[
0
]
->
get_shape
().
max_lens
();
fixed_dims
.
erase
(
fixed_dims
.
begin
());
// dimensions of the (scaled) output, also with the 0'th dimension dropped
auto
fixed_out_lens
=
out_lens
;
fixed_out_lens
.
erase
(
fixed_out_lens
.
begin
());
// create a shape with the scaled lens and no batch dimension
migraphx
::
shape
static_out_shape
(
args
[
0
]
->
get_shape
().
type
(),
fixed_out_lens
);
size_t
out_elements
=
std
::
accumulate
(
fixed_out_lens
.
begin
(),
fixed_out_lens
.
end
(),
std
::
size_t
{
1
},
std
::
multiplies
<>
());
std
::
vector
<
int
>
ind
(
out_elements
);
// map out_idx to in_idx
auto
idx_op
=
get_original_idx_op
(
coord_trans_mode
);
auto
nearest_op
=
get_nearest_op
(
nearest_mode
);
// For each element of static_out_shape, find the matching location of input shape.
// The indexes we find will be an argument to the gather op.
shape_for_each
(
static_out_shape
,
[
&
](
const
auto
&
out_idx_v
,
size_t
out_idx
)
{
std
::
vector
<
size_t
>
in_idx
(
out_idx_v
.
size
());
for
(
auto
ii
=
0
;
ii
<
fixed_dims
.
size
();
++
ii
)
{
// Convert this index by scaling. Inefficient since indexes are repeated
auto
idx_val
=
idx_op
(
fixed_dims
[
ii
],
fixed_out_lens
[
ii
],
out_idx_v
[
ii
],
vec_scale
[
ii
]);
// round the scaled value to an index
in_idx
[
ii
]
=
nearest_op
(
fixed_dims
[
ii
],
idx_val
);
}
shape
ind_s
{
shape
::
int32_type
,
out_lens
};
ind
[
out_idx
]
=
static_cast
<
int64_t
>
(
static_out_shape
.
index
(
in_idx
));
auto
ins_ind
=
info
.
add_literal
(
literal
(
ind_s
,
ind
));
});
return
info
.
add_instruction
(
make_op
(
"gather"
,
{{
"axis"
,
0
}}),
rsp
,
ins_ind
);
// Create a static shape that's just like the scaled out_lens except we set to 1 the
// 0'th dimension of output, later to be broadcasted to dynamic batch size
out_lens
[
0
]
=
1
;
shape
ind_s
{
shape
::
int32_type
,
out_lens
};
auto
ins_ind
=
info
.
add_literal
(
literal
(
ind_s
,
ind
));
// define a dynamic shape including the batch dimension
std
::
vector
<
shape
::
dynamic_dimension
>
out_dyn_dims
(
in_dims
.
size
());
out_dyn_dims
[
0
]
=
in_dims
[
0
];
std
::
transform
(
fixed_out_lens
.
begin
(),
fixed_out_lens
.
end
(),
out_dyn_dims
.
begin
()
+
1
,
[
&
](
auto
len
)
{
return
shape
::
dynamic_dimension
{
len
,
len
};
});
shape
dyn_out_shape
{
in_s
.
type
(),
out_dyn_dims
};
// allocate op to create the output argument we want
auto
ins_dyn_out
=
info
.
add_instruction
(
make_op
(
"allocate"
,
{{
"shape"
,
to_value
(
dyn_out_shape
)}}));
// multibroadcast op to convert static ins_ind to a dynamic shape
auto
ins_dyn
=
info
.
add_instruction
(
make_op
(
"multibroadcast"
),
ins_ind
,
ins_dyn_out
);
return
info
.
add_instruction
(
make_op
(
"gather"
,
{{
"axis"
,
0
}}),
args
[
0
],
ins_dyn
);
}
else
{
MIGRAPHX_THROW
(
"PARSE_RESIZE: only nearest_mode supports dynamic batch size input"
);
}
}
}
// linear mode
else
else
{
{
auto
nearest_floor
=
get_nearest_op
(
"floor"
);
//
auto
nearest_ceil
=
get_nearest_op
(
"ceil"
);
// Static input shape.
//
in_s
=
args
[
0
]
->
get_shape
();
auto
in_lens
=
args
[
0
]
->
get_shape
().
lens
();
shape
out_s
{
in_s
.
type
(),
out_lens
};
std
::
size_t
out_elements
=
out_s
.
elements
();
auto
idx_op
=
get_original_idx_op
(
coord_trans_mode
);
// reshape input to one-dimension
// TODO: We did this in multi dimensions in the dynamic case. Can we do
// the same here?
std
::
vector
<
int64_t
>
rsp_lens
=
{
static_cast
<
int64_t
>
(
in_s
.
elements
())};
args
[
0
]
=
info
.
make_contiguous
(
args
[
0
]);
auto
rsp
=
info
.
add_instruction
(
make_op
(
"reshape"
,
{{
"dims"
,
rsp_lens
}}),
args
[
0
]);
if
(
mode
==
"nearest"
)
{
std
::
vector
<
int
>
ind
(
out_elements
);
// map out_idx to in_idx
auto
nearest_op
=
get_nearest_op
(
nearest_mode
);
shape_for_each
(
out_s
,
[
&
](
const
auto
&
out_idx_v
,
size_t
out_idx
)
{
std
::
vector
<
size_t
>
in_idx
(
out_idx_v
.
size
());
for
(
auto
ii
=
0
;
ii
<
in_lens
.
size
();
++
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
);
}
// get the number of dimensions
ind
[
out_idx
]
=
static_cast
<
int64_t
>
(
in_s
.
index
(
in_idx
));
std
::
size_t
n_dim
=
out_lens
.
size
();
});
auto
vvv_ind
=
std
::
vector
(
n_dim
,
std
::
vector
(
2
,
std
::
vector
<
size_t
>
(
out_elements
)));
std
::
vector
<
std
::
vector
<
float
>>
delta
(
n_dim
,
std
::
vector
<
float
>
(
out_elements
));
shape_for_each
(
out_s
,
[
&
](
const
auto
&
out_idx_v
,
size_t
out_idx
)
{
shape
ind_s
{
shape
::
int32_type
,
out_lens
};
for
(
auto
ii
=
0
;
ii
<
in_lens
.
size
();
++
ii
)
auto
ins_ind
=
info
.
add_literal
(
literal
(
ind_s
,
ind
));
{
return
info
.
add_instruction
(
make_op
(
"gather"
,
{{
"axis"
,
0
}}),
rsp
,
ins_ind
);
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
);
// linear mode
vvv_ind
[
ii
][
1
][
out_idx
]
=
nearest_ceil
(
in_lens
[
ii
],
idx_val
);
else
delta
[
ii
][
out_idx
]
=
idx_val
-
vvv_ind
[
ii
][
0
][
out_idx
];
}
});
auto
ind
=
calc_neighbor_points
(
vvv_ind
,
0
,
std
::
vector
<
std
::
vector
<
std
::
size_t
>>
(
out_elements
),
in_s
);
auto
ind_lens
=
out_lens
;
ind_lens
[
0
]
*=
(
std
::
size_t
{
1
}
<<
n_dim
);
shape
ind_s
{
shape
::
int32_type
,
ind_lens
};
auto
ins_ind
=
info
.
add_literal
(
literal
(
ind_s
,
ind
));
auto
data
=
info
.
add_instruction
(
make_op
(
"gather"
,
{{
"axis"
,
0
}}),
rsp
,
ins_ind
);
auto
dim_lens
=
out_lens
;
dim_lens
[
0
]
*=
(
std
::
size_t
{
1
}
<<
(
n_dim
-
1
));
for
(
std
::
size_t
i
=
0
;
i
<
n_dim
;
++
i
)
{
{
shape
dim_s
{
shape
::
float_type
,
dim_lens
};
auto
nearest_floor
=
get_nearest_op
(
"floor"
);
const
auto
&
dim_delta
=
delta
[
n_dim
-
i
-
1
];
auto
nearest_ceil
=
get_nearest_op
(
"ceil"
);
std
::
vector
<
float
>
delta_data
;
for
(
std
::
size_t
j
=
0
;
j
<
dim_lens
[
0
]
/
out_lens
[
0
];
++
j
)
// get the number of dimensions
std
::
size_t
n_dim
=
out_lens
.
size
();
auto
vvv_ind
=
std
::
vector
(
n_dim
,
std
::
vector
(
2
,
std
::
vector
<
size_t
>
(
out_elements
)));
std
::
vector
<
std
::
vector
<
float
>>
delta
(
n_dim
,
std
::
vector
<
float
>
(
out_elements
));
shape_for_each
(
out_s
,
[
&
](
const
auto
&
out_idx_v
,
size_t
out_idx
)
{
for
(
auto
ii
=
0
;
ii
<
in_lens
.
size
();
++
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
][
1
][
out_idx
]
=
nearest_ceil
(
in_lens
[
ii
],
idx_val
);
delta
[
ii
][
out_idx
]
=
idx_val
-
vvv_ind
[
ii
][
0
][
out_idx
];
}
});
auto
ind
=
calc_neighbor_points
(
vvv_ind
,
0
,
std
::
vector
<
std
::
vector
<
std
::
size_t
>>
(
out_elements
),
in_s
);
auto
ind_lens
=
out_lens
;
ind_lens
[
0
]
*=
(
std
::
size_t
{
1
}
<<
n_dim
);
shape
ind_s
{
shape
::
int32_type
,
ind_lens
};
auto
ins_ind
=
info
.
add_literal
(
literal
(
ind_s
,
ind
));
auto
data
=
info
.
add_instruction
(
make_op
(
"gather"
,
{{
"axis"
,
0
}}),
rsp
,
ins_ind
);
auto
dim_lens
=
out_lens
;
dim_lens
[
0
]
*=
(
std
::
size_t
{
1
}
<<
(
n_dim
-
1
));
for
(
std
::
size_t
i
=
0
;
i
<
n_dim
;
++
i
)
{
{
delta_data
.
insert
(
delta_data
.
begin
(),
dim_delta
.
begin
(),
dim_delta
.
end
());
shape
dim_s
{
shape
::
float_type
,
dim_lens
};
}
const
auto
&
dim_delta
=
delta
[
n_dim
-
i
-
1
];
auto
ins_delta
=
info
.
add_literal
(
dim_s
,
delta_data
);
std
::
vector
<
float
>
delta_data
;
for
(
std
::
size_t
j
=
0
;
j
<
dim_lens
[
0
]
/
out_lens
[
0
];
++
j
)
// slice the data
{
int64_t
slc_stride
=
dim_lens
[
0
];
delta_data
.
insert
(
delta_data
.
begin
(),
dim_delta
.
begin
(),
dim_delta
.
end
());
auto
low
=
info
.
add_instruction
(
}
make_op
(
"slice"
,
{{
"axes"
,
{
0
}},
{
"starts"
,
{
0
}},
{
"ends"
,
{
slc_stride
}}}),
auto
ins_delta
=
info
.
add_literal
(
dim_s
,
delta_data
);
data
);
auto
hi
=
info
.
add_instruction
(
// slice the data
make_op
(
"slice"
,
int64_t
slc_stride
=
dim_lens
[
0
];
auto
low
=
info
.
add_instruction
(
make_op
(
"slice"
,
{{
"axes"
,
{
0
}},
{
"starts"
,
{
0
}},
{
"ends"
,
{
slc_stride
}}}),
data
);
auto
hi
=
info
.
add_instruction
(
make_op
(
"slice"
,
{{
"axes"
,
{
0
}},
{
"starts"
,
{
slc_stride
}},
{
"ends"
,
{
2
*
slc_stride
}}}),
{{
"axes"
,
{
0
}},
{
"starts"
,
{
slc_stride
}},
{
"ends"
,
{
2
*
slc_stride
}}}),
data
);
data
);
auto
diff
=
info
.
add_instruction
(
make_op
(
"sub"
),
hi
,
low
);
auto
diff
=
info
.
add_instruction
(
make_op
(
"sub"
),
hi
,
low
);
auto
ddf
=
info
.
add_instruction
(
make_op
(
"mul"
),
diff
,
ins_delta
);
auto
ddf
=
info
.
add_instruction
(
make_op
(
"mul"
),
diff
,
ins_delta
);
data
=
info
.
add_instruction
(
make_op
(
"add"
),
ddf
,
low
);
data
=
info
.
add_instruction
(
make_op
(
"add"
),
ddf
,
low
);
dim_lens
[
0
]
/=
2
;
dim_lens
[
0
]
/=
2
;
}
}
return
data
;
return
data
;
}
}
}
}
}
};
};
...
...
test/onnx/gen_onnx.py
View file @
19bbfb2b
...
@@ -5652,14 +5652,37 @@ def resize_downsample_f_test():
...
@@ -5652,14 +5652,37 @@ def resize_downsample_f_test():
dims
=
scales
.
shape
,
dims
=
scales
.
shape
,
vals
=
scales
.
flatten
().
astype
(
np
.
float32
))
vals
=
scales
.
flatten
().
astype
(
np
.
float32
))
X
=
helper
.
make_tensor_value_info
(
'X'
,
TensorProto
.
FLOAT
,
[
1
,
1
,
2
,
4
])
X
=
helper
.
make_tensor_value_info
(
'X'
,
TensorProto
.
FLOAT
,
[
1
,
1
,
35
,
60
])
Y
=
helper
.
make_tensor_value_info
(
'Y'
,
TensorProto
.
FLOAT
,
[])
node
=
onnx
.
helper
.
make_node
(
'Resize'
,
inputs
=
[
'X'
,
''
,
'scales'
],
outputs
=
[
'Y'
],
coordinate_transformation_mode
=
'asymmetric'
,
mode
=
'nearest'
,
nearest_mode
=
'floor'
)
return
([
node
],
[
X
],
[
Y
],
[
scale_tensor
])
@
onnx_test
()
def
resize_downsample_f_dyn_test
():
scales
=
np
.
array
([
1.0
,
1.0
,
0.6
,
0.6
],
dtype
=
np
.
float32
)
scale_tensor
=
helper
.
make_tensor
(
name
=
'scales'
,
data_type
=
TensorProto
.
FLOAT
,
dims
=
scales
.
shape
,
vals
=
scales
.
flatten
().
astype
(
np
.
float32
))
X
=
helper
.
make_tensor_value_info
(
'X'
,
TensorProto
.
FLOAT
,
[
None
,
1
,
35
,
60
])
Y
=
helper
.
make_tensor_value_info
(
'Y'
,
TensorProto
.
FLOAT
,
[])
Y
=
helper
.
make_tensor_value_info
(
'Y'
,
TensorProto
.
FLOAT
,
[])
node
=
onnx
.
helper
.
make_node
(
node
=
onnx
.
helper
.
make_node
(
'Resize'
,
'Resize'
,
inputs
=
[
'X'
,
''
,
'scales'
],
inputs
=
[
'X'
,
''
,
'scales'
],
outputs
=
[
'Y'
],
outputs
=
[
'Y'
],
coordinate_transformation_mode
=
'a
lign_corners
'
,
coordinate_transformation_mode
=
'a
symmetric
'
,
mode
=
'nearest'
,
mode
=
'nearest'
,
nearest_mode
=
'floor'
)
nearest_mode
=
'floor'
)
...
...
test/onnx/onnx_test.cpp
View file @
19bbfb2b
...
@@ -5374,7 +5374,7 @@ TEST_CASE(resize_downsample_f_test)
...
@@ -5374,7 +5374,7 @@ TEST_CASE(resize_downsample_f_test)
migraphx
::
shape
ss
{
migraphx
::
shape
::
float_type
,
{
4
}};
migraphx
::
shape
ss
{
migraphx
::
shape
::
float_type
,
{
4
}};
mm
->
add_literal
(
migraphx
::
literal
{
ss
,
ds
});
mm
->
add_literal
(
migraphx
::
literal
{
ss
,
ds
});
migraphx
::
shape
sx
{
migraphx
::
shape
::
float_type
,
{
1
,
1
,
2
,
4
}};
migraphx
::
shape
sx
{
migraphx
::
shape
::
float_type
,
{
1
,
1
,
35
,
60
}};
auto
inx
=
mm
->
add_parameter
(
"X"
,
sx
);
auto
inx
=
mm
->
add_parameter
(
"X"
,
sx
);
mm
->
add_instruction
(
migraphx
::
make_op
(
"undefined"
));
mm
->
add_instruction
(
migraphx
::
make_op
(
"undefined"
));
...
@@ -5383,7 +5383,7 @@ TEST_CASE(resize_downsample_f_test)
...
@@ -5383,7 +5383,7 @@ TEST_CASE(resize_downsample_f_test)
std
::
vector
<
int
>
ind
=
{
0
,
3
};
std
::
vector
<
int
>
ind
=
{
0
,
3
};
auto
li
=
mm
->
add_literal
(
migraphx
::
literal
(
si
,
ind
));
auto
li
=
mm
->
add_literal
(
migraphx
::
literal
(
si
,
ind
));
auto
lrsp
=
mm
->
add_instruction
(
migraphx
::
make_op
(
"reshape"
,
{{
"dims"
,
{
8
}}}),
inx
);
auto
lrsp
=
mm
->
add_instruction
(
migraphx
::
make_op
(
"reshape"
,
{{
"dims"
,
{
2100
}}}),
inx
);
auto
r
=
mm
->
add_instruction
(
migraphx
::
make_op
(
"gather"
,
{{
"axis"
,
0
}}),
lrsp
,
li
);
auto
r
=
mm
->
add_instruction
(
migraphx
::
make_op
(
"gather"
,
{{
"axis"
,
0
}}),
lrsp
,
li
);
mm
->
add_return
({
r
});
mm
->
add_return
({
r
});
...
@@ -5392,6 +5392,39 @@ TEST_CASE(resize_downsample_f_test)
...
@@ -5392,6 +5392,39 @@ TEST_CASE(resize_downsample_f_test)
EXPECT
(
p
==
prog
);
EXPECT
(
p
==
prog
);
}
}
TEST_CASE
(
resize_downsample_f_dyn_test
)
{
migraphx
::
program
p
;
auto
*
mm
=
p
.
get_main_module
();
std
::
vector
<
float
>
ds
=
{
1.0
f
,
1.0
f
,
0.6
f
,
0.6
f
};
migraphx
::
shape
ss
{
migraphx
::
shape
::
float_type
,
{
4
}};
mm
->
add_literal
(
migraphx
::
literal
{
ss
,
ds
});
// reshape only allows one non-fixed dimension
migraphx
::
shape
sx
{
migraphx
::
shape
::
float_type
,
{{
1
,
4
,
{
1
,
4
}},
{
1
,
1
},
{
35
,
35
},
{
60
,
60
}}};
auto
inx
=
mm
->
add_parameter
(
"X"
,
sx
);
mm
->
add_instruction
(
migraphx
::
make_op
(
"undefined"
));
// the "nearest" indices to gather
migraphx
::
shape
si
{
migraphx
::
shape
::
int32_type
,
{
1
,
1
,
1
,
2
}};
std
::
vector
<
int
>
ind
=
{
0
,
3
};
auto
li
=
mm
->
add_literal
(
migraphx
::
literal
(
si
,
ind
));
// dim corresponding to the non-static dimension in sx must be either 0 or -1. Still
// don't know what this is for
auto
lrsp
=
mm
->
add_instruction
(
migraphx
::
make_op
(
"reshape"
,
{{
"dims"
,
{
0
,
2100
,
1
,
1
}}}),
inx
);
auto
r
=
mm
->
add_instruction
(
migraphx
::
make_op
(
"gather"
,
{{
"axis"
,
0
}}),
lrsp
,
li
);
mm
->
add_return
({
r
});
migraphx
::
onnx_options
options
;
options
.
map_dyn_input_dims
[
"X"
]
=
{{
1
,
4
,
{
1
,
4
}},
{
1
,
1
},
{
35
,
35
},
{
60
,
60
}};
auto
prog
=
migraphx
::
parse_onnx
(
"resize_downsample_f_dyn_test.onnx"
,
options
);
EXPECT
(
p
==
prog
);
}
TEST_CASE
(
resize_downsample_linear_test
)
TEST_CASE
(
resize_downsample_linear_test
)
{
{
migraphx
::
program
p
;
migraphx
::
program
p
;
...
...
test/onnx/resize_downsample_f_test.onnx
View file @
19bbfb2b
No preview for this file type
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