Unverified Commit 500d9441 authored by Paul Fultz II's avatar Paul Fultz II Committed by GitHub
Browse files

Split cpu and reference implementation (#671)



* Add all_targets cmake target

* Rename target

* Add ref target

* Rename tests

* Refactor compiler target

* Formatting

* Verify for every target

* Formatting

* Add verify test suite

* Formatting

* Add initial test programs

* Formatting

* Add rnn tests

* Formatting

* Validate gpu

* Formatting

* Remove old gpu tests

* Fix gpu tests

* Fix ref error

* Fix tidy issues

* Formatting

* Tidy fixes

* Fix header in python api

* Rename to ref

* Use ref in verify_onnx

* Fix tidy issue

* Build with verbose on

* Fix typo

* Remove verbose

* rename some cpu prefix to ref
Co-authored-by: default avatarShucai Xiao <Shucai.Xiao@amd.com>
parent ba33d25c
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
struct quant_dot_3args_3 : verify_program<quant_dot_3args_3>
{
migraphx::program create_program() const
{
migraphx::program p;
migraphx::shape m1_shape{migraphx::shape::int8_type, {2, 8}};
migraphx::shape m2_shape{migraphx::shape::int8_type, {7, 8}};
migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 7}};
auto l1 = p.add_parameter("a", m1_shape);
auto l2 = p.add_parameter("b", m2_shape);
auto tl2 = p.add_instruction(migraphx::op::transpose{{1, 0}}, l2);
auto l3 = p.add_parameter("c", m3_shape);
p.add_instruction(migraphx::op::quant_dot{2, 3}, l1, tl2, l3);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
struct quant_dot_3args_4 : verify_program<quant_dot_3args_4>
{
migraphx::program create_program() const
{
migraphx::program p;
migraphx::shape m1_shape{migraphx::shape::int8_type, {8, 2}};
migraphx::shape m2_shape{migraphx::shape::int8_type, {7, 8}};
migraphx::shape m3_shape{migraphx::shape::int32_type, {2, 7}};
auto l1 = p.add_parameter("a", m1_shape);
auto tl1 = p.add_instruction(migraphx::op::transpose{{1, 0}}, l1);
auto l2 = p.add_parameter("b", m2_shape);
auto tl2 = p.add_instruction(migraphx::op::transpose{{1, 0}}, l2);
auto l3 = p.add_parameter("c", m3_shape);
p.add_instruction(migraphx::op::quant_dot{3, 2}, tl1, tl2, l3);
return p;
}
};
#include "run_verify.hpp"
#include "auto_print.hpp"
#include "verify_program.hpp"
#include <migraphx/env.hpp>
#include <migraphx/ref/target.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/verify_args.hpp>
#include <set>
#include <future>
#include <thread>
#include <utility>
MIGRAPHX_DECLARE_ENV_VAR(MIGRAPHX_TRACE_TEST_COMPILE)
// An improved async, that doesn't block
template <class Function>
std::future<typename std::result_of<Function()>::type> detach_async(Function&& f,
bool parallel = true)
{
if(parallel)
{
using result_type = typename std::result_of<Function()>::type;
std::packaged_task<result_type()> task(std::forward<Function>(f));
auto fut = task.get_future();
std::thread(std::move(task)).detach();
return std::move(fut);
}
return std::async(std::launch::deferred, std::forward<Function>(f));
}
inline void compile_check(migraphx::program& p, const migraphx::target& t, bool show_trace = false)
{
auto name = t.name();
auto shapes = p.get_output_shapes();
std::stringstream ss;
migraphx::compile_options options;
options.trace = migraphx::tracer{ss};
p.compile(t, options);
if(shapes.size() != p.get_output_shapes().size())
{
std::cout << ss.str() << std::endl;
throw std::runtime_error("Compiling program with " + name +
" alters its number of outputs");
}
auto num = shapes.size();
for(std::size_t i = 0; i < num; ++i)
{
if(p.get_output_shapes()[i].lens() != shapes[i].lens())
{
std::cout << ss.str() << std::endl;
throw std::runtime_error("Compiling program with " + name + " alters its shape");
}
}
if(show_trace)
{
std::cout << ss.str() << std::endl;
}
}
target_info run_verify::get_target_info(const std::string& name) const
{
auto it = info.find(name);
if(it != info.end())
return it->second;
else
return {};
}
void run_verify::validate(const migraphx::target& t,
const migraphx::program& p,
const migraphx::program::parameter_map& m) const
{
auto ti = get_target_info(t.name());
if(ti.validate)
ti.validate(p, m);
}
std::vector<migraphx::argument> run_verify::run_ref(migraphx::program p,
migraphx::program::parameter_map inputs) const
{
migraphx::ref::target t{};
auto_print pp{p, t.name()};
compile_check(p, t);
return p.eval(std::move(inputs));
}
std::pair<migraphx::program, std::vector<migraphx::argument>>
run_verify::run_target(const migraphx::target& t,
migraphx::program p,
const migraphx::program::parameter_map& inputs) const
{
auto_print pp{p, t.name()};
auto trace_target = migraphx::string_value_of(MIGRAPHX_TRACE_TEST_COMPILE{});
compile_check(p, t, (trace_target == t.name()));
migraphx::program::parameter_map m;
for(auto&& input : inputs)
{
m[input.first] = t.copy_to(input.second);
}
for(auto&& x : p.get_parameter_shapes())
{
if(m.count(x.first) == 0)
m[x.first] = t.allocate(x.second);
}
validate(t, p, m);
p.eval(m);
auto tres = p.eval(m);
std::vector<migraphx::argument> res(tres.size());
std::transform(
tres.begin(), tres.end(), res.begin(), [&](auto& argu) { return t.copy_from(argu); });
return std::make_pair(p, res);
}
template <class T>
auto get_hash(const T& x)
{
return std::hash<T>{}(x);
}
void run_verify::verify(const std::string& name, const migraphx::program& p) const
{
using result_future =
std::future<std::pair<migraphx::program, std::vector<migraphx::argument>>>;
std::cout << "[ RUN ] " << name << std::endl;
auto_print::set_terminate_handler(name);
std::vector<std::pair<std::string, result_future>> results;
std::vector<std::string> target_names;
for(const auto& tname : migraphx::get_targets())
{
if(tname == "ref")
continue;
target_names.push_back(tname);
}
if(not target_names.empty())
{
migraphx::program::parameter_map m;
for(auto&& x : p.get_parameter_shapes())
{
m[x.first] = migraphx::generate_argument(x.second, get_hash(x.first));
}
auto gold_f = detach_async([=] { return run_ref(p, m); });
for(const auto& tname : target_names)
{
target_info ti = get_target_info(tname);
auto t = migraphx::make_target(tname);
results.emplace_back(tname,
detach_async([=] { return run_target(t, p, m); }, ti.parallel));
}
auto gold = gold_f.get();
for(auto&& pp : results)
{
auto tname = pp.first;
auto x = pp.second.get();
auto cp = x.first;
auto result = x.second;
bool passed = true;
passed &= (gold.size() == result.size());
std::size_t num = gold.size();
for(std::size_t i = 0; ((i < num) and passed); ++i)
{
passed &= migraphx::verify_args(tname, gold[i], result[i]);
}
if(not passed)
{
std::cout << p << std::endl;
std::cout << "ref:\n" << p << std::endl;
std::cout << tname << ":\n" << cp << std::endl;
std::cout << std::endl;
}
}
}
std::set_terminate(nullptr);
std::cout << "[ COMPLETE ] " << name << std::endl;
}
void run_verify::run(int argc, const char* argv[]) const
{
std::set<std::string> args(argv + 1, argv + argc);
const auto& ps = get_programs();
for(auto&& p : ps)
{
if(not args.empty())
{
if(args.count(p.name) == 0 and args.count(p.section) == 0)
continue;
}
verify(p.name, p.get_program());
}
}
void run_verify::disable_parallel_for(const std::string& name) { info[name].parallel = false; }
void run_verify::add_validation_for(const std::string& name, target_info::validation_function v)
{
info[name].validate = std::move(v);
}
#ifndef MIGRAPHX_GUARD_TEST_RUN_VERIFY_HPP
#define MIGRAPHX_GUARD_TEST_RUN_VERIFY_HPP
#include <migraphx/program.hpp>
#include <functional>
#include <map>
struct target_info
{
using validation_function =
std::function<void(const migraphx::program& p, const migraphx::program::parameter_map& m)>;
bool parallel = true;
validation_function validate;
};
struct run_verify
{
std::vector<migraphx::argument> run_ref(migraphx::program p,
migraphx::program::parameter_map inputs) const;
std::pair<migraphx::program, std::vector<migraphx::argument>>
run_target(const migraphx::target& t,
migraphx::program p,
const migraphx::program::parameter_map& inputs) const;
void validate(const migraphx::target& t,
const migraphx::program& p,
const migraphx::program::parameter_map& m) const;
void verify(const std::string& name, const migraphx::program& p) const;
void run(int argc, const char* argv[]) const;
target_info get_target_info(const std::string& name) const;
void disable_parallel_for(const std::string& name);
void add_validation_for(const std::string& name, target_info::validation_function v);
private:
std::map<std::string, target_info> info{};
};
#endif
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
struct test_abs : verify_program<test_abs>
{
migraphx::program create_program() const
{
migraphx::program p;
auto x = p.add_parameter("x", migraphx::shape{migraphx::shape::float_type, {4, 3, 3, 3}});
p.add_instruction(migraphx::op::abs{}, x);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
struct test_acos : verify_program<test_acos>
{
migraphx::program create_program() const
{
migraphx::program p;
migraphx::shape s{migraphx::shape::double_type, {16}};
auto x = p.add_parameter("x", s);
p.add_instruction(migraphx::op::acos{}, x);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
struct test_acosh : verify_program<test_acosh>
{
migraphx::program create_program() const
{
migraphx::program p;
migraphx::shape s{migraphx::shape::float_type, {16}};
auto x = p.add_parameter("x", s);
auto min_val = p.add_literal(1.1f);
auto max_val = p.add_literal(100.0f);
min_val = p.add_instruction(migraphx::op::multibroadcast{{16}}, min_val);
max_val = p.add_instruction(migraphx::op::multibroadcast{{16}}, max_val);
auto cx = p.add_instruction(migraphx::op::clip{}, x, min_val, max_val);
p.add_instruction(migraphx::op::acosh{}, cx);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
struct test_add : verify_program<test_add>
{
migraphx::program create_program() const
{
migraphx::program p;
migraphx::shape s{migraphx::shape::float_type, {3}};
auto x = p.add_parameter("x", s);
auto y = p.add_parameter("y", s);
p.add_instruction(migraphx::op::add{}, x, y);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
#include <migraphx/instruction.hpp>
struct test_add_broadcast : verify_program<test_add_broadcast>
{
migraphx::program create_program() const
{
migraphx::program p;
migraphx::shape s{migraphx::shape::float_type, {3}};
auto x = p.add_parameter("x", {migraphx::shape::float_type, {2, 2, 3}});
auto y = p.add_parameter("y", {migraphx::shape::float_type, {2, 2}});
auto by = p.add_instruction(migraphx::op::broadcast{0, x->get_shape().lens()}, y);
p.add_instruction(migraphx::op::add{}, x, by);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
#include <migraphx/instruction.hpp>
struct test_add_broadcast2 : verify_program<test_add_broadcast2>
{
migraphx::program create_program() const
{
migraphx::program p;
migraphx::shape s{migraphx::shape::float_type, {3}};
auto x = p.add_parameter("x", {migraphx::shape::float_type, {2, 3, 4}});
auto y = p.add_parameter("y", {migraphx::shape::float_type, {3}});
auto by = p.add_instruction(migraphx::op::broadcast{1, x->get_shape().lens()}, y);
p.add_instruction(migraphx::op::add{}, x, by);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
#include <migraphx/instruction.hpp>
struct test_add_broadcast3 : verify_program<test_add_broadcast3>
{
migraphx::program create_program() const
{
migraphx::program p;
migraphx::shape s{migraphx::shape::float_type, {3}};
auto x = p.add_parameter("x", {migraphx::shape::float_type, {2, 4, 5}});
auto y = p.add_parameter("y", {migraphx::shape::float_type, {4}});
auto by = p.add_instruction(migraphx::op::broadcast{1, x->get_shape().lens()}, y);
p.add_instruction(migraphx::op::add{}, x, by);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
#include <migraphx/instruction.hpp>
struct test_add_broadcast4 : verify_program<test_add_broadcast4>
{
migraphx::program create_program() const
{
migraphx::program p;
migraphx::shape s{migraphx::shape::float_type, {3}};
auto x = p.add_parameter("x", {migraphx::shape::float_type, {2, 3, 5}});
auto y = p.add_parameter("y", {migraphx::shape::float_type, {3}});
auto by = p.add_instruction(migraphx::op::broadcast{1, x->get_shape().lens()}, y);
p.add_instruction(migraphx::op::add{}, x, by);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
#include <migraphx/instruction.hpp>
struct test_add_broadcast5 : verify_program<test_add_broadcast5>
{
migraphx::program create_program() const
{
migraphx::program p;
migraphx::shape s{migraphx::shape::float_type, {3}};
auto x = p.add_parameter("x", {migraphx::shape::float_type, {2, 4, 8}});
auto y = p.add_parameter("y", {migraphx::shape::float_type, {4}});
auto by = p.add_instruction(migraphx::op::broadcast{1, x->get_shape().lens()}, y);
p.add_instruction(migraphx::op::add{}, x, by);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
struct test_add_gelu : verify_program<test_add_gelu>
{
migraphx::program create_program() const
{
migraphx::program p;
std::vector<size_t> input_lens{1, 1, 5};
auto x = p.add_parameter("x", {migraphx::shape::float_type, input_lens});
auto y = p.add_parameter("y", {migraphx::shape::float_type, input_lens});
auto half = p.add_literal(0.5f);
auto one = p.add_literal(1.0f);
auto sqrt2 = p.add_literal(static_cast<float>(M_SQRT2));
auto add = p.add_instruction(migraphx::op::add{}, x, y);
auto half_mbcast = p.add_instruction(migraphx::op::multibroadcast{input_lens}, half);
auto mul_half = p.add_instruction(migraphx::op::mul{}, add, half_mbcast);
auto sqrt2_mbcast = p.add_instruction(migraphx::op::multibroadcast{input_lens}, sqrt2);
auto div = p.add_instruction(migraphx::op::div{}, add, sqrt2_mbcast);
auto erf = p.add_instruction(migraphx::op::erf{}, div);
auto one_mbcast = p.add_instruction(migraphx::op::multibroadcast{input_lens}, one);
auto add_one = p.add_instruction(migraphx::op::add{}, erf, one_mbcast);
p.add_instruction(migraphx::op::mul{}, mul_half, add_one);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
struct test_add_half : verify_program<test_add_half>
{
migraphx::program create_program() const
{
migraphx::program p;
migraphx::shape s{migraphx::shape::half_type, {3}};
auto x = p.add_parameter("x", s);
auto y = p.add_parameter("y", s);
p.add_instruction(migraphx::op::add{}, x, y);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
struct test_add_relu : verify_program<test_add_relu>
{
migraphx::program create_program() const
{
migraphx::program p;
auto x = p.add_parameter("x", migraphx::shape{migraphx::shape::float_type, {4, 3, 3, 3}});
auto y = p.add_parameter("y", migraphx::shape{migraphx::shape::float_type, {4, 3, 3, 3}});
auto add = p.add_instruction(migraphx::op::add{}, x, y);
p.add_instruction(migraphx::op::relu{}, add);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
struct test_add_sigmoid : verify_program<test_add_sigmoid>
{
migraphx::program create_program() const
{
migraphx::program p;
auto x = p.add_parameter("x", migraphx::shape{migraphx::shape::float_type, {4, 3, 3, 3}});
auto y = p.add_parameter("y", migraphx::shape{migraphx::shape::float_type, {4, 3, 3, 3}});
auto add = p.add_instruction(migraphx::op::add{}, x, y);
p.add_instruction(migraphx::op::sigmoid{}, add);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
struct test_add_tanh : verify_program<test_add_tanh>
{
migraphx::program create_program() const
{
migraphx::program p;
auto x = p.add_parameter("x", migraphx::shape{migraphx::shape::float_type, {4, 3, 3, 3}});
auto y = p.add_parameter("y", migraphx::shape{migraphx::shape::float_type, {4, 3, 3, 3}});
auto add = p.add_instruction(migraphx::op::add{}, x, y);
p.add_instruction(migraphx::op::tanh{}, add);
return p;
}
};
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
template <class T, int Axis>
struct test_arg_ops : verify_program<test_arg_ops<T, Axis>>
{
migraphx::program create_program() const
{
migraphx::program p;
migraphx::shape s{migraphx::shape::float_type, {2, 3, 4, 1025}};
auto param = p.add_parameter("data", s);
p.add_instruction(T{Axis}, param);
return p;
}
};
template struct test_arg_ops<migraphx::op::argmax, 0>;
template struct test_arg_ops<migraphx::op::argmax, 1>;
template struct test_arg_ops<migraphx::op::argmax, 2>;
template struct test_arg_ops<migraphx::op::argmax, 3>;
template struct test_arg_ops<migraphx::op::argmax, -1>;
template struct test_arg_ops<migraphx::op::argmax, -2>;
template struct test_arg_ops<migraphx::op::argmin, 0>;
template struct test_arg_ops<migraphx::op::argmin, 1>;
template struct test_arg_ops<migraphx::op::argmin, 2>;
template struct test_arg_ops<migraphx::op::argmin, 3>;
template struct test_arg_ops<migraphx::op::argmin, -3>;
template struct test_arg_ops<migraphx::op::argmin, -4>;
#include "verify_program.hpp"
#include <migraphx/program.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/operators.hpp>
struct test_asin : verify_program<test_asin>
{
migraphx::program create_program() const
{
migraphx::program p;
migraphx::shape s{migraphx::shape::double_type, {16}};
auto x = p.add_parameter("x", s);
p.add_instruction(migraphx::op::asin{}, x);
return p;
}
};
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