Commit 06fb0905 authored by Scott Thornton's avatar Scott Thornton
Browse files

Added MNIST test for cpu target

parents 0a59f103 cff16121
#include <rtg/literal.hpp>
#include <migraph/literal.hpp>
#include <sstream>
#include <string>
#include "test.hpp"
void literal_test()
{
EXPECT(rtg::literal{1} == rtg::literal{1});
EXPECT(rtg::literal{1} != rtg::literal{2});
EXPECT(rtg::literal{} == rtg::literal{});
EXPECT(rtg::literal{} != rtg::literal{2});
EXPECT(migraph::literal{1} == migraph::literal{1});
EXPECT(migraph::literal{1} != migraph::literal{2});
EXPECT(migraph::literal{} == migraph::literal{});
EXPECT(migraph::literal{} != migraph::literal{2});
rtg::literal l1{1};
rtg::literal l2 = l1; // NOLINT
migraph::literal l1{1};
migraph::literal l2 = l1; // NOLINT
EXPECT(l1 == l2);
EXPECT(l1.at<int>(0) == 1);
EXPECT(!l1.empty());
EXPECT(!l2.empty());
rtg::literal l3{};
rtg::literal l4{};
migraph::literal l3{};
migraph::literal l4{};
EXPECT(l3 == l4);
EXPECT(l3.empty());
EXPECT(l4.empty());
......@@ -27,7 +27,7 @@ void literal_test()
void literal_os1()
{
rtg::literal l{1};
migraph::literal l{1};
std::stringstream ss;
ss << l;
EXPECT(ss.str() == "1");
......@@ -35,7 +35,7 @@ void literal_os1()
void literal_os2()
{
rtg::literal l{};
migraph::literal l{};
std::stringstream ss;
ss << l;
EXPECT(ss.str().empty());
......@@ -43,8 +43,8 @@ void literal_os2()
void literal_os3()
{
rtg::shape s{rtg::shape::int64_type, {3}};
rtg::literal l{s, {1, 2, 3}};
migraph::shape s{migraph::shape::int64_type, {3}};
migraph::literal l{s, {1, 2, 3}};
std::stringstream ss;
ss << l;
EXPECT(ss.str() == "1, 2, 3");
......
#include <rtg/program.hpp>
#include <rtg/operators.hpp>
#include <rtg/generate.hpp>
#include <rtg/cpu/cpu_target.hpp>
#include <rtg/miopen/miopen_target.hpp>
#include <rtg/manage_ptr.hpp>
#include <migraph/program.hpp>
#include <migraph/operators.hpp>
#include <migraph/generate.hpp>
#include <migraph/cpu/cpu_target.hpp>
#include <migraph/miopen/miopen_target.hpp>
#include <migraph/miopen/miopen.hpp>
#include <migraph/miopen/hip.hpp>
#include <migraph/manage_ptr.hpp>
#include <miopen/miopen.h>
#include "test.hpp"
#include "verify.hpp"
using hip_ptr = RTG_MANAGE_PTR(void, hipFree);
using miopen_handle = RTG_MANAGE_PTR(miopenHandle_t, miopenDestroy);
template <class Result, class F, class... Ts>
Result make_obj(F f, Ts... xs)
template <class V>
migraph::argument run_cpu()
{
typename Result::pointer x = nullptr;
auto status = f(&x, xs...);
Result r{x};
if(status != miopenStatusSuccess)
RTG_THROW("MIOpen call failed");
return r;
V v;
auto p = v.create_program();
p.compile(migraph::cpu::cpu_target{});
return p.eval(v.create_params());
}
hip_ptr hip_allocate(std::size_t sz)
template <class V>
migraph::argument run_gpu()
{
void* result;
// TODO: Check status
hipMalloc(&result, sz);
return hip_ptr{result};
V v;
auto p = v.create_program();
p.compile(migraph::miopen::miopen_target{});
auto m = v.create_params();
for(auto&& e : m)
{
e.second = migraph::miopen::to_gpu(e.second);
}
m["output"] =
migraph::miopen::to_gpu(migraph::generate_argument(p.get_parameter_shape("output")));
return migraph::miopen::from_gpu(p.eval(m));
}
template <class T>
hip_ptr write(const T& x)
template <class V>
void verify_program()
{
using type = typename T::value_type;
auto size = x.size() * sizeof(type);
auto result = hip_allocate(size);
// TODO: Check status
hipMemcpy(result.get(), x.data(), size, hipMemcpyHostToDevice);
return result;
auto cpu_arg = run_cpu<V>();
auto gpu_arg = run_gpu<V>();
visit_all(cpu_arg, gpu_arg)([](auto cpu, auto gpu) { EXPECT(test::verify_range(cpu, gpu)); });
}
template <class T>
std::vector<T> read(const void* x, std::size_t sz)
struct test_add
{
std::vector<T> result(sz);
// TODO: Check status
hipMemcpy(result.data(), x, sz * sizeof(T), hipMemcpyDeviceToHost);
return result;
}
migraph::program create_program() const
{
migraph::program p;
migraph::shape s{migraph::shape::float_type, {3}};
auto x = p.add_parameter("x", s);
auto y = p.add_parameter("y", s);
p.add_instruction(migraph::add{}, x, y);
return p;
}
migraph::program::parameter_map create_params() const
{
migraph::program::parameter_map m;
m["x"] = migraph::generate_argument({migraph::shape::float_type, {3}});
m["y"] = migraph::generate_argument({migraph::shape::float_type, {3}});
return m;
}
};
rtg::program create_program()
struct test_add_broadcast
{
rtg::program p;
auto input = p.add_parameter("x", rtg::shape{rtg::shape::float_type, {4, 3, 3, 3}});
auto weights = p.add_parameter("w", rtg::shape{rtg::shape::float_type, {4, 3, 3, 3}});
auto conv = p.add_instruction(rtg::convolution{}, input, weights);
p.add_instruction(rtg::activation{"relu"}, conv);
return p;
}
migraph::program create_program() const
{
migraph::program p;
migraph::shape s{migraph::shape::float_type, {3}};
auto x = p.add_parameter("x", {migraph::shape::float_type, {2, 2, 3}});
auto y = p.add_parameter("y", {migraph::shape::float_type, {2, 2}});
auto by = p.add_instruction(migraph::broadcast{0}, x, y);
p.add_instruction(migraph::add{}, x, by);
return p;
}
migraph::program::parameter_map create_params() const
{
migraph::program::parameter_map m;
m["x"] = migraph::generate_argument({migraph::shape::float_type, {2, 2, 3}});
m["y"] = migraph::generate_argument({migraph::shape::float_type, {2, 2}});
return m;
}
};
// TODO: Move to header
rtg::argument get_tensor_argument_gpu(rtg::shape s)
struct test_conv_relu
{
auto v = rtg::generate_tensor_data<float>(s);
auto p = rtg::share(write(v));
return {s, [p]() mutable { return reinterpret_cast<char*>(p.get()); }};
}
migraph::program create_program() const
{
migraph::program p;
auto input = p.add_parameter("x", migraph::shape{migraph::shape::float_type, {4, 3, 3, 3}});
auto weights =
p.add_parameter("w", migraph::shape{migraph::shape::float_type, {4, 3, 3, 3}});
auto conv = p.add_instruction(migraph::convolution{}, input, weights);
p.add_instruction(migraph::activation{"relu"}, conv);
return p;
}
migraph::program::parameter_map create_params() const
{
migraph::program::parameter_map m;
m["x"] = migraph::generate_argument({migraph::shape::float_type, {4, 3, 3, 3}});
m["w"] = migraph::generate_argument({migraph::shape::float_type, {4, 3, 3, 3}});
return m;
}
};
std::vector<float> cpu()
struct test_conv_pooling
{
std::vector<float> result;
auto p = create_program();
auto x = rtg::generate_argument({rtg::shape::float_type, {4, 3, 3, 3}});
auto w = rtg::generate_argument({rtg::shape::float_type, {4, 3, 3, 3}});
p.compile(rtg::cpu::cpu_target{});
auto r = p.eval({{"x", x}, {"w", w}});
auto output = r.get<float>();
result.assign(output.begin(), output.end());
return result;
}
migraph::program create_program() const
{
migraph::program p;
auto input =
p.add_parameter("x", migraph::shape{migraph::shape::float_type, {4, 3, 32, 32}});
auto weights =
p.add_parameter("w", migraph::shape{migraph::shape::float_type, {4, 3, 3, 3}});
auto conv = p.add_instruction(migraph::convolution{}, input, weights);
auto pooling = p.add_instruction(migraph::pooling{"max"}, conv);
p.add_instruction(migraph::activation{"relu"}, pooling);
return p;
}
migraph::program::parameter_map create_params() const
{
migraph::program::parameter_map m;
m["x"] = migraph::generate_argument({migraph::shape::float_type, {4, 3, 32, 32}});
m["w"] = migraph::generate_argument({migraph::shape::float_type, {4, 3, 3, 3}});
return m;
}
};
std::vector<float> gpu()
struct test_gemm
{
std::vector<float> result;
auto p = create_program();
auto x = get_tensor_argument_gpu({rtg::shape::float_type, {4, 3, 3, 3}});
auto w = get_tensor_argument_gpu({rtg::shape::float_type, {4, 3, 3, 3}});
p.compile(rtg::miopen::miopen_target{});
auto y = get_tensor_argument_gpu(p.get_parameter_shape("output"));
auto handle = make_obj<miopen_handle>(&miopenCreate);
auto r = p.eval(
{{"x", x}, {"w", w}, {"output", y}, {"handle", {rtg::shape::any_type, handle.get()}}});
result = read<float>(r.data(), r.get_shape().elements());
return result;
}
migraph::program create_program() const
{
migraph::program p;
auto a = p.add_parameter("a", migraph::shape{migraph::shape::float_type, {4, 5}});
auto b = p.add_parameter("b", migraph::shape{migraph::shape::float_type, {5, 3}});
p.add_instruction(migraph::gemm{}, a, b);
return p;
}
migraph::program::parameter_map create_params() const
{
migraph::program::parameter_map m;
m["a"] = migraph::generate_argument({migraph::shape::float_type, {4, 5}});
m["b"] = migraph::generate_argument({migraph::shape::float_type, {5, 3}});
return m;
}
};
void test1()
int main()
{
auto x = cpu();
auto y = gpu();
EXPECT(test::verify_range(x, y));
verify_program<test_add>();
verify_program<test_add_broadcast>();
verify_program<test_conv_relu>();
verify_program<test_conv_pooling>();
verify_program<test_gemm>();
}
int main() { test1(); }
#include <rtg/operation.hpp>
#include <migraph/operation.hpp>
#include <sstream>
#include <string>
#include "test.hpp"
......@@ -8,10 +8,14 @@ struct simple_operation
{
int data = 1;
std::string name() const { return "simple"; }
rtg::shape compute_shape(std::vector<rtg::shape>) const { RTG_THROW("not computable"); }
rtg::argument compute(rtg::shape, std::vector<rtg::argument>) const
migraph::shape compute_shape(std::vector<migraph::shape>) const
{
RTG_THROW("not computable");
MIGRAPH_THROW("not computable");
}
migraph::argument
compute(migraph::context&, migraph::shape, std::vector<migraph::argument>) const
{
MIGRAPH_THROW("not computable");
}
friend std::ostream& operator<<(std::ostream& os, const simple_operation& op)
{
......@@ -23,18 +27,22 @@ struct simple_operation
struct simple_operation_no_print
{
std::string name() const { return "simple"; }
rtg::shape compute_shape(std::vector<rtg::shape>) const { RTG_THROW("not computable"); }
rtg::argument compute(rtg::shape, std::vector<rtg::argument>) const
migraph::shape compute_shape(std::vector<migraph::shape>) const
{
MIGRAPH_THROW("not computable");
}
migraph::argument
compute(migraph::context&, migraph::shape, std::vector<migraph::argument>) const
{
RTG_THROW("not computable");
MIGRAPH_THROW("not computable");
}
};
void operation_copy_test()
{
simple_operation s{};
rtg::operation op1 = s; // NOLINT
rtg::operation op2 = op1; // NOLINT
migraph::operation op1 = s; // NOLINT
migraph::operation op2 = op1; // NOLINT
EXPECT(s.name() == op1.name());
EXPECT(op2.name() == op1.name());
}
......@@ -45,18 +53,18 @@ struct not_operation
void operation_any_cast()
{
rtg::operation op1 = simple_operation{};
EXPECT(rtg::any_cast<simple_operation>(op1).data == 1);
EXPECT(rtg::any_cast<not_operation*>(&op1) == nullptr);
EXPECT(test::throws([&] { rtg::any_cast<not_operation&>(op1); }));
rtg::operation op2 = simple_operation{2};
EXPECT(rtg::any_cast<simple_operation>(op2).data == 2);
EXPECT(rtg::any_cast<not_operation*>(&op2) == nullptr);
migraph::operation op1 = simple_operation{};
EXPECT(migraph::any_cast<simple_operation>(op1).data == 1);
EXPECT(migraph::any_cast<not_operation*>(&op1) == nullptr);
EXPECT(test::throws([&] { migraph::any_cast<not_operation&>(op1); }));
migraph::operation op2 = simple_operation{2};
EXPECT(migraph::any_cast<simple_operation>(op2).data == 2);
EXPECT(migraph::any_cast<not_operation*>(&op2) == nullptr);
}
void operation_print()
{
rtg::operation op = simple_operation{};
migraph::operation op = simple_operation{};
std::stringstream ss;
ss << op;
std::string s = ss.str();
......@@ -65,7 +73,7 @@ void operation_print()
void operation_default_print()
{
rtg::operation op = simple_operation_no_print{};
migraph::operation op = simple_operation_no_print{};
std::stringstream ss;
ss << op;
std::string s = ss.str();
......
#include <rtg/shape.hpp>
#include <migraph/shape.hpp>
#include <array>
#include <algorithm>
#include <numeric>
......@@ -7,25 +7,25 @@
void test_shape_assign()
{
rtg::shape s1{rtg::shape::float_type, {100, 32, 8, 8}};
rtg::shape s2 = s1; // NOLINT
migraph::shape s1{migraph::shape::float_type, {100, 32, 8, 8}};
migraph::shape s2 = s1; // NOLINT
EXPECT(s1 == s2);
EXPECT(!(s1 != s2));
}
void test_shape_default()
{
rtg::shape s1{};
rtg::shape s2{};
migraph::shape s1{};
migraph::shape s2{};
EXPECT(s1 == s2);
EXPECT(!(s1 != s2));
}
void test_shape4()
{
rtg::shape s{rtg::shape::float_type, {100, 32, 8, 8}};
migraph::shape s{migraph::shape::float_type, {100, 32, 8, 8}};
EXPECT(s.packed());
EXPECT(s.type() == rtg::shape::float_type);
EXPECT(s.type() == migraph::shape::float_type);
EXPECT(s.lens()[0] == 100);
EXPECT(s.lens()[1] == 32);
EXPECT(s.lens()[2] == 8);
......@@ -67,9 +67,9 @@ void test_shape4_nonpacked()
strides.rbegin() + 1,
std::multiplies<std::size_t>());
rtg::shape s{rtg::shape::float_type, lens, strides};
migraph::shape s{migraph::shape::float_type, lens, strides};
EXPECT(!s.packed());
EXPECT(s.type() == rtg::shape::float_type);
EXPECT(s.type() == migraph::shape::float_type);
EXPECT(s.lens()[0] == 100);
EXPECT(s.lens()[1] == 32);
EXPECT(s.lens()[2] == 8);
......
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ls -1 $DIR/include/ | xargs -n 1 -P $(nproc) -I{} -t bash -c "python $DIR/te.py $DIR/include/{} | clang-format-5.0 -style=file > $DIR/../src/include/rtg/{}"
ls -1 $DIR/include/ | xargs -n 1 -P $(nproc) -I{} -t bash -c "python3.6 $DIR/te.py $DIR/include/{} | clang-format-5.0 -style=file > $DIR/../src/include/migraph/{}"
#ifndef MIGRAPH_GUARD_CONTEXT_HPP
#define MIGRAPH_GUARD_CONTEXT_HPP
namespace migraph {
<%
interface('context')
%>
} // namespace migraph
#endif
#ifndef RTG_GUARD_RTGLIB_OPERAND_HPP
#define RTG_GUARD_RTGLIB_OPERAND_HPP
#ifndef MIGRAPH_GUARD_MIGRAPHLIB_OPERAND_HPP
#define MIGRAPH_GUARD_MIGRAPHLIB_OPERAND_HPP
#include <string>
#include <functional>
#include <memory>
#include <type_traits>
#include <utility>
#include <rtg/shape.hpp>
#include <rtg/argument.hpp>
#include <migraph/shape.hpp>
#include <migraph/argument.hpp>
#include <migraph/context.hpp>
namespace rtg {
namespace migraph {
namespace operation_stream {
......@@ -25,11 +26,11 @@ auto operator<<(std::ostream& os, const T& x) -> decltype(os << x.name())
interface('operation',
virtual('name', returns='std::string', const=True),
virtual('compute_shape', returns='shape', input='std::vector<shape>', const=True),
virtual('compute', returns='argument', output='shape', input='std::vector<argument>', const=True),
friend('operator<<', returns='std::ostream &', os='std::ostream &', op='const operation &', using='rtg::operation_stream::operator<<')
virtual('compute', returns='argument', ctx='context&', output='shape', input='std::vector<argument>', const=True),
friend('operator<<', returns='std::ostream &', os='std::ostream &', op='const operation &', using='migraph::operation_stream::operator<<')
)
%>
} // namespace rtg
} // namespace migraph
#endif
#ifndef RTG_GUARD_RTGLIB_TARGET_HPP
#define RTG_GUARD_RTGLIB_TARGET_HPP
#ifndef MIGRAPH_GUARD_MIGRAPHLIB_TARGET_HPP
#define MIGRAPH_GUARD_MIGRAPHLIB_TARGET_HPP
#include <string>
#include <functional>
#include <memory>
#include <type_traits>
#include <utility>
#include <migraph/context.hpp>
namespace rtg {
namespace migraph {
struct program;
<%
interface('target',
virtual('name', returns='std::string', const=True),
virtual('apply', returns='void', p='program &', const=True)
virtual('apply', returns='void', p='program &', const=True),
virtual('get_context', returns='context', const=True)
)
%>
} // namespace rtg
} // namespace migraph
#endif
......@@ -63,6 +63,12 @@ struct ${struct_name}
nullptr;
}
const std::type_info& type_id() const
{
if(private_detail_te_handle_empty()) return typeid(std::nullptr_t);
else return private_detail_te_get_handle().type();
}
${nonvirtual_members}
private:
......@@ -118,11 +124,20 @@ private:
{}
};
bool private_detail_te_handle_empty() const
{
return private_detail_te_handle_mem_var == nullptr;
}
const private_detail_te_handle_base_type & private_detail_te_get_handle () const
{ return *private_detail_te_handle_mem_var; }
{
assert(private_detail_te_handle_mem_var != nullptr);
return *private_detail_te_handle_mem_var;
}
private_detail_te_handle_base_type & private_detail_te_get_handle ()
{
assert(private_detail_te_handle_mem_var != nullptr);
if (!private_detail_te_handle_mem_var.unique())
private_detail_te_handle_mem_var = private_detail_te_handle_mem_var->clone();
return *private_detail_te_handle_mem_var;
......
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