miopen.cpp 3.05 KB
Newer Older
Paul's avatar
Paul committed
1
2
3

#include <rtg/program.hpp>
#include <rtg/operators.hpp>
Paul's avatar
Paul committed
4
#include <rtg/generate.hpp>
Paul's avatar
Paul committed
5
6
7
8
9
10
11
#include <rtg/cpu/cpu_target.hpp>
#include <rtg/miopen/miopen_target.hpp>
#include <rtg/manage_ptr.hpp>

#include <miopen/miopen.h>

#include "test.hpp"
Paul's avatar
Paul committed
12
#include "verify.hpp"
Paul's avatar
Paul committed
13

Paul's avatar
Paul committed
14
15
using hip_ptr       = RTG_MANAGE_PTR(void, hipFree);
using miopen_handle = RTG_MANAGE_PTR(miopenHandle_t, miopenDestroy);
Paul's avatar
Paul committed
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

template <class Result, class F, class... Ts>
Result make_obj(F f, Ts... xs)
{
    typename Result::pointer x = nullptr;
    auto status                = f(&x, xs...);
    Result r{x};
    if(status != miopenStatusSuccess)
        RTG_THROW("MIOpen call failed");
    return r;
}

hip_ptr hip_allocate(std::size_t sz)
{
    void* result;
    // TODO: Check status
    hipMalloc(&result, sz);
    return hip_ptr{result};
}

Paul's avatar
Paul committed
36
template <class T>
Paul's avatar
Paul committed
37
38
hip_ptr write(const T& x)
{
Paul's avatar
Paul committed
39
40
    using type  = typename T::value_type;
    auto size   = x.size() * sizeof(type);
Paul's avatar
Paul committed
41
42
43
44
45
46
    auto result = hip_allocate(size);
    // TODO: Check status
    hipMemcpy(result.get(), x.data(), size, hipMemcpyHostToDevice);
    return result;
}

Paul's avatar
Paul committed
47
template <class T>
Paul's avatar
Paul committed
48
std::vector<T> read(const void* x, std::size_t sz)
Paul's avatar
Paul committed
49
50
51
{
    std::vector<T> result(sz);
    // TODO: Check status
Paul's avatar
Paul committed
52
    hipMemcpy(result.data(), x, sz * sizeof(T), hipMemcpyDeviceToHost);
Paul's avatar
Paul committed
53
54
55
56
57
58
    return result;
}

rtg::program create_program()
{
    rtg::program p;
Paul's avatar
Paul committed
59
    auto input   = p.add_parameter("x", rtg::shape{rtg::shape::float_type, {4, 3, 3, 3}});
Paul's avatar
Paul committed
60
    auto weights = p.add_parameter("w", rtg::shape{rtg::shape::float_type, {4, 3, 3, 3}});
Paul's avatar
Paul committed
61
    auto conv    = p.add_instruction(rtg::convolution{}, input, weights);
Paul's avatar
Paul committed
62
63
64
65
    p.add_instruction(rtg::activation{"relu"}, conv);
    return p;
}

Paul's avatar
Paul committed
66
// TODO: Move to header
Paul's avatar
Paul committed
67
68
rtg::argument get_tensor_argument_gpu(rtg::shape s)
{
Paul's avatar
Paul committed
69
    auto v = rtg::generate_tensor_data<float>(s);
Paul's avatar
Paul committed
70
71
72
73
74
75
76
77
    auto p = rtg::share(write(v));
    return {s, [p]() mutable { return reinterpret_cast<char*>(p.get()); }};
}

std::vector<float> cpu()
{
    std::vector<float> result;
    auto p = create_program();
Paul's avatar
Paul committed
78
79
    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}});
Paul's avatar
Paul committed
80
    p.compile(rtg::cpu::cpu_target{});
Paul's avatar
Paul committed
81
    auto r      = p.eval({{"x", x}, {"w", w}});
Paul's avatar
Paul committed
82
83
    auto output = r.get<float>();
    result.assign(output.begin(), output.end());
Paul's avatar
Paul committed
84
85
86
87
88
89
90
91
92
93
    return result;
}

std::vector<float> gpu()
{
    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{});
Paul's avatar
Paul committed
94
    auto y      = get_tensor_argument_gpu(p.get_parameter_shape("output"));
Paul's avatar
Paul committed
95
    auto handle = make_obj<miopen_handle>(&miopenCreate);
Paul's avatar
Paul committed
96
97
    auto r      = p.eval(
        {{"x", x}, {"w", w}, {"output", y}, {"handle", {rtg::shape::any_type, handle.get()}}});
Paul's avatar
Paul committed
98
    result = read<float>(r.data(), r.get_shape().elements());
Paul's avatar
Paul committed
99
100
101
    return result;
}

Paul's avatar
Paul committed
102
void test1()
Paul's avatar
Paul committed
103
104
105
{
    auto x = cpu();
    auto y = gpu();
Paul's avatar
Paul committed
106
    EXPECT(test::verify_range(x, y));
Paul's avatar
Paul committed
107
108
}

Paul's avatar
Paul committed
109
int main() { test1(); }