11a965706SJon Chesterfield //===--- amdgpu/dynamic_hsa/hsa.cpp ------------------------------- C++ -*-===//
21a965706SJon Chesterfield //
31a965706SJon Chesterfield // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41a965706SJon Chesterfield // See https://llvm.org/LICENSE.txt for license information.
51a965706SJon Chesterfield // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61a965706SJon Chesterfield //
71a965706SJon Chesterfield //===----------------------------------------------------------------------===//
81a965706SJon Chesterfield //
91a965706SJon Chesterfield // Implement subset of hsa api by calling into hsa library via dlopen
101a965706SJon Chesterfield // Does the dlopen/dlsym calls as part of the call to hsa_init
111a965706SJon Chesterfield //
121a965706SJon Chesterfield //===----------------------------------------------------------------------===//
131a965706SJon Chesterfield #include "hsa.h"
141a965706SJon Chesterfield #include "Debug.h"
151a965706SJon Chesterfield #include "dlwrap.h"
161a965706SJon Chesterfield #include "hsa_ext_amd.h"
171a965706SJon Chesterfield 
181a965706SJon Chesterfield #include <dlfcn.h>
191a965706SJon Chesterfield 
2038af5b4fSJon Chesterfield DLWRAP_INITIALIZE();
2138af5b4fSJon Chesterfield 
221a965706SJon Chesterfield DLWRAP_INTERNAL(hsa_init, 0);
231a965706SJon Chesterfield 
241a965706SJon Chesterfield DLWRAP(hsa_status_string, 2);
251a965706SJon Chesterfield DLWRAP(hsa_shut_down, 0);
26*15ed5c0aSJose Manuel Monsalve Diaz DLWRAP(hsa_system_get_info, 2);
271a965706SJon Chesterfield DLWRAP(hsa_agent_get_info, 3);
28*15ed5c0aSJose Manuel Monsalve Diaz DLWRAP(hsa_isa_get_info_alt, 3);
291a965706SJon Chesterfield DLWRAP(hsa_iterate_agents, 2);
30*15ed5c0aSJose Manuel Monsalve Diaz DLWRAP(hsa_agent_iterate_isas, 3);
311a965706SJon Chesterfield DLWRAP(hsa_signal_create, 4);
321a965706SJon Chesterfield DLWRAP(hsa_signal_destroy, 1);
331a965706SJon Chesterfield DLWRAP(hsa_signal_store_relaxed, 2);
341a965706SJon Chesterfield DLWRAP(hsa_signal_store_screlease, 2);
351a965706SJon Chesterfield DLWRAP(hsa_signal_wait_scacquire, 5);
361a965706SJon Chesterfield DLWRAP(hsa_queue_create, 8);
378cf93a35SJon Chesterfield DLWRAP(hsa_queue_destroy, 1);
381a965706SJon Chesterfield DLWRAP(hsa_queue_load_read_index_scacquire, 1);
391a965706SJon Chesterfield DLWRAP(hsa_queue_add_write_index_relaxed, 2);
401a965706SJon Chesterfield DLWRAP(hsa_memory_copy, 3);
411a965706SJon Chesterfield DLWRAP(hsa_executable_create, 4);
421a965706SJon Chesterfield DLWRAP(hsa_executable_destroy, 1);
431a965706SJon Chesterfield DLWRAP(hsa_executable_freeze, 2);
441a965706SJon Chesterfield DLWRAP(hsa_executable_symbol_get_info, 3);
451a965706SJon Chesterfield DLWRAP(hsa_executable_iterate_symbols, 3);
461a965706SJon Chesterfield DLWRAP(hsa_code_object_deserialize, 4);
471a965706SJon Chesterfield DLWRAP(hsa_executable_load_code_object, 4);
481a965706SJon Chesterfield DLWRAP(hsa_amd_agent_memory_pool_get_info, 4);
491a965706SJon Chesterfield DLWRAP(hsa_amd_agent_iterate_memory_pools, 3);
501a965706SJon Chesterfield DLWRAP(hsa_amd_memory_pool_allocate, 4);
511a965706SJon Chesterfield DLWRAP(hsa_amd_memory_pool_free, 1);
521a965706SJon Chesterfield DLWRAP(hsa_amd_memory_async_copy, 8);
531a965706SJon Chesterfield DLWRAP(hsa_amd_memory_pool_get_info, 3);
541a965706SJon Chesterfield DLWRAP(hsa_amd_agents_allow_access, 4);
55cc8dc5e2SCarlo Bertolli DLWRAP(hsa_amd_memory_lock, 5);
56cc8dc5e2SCarlo Bertolli DLWRAP(hsa_amd_memory_unlock, 1);
571a965706SJon Chesterfield DLWRAP(hsa_amd_memory_fill, 3);
581a965706SJon Chesterfield DLWRAP(hsa_amd_register_system_event_handler, 2);
591a965706SJon Chesterfield 
601a965706SJon Chesterfield DLWRAP_FINALIZE();
611a965706SJon Chesterfield 
621a965706SJon Chesterfield #ifndef DYNAMIC_HSA_PATH
631a965706SJon Chesterfield #define DYNAMIC_HSA_PATH "libhsa-runtime64.so"
641a965706SJon Chesterfield #endif
651a965706SJon Chesterfield 
661a965706SJon Chesterfield #ifndef TARGET_NAME
67a90da62aSJon Chesterfield #error "Missing TARGET_NAME macro"
681a965706SJon Chesterfield #endif
691a965706SJon Chesterfield #define DEBUG_PREFIX "Target " GETNAME(TARGET_NAME) " RTL"
701a965706SJon Chesterfield 
checkForHSA()711a965706SJon Chesterfield static bool checkForHSA() {
721a965706SJon Chesterfield   // return true if dlopen succeeded and all functions found
731a965706SJon Chesterfield 
741a965706SJon Chesterfield   const char *HsaLib = DYNAMIC_HSA_PATH;
751a965706SJon Chesterfield   void *DynlibHandle = dlopen(HsaLib, RTLD_NOW);
761a965706SJon Chesterfield   if (!DynlibHandle) {
771a965706SJon Chesterfield     DP("Unable to load library '%s': %s!\n", HsaLib, dlerror());
781a965706SJon Chesterfield     return false;
791a965706SJon Chesterfield   }
801a965706SJon Chesterfield 
811a965706SJon Chesterfield   for (size_t I = 0; I < dlwrap::size(); I++) {
821a965706SJon Chesterfield     const char *Sym = dlwrap::symbol(I);
831a965706SJon Chesterfield 
841a965706SJon Chesterfield     void *P = dlsym(DynlibHandle, Sym);
851a965706SJon Chesterfield     if (P == nullptr) {
861a965706SJon Chesterfield       DP("Unable to find '%s' in '%s'!\n", Sym, HsaLib);
871a965706SJon Chesterfield       return false;
881a965706SJon Chesterfield     }
891a965706SJon Chesterfield     DP("Implementing %s with dlsym(%s) -> %p\n", Sym, Sym, P);
901a965706SJon Chesterfield 
911a965706SJon Chesterfield     *dlwrap::pointer(I) = P;
921a965706SJon Chesterfield   }
931a965706SJon Chesterfield 
941a965706SJon Chesterfield   return true;
951a965706SJon Chesterfield }
961a965706SJon Chesterfield 
hsa_init()971a965706SJon Chesterfield hsa_status_t hsa_init() {
981a965706SJon Chesterfield   if (!checkForHSA()) {
991a965706SJon Chesterfield     return HSA_STATUS_ERROR;
1001a965706SJon Chesterfield   }
1011a965706SJon Chesterfield   return dlwrap_hsa_init();
1021a965706SJon Chesterfield }
103