Skip to content

Commit b5fb056

Browse files
committed
Fix cache simulation usages
1 parent d3c3ad7 commit b5fb056

File tree

7 files changed

+517
-50
lines changed

7 files changed

+517
-50
lines changed

CMakeLists.txt

Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
cmake_minimum_required(VERSION 3.15...3.27)
22
project(libCacheSim-python)
33
set(DESCRIPTION "The libCacheSim Python Package")
4-
set(PROJECT_WEB "http://cachemon.github.io/libCacheSim-python")
4+
set(PROJECT_WEB "https://docs.libcachesim.com/python")
55

6-
# Auto-initialize submodules if not already done
6+
# Options from the libCacheSim library
7+
option(ENABLE_GLCACHE "enable group-learned cache" ON)
8+
option(ENABLE_LRB "enable LRB" ON)
9+
option(ENABLE_3L_CACHE "enable 3LCache" ON)
10+
11+
if(NOT CMAKE_BUILD_TYPE)
12+
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Debug" FORCE)
13+
endif()
14+
15+
message(STATUS "CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}")
16+
17+
# 1. Auto-initialize submodules if not already done
718
find_package(Git QUIET)
819
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
920
# Check if submodule is initialized
@@ -18,33 +29,31 @@ if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
1829
endif()
1930
endif()
2031

