| 3976 | } |
| 3977 | |
| 3978 | static void FinishAsyncModelRun(RAI_OnFinishCtx *onFinishCtx, void *private_data) { |
| 3979 | |
| 3980 | RAI_Error *error; |
| 3981 | RedisAI_InitError(&error); |
| 3982 | RAI_ModelRunCtx* mctx = RedisAI_GetAsModelRunCtx(onFinishCtx, error); |
| 3983 | |
| 3984 | RedisGearsPy_LOCK |
| 3985 | PyObject* future = private_data; |
| 3986 | PyObject* pArgs = PyTuple_New(2); |
| 3987 | PyTuple_SetItem(pArgs, 0, future); |
| 3988 | |
| 3989 | if (RedisAI_GetErrorCode(error) != RedisAI_ErrorCode_OK) { |
| 3990 | const char *errStr = RedisAI_GetError(error); |
| 3991 | PyObject* pyErr = PyUnicode_FromStringAndSize(errStr, strlen(errStr)); |
| 3992 | PyTuple_SetItem(pArgs, 1, pyErr); |
| 3993 | PyObject_CallObject(setFutureExceptionFunction, pArgs); |
| 3994 | goto finish; |
| 3995 | } |
| 3996 | |
| 3997 | PyObject* tensorList = PyList_New(0); |
| 3998 | for(size_t i = 0 ; i < RedisAI_ModelRunCtxNumOutputs(mctx) ; ++i){ |
| 3999 | PyTensor* pyt = PyObject_New(PyTensor, &PyTensorType); |
| 4000 | pyt->t = RedisAI_TensorGetShallowCopy(RedisAI_ModelRunCtxOutputTensor(mctx, i)); |
| 4001 | PyList_Append(tensorList, (PyObject*)pyt); |
| 4002 | GearsPyDecRef((PyObject*)pyt); |
| 4003 | } |
| 4004 | |
| 4005 | PyTuple_SetItem(pArgs, 1, tensorList); |
| 4006 | PyObject* r = PyObject_CallObject(setFutureResultsFunction, pArgs); |
| 4007 | if(!r){ |
| 4008 | char* err = getPyError(); |
| 4009 | RedisModule_Log(NULL, "warning", "Error happened when releasing execution future, error='%s'", err); |
| 4010 | RG_FREE(err); |
| 4011 | }else{ |
| 4012 | GearsPyDecRef(r); |
| 4013 | } |
| 4014 | |
| 4015 | finish: |
| 4016 | RedisAI_FreeError(error); |
| 4017 | RedisAI_ModelRunCtxFree(mctx); |
| 4018 | GearsPyDecRef(pArgs); |
| 4019 | RedisGearsPy_UNLOCK |
| 4020 | } |
| 4021 | |
| 4022 | static PyObject* modelRunnerRunAsync(PyObject *cls, PyObject *args){ |
| 4023 | verifyRedisAILoaded(); |
nothing calls this directly
no test coverage detected