From 24f02b7aec0506cf45774d8b848121e03f2e8de9 Mon Sep 17 00:00:00 2001 From: DvirDukhan Date: Wed, 3 Jun 2020 10:44:42 +0300 Subject: [PATCH 1/3] added low level api return redis types --- src/model.c | 4 ++++ src/model.h | 7 +++++++ src/redisai.c | 3 +++ src/redisai.h | 6 ++++++ src/script.c | 6 +++++- src/script.h | 6 ++++++ src/tensor.c | 6 +++++- src/tensor.h | 6 ++++++ 8 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/model.c b/src/model.c index 21bb5e58b..e0ba0ef7c 100644 --- a/src/model.c +++ b/src/model.c @@ -645,3 +645,7 @@ int RedisAI_Parse_ModelRun_RedisCommand(RedisModuleCtx *ctx, } return argpos; } + +RedisModuleType *RAI_getModelRedisType(void) { + return RedisAI_ModelType; +} diff --git a/src/model.h b/src/model.h index 90b019dc4..cb9c98610 100644 --- a/src/model.h +++ b/src/model.h @@ -225,4 +225,11 @@ int RedisAI_Parse_ModelRun_RedisCommand( RAI_ModelRunCtx** mctx, RedisModuleString*** outkeys, RAI_Model** mto, int useLocalContext, AI_dict** localContextDict, int use_chaining_operator, const char* chaining_operator, RAI_Error* error); + +/** + * @brief Returns the redis module type representing a model. + * @return redis module type representing a model. + */ +RedisModuleType *RAI_ModelRedisType(void); + #endif /* SRC_MODEL_H_ */ diff --git a/src/redisai.c b/src/redisai.c index c9796f1ad..c91f2d13f 100644 --- a/src/redisai.c +++ b/src/redisai.c @@ -966,6 +966,7 @@ static int RedisAI_RegisterApi(RedisModuleCtx* ctx) { REGISTER_API(TensorDim, ctx); REGISTER_API(TensorByteSize, ctx); REGISTER_API(TensorData, ctx); + REGISTER_API(TensorRedisType, ctx); REGISTER_API(ModelCreate, ctx); REGISTER_API(ModelFree, ctx); @@ -978,6 +979,7 @@ static int RedisAI_RegisterApi(RedisModuleCtx* ctx) { REGISTER_API(ModelRun, ctx); REGISTER_API(ModelSerialize, ctx); REGISTER_API(ModelGetShallowCopy, ctx); + REGISTER_API(ModelRedisType, ctx); REGISTER_API(ScriptCreate, ctx); REGISTER_API(ScriptFree, ctx); @@ -989,6 +991,7 @@ static int RedisAI_RegisterApi(RedisModuleCtx* ctx) { REGISTER_API(ScriptRunCtxFree, ctx); REGISTER_API(ScriptRun, ctx); REGISTER_API(ScriptGetShallowCopy, ctx); + REGISTER_API(ScriptRedisType, ctx); return REDISMODULE_OK; } diff --git a/src/redisai.h b/src/redisai.h index cdf63bb7f..f4c8bebff 100644 --- a/src/redisai.h +++ b/src/redisai.h @@ -78,6 +78,7 @@ int MODULE_API_FUNC(RedisAI_TensorNumDims)(RAI_Tensor* t); long long MODULE_API_FUNC(RedisAI_TensorDim)(RAI_Tensor* t, int dim); size_t MODULE_API_FUNC(RedisAI_TensorByteSize)(RAI_Tensor* t); char* MODULE_API_FUNC(RedisAI_TensorData)(RAI_Tensor* t); +RedisModuleType MODULE_API_FUNC(RedisAI_TensorRedisType)(void); RAI_Model* MODULE_API_FUNC(RedisAI_ModelCreate)(int backend, char* devicestr, char* tag, RAI_ModelOpts opts, size_t ninputs, const char **inputs, @@ -93,6 +94,7 @@ void MODULE_API_FUNC(RedisAI_ModelRunCtxFree)(RAI_ModelRunCtx* mctx); int MODULE_API_FUNC(RedisAI_ModelRun)(RAI_ModelRunCtx** mctx, long long n, RAI_Error* err); RAI_Model* MODULE_API_FUNC(RedisAI_ModelGetShallowCopy)(RAI_Model* model); int MODULE_API_FUNC(RedisAI_ModelSerialize)(RAI_Model *model, char **buffer, size_t *len, RAI_Error *err); +RedisModuleType MODULE_API_FUNC(RedisAI_ModelRedisType)(void); RAI_Script* MODULE_API_FUNC(RedisAI_ScriptCreate)(char* devicestr, char* tag, const char* scriptdef, RAI_Error* err); void MODULE_API_FUNC(RedisAI_ScriptFree)(RAI_Script* script, RAI_Error* err); @@ -104,6 +106,7 @@ RAI_Tensor* MODULE_API_FUNC(RedisAI_ScriptRunCtxOutputTensor)(RAI_ScriptRunCtx* void MODULE_API_FUNC(RedisAI_ScriptRunCtxFree)(RAI_ScriptRunCtx* sctx); int MODULE_API_FUNC(RedisAI_ScriptRun)(RAI_ScriptRunCtx* sctx, RAI_Error* err); RAI_Script* MODULE_API_FUNC(RedisAI_ScriptGetShallowCopy)(RAI_Script* script); +RedisModuleType MODULE_API_FUNC(RedisAI_ScriptRedisType)(void); int MODULE_API_FUNC(RedisAI_GetLLAPIVersion)(); @@ -145,6 +148,7 @@ static int RedisAI_Initialize(RedisModuleCtx* ctx){ REDISAI_MODULE_INIT_FUNCTION(ctx, TensorDim); REDISAI_MODULE_INIT_FUNCTION(ctx, TensorByteSize); REDISAI_MODULE_INIT_FUNCTION(ctx, TensorData); + REDISAI_MODULE_INIT_FUNCTION(ctx, TensorRedisType); REDISAI_MODULE_INIT_FUNCTION(ctx, ModelCreate); REDISAI_MODULE_INIT_FUNCTION(ctx, ModelFree); @@ -157,6 +161,7 @@ static int RedisAI_Initialize(RedisModuleCtx* ctx){ REDISAI_MODULE_INIT_FUNCTION(ctx, ModelRun); REDISAI_MODULE_INIT_FUNCTION(ctx, ModelGetShallowCopy); REDISAI_MODULE_INIT_FUNCTION(ctx, ModelSerialize); + REDISAI_MODULE_INIT_FUNCTION(ctx, ModelRedisType); REDISAI_MODULE_INIT_FUNCTION(ctx, ScriptCreate); REDISAI_MODULE_INIT_FUNCTION(ctx, ScriptFree); @@ -168,6 +173,7 @@ static int RedisAI_Initialize(RedisModuleCtx* ctx){ REDISAI_MODULE_INIT_FUNCTION(ctx, ScriptRunCtxFree); REDISAI_MODULE_INIT_FUNCTION(ctx, ScriptRun); REDISAI_MODULE_INIT_FUNCTION(ctx, ScriptGetShallowCopy); + REDISAI_MODULE_INIT_FUNCTION(ctx, ScriptRedisType); if(RedisAI_GetLLAPIVersion() < REDISAI_LLAPI_VERSION){ return REDISMODULE_ERR; diff --git a/src/script.c b/src/script.c index a907e1955..9da1d7c95 100644 --- a/src/script.c +++ b/src/script.c @@ -334,4 +334,8 @@ void RedisAI_ReplyOrSetError(RedisModuleCtx *ctx, RAI_Error *error, RAI_ErrorCod } else { RedisModule_ReplyWithError(ctx, errorMessage); } -} \ No newline at end of file +} + +RedisModuleType *RAI_ScriptRedisType(void) { + return RedisAI_ScriptType; +} diff --git a/src/script.h b/src/script.h index 87b230457..1d338c764 100644 --- a/src/script.h +++ b/src/script.h @@ -192,4 +192,10 @@ int RedisAI_Parse_ScriptRun_RedisCommand(RedisModuleCtx *ctx, */ void RedisAI_ReplyOrSetError(RedisModuleCtx *ctx, RAI_Error *error, RAI_ErrorCode code, const char* errorMessage ); +/** + * @brief Returns the redis module type representing a script. + * @return redis module type representing a script. + */ +RedisModuleType *RAI_ScriptRedisType(void); + #endif /* SRC_SCRIPT_H_ */ diff --git a/src/tensor.c b/src/tensor.c index 2d7485741..efcaca9b1 100644 --- a/src/tensor.c +++ b/src/tensor.c @@ -1071,4 +1071,8 @@ int RAI_parseTensorGetArgs(RedisModuleCtx *ctx, RedisModuleString **argv, int ar // return command arity as the number of processed args return argc; -} \ No newline at end of file +} + +RedisModuleType *RAI_TensorRedisType(void) { + return RedisAI_TensorType; +} diff --git a/src/tensor.h b/src/tensor.h index 2fe89e124..3269b18e9 100644 --- a/src/tensor.h +++ b/src/tensor.h @@ -378,4 +378,10 @@ int RAI_parseTensorSetArgs(RedisModuleCtx* ctx, RedisModuleString** argv, int RAI_parseTensorGetArgs(RedisModuleCtx* ctx, RedisModuleString** argv, int argc, RAI_Tensor* t); +/** + * @brief Returns the redis module type representing a tensor. + * @return redis module type representing a tensor. + */ +RedisModuleType *RAI_TensorRedisType(void); + #endif /* SRC_TENSOR_H_ */ From c4e237d76dc5dc0f9a31e799a5295ed804deddaa Mon Sep 17 00:00:00 2001 From: DvirDukhan Date: Thu, 4 Jun 2020 23:46:09 +0300 Subject: [PATCH 2/3] added variadic to llapi --- src/model.c | 2 +- src/redisai.c | 1 + src/redisai.h | 10 ++++++---- src/script.c | 39 +++++++++++++++++++++++++++++++-------- src/script.h | 20 ++++++++++++++++++-- test/tests_pytorch.py | 7 +++++++ 6 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/model.c b/src/model.c index e0ba0ef7c..6d2880e44 100644 --- a/src/model.c +++ b/src/model.c @@ -646,6 +646,6 @@ int RedisAI_Parse_ModelRun_RedisCommand(RedisModuleCtx *ctx, return argpos; } -RedisModuleType *RAI_getModelRedisType(void) { +RedisModuleType *RAI_ModelRedisType(void) { return RedisAI_ModelType; } diff --git a/src/redisai.c b/src/redisai.c index c91f2d13f..0c1f83c9d 100644 --- a/src/redisai.c +++ b/src/redisai.c @@ -985,6 +985,7 @@ static int RedisAI_RegisterApi(RedisModuleCtx* ctx) { REGISTER_API(ScriptFree, ctx); REGISTER_API(ScriptRunCtxCreate, ctx); REGISTER_API(ScriptRunCtxAddInput, ctx); + REGISTER_API(ScriptRunCtxAddInputList, ctx); REGISTER_API(ScriptRunCtxAddOutput, ctx); REGISTER_API(ScriptRunCtxNumOutputs, ctx); REGISTER_API(ScriptRunCtxOutputTensor, ctx); diff --git a/src/redisai.h b/src/redisai.h index f4c8bebff..b93b112f8 100644 --- a/src/redisai.h +++ b/src/redisai.h @@ -78,7 +78,7 @@ int MODULE_API_FUNC(RedisAI_TensorNumDims)(RAI_Tensor* t); long long MODULE_API_FUNC(RedisAI_TensorDim)(RAI_Tensor* t, int dim); size_t MODULE_API_FUNC(RedisAI_TensorByteSize)(RAI_Tensor* t); char* MODULE_API_FUNC(RedisAI_TensorData)(RAI_Tensor* t); -RedisModuleType MODULE_API_FUNC(RedisAI_TensorRedisType)(void); +RedisModuleType* MODULE_API_FUNC(RedisAI_TensorRedisType)(void); RAI_Model* MODULE_API_FUNC(RedisAI_ModelCreate)(int backend, char* devicestr, char* tag, RAI_ModelOpts opts, size_t ninputs, const char **inputs, @@ -94,19 +94,20 @@ void MODULE_API_FUNC(RedisAI_ModelRunCtxFree)(RAI_ModelRunCtx* mctx); int MODULE_API_FUNC(RedisAI_ModelRun)(RAI_ModelRunCtx** mctx, long long n, RAI_Error* err); RAI_Model* MODULE_API_FUNC(RedisAI_ModelGetShallowCopy)(RAI_Model* model); int MODULE_API_FUNC(RedisAI_ModelSerialize)(RAI_Model *model, char **buffer, size_t *len, RAI_Error *err); -RedisModuleType MODULE_API_FUNC(RedisAI_ModelRedisType)(void); +RedisModuleType* MODULE_API_FUNC(RedisAI_ModelRedisType)(void); RAI_Script* MODULE_API_FUNC(RedisAI_ScriptCreate)(char* devicestr, char* tag, const char* scriptdef, RAI_Error* err); void MODULE_API_FUNC(RedisAI_ScriptFree)(RAI_Script* script, RAI_Error* err); RAI_ScriptRunCtx* MODULE_API_FUNC(RedisAI_ScriptRunCtxCreate)(RAI_Script* script, const char *fnname); -int MODULE_API_FUNC(RedisAI_ScriptRunCtxAddInput)(RAI_ScriptRunCtx* sctx, RAI_Tensor* inputTensor); +int MODULE_API_FUNC(RedisAI_ScriptRunCtxAddInput)(RAI_ScriptRunCtx* sctx, RAI_Tensor* inputTensor, RAI_Error* err); +int MODULE_API_FUNC(RedisAI_ScriptRunCtxAddInputList)(RAI_ScriptRunCtx* sctx, RAI_Tensor** inputTensors, size_t len, RAI_Error* err); int MODULE_API_FUNC(RedisAI_ScriptRunCtxAddOutput)(RAI_ScriptRunCtx* sctx); size_t MODULE_API_FUNC(RedisAI_ScriptRunCtxNumOutputs)(RAI_ScriptRunCtx* sctx); RAI_Tensor* MODULE_API_FUNC(RedisAI_ScriptRunCtxOutputTensor)(RAI_ScriptRunCtx* sctx, size_t index); void MODULE_API_FUNC(RedisAI_ScriptRunCtxFree)(RAI_ScriptRunCtx* sctx); int MODULE_API_FUNC(RedisAI_ScriptRun)(RAI_ScriptRunCtx* sctx, RAI_Error* err); RAI_Script* MODULE_API_FUNC(RedisAI_ScriptGetShallowCopy)(RAI_Script* script); -RedisModuleType MODULE_API_FUNC(RedisAI_ScriptRedisType)(void); +RedisModuleType* MODULE_API_FUNC(RedisAI_ScriptRedisType)(void); int MODULE_API_FUNC(RedisAI_GetLLAPIVersion)(); @@ -167,6 +168,7 @@ static int RedisAI_Initialize(RedisModuleCtx* ctx){ REDISAI_MODULE_INIT_FUNCTION(ctx, ScriptFree); REDISAI_MODULE_INIT_FUNCTION(ctx, ScriptRunCtxCreate); REDISAI_MODULE_INIT_FUNCTION(ctx, ScriptRunCtxAddInput); + REDISAI_MODULE_INIT_FUNCTION(ctx, ScriptRunCtxAddInputList); REDISAI_MODULE_INIT_FUNCTION(ctx, ScriptRunCtxAddOutput); REDISAI_MODULE_INIT_FUNCTION(ctx, ScriptRunCtxNumOutputs); REDISAI_MODULE_INIT_FUNCTION(ctx, ScriptRunCtxOutputTensor); diff --git a/src/script.c b/src/script.c index 9da1d7c95..b0ecf2748 100644 --- a/src/script.c +++ b/src/script.c @@ -164,8 +164,27 @@ static int Script_RunCtxAddParam(RAI_ScriptRunCtx* sctx, return 1; } -int RAI_ScriptRunCtxAddInput(RAI_ScriptRunCtx* sctx, RAI_Tensor* inputTensor) { - return Script_RunCtxAddParam(sctx, sctx->inputs, inputTensor); +int RAI_ScriptRunCtxAddInput(RAI_ScriptRunCtx* sctx, RAI_Tensor* inputTensor, RAI_Error* err) { + if(sctx->variadic != -1) { + RAI_SetError(err, RAI_EBACKENDNOTLOADED, "ERR Already encountered a variable size list of tensors"); + return 0; + } + return Script_RunCtxAddParam(sctx, sctx->inputs, inputTensor); +} + +int RAI_ScriptRunCtxAddInputList(RAI_ScriptRunCtx* sctx, RAI_Tensor** inputTensors, size_t len, RAI_Error* err) { + // If this is the first time a list is added, set the variadic, else return an error. + if(sctx->variadic == -1) { + sctx->variadic = array_len(sctx->inputs); + } + else { + RAI_SetError(err, RAI_EBACKENDNOTLOADED, "ERR Already encountered a variable size list of tensors"); + return 0; + } + for(size_t i=0; i < len; i++){ + Script_RunCtxAddParam(sctx, sctx->inputs, inputTensors[i]); + } + return 1; } int RAI_ScriptRunCtxAddOutput(RAI_ScriptRunCtx* sctx) { @@ -270,7 +289,8 @@ int RedisAI_Parse_ScriptRun_RedisCommand(RedisModuleCtx *ctx, int is_input = 0; int outputs_flag_count = 0; size_t argpos = 4; - + // Keep variadic local variable as the calls for RAI_ScriptRunCtxAddInput check if (*sctx)->variadic already assigned. + size_t variadic = (*sctx)->variadic; for (; argpos <= argc - 1; argpos++) { const char *arg_string = RedisModule_StringPtrLen(argv[argpos], NULL); if(!arg_string){ @@ -287,7 +307,11 @@ int RedisAI_Parse_ScriptRun_RedisCommand(RedisModuleCtx *ctx, outputs_flag_count = 1; } else { if (!strcasecmp(arg_string, "$")) { - (*sctx)->variadic = argpos - 4; + if(variadic > -1) { + RedisAI_ReplyOrSetError(ctx,error,RAI_ESCRIPTRUN, "ERR Already encountered a variable size list of tensors"); + return -1; + } + variadic = argpos - 4; continue; } RedisModule_RetainString(ctx, argv[argpos]); @@ -309,10 +333,7 @@ int RedisAI_Parse_ScriptRun_RedisCommand(RedisModuleCtx *ctx, return -1; } } - if (!RAI_ScriptRunCtxAddInput(*sctx, inputTensor)) { - RedisAI_ReplyOrSetError(ctx, error, RAI_ESCRIPTRUN, "ERR Input key not found"); - return -1; - } + if (!RAI_ScriptRunCtxAddInput(*sctx, inputTensor, error)) return -1; } else { if (!RAI_ScriptRunCtxAddOutput(*sctx)) { RedisAI_ReplyOrSetError(ctx, error, RAI_ESCRIPTRUN, "ERR Output key not found"); @@ -322,6 +343,8 @@ int RedisAI_Parse_ScriptRun_RedisCommand(RedisModuleCtx *ctx, } } } + // In case variadic position found, set it in the context. + (*sctx)->variadic = variadic; return argpos; } diff --git a/src/script.h b/src/script.h index 1d338c764..ce15aaa43 100644 --- a/src/script.h +++ b/src/script.h @@ -67,9 +67,25 @@ RAI_ScriptRunCtx* RAI_ScriptRunCtxCreate(RAI_Script* script, * * @param sctx input RAI_ScriptRunCtx to add the input tensor * @param inputTensor input tensor structure - * @return returns 1 on success ( always returns success ) + * @param err error data structure to store error message in the case of + * failures + * @return returns 1 on success, 0 in case of error. + */ +int RAI_ScriptRunCtxAddInput(RAI_ScriptRunCtx* sctx, RAI_Tensor* inputTensor, RAI_Error* err); + +/** + * For each Allocates a RAI_ScriptCtxParam data structure, and enforces a shallow copy of + * the provided input tensor, adding it to the input tensors array of the + * RAI_ScriptRunCtx. + * + * @param sctx input RAI_ScriptRunCtx to add the input tensor + * @param inputTensors input tensors array + * @param len input tensors array len + * @param err error data structure to store error message in the case of + * failures + * @return returns 1 on success, 0 in case of error. */ -int RAI_ScriptRunCtxAddInput(RAI_ScriptRunCtx* sctx, RAI_Tensor* inputTensor); +int RAI_ScriptRunCtxAddInputList(RAI_ScriptRunCtx* sctx, RAI_Tensor** inputTensors, size_t len, RAI_Error* err); /** * Allocates a RAI_ScriptCtxParam data structure, and sets the tensor reference diff --git a/test/tests_pytorch.py b/test/tests_pytorch.py index ff33b2715..6e603ccf8 100644 --- a/test/tests_pytorch.py +++ b/test/tests_pytorch.py @@ -641,6 +641,13 @@ def test_pytorch_scriptrun_errors(env): except Exception as e: exception = e env.assertEqual(type(exception), redis.exceptions.ResponseError) + + # "ERR Already encountered a variable size list of tensors" + try: + con.execute_command('AI.SCRIPTRUN', 'ket', 'bar_variadic', 'INPUTS', '$', 'a', '$', 'b' 'OUTPUTS') + except Exception as e: + exception = e + env.assertEqual(type(exception), redis.exceptions.ResponseError) def test_pytorch_scriptinfo(env): From 54e7c5f953fbe7fd0459ff76651d55a471cb3bd5 Mon Sep 17 00:00:00 2001 From: DvirDukhan Date: Sun, 7 Jun 2020 21:25:18 +0300 Subject: [PATCH 3/3] fixed memory issue for params array re-alloc --- src/script.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/script.c b/src/script.c index b0ecf2748..b24b14349 100644 --- a/src/script.c +++ b/src/script.c @@ -155,12 +155,12 @@ RAI_ScriptRunCtx* RAI_ScriptRunCtxCreate(RAI_Script* script, } static int Script_RunCtxAddParam(RAI_ScriptRunCtx* sctx, - RAI_ScriptCtxParam* paramArr, + RAI_ScriptCtxParam** paramArr, RAI_Tensor* tensor) { RAI_ScriptCtxParam param = { .tensor = tensor ? RAI_TensorGetShallowCopy(tensor) : NULL, }; - paramArr = array_append(paramArr, param); + *paramArr = array_append(*paramArr, param); return 1; } @@ -169,7 +169,7 @@ int RAI_ScriptRunCtxAddInput(RAI_ScriptRunCtx* sctx, RAI_Tensor* inputTensor, RA RAI_SetError(err, RAI_EBACKENDNOTLOADED, "ERR Already encountered a variable size list of tensors"); return 0; } - return Script_RunCtxAddParam(sctx, sctx->inputs, inputTensor); + return Script_RunCtxAddParam(sctx, &sctx->inputs, inputTensor); } int RAI_ScriptRunCtxAddInputList(RAI_ScriptRunCtx* sctx, RAI_Tensor** inputTensors, size_t len, RAI_Error* err) { @@ -182,13 +182,13 @@ int RAI_ScriptRunCtxAddInputList(RAI_ScriptRunCtx* sctx, RAI_Tensor** inputTenso return 0; } for(size_t i=0; i < len; i++){ - Script_RunCtxAddParam(sctx, sctx->inputs, inputTensors[i]); + Script_RunCtxAddParam(sctx, &sctx->inputs, inputTensors[i]); } return 1; } int RAI_ScriptRunCtxAddOutput(RAI_ScriptRunCtx* sctx) { - return Script_RunCtxAddParam(sctx, sctx->outputs, NULL); + return Script_RunCtxAddParam(sctx, &sctx->outputs, NULL); } size_t RAI_ScriptRunCtxNumOutputs(RAI_ScriptRunCtx* sctx) {