21-
# Auto-build libCacheSim if needed
32+
# 2. Auto-build libCacheSim if needed
2233
set(LIBCACHESIM_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/libCacheSim")
2334
if(NOT EXISTS "${LIBCACHESIM_SOURCE_DIR}/CMakeLists.txt")
2435
message(FATAL_ERROR "libCacheSim submodule not found. Please run 'git submodule update --init --recursive'")
2536
endif()
2637

2738
# Build libCacheSim first
2839
set(LIBCACHESIM_BUILD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/libCacheSim/build")
29-
if(NOT EXISTS "${LIBCACHESIM_BUILD_DIR}/export_vars.cmake")
30-
message(STATUS "Building libCacheSim...")
31-
execute_process(
32-
COMMAND ${CMAKE_COMMAND} -S ${LIBCACHESIM_SOURCE_DIR} -B ${LIBCACHESIM_BUILD_DIR} -G Ninja
33-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
34-
RESULT_VARIABLE CMAKE_CONFIG_RESULT
35-
)
36-
if(NOT CMAKE_CONFIG_RESULT EQUAL "0")
37-
message(FATAL_ERROR "Failed to configure libCacheSim")
38-
endif()
40+
message(STATUS "Building libCacheSim...")
41+
execute_process(
42+
COMMAND ${CMAKE_COMMAND} -S ${LIBCACHESIM_SOURCE_DIR} -B ${LIBCACHESIM_BUILD_DIR} -G Ninja -DENABLE_LRB=${ENABLE_LRB} -DENABLE_GLCACHE=${ENABLE_GLCACHE} -DENABLE_3L_CACHE=${ENABLE_3L_CACHE} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
43+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
44+
RESULT_VARIABLE CMAKE_CONFIG_RESULT
45+
)
46+
if(NOT CMAKE_CONFIG_RESULT EQUAL "0")
47+
message(FATAL_ERROR "Failed to configure libCacheSim")
48+
endif()
3949

40-
execute_process(
41-
COMMAND ${CMAKE_COMMAND} --build ${LIBCACHESIM_BUILD_DIR}
42-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
43-
RESULT_VARIABLE CMAKE_BUILD_RESULT
44-
)
45-
if(NOT CMAKE_BUILD_RESULT EQUAL "0")
46-
message(FATAL_ERROR "Failed to build libCacheSim")
47-
endif()
50+
execute_process(
51+
COMMAND ${CMAKE_COMMAND} --build ${LIBCACHESIM_BUILD_DIR}
52+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
53+
RESULT_VARIABLE CMAKE_BUILD_RESULT
54+
)
55+
if(NOT CMAKE_BUILD_RESULT EQUAL "0")
56+
message(FATAL_ERROR "Failed to build libCacheSim")
4857
endif()
4958

5059
# Note(haocheng): now we still utilize the exported cache from
@@ -100,6 +109,34 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
100109
find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
101110
find_package(pybind11 CONFIG REQUIRED)
102111

112+
set(optional_dependency_libs "")
113+
114+
# Find optional deps
115+
if(ENABLE_GLCACHE)
116+
find_package(xgboost REQUIRED)
117+
include_directories(${XGBOOST_INCLUDE_DIR})
118+
list(APPEND optional_dependency_libs xgboost::xgboost)
119+
add_compile_definitions(ENABLE_GLCACHE=1)
120+
message(STATUS "XGBOOST_INCLUDE_DIR=${XGBOOST_INCLUDE_DIR}")
121+
endif()
122+
123+
foreach(FEATURE ENABLE_LRB ENABLE_3L_CACHE)
124+
if(${FEATURE})
125+
find_path(LIGHTGBM_PATH LightGBM)
126+
if(NOT LIGHTGBM_PATH)
127+
message(FATAL_ERROR "LIGHTGBM_PATH not found")
128+
endif()
129+
# include_directories(${LIGHTGBM_PATH})
130+
131+
find_library(LIGHTGBM_LIB _lightgbm)
132+
if(NOT LIGHTGBM_LIB)
133+
message(FATAL_ERROR "LIGHTGBM_LIB not found")
134+
endif()
135+
list(APPEND optional_dependency_libs ${LIGHTGBM_LIB})
136+
add_compile_definitions(${FEATURE}=1)
137+
endif()
138+
endforeach()
139+
103140
# Include directories for dependencies
104141
include_directories(${GLib_INCLUDE_DIRS})
105142
include_directories(${GLib_CONFIG_INCLUDE_DIR})
@@ -160,6 +197,7 @@ target_link_libraries(libcachesim_python PRIVATE
160197
pybind11::module
161198
${GLib_LIBRARIES}
162199
${ZSTD_LIBRARIES}
200+
${optional_dependency_libs}
163201
)
164202

165203
# Add platform-specific link options and libraries

libcachesim/cache.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ def __init__(
281281
_cache=LIRS_init(_create_common_params(cache_size, default_ttl, hashpower, consider_obj_metadata))
282282
)
283283

284+
def insert(self, req: Request) -> Optional[CacheObject]:
285+
return super().insert(req)
284286

285287
class TwoQ(CacheBase):
286288
"""2Q replacement algorithm
@@ -360,7 +362,7 @@ def __init__(
360362
update_weight: bool = True,
361363
lru_weight: float = 0.5,
362364
):
363-
cache_specific_params = f"update-weight={update_weight}, lru-weight={lru_weight}"
365+
cache_specific_params = f"update-weight={int(update_weight)}, lru-weight={lru_weight}"
364366
super().__init__(
365367
_cache=LeCaR_init(
366368
_create_common_params(cache_size, default_ttl, hashpower, consider_obj_metadata), cache_specific_params
@@ -383,7 +385,7 @@ class ClockPro(CacheBase):
383385
"""Clock-Pro replacement algorithm
384386
385387
Special parameters:
386-
init_req: initial reference count (default: 0)
388+
init_ref: initial reference count (default: 0)
387389
init_ratio_cold: initial ratio of cold pages (default: 1)
388390
"""
389391

@@ -393,10 +395,10 @@ def __init__(
393395
default_ttl: int = 86400 * 300,
394396
hashpower: int = 24,
395397
consider_obj_metadata: bool = False,
396-
init_req: int = 0,
398+
init_ref: int = 0,
397399
init_ratio_cold: float = 0.5,
398400
):
399-
cache_specific_params = f"init-req={init_req}, init-ratio-cold={init_ratio_cold}"
401+
cache_specific_params = f"init-ref={init_ref}, init-ratio-cold={init_ratio_cold}"
400402
super().__init__(
401403
_cache=ClockPro_init(
402404
_create_common_params(cache_size, default_ttl, hashpower, consider_obj_metadata), cache_specific_params
@@ -451,13 +453,19 @@ def __init__(
451453

452454

453455
class LRUProb(CacheBase):
454-
"""LRU with Probabilistic Replacement (no special parameters)"""
456+
"""LRU with Probabilistic Replacement
457+
458+
Special parameters:
459+
prob: probability of promoting an object to the head of the queue (default: 0.5)
460+
"""
455461

456462
def __init__(
457-
self, cache_size: int, default_ttl: int = 86400 * 300, hashpower: int = 24, consider_obj_metadata: bool = False
463+
self, cache_size: int, default_ttl: int = 86400 * 300, hashpower: int = 24, consider_obj_metadata: bool = False,
464+
prob: float = 0.5,
458465
):
466+
cache_specific_params = f"prob={prob}"
459467
super().__init__(
460-
_cache=LRU_Prob_init(_create_common_params(cache_size, default_ttl, hashpower, consider_obj_metadata))
468+
_cache=LRU_Prob_init(_create_common_params(cache_size, default_ttl, hashpower, consider_obj_metadata), cache_specific_params)
461469
)
462470

463471

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ environment = { LCS_BUILD_DIR = "{project}/src/libCacheSim/build", MACOSX_DEPLOY
8686
test-command = "python -c 'import libcachesim; print(\"Import successful\")'"
8787

8888
[tool.cibuildwheel.linux]
89-
before-all = "yum install -y yum-utils && yum-config-manager --set-enabled crb && yum install -y ninja-build cmake libzstd-devel glib2-devel"
89+
before-all = "yum install -y yum-utils && yum-config-manager --set-enabled crb && yum install -y ninja-build cmake libzstd-devel glib2-devel xgboost-devel lightgbm-devel"
9090
before-build = "pip install pybind11 && git submodule update --init --recursive && python {project}/scripts/smart_build.py"
9191

9292
[tool.cibuildwheel.macos]

scripts/install.sh

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
git submodule update --init --recursive
2+
# Sync submodules
3+
git submodule update --recursive --remote
24

3-
# Build the main libCacheSim C++ library first
4-
echo "Building main libCacheSim library..."
5-
pushd src/libCacheSim
6-
bash scripts/install_dependency.sh
7-
rm -rf build
8-
cmake -G Ninja -B build
9-
ninja -C build
10-
popd
115

126
# Now build and install the Python binding
137
echo "Building Python binding..."

src/export_cache.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ auto make_cache_wrapper(const std::string& fn_name) {
256256
cache_t* ptr = InitFn(cc_params, params_cstr);
257257
return std::unique_ptr<cache_t, CacheDeleter>(ptr);
258258
},
259-
"cc_params"_a, "cache_specific_params"_a = "");
259+
"cc_params"_a, "cache_specific_params"_a = "");
260260
};
261261
}
262262

@@ -280,7 +280,8 @@ void export_cache(py::module& m) {
280280
.def(
281281
"find",
282282
[](cache_t& self, const request_t& req, const bool update_cache) {
283-
return self.find(&self, &req, update_cache);
283+
cache_obj_t* obj = self.find(&self, &req, update_cache);
284+
return py::cast(obj, py::return_value_policy::reference);
284285
},
285286
"req"_a, "update_cache"_a = true)
286287
.def(
@@ -289,16 +290,23 @@ void export_cache(py::module& m) {
289290
return self.can_insert(&self, &req);
290291
},
291292
"req"_a)
292-
.def(
293-
"insert",
294-
[](cache_t& self, const request_t& req) {
295-
return self.insert(&self, &req);
296-
},
297-
"req"_a)
293+
.def(
294+
"insert",
295+
[](cache_t& self, const request_t& req) -> std::optional<cache_obj_t*> {
296+
cache_obj_t* inserted = self.insert(&self, &req);
297+
if (inserted == nullptr) {
298+
return std::nullopt;
299+
}
300+
return inserted;
301+
},
302+
"req"_a,
303+
py::return_value_policy::reference // optional still respected
304+
)
305+
298306
.def(
299307
"need_eviction",
300308
[](cache_t& self, const request_t& req) {
301-
return self.need_eviction(&self, &req);
309+
return self.get_occupied_byte(&self) + req.obj_size > self.cache_size;
302310
},
303311
"req"_a)
304312
.def(
@@ -316,7 +324,8 @@ void export_cache(py::module& m) {
316324
.def(
317325
"to_evict",
318326
[](cache_t& self, const request_t& req) {
319-
return self.to_evict(&self, &req);
327+
cache_obj_t* obj = self.to_evict(&self, &req);
328+
return py::cast(obj, py::return_value_policy::reference);
320329
},
321330
"req"_a)
322331
.def("get_occupied_byte",
@@ -348,7 +357,7 @@ void export_cache(py::module& m) {
348357
params->default_ttl = default_ttl;
349358
params->hashpower = hashpower;
350359
params->consider_obj_metadata = consider_obj_metadata;
351-
return params;
360+
return std::unique_ptr<common_cache_params_t, CommonCacheParamsDeleter>(params);
352361
}),
353362
"cache_size"_a, "default_ttl"_a = 86400 * 300, "hashpower"_a = 24,
354363
"consider_obj_metadata"_a = false)
@@ -407,7 +416,7 @@ void export_cache(py::module& m) {
407416
req->hv = hv;
408417
req->next_access_vtime = next_access_vtime;
409418
req->ttl = ttl;
410-
return req;
419+
return std::unique_ptr<request_t, RequestDeleter>(req);
411420
}),
412421
"obj_size"_a = 1, "op"_a = OP_NOP, "valid"_a = true, "obj_id"_a = 0,
413422
"clock_time"_a = 0, "hv"_a = 0, "next_access_vtime"_a = -2,

0 commit comments

Comments
 (0)