jit.cpp 4.9 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
17
18
19
20
21
22
23
24
25
26
#include <hip/hip_runtime.h>

extern "C" {
__global__ void write(int* data) 
{
    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
34
35
36
37
38
39
40
41
42
43
#include <hip/hip_runtime.h>

extern "C" {
__global__ void add_2(std::int32_t* x, std::int32_t* y) 
{
    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
92
93
94
95
96
97
98
99
100
101
102
{
    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);

    migraphx::argument input{{migraphx::shape::int32_type, {5}}};
    auto ginput = migraphx::gpu::to_gpu(input);
    migraphx::gpu::kernel k{binaries.front(), "write"};
    k.launch(nullptr, input.get_shape().elements(), 1024)(ginput.cast<int>());
    auto output = migraphx::gpu::from_gpu(ginput);

    EXPECT(output != input);
    auto data = output.get<int>();
    EXPECT(migraphx::all_of(data, [](auto x) { return x == 2; }));
}

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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);

    migraphx::shape input{migraphx::shape::int32_type, {5}};

    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); }