Skip to content

Commit

Permalink
[ESI] Add option to build runtime as a static library (#7455)
Browse files Browse the repository at this point in the history
* [ESI] Add option to build runtime as a static library

* review comments

---------

Co-authored-by: Morten Borup Petersen <[email protected]>
  • Loading branch information
mortbopet and Morten Borup Petersen authored Aug 8, 2024
1 parent 12822ad commit caab217
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 22 deletions.
40 changes: 31 additions & 9 deletions lib/Dialect/ESI/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ cmake_minimum_required(VERSION 3.20)
project(ESIRuntime LANGUAGES CXX)
include(FetchContent)

set(ESI_STATIC_RUNTIME OFF CACHE BOOL "Build the ESI runtime as a static library.")
if(ESI_STATIC_RUNTIME)
message("-- Building ESI runtime as a static library.")
endif()

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
Expand All @@ -44,6 +49,10 @@ if (NOT TARGET nlohmann_json)
FetchContent_MakeAvailable(json)
endif()

if(ESI_STATIC_RUNTIME)
set(ZLIB_USE_STATIC_LIBS ON)
endif()

# We need zlib to uncompress the manifest.
find_package(ZLIB)
if(ZLIB_FOUND)
Expand All @@ -57,7 +66,11 @@ else()
)
FetchContent_MakeAvailable(ZLIB)
set(ZLIB_INCLUDE_DIR ${zlib_SOURCE_DIR} ${zlib_BINARY_DIR})
set(ZLIB_LIBRARY zlib)
if(ESI_STATIC_RUNTIME)
set(ZLIB_LIBRARY zlibstatic)
else()
set(ZLIB_LIBRARY zlib)
endif()
endif()

# In a Python wheel build, we need to install libraries to different places.
Expand Down Expand Up @@ -118,10 +131,17 @@ IF(MSVC)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS 1)
ENDIF(MSVC)

# The core API. For now, compile the backends into it directly.
add_library(ESICppRuntime SHARED
${ESICppRuntimeSources}
)
if(ESI_STATIC_RUNTIME)
add_library(ESICppRuntime STATIC
${ESICppRuntimeSources}
)
else()
add_library(ESICppRuntime SHARED
${ESICppRuntimeSources}
)
endif()
add_library(esiaccel::ESICppRuntime ALIAS ESICppRuntime)

target_include_directories(ESICppRuntime PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/cpp/include
)
Expand Down Expand Up @@ -165,10 +185,12 @@ install(TARGETS ESICppRuntime
COMPONENT ESIRuntime
)

install(IMPORTED_RUNTIME_ARTIFACTS ESICppRuntime
RUNTIME_DEPENDENCY_SET ESICppRuntime_RUNTIME_DEPS
COMPONENT ESIRuntime
)
if(NOT ESI_STATIC_RUNTIME)
install(IMPORTED_RUNTIME_ARTIFACTS ESICppRuntime
RUNTIME_DEPENDENCY_SET ESICppRuntime_RUNTIME_DEPS
COMPONENT ESIRuntime
)
endif()
install(RUNTIME_DEPENDENCY_SET ESICppRuntime_RUNTIME_DEPS
DESTINATION ${LIB_DIR}
PRE_EXCLUDE_REGEXES .*
Expand Down
7 changes: 4 additions & 3 deletions lib/Dialect/ESI/runtime/cpp/include/esi/Accelerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,16 @@ namespace registry {

// Connect to an ESI accelerator given a backend name and connection specifier.
// Alternatively, instantiate the backend directly (if you're using C++).
std::unique_ptr<AcceleratorConnection>
connect(Context &ctxt, std::string backend, std::string connection);
std::unique_ptr<AcceleratorConnection> connect(Context &ctxt,
const std::string &backend,
const std::string &connection);

namespace internal {

/// Backends can register themselves to be connected via a connection string.
using BackendCreate = std::function<std::unique_ptr<AcceleratorConnection>(
Context &, std::string)>;
void registerBackend(std::string name, BackendCreate create);
void registerBackend(const std::string &name, BackendCreate create);

// Helper struct to
template <typename TAccelerator>
Expand Down
33 changes: 23 additions & 10 deletions lib/Dialect/ESI/runtime/cpp/lib/Accelerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,22 +175,35 @@ static void loadBackend(std::string backend) {
namespace registry {
namespace internal {

static std::map<std::string, BackendCreate> backendRegistry;
void registerBackend(std::string name, BackendCreate create) {
if (backendRegistry.count(name))
class BackendRegistry {
public:
static std::map<std::string, BackendCreate> &get() {
static BackendRegistry instance;
return instance.backendRegistry;
}

private:
std::map<std::string, BackendCreate> backendRegistry;
};

void registerBackend(const std::string &name, BackendCreate create) {
auto &registry = BackendRegistry::get();
if (registry.count(name))
throw std::runtime_error("Backend already exists in registry");
backendRegistry[name] = create;
registry[name] = create;
}
} // namespace internal

std::unique_ptr<AcceleratorConnection>
connect(Context &ctxt, std::string backend, std::string connection) {
auto f = internal::backendRegistry.find(backend);
if (f == internal::backendRegistry.end()) {
std::unique_ptr<AcceleratorConnection> connect(Context &ctxt,
const std::string &backend,
const std::string &connection) {
auto &registry = internal::BackendRegistry::get();
auto f = registry.find(backend);
if (f == registry.end()) {
// If it's not already found in the registry, try to load it dynamically.
loadBackend(backend);
f = internal::backendRegistry.find(backend);
if (f == internal::backendRegistry.end())
f = registry.find(backend);
if (f == registry.end())
throw std::runtime_error("Backend '" + backend + "' not found");
}
return f->second(ctxt, connection);
Expand Down

0 comments on commit caab217

Please sign in to comment.