Commit 37236428 authored by Paul's avatar Paul
Browse files

Add verify command

parent de62b8ac
google/protobuf@v3.8.0 -DCMAKE_POSITION_INDEPENDENT_CODE=On -X subdir -Dprotobuf_BUILD_TESTS=Off
# google/protobuf -DCMAKE_POSITION_INDEPENDENT_CODE=On
RadeonOpenCompute/rocm-cmake@42f6740 --build
ROCmSoftwarePlatform/rocBLAS@30a992ae02fda568688bcd190edd5e277d6674d9
ROCmSoftwarePlatform/MIOpen@1.7.0
......
add_executable(driver main.cpp)
add_executable(driver main.cpp verify.cpp)
target_link_libraries(driver migraphx_cpu migraphx_onnx migraphx_tf)
if(MIGRAPHX_ENABLE_GPU)
target_link_libraries(driver migraphx_gpu)
target_compile_definitions(driver PRIVATE -DHAVE_GPU)
endif()
......@@ -192,7 +192,7 @@ struct argument_parser
auto flags = arg.flags;
if(flags.empty())
flags = {""};
for(auto&& flag : arg.flags)
for(auto&& flag : flags)
{
if(arg_map.count(flag) > 0)
{
......
#include "argument_parser.hpp"
#include "command.hpp"
#include "verify.hpp"
#include <migraphx/tf.hpp>
#include <migraphx/onnx.hpp>
......@@ -14,6 +15,7 @@ struct loader
std::string file;
std::string type;
bool is_nhwc = false;
unsigned trim = 0;
void parse(argument_parser& ap)
{
......@@ -23,6 +25,7 @@ struct loader
ap.add(is_nhwc, {"--nhwc"}, ap.help("Treat tensorflow format as nhwc"), ap.set_value(true));
ap.add(
is_nhwc, {"--nchw"}, ap.help("Treat tensorflow format as nchw"), ap.set_value(false));
ap.add(trim, {"--trim", "-t"}, ap.help("Trim instructions from the end"));
}
program load()
......@@ -35,10 +38,16 @@ struct loader
else
type = "tf";
}
std::cout << "Reading: " << file << std::endl;
if(type == "onnx")
p = parse_onnx(file);
else if(type == "tf")
p = parse_tf(file, is_nhwc);
if (trim > 0)
{
auto last = std::prev(p.end(), trim);
p.remove_instructions(last, p.end());
}
return p;
}
};
......@@ -55,6 +64,40 @@ struct read : command<read>
}
};
struct verify : command<verify>
{
loader l;
double tolerance = 80;
bool per_instruction = false;
bool reduce = false;
void parse(argument_parser& ap)
{
l.parse(ap);
ap.add(tolerance, {"--tolerance"}, ap.help("Tolerance for errors"));
ap.add(per_instruction, {"-i", "--per-instruction"}, ap.help("Verify each instruction"), ap.set_value(true));
ap.add(reduce, {"-r", "--reduce"}, ap.help("Reduce program and verify"), ap.set_value(true));
}
void run()
{
auto p = l.load();
std::cout << p << std::endl;
if(per_instruction)
{
verify_instructions(p, tolerance);
}
else if(reduce)
{
verify_reduced_program(p, tolerance);
}
else
{
verify_program(l.file, p, tolerance);
}
}
};
struct main_command
{
static std::string get_command_help()
......
#include "verify.hpp"
#include <migraphx/cpu/target.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/verify_args.hpp>
#include <migraphx/instruction.hpp>
#ifdef HAVE_GPU
#include <migraphx/gpu/target.hpp>
#include <migraphx/gpu/hip.hpp>
#endif
namespace migraphx {
namespace driver {
inline namespace MIGRAPHX_INLINE_NS {
template <class T>
auto get_hash(const T& x)
{
return std::hash<T>{}(x);
}
argument run_cpu(program p)
{
p.compile(cpu::target{});
program::parameter_map m;
for(auto&& x : p.get_parameter_shapes())
{
m[x.first] = generate_argument(x.second, get_hash(x.first));
}
auto out = p.eval(m);
std::cout << p << std::endl;
return out;
}
argument run_gpu(program p)
{
#ifdef HAVE_GPU
p.compile(gpu::target{});
program::parameter_map m;
for(auto&& x : p.get_parameter_shapes())
{
m[x.first] =
gpu::to_gpu(generate_argument(x.second, get_hash(x.first)));
}
auto out = gpu::from_gpu(p.eval(m));
std::cout << p << std::endl;
return gpu::from_gpu(out);
#else
(void)p;
MIGRAPHX_THROW("Gpu unsupported!");
#endif
}
void verify_program(const std::string& name, program p, double tolerance)
{
auto x = run_cpu(p);
auto y = run_gpu(p);
verify_args(name, x, y, tolerance);
// std::cout << "cpu: " << x << std::endl;
// std::cout << "gpu: " << y << std::endl;
}
void verify_instructions(const program& prog, double tolerance)
{
for(auto&& ins : prog)
{
if(ins.name().front() == '@')
continue;
if(ins.name() == "broadcast")
continue;
if(ins.name() == "transpose")
continue;
if(ins.name() == "reshape")
continue;
program p;
std::vector<instruction_ref> inputs;
for(auto&& arg : ins.inputs())
{
if(arg->name() == "@literal")
inputs.push_back(p.add_literal(arg->get_literal()));
else
inputs.push_back(
p.add_parameter(std::to_string(inputs.size()), arg->get_shape()));
}
p.add_instruction(ins.get_operator(), inputs);
try
{
std::cout << "Verify: " << ins.name() << std::endl;
std::cout << p << std::endl;
verify_program(ins.name(), p, tolerance);
}
catch(...)
{
std::cout << "Instruction " << ins.name() << " threw an exception." << std::endl;
throw;
}
}
}
void verify_reduced(program p, int n, double tolerance)
{
auto last = std::prev(p.end(), n + 1);
p.remove_instructions(last, p.end());
std::cout << "Verify: " << std::endl;
std::cout << p << std::endl;
verify_program(std::to_string(n), p, tolerance);
}
void verify_reduced_program(program p, double tolerance)
{
auto n = std::distance(p.begin(), p.end());
for(std::size_t i = 0; i < n; i++)
{
verify_reduced(p, i, tolerance);
}
}
} // namespace MIGRAPHX_INLINE_NS
} // namespace driver
} // namespace migraphx
#ifndef MIGRAPHX_GUARD_RTGLIB_DRIVER_VERIFY_HPP
#define MIGRAPHX_GUARD_RTGLIB_DRIVER_VERIFY_HPP
#include <migraphx/program.hpp>
namespace migraphx {
namespace driver {
inline namespace MIGRAPHX_INLINE_NS {
argument run_cpu(program p);
argument run_gpu(program p);
void verify_program(const std::string& name, program p, double tolerance = 100);
void verify_instructions(const program& prog, double tolerance = 80);
void verify_reduced_program(program p, double tolerance = 80);
} // namespace MIGRAPHX_INLINE_NS
} // namespace driver
} // namespace migraphx
#endif
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