jit.cpp 4.74 KB
Newer Older
Paul Fultz II's avatar
Paul Fultz II committed
1
2
#include <test.hpp>
#include <migraphx/ranges.hpp>
3
4
5
#include <migraphx/make_op.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/program.hpp>
Paul Fultz II's avatar
Paul Fultz II committed
6
#include <migraphx/gpu/kernel.hpp>
7
#include <migraphx/gpu/target.hpp>
Paul Fultz II's avatar
Paul Fultz II committed
8
#include <migraphx/gpu/hip.hpp>
9
#include <migraphx/gpu/device_name.hpp>
Paul Fultz II's avatar
Paul Fultz II committed
10
#include <migraphx/gpu/compile_hip.hpp>
11
#include <migraphx/gpu/compile_hip_code_object.hpp>
Paul Fultz II's avatar
Paul Fultz II committed
12
13

// NOLINTNEXTLINE
14
const std::string write_2s = R"__migraphx__(
Paul Fultz II's avatar
Paul Fultz II committed
15
16
17
#include <hip/hip_runtime.h>

extern "C" {
18
__global__ void write(int8_t* data) 
Paul Fultz II's avatar
Paul Fultz II committed
19
20
21
22
23
24
25
26
27
{
    int num = threadIdx.x + blockDim.x * blockIdx.x;
    data[num] = 2;
}
    
}

int main() {}

28
)__migraphx__";
Paul Fultz II's avatar
Paul Fultz II committed
29

30
// NOLINTNEXTLINE
31
const std::string add_2s_binary = R"__migraphx__(
32
33
34
#include <hip/hip_runtime.h>

extern "C" {
35
__global__ void add_2(std::int8_t* x, std::int8_t* y) 
36
37
38
39
40
41
42
43
44
{
    int num = threadIdx.x + blockDim.x * blockIdx.x;
    y[num] = x[num] + 2;
}
    
}

int main() {}

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
)__migraphx__";

// NOLINTNEXTLINE
const std::string simple_pointwise_increment = R"__migraphx__(
#include <migraphx/kernels/index.hpp>
#include <args.hpp>

using namespace migraphx;

extern "C" {
__global__ void kernel(void* x, void* y) 
{
    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)
        {
            yt[i] = xt[i] + 1;
        }
    });
}
    
}

int main() {}

)__migraphx__";
72

73
migraphx::src_file make_src_file(const std::string& name, const std::string& content)
Paul Fultz II's avatar
Paul Fultz II committed
74
75
76
77
78
79
80
{
    return {name, std::make_pair(content.data(), content.data() + content.size())};
}

TEST_CASE(simple_compile_hip)
{
    auto binaries = migraphx::gpu::compile_hip_src(
81
        {make_src_file("main.cpp", write_2s)}, "", migraphx::gpu::get_device_name());
Paul Fultz II's avatar
Paul Fultz II committed
82
83
    EXPECT(binaries.size() == 1);

84
    migraphx::argument input{{migraphx::shape::int8_type, {5}}};
Paul Fultz II's avatar
Paul Fultz II committed
85
86
    auto ginput = migraphx::gpu::to_gpu(input);
    migraphx::gpu::kernel k{binaries.front(), "write"};
87
    k.launch(nullptr, input.get_shape().elements(), 1024)(ginput.cast<std::int8_t>());
Paul Fultz II's avatar
Paul Fultz II committed
88
89
90
    auto output = migraphx::gpu::from_gpu(ginput);

    EXPECT(output != input);
91
    auto data = output.get<std::int8_t>();
Paul Fultz II's avatar
Paul Fultz II committed
92
93
94
    EXPECT(migraphx::all_of(data, [](auto x) { return x == 2; }));
}

95
96
97
TEST_CASE(code_object_hip)
{
    auto binaries = migraphx::gpu::compile_hip_src(
98
        {make_src_file("main.cpp", add_2s_binary)}, "", migraphx::gpu::get_device_name());
99
100
    EXPECT(binaries.size() == 1);

101
    migraphx::shape input{migraphx::shape::int8_type, {5}};
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

    std::vector<migraphx::shape> expected_inputs = {input, input};
    auto co                                      = migraphx::make_op("gpu::code_object",
                                {{"code_object", migraphx::value::binary{binaries.front()}},
                                 {"symbol_name", "add_2"},
                                 {"global", input.elements()},
                                 {"local", 1024},
                                 {"expected_inputs", migraphx::to_value(expected_inputs)},
                                 {"output", migraphx::to_value(input)}});

    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 + 2; });
    auto x              = mm->add_literal(input_literal);
117
    auto y              = mm->add_parameter("output", input);
118
119
120
121
    mm->add_instruction(co, x, y);
    migraphx::compile_options options;
    p.compile(migraphx::gpu::target{}, options);

122
123
    auto result =
        migraphx::gpu::from_gpu(p.eval({{"output", migraphx::gpu::allocate_gpu(input)}}).front());
124
125
126
127

    EXPECT(result == output_literal.get_argument());
}

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
TEST_CASE(compile_code_object_hip)
{
    migraphx::shape input{migraphx::shape::float_type, {5, 2}};
    migraphx::gpu::hip_compile_options options;
    options.global = 256 * 1024;
    options.local  = 1024;
    options.inputs = {input, input};
    options.output = input;

    auto co = migraphx::gpu::compile_hip_code_object(simple_pointwise_increment, options);

    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);
144
    auto y              = mm->add_parameter("output", input);
145
146
147
    mm->add_instruction(co, x, y);
    p.compile(migraphx::gpu::target{}, migraphx::compile_options{});

148
149
    auto result =
        migraphx::gpu::from_gpu(p.eval({{"output", migraphx::gpu::allocate_gpu(input)}}).front());
150
151
152
153

    EXPECT(result == output_literal.get_argument());
}

Paul Fultz II's avatar
Paul Fultz II committed
154
int main(int argc, const char* argv[]) { test::run(argc, argv); }