Skip to content

Commit 1ea457a

Browse files
authored
Set default backends path (#924)
* Set backends default path on module load, so it can be retrieved with ai.config get command. * Use server shutdown event to clean up global backends path (instead of limiting its size)
1 parent 5e4517d commit 1ea457a

File tree

8 files changed

+50
-53
lines changed

8 files changed

+50
-53
lines changed

src/backends/backends.c

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -92,33 +92,17 @@ int RAI_ExportFunc(const char *func_name, void **targetFuncPtr) {
9292
return REDISMODULE_OK;
9393
}
9494

95-
RedisModuleString *RAI_GetModulePath(RedisModuleCtx *ctx) {
95+
void RAI_SetBackendsDefaultPath(char **backends_path) {
96+
RedisModule_Assert(*backends_path == NULL);
9697
Dl_info info;
97-
RedisModuleString *module_path = NULL;
98-
if (dladdr(RAI_GetModulePath, &info)) {
99-
char *dli_fname = RedisModule_Strdup(info.dli_fname);
100-
const char *dli_dirname = dirname(dli_fname);
101-
module_path = RedisModule_CreateString(ctx, dli_dirname, strlen(dli_dirname));
102-
RedisModule_Free(dli_fname);
103-
}
104-
105-
return module_path;
106-
}
107-
108-
RedisModuleString *RAI_GetBackendsPath(RedisModuleCtx *ctx) {
109-
Dl_info info;
110-
RedisModuleString *backends_path = NULL;
111-
if (Config_GetBackendsPath() != NULL) {
112-
backends_path = RedisModule_CreateString(ctx, Config_GetBackendsPath(),
113-
strlen(Config_GetBackendsPath()));
114-
} else {
115-
RedisModuleString *module_path = RAI_GetModulePath(ctx);
116-
backends_path = RedisModule_CreateStringPrintf(ctx, "%s/backends",
117-
RedisModule_StringPtrLen(module_path, NULL));
118-
RedisModule_FreeString(ctx, module_path);
119-
}
120-
121-
return backends_path;
98+
// Retrieve the info about the module's dynamic library, and extract the .so file dir name.
99+
RedisModule_Assert(dladdr(RAI_SetBackendsDefaultPath, &info) != 0);
100+
const char *dyn_lib_dir_name = dirname((char *)info.dli_fname);
101+
102+
// Populate backends_path global string with the default path.
103+
size_t backends_default_path_len = strlen(dyn_lib_dir_name) + strlen("/backends");
104+
*backends_path = RedisModule_Alloc(backends_default_path_len + 1);
105+
RedisModule_Assert(sprintf(*backends_path, "%s/backends", dyn_lib_dir_name) > 0);
122106
}
123107

124108
const char *RAI_GetBackendName(RAI_Backend backend) {
@@ -460,10 +444,8 @@ int RAI_LoadBackend(RedisModuleCtx *ctx, int backend, const char *path) {
460444
if (path[0] == '/') {
461445
fullpath = RedisModule_CreateString(ctx, path, strlen(path));
462446
} else {
463-
RedisModuleString *backends_path = RAI_GetBackendsPath(ctx);
464-
fullpath = RedisModule_CreateStringPrintf(
465-
ctx, "%s/%s", RedisModule_StringPtrLen(backends_path, NULL), path);
466-
RedisModule_FreeString(ctx, backends_path);
447+
const char *backends_path = Config_GetBackendsPath();
448+
fullpath = RedisModule_CreateStringPrintf(ctx, "%s/%s", backends_path, path);
467449
}
468450

469451
int ret;

src/backends/backends.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,8 @@ int RAI_LoadDefaultBackend(RedisModuleCtx *ctx, int backend);
110110
* @brief Returns the backend name as string.
111111
*/
112112
const char *RAI_GetBackendName(RAI_Backend backend);
113+
114+
/**
115+
* @brief Set the default backends path (<module_path>/backends) in backends_path place holder.
116+
*/
117+
void RAI_SetBackendsDefaultPath(char **backends_path);

src/config/config.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33
#include "redismodule.h"
44
#include "backends/backends.h"
55

6-
// Default configs
7-
char *BackendsPath = NULL; // Path to backends dir.
8-
9-
long long BackendsIntraOpParallelism = 0; // number of threads used within an
10-
// individual op for parallelism.
11-
long long BackendsInterOpParallelism = 0; // number of threads used for parallelism
12-
// between independent operations.
13-
long long ModelChunkSize = 535822336; // size of chunks used to break up model payloads.
14-
// default is 511 * 1024 * 1024
15-
long long ThreadPoolSizePerQueue = 1; // Number of working threads for device.
16-
17-
long long ModelExecutionTimeout = 5000; // The maximum time in milliseconds
18-
// before killing onnx run session.
19-
long long BackendMemoryLimit = 0; // The maximum amount of memory in MB
20-
// that backend is allowed to consume.
6+
/* Default configs: */
7+
// Path to backends dir. Default value is set when parsing load_time configs.
8+
char *BackendsPath;
9+
// Number of threads used within an individual op for parallelism.
10+
long long BackendsIntraOpParallelism = 0;
11+
// Number of threads used for parallelism between independent operations.
12+
long long BackendsInterOpParallelism = 0;
13+
// Size of chunks used to break up model payloads. Default is 511 * 1024 * 1024
14+
long long ModelChunkSize = REDISAI_DEFAULT_MODEL_CHUNK_SIZE;
15+
// Number of working threads for device.
16+
long long ThreadPoolSizePerQueue = 1;
17+
// The maximum time in milliseconds before killing onnx run session.
18+
long long ModelExecutionTimeout = 5000;
19+
// The maximum amount of memory in MB that backend is allowed to consume.
20+
long long BackendMemoryLimit = 0;
2121

2222
static int _Config_LoadTimeParamParse(RedisModuleCtx *ctx, const char *key, const char *val,
2323
RedisModuleString *rsval) {
@@ -111,9 +111,8 @@ int Config_LoadBackend(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
111111
}
112112

113113
void Config_SetBackendsPath(const char *path) {
114-
if (BackendsPath != NULL) {
115-
RedisModule_Free(BackendsPath);
116-
}
114+
RedisModule_Assert(BackendsPath != NULL && path != NULL);
115+
RedisModule_Free(BackendsPath);
117116
BackendsPath = RedisModule_Strdup(path);
118117
}
119118

@@ -188,6 +187,7 @@ int Config_SetLoadTimeParams(RedisModuleCtx *ctx, RedisModuleString *const *argv
188187
}
189188

190189
// need BACKENDSPATH set up before loading specific backends
190+
RAI_SetBackendsDefaultPath(&BackendsPath);
191191
for (int i = 0; i < argc / 2; i++) {
192192
const char *key = RedisModule_StringPtrLen(argv[2 * i], NULL);
193193
const char *val = RedisModule_StringPtrLen(argv[2 * i + 1], NULL);

src/config/config.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ typedef enum { RAI_DEVICE_CPU = 0, RAI_DEVICE_GPU = 1 } RAI_Device;
2828
#define REDISAI_INFOMSG_MODEL_EXECUTION_TIMEOUT "Setting MODEL_EXECUTION_TIMEOUT parameter to"
2929
#define REDISAI_INFOMSG_BACKEND_MEMORY_LIMIT "Setting BACKEND_MEMORY_LIMIT parameter to"
3030

31+
#define REDISAI_DEFAULT_MODEL_CHUNK_SIZE (511 * 1024 * 1024)
32+
3133
/**
3234
* Get number of threads used for parallelism between independent operations, by
3335
* backend.
@@ -81,9 +83,8 @@ char *Config_GetBackendsPath(void);
8183
int Config_LoadBackend(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
8284

8385
/**
84-
* Helper method for AI.CONFIG BACKENDSPATH
85-
* <default_location_of_backend_libraries>
86-
* @param path string containing backend path
86+
* Helper method for AI.CONFIG BACKENDSPATH <default_location_of_backend_libraries>
87+
* @param path string containing backend path.
8788
*/
8889
void Config_SetBackendsPath(const char *path);
8990

src/redisai.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,6 +1279,11 @@ void RAI_moduleInfoFunc(RedisModuleInfoCtx *ctx, int for_crash_report) {
12791279
AI_dictReleaseIterator(iter);
12801280
}
12811281

1282+
void RAI_CleanupModule(RedisModuleCtx *ctx, RedisModuleEvent eid, uint64_t subevent, void *data) {
1283+
RedisModule_Log(ctx, "notice", "%s", "Clearing resources on shutdown");
1284+
RedisModule_Free(Config_GetBackendsPath());
1285+
}
1286+
12821287
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
12831288

12841289
#ifndef REDISAI_LITE
@@ -1424,6 +1429,8 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
14241429

14251430
RedisModule_SetModuleOptions(ctx, REDISMODULE_OPTIONS_HANDLE_IO_ERRORS);
14261431

1432+
RedisModule_SubscribeToServerEvent(ctx, RedisModuleEvent_Shutdown, RAI_CleanupModule);
1433+
14271434
if (Config_SetLoadTimeParams(ctx, argv, argc) != REDISMODULE_OK) {
14281435
return REDISMODULE_ERR;
14291436
}

tests/flow/includes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import paella
1818

1919
ROOT = os.environ.get("ROOT", None)
20+
MODULE = os.environ.get("MODULE", None)
2021
TESTMOD_PATH = os.environ.get("TESTMOD", None)
2122
MAX_ITERATIONS = 2 if os.environ.get("MAX_ITERATIONS") == None else os.environ.get("MAX_ITERATIONS")
2223
TEST_TF = os.environ.get("TEST_TF") != "0" and os.environ.get("WITH_TF") != "0"

tests/flow/tests_commands.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ def test_ai_config(env):
552552
for con in conns:
553553
# Get the default configs.
554554
res = con.execute_command('AI.CONFIG', 'GET', 'BACKENDSPATH')
555-
env.assertEqual(res, None)
555+
env.assertEqual(res.decode(), f'{"/".join(MODULE.split("/")[:-1])}/backends') # <path_to_module_dir>/backends
556556
res = con.execute_command('AI.CONFIG', 'GET', 'MODEL_CHUNK_SIZE')
557557
env.assertEqual(res, 511*1024*1024)
558558

@@ -609,6 +609,7 @@ def test_ai_config_errors(env):
609609

610610
check_error_message(env, con, 'BACKENDSPATH: missing path argument', 'AI.CONFIG', 'BACKENDSPATH')
611611
check_error_message(env, con, 'MODEL_CHUNK_SIZE: missing chunk size', 'AI.CONFIG', 'MODEL_CHUNK_SIZE')
612+
check_error_message(env, con, 'MODEL_CHUNK_SIZE: invalid chunk size', 'AI.CONFIG', 'MODEL_CHUNK_SIZE', 'not_number')
612613

613614
check_error_message(env, con, "wrong number of arguments for 'AI.CONFIG' command", 'AI.CONFIG', 'GET')
614615
env.assertEqual(con.execute_command('AI.CONFIG', 'GET', 'bad_config'), None)

tests/flow/tests_onnx.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ def test_synchronization(self):
567567

568568
def launch_redis_and_run_onnx(con, proc_id, pipes):
569569
my_pipe = pipes[proc_id]
570-
port = 6380 + proc_id # Let every subprocess run on a fresh port.
570+
port = 6380 + 30*proc_id # Let every subprocess run on a fresh port (safe distance for RLTEST parallelism).
571571
redis_server = subprocess.Popen(['redis-server', '--port', str(port),
572572
'--loadmodule', f'{ROOT}/install-{DEVICE.lower()}/redisai.so',
573573
'--logfile', f'{self.env.logDir}/test_onnx_kill_switch_synchronization-{port}.log',

0 commit comments

Comments
 (0)