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 #include "hsa.h"
14 #include "Debug.h"
15 #include "dlwrap.h"
16 #include "hsa_ext_amd.h"
17 
18 #include <dlfcn.h>
19 
20 DLWRAP_INITIALIZE();
21 
22 DLWRAP_INTERNAL(hsa_init, 0);
23 
24 DLWRAP(hsa_status_string, 2);
25 DLWRAP(hsa_shut_down, 0);
26 DLWRAP(hsa_system_get_info, 2);
27 DLWRAP(hsa_agent_get_info, 3);
28 DLWRAP(hsa_isa_get_info_alt, 3);
29 DLWRAP(hsa_iterate_agents, 2);
30 DLWRAP(hsa_agent_iterate_isas, 3);
31 DLWRAP(hsa_signal_create, 4);
32 DLWRAP(hsa_signal_destroy, 1);
33 DLWRAP(hsa_signal_store_relaxed, 2);
34 DLWRAP(hsa_signal_store_screlease, 2);
35 DLWRAP(hsa_signal_wait_scacquire, 5);
36 DLWRAP(hsa_queue_create, 8);
37 DLWRAP(hsa_queue_destroy, 1);
38 DLWRAP(hsa_queue_load_read_index_scacquire, 1);
39 DLWRAP(hsa_queue_add_write_index_relaxed, 2);
40 DLWRAP(hsa_memory_copy, 3);
41 DLWRAP(hsa_executable_create, 4);
42 DLWRAP(hsa_executable_destroy, 1);
43 DLWRAP(hsa_executable_freeze, 2);
44 DLWRAP(hsa_executable_symbol_get_info, 3);
45 DLWRAP(hsa_executable_iterate_symbols, 3);
46 DLWRAP(hsa_code_object_deserialize, 4);
47 DLWRAP(hsa_executable_load_code_object, 4);
48 DLWRAP(hsa_amd_agent_memory_pool_get_info, 4);
49 DLWRAP(hsa_amd_agent_iterate_memory_pools, 3);
50 DLWRAP(hsa_amd_memory_pool_allocate, 4);
51 DLWRAP(hsa_amd_memory_pool_free, 1);
52 DLWRAP(hsa_amd_memory_async_copy, 8);
53 DLWRAP(hsa_amd_memory_pool_get_info, 3);
54 DLWRAP(hsa_amd_agents_allow_access, 4);
55 DLWRAP(hsa_amd_memory_lock, 5);
56 DLWRAP(hsa_amd_memory_unlock, 1);
57 DLWRAP(hsa_amd_memory_fill, 3);
58 DLWRAP(hsa_amd_register_system_event_handler, 2);
59 
60 DLWRAP_FINALIZE();
61 
62 #ifndef DYNAMIC_HSA_PATH
63 #define DYNAMIC_HSA_PATH "libhsa-runtime64.so"
64 #endif
65 
66 #ifndef TARGET_NAME
67 #error "Missing TARGET_NAME macro"
68 #endif
69 #define DEBUG_PREFIX "Target " GETNAME(TARGET_NAME) " RTL"
70 
checkForHSA()71 static bool checkForHSA() {
72   // return true if dlopen succeeded and all functions found
73 
74   const char *HsaLib = DYNAMIC_HSA_PATH;
75   void *DynlibHandle = dlopen(HsaLib, RTLD_NOW);
76   if (!DynlibHandle) {
77     DP("Unable to load library '%s': %s!\n", HsaLib, dlerror());
78     return false;
79   }
80 
81   for (size_t I = 0; I < dlwrap::size(); I++) {
82     const char *Sym = dlwrap::symbol(I);
83 
84     void *P = dlsym(DynlibHandle, Sym);
85     if (P == nullptr) {
86       DP("Unable to find '%s' in '%s'!\n", Sym, HsaLib);
87       return false;
88     }
89     DP("Implementing %s with dlsym(%s) -> %p\n", Sym, Sym, P);
90 
91     *dlwrap::pointer(I) = P;
92   }
93 
94   return true;
95 }
96 
hsa_init()97 hsa_status_t hsa_init() {
98   if (!checkForHSA()) {
99     return HSA_STATUS_ERROR;
100   }
101   return dlwrap_hsa_init();
102 }
103