jit.cpp 4.91 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
9
#include <migraphx/gpu/hip.hpp>
#include <migraphx/gpu/compile_hip.hpp>
10
#include <migraphx/gpu/compile_hip_code_object.hpp>
Paul Fultz II's avatar
Paul Fultz II committed
11
12

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

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

int main() {}

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

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

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

int main() {}

44
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
)__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__";
71

72
migraphx::src_file make_src_file(const std::string& name, const std::string& content)
Paul Fultz II's avatar
Paul Fultz II committed
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
{
    return {name, std::make_pair(content.data(), content.data() + content.size())};
}

std::string get_device_name()
{
    hipDeviceProp_t props{};
    int device;
    EXPECT(hipGetDevice(&device) == hipSuccess);
    EXPECT(hipGetDeviceProperties(&props, device) == hipSuccess);
    return "gfx" + std::to_string(props.gcnArch);
}

TEST_CASE(simple_compile_hip)
{
    auto binaries = migraphx::gpu::compile_hip_src(
        {make_src_file("main.cpp", write_2s)}, "", get_device_name());
    EXPECT(binaries.size() == 1);

92
    migraphx::argument input{{migraphx::shape::int8_type, {5}}};
Paul Fultz II's avatar
Paul Fultz II committed
93
94
    auto ginput = migraphx::gpu::to_gpu(input);
    migraphx::gpu::kernel k{binaries.front(), "write"};
95
    k.launch(nullptr, input.get_shape().elements(), 1024)(ginput.cast<std::int8_t>());
Paul Fultz II's avatar
Paul Fultz II committed
96
97
98
    auto output = migraphx::gpu::from_gpu(ginput);

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

103
104
105
106
107
108
TEST_CASE(code_object_hip)
{
    auto binaries = migraphx::gpu::compile_hip_src(
        {make_src_file("main.cpp", add_2s_binary)}, "", get_device_name());
    EXPECT(binaries.size() == 1);

109
    migraphx::shape input{migraphx::shape::int8_type, {5}};
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

    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);
125
    auto y              = mm->add_parameter("output", input);
126
127
128
129
    mm->add_instruction(co, x, y);
    migraphx::compile_options options;
    p.compile(migraphx::gpu::target{}, options);

130
131
    auto result =
        migraphx::gpu::from_gpu(p.eval({{"output", migraphx::gpu::allocate_gpu(input)}}).front());
132
133
134
135

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

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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);
152
    auto y              = mm->add_parameter("output", input);
153
154
155
    mm->add_instruction(co, x, y);
    p.compile(migraphx::gpu::target{}, migraphx::compile_options{});

156
157
    auto result =
        migraphx::gpu::from_gpu(p.eval({{"output", migraphx::gpu::allocate_gpu(input)}}).front());
158
159
160
161

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

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