Skip to content

Commit 4bb238b

Browse files
committed
api to load backend libraries
1 parent b154b70 commit 4bb238b

File tree

8 files changed

+87
-84
lines changed

8 files changed

+87
-84
lines changed

icicle_v3/backend/cpu/CMakeLists.txt

-5
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@ project(icicle_cpu_backend)
66
set(CMAKE_CXX_STANDARD 17)
77
set(CMAKE_CXX_STANDARD_REQUIRED True)
88

9-
# TODO Yuval: handle incdir when backend is separated from frontend
10-
# TODO Yuval: dll?
11-
12-
include_directories(${CMAKE_SOURCE_DIR}/include)
13-
149
# device API library
1510
add_library(icicle_cpu_device SHARED src/cpu_device_api.cpp)
1611
target_link_libraries(icicle_cpu_device PUBLIC icicle_device)

icicle_v3/backend/cuda/CMakeLists.txt

+9-12
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,25 @@ set_gpu_env()
99

1010
find_package(CUDA REQUIRED)
1111

12-
include_directories(include)
13-
14-
# TODO Yuval: handle incdir when backend is separated from frontend
15-
# TODO Yuval: dll?
12+
# device API library
1613
add_library(icicle_cuda_device SHARED src/cuda_device_api.cu)
14+
target_include_directories(icicle_cuda_device PRIVATE include)
1715
target_link_libraries(icicle_cuda_device PUBLIC icicle_device)
18-
# Link to CUDA
1916
target_include_directories(icicle_cuda_device PRIVATE ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
20-
target_link_libraries(icicle_cuda_device PRIVATE ${CUDA_LIBRARIES})
17+
target_link_libraries(icicle_cuda_device PRIVATE ${CUDA_LIBRARIES}) # Link to CUDA
2118

2219
# field API library
23-
add_library(icicle_cuda_field STATIC src/field/cuda_vec_ops.cu)
20+
add_library(icicle_cuda_field SHARED src/field/cuda_vec_ops.cu)
21+
target_include_directories(icicle_cuda_field PRIVATE include)
2422
target_link_libraries(icicle_cuda_field PUBLIC icicle_device icicle_field)
2523
set_target_properties(icicle_cuda_field PROPERTIES OUTPUT_NAME "icicle_cuda_field_${FIELD}")
26-
# Link to CUDA
2724
target_include_directories(icicle_cuda_field PRIVATE ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
28-
target_link_libraries(icicle_cuda_field PRIVATE ${CUDA_LIBRARIES})
25+
target_link_libraries(icicle_cuda_field PRIVATE ${CUDA_LIBRARIES}) # Link to CUDA
2926

3027
# curve API library
31-
add_library(icicle_cuda_curve STATIC src/curve/cuda_msm.cu)
28+
add_library(icicle_cuda_curve SHARED src/curve/cuda_msm.cu)
29+
target_include_directories(icicle_cuda_curve PRIVATE include)
3230
target_link_libraries(icicle_cuda_curve PUBLIC icicle_device icicle_curve)
3331
set_target_properties(icicle_cuda_curve PROPERTIES OUTPUT_NAME "icicle_cuda_curve_${FIELD}")
34-
# Link to CUDA
3532
target_include_directories(icicle_cuda_curve PRIVATE ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
36-
target_link_libraries(icicle_cuda_curve PRIVATE ${CUDA_LIBRARIES})
33+
target_link_libraries(icicle_cuda_curve PRIVATE ${CUDA_LIBRARIES}) # Link to CUDA

icicle_v3/include/icicle/runtime.h

+9
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77

88
using namespace icicle;
99

10+
/**
11+
* @brief Search and load icicle backed to process
12+
*
13+
14+
* @param path Path of the backend library or directory where backend libraries are installed
15+
* @return eIcicleError Status of the loaded backend
16+
*/
17+
extern "C" eIcicleError icicle_load_backend(const std::string& path);
18+
1019
/**
1120
* @brief Set active device for thread
1221
*

icicle_v3/src/runtime.cpp

+65-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
#include "icicle/runtime.h"
1+
#include <iostream>
2+
#include <dlfcn.h>
3+
#include <dirent.h>
4+
#include <sys/stat.h>
5+
#include <string>
6+
27
#include "icicle/runtime.h"
38
#include "icicle/device_api.h"
49
#include "icicle/errors.h"
@@ -68,3 +73,62 @@ extern "C" eIcicleError icicle_destroy_stream(icicleStreamHandle stream)
6873
{
6974
return DeviceAPI::get_thread_local_deviceAPI()->destroy_stream(stream);
7075
}
76+
77+
// Determine the shared library extension based on the operating system
78+
#ifdef __linux__
79+
const std::string SHARED_LIB_EXTENSION = ".so";
80+
#elif __APPLE__
81+
const std::string SHARED_LIB_EXTENSION = ".dylib";
82+
#else
83+
#error "Unsupported operating system"
84+
#endif
85+
86+
extern "C" eIcicleError icicle_load_backend(const std::string& path)
87+
{
88+
auto is_shared_library = [](const std::string& filename) {
89+
return filename.size() >= SHARED_LIB_EXTENSION.size() &&
90+
filename.compare(
91+
filename.size() - SHARED_LIB_EXTENSION.size(), SHARED_LIB_EXTENSION.size(), SHARED_LIB_EXTENSION) == 0;
92+
};
93+
94+
auto load_library = [](const std::string& filePath) {
95+
std::cout << "Attempting load: " << filePath << std::endl;
96+
void* handle = dlopen(filePath.c_str(), RTLD_LAZY | RTLD_GLOBAL);
97+
if (!handle) { std::cerr << "Failed to load " << filePath << ": " << dlerror() << std::endl; }
98+
};
99+
100+
struct stat pathStat;
101+
if (stat(path.c_str(), &pathStat) != 0) {
102+
std::cerr << "Cannot access path: " << path << std::endl;
103+
return eIcicleError::INVALID_ARGUMENT;
104+
}
105+
106+
if (S_ISDIR(pathStat.st_mode)) {
107+
// Path is a directory, recursively search for libraries
108+
DIR* dir = opendir(path.c_str());
109+
if (!dir) {
110+
std::cerr << "Cannot open directory: " << path << std::endl;
111+
return eIcicleError::INVALID_ARGUMENT;
112+
}
113+
114+
struct dirent* entry;
115+
while ((entry = readdir(dir)) != nullptr) {
116+
std::string entryPath = path + "/" + entry->d_name;
117+
118+
// Skip "." and ".." entries
119+
if (std::string(entry->d_name) == "." || std::string(entry->d_name) == "..") { continue; }
120+
121+
// Recurse into subdirectories and load libraries in files
122+
icicle_load_backend(entryPath);
123+
}
124+
125+
closedir(dir);
126+
} else if (S_ISREG(pathStat.st_mode)) {
127+
// Path is a regular file, check if it is a shared library and load it
128+
if (is_shared_library(path)) { load_library(path); }
129+
} else {
130+
std::cerr << "Unsupported file type: " << path << std::endl;
131+
}
132+
133+
return eIcicleError::SUCCESS;
134+
}

icicle_v3/tests/CMakeLists.txt

+1-28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11

2-
message("icicle_v3 tests enabled")
3-
42
include(GoogleTest)
53
include(FetchContent)
64
FetchContent_Declare(
@@ -9,23 +7,9 @@ FetchContent_Declare(
97
)
108

119
# For Windows: Prevent overriding the parent project's compiler/linker settings
12-
1310
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
1411
FetchContent_MakeAvailable(googletest)
1512

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

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

4529

46-
if(BUILD_CPU_BE)
47-
target_link_libraries(test_device_api PUBLIC icicle_cpu_device dl)
48-
target_link_libraries(test_field_api PUBLIC icicle_cpu_device icicle_cpu_field dl)
49-
target_link_libraries(test_curve_api PUBLIC icicle_cpu_device icicle_cpu_curve dl)
50-
endif()
51-
52-
if(BUILD_CUDA_BE)
53-
target_link_libraries(test_device_api PUBLIC icicle_cuda_device dl)
54-
target_link_libraries(test_field_api PUBLIC icicle_cuda_device icicle_cuda_field dl)
55-
target_link_libraries(test_curve_api PUBLIC icicle_cuda_device icicle_cuda_curve dl)
56-
endif()
57-
30+
add_compile_definitions(BACKEND_BUILD_DIR="${CMAKE_BINARY_DIR}/backend")
5831

5932
enable_testing()
6033
gtest_discover_tests(test_device_api)

icicle_v3/tests/test_curve_api.cpp

+1-17
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,7 @@ class CurveApiTest : public ::testing::Test
3030
// SetUpTestSuite/TearDownTestSuite are called once for the entire test suite
3131
static void SetUpTestSuite()
3232
{
33-
dlopen(
34-
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cpu/libicicle_cpu_device.so",
35-
RTLD_LAZY | RTLD_NOW);
36-
dlopen(
37-
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cpu/libicicle_cpu_curve_bn254.so",
38-
RTLD_LAZY | RTLD_NOW);
39-
dlopen(
40-
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cpu/libicicle_cpu_field_bn254.so",
41-
RTLD_LAZY | RTLD_NOW);
42-
43-
dlopen(
44-
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cuda/libicicle_cuda_device.so",
45-
RTLD_LAZY | RTLD_NOW);
46-
dlopen(
47-
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cuda/libicicle_cuda_curve_bn254.so",
48-
RTLD_LAZY | RTLD_NOW);
49-
33+
icicle_load_backend(BACKEND_BUILD_DIR);
5034
s_regsitered_devices = get_registered_devices();
5135
ASSERT_GT(s_regsitered_devices.size(), 0);
5236
}

icicle_v3/tests/test_device_api.cpp

+1-7
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,7 @@ class DeviceApiTest : public ::testing::Test
1414
// SetUpTestSuite/TearDownTestSuite are called once for the entire test suite
1515
static void SetUpTestSuite()
1616
{
17-
// dlopen(
18-
// "/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cpu/libicicle_cpu_device.so",
19-
// RTLD_LAZY | RTLD_NOW);
20-
// dlopen(
21-
// "/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cuda/libicicle_cuda_device.so",
22-
// RTLD_LAZY | RTLD_NOW);
23-
17+
icicle_load_backend(BACKEND_BUILD_DIR);
2418
s_regsitered_devices = get_registered_devices();
2519
ASSERT_GT(s_regsitered_devices.size(), 0);
2620
}

icicle_v3/tests/test_field_api.cpp

+1-14
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,7 @@ class FieldApiTest : public ::testing::Test
3030
// SetUpTestSuite/TearDownTestSuite are called once for the entire test suite
3131
static void SetUpTestSuite()
3232
{
33-
dlopen(
34-
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cpu/libicicle_cpu_device.so",
35-
RTLD_LAZY | RTLD_NOW);
36-
dlopen(
37-
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cpu/libicicle_cpu_field_bn254.so",
38-
RTLD_LAZY | RTLD_NOW);
39-
40-
dlopen(
41-
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cuda/libicicle_cuda_device.so",
42-
RTLD_LAZY | RTLD_NOW);
43-
dlopen(
44-
"/home/administrator/users/yuvals/icicle/icicle_v3/build/backend/cuda/libicicle_cuda_field_bn254.so",
45-
RTLD_LAZY | RTLD_NOW);
46-
33+
icicle_load_backend(BACKEND_BUILD_DIR);
4734
s_regsitered_devices = get_registered_devices();
4835
ASSERT_GT(s_regsitered_devices.size(), 0);
4936
}

0 commit comments

Comments
 (0)