Commit 5b68317c authored by Scott Thornton's avatar Scott Thornton
Browse files

Fixed the parsing of padding in conv and pool

parent f46c7008
...@@ -285,6 +285,12 @@ struct transpose ...@@ -285,6 +285,12 @@ struct transpose
int output_alias(const std::vector<shape>&) const { return 0; } int output_alias(const std::vector<shape>&) const { return 0; }
}; };
// The contiguous operator takes a non-standard input tensor and returns
// the same tensor but in standard form. For example, if input tensor A which has lens = (4,5)
// is first transposed, i.e. lens = (5,4), this tensor's data layout remained the same
// during the transpose operation; only it's shape lengths and strides were changed.
// This leaves the tensor in a non-standard form. The contiguous operator copies the
// underlying data such that resulting tensor is returned to a standard form.
struct contiguous struct contiguous
{ {
std::string name() const { return "contiguous"; } std::string name() const { return "contiguous"; }
...@@ -400,15 +406,6 @@ struct slice ...@@ -400,15 +406,6 @@ struct slice
auto t = input_shape.type(); auto t = input_shape.type();
const auto& old_lens = input_shape.lens(); const auto& old_lens = input_shape.lens();
const auto& old_strides = input_shape.strides(); const auto& old_strides = input_shape.strides();
// std::vector<int64_t> t_axes(old_lens.size());
// if(axes.size() == 0)
// {
// std::iota(t_axes.begin(), t_axes.end(), 0);
// }
// else
// {
// std::copy(axes.begin(), axes.end(), t_axes.begin());
// }
if(starts.size() != axes.size() || axes.size() != ends.size()) if(starts.size() != axes.size() || axes.size() != ends.size())
{ {
MIGRAPH_THROW("inconsistent sizes"); MIGRAPH_THROW("inconsistent sizes");
...@@ -718,6 +715,14 @@ struct flatten ...@@ -718,6 +715,14 @@ struct flatten
} }
int output_alias(const std::vector<shape>&) const { return 0; } int output_alias(const std::vector<shape>&) const { return 0; }
}; };
// The broadcast operator performs the numpy-style broadcasting of an axis of a given tensor. This is achieved
// primarily by setting the stride of the broadcasted axis to zero. Linear indicies are computed from multi-indicies
// by computing the inner product on the multi-index with the strides. For example, if we have a tensor A(2,3) it has
// lengths of (2,3) and strides of (3,1). If we want to compute the linear offset that corresponds to the element
// on the 2nd row (i = 1) and 3rd column (j = 2), we compute the following inner product (1,2) dot (3, 1) =
// 1*3 + 2*1 = 5. It is obvious from there that we can negate the effects of a given axis by setting the
// stride of that axis to zero.
struct broadcast struct broadcast
{ {
uint64_t axis = 0; uint64_t axis = 0;
......
...@@ -44,6 +44,7 @@ struct onnx_parser ...@@ -44,6 +44,7 @@ struct onnx_parser
node_map nodes; node_map nodes;
std::unordered_map<std::string, instruction_ref> instructions; std::unordered_map<std::string, instruction_ref> instructions;
program prog = program(); program prog = program();
bool is_pytorch = false;
std::unordered_map<std::string, op_func> ops; std::unordered_map<std::string, op_func> ops;
...@@ -138,7 +139,7 @@ struct onnx_parser ...@@ -138,7 +139,7 @@ struct onnx_parser
std::swap(s0, s1); std::swap(s0, s1);
// Copy the larger vector to output_lens // Copy the larger vector to output_lens
std::vector<std::size_t> output_lens(s1->size()); std::vector<std::size_t> output_lens = *s1;
auto offset = s1->size() - s0->size(); auto offset = s1->size() - s0->size();
std::transform(s0->begin(), std::transform(s0->begin(),
s0->end(), s0->end(),
...@@ -181,7 +182,22 @@ struct onnx_parser ...@@ -181,7 +182,22 @@ struct onnx_parser
op::convolution op; op::convolution op;
if(contains(attributes, "pads")) if(contains(attributes, "pads"))
{ {
copy(attributes["pads"].ints(), op.padding.begin()); if (contains(attributes, "auto_pad"))
{
MIGRAPH_THROW("auto_pad and padding cannot be specified simultaneously");
}
std::vector<std::size_t> padding(4);
copy(attributes["pads"].ints(), padding.begin());
if (padding.size() != 4)
{
MIGRAPH_THROW("padding should have 4 values");
}
if (padding[0] != padding[2] || padding[1] != padding[3])
{
MIGRAPH_THROW("migraphx does not support asymetric padding");
}
op.padding[0] = padding[0];
op.padding[1] = padding[1];
} }
if(contains(attributes, "strides")) if(contains(attributes, "strides"))
{ {
...@@ -191,6 +207,19 @@ struct onnx_parser ...@@ -191,6 +207,19 @@ struct onnx_parser
{ {
copy(attributes["dilations"].ints(), op.dilation.begin()); copy(attributes["dilations"].ints(), op.dilation.begin());
} }
if (contains(attributes, "auto_pad"))
{
auto s = attributes["auto_pad"].s();
if (contains(attributes, "pads") and to_upper(s) != "NOTSET")
{
MIGRAPH_THROW("auto_pad and padding cannot be specified simultaneously");
}
if (s.find("SAME") >= 0)
{
op.padding_mode = op::convolution::same;
}
}
if(args.size() == 3) if(args.size() == 3)
{ {
uint64_t axis = 1; uint64_t axis = 1;
...@@ -213,7 +242,18 @@ struct onnx_parser ...@@ -213,7 +242,18 @@ struct onnx_parser
} }
if(contains(attributes, "pads")) if(contains(attributes, "pads"))
{ {
copy(attributes["pads"].ints(), op.padding.begin()); std::vector<std::size_t> padding(4);
copy(attributes["pads"].ints(), padding.begin());
if (padding.size() != 4)
{
MIGRAPH_THROW("padding should have 4 values");
}
if (padding[0] != padding[2] || padding[1] != padding[3])
{
MIGRAPH_THROW("migraphx does not support asymetric padding");
}
op.padding[0] = padding[0];
op.padding[1] = padding[1];
} }
if(contains(attributes, "strides")) if(contains(attributes, "strides"))
{ {
...@@ -223,6 +263,15 @@ struct onnx_parser ...@@ -223,6 +263,15 @@ struct onnx_parser
{ {
copy(attributes["kernel_shape"].ints(), op.lengths.begin()); copy(attributes["kernel_shape"].ints(), op.lengths.begin());
} }
if (contains(attributes, "auto_pad"))
{
auto s = attributes["auto_pad"].s();
if (to_upper(s) != "NOTSET")
{
MIGRAPH_THROW("auto_pad is not supported for pooling");
}
}
return prog.add_instruction(op, std::move(args)); return prog.add_instruction(op, std::move(args));
} }
...@@ -432,6 +481,15 @@ struct onnx_parser ...@@ -432,6 +481,15 @@ struct onnx_parser
onnx::ModelProto model; onnx::ModelProto model;
if(model.ParseFromIstream(&is)) if(model.ParseFromIstream(&is))
{ {
auto str_toupper = [](std::string s) {
std::transform(s.begin(), s.end(), s.begin(),
[](unsigned char c){ return std::toupper(c);
});
return s;
};
auto producer_name = str_toupper(model.producer_name());
std::cout << producer_name << std::endl;
if(model.has_graph()) if(model.has_graph())
{ {
this->parse_graph(model.graph()); this->parse_graph(model.graph());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment