Skip to content

Commit

Permalink
api to load backend libraries
Browse files Browse the repository at this point in the history
  • Loading branch information
yshekel committed Jun 2, 2024
1 parent b154b70 commit 4bb238b
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 84 deletions.
5 changes: 0 additions & 5 deletions icicle_v3/backend/cpu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ project(icicle_cpu_backend)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# TODO Yuval: handle incdir when backend is separated from frontend
# TODO Yuval: dll?

include_directories(${CMAKE_SOURCE_DIR}/include)

# device API library
add_library(icicle_cpu_device SHARED src/cpu_device_api.cpp)
target_link_libraries(icicle_cpu_device PUBLIC icicle_device)
Expand Down
21 changes: 9 additions & 12 deletions icicle_v3/backend/cuda/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,25 @@ set_gpu_env()

find_package(CUDA REQUIRED)

include_directories(include)

# TODO Yuval: handle incdir when backend is separated from frontend
# TODO Yuval: dll?
# device API library
add_library(icicle_cuda_device SHARED src/cuda_device_api.cu)
target_include_directories(icicle_cuda_device PRIVATE include)
target_link_libraries(icicle_cuda_device PUBLIC icicle_device)
# Link to CUDA
target_include_directories(icicle_cuda_device PRIVATE ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
target_link_libraries(icicle_cuda_device PRIVATE ${CUDA_LIBRARIES})
target_link_libraries(icicle_cuda_device PRIVATE ${CUDA_LIBRARIES}) # Link to CUDA

# field API library
add_library(icicle_cuda_field STATIC src/field/cuda_vec_ops.cu)
add_library(icicle_cuda_field SHARED src/field/cuda_vec_ops.cu)
target_include_directories(icicle_cuda_field PRIVATE include)
target_link_libraries(icicle_cuda_field PUBLIC icicle_device icicle_field)
set_target_properties(icicle_cuda_field PROPERTIES OUTPUT_NAME "icicle_cuda_field_${FIELD}")
# Link to CUDA
target_include_directories(icicle_cuda_field PRIVATE ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
target_link_libraries(icicle_cuda_field PRIVATE ${CUDA_LIBRARIES})
target_link_libraries(icicle_cuda_field PRIVATE ${CUDA_LIBRARIES}) # Link to CUDA

# curve API library
add_library(icicle_cuda_curve STATIC src/curve/cuda_msm.cu)
add_library(icicle_cuda_curve SHARED src/curve/cuda_msm.cu)
target_include_directories(icicle_cuda_curve PRIVATE include)
target_link_libraries(icicle_cuda_curve PUBLIC icicle_device icicle_curve)
set_target_properties(icicle_cuda_curve PROPERTIES OUTPUT_NAME "icicle_cuda_curve_${FIELD}")
# Link to CUDA
target_include_directories(icicle_cuda_curve PRIVATE ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
target_link_libraries(icicle_cuda_curve PRIVATE ${CUDA_LIBRARIES})
target_link_libraries(icicle_cuda_curve PRIVATE ${CUDA_LIBRARIES}) # Link to CUDA
9 changes: 9 additions & 0 deletions icicle_v3/include/icicle/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@

using namespace icicle;

/**
* @brief Search and load icicle backed to process
*
* @param path Path of the backend library or directory where backend libraries are installed
* @return eIcicleError Status of the loaded backend
*/
extern "C" eIcicleError icicle_load_backend(const std::string& path);

/**
* @brief Set active device for thread
*
Expand Down
66 changes: 65 additions & 1 deletion icicle_v3/src/runtime.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
#include "icicle/runtime.h"
#include <iostream>
#include <dlfcn.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string>

#include "icicle/runtime.h"
#include "icicle/device_api.h"
#include "icicle/errors.h"
Expand Down Expand Up @@ -68,3 +73,62 @@ extern "C" eIcicleError icicle_destroy_stream(icicleStreamHandle stream)
{
return DeviceAPI::get_thread_local_deviceAPI()->destroy_stream(stream);
}

// Determine the shared library extension based on the operating system
#ifdef __linux__
const std::string SHARED_LIB_EXTENSION = ".so";
#elif __APPLE__
const std::string SHARED_LIB_EXTENSION = ".dylib";
#else
#error "Unsupported operating system"
#endif

extern "C" eIcicleError icicle_load_backend(const std::string& path)
{
auto is_shared_library = [](const std::string& filename) {
return filename.size() >= SHARED_LIB_EXTENSION.size() &&
filename.compare(
filename.size() - SHARED_LIB_EXTENSION.size(), SHARED_LIB_EXTENSION.size(), SHARED_LIB_EXTENSION) == 0;
};

auto load_library = [](const std::string& filePath) {
std::cout << "Attempting load: " << filePath << std::endl;
void* handle = dlopen(filePath.c_str(), RTLD_LAZY | RTLD_GLOBAL);
if (!handle) { std::cerr << "Failed to load " << filePath << ": " << dlerror() << std::endl; }
};

struct stat pathStat;
if (stat(path.c_str(), &pathStat) != 0) {
std::cerr << "Cannot access path: " << path << std::endl;
return eIcicleError::INVALID_ARGUMENT;
}

if (S_ISDIR(pathStat.st_mode)) {
// Path is a directory, recursively search for libraries
DIR* dir = opendir(path.c_str());
if (!dir) {
std::cerr << "Cannot open directory: " << path << std::endl;
return eIcicleError::INVALID_ARGUMENT;
}

struct dirent* entry;
while ((entry = readdir(dir)) != nullptr) {
std::string entryPath = path + "/" + entry->d_name;

// Skip "." and ".." entries
if (std::string(entry->d_name) == "." || std::string(entry->d_name) == "..") { continue; }

// Recurse into subdirectories and load libraries in files
icicle_load_backend(entryPath);
}

closedir(dir);
} else if (S_ISREG(pathStat.st_mode)) {
// Path is a regular file, check if it is a shared library and load it
if (is_shared_library(path)) { load_library(path); }
} else {
std::cerr << "Unsupported file type: " << path << std::endl;
}

return eIcicleError::SUCCESS;
}
29 changes: 1 addition & 28 deletions icicle_v3/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@

message("icicle_v3 tests enabled")

include(GoogleTest)
include(FetchContent)
FetchContent_Declare(
Expand All @@ -9,23 +7,9 @@ FetchContent_Declare(
)

# For Windows: Prevent overriding the parent project's compiler/linker settings

set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

# Force load backend libraries even though they the symbols are not referenced by icicle or the app
# TODO Yuval: implement dynamic loading and avoid this compiler specific thing
# message("CMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}")
# set(FORCE_LOAD_START "")
# set(FORCE_LOAD_END "")
# if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
# set(FORCE_LOAD_START "-Wl,-force_load")
# elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# set(FORCE_LOAD_START "-Wl,--whole-archive")
# set(FORCE_LOAD_END "-Wl,--no-whole-archive")
# else()
# message(FATAL_ERROR "This CMake configuration only supports Clang and GCC.")
# endif()

# device API test
add_executable(test_device_api test_device_api.cpp)
Expand All @@ -43,18 +27,7 @@ target_include_directories(test_curve_api PUBLIC ${CMAKE_SOURCE_DIR}/include/)
target_link_libraries(test_curve_api PUBLIC GTest::gtest_main icicle_device icicle_field icicle_curve)


if(BUILD_CPU_BE)
target_link_libraries(test_device_api PUBLIC icicle_cpu_device dl)
target_link_libraries(test_field_api PUBLIC icicle_cpu_device icicle_cpu_field dl)
target_link_libraries(test_curve_api PUBLIC icicle_cpu_device icicle_cpu_curve dl)
endif()

if(BUILD_CUDA_BE)
target_link_libraries(test_device_api PUBLIC icicle_cuda_device dl)
target_link_libraries(test_field_api PUBLIC icicle_cuda_device icicle_cuda_field dl)
target_link_libraries(test_curve_api PUBLIC icicle_cuda_device icicle_cuda_curve dl)
endif()

add_compile_definitions(BACKEND_BUILD_DIR="${CMAKE_BINARY_DIR}/backend")

enable_testing()
gtest_discover_tests(test_device_api)
Expand Down
18 changes: 1 addition & 17 deletions icicle_v3/tests/test_curve_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,7 @@ class CurveApiTest : public ::testing::Test
// SetUpTestSuite/TearDownTestSuite are called once for the entire test suite
static void SetUpTestSuite()
{
dlopen(
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cpu/libicicle_cpu_device.so",
RTLD_LAZY | RTLD_NOW);
dlopen(
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cpu/libicicle_cpu_curve_bn254.so",
RTLD_LAZY | RTLD_NOW);
dlopen(
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cpu/libicicle_cpu_field_bn254.so",
RTLD_LAZY | RTLD_NOW);

dlopen(
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cuda/libicicle_cuda_device.so",
RTLD_LAZY | RTLD_NOW);
dlopen(
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cuda/libicicle_cuda_curve_bn254.so",
RTLD_LAZY | RTLD_NOW);

icicle_load_backend(BACKEND_BUILD_DIR);
s_regsitered_devices = get_registered_devices();
ASSERT_GT(s_regsitered_devices.size(), 0);
}
Expand Down
8 changes: 1 addition & 7 deletions icicle_v3/tests/test_device_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@ class DeviceApiTest : public ::testing::Test
// SetUpTestSuite/TearDownTestSuite are called once for the entire test suite
static void SetUpTestSuite()
{
// dlopen(
// "/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cpu/libicicle_cpu_device.so",
// RTLD_LAZY | RTLD_NOW);
// dlopen(
// "/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cuda/libicicle_cuda_device.so",
// RTLD_LAZY | RTLD_NOW);

icicle_load_backend(BACKEND_BUILD_DIR);
s_regsitered_devices = get_registered_devices();
ASSERT_GT(s_regsitered_devices.size(), 0);
}
Expand Down
15 changes: 1 addition & 14 deletions icicle_v3/tests/test_field_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,7 @@ class FieldApiTest : public ::testing::Test
// SetUpTestSuite/TearDownTestSuite are called once for the entire test suite
static void SetUpTestSuite()
{
dlopen(
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cpu/libicicle_cpu_device.so",
RTLD_LAZY | RTLD_NOW);
dlopen(
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cpu/libicicle_cpu_field_bn254.so",
RTLD_LAZY | RTLD_NOW);

dlopen(
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cuda/libicicle_cuda_device.so",
RTLD_LAZY | RTLD_NOW);
dlopen(
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cuda/libicicle_cuda_field_bn254.so",
RTLD_LAZY | RTLD_NOW);

icicle_load_backend(BACKEND_BUILD_DIR);
s_regsitered_devices = get_registered_devices();
ASSERT_GT(s_regsitered_devices.size(), 0);
}
Expand Down

0 comments on commit 4bb238b

Please sign in to comment.