"...modeling/git@developer.sourcefind.cn:OpenDAS/autogptq.git" did not exist on "da900c3b684da5a63070257b2469472ab9fc4e62"
hip.cpp 3.04 KB
Newer Older
Paul Fultz II's avatar
Paul Fultz II committed
1
2
3
4
#include <rtc/hip.hpp>
#include <rtc/manage_ptr.hpp>
#include <stdexcept>
#include <cassert>
arai713's avatar
arai713 committed
5
#include <iostream>
Paul Fultz II's avatar
Paul Fultz II committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

namespace rtc {

using hip_ptr = RTC_MANAGE_PTR(void, hipFree);

std::string hip_error(int error) { return hipGetErrorString(static_cast<hipError_t>(error)); }

int get_device_id()
{
    int device;
    auto status = hipGetDevice(&device);
    if(status != hipSuccess)
        throw std::runtime_error("No device");
    return device;
}

std::string get_device_name()
{
    hipDeviceProp_t props{};
    auto status = hipGetDeviceProperties(&props, get_device_id());
    if(status != hipSuccess)
        throw std::runtime_error("Failed to get device properties");
    return props.gcnArchName;
}

bool is_device_ptr(const void* ptr)
{
    hipPointerAttribute_t attr;
    auto status = hipPointerGetAttributes(&attr, ptr);
    if(status != hipSuccess)
        return false;
    return attr.type == hipMemoryTypeDevice;
}

void gpu_sync()
{
    auto status = hipDeviceSynchronize();
    if(status != hipSuccess)
        throw std::runtime_error("hip device synchronization failed: " + hip_error(status));
}

std::size_t get_available_gpu_memory()
{
    size_t free;
    size_t total;
    auto status = hipMemGetInfo(&free, &total);
    if(status != hipSuccess)
arai713's avatar
arai713 committed
53
54
55
56
    {
        std::cerr << "Failed getting available memory: " + hip_error(status) << std::endl;
        return (8ull * 1024ull * 1024ull * 1024ull);
    }
Paul Fultz II's avatar
Paul Fultz II committed
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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
103
104
105
106
    return free;
}

std::shared_ptr<void> allocate_gpu(std::size_t sz, bool host)
{
    if(sz > get_available_gpu_memory())
        throw std::runtime_error("Memory not available to allocate buffer: " + std::to_string(sz));
    void* alloc_ptr = nullptr;
    auto status     = host ? hipHostMalloc(&alloc_ptr, sz) : hipMalloc(&alloc_ptr, sz);
    if(status != hipSuccess)
    {
        if(host)
            throw std::runtime_error("Gpu allocation failed: " + hip_error(status));
        else
            return allocate_gpu(sz, true);
    }
    assert(alloc_ptr != nullptr);
    std::shared_ptr<void> result = share(hip_ptr{alloc_ptr});
    return result;
}

std::shared_ptr<void> write_to_gpu(const void* x, std::size_t sz, bool host)
{
    gpu_sync();
    auto result = allocate_gpu(sz, host);
    assert(is_device_ptr(result.get()));
    assert(not is_device_ptr(x));
    auto status = hipMemcpy(result.get(), x, sz, hipMemcpyHostToDevice);
    if(status != hipSuccess)
        throw std::runtime_error("Copy to gpu failed: " + hip_error(status));
    return result;
}

std::shared_ptr<void> read_from_gpu(const void* x, std::size_t sz)
{
    gpu_sync();
    std::shared_ptr<char> result(new char[sz]);
    assert(not is_device_ptr(result.get()));
    if(not is_device_ptr(x))
    {
        throw std::runtime_error(
            "read_from_gpu() requires Src buffer to be on the GPU, Copy from gpu failed\n");
    }
    auto status = hipMemcpy(result.get(), x, sz, hipMemcpyDeviceToHost);
    if(status != hipSuccess)
        throw std::runtime_error("Copy from gpu failed: " + hip_error(status)); // NOLINT
    return std::static_pointer_cast<void>(result);
}

} // namespace rtc