1 | //===--- amdgpu/dynamic_hsa/hsa.cpp ------------------------------- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // Implement subset of hsa api by calling into hsa library via dlopen |
10 | // Does the dlopen/dlsym calls as part of the call to hsa_init |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "llvm/Support/DynamicLibrary.h" |
15 | |
16 | #include "Shared/Debug.h" |
17 | |
18 | #include "DLWrap.h" |
19 | #include "hsa.h" |
20 | #include "hsa_ext_amd.h" |
21 | #include <memory> |
22 | |
23 | DLWRAP_INITIALIZE() |
24 | |
25 | DLWRAP_INTERNAL(hsa_init, 0) |
26 | |
27 | DLWRAP(hsa_status_string, 2) |
28 | DLWRAP(hsa_shut_down, 0) |
29 | DLWRAP(hsa_system_get_info, 2) |
30 | DLWRAP(hsa_agent_get_info, 3) |
31 | DLWRAP(hsa_isa_get_info_alt, 3) |
32 | DLWRAP(hsa_iterate_agents, 2) |
33 | DLWRAP(hsa_agent_iterate_isas, 3) |
34 | DLWRAP(hsa_signal_create, 4) |
35 | DLWRAP(hsa_signal_destroy, 1) |
36 | DLWRAP(hsa_signal_store_relaxed, 2) |
37 | DLWRAP(hsa_signal_store_screlease, 2) |
38 | DLWRAP(hsa_signal_wait_scacquire, 5) |
39 | DLWRAP(hsa_signal_load_scacquire, 1) |
40 | DLWRAP(hsa_signal_subtract_screlease, 2) |
41 | DLWRAP(hsa_queue_create, 8) |
42 | DLWRAP(hsa_queue_destroy, 1) |
43 | DLWRAP(hsa_queue_load_read_index_scacquire, 1) |
44 | DLWRAP(hsa_queue_add_write_index_relaxed, 2) |
45 | DLWRAP(hsa_memory_copy, 3) |
46 | DLWRAP(hsa_executable_create, 4) |
47 | DLWRAP(hsa_executable_create_alt, 4) |
48 | DLWRAP(hsa_executable_destroy, 1) |
49 | DLWRAP(hsa_executable_freeze, 2) |
50 | DLWRAP(hsa_executable_validate, 2) |
51 | DLWRAP(hsa_executable_symbol_get_info, 3) |
52 | DLWRAP(hsa_executable_get_symbol_by_name, 4) |
53 | DLWRAP(hsa_executable_iterate_symbols, 3) |
54 | DLWRAP(hsa_code_object_deserialize, 4) |
55 | DLWRAP(hsa_executable_load_code_object, 4) |
56 | DLWRAP(hsa_code_object_destroy, 1) |
57 | DLWRAP(hsa_amd_agent_memory_pool_get_info, 4) |
58 | DLWRAP(hsa_amd_agent_iterate_memory_pools, 3) |
59 | DLWRAP(hsa_amd_memory_pool_allocate, 4) |
60 | DLWRAP(hsa_amd_memory_pool_free, 1) |
61 | DLWRAP(hsa_amd_memory_async_copy, 8) |
62 | DLWRAP(hsa_amd_memory_pool_get_info, 3) |
63 | DLWRAP(hsa_amd_agents_allow_access, 4) |
64 | DLWRAP(hsa_amd_memory_lock, 5) |
65 | DLWRAP(hsa_amd_memory_unlock, 1) |
66 | DLWRAP(hsa_amd_memory_fill, 3) |
67 | DLWRAP(hsa_amd_register_system_event_handler, 2) |
68 | DLWRAP(hsa_amd_signal_create, 5) |
69 | DLWRAP(hsa_amd_signal_async_handler, 5) |
70 | DLWRAP(hsa_amd_pointer_info, 5) |
71 | |
72 | DLWRAP_FINALIZE() |
73 | |
74 | #ifndef DYNAMIC_HSA_PATH |
75 | #define DYNAMIC_HSA_PATH "libhsa-runtime64.so" |
76 | #endif |
77 | |
78 | #ifndef TARGET_NAME |
79 | #error "Missing TARGET_NAME macro" |
80 | #endif |
81 | #ifndef DEBUG_PREFIX |
82 | #define DEBUG_PREFIX "Target " GETNAME(TARGET_NAME) " RTL" |
83 | #endif |
84 | |
85 | static bool checkForHSA() { |
86 | // return true if dlopen succeeded and all functions found |
87 | |
88 | const char *HsaLib = DYNAMIC_HSA_PATH; |
89 | std::string ErrMsg; |
90 | auto DynlibHandle = std::make_unique<llvm::sys::DynamicLibrary>( |
91 | llvm::sys::DynamicLibrary::getPermanentLibrary(HsaLib, &ErrMsg)); |
92 | if (!DynlibHandle->isValid()) { |
93 | DP("Unable to load library '%s': %s!\n" , HsaLib, ErrMsg.c_str()); |
94 | return false; |
95 | } |
96 | |
97 | for (size_t I = 0; I < dlwrap::size(); I++) { |
98 | const char *Sym = dlwrap::symbol(I); |
99 | |
100 | void *P = DynlibHandle->getAddressOfSymbol(Sym); |
101 | if (P == nullptr) { |
102 | DP("Unable to find '%s' in '%s'!\n" , Sym, HsaLib); |
103 | return false; |
104 | } |
105 | DP("Implementing %s with dlsym(%s) -> %p\n" , Sym, Sym, P); |
106 | |
107 | *dlwrap::pointer(I) = P; |
108 | } |
109 | |
110 | return true; |
111 | } |
112 | |
113 | hsa_status_t hsa_init() { |
114 | if (!checkForHSA()) { |
115 | return HSA_STATUS_ERROR; |
116 | } |
117 | return dlwrap_hsa_init(); |
118 | } |
119 | |