Commit 7dc6e3ae authored by Khalique Ahmed's avatar Khalique Ahmed
Browse files

Merge branch 'develop' of https://github.com/ROCmSoftwarePlatform/AMDMIGraphX into mi100_opts

parents f94d77fc a275f590
......@@ -10,10 +10,10 @@
#include <migraphx/op/dot.hpp>
#include <migraphx/op/quant_dot.hpp>
#include <migraphx/op/elu.hpp>
#include <migraphx/op/if_op.hpp>
#include <migraphx/op/im2col.hpp>
#include <migraphx/op/leaky_relu.hpp>
#include <migraphx/op/logsoftmax.hpp>
#include <migraphx/op/loop.hpp>
#include <migraphx/op/lrn.hpp>
#include <migraphx/op/pad.hpp>
#include <migraphx/op/pooling.hpp>
......@@ -269,99 +269,6 @@ struct ref_convolution : auto_register_op<ref_convolution<Op>>
}
};
template <class Op>
struct ref_deconvolution : auto_register_op<ref_deconvolution<Op>>
{
ref_deconvolution() = default;
ref_deconvolution(Op pop) : op(std::move(pop)) {}
Op op;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return migraphx::reflect(self.op, f);
}
std::string name() const { return "ref::" + op.name(); }
shape compute_shape(const std::vector<shape>& inputs) const { return op.compute_shape(inputs); }
argument compute(context&, shape output_shape, std::vector<argument> args) const
{
argument result{output_shape};
visit_all(result, args[0], args[1])([&](auto output, auto input, auto weights) {
using type = typename decltype(output)::value_type;
std::fill(output.begin(), output.end(), type{0});
auto in_lens = input.get_shape().lens();
auto in_n = in_lens[0];
auto in_c = in_lens[1];
auto wei = weights.get_shape().lens();
auto wei_n = wei[0];
auto wei_c = wei[1];
auto out_lens = output_shape.lens();
auto kdims = op.kdims();
std::vector<std::size_t> win_size{in_c};
std::copy(in_lens.begin() + 2, in_lens.end(), std::back_inserter(win_size));
std::copy(wei.begin() + 2, wei.end(), std::back_inserter(win_size));
shape win_shape{output_shape.type(), win_size};
par_dfor(in_n, wei_c)([&](int o, int k) {
shape_for_each(win_shape, [&](auto idx_win) {
const int w = idx_win[0];
auto input_dims_start = idx_win.begin() + 1;
auto wei_dims_start = idx_win.begin() + kdims + 1;
std::vector<std::ptrdiff_t> win_start;
for(std::size_t n = 0; n < kdims; ++n)
{
win_start.push_back(std::ptrdiff_t(*(input_dims_start + n) * op.stride[n]) -
std::ptrdiff_t(op.padding[n]));
}
const int group_id = w / (wei_n / op.group);
const int in_ch = group_id * wei_c + k;
std::vector<std::ptrdiff_t> idx_out{o, in_ch};
for(size_t n = 0; n < kdims; n++)
{
idx_out.push_back(win_start[n] + *(wei_dims_start + n) * op.dilation[n]);
}
std::vector<std::ptrdiff_t> idx_wei{w, k};
std::copy(wei_dims_start, idx_win.end(), std::back_inserter(idx_wei));
std::vector<std::ptrdiff_t> idx_in{o, w};
std::copy(input_dims_start, wei_dims_start, std::back_inserter(idx_in));
if(std::all_of(
idx_out.begin() + 2, idx_out.end(), [&](auto ii) { return ii >= 0; }) and
std::equal(idx_out.begin() + 2,
idx_out.end(),
out_lens.begin() + 2,
out_lens.end(),
std::less<std::ptrdiff_t>{}))
{
output(idx_out.begin(), idx_out.end()) +=
input(idx_in.begin(), idx_in.end()) *
weights(idx_wei.begin(), idx_wei.end());
}
});
});
});
return result;
}
};
struct ref_im2col
{
op::im2col op;
......@@ -917,10 +824,8 @@ struct ref_apply
apply_map["batch_norm_inference"] =
extend_op<ref_batch_norm_inference, op::batch_norm_inference>();
apply_map["convolution"] = extend_op<ref_convolution<op::convolution>, op::convolution>();
apply_map["deconvolution"] =
extend_op<ref_deconvolution<op::deconvolution>, op::deconvolution>();
apply_map["dot"] = extend_op<ref_gemm, op::dot>();
apply_map["quant_dot"] = extend_op<ref_quant_gemm, op::quant_dot>();
apply_map["dot"] = extend_op<ref_gemm, op::dot>();
apply_map["quant_dot"] = extend_op<ref_quant_gemm, op::quant_dot>();
apply_map["quant_convolution"] =
extend_op<ref_convolution<op::quant_convolution>, op::quant_convolution>();
apply_map["elu"] = extend_op<ref_unary<elu_op>, op::elu>();
......
......@@ -20,7 +20,8 @@ struct parse_biasadd : op_parser<parse_biasadd>
uint64_t axis = 1; // assume output of previous layer is in NCHW (broadcast on channel)
auto l0 = info.add_instruction(
make_op("broadcast", {{"axis", axis}, {"dims", args[0]->get_shape().lens()}}), args[1]);
make_op("broadcast", {{"axis", axis}, {"out_lens", args[0]->get_shape().lens()}}),
args[1]);
return info.add_instruction(make_op("add"), args[0], l0);
}
};
......
......@@ -46,10 +46,12 @@ struct parse_matmul : op_parser<parse_matmul>
// swap the last two elements
std::iter_swap(perm.end() - 1, perm.end() - 2);
auto l1 = (transa) ? info.add_instruction(make_op("transpose", {{"dims", perm}}), args[0])
: args[0];
auto l2 = (transb) ? info.add_instruction(make_op("transpose", {{"dims", perm}}), args[1])
: args[1];
auto l1 = (transa)
? info.add_instruction(make_op("transpose", {{"permutation", perm}}), args[0])
: args[0];
auto l2 = (transb)
? info.add_instruction(make_op("transpose", {{"permutation", perm}}), args[1])
: args[1];
return info.add_instruction(make_op("dot"), l1, l2);
}
......
......@@ -23,9 +23,9 @@ struct parse_relu6 : op_parser<parse_relu6>
auto max_val = info.add_literal(6.0f);
min_val =
info.add_instruction(make_op("multibroadcast", {{"output_lens", input_lens}}), min_val);
info.add_instruction(make_op("multibroadcast", {{"out_lens", input_lens}}), min_val);
max_val =
info.add_instruction(make_op("multibroadcast", {{"output_lens", input_lens}}), max_val);
info.add_instruction(make_op("multibroadcast", {{"out_lens", input_lens}}), max_val);
return info.add_instruction(make_op("clip"), args.front(), min_val, max_val);
}
};
......
......@@ -20,7 +20,7 @@ struct parse_transpose : op_parser<parse_transpose>
auto perm = args[1]->eval().get<int32_t>().to_vector();
std::vector<int64_t> dims(perm.begin(), perm.end());
return info.add_instruction(make_op("transpose", {{"dims", dims}}), args.front());
return info.add_instruction(make_op("transpose", {{"permutation", dims}}), args.front());
}
};
......
......@@ -35,20 +35,20 @@ bool tf_parser::should_transpose(instruction_ref ins) const
instruction_ref tf_parser::to_nhwc(instruction_ref ins) const
{
if(should_transpose(ins))
return mm->add_instruction(make_op("transpose", {{"dims", {0, 2, 3, 1}}}), ins);
return mm->add_instruction(make_op("transpose", {{"permutation", {0, 2, 3, 1}}}), ins);
return ins;
}
instruction_ref tf_parser::to_nchw(instruction_ref ins) const
{
if(should_transpose(ins))
return mm->add_instruction(make_op("transpose", {{"dims", {0, 3, 1, 2}}}), ins);
return mm->add_instruction(make_op("transpose", {{"permutation", {0, 3, 1, 2}}}), ins);
return ins;
}
instruction_ref tf_parser::to_kcxy(instruction_ref ins) const
{
return mm->add_instruction(make_op("transpose", {{"dims", {3, 2, 0, 1}}}), ins);
return mm->add_instruction(make_op("transpose", {{"permutation", {3, 2, 0, 1}}}), ins);
}
std::vector<instruction_ref> tf_parser::to_nchw(const std::vector<instruction_ref>& args) const
......
......@@ -224,23 +224,24 @@ std::vector<value>& get_array_throw(const std::shared_ptr<value_base_impl>& x)
return *a;
}
value* find_impl(const std::shared_ptr<value_base_impl>& x, const std::string& key)
template <class T>
T* find_impl(const std::shared_ptr<value_base_impl>& x, const std::string& key, T* end)
{
auto* a = if_array_impl(x);
if(a == nullptr)
return nullptr;
return end;
auto* lookup = x->if_object();
if(lookup == nullptr)
return nullptr;
return end;
auto it = lookup->find(key);
if(it == lookup->end())
return a->data() + a->size();
return end;
return std::addressof((*a)[it->second]);
}
value* value::find(const std::string& pkey) { return find_impl(x, pkey); }
value* value::find(const std::string& pkey) { return find_impl(x, pkey, this->end()); }
const value* value::find(const std::string& pkey) const { return find_impl(x, pkey); }
const value* value::find(const std::string& pkey) const { return find_impl(x, pkey, this->end()); }
bool value::contains(const std::string& pkey) const
{
const auto* it = find(pkey);
......
......@@ -163,4 +163,16 @@ TEST_CASE(get_main_module)
p.print();
}
TEST_CASE(set_loop_default_iter_num)
{
migraphx::onnx_options option;
option.set_default_loop_iterations(15);
auto p = migraphx::parse_onnx("loop_default_test.onnx", option);
auto out_shapes = p.get_output_shapes();
std::vector<std::size_t> out_lens0 = {1};
EXPECT(out_shapes[0].lengths() == out_lens0);
std::vector<std::size_t> out_lens1 = {15, 1};
EXPECT(out_shapes[1].lengths() == out_lens1);
}
int main(int argc, const char* argv[]) { test::run(argc, argv); }
......@@ -74,4 +74,62 @@ TEST_CASE(if_pl_test)
}
}
TEST_CASE(loop_test)
{
auto run_prog = [&](int64_t max_iter_num) {
migraphx::onnx_options parse_options;
parse_options.set_default_loop_iterations(max_iter_num);
auto p = migraphx::parse_onnx("loop_default_test.onnx", parse_options);
auto shapes_before = p.get_output_shapes();
migraphx_compile_options options;
options.offload_copy = true;
p.compile(migraphx::target("gpu"), options);
auto shapes_after = p.get_output_shapes();
CHECK(shapes_before.size() == 2);
CHECK(bool{shapes_before.front() == shapes_after.front()});
migraphx::program_parameters pp;
auto param_shapes = p.get_parameter_shapes();
auto aas = param_shapes["a"];
std::vector<float> xd = {1.0f};
pp.add("a", migraphx::argument(aas, xd.data()));
auto bbs = param_shapes["b"];
std::vector<float> yd = {2.0};
pp.add("b", migraphx::argument(bbs, yd.data()));
auto outputs = p.eval(pp);
auto output = outputs[0];
auto lens = output.get_shape().lengths();
auto elem_num =
std::accumulate(lens.begin(), lens.end(), 1, std::multiplies<std::size_t>());
float* data_ptr = reinterpret_cast<float*>(output.data());
std::vector<std::vector<float>> ret;
ret.push_back({data_ptr, data_ptr + elem_num});
output = outputs[1];
lens = output.get_shape().lengths();
elem_num = std::accumulate(lens.begin(), lens.end(), 1, std::multiplies<std::size_t>());
data_ptr = reinterpret_cast<float*>(output.data());
ret.push_back({data_ptr, data_ptr + elem_num});
return ret;
};
{
auto result_vector = run_prog(10);
std::vector<float> gold0 = {2.0f};
EXPECT(result_vector.at(0) == gold0);
std::vector<float> gold1 = {-2, 4, 0, 0, 0, 0, 0, 0, 0, 0};
EXPECT(result_vector.at(1) == gold1);
}
{
auto result_vector = run_prog(15);
std::vector<float> gold0 = {2.0f};
EXPECT(result_vector.at(0) == gold0);
std::vector<float> gold1 = {-2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
EXPECT(result_vector.at(1) == gold1);
}
}
int main(int argc, const char* argv[]) { test::run(argc, argv); }
......@@ -98,6 +98,22 @@ TEST_CASE(nested_tuple)
EXPECT(a1.to_string() != a3.to_string());
}
TEST_CASE(tuple_construct)
{
migraphx::shape s{{migraphx::shape{migraphx::shape::float_type, {4}},
migraphx::shape{migraphx::shape::int8_type, {3}}}};
migraphx::argument a{s};
EXPECT(a.get_sub_objects().size() == 2);
EXPECT(a.get_shape() == s);
auto b = a; // NOLINT
EXPECT(a.get_shape() == b.get_shape());
EXPECT(a.get_sub_objects().size() == 2);
EXPECT(a.get_sub_objects()[0] == b.get_sub_objects()[0]);
EXPECT(a.get_sub_objects()[1] == b.get_sub_objects()[1]);
EXPECT(a == b);
}
TEST_CASE(tuple_visit)
{
auto a1 = make_tuple(3, 3.0);
......
......@@ -40,7 +40,7 @@ TEST_CASE(after_literal_transpose)
auto l = m.add_literal(get_2x2());
EXPECT(m.get_output_shapes().back().standard());
EXPECT(not m.get_output_shapes().back().transposed());
auto t = m.add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), l);
auto t = m.add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l);
m.add_instruction(pass_op{}, t);
EXPECT(not m.get_output_shapes().back().standard());
EXPECT(m.get_output_shapes().back().transposed());
......@@ -58,7 +58,7 @@ TEST_CASE(after_literal_broadcast)
EXPECT(m.get_output_shapes().back().standard());
EXPECT(not m.get_output_shapes().back().broadcasted());
auto b = m.add_instruction(
migraphx::make_op("broadcast", {{"axis", 0}, {"dims", l1->get_shape().lens()}}), l2);
migraphx::make_op("broadcast", {{"axis", 0}, {"out_lens", l1->get_shape().lens()}}), l2);
m.add_instruction(pass_op{}, b);
EXPECT(not m.get_output_shapes().back().standard());
EXPECT(m.get_output_shapes().back().broadcasted());
......@@ -74,7 +74,7 @@ TEST_CASE(after_param_transpose)
auto l = m.add_parameter("2x2", {migraphx::shape::float_type, {2, 2}});
EXPECT(m.get_output_shapes().back().standard());
EXPECT(not m.get_output_shapes().back().transposed());
auto t = m.add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), l);
auto t = m.add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l);
m.add_instruction(pass_op{}, t);
EXPECT(not m.get_output_shapes().back().standard());
EXPECT(m.get_output_shapes().back().transposed());
......@@ -92,7 +92,7 @@ TEST_CASE(after_param_broadcast)
EXPECT(m.get_output_shapes().back().standard());
EXPECT(not m.get_output_shapes().back().broadcasted());
auto b = m.add_instruction(
migraphx::make_op("broadcast", {{"axis", 0}, {"dims", l1->get_shape().lens()}}), l2);
migraphx::make_op("broadcast", {{"axis", 0}, {"out_lens", l1->get_shape().lens()}}), l2);
m.add_instruction(pass_op{}, b);
EXPECT(not m.get_output_shapes().back().standard());
EXPECT(m.get_output_shapes().back().broadcasted());
......
......@@ -197,4 +197,24 @@ TEST_CASE(unused_module)
EXPECT(not migraphx::contains(p.get_modules(), m1));
}
TEST_CASE(param_not_eliminated)
{
auto create_program = [] {
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape s{migraphx::shape::int32_type, {2, 2}};
auto x = mm->add_parameter("x", s);
auto y = mm->add_parameter("y", s);
mm->add_parameter("z", s);
auto sum = mm->add_instruction(migraphx::make_op("add"), x, y);
mm->add_return({sum});
return p;
};
auto p = create_program();
run_pass(p);
EXPECT(p == create_program());
}
int main(int argc, const char* argv[]) { test::run(argc, argv); }
......@@ -50,8 +50,8 @@ TEST_CASE(dot_add_beta_float)
auto dot = m2.add_instruction(migraphx::make_op("dot", {{"alpha", 1}, {"beta", 0}}), x, y);
auto beta =
m2.add_literal(migraphx::literal{migraphx::shape{migraphx::shape::float_type}, {0.5}});
auto beta_broadcast = m2.add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", {2, 2}}}), beta);
auto beta_broadcast =
m2.add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2}}}), beta);
auto mul = m2.add_instruction(migraphx::make_op("mul"), z, beta_broadcast);
auto add = m2.add_instruction(migraphx::make_op("add"), dot, mul);
m2.add_instruction(migraphx::make_op("identity"), add);
......@@ -79,8 +79,8 @@ TEST_CASE(dot_add_beta_half)
auto dot = m2.add_instruction(migraphx::make_op("dot", {{"alpha", 1}, {"beta", 0}}), x, y);
auto beta =
m2.add_literal(migraphx::literal{migraphx::shape{migraphx::shape::half_type}, {0.5}});
auto beta_broadcast = m2.add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", {2, 2}}}), beta);
auto beta_broadcast =
m2.add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2}}}), beta);
auto mul = m2.add_instruction(migraphx::make_op("mul"), z, beta_broadcast);
auto add = m2.add_instruction(migraphx::make_op("add"), dot, mul);
m2.add_instruction(migraphx::make_op("identity"), add);
......@@ -108,8 +108,8 @@ TEST_CASE(dot_add_beta_double)
auto dot = m2.add_instruction(migraphx::make_op("dot", {{"alpha", 1}, {"beta", 0}}), x, y);
auto beta =
m2.add_literal(migraphx::literal{migraphx::shape{migraphx::shape::double_type}, {0.5}});
auto beta_broadcast = m2.add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", {2, 2}}}), beta);
auto beta_broadcast =
m2.add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2}}}), beta);
auto mul = m2.add_instruction(migraphx::make_op("mul"), z, beta_broadcast);
auto add = m2.add_instruction(migraphx::make_op("add"), dot, mul);
m2.add_instruction(migraphx::make_op("identity"), add);
......@@ -137,8 +137,8 @@ TEST_CASE(dot_add_beta_int)
auto dot = m2.add_instruction(migraphx::make_op("dot", {{"alpha", 1}, {"beta", 0}}), x, y);
auto beta =
m2.add_literal(migraphx::literal{migraphx::shape{migraphx::shape::int32_type}, {0.5}});
auto beta_broadcast = m2.add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", {2, 2}}}), beta);
auto beta_broadcast =
m2.add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {2, 2}}}), beta);
auto mul = m2.add_instruction(migraphx::make_op("mul"), z, beta_broadcast);
auto add = m2.add_instruction(migraphx::make_op("add"), dot, mul);
m2.add_instruction(migraphx::make_op("identity"), add);
......
......@@ -17,7 +17,7 @@ TEST_CASE(standard_op)
migraphx::module m;
auto l = m.add_parameter("x", {migraphx::shape::float_type, {2, 2}});
auto t = m.add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), l);
auto t = m.add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l);
auto c = m.add_instruction(migraphx::make_op("contiguous"), t);
m.add_instruction(pass_standard_op{}, c);
auto count = std::distance(m.begin(), m.end());
......@@ -30,7 +30,7 @@ TEST_CASE(standard_op_const)
migraphx::module m;
auto l = m.add_literal(get_2x2());
auto t = m.add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), l);
auto t = m.add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l);
auto c = m.add_instruction(migraphx::make_op("contiguous"), t);
m.add_instruction(pass_standard_op{}, c);
run_pass(m);
......@@ -42,7 +42,7 @@ TEST_CASE(non_standard_op)
migraphx::module m;
auto l = m.add_parameter("x", {migraphx::shape::float_type, {2, 2}});
auto t = m.add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), l);
auto t = m.add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l);
auto c = m.add_instruction(migraphx::make_op("contiguous"), t);
m.add_instruction(pass_op{}, c);
auto count = std::distance(m.begin(), m.end());
......@@ -55,7 +55,7 @@ TEST_CASE(non_standard_op_const)
migraphx::module m;
auto l = m.add_literal(get_2x2());
auto t = m.add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), l);
auto t = m.add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l);
auto c = m.add_instruction(migraphx::make_op("contiguous"), t);
m.add_instruction(pass_op{}, c);
run_pass(m);
......@@ -67,7 +67,7 @@ TEST_CASE(transpose_gem)
migraphx::module m;
auto l = m.add_literal(get_2x2());
auto t = m.add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), l);
auto t = m.add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l);
auto c = m.add_instruction(migraphx::make_op("contiguous"), t);
auto ic = m.add_instruction(migraphx::make_op("identity"), c);
m.add_instruction(migraphx::make_op("dot"), ic, l);
......@@ -81,7 +81,7 @@ TEST_CASE(transpose_standard_op)
migraphx::module m;
auto l = m.add_parameter("x", {migraphx::shape::float_type, {2, 2}});
auto t = m.add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), l);
auto t = m.add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l);
auto c = m.add_instruction(migraphx::make_op("contiguous"), t);
auto sn = m.add_instruction(migraphx::make_op("sin"), c);
m.add_instruction(pass_standard_op{}, sn);
......@@ -95,7 +95,7 @@ TEST_CASE(transpose_standard_op_const)
migraphx::module m;
auto l = m.add_literal(get_2x2());
auto t = m.add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), l);
auto t = m.add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l);
auto c = m.add_instruction(migraphx::make_op("contiguous"), t);
auto sn = m.add_instruction(migraphx::make_op("sin"), c);
m.add_instruction(pass_standard_op{}, sn);
......@@ -123,7 +123,7 @@ TEST_CASE(non_standard_return_input)
migraphx::module m;
auto l = m.add_literal(get_2x2());
auto tl = m.add_instruction(migraphx::make_op("transpose", {{"dims", {1, 0}}}), l);
auto tl = m.add_instruction(migraphx::make_op("transpose", {{"permutation", {1, 0}}}), l);
auto c = m.add_instruction(migraphx::make_op("contiguous"), tl);
m.add_return({c});
auto count = std::distance(m.begin(), m.end());
......
......@@ -8,4 +8,34 @@ TEST_CASE(generate)
EXPECT(migraphx::generate_literal(s, 1) != migraphx::generate_argument(s, 0));
}
TEST_CASE(fill_tuple)
{
migraphx::shape s0{migraphx::shape::float_type, {4, 4, 1, 1}};
migraphx::shape s1{migraphx::shape::int32_type, {2, 3}};
migraphx::shape s2{migraphx::shape::bool_type, {3, 2}};
migraphx::shape s({s0, s1, s2});
auto arg = migraphx::fill_argument(s, 1);
const auto& args = arg.get_sub_objects();
EXPECT(args.at(0) == migraphx::fill_argument(s0, 1));
EXPECT(args.at(1) == migraphx::fill_argument(s1, 1));
EXPECT(args.at(2) == migraphx::fill_argument(s2, 1));
}
TEST_CASE(generate_tuple)
{
migraphx::shape s0{migraphx::shape::float_type, {4, 4, 1, 1}};
migraphx::shape s1{migraphx::shape::int32_type, {2, 3}};
migraphx::shape s2{migraphx::shape::bool_type, {3, 2}};
migraphx::shape s({s0, s1, s2});
auto arg = migraphx::generate_argument(s, 1);
const auto& args = arg.get_sub_objects();
EXPECT(args.at(0) == migraphx::generate_argument(s0, 1));
EXPECT(args.at(1) == migraphx::generate_argument(s1, 1));
EXPECT(args.at(2) == migraphx::generate_argument(s2, 1));
EXPECT(args.at(0) != migraphx::generate_argument(s0, 0));
EXPECT(args.at(1) != migraphx::generate_argument(s1, 2));
EXPECT(args.at(2) != migraphx::generate_argument(s2, 0));
}
int main(int argc, const char* argv[]) { test::run(argc, argv); }
......@@ -13,15 +13,16 @@
#include <migraphx/op/tanh.hpp>
#include <migraphx/op/transpose.hpp>
#include <migraphx/pass_manager.hpp>
#include <migraphx/make_op.hpp>
#include <basic_ops.hpp>
#include <test.hpp>
void run_lowering(migraphx::program& p)
void run_lowering(migraphx::program& p, bool offload_copy = false)
{
auto ctx = migraphx::gpu::context{};
migraphx::run_passes(*p.get_main_module(),
{migraphx::auto_contiguous{},
migraphx::gpu::lowering{&ctx, false},
migraphx::gpu::lowering{&ctx, offload_copy},
migraphx::dead_code_elimination{},
migraphx::eliminate_contiguous{"gpu::contiguous"},
migraphx::dead_code_elimination{}});
......@@ -67,4 +68,41 @@ TEST_CASE(tanh_shape)
EXPECT(p1 == p2);
}
TEST_CASE(no_copy_dead_param)
{
auto create_program = [] {
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape s{migraphx::shape::float_type, {2, 3}};
auto x = mm->add_parameter("x", s);
mm->add_parameter("y", s);
auto sum = mm->add_instruction(migraphx::make_op("add"), x, x);
mm->add_return({sum});
return p;
};
auto create_gpu_program = [] {
migraphx::program p;
auto* mm = p.get_main_module();
migraphx::shape s{migraphx::shape::float_type, {2, 3}};
auto x = mm->add_parameter("x", s);
mm->add_parameter("y", s);
auto xb = mm->add_instruction(migraphx::make_op("hip::allocate", {{"shape", to_value(s)}}));
auto gx = mm->add_instruction(migraphx::make_op("hip::copy_to_gpu"), x, xb);
auto ab = mm->add_instruction(migraphx::make_op("hip::allocate", {{"shape", to_value(s)}}));
auto sum = mm->add_instruction(migraphx::make_op("gpu::add"), gx, gx, ab);
auto r = mm->add_instruction(migraphx::make_op("hip::copy_from_gpu"), sum);
mm->add_return({r});
return p;
};
auto p1 = create_program();
auto p2 = create_gpu_program();
run_lowering(p1, true);
EXPECT(p1 == p2);
}
int main(int argc, const char* argv[]) { test::run(argc, argv); }
......@@ -6,9 +6,11 @@
#include <migraphx/gpu/kernel.hpp>
#include <migraphx/gpu/target.hpp>
#include <migraphx/gpu/hip.hpp>
#include <migraphx/gpu/context.hpp>
#include <migraphx/gpu/device_name.hpp>
#include <migraphx/gpu/compile_hip.hpp>
#include <migraphx/gpu/compile_hip_code_object.hpp>
#include <migraphx/gpu/compile_pointwise.hpp>
// NOLINTNEXTLINE
const std::string write_2s = R"__migraphx__(
......@@ -54,7 +56,7 @@ using namespace migraphx;
extern "C" {
__global__ void kernel(void* x, void* y)
{
make_tensors(x, y)([](auto xt, auto yt) __device__ {
make_tensors()(x, y)([](auto xt, auto yt) __device__ {
auto idx = make_index();
const auto stride = idx.nglobal();
for(index_int i = idx.global; i < xt.get_shape().elements(); i += stride)
......@@ -70,6 +72,43 @@ int main() {}
)__migraphx__";
// NOLINTNEXTLINE
const std::string check_define = R"__migraphx__(
#ifndef __DEFINE__
#error __DEFINE__ was not defined
#endif
int main() {}
)__migraphx__";
// NOLINTNEXTLINE
const std::string unused_param = R"__migraphx__(
extern "C" {
__global__ void kernel(void* x, void* y)
{}
}
int main() {}
)__migraphx__";
// NOLINTNEXTLINE
const std::string incorrect_program = R"__migraphx__(
extern "C" {
__global__ void kernel(void* x)
{
x += y;
}
}
int main() {}
)__migraphx__";
migraphx::src_file make_src_file(const std::string& name, const std::string& content)
{
return {name, std::make_pair(content.data(), content.data() + content.size())};
......@@ -92,6 +131,41 @@ TEST_CASE(simple_compile_hip)
EXPECT(migraphx::all_of(data, [](auto x) { return x == 2; }));
}
auto check_target(const std::string& arch)
{
auto define = "__" + arch + "__";
auto content = migraphx::replace_string(check_define, "__DEFINE__", define);
return migraphx::gpu::compile_hip_src({make_src_file("main.cpp", content)}, "", arch);
}
TEST_CASE(compile_target)
{
EXPECT(not check_target("gfx900").empty());
EXPECT(not check_target("gfx906").empty());
}
TEST_CASE(compile_errors)
{
EXPECT(test::throws([&] {
migraphx::gpu::compile_hip_src(
{make_src_file("main.cpp", incorrect_program)}, "", migraphx::gpu::get_device_name());
}));
}
TEST_CASE(compile_warnings)
{
auto compile = [](const std::string& params) {
return migraphx::gpu::compile_hip_src(
{make_src_file("main.cpp", unused_param)}, params, migraphx::gpu::get_device_name());
};
EXPECT(not compile("").empty());
EXPECT(not compile("-Wunused-parameter -Wno-error").empty());
EXPECT(not compile("-Wno-unused-parameter -Werror").empty());
EXPECT(test::throws([&] { compile("-Werror=unused-parameter"); }));
EXPECT(test::throws([&] { compile("-Wunused-parameter -Werror"); }));
}
TEST_CASE(code_object_hip)
{
auto binaries = migraphx::gpu::compile_hip_src(
......@@ -151,4 +225,26 @@ TEST_CASE(compile_code_object_hip)
EXPECT(result == output_literal.get_argument());
}
TEST_CASE(compile_pointwise)
{
migraphx::shape input{migraphx::shape::float_type, {5, 2}};
migraphx::gpu::context ctx;
auto co = migraphx::gpu::compile_pointwise(ctx, {input, input}, "[](auto x) { return x + 1; }");
migraphx::program p;
auto* mm = p.get_main_module();
auto input_literal = migraphx::generate_literal(input);
auto output_literal = migraphx::transform(input_literal, [](auto x) { return x + 1; });
auto x = mm->add_literal(input_literal);
auto y = mm->add_parameter("output", input);
mm->add_instruction(co, x, y);
p.compile(migraphx::gpu::target{}, migraphx::compile_options{});
auto result =
migraphx::gpu::from_gpu(p.eval({{"output", migraphx::gpu::allocate_gpu(input)}}).front());
EXPECT(result == output_literal.get_argument());
}
int main(int argc, const char* argv[]) { test::run(argc, argv); }
......@@ -100,11 +100,13 @@ TEST_CASE(quant_dot_trans)
migraphx::shape s1{migraphx::shape::int8_type, {3, 2, 8, 5}};
migraphx::shape s2{migraphx::shape::int8_type, {3, 2, 7, 8}};
auto l1 = m.add_parameter("a", s1);
auto tl1 = m.add_instruction(migraphx::make_op("transpose", {{"dims", {0, 1, 3, 2}}}), l1);
auto l2 = m.add_parameter("b", s2);
auto tl2 = m.add_instruction(migraphx::make_op("transpose", {{"dims", {0, 1, 3, 2}}}), l2);
auto r = m.add_instruction(
auto l1 = m.add_parameter("a", s1);
auto tl1 =
m.add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 1, 3, 2}}}), l1);
auto l2 = m.add_parameter("b", s2);
auto tl2 =
m.add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 1, 3, 2}}}), l2);
auto r = m.add_instruction(
migraphx::make_op("quant_dot", {{"alpha", 3}, {"beta", 2}}), tl1, tl2);
m.add_return({r});
return m;
......@@ -120,13 +122,15 @@ TEST_CASE(quant_dot_trans)
auto l2 = m.add_parameter("b", s2);
auto output = m.add_parameter("test:#output_0", s3);
auto tl1 = m.add_instruction(migraphx::make_op("transpose", {{"dims", {0, 1, 3, 2}}}), l1);
auto tl1 =
m.add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 1, 3, 2}}}), l1);
migraphx::shape ts1{migraphx::shape::int8_type, {3, 2, 5, 8}};
auto alloca = m.add_instruction(
migraphx::make_op("hip::allocate", {{"shape", migraphx::to_value(ts1)}}));
auto conta = m.add_instruction(migraphx::make_op("gpu::contiguous"), tl1, alloca);
auto tl2 = m.add_instruction(migraphx::make_op("transpose", {{"dims", {0, 1, 3, 2}}}), l2);
auto tl2 =
m.add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 1, 3, 2}}}), l2);
migraphx::shape ts2{migraphx::shape::int8_type, {3, 2, 8, 7}};
auto allocb = m.add_instruction(
migraphx::make_op("hip::allocate", {{"shape", migraphx::to_value(ts2)}}));
......@@ -245,11 +249,13 @@ TEST_CASE(quant_dot_trans_pad)
migraphx::shape s1{migraphx::shape::int8_type, {3, 2, 9, 5}};
migraphx::shape s2{migraphx::shape::int8_type, {3, 2, 7, 9}};
auto l1 = m.add_parameter("a", s1);
auto tl1 = m.add_instruction(migraphx::make_op("transpose", {{"dims", {0, 1, 3, 2}}}), l1);
auto l2 = m.add_parameter("b", s2);
auto tl2 = m.add_instruction(migraphx::make_op("transpose", {{"dims", {0, 1, 3, 2}}}), l2);
auto r = m.add_instruction(
auto l1 = m.add_parameter("a", s1);
auto tl1 =
m.add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 1, 3, 2}}}), l1);
auto l2 = m.add_parameter("b", s2);
auto tl2 =
m.add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 1, 3, 2}}}), l2);
auto r = m.add_instruction(
migraphx::make_op("quant_dot", {{"alpha", 3}, {"beta", 2}}), tl1, tl2);
m.add_return({r});
return m;
......@@ -267,7 +273,8 @@ TEST_CASE(quant_dot_trans_pad)
auto l2 = m.add_parameter("b", s2);
auto output = m.add_parameter("test:#output_0", s3);
auto tl1 = m.add_instruction(migraphx::make_op("transpose", {{"dims", {0, 1, 3, 2}}}), l1);
auto tl1 =
m.add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 1, 3, 2}}}), l1);
migraphx::shape ts1{migraphx::shape::int8_type, {3, 2, 5, 9}};
auto ta = m.add_instruction(
migraphx::make_op("hip::allocate", {{"shape", migraphx::to_value(ts1)}}));
......@@ -287,7 +294,8 @@ TEST_CASE(quant_dot_trans_pad)
pta);
}
auto tl2 = m.add_instruction(migraphx::make_op("transpose", {{"dims", {0, 1, 3, 2}}}), l2);
auto tl2 =
m.add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 1, 3, 2}}}), l2);
migraphx::shape ts2{migraphx::shape::int8_type, {3, 2, 9, 7}};
auto tb = m.add_instruction(
migraphx::make_op("hip::allocate", {{"shape", migraphx::to_value(ts2)}}));
......
......@@ -68,8 +68,7 @@ TEST_CASE(int8_quantization)
migraphx::shape sc{migraphx::shape::float_type, {5, 8}};
auto pa = mm->add_parameter("a", sa);
auto pb = mm->add_parameter("b", sb);
auto pc = mm->add_parameter("c", sc);
mm->add_instruction(migraphx::op::dot{}, pa, pb, pc);
mm->add_instruction(migraphx::op::dot{}, pa, pb);
return p;
};
......@@ -82,7 +81,6 @@ TEST_CASE(int8_quantization)
migraphx::shape sc{migraphx::shape::float_type, {5, 8}};
m["a"] = migraphx::generate_argument(sa);
m["b"] = migraphx::generate_argument(sb);
m["c"] = migraphx::generate_argument(sc);
std::vector<float> ref_result;
migraphx::target ref_t = migraphx::ref::target{};
run_prog(p, ref_t, m, ref_result);
......
......@@ -175,6 +175,7 @@ TEST_CASE(inline_else_test)
auto l2 = mm->add_literal(s, rand);
mm->add_parameter("x", s);
auto y = mm->add_parameter("y", s);
mm->add_parameter("e", s);
auto r = mm->add_instruction(migraphx::make_op("mul"), y, l2);
mm->add_return({r});
......@@ -364,19 +365,19 @@ TEST_CASE(inline_tuple_true_test)
auto* then_mod = p.create_module("If_6_if");
auto m1 = then_mod->add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", {1, 4}}}), l1);
migraphx::make_op("multibroadcast", {{"out_lens", {1, 4}}}), l1);
auto add0 = then_mod->add_instruction(migraphx::make_op("add"), x, m1);
auto m2 = then_mod->add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", {3, 4}}}), l2);
migraphx::make_op("multibroadcast", {{"out_lens", {3, 4}}}), l2);
auto mul0 = then_mod->add_instruction(migraphx::make_op("mul"), y, m2);
then_mod->add_return({add0, mul0});
auto* else_mod = p.create_module("If_6_else");
auto me1 = else_mod->add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", {1, 4}}}), l3);
migraphx::make_op("multibroadcast", {{"out_lens", {1, 4}}}), l3);
auto mul1 = else_mod->add_instruction(migraphx::make_op("mul"), x, me1);
auto me2 = else_mod->add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", {3, 4}}}), l3);
migraphx::make_op("multibroadcast", {{"out_lens", {3, 4}}}), l3);
auto add1 = else_mod->add_instruction(migraphx::make_op("add"), y, me2);
else_mod->add_return({mul1, add1});
......@@ -401,10 +402,10 @@ TEST_CASE(inline_tuple_true_test)
auto y = mm->add_parameter("y", sy);
auto m1 =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {1, 4}}}), l1);
mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {1, 4}}}), l1);
auto add = mm->add_instruction(migraphx::make_op("add"), x, m1);
auto m2 =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {3, 4}}}), l2);
mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 4}}}), l2);
auto mul = mm->add_instruction(migraphx::make_op("mul"), y, m2);
mm->add_return({add, mul});
......@@ -434,19 +435,19 @@ TEST_CASE(inline_tuple_false_test)
auto* then_mod = p.create_module("If_6_if");
auto m1 = then_mod->add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", {1, 4}}}), l1);
migraphx::make_op("multibroadcast", {{"out_lens", {1, 4}}}), l1);
auto add0 = then_mod->add_instruction(migraphx::make_op("add"), x, m1);
auto m2 = then_mod->add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", {3, 4}}}), l2);
migraphx::make_op("multibroadcast", {{"out_lens", {3, 4}}}), l2);
auto mul0 = then_mod->add_instruction(migraphx::make_op("mul"), y, m2);
then_mod->add_return({add0, mul0});
auto* else_mod = p.create_module("If_6_else");
auto me1 = else_mod->add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", {1, 4}}}), l3);
migraphx::make_op("multibroadcast", {{"out_lens", {1, 4}}}), l3);
auto mul1 = else_mod->add_instruction(migraphx::make_op("mul"), x, me1);
auto me2 = else_mod->add_instruction(
migraphx::make_op("multibroadcast", {{"output_lens", {3, 4}}}), l3);
migraphx::make_op("multibroadcast", {{"out_lens", {3, 4}}}), l3);
auto add1 = else_mod->add_instruction(migraphx::make_op("add"), y, me2);
else_mod->add_return({mul1, add1});
......@@ -473,10 +474,10 @@ TEST_CASE(inline_tuple_false_test)
auto y = mm->add_parameter("y", sy);
auto m1 =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {1, 4}}}), l3);
mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {1, 4}}}), l3);
auto mul = mm->add_instruction(migraphx::make_op("mul"), x, m1);
auto m2 =
mm->add_instruction(migraphx::make_op("multibroadcast", {{"output_lens", {3, 4}}}), l3);
mm->add_instruction(migraphx::make_op("multibroadcast", {{"out_lens", {3, 4}}}), l3);
auto add = mm->add_instruction(migraphx::make_op("add"), y, m2);
mm->add_return({mul, add});
......
